Merge remote-tracking branch 'origin/develop' into develop

master
eason.qian 7 years ago
commit 83f2de9c93

@ -490,4 +490,6 @@ CREATE TABLE `pmt_directed_bill_code` (
KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
ALTER TABLE `act_red_packets_customer` ADD COLUMN `rule_max_num_limit` tinyint(1) DEFAULT 1 COMMENT '0:Whole Activity,1day'

@ -21,6 +21,7 @@ public class AppPermissionSupportImpl implements AppPermissionSupport {
private SysAppsMapper sysAppsMapper;
private final String signTemplate = "%s&%s&%s&%s&%s";
private Logger logger = LoggerFactory.getLogger(getClass());
public static final String[] NODES_IP_ADDRESSS = new String[]{"119.28.3.196","150.109.64.108", "119.28.178.24", "119.28.24.146", "119.28.77.25"};
@Override
public JSONObject validateSign(String appid, long timestamp, String ip, String requestUri, String sign) {
@ -44,6 +45,15 @@ public class AppPermissionSupportImpl implements AppPermissionSupport {
logger.debug("sso-str before hash:" + str);
String hash = DigestUtils.sha256Hex(str).toLowerCase();
if (!StringUtils.equals(hash, sign)) {
logger.error("[{}]请求的签名有误,使用节点 [{}] 签名", appid, NODES_IP_ADDRESSS.toString());
for (String nodeIp : NODES_IP_ADDRESSS) {
str = String.format(signTemplate, appid, auth, timestamp, requestUri, nodeIp);
logger.debug("NodeIp check sso-str before hash:" + str);
hash = DigestUtils.sha256Hex(str).toLowerCase();
if (StringUtils.equals(hash, sign)) {
return app;
}
}
throw new ForbiddenException("InvalidSign");
}
return app;

@ -44,4 +44,8 @@ public interface ActRedPacketsCustomerOrdersMapper {
PageList<JSONObject> listOrders(JSONObject jsonObject, PageBounds pageBounds);
List<JSONObject> listUnsend(@Param("act_id") String actId, @Param("before") Date before);
List<JSONObject> getCustomerRedpackAnalysis(JSONObject params);
JSONObject analysisCustomerLuckyMoney(JSONObject params);
}

@ -13,6 +13,7 @@ public class CustomerRedpackActBean {
private String act_name;
private BigDecimal rule_order_total;
private int rule_max_num;
private int rule_max_num_limit;
private int status=0;
private List<JSONObject> prize_type_list;
@ -59,4 +60,12 @@ public class CustomerRedpackActBean {
public void setPrize_type_list(List<JSONObject> prize_type_list) {
this.prize_type_list = prize_type_list;
}
public int getRule_max_num_limit() {
return rule_max_num_limit;
}
public void setRule_max_num_limit(int rule_max_num_limit) {
this.rule_max_num_limit = rule_max_num_limit;
}
}

@ -2,6 +2,7 @@ package au.com.royalpay.payment.manage.redpack.beans;
import au.com.royalpay.payment.core.exceptions.ParamInvalidException;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import java.text.ParseException;
@ -50,16 +51,16 @@ public class RedpackQuery {
throw new ParamInvalidException("event_date", "error.payment.valid.invalid_date_format");
}
}
if (short_name != null){
if (StringUtils.isNotEmpty(short_name)){
param.put("short_name",short_name);
}
if (client_moniker != null){
if (StringUtils.isNotEmpty(client_moniker)){
param.put("client_moniker",client_moniker);
}
if (nickname != null){
if (StringUtils.isNotEmpty(nickname)){
param.put("nickname",nickname);
}
if (org_id != null){
if (StringUtils.isNotEmpty(org_id)){
param.put("org_id",org_id);
}
if (bd != null){

@ -1,8 +1,11 @@
package au.com.royalpay.payment.manage.redpack.core;
import au.com.royalpay.payment.core.exceptions.RedPackException;
import au.com.royalpay.payment.manage.redpack.beans.RedpackQuery;
import com.alibaba.fastjson.JSONObject;
import java.util.List;
/**
* Created by wangning on 2017/8/10.
*/
@ -23,4 +26,8 @@ public interface ActRedPackService {
JSONObject listCustomerOrders(JSONObject params, int page, int limit);
void resendFailed();
List<JSONObject> getCustomerRedpackAnalysis(String act_id, RedpackQuery redpackQuery);
JSONObject analysisCustomerLuckyMoney(JSONObject params);
}

@ -7,6 +7,7 @@ import au.com.royalpay.payment.manage.mappers.redpack.ActPrizeTypeCustomerMapper
import au.com.royalpay.payment.manage.mappers.redpack.ActRedPacketsCustomerMapper;
import au.com.royalpay.payment.manage.mappers.redpack.ActRedPacketsCustomerOrdersMapper;
import au.com.royalpay.payment.manage.mappers.system.CustomerMapper;
import au.com.royalpay.payment.manage.redpack.beans.RedpackQuery;
import au.com.royalpay.payment.manage.redpack.core.ActRedPackService;
import au.com.royalpay.payment.tools.CommonConsts;
import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApi;
@ -15,13 +16,15 @@ import au.com.royalpay.payment.tools.connections.mpsupport.beans.WechatRedpack;
import au.com.royalpay.payment.tools.exceptions.ForbiddenException;
import au.com.royalpay.payment.tools.exceptions.NotFoundException;
import au.com.royalpay.payment.tools.utils.PageListUtils;
import com.alibaba.fastjson.JSONObject;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
@ -30,7 +33,6 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
@ -39,6 +41,8 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
/**
* Created by wangning on 2017/8/10.
*/
@ -129,37 +133,51 @@ public class ActRedPackServiceImpl implements ActRedPackService {
int getTotalCounts = getRedPacketsByOpenid(open_id, new Date(), actId);
int ruleMaxNum = redpackCustomerActivity.getIntValue("rule_max_num");
if (getTotalCounts >= ruleMaxNum) {
logger.error("open_id:" + open_id + "当日红包发送数量已到达" + ruleMaxNum + "!跳过");
logger.debug("open_id:" + open_id + "已达到本次活动发送最大次数" + ruleMaxNum + "!跳过");
return;
}
int getDailyTotalCounts = getRedPacketsByOpenid(open_id, new Date(), actId);
int ruleMaxNumLimit = redpackCustomerActivity.getIntValue("rule_max_num_limit");
if (getDailyTotalCounts >= ruleMaxNumLimit) {
logger.debug("open_id:" + open_id + "已达当日发送最大次数" + ruleMaxNumLimit + "!跳过");
return;
}
takeRedpack(actId,orderId, client_id, clientApply, currencyAmount, open_id, 0);
takeRedpack(actId, orderId, client_id, clientApply, currencyAmount, open_id, 0);
}
private void takeRedpack(String actId,String orderId, int client_id, JSONObject clientApply, BigDecimal currencyAmount, String open_id, int tryTimes)
private void takeRedpack(String actId, String orderId, int client_id, JSONObject clientApply, BigDecimal currencyAmount, String open_id, int tryTimes)
throws RedPackException {
if (tryTimes > 5) {
return;
}
int random = (int) (Math.random() * 100);
if (random > 80) {
logger.info("未达到触发概率当前概率为:" + random);
return;
}
List<JSONObject> prizeTypes = actPrizeTypeCustomerMapper.listAvailableTypes(actId);
Collections.shuffle(prizeTypes);
int totalWeight = 0;
for (JSONObject prizeType : prizeTypes) {
totalWeight += prizeType.getIntValue("weight");
}
int ran = RandomUtils.nextInt(0,totalWeight);
int ran = RandomUtils.nextInt(0, totalWeight);
for (JSONObject prizeType : prizeTypes) {
ran -= prizeType.getIntValue("weight");
if (ran < 0) {
String lock = Long.toString(System.currentTimeMillis(), 36) + RandomStringUtils.random(5, true, true);
int lockedCount = actRedPacketsCustomerOrdersMapper.lockPrize(actId,lock, prizeType.getString("type_id"), open_id, client_id, orderId, currencyAmount,
new Date());
int lockedCount = actRedPacketsCustomerOrdersMapper.lockPrize(actId, lock, prizeType.getString("type_id"), open_id, client_id, orderId,
currencyAmount, new Date());
if (lockedCount > 0) {
doSendActLuckyMoney(open_id, lock, clientApply.getString("act_name"), clientApply.getString("send_name"), clientApply.getString("wishing"));
break;
} else {
takeRedpack(actId,orderId, client_id, clientApply, currencyAmount, open_id, tryTimes + 1);
takeRedpack(actId, orderId, client_id, clientApply, currencyAmount, open_id, tryTimes + 1);
break;
}
}
@ -211,8 +229,8 @@ public class ActRedPackServiceImpl implements ActRedPackService {
if (redpack_counts > 0) {
for (int i = 0; i < redpack_counts; i++) {
BigDecimal amount = amountFrom.equals(amountTo) ? amountFrom
: amountFrom.add(BigDecimal.valueOf(RandomUtils.nextInt(0,amountTo.subtract(amountFrom).multiply(CommonConsts.HUNDRED).intValue()))
.divide(CommonConsts.HUNDRED, 2, BigDecimal.ROUND_DOWN));
: amountFrom.add(BigDecimal.valueOf(RandomUtils.nextInt(0, amountTo.subtract(amountFrom).multiply(CommonConsts.HUNDRED).intValue()))
.divide(CommonConsts.HUNDRED, 2, BigDecimal.ROUND_DOWN));
JSONObject prize = new JSONObject();
String prefix = DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS");
String red_packet_order_id = prefix + RandomStringUtils.random(28 - prefix.length(), true, true);
@ -277,7 +295,8 @@ public class ActRedPackServiceImpl implements ActRedPackService {
pool.execute(() -> {
JSONObject clientApply = actClientApplyMapper.findActivity(actId, redpack.getIntValue("client_id"));
try {
doSendActLuckyMoney(redpack.getString("open_id"), redpack.getString("lock"), clientApply.getString("act_name"), clientApply.getString("send_name"), clientApply.getString("wishing"));
doSendActLuckyMoney(redpack.getString("open_id"), redpack.getString("lock"), clientApply.getString("act_name"),
clientApply.getString("send_name"), clientApply.getString("wishing"));
} catch (RedPackException e) {
e.printStackTrace();
}
@ -286,4 +305,15 @@ public class ActRedPackServiceImpl implements ActRedPackService {
}
}
@Override
public List<JSONObject> getCustomerRedpackAnalysis(String act_id, RedpackQuery redpackQuery) {
JSONObject params = redpackQuery.params();
params.put("act_id", act_id);
return actRedPacketsCustomerOrdersMapper.getCustomerRedpackAnalysis(params);
}
@Override
public JSONObject analysisCustomerLuckyMoney(JSONObject params) {
return actRedPacketsCustomerOrdersMapper.analysisCustomerLuckyMoney(params);
}
}

@ -1,12 +1,14 @@
package au.com.royalpay.payment.manage.redpack.web;
import au.com.royalpay.payment.manage.permission.manager.ManagerMapping;
import au.com.royalpay.payment.manage.redpack.beans.RedpackQuery;
import au.com.royalpay.payment.tools.permission.enums.ManagerRole;
import au.com.royalpay.payment.manage.redpack.core.ActRedPackService;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* Created by wangning on 2017/8/10.
@ -30,10 +32,21 @@ public class ActRedpackConfigController {
}
@RequestMapping(value = "/act/{act_id}",method = RequestMethod.GET)
private JSONObject listCustomerOrders(@PathVariable String act_id, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int limit){
JSONObject params = new JSONObject();
private JSONObject listCustomerOrders(@PathVariable String act_id, RedpackQuery redpackQuery){
JSONObject params = redpackQuery.params();
params.put("actId",act_id);
return actRedPackService.listCustomerOrders(params,page,limit);
return actRedPackService.listCustomerOrders(params,redpackQuery.getPage(),redpackQuery.getLimit());
}
@ManagerMapping(value = "/{act_id}/sendLogs/analysis",method = RequestMethod.GET)
public List<JSONObject> getCustomerRedpackAnalysis(@PathVariable String act_id, RedpackQuery query){
return actRedPackService.getCustomerRedpackAnalysis(act_id,query);
}
@ManagerMapping(value = "/act/{act_id}/analysis",method = RequestMethod.GET)
public JSONObject customerLuckyMoneyAnalysis(@PathVariable String act_id, RedpackQuery query){
JSONObject params= query.params();
params.put("act_id",act_id);
return actRedPackService.analysisCustomerLuckyMoney(params);
}
}

@ -3,15 +3,18 @@ package au.com.royalpay.payment.manage.task;
import au.com.royalpay.payment.manage.mappers.bill.BillOrderMapper;
import au.com.royalpay.payment.manage.mappers.payment.OrderMapper;
import au.com.royalpay.payment.tools.scheduler.SynchronizedScheduler;
import com.alibaba.fastjson.JSONObject;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
import javax.annotation.Resource;
/**
* Created by wangning on 2018/1/2.
*/
@ -27,8 +30,8 @@ public class BillOrderCheckTask {
private SynchronizedScheduler synchronizedScheduler;
@Scheduled(cron = "0 0/3 * * * ?")
public void checkGreenChannel() {
synchronizedScheduler.executeProcess("manage_task:checkGreenChannel", 120_000, () -> {
public void checkBillOrderCheck() {
synchronizedScheduler.executeProcess("manage_task:checkBillOrderCheck", 120_000, () -> {
List<String> orderIds = billOrderMapper.findOrderIdByStatus("0");
if (CollectionUtils.isEmpty(orderIds)) {
return;

@ -25,8 +25,8 @@ public class CheckPartnerAuthStatusAndSendMessageTask {
// simpleClientService.checkAuthAndSendMessage();
// }
@Scheduled(cron = "0 0 9 * * ?")
public void checkGreenChannel() {
synchronizedScheduler.executeProcess("manage_task:CheckPartnerAuthStatus", 120_000, () -> simpleClientService.checkGreenChannelClients());
public void checkPartnerAuthStatusAndSendMessage() {
synchronizedScheduler.executeProcess("manage_task:checkPartnerAuthStatusAndSendMessage", 120_000, () -> simpleClientService.checkGreenChannelClients());
}
}

@ -34,8 +34,8 @@ public class CustomerImpressionTask {
private ThreadPoolExecutor generatePool = new ThreadPoolExecutor(10, 30, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
@Scheduled(cron = "0 30 3 * * ?")
public void generateTags() {
synchronizedScheduler.executeProcess("manage_task:CustomerImpression", 120_000, () -> {
public void customerImpressionGenerateTags() {
synchronizedScheduler.executeProcess("manage_task:customerImpressionGenerateTags", 120_000, () -> {
List<JSONObject> clients = clientMapper.listValidClient();
List<List<JSONObject>> splitList = new ArrayList<>();
for (int i = 0; i < clients.size(); i += 200) {
@ -57,7 +57,7 @@ public class CustomerImpressionTask {
}
@Scheduled(cron = "0/1 * * * * ?")
public void generateInfo() {
public void customerImpressionGenerateInfo() {
synchronizedScheduler.executeProcess("manage_task:CustomerImpression", 1_000, () -> customerImpressionService.generateInfo());
}
}

@ -26,8 +26,8 @@ public class DailyReportGenerationTask {
private SynchronizedScheduler synchronizedScheduler;
@Scheduled(cron = "0 0 10 * * ?")
public void autoGenerateReport() {
synchronizedScheduler.executeProcess("manage_task:autoGenerateDailyReport", 120_000, () -> {
public void dailyReportAutoGenerateReport() {
synchronizedScheduler.executeProcess("manage_task:dailyReportAutoGenerateReport", 120_000, () -> {
Date yesterday = DateUtils.addDays(new Date(), -1);
dailyReport.generateReport(DateFormatUtils.format(yesterday, "yyyy-MM-dd"), true);
});

@ -20,8 +20,8 @@ public class DirectedBillCodeStatusDailyCheck {
private SynchronizedScheduler synchronizedScheduler;
@Scheduled(cron = "0 30 5 * * ?")
public void statusDailyCheck() {
synchronizedScheduler.executeProcess("manage_task:dailyCheckDirected", 120_000,
public void directedBillCodeStatusDailyCheck() {
synchronizedScheduler.executeProcess("manage_task:directedBillCodeStatusDailyCheck", 120_000,
() -> partnerBillService.dailyCheckDirectedBillCode());
}
}

@ -27,7 +27,7 @@ public class OfeiOrderCheckTask {
private SynchronizedScheduler synchronizedScheduler;
@Scheduled(cron = "0 0/20 * * * ?")
public void checkGreenChannel() {
public void ofeiOrderCheck() {
synchronizedScheduler.executeProcess("manage_task:ofeiOrderCheck", 120_000, () -> {
List<String> orderIds = topUpOrderMapper.findOrderIdByStatus("10");
if (CollectionUtils.isEmpty(orderIds)) {

@ -23,9 +23,9 @@ public class PartnerInitEmailChecker {
private SynchronizedScheduler synchronizedScheduler;
@Scheduled(cron = "0 0/5 * * * *")
public void checkEmailStatus() {
public void checkPartnerInitEmail() {
if (PlatformEnvironment.getEnv().taskEnabled()) {
synchronizedScheduler.executeProcess("manage_task:emailStatusCheck", 120_000,
synchronizedScheduler.executeProcess("manage_task:checkPartnerInitEmail", 120_000,
() -> clientManager.checkEmailStatus());
}
}

@ -24,8 +24,8 @@ public class PartnerTransactionsDailyMsgTaskManager {
private SynchronizedScheduler synchronizedScheduler;
@Scheduled(cron = "0 0 8 * * ?")
public void analysisDashboard() {
synchronizedScheduler.executeProcess("manage_task:partnerDailyMsg", 120_000,
public void partnerTransactionsDailyMsg() {
synchronizedScheduler.executeProcess("manage_task:partnerTransactionsDailyMsg", 120_000,
() -> customersAnalysisService.sendPartnerTransactionDaily(DateUtils.addDays(new Date(), -1)));
}
}

@ -50,7 +50,7 @@ public class PostponeClientTask {
@Scheduled(cron = "0 30 8 * * ?")
public void checkGreenChannel() {
public void postponeClient() {
synchronizedScheduler.executeProcess("manage_task:postPoneClient", 120_000, () -> {
Date now = new Date();
Date tomorrow = DateUtils.addDays(now, 1);

@ -26,8 +26,8 @@ public class WeekReportGenerationTask {
private SynchronizedScheduler synchronizedScheduler;
@Scheduled(cron = "0 0 2 * * 1")
public void autoGenerateReport() {
synchronizedScheduler.executeProcess("manage_task:genWeekReport", 120_000, () -> {
public void weekReportGeneration() {
synchronizedScheduler.executeProcess("manage_task:weekReportGeneration", 120_000, () -> {
Date lastweek = new Date();
lastweek = DateUtils.addDays(lastweek, -7);
weekReporter.generateReport(DateFormatUtils.format(lastweek, "yyyy-MM-dd"), true);

@ -198,7 +198,6 @@
<select id="listCustomersData" resultType="com.alibaba.fastjson.JSONObject">
SELECT o.customer_id,sum(if(t.transaction_type='Credit',t.clearing_amount,0)) amount,
sum(if(t.transaction_type='Credit',t.clearing_amount div 10,0)) points,
COUNT(DISTINCT o.order_id) orders,max(t.clearing_amount) max_order
FROM pmt_orders o
INNER JOIN pmt_transactions t on t.order_id=o.order_id and t.system_generate=0 and (t.transaction_type='Credit' or t.transaction_type>0)
@ -224,12 +223,11 @@
<if test="org_ids!=null">and o.org_id in
<foreach collection="org_ids" item="org_id" open="(" close=")" separator=",">#{org_id}</foreach></if>
</where>
GROUP BY o.customer_id ORDER BY points desc
GROUP BY o.customer_id
</select>
<select id="listCustomersDataAnalysis" resultType="com.alibaba.fastjson.JSONObject">
SELECT sum(if(t.transaction_type='Credit',t.clearing_amount,0)) total_amount,
sum(if(t.transaction_type='Credit',t.clearing_amount div 10,0)) total_points
SELECT sum(if(t.transaction_type='Credit',t.clearing_amount,0)) total_amount
FROM pmt_orders o
INNER JOIN pmt_transactions t on t.order_id=o.order_id and t.system_generate=0 and (t.transaction_type='Credit' or t.refund_id is not null)
<where>

@ -17,15 +17,35 @@
<select id="getRedPacketsByOpenid" resultType="int">
SELECT count(1)
FROM act_red_packets_customer_orders
WHERE open_id = #{open_id} AND date(event_time) = date(#{event_date}) AND status != 0 AND act_id = #{act_id}
WHERE open_id = #{open_id}
<if test="event_date != null">
AND date(event_time) = date(#{event_date})
</if>
AND status != 0 AND act_id = #{act_id}
</select>
<select id="listOrders" resultType="com.alibaba.fastjson.JSONObject">
SELECT
a.*,
b.client_moniker
FROM act_red_packets_customer_orders a INNER JOIN sys_clients b ON a.client_id = b.client_id
b.client_moniker,
c.headimg,
c.nickname
FROM act_red_packets_customer_orders a
INNER JOIN sys_clients b ON a.client_id = b.client_id
LEFT JOIN sys_customer_relation c ON c.wechat_openid = a.open_id
WHERE act_id = #{actId}
<if test="client_moniker != null">
AND b.client_moniker = #{client_moniker}
</if>
<if test="short_name != null">
AND b.short_name = #{short_name}
</if>
<if test="nickname != null">
<bind name="nickname_pattern" value="'%'+nickname+'%'"/>
and c.nickname like #{nickname_pattern}
</if>
<if test="from!=null">and a.event_time >= #{from}</if>
<if test="to!=null">and a.event_time &lt;= #{to}</if>
</select>
<select id="listUnsend" resultType="com.alibaba.fastjson.JSONObject">
SELECT *
@ -48,4 +68,34 @@
]]>
</update>
<select id="getCustomerRedpackAnalysis" resultType="com.alibaba.fastjson.JSONObject">
<![CDATA[
SELECT date_format(event_time, '%Y-%m-%d') date,COUNT(red_packet_customer_order_id) counts,
sum(if(STATUS!=0,1,0)) sendtotal_counts,sum(if(status=1,1,0)) send_counts,sum(if(STATUS=2,1,0))fail_counts,sum(if(STATUS=3,1,0))receive_counts,sum(if(STATUS=4,1,0))refund_counts,
SUM(red_packet_amount) amount,sum(if(status=1 or status=3,red_packet_amount,0)) real_amount
FROM act_red_packets_customer_orders
where act_id = #{act_id}
and event_time is not null
and status !=0
]]>
<if test="from!=null">and event_time &gt;= #{from}</if>
<if test="to!=null">and event_time &lt;= #{to}</if>
GROUP BY date
</select>
<select id="analysisCustomerLuckyMoney" resultType="com.alibaba.fastjson.JSONObject">
SELECT COUNT(red_packet_customer_order_id) total_counts,sum(red_packet_amount) total_amount,
ifnull(SUM(if(status=0 AND lock_key is null,1,0)),0) unsend_counts,SUM(if(status=0 AND lock_key is null,red_packet_amount,0)) unsend_amount,
sum(if(status!=0,1,0)) send_counts,SUM(if(status !=0 ,red_packet_amount,0)) send_amount,
sum(if(status=2,1,0)) fail_counts,SUM(if(status=2,red_packet_amount,0)) fail_amount,
sum(if(status=1 or status=3,1,0)) receive_counts,SUM(if(status=1 or status=3,red_packet_amount,0)) receive_amount,
sum(if(status=4,1,0)) return_counts,SUM(if(status=4,red_packet_amount,0)) return_amount
FROM act_red_packets_customer_orders
<where>
act_id = #{act_id}
<if test="red_pack_type_id">and red_pack_type_id=#{red_pack_type_id}</if>
</where>
</select>
</mapper>

@ -148,6 +148,7 @@ define(['angular', 'static/commons/commons', 'static/commons/angular-ueditor', '
// $scope.analysis = resp.data.analysis;
});
};
$scope.chooseToday();
$scope.orderDetail = function (order) {
orderService.managerOrderDetail(order)

@ -90,8 +90,8 @@
<div class="box">
<div class="box-header">
<h3 class="box-title">Customer List</h3>
<small>Total Amount:{{customers_analysis.total_amount}},Total
Points:{{customers_analysis.total_points}}
<small>Total Amount:{{customers_analysis.total_amount}}<!--,Total
Points:{{customers_analysis.total_points}}-->
</small>
</div>
@ -101,7 +101,7 @@
<tr>
<th>Customer openId</th>
<th>Amount(AUD)</th>
<th>Points</th>
<!-- <th>Points</th>-->
<th>Orders</th>
<th>Max Order(AUD)</th>
</tr>
@ -112,7 +112,7 @@
ng-click="order_params.customer_id=customer.customer_id;listCustomerOrders()">
<td ng-bind="customer.customer_id"></td>
<td ng-bind="customer.amount"></td>
<td ng-bind="customer.points"></td>
<!-- <td ng-bind="customer.points"></td>-->
<td ng-bind="customer.orders"></td>
<td ng-bind="customer.max_order"></td>
</tr>

@ -37,11 +37,184 @@ define(['angular', 'static/commons/commons', 'uiBootstrap', 'uiRouter', 'ngBootS
}]);
app.controller('actCustomerRedpackOrdersCtrl',['$scope','$http',function ($scope, $http) {
app.controller('actCustomerRedpackOrdersCtrl',['$scope','$http','$filter',function ($scope, $http,$filter) {
$scope.analysis = {};
$scope.today = new Date();
$scope.chooseToday = function () {
$scope.analysis.begin = $scope.analysis.end = new Date();
$scope.doAnalysis();
};
$scope.chooseYesterday = function () {
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
$scope.analysis.begin = $scope.analysis.end = yesterday;
$scope.doAnalysis();
};
$scope.chooseLast7Days = function () {
$scope.analysis.end = new Date();
var day = new Date();
day.setDate(day.getDate() - 7);
$scope.analysis.begin = day;
$scope.doAnalysis();
};
$scope.thisMonth = function () {
$scope.analysis.end = new Date();
var monthBegin = new Date();
monthBegin.setDate(1);
$scope.analysis.begin = monthBegin;
$scope.doAnalysis();
};
$scope.doAnalysis = function () {
var params = angular.copy($scope.analysis);
if (params.begin) {
params.from = $filter('date')(params.begin, 'yyyyMMdd');
} else {
params.from = $filter('date')(new Date(), 'yyyyMMdd');
}
if (params.end) {
params.to = $filter('date')(params.end, 'yyyyMMdd');
} else {
params.to = $filter('date')(new Date(), 'yyyyMMdd');
}
$http.get('/sys/redpack/customer/'+$scope.act.act_id+'/sendLogs/analysis', {params: params}).then(function (resp) {
$scope.redPackCounts = angular.copy(resp.data);
var dates = [];
var send_counts = [];
var fail_counts = [];
var receive_counts = [];
var refund_counts = [];
var amounts = [];
var real_amounts = [];
resp.data.forEach(function (e) {
dates.push(e.date);
send_counts.push(e.send_counts);
fail_counts.push(e.fail_counts);
receive_counts.push(e.receive_counts);
refund_counts.push(e.refund_counts);
amounts.push(e.amount);
real_amounts.push(e.real_amount);
});
var customerRedPackSendLogsHistory = function (dates, send_counts, fail_counts, receive_counts, refund_counts, amounts, real_amounts) {
return {
color: colors,
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
legend: {
data: ['已领取', '发送未领取', '发送失败', '退回', '发送红包金额', '实际红包金额']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: dates
}
],
yAxis: [
{
type: 'value',
name: 'RedPackets'
}, {
type: 'value',
name: 'Amount(¥)'
}
],
series: [{
name: '已领取',
type: 'bar',
stack: 'repackets',
data: receive_counts
},
{
name: '发送未领取',
type: 'bar',
stack: 'repackets',
data: send_counts
},
{
name: '发送失败',
type: 'bar',
stack: 'repackets',
data: fail_counts
},
{
name: '退回',
type: 'bar',
stack: 'repackets',
data: refund_counts
},
{
name: '发送红包金额',
type: 'line',
yAxisIndex: 1,
data: amounts
},
{
name: '实际红包金额',
type: 'line',
yAxisIndex: 1,
data: real_amounts
}
]
};
};
$scope.customerRedPackSendLogsHistory = customerRedPackSendLogsHistory(dates, send_counts, fail_counts, receive_counts, refund_counts, amounts, real_amounts);
})
};
$scope.chooseLast7Days();
/* 《==========================================OrderList========================================================>*/
$scope.params = {};
$scope.redpack_order_pagination = {};
$scope.chooseTodayForLogs = function () {
$scope.params.begin = $scope.params.end = new Date();
$scope.listOrders(1);
};
$scope.chooseYesterdayForLogs = function () {
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
$scope.params.begin = $scope.params.end = yesterday;
$scope.listOrders(1);
};
$scope.chooseLast7DaysForLogs = function () {
$scope.params.end = new Date();
var day = new Date();
day.setDate(day.getDate() - 7);
$scope.params.begin = day;
$scope.listOrders(1);
};
$scope.thisMonthForLogs = function () {
$scope.params.end = new Date();
var monthBegin = new Date();
monthBegin.setDate(1);
$scope.params.begin = monthBegin;
$scope.listOrders(1);
};
$scope.customerLuckyMoneyAnalysis = function (params) {
$http.get('/sys/redpack/customer/act/' + $scope.act.act_id + '/analysis', {params: params}).then(function (resp) {
$scope.luckyMoneyAnalysis = resp.data;
});
};
$scope.customerLuckyMoneyAnalysis({});
$scope.listOrders = function (page) {
var params = angular.copy($scope.redpack_order_pagination);
params.page = page || params.page || 1;
var params = angular.copy($scope.params);
if (params.begin) {
params.from = $filter('date')(params.begin, 'yyyyMMdd');
}
if (params.end) {
params.to = $filter('date')(params.end, 'yyyyMMdd');
}
params.page = page || $scope.redpack_order_pagination.page || 1;
$http.get('/sys/redpack/customer/act/'+$scope.act.act_id, {params: params}).then(function (resp) {
$scope.redpack_order_pagination = resp.data.pagination;
$scope.orders = resp.data.data;
@ -94,6 +267,17 @@ define(['angular', 'static/commons/commons', 'uiBootstrap', 'uiRouter', 'ngBootS
};
$scope.listClients();
$scope.addAttendClient = function () {
$uibModal.open({
templateUrl: '/static/config/redpackets/templates/add_act_client.html',
controller: 'addClientInfoCtrl',
resolve: {
act: $scope.act
}
}).result.then(function () {
$scope.listClients();
})
};
$scope.editClientInfo = function (client) {
var client = angular.copy(client);
$uibModal.open({
@ -129,6 +313,18 @@ define(['angular', 'static/commons/commons', 'uiBootstrap', 'uiRouter', 'ngBootS
$scope.$close();
}
}]);
app.controller('addClientInfoCtrl',['$scope', '$http','act','commonDialog', function ($scope, $http,act,commonDialog) {
$scope.client = {act_name:act.act_name};
$scope.doAddClientInfo = function(){
var params= {'send_name':$scope.client.send_name,'act_name':$scope.client.act_name,'wishing':$scope.client.wishing};
$http.post('/sys/lucky_money/customer/acts/'+act.act_id+'/partners/'+$scope.client.client_moniker,params).then(function () {
commonDialog.alert({title: 'Success', content: '新增成功!', type: 'success'});
$scope.$close();
}, function (resp) {
commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'})
});
}
}]);
app.filter('send_status', function () {
return function (stateValue) {

@ -49,13 +49,20 @@
<p class="small text-info">红包限制:订单满足的最小金额</p>
</div>
</div>
<div class="form-group">
<div class="form-group" ng-if="act.rule_max_num_limit">
<label class="control-label col-sm-2">RedPacket Counts</label>
<div class="col-sm-10">
<p class="form-control-static" ng-bind="act.rule_max_num"></p>
<p class="small text-info">红包限制:每个客户每天最多所能获取的红包数量</p>
</div>
</div>
<div class="form-group" ng-if="!act.rule_max_num_limit">
<label class="control-label col-sm-2">RedPacket Counts</label>
<div class="col-sm-10">
<p class="form-control-static" ng-bind="act.rule_max_num"></p>
<p class="small text-info">红包限制:每个客户活动期间最多所能获取的红包数量</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Activity Status</label>
<div class="col-sm-10">

@ -53,8 +53,20 @@
</div>
</div>
</div>
<div class="form-group"
<div class="form-group">
<label class="control-label col-sm-2" for="rule_max_num-input">* RedPacket Counts Limit</label>
<div class="col-sm-8">
<label class="radio-inline">
<input type="radio" value="1" checked ng-model="act.rule_max_num_limit">
Day
</label>
<label class="radio-inline">
<input type="radio" value="0" ng-model="act.rule_max_num_limit">
Whole Activity
</label>
</div>
</div>
<div class="form-group" ng-if="act.rule_max_num_limit == 1"
ng-class="{'has-error':ActivityForm.rule_max_num.$invalid && ActivityForm.rule_max_num.$dirty}">
<label class="control-label col-sm-2" for="rule_max_num-input">* RedPacket
Counts</label>
@ -79,6 +91,31 @@
</div>
</div>
<div class="form-group" ng-if="act.rule_max_num_limit == 0"
ng-class="{'has-error':ActivityForm.rule_max_num.$invalid && ActivityForm.rule_max_num.$dirty}">
<label class="control-label col-sm-2" for="rule_max_num_day-input">* RedPacket
Counts</label>
<div class="col-sm-8">
<input type="number" name="rule_max_num" class="form-control"
ng-model="act.rule_max_num"
min="1" max="100" step="1"
id="rule_max_num_day-input" required>
<p class="small text-info">红包限制:每个客户活动内最多所能获取的红包数量</p>
<div ng-messages="act.rule_partner_max_num.$error"
ng-if="act.rule_max_num.$dirty">
<div class="small text-danger" ng-message="max">
<i class="glyphicon glyphicon-alert"></i> No more than 100
</div>
<div class="small text-danger" ng-message="min">
<i class="glyphicon glyphicon-alert"></i> No less than 1
</div>
<div class="small text-danger" ng-message="required">
<i class="glyphicon glyphicon-alert"></i> Required Field
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Activity Status</label>
<div class="col-sm-8 checkbox-inline">

@ -1,23 +1,35 @@
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Client</th>
<th>Send Name</th>
<th>Act Name</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="client in clients">
<td>{{client.short_name}}({{client.client_moniker}})</td>
<td ng-bind="client.send_name"></td>
<td ng-bind="client.act_name"></td>
<td>
<a role="button" ng-click="editClientInfo(client)"><i class="fa fa-cog"></i></a>
<a role="button" ng-click="deleteClient(client)" class="text-danger"><i class="fa fa-trash"></i></a>
</td>
</tr>
</tbody>
</table>
</div>
<div class="box box-warning">
<div class="box-header">
<div class="form-inline">
<div class="form-group">
<button class="btn btn-success" type="button" ng-click="addAttendClient()"><i class="fa fa-plus"></i> New Attend Partner</button>
</div>
</div>
</div>
</div>
<div class="box box-warning">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Client</th>
<th>Send Name</th>
<th>Act Name</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="client in clients">
<td>{{client.short_name}}({{client.client_moniker}})</td>
<td ng-bind="client.send_name"></td>
<td ng-bind="client.act_name"></td>
<td>
<a role="button" ng-click="editClientInfo(client)"><i class="fa fa-cog"></i></a>
<a role="button" ng-click="deleteClient(client)" class="text-danger"><i class="fa fa-trash"></i></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>

@ -1,37 +1,206 @@
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Client Moniker</th>
<th>status</th>
<th>Order Amount</th>
<th>Create Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="order in orders">
<td>{{order.client_moniker}}</td>
<td>{{order.status|send_status}}</td>
<td>{{order.order_amount}}</td>
<td>{{order.create_time}}</td>
</tr>
</tbody>
</table>
<div class="box box-warning">
<div class="box-header">
<div class="row">
<div class="col-sm-12">
<div class="form-horizontal">
<div class="form-group col-xs-12 col-sm-12">
<label class="control-label col-xs-4 col-sm-2">Date Range</label>
<div class="col-sm-10">
<div class="form-control-static form-inline">
<div style="display: inline-block">
<input class="form-control" id="date-from-input"
ng-model="analysis.begin"
uib-datepicker-popup size="10" placeholder="From"
is-open="analysis_dateBegin.open" ng-click="analysis_dateBegin.open=true"
datepicker-options="{maxDate:analysis.end||today}">
</div>
~
<div style="display: inline-block">
<input class="form-control" id="date-to-input" ng-model="analysis.end"
uib-datepicker-popup size="10" placeholder="To"
is-open="analysis_dateTo.open" ng-click="analysis_dateTo.open=true"
datepicker-options="{minDate:analysis.begin,maxDate:today}">
</div>
<div class="box-footer" ng-if="orders.length">
<uib-pagination class="pagination"
total-items="redpack_order_pagination.totalCount"
boundary-links="true"
ng-model="redpack_order_pagination.page"
items-per-page="redpack_order_pagination.limit"
max-size="10"
ng-change="listOrders()"
previous-text="&lsaquo;"
next-text="&rsaquo;"
first-text="&laquo;"
last-text="&raquo;"></uib-pagination>
<!--<div class="btn-group">-->
<!--<a role="button" class="btn btn-default btn-sm"-->
<!--ng-click="chooseToday()">Today</a>-->
<!--</div>-->
<!--<div class="btn-group">-->
<!--<a role="button" class="btn btn-default btn-sm"-->
<!--ng-click="chooseYesterday()">Yesterday</a>-->
<!--</div>-->
<div class="btn-group">
<a role="button" class="btn btn-default btn-sm"
ng-click="chooseLast7Days()">Last 7 Days</a>
</div>
<div class="btn-group">
<a role="button" class="btn btn-default btn-sm"
ng-click="thisMonth()">This Month</a>
</div>
<!--<div class="btn-group">-->
<!--<a role="button" class="btn btn-default btn-sm"-->
<!--ng-click="lastMonth()">Last Month</a>-->
<!--</div>-->
<!--<div class="btn-group">-->
<!--<a role="button" class="btn btn-default btn-sm"-->
<!--ng-click="thisYear()">This Year</a>-->
<!--</div>-->
<!--<div class="btn-group" uib-dropdown ng-if="currentUser.client.has_children">-->
<!--<button id="single-button" type="button" class="btn btn-primary"-->
<!--uib-dropdown-toggle ng-disabled="disabled">-->
<!--{{chooseShow}} <span class="caret"></span>-->
<!--</button>-->
<!--<ul class="dropdown-menu" uib-dropdown-menu aria-labelledby="single-button" style="min-width: 80px">-->
<!--<li><a ng-click="chooseClient('All')">All</a></li>-->
<!--<li ng-repeat="client in clients"><a ng-click="chooseClient(client)">{{client.short_name}}</a></li>-->
<!--</ul>-->
<!--</div>-->
<button class="btn btn-success" type="button"
ng-click="doAnalysis()">
<i class="fa fa-search"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="box">
<div class="box-body">
<div class="chart col-md-12" echarts="customerRedPackSendLogsHistory" style="height: 300px"
ng-class="{nodata:customerRedPackSendLogsHistory.nodata}"></div>
</div>
</div>
<div class="box box-warning">
<div class="box-header">
<div class="row">
<div class="col-xs-12">Total Records:{{redpack_order_pagination.totalCount}};Total Pages:{{redpack_order_pagination.totalPages}}</div>
<div class="col-sm-12">
<div class="form-horizontal">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-4" for="partner-search">Partner Name</label>
<div class="col-xs-12 col-sm-6">
<input type="text" class="form-control" id="partner-search"
ng-enter="listOrders(1)"
ng-model="params.short_name">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-4" for="code-search">Partner Code</label>
<div class="col-xs-12 col-sm-6">
<input type="text" class="form-control" id="code-search"
ng-enter="listOrders(1)"
ng-model="params.client_moniker">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-2 col-sm-4" for="sub-merchant-search">
<span ng-bind='act.channel'></span>
Nickname</label>
<div class="col-xs-12 col-sm-6">
<input type="text" class="form-control" id="sub-merchant-search"
ng-enter="listOrders(1)"
ng-model="params.nickname">
</div>
</div>
<div class="form-group col-xs-12 col-sm-12">
<label class="control-label col-xs-4 col-sm-2">Date Range</label>
<div class="col-sm-10">
<div class="form-control-static form-inline">
<div style="display: inline-block">
<input class="form-control" id="date-from-input-logs"
ng-model="params.begin"
uib-datepicker-popup size="10" placeholder="From"
is-open="dateBegin.open" ng-click="dateBegin.open=true"
datepicker-options="{maxDate:params.end||today}">
</div>
~
<div style="display: inline-block">
<input class="form-control" id="date-to-input-logs"
ng-model="params.end"
uib-datepicker-popup size="10" placeholder="To"
is-open="dateTo.open" ng-click="dateTo.open=true"
datepicker-options="{minDate:params.begin,maxDate:today}">
</div>
<div class="btn-group">
<a role="button" class="btn btn-default btn-sm"
ng-click="chooseTodayForLogs()">Today</a>
</div>
<div class="btn-group">
<a role="button" class="btn btn-default btn-sm"
ng-click="chooseYesterdayForLogs()">Yesterday</a>
</div>
<div class="btn-group">
<a role="button" class="btn btn-default btn-sm"
ng-click="chooseLast7DaysForLogs()">Last 7 Days</a>
</div>
<button class="btn btn-success" type="button"
ng-click="listOrders(1)">
<i class="fa fa-search"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
Orders<span style="font-size: smaller;color: grey">(总共红包{{luckyMoneyAnalysis.total_counts}}|{{luckyMoneyAnalysis.total_amount}}¥;
已发红包{{luckyMoneyAnalysis.send_counts}}|{{luckyMoneyAnalysis.send_amount}}¥;客户所得红包{{luckyMoneyAnalysis.receive_counts}}|{{luckyMoneyAnalysis.receive_amount}}¥
待发送红包{{luckyMoneyAnalysis.unsend_counts}}|{{luckyMoneyAnalysis.unsend_amount}}¥)</span></div>
<div class="panel-body">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Client Moniker</th>
<th>Lucky Money</th>
<th>Order Amount</th>
<th>Nick Name</th>
<th>status</th>
<th>Event Time</th>
<th>Create Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="order in orders">
<td>{{order.client_moniker}}</td>
<td>{{order.red_packet_amount}}</td>
<td>{{order.order_amount}}</td>
<td><span><img style="height: 30px;width: 30px" class="img-circle"
ng-src="{{order.headimg}}"> {{order.nickname}}</span></td>
<td>{{order.status|send_status}}</td>
<td>{{order.event_time}}</td>
<td>{{order.create_time}}</td>
</tr>
</tbody>
</table>
<div class="box-footer" ng-if="orders.length">
<uib-pagination class="pagination"
total-items="redpack_order_pagination.totalCount"
boundary-links="true"
ng-model="redpack_order_pagination.page"
items-per-page="redpack_order_pagination.limit"
max-size="10"
ng-change="listOrders()"
previous-text="&lsaquo;"
next-text="&rsaquo;"
first-text="&laquo;"
last-text="&raquo;"></uib-pagination>
<div class="row">
<div class="col-xs-12">Total Records:{{redpack_order_pagination.totalCount}};Total Pages:{{redpack_order_pagination.totalPages}}</div>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,51 @@
<div class="modal-header">
<h4>Edit Client{{client.act_id}}</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-12">
<form name="clientForm" novalidate>
<label class="control-label col-sm-6" for="act-name-input">Partner Code</label>
<div class="col-sm-6">
<input class="form-control" ng-model="client.client_moniker"
type="text"
name="act_name"
id="client_moniker-input">
</div>
<div class="form-group"
ng-class="{'has-error':clientForm.client_moniker.$invalid && clientForm.client_moniker.$dirty}">
<label class="control-label col-sm-6" for="send-name-input">Send Name</label>
<div class="col-sm-6">
<input class="form-control" ng-model="client.send_name"
type="text"
name="send_name"
id="send-name-input">
</div>
<label class="control-label col-sm-6" for="act-name-input">Act Name</label>
<div class="col-sm-6">
<input class="form-control" ng-model="client.act_name"
type="text"
name="act_name"
id="act-name-input">
</div>
<label class="control-label col-sm-6" for="wishing-input">Wishing</label>
<div class="col-sm-6">
<input class="form-control" ng-model="client.wishing"
type="text"
name="wishing"
id="wishing-input">
</div>
</div>
</form>
</div>
<div class="col-sm-12">
<div class="alert alert-danger" ng-if="errmsg" ng-bind="errmsg"></div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" ng-click="$dismiss()">Cancel</button>
<button type="button" class="btn btn-success" ng-click="doAddClientInfo()">save</button>
</div>
Loading…
Cancel
Save