|
|
|
@ -8,29 +8,38 @@ import au.com.royalpay.payment.manage.mappers.log.WechatTemplateMsgSendLogMapper
|
|
|
|
|
import au.com.royalpay.payment.manage.mappers.payment.OrderMapper;
|
|
|
|
|
import au.com.royalpay.payment.manage.mappers.system.ClientAccountMapper;
|
|
|
|
|
import au.com.royalpay.payment.manage.mappers.system.ClientMapper;
|
|
|
|
|
import au.com.royalpay.payment.manage.mappers.system.CustomerMapper;
|
|
|
|
|
import au.com.royalpay.payment.manage.mappers.system.ManagerCustomerRelationAlipayMapper;
|
|
|
|
|
import au.com.royalpay.payment.manage.merchants.core.ClientManager;
|
|
|
|
|
import au.com.royalpay.payment.manage.tradelog.beans.TradeLogQuery;
|
|
|
|
|
import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApi;
|
|
|
|
|
import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApiProvider;
|
|
|
|
|
import au.com.royalpay.payment.tools.connections.mpsupport.beans.TemplateMessage;
|
|
|
|
|
import au.com.royalpay.payment.tools.env.PlatformEnvironment;
|
|
|
|
|
import au.com.royalpay.payment.tools.utils.PageListUtils;
|
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
import com.github.miemiedev.mybatis.paginator.domain.Order;
|
|
|
|
|
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
|
|
|
|
|
import com.github.miemiedev.mybatis.paginator.domain.PageList;
|
|
|
|
|
import com.maxmind.geoip.LookupService;
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
|
|
|
|
import org.apache.commons.lang3.time.DateUtils;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.math.RoundingMode;
|
|
|
|
|
import java.text.DateFormat;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Created by yishuqian on 10/11/2016.
|
|
|
|
@ -51,6 +60,10 @@ public class CustomersAnalysisServiceImp implements CustomersAnalysisService {
|
|
|
|
|
private ClientMapper clientMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ClientAccountMapper clientAccountMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private CustomerMapper customerMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ManagerCustomerRelationAlipayMapper managerCustomerRelationAlipayMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private WechatTemplateMsgSendLogMapper wechatTemplateMsgSendLogMapper;
|
|
|
|
@ -60,6 +73,8 @@ public class CustomersAnalysisServiceImp implements CustomersAnalysisService {
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private RetailAppService retailAppService;
|
|
|
|
|
@Resource
|
|
|
|
|
private LookupService lookupService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<JSONObject> getCustomersAnalysis(JSONObject params) {
|
|
|
|
@ -95,6 +110,11 @@ public class CustomersAnalysisServiceImp implements CustomersAnalysisService {
|
|
|
|
|
@Override
|
|
|
|
|
public JSONObject getCustomersRanking(JSONObject params, int page, int limit) {
|
|
|
|
|
PageList<JSONObject> logs = orderAnalysisMapper.listCustomersData(params, new PageBounds(page, limit, Order.formString("amount.desc")));
|
|
|
|
|
if (logs.size() > 0) {
|
|
|
|
|
for (JSONObject log : logs) {
|
|
|
|
|
generatorUserProfile(log, params);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
JSONObject result = PageListUtils.buildPageListResult(logs);
|
|
|
|
|
result.put("analysis", orderAnalysisMapper.listCustomersDataAnalysis(params));
|
|
|
|
|
result.put("openid_type", params.getIntValue("openid_type"));
|
|
|
|
@ -224,6 +244,63 @@ public class CustomersAnalysisServiceImp implements CustomersAnalysisService {
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public JSONObject getUserEcharts(JSONObject params, JSONObject manager) {
|
|
|
|
|
JSONObject graph = new JSONObject();
|
|
|
|
|
List<JSONObject> nodes = new ArrayList<>();
|
|
|
|
|
List<JSONObject> links = new ArrayList<>();
|
|
|
|
|
initUserInfo(nodes, params);
|
|
|
|
|
List<JSONObject> clients = orderAnalysisMapper.listClientsByCustomerId(params);
|
|
|
|
|
JSONObject total = orderAnalysisMapper.listClientsTotalByCustomerId(params);
|
|
|
|
|
int id = 1;
|
|
|
|
|
for (JSONObject client : clients) {
|
|
|
|
|
BigDecimal clientInTotal = client.getBigDecimal("orders").divide(total.getBigDecimal("orders"), 5, RoundingMode.HALF_UP).multiply(new BigDecimal(300));
|
|
|
|
|
BigDecimal orderInTotal = client.getBigDecimal("orders").divide(total.getBigDecimal("orders"), 5, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
|
|
|
|
|
BigDecimal amountInTotal = client.getBigDecimal("total_amount").divide(total.getBigDecimal("total_amount"), 5, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
|
|
|
|
|
JSONObject node = new JSONObject();
|
|
|
|
|
node.put("id", id);
|
|
|
|
|
node.put("category", id);
|
|
|
|
|
node.put("name", client.getString("client_moniker"));
|
|
|
|
|
node.put("label", client.getString("short_name"));
|
|
|
|
|
node.put("value", client.getString("short_name"));
|
|
|
|
|
node.put("symbolSize", clientInTotal.compareTo(new BigDecimal(10))<0?10:clientInTotal.toPlainString());
|
|
|
|
|
if (clientInTotal.compareTo(new BigDecimal(300)) == 0) {
|
|
|
|
|
node.put("symbolSize", 100);
|
|
|
|
|
}
|
|
|
|
|
node.put("ignore", true);
|
|
|
|
|
node.put("flag", true);
|
|
|
|
|
node.put("draggable", true);
|
|
|
|
|
nodes.add(node);
|
|
|
|
|
JSONObject totalAmountInfo = getClientAmountInfo(id,"x0", "交易金额", client);
|
|
|
|
|
totalAmountInfo.put("label", client.getString("total_amount"));
|
|
|
|
|
totalAmountInfo.put("value", client.getBigDecimal("total_amount").setScale(2,RoundingMode.HALF_UP));
|
|
|
|
|
totalAmountInfo.put("symbolSize",amountInTotal.compareTo(new BigDecimal(10))<0?10:amountInTotal.toPlainString());
|
|
|
|
|
nodes.add(totalAmountInfo);
|
|
|
|
|
JSONObject OrdersInfo = getClientAmountInfo(id,"x1", "订单数", client);
|
|
|
|
|
OrdersInfo.put("label", client.getString("orders"));
|
|
|
|
|
OrdersInfo.put("value", client.getString("orders"));
|
|
|
|
|
OrdersInfo.put("symbolSize", orderInTotal.compareTo(new BigDecimal(10))<0?10:orderInTotal.toPlainString());
|
|
|
|
|
nodes.add(OrdersInfo);
|
|
|
|
|
JSONObject priceInfo = getClientAmountInfo(id,"x2", "客单价", client);
|
|
|
|
|
BigDecimal price = client.getBigDecimal("total_amount").divide(client.getBigDecimal("orders"), 2, RoundingMode.HALF_UP);
|
|
|
|
|
priceInfo.put("label", price.toPlainString());
|
|
|
|
|
priceInfo.put("value", price.toPlainString());
|
|
|
|
|
priceInfo.put("symbolSize", price.divide(new BigDecimal(50), 0, RoundingMode.DOWN).compareTo(new BigDecimal(10))<0?5:price.divide(new BigDecimal(50), 0, RoundingMode.DOWN).toPlainString());
|
|
|
|
|
nodes.add(priceInfo);
|
|
|
|
|
id++;
|
|
|
|
|
}
|
|
|
|
|
for (JSONObject node : nodes) {
|
|
|
|
|
JSONObject link = new JSONObject();
|
|
|
|
|
String linkId = node.getString("id");
|
|
|
|
|
link.put("source", linkId);
|
|
|
|
|
link.put("target", linkId.indexOf("x")>0?linkId.substring(0,linkId.indexOf("x")):0);
|
|
|
|
|
links.add(link);
|
|
|
|
|
}
|
|
|
|
|
graph.put("nodes", nodes);
|
|
|
|
|
graph.put("links", links);
|
|
|
|
|
return graph;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int setAllClientIds(JSONObject params, int clientId) {
|
|
|
|
|
JSONArray client_ids = clientManager.getAllClientIds(clientId);
|
|
|
|
|
if (client_ids.size() > 1) {
|
|
|
|
@ -268,6 +345,89 @@ public class CustomersAnalysisServiceImp implements CustomersAnalysisService {
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initUserInfo(List<JSONObject> nodes, JSONObject params) {
|
|
|
|
|
JSONObject userInfo = new JSONObject();
|
|
|
|
|
if (params.getString("customer_id").startsWith("o")) {
|
|
|
|
|
userInfo = customerMapper.findCustomerByOpenId(params.getString("customer_id"));
|
|
|
|
|
} else {
|
|
|
|
|
userInfo = managerCustomerRelationAlipayMapper.findCustomerByUserId(params.getString("customer_id"));
|
|
|
|
|
}
|
|
|
|
|
JSONObject user = new JSONObject();
|
|
|
|
|
user.put("id", 0);
|
|
|
|
|
user.put("category", 0);
|
|
|
|
|
if (userInfo.size() > 0) {
|
|
|
|
|
user.put("name", userInfo.getString("nickname"));
|
|
|
|
|
} else {
|
|
|
|
|
user.put("name", params.getString("customer_id"));
|
|
|
|
|
}
|
|
|
|
|
user.put("symbolSize", 80);
|
|
|
|
|
user.put("ignore", true);
|
|
|
|
|
user.put("flag", true);
|
|
|
|
|
user.put("draggable", true);
|
|
|
|
|
String imgUrl = StringUtils.isNotBlank(userInfo.getString("headimg")) ? userInfo.getString("headimg") : PlatformEnvironment.getEnv().concatUrl("/static/images/r_logo.svg");
|
|
|
|
|
user.put("symbol", "image://" + imgUrl);
|
|
|
|
|
nodes.add(user);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private JSONObject getClientAmountInfo(int oldId, String newId, String name, JSONObject client) {
|
|
|
|
|
JSONObject amountInfo = new JSONObject();
|
|
|
|
|
amountInfo.put("ignore", true);
|
|
|
|
|
amountInfo.put("flag", true);
|
|
|
|
|
amountInfo.put("draggable", true);
|
|
|
|
|
amountInfo.put("id", String.valueOf(oldId) + newId);
|
|
|
|
|
amountInfo.put("name", name);
|
|
|
|
|
return amountInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void generatorUserProfile(JSONObject customer, JSONObject params) {
|
|
|
|
|
List<String> topAddress = new ArrayList<>();
|
|
|
|
|
String topAmountRange = "None";
|
|
|
|
|
String topTimeRange = "None";
|
|
|
|
|
params.put("customer_id", customer.getString("customer_id"));
|
|
|
|
|
List<JSONObject> mostUseClientsByCustomer = orderAnalysisMapper.mostUseClientsByCustomer(params);
|
|
|
|
|
List<JSONObject> mostUseIndustryByCustomer = orderAnalysisMapper.mostUseIndustryByCustomer(params);
|
|
|
|
|
List<JSONObject> mostUseAddressByCustomer = orderAnalysisMapper.mostUseAddressByCustomer(params);
|
|
|
|
|
for (JSONObject address : mostUseAddressByCustomer) {
|
|
|
|
|
String city = lookupService.getLocation(address.getString("customer_ip")).city;
|
|
|
|
|
if (topAddress.size() < 3 && !topAddress.contains(city)) {
|
|
|
|
|
topAddress.add(city);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
JSONObject mostUseAmountByCustomer = orderAnalysisMapper.mostUseAmountByCustomer(params);
|
|
|
|
|
if (mostUseAmountByCustomer != null) {
|
|
|
|
|
int amount = mostUseAmountByCustomer.getIntValue("amount_int");
|
|
|
|
|
if (amount == 0) {
|
|
|
|
|
topAmountRange = "0~100";
|
|
|
|
|
}else {
|
|
|
|
|
topAmountRange = String.valueOf(amount * 100) + "~" + String.valueOf((amount + 1) * 100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
JSONObject mostUseTimesByCustomer = orderAnalysisMapper.mostUseTimesByCustomer(params);
|
|
|
|
|
if (mostUseTimesByCustomer != null) {
|
|
|
|
|
Date orderDate = mostUseTimesByCustomer.getDate("create_time");
|
|
|
|
|
Date nextHourDate = DateUtils.addHours(orderDate, 1);
|
|
|
|
|
orderDate = DateUtils.setMinutes(orderDate, 0);
|
|
|
|
|
nextHourDate = DateUtils.setMinutes(nextHourDate, 0);
|
|
|
|
|
topTimeRange = DateFormatUtils.format(orderDate, "HH:mm") + "-" + DateFormatUtils.format(nextHourDate, "HH:mm");
|
|
|
|
|
}
|
|
|
|
|
customer.put("top_clients", getTopInfo(mostUseClientsByCustomer, "client_moniker"));
|
|
|
|
|
customer.put("top_industry", getTopInfo(mostUseIndustryByCustomer, "royalpayindustry"));
|
|
|
|
|
customer.put("top_citys", String.join(",", topAddress));
|
|
|
|
|
customer.put("amount_range", topAmountRange);
|
|
|
|
|
customer.put("hour_range", topTimeRange);
|
|
|
|
|
customer.put("price", customer.getBigDecimal("amount").divide(customer.getBigDecimal("orders"), 2, RoundingMode.HALF_UP).toPlainString());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String getTopInfo(List<JSONObject> list, String key) {
|
|
|
|
|
if (list != null && list.size() > 0) {
|
|
|
|
|
List<String> clients = list.stream().map(e -> e.getString(key)).collect(Collectors.toList());
|
|
|
|
|
return String.join(",", clients);
|
|
|
|
|
}
|
|
|
|
|
return "None";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// private TemplateMessage initWxMsg(JSONObject tradeInfo,String short_name,String clientCounts, String openId, String templateId,String path,String color) {
|
|
|
|
|
//
|
|
|
|
|