You've already forked FrameTour-BE
refactor(statistics): 切换数据查询服务并优化扫码统计功能
- 将 BrokerBiz 和 OrderBiz 中的数据查询从 StatisticsMapper 切换到 StatsQueryService - 更新 StatisticsServiceImpl 使用 StatsQueryService 进行数据查询 - 添加订单数据合并功能到扫码统计图表中 - 重构扫码统计查询逻辑以支持统计数据和订单数据的合并显示 - 新增按小时和按日期统计订单数据的查询方法 - 优化 SQL 查询以分离统计数据和订单数据的查询逻辑
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package com.ycwl.basic.biz;
|
package com.ycwl.basic.biz;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.ycwl.basic.clickhouse.service.StatsQueryService;
|
||||||
import com.ycwl.basic.mapper.BrokerMapper;
|
import com.ycwl.basic.mapper.BrokerMapper;
|
||||||
import com.ycwl.basic.mapper.BrokerRecordMapper;
|
import com.ycwl.basic.mapper.BrokerRecordMapper;
|
||||||
import com.ycwl.basic.mapper.StatisticsMapper;
|
import com.ycwl.basic.mapper.StatisticsMapper;
|
||||||
@@ -34,7 +35,7 @@ public class BrokerBiz {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ScenicRepository scenicRepository;
|
private ScenicRepository scenicRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private StatisticsMapper statisticsMapper;
|
private StatsQueryService statsQueryService;
|
||||||
|
|
||||||
public void processOrder(Long orderId) {
|
public void processOrder(Long orderId) {
|
||||||
log.info("开始处理订单分佣,订单ID:{}", orderId);
|
log.info("开始处理订单分佣,订单ID:{}", orderId);
|
||||||
@@ -52,7 +53,7 @@ public class BrokerBiz {
|
|||||||
if (scenicConfig.getInteger("sample_store_day") != null) {
|
if (scenicConfig.getInteger("sample_store_day") != null) {
|
||||||
expireDay = scenicConfig.getInteger("sample_store_day");
|
expireDay = scenicConfig.getInteger("sample_store_day");
|
||||||
}
|
}
|
||||||
List<Long> brokerIdList = statisticsMapper.getBrokerIdListForUser(order.getMemberId(), DateUtil.offsetDay(DateUtil.beginOfDay(order.getCreateAt()), -expireDay), order.getCreateAt());
|
List<Long> brokerIdList = statsQueryService.getBrokerIdListForUser(order.getMemberId(), DateUtil.offsetDay(DateUtil.beginOfDay(order.getCreateAt()), -expireDay), order.getCreateAt());
|
||||||
if (brokerIdList == null || brokerIdList.isEmpty()) {
|
if (brokerIdList == null || brokerIdList.isEmpty()) {
|
||||||
log.info("用户与推客无关,订单ID:{}", orderId);
|
log.info("用户与推客无关,订单ID:{}", orderId);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ycwl.basic.biz;
|
package com.ycwl.basic.biz;
|
||||||
|
|
||||||
|
import com.ycwl.basic.clickhouse.service.StatsQueryService;
|
||||||
import com.ycwl.basic.enums.StatisticEnum;
|
import com.ycwl.basic.enums.StatisticEnum;
|
||||||
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
|
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
|
||||||
import com.ycwl.basic.mapper.OrderMapper;
|
import com.ycwl.basic.mapper.OrderMapper;
|
||||||
@@ -66,6 +67,8 @@ public class OrderBiz {
|
|||||||
private PrinterService printerService;
|
private PrinterService printerService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IPriceCalculationService iPriceCalculationService;
|
private IPriceCalculationService iPriceCalculationService;
|
||||||
|
@Autowired
|
||||||
|
private StatsQueryService statsQueryService;
|
||||||
|
|
||||||
public PriceObj queryPrice(Long scenicId, Long memberId, int goodsType, Long goodsId) {
|
public PriceObj queryPrice(Long scenicId, Long memberId, int goodsType, Long goodsId) {
|
||||||
PriceObj priceObj = new PriceObj();
|
PriceObj priceObj = new PriceObj();
|
||||||
@@ -254,7 +257,7 @@ public class OrderBiz {
|
|||||||
orderRepository.clearOrderCache(orderId); // 更新完了,清理下
|
orderRepository.clearOrderCache(orderId); // 更新完了,清理下
|
||||||
StatisticsRecordAddReq statisticsRecordAddReq = new StatisticsRecordAddReq();
|
StatisticsRecordAddReq statisticsRecordAddReq = new StatisticsRecordAddReq();
|
||||||
statisticsRecordAddReq.setMemberId(order.getMemberId());
|
statisticsRecordAddReq.setMemberId(order.getMemberId());
|
||||||
Long enterType = statisticsMapper.getUserRecentEnterType(order.getMemberId(), order.getCreateAt());
|
Long enterType = statsQueryService.getUserRecentEnterType(order.getMemberId(), order.getCreateAt());
|
||||||
if(!Long.valueOf(1014).equals(enterType)){//
|
if(!Long.valueOf(1014).equals(enterType)){//
|
||||||
statisticsRecordAddReq.setType(StatisticEnum.ON_SITE_PAYMENT.code);
|
statisticsRecordAddReq.setType(StatisticEnum.ON_SITE_PAYMENT.code);
|
||||||
}else {
|
}else {
|
||||||
|
|||||||
@@ -79,12 +79,14 @@ public interface StatsQueryService {
|
|||||||
List<HashMap<String, Object>> getDailyScanStats(Long brokerId, Date startTime, Date endTime);
|
List<HashMap<String, Object>> getDailyScanStats(Long brokerId, Date startTime, Date endTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按小时统计扫码人数
|
* 按小时统计扫码人数(仅返回统计数据,不含订单)
|
||||||
|
* 返回格式: [{t: "MM-dd HH", count: "xxx"}, ...]
|
||||||
*/
|
*/
|
||||||
List<HashMap<String, String>> scanCodeMemberChartByHour(CommonQueryReq query);
|
List<HashMap<String, String>> scanCodeMemberChartByHour(CommonQueryReq query);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按日期统计扫码人数
|
* 按日期统计扫码人数(仅返回统计数据,不含订单)
|
||||||
|
* 返回格式: [{t: "MM-dd", count: "xxx"}, ...]
|
||||||
*/
|
*/
|
||||||
List<HashMap<String, String>> scanCodeMemberChartByDate(CommonQueryReq query);
|
List<HashMap<String, String>> scanCodeMemberChartByDate(CommonQueryReq query);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,10 +105,26 @@ public interface StatisticsMapper {
|
|||||||
|
|
||||||
List<HashMap<String, String>> orderChartByHour(CommonQueryReq query);
|
List<HashMap<String, String>> orderChartByHour(CommonQueryReq query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按小时统计扫码人数(仅统计数据,不含订单)
|
||||||
|
*/
|
||||||
List<HashMap<String, String>> scanCodeMemberChartByHour(CommonQueryReq query);
|
List<HashMap<String, String>> scanCodeMemberChartByHour(CommonQueryReq query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按日期统计扫码人数(仅统计数据,不含订单)
|
||||||
|
*/
|
||||||
List<HashMap<String, String>> scanCodeMemberChartByDate(CommonQueryReq query);
|
List<HashMap<String, String>> scanCodeMemberChartByDate(CommonQueryReq query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按小时统计订单数据
|
||||||
|
*/
|
||||||
|
List<HashMap<String, String>> orderChartByHourForMerge(CommonQueryReq query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按日期统计订单数据
|
||||||
|
*/
|
||||||
|
List<HashMap<String, String>> orderChartByDateForMerge(CommonQueryReq query);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计分销员扫码次数
|
* 统计分销员扫码次数
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ycwl.basic.service.pc.impl;
|
package com.ycwl.basic.service.pc.impl;
|
||||||
|
|
||||||
|
import com.ycwl.basic.clickhouse.service.StatsQueryService;
|
||||||
import com.ycwl.basic.mapper.StatisticsMapper;
|
import com.ycwl.basic.mapper.StatisticsMapper;
|
||||||
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
|
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
|
||||||
import com.ycwl.basic.model.pc.statistics.resp.OrderStatisticsResp;
|
import com.ycwl.basic.model.pc.statistics.resp.OrderStatisticsResp;
|
||||||
@@ -13,6 +14,8 @@ import java.time.temporal.ChronoUnit;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author:longbinbin
|
* @Author:longbinbin
|
||||||
@@ -21,17 +24,11 @@ import java.util.List;
|
|||||||
@Service
|
@Service
|
||||||
public class StatisticsServiceImpl implements StatisticsService {
|
public class StatisticsServiceImpl implements StatisticsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StatsQueryService statsQueryService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private StatisticsMapper statisticsMapper;
|
private StatisticsMapper statisticsMapper;
|
||||||
|
|
||||||
List<HashMap<String, String>> getScanCodeMemberChartByHour(CommonQueryReq query) {
|
|
||||||
return statisticsMapper.scanCodeMemberChartByHour(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<HashMap<String, String>> getScanCodeMemberChartByDate(CommonQueryReq query) {
|
|
||||||
return statisticsMapper.scanCodeMemberChartByDate(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HashMap<String, String>> getScanCodeMemberChartAuto(CommonQueryReq query) {
|
public List<HashMap<String, String>> getScanCodeMemberChartAuto(CommonQueryReq query) {
|
||||||
// 检查时间范围
|
// 检查时间范围
|
||||||
@@ -76,6 +73,68 @@ public class StatisticsServiceImpl implements StatisticsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按小时统计扫码人数(合并统计数据和订单数据)
|
||||||
|
*/
|
||||||
|
private List<HashMap<String, String>> getScanCodeMemberChartByHour(CommonQueryReq query) {
|
||||||
|
// 1. 从 StatsQueryService 获取统计数据(根据配置走 ClickHouse 或 MySQL)
|
||||||
|
List<HashMap<String, String>> statsData = statsQueryService.scanCodeMemberChartByHour(query);
|
||||||
|
|
||||||
|
// 2. 从 MySQL 获取订单数据
|
||||||
|
List<HashMap<String, String>> orderData = statisticsMapper.orderChartByHourForMerge(query);
|
||||||
|
|
||||||
|
// 3. 合并数据
|
||||||
|
return mergeChartData(statsData, orderData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按日期统计扫码人数(合并统计数据和订单数据)
|
||||||
|
*/
|
||||||
|
private List<HashMap<String, String>> getScanCodeMemberChartByDate(CommonQueryReq query) {
|
||||||
|
// 1. 从 StatsQueryService 获取统计数据(根据配置走 ClickHouse 或 MySQL)
|
||||||
|
List<HashMap<String, String>> statsData = statsQueryService.scanCodeMemberChartByDate(query);
|
||||||
|
|
||||||
|
// 2. 从 MySQL 获取订单数据
|
||||||
|
List<HashMap<String, String>> orderData = statisticsMapper.orderChartByDateForMerge(query);
|
||||||
|
|
||||||
|
// 3. 合并数据
|
||||||
|
return mergeChartData(statsData, orderData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合并统计数据和订单数据
|
||||||
|
* 统计数据包含: t, count
|
||||||
|
* 订单数据包含: t, orderCount, orderAmount
|
||||||
|
* 合并结果: t, count, orderCount, orderAmount
|
||||||
|
*/
|
||||||
|
private List<HashMap<String, String>> mergeChartData(
|
||||||
|
List<HashMap<String, String>> statsData,
|
||||||
|
List<HashMap<String, String>> orderData) {
|
||||||
|
|
||||||
|
// 将订单数据转为 Map 以便快速查找
|
||||||
|
Map<String, HashMap<String, String>> orderMap = orderData.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
m -> m.get("t"),
|
||||||
|
m -> m,
|
||||||
|
(existing, replacement) -> existing
|
||||||
|
));
|
||||||
|
|
||||||
|
// 合并数据
|
||||||
|
for (HashMap<String, String> stat : statsData) {
|
||||||
|
String timeKey = stat.get("t");
|
||||||
|
HashMap<String, String> order = orderMap.get(timeKey);
|
||||||
|
if (order != null) {
|
||||||
|
stat.put("orderCount", order.get("orderCount"));
|
||||||
|
stat.put("orderAmount", order.get("orderAmount"));
|
||||||
|
} else {
|
||||||
|
stat.put("orderCount", "0");
|
||||||
|
stat.put("orderAmount", "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return statsData;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OrderStatisticsResp getOrderStatistics(CommonQueryReq query) {
|
public OrderStatisticsResp getOrderStatistics(CommonQueryReq query) {
|
||||||
// 时间参数兜底与规范化
|
// 时间参数兜底与规范化
|
||||||
|
|||||||
@@ -398,9 +398,7 @@
|
|||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
hour_series.HOUR as t,
|
hour_series.HOUR as t,
|
||||||
COALESCE(scan_data.member_count, 0) AS count,
|
COALESCE(scan_data.member_count, 0) AS count
|
||||||
COALESCE(order_data.order_count, 0) AS orderCount,
|
|
||||||
COALESCE(order_data.order_amount, 0) AS orderAmount
|
|
||||||
FROM hour_series
|
FROM hour_series
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT
|
SELECT
|
||||||
@@ -420,19 +418,6 @@
|
|||||||
AND s.create_time BETWEEN #{startTime} AND #{endTime}
|
AND s.create_time BETWEEN #{startTime} AND #{endTime}
|
||||||
GROUP BY DATE_FORMAT(s.create_time, '%m-%d %H')
|
GROUP BY DATE_FORMAT(s.create_time, '%m-%d %H')
|
||||||
) scan_data ON scan_data.hour_key = hour_series.HOUR
|
) scan_data ON scan_data.hour_key = hour_series.HOUR
|
||||||
LEFT JOIN (
|
|
||||||
SELECT
|
|
||||||
DATE_FORMAT(create_at, '%m-%d %H') AS hour_key,
|
|
||||||
COUNT(id) AS order_count,
|
|
||||||
SUM(pay_price) AS order_amount
|
|
||||||
FROM `order`
|
|
||||||
WHERE (status = 1 OR status = 2)
|
|
||||||
<if test="scenicId != null">
|
|
||||||
AND scenic_id = #{scenicId}
|
|
||||||
</if>
|
|
||||||
AND create_at BETWEEN #{startTime} AND #{endTime}
|
|
||||||
GROUP BY DATE_FORMAT(create_at, '%m-%d %H')
|
|
||||||
) order_data ON order_data.hour_key = hour_series.HOUR
|
|
||||||
ORDER BY hour_series.hour_time
|
ORDER BY hour_series.hour_time
|
||||||
</select>
|
</select>
|
||||||
<select id="scanCodeMemberChartByDate" resultType="java.util.HashMap">
|
<select id="scanCodeMemberChartByDate" resultType="java.util.HashMap">
|
||||||
@@ -449,9 +434,7 @@
|
|||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
date_series.DATE_KEY as t,
|
date_series.DATE_KEY as t,
|
||||||
COALESCE(scan_data.member_count, 0) AS count,
|
COALESCE(scan_data.member_count, 0) AS count
|
||||||
COALESCE(order_data.order_count, 0) AS orderCount,
|
|
||||||
COALESCE(order_data.order_amount, 0) AS orderAmount
|
|
||||||
FROM date_series
|
FROM date_series
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT
|
SELECT
|
||||||
@@ -471,6 +454,57 @@
|
|||||||
AND s.create_time BETWEEN #{startTime} AND #{endTime}
|
AND s.create_time BETWEEN #{startTime} AND #{endTime}
|
||||||
GROUP BY DATE_FORMAT(s.create_time, '%m-%d')
|
GROUP BY DATE_FORMAT(s.create_time, '%m-%d')
|
||||||
) scan_data ON scan_data.date_key = date_series.DATE_KEY
|
) scan_data ON scan_data.date_key = date_series.DATE_KEY
|
||||||
|
ORDER BY date_series.date_value
|
||||||
|
</select>
|
||||||
|
<select id="orderChartByHourForMerge" resultType="java.util.HashMap">
|
||||||
|
WITH RECURSIVE hour_series AS (
|
||||||
|
SELECT
|
||||||
|
#{startTime} AS hour_time,
|
||||||
|
DATE_FORMAT(#{startTime}, '%m-%d %H') AS HOUR
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
DATE_ADD(hour_time, INTERVAL 1 HOUR) AS hour_time,
|
||||||
|
DATE_FORMAT(DATE_ADD(hour_time, INTERVAL 1 HOUR), '%m-%d %H') AS HOUR
|
||||||
|
FROM hour_series
|
||||||
|
WHERE DATE_ADD(hour_time, INTERVAL 1 HOUR) <= #{endTime}
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
hour_series.HOUR as t,
|
||||||
|
COALESCE(order_data.order_count, 0) AS orderCount,
|
||||||
|
COALESCE(order_data.order_amount, 0) AS orderAmount
|
||||||
|
FROM hour_series
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT
|
||||||
|
DATE_FORMAT(create_at, '%m-%d %H') AS hour_key,
|
||||||
|
COUNT(id) AS order_count,
|
||||||
|
SUM(pay_price) AS order_amount
|
||||||
|
FROM `order`
|
||||||
|
WHERE (status = 1 OR status = 2)
|
||||||
|
<if test="scenicId != null">
|
||||||
|
AND scenic_id = #{scenicId}
|
||||||
|
</if>
|
||||||
|
AND create_at BETWEEN #{startTime} AND #{endTime}
|
||||||
|
GROUP BY DATE_FORMAT(create_at, '%m-%d %H')
|
||||||
|
) order_data ON order_data.hour_key = hour_series.HOUR
|
||||||
|
ORDER BY hour_series.hour_time
|
||||||
|
</select>
|
||||||
|
<select id="orderChartByDateForMerge" resultType="java.util.HashMap">
|
||||||
|
WITH RECURSIVE date_series AS (
|
||||||
|
SELECT
|
||||||
|
DATE(#{startTime}) AS date_value,
|
||||||
|
DATE_FORMAT(#{startTime}, '%m-%d') AS DATE_KEY
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
DATE_ADD(date_value, INTERVAL 1 DAY) AS date_value,
|
||||||
|
DATE_FORMAT(DATE_ADD(date_value, INTERVAL 1 DAY), '%m-%d') AS DATE_KEY
|
||||||
|
FROM date_series
|
||||||
|
WHERE DATE_ADD(date_value, INTERVAL 1 DAY) <= DATE(#{endTime})
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
date_series.DATE_KEY as t,
|
||||||
|
COALESCE(order_data.order_count, 0) AS orderCount,
|
||||||
|
COALESCE(order_data.order_amount, 0) AS orderAmount
|
||||||
|
FROM date_series
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT
|
SELECT
|
||||||
DATE_FORMAT(create_at, '%m-%d') AS date_key,
|
DATE_FORMAT(create_at, '%m-%d') AS date_key,
|
||||||
|
|||||||
Reference in New Issue
Block a user