feat(database): 迁移统计数据查询到ClickHouse

- 添加ClickHouse数据源配置和相关依赖
- 实现ClickHouse统计查询服务和MySQL兜底方案
- 新增扫码统计、订单统计等数据查询接口
- 重构分销员数据统计逻辑,整合MySQL和ClickHouse数据源
- 更新应用配置文件以支持ClickHouse启用开关
- 修改分布式任务统计以支持跨库查询场景
This commit is contained in:
2026-01-04 10:34:17 +08:00
parent 32297dc29c
commit aec5e57df7
19 changed files with 944 additions and 20 deletions

View File

@@ -0,0 +1,95 @@
package com.ycwl.basic.clickhouse.mapper;
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* ClickHouse 统计数据 Mapper
* 用于查询 t_stats 和 t_stats_record 表
*/
@Mapper
public interface ClickHouseStatsMapper {
/**
* 统计预览视频人数
*/
Integer countPreviewVideoOfMember(CommonQueryReq query);
/**
* 统计扫码访问人数
*/
Integer countScanCodeOfMember(CommonQueryReq query);
/**
* 统计推送订阅人数
*/
Integer countPushOfMember(CommonQueryReq query);
/**
* 统计上传头像人数
*/
Integer countUploadFaceOfMember(CommonQueryReq query);
/**
* 统计生成视频人数
* 注意:需要关联 MySQL 中的 task 表,此处只返回 face_id 列表
*/
List<String> listFaceIdsWithUpload(CommonQueryReq query);
/**
* 统计总访问人数
*/
Integer countTotalVisitorOfMember(CommonQueryReq query);
/**
* 统计预览视频条数
*/
Integer countPreviewOfVideo(CommonQueryReq query);
/**
* 获取用户分销员 ID 列表
*/
List<Long> getBrokerIdListForUser(@Param("memberId") Long memberId,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
/**
* 获取用户最近进入类型
*/
Long getUserRecentEnterType(@Param("memberId") Long memberId,
@Param("endTime") Date endTime);
/**
* 获取用户项目 ID 列表
*/
List<Long> getProjectIdListForUser(@Param("memberId") Long memberId,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
/**
* 统计分销员扫码次数
*/
Integer countBrokerScanCount(@Param("brokerId") Long brokerId);
/**
* 按日期统计分销员扫码数据(用于 BrokerRecordMapper.getDailySummaryByBrokerId)
*/
List<HashMap<String, Object>> getDailyScanStats(@Param("brokerId") Long brokerId,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
/**
* 按小时统计扫码人数
*/
List<HashMap<String, String>> scanCodeMemberChartByHour(CommonQueryReq query);
/**
* 按日期统计扫码人数
*/
List<HashMap<String, String>> scanCodeMemberChartByDate(CommonQueryReq query);
}

View File

@@ -0,0 +1,90 @@
package com.ycwl.basic.clickhouse.service;
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* 统计数据查询服务接口
* 用于抽象 t_stats 和 t_stats_record 表的查询
* 支持 MySQL 和 ClickHouse 两种实现
*/
public interface StatsQueryService {
/**
* 统计预览视频人数
*/
Integer countPreviewVideoOfMember(CommonQueryReq query);
/**
* 统计扫码访问人数
*/
Integer countScanCodeOfMember(CommonQueryReq query);
/**
* 统计推送订阅人数
*/
Integer countPushOfMember(CommonQueryReq query);
/**
* 统计上传头像人数
*/
Integer countUploadFaceOfMember(CommonQueryReq query);
/**
* 统计生成视频人数
*/
Integer countCompleteVideoOfMember(CommonQueryReq query);
/**
* 统计生成视频条数
*/
Integer countCompleteOfVideo(CommonQueryReq query);
/**
* 统计总访问人数
*/
Integer countTotalVisitorOfMember(CommonQueryReq query);
/**
* 统计预览视频条数
*/
Integer countPreviewOfVideo(CommonQueryReq query);
/**
* 获取用户分销员 ID 列表
*/
List<Long> getBrokerIdListForUser(Long memberId, Date startTime, Date endTime);
/**
* 获取用户最近进入类型
*/
Long getUserRecentEnterType(Long memberId, Date endTime);
/**
* 获取用户项目 ID 列表
*/
List<Long> getProjectIdListForUser(Long memberId, Date startTime, Date endTime);
/**
* 统计分销员扫码次数
*/
Integer countBrokerScanCount(Long brokerId);
/**
* 按日期统计分销员扫码数据
*/
List<HashMap<String, Object>> getDailyScanStats(Long brokerId, Date startTime, Date endTime);
/**
* 按小时统计扫码人数
*/
List<HashMap<String, String>> scanCodeMemberChartByHour(CommonQueryReq query);
/**
* 按日期统计扫码人数
*/
List<HashMap<String, String>> scanCodeMemberChartByDate(CommonQueryReq query);
}

View File

@@ -0,0 +1,118 @@
package com.ycwl.basic.clickhouse.service.impl;
import com.ycwl.basic.clickhouse.mapper.ClickHouseStatsMapper;
import com.ycwl.basic.clickhouse.service.StatsQueryService;
import com.ycwl.basic.mapper.TaskMapper;
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* ClickHouse 统计数据查询服务实现
* 当 clickhouse.enabled=true 时启用
*/
@Slf4j
@Service
@ConditionalOnProperty(prefix = "clickhouse", name = "enabled", havingValue = "true")
public class ClickHouseStatsQueryServiceImpl implements StatsQueryService {
@Autowired
private ClickHouseStatsMapper clickHouseStatsMapper;
@Autowired
private TaskMapper taskMapper;
@Override
public Integer countPreviewVideoOfMember(CommonQueryReq query) {
return clickHouseStatsMapper.countPreviewVideoOfMember(query);
}
@Override
public Integer countScanCodeOfMember(CommonQueryReq query) {
return clickHouseStatsMapper.countScanCodeOfMember(query);
}
@Override
public Integer countPushOfMember(CommonQueryReq query) {
return clickHouseStatsMapper.countPushOfMember(query);
}
@Override
public Integer countUploadFaceOfMember(CommonQueryReq query) {
return clickHouseStatsMapper.countUploadFaceOfMember(query);
}
@Override
public Integer countCompleteVideoOfMember(CommonQueryReq query) {
// 从 ClickHouse 获取 face_id 列表,然后在 MySQL 中查询完成的任务
List<String> faceIds = clickHouseStatsMapper.listFaceIdsWithUpload(query);
if (faceIds == null || faceIds.isEmpty()) {
return 0;
}
// 在 MySQL 中统计已完成任务的用户数
return taskMapper.countCompletedTaskMembersByFaceIds(faceIds);
}
@Override
public Integer countCompleteOfVideo(CommonQueryReq query) {
// 从 ClickHouse 获取 face_id 列表,然后在 MySQL 中查询完成的任务数
List<String> faceIds = clickHouseStatsMapper.listFaceIdsWithUpload(query);
if (faceIds == null || faceIds.isEmpty()) {
return 0;
}
// 在 MySQL 中统计已完成的任务数
return taskMapper.countCompletedTasksByFaceIds(faceIds);
}
@Override
public Integer countTotalVisitorOfMember(CommonQueryReq query) {
return clickHouseStatsMapper.countTotalVisitorOfMember(query);
}
@Override
public Integer countPreviewOfVideo(CommonQueryReq query) {
return clickHouseStatsMapper.countPreviewOfVideo(query);
}
@Override
public List<Long> getBrokerIdListForUser(Long memberId, Date startTime, Date endTime) {
return clickHouseStatsMapper.getBrokerIdListForUser(memberId, startTime, endTime);
}
@Override
public Long getUserRecentEnterType(Long memberId, Date endTime) {
return clickHouseStatsMapper.getUserRecentEnterType(memberId, endTime);
}
@Override
public List<Long> getProjectIdListForUser(Long memberId, Date startTime, Date endTime) {
return clickHouseStatsMapper.getProjectIdListForUser(memberId, startTime, endTime);
}
@Override
public Integer countBrokerScanCount(Long brokerId) {
return clickHouseStatsMapper.countBrokerScanCount(brokerId);
}
@Override
public List<HashMap<String, Object>> getDailyScanStats(Long brokerId, Date startTime, Date endTime) {
return clickHouseStatsMapper.getDailyScanStats(brokerId, startTime, endTime);
}
@Override
public List<HashMap<String, String>> scanCodeMemberChartByHour(CommonQueryReq query) {
return clickHouseStatsMapper.scanCodeMemberChartByHour(query);
}
@Override
public List<HashMap<String, String>> scanCodeMemberChartByDate(CommonQueryReq query) {
return clickHouseStatsMapper.scanCodeMemberChartByDate(query);
}
}

View File

@@ -0,0 +1,101 @@
package com.ycwl.basic.clickhouse.service.impl;
import com.ycwl.basic.clickhouse.service.StatsQueryService;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* MySQL 统计数据查询服务实现
* 当 clickhouse.enabled 未启用时使用此实现(兜底)
*/
@Slf4j
@Service
@ConditionalOnProperty(prefix = "clickhouse", name = "enabled", havingValue = "false", matchIfMissing = true)
public class MySqlStatsQueryServiceImpl implements StatsQueryService {
@Autowired
private StatisticsMapper statisticsMapper;
@Override
public Integer countPreviewVideoOfMember(CommonQueryReq query) {
return statisticsMapper.countPreviewVideoOfMember(query);
}
@Override
public Integer countScanCodeOfMember(CommonQueryReq query) {
return statisticsMapper.countScanCodeOfMember(query);
}
@Override
public Integer countPushOfMember(CommonQueryReq query) {
return statisticsMapper.countPushOfMember(query);
}
@Override
public Integer countUploadFaceOfMember(CommonQueryReq query) {
return statisticsMapper.countUploadFaceOfMember(query);
}
@Override
public Integer countCompleteVideoOfMember(CommonQueryReq query) {
return statisticsMapper.countCompleteVideoOfMember(query);
}
@Override
public Integer countCompleteOfVideo(CommonQueryReq query) {
return statisticsMapper.countCompleteOfVideo(query);
}
@Override
public Integer countTotalVisitorOfMember(CommonQueryReq query) {
return statisticsMapper.countTotalVisitorOfMember(query);
}
@Override
public Integer countPreviewOfVideo(CommonQueryReq query) {
return statisticsMapper.countPreviewOfVideo(query);
}
@Override
public List<Long> getBrokerIdListForUser(Long memberId, Date startTime, Date endTime) {
return statisticsMapper.getBrokerIdListForUser(memberId, startTime, endTime);
}
@Override
public Long getUserRecentEnterType(Long memberId, Date endTime) {
return statisticsMapper.getUserRecentEnterType(memberId, endTime);
}
@Override
public List<Long> getProjectIdListForUser(Long memberId, Date startTime, Date endTime) {
return statisticsMapper.getProjectIdListForUser(memberId, startTime, endTime);
}
@Override
public Integer countBrokerScanCount(Long brokerId) {
return statisticsMapper.countBrokerScanCount(brokerId);
}
@Override
public List<HashMap<String, Object>> getDailyScanStats(Long brokerId, Date startTime, Date endTime) {
return statisticsMapper.getDailyScanStats(brokerId, startTime, endTime);
}
@Override
public List<HashMap<String, String>> scanCodeMemberChartByHour(CommonQueryReq query) {
return statisticsMapper.scanCodeMemberChartByHour(query);
}
@Override
public List<HashMap<String, String>> scanCodeMemberChartByDate(CommonQueryReq query) {
return statisticsMapper.scanCodeMemberChartByDate(query);
}
}

View File

@@ -0,0 +1,56 @@
package com.ycwl.basic.config;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
/**
* ClickHouse 数据源配置
* 用于 t_stats 和 t_stats_record 表的查询
*/
@Configuration
@ConditionalOnProperty(prefix = "clickhouse", name = "enabled", havingValue = "true")
@MapperScan(
basePackages = "com.ycwl.basic.clickhouse.mapper",
sqlSessionFactoryRef = "clickHouseSqlSessionFactory"
)
public class ClickHouseDataSourceConfig {
@Bean(name = "clickHouseDataSource")
@ConfigurationProperties(prefix = "clickhouse.datasource")
public DataSource clickHouseDataSource() {
return new HikariDataSource();
}
@Bean(name = "clickHouseSqlSessionFactory")
public SqlSessionFactory clickHouseSqlSessionFactory(
@Qualifier("clickHouseDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/clickhouse/*.xml")
);
// 配置 MyBatis 设置
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
configuration.setMapUnderscoreToCamelCase(true);
factoryBean.setConfiguration(configuration);
return factoryBean.getObject();
}
@Bean(name = "clickHouseSqlSessionTemplate")
public SqlSessionTemplate clickHouseSqlSessionTemplate(
@Qualifier("clickHouseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}

View File

@@ -6,7 +6,10 @@ import com.ycwl.basic.model.pc.broker.resp.BrokerRecordRespVO;
import com.ycwl.basic.model.pc.broker.resp.DailySummaryRespVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
@@ -28,4 +31,11 @@ public interface BrokerRecordMapper {
int update(BrokerRecord brokerRecord);
List<DailySummaryRespVO> getDailySummaryByBrokerId(Long brokerId, Date startTime, Date endTime);
/**
* 按日期统计分销员订单数据(不含扫码统计,已迁移到 ClickHouse)
*/
List<HashMap<String, Object>> getDailyOrderStats(@Param("brokerId") Long brokerId,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
}

View File

@@ -4,6 +4,7 @@ import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq;
import com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.Date;
@@ -108,6 +109,18 @@ public interface StatisticsMapper {
List<HashMap<String, String>> scanCodeMemberChartByDate(CommonQueryReq query);
/**
* 统计分销员扫码次数
*/
Integer countBrokerScanCount(Long brokerId);
/**
* 按日期统计分销员扫码数据
*/
List<HashMap<String, Object>> getDailyScanStats(@Param("brokerId") Long brokerId,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
/**
* 统计订单数量和金额(包含推送订单和现场订单)
* @param query

View File

@@ -59,4 +59,16 @@ public interface TaskMapper {
List<TaskEntity> selectAllFailed();
TaskEntity listLastFaceTemplateTask(Long faceId, Long templateId);
/**
* 根据 face_id 列表统计已完成任务的用户数
* 用于 ClickHouse 迁移后的跨库统计
*/
Integer countCompletedTaskMembersByFaceIds(@Param("faceIds") List<String> faceIds);
/**
* 根据 face_id 列表统计已完成任务数
* 用于 ClickHouse 迁移后的跨库统计
*/
Integer countCompletedTasksByFaceIds(@Param("faceIds") List<String> faceIds);
}

View File

@@ -3,6 +3,7 @@ package com.ycwl.basic.service.mobile.impl;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.ycwl.basic.clickhouse.service.StatsQueryService;
import com.ycwl.basic.utils.JacksonUtil;
import com.ycwl.basic.enums.StatisticEnum;
import com.ycwl.basic.mapper.StatisticsMapper;
@@ -41,6 +42,9 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
@Autowired
private StatisticsMapper statisticsMapper;
@Autowired
private StatsQueryService statsQueryService;
/**
* 支付订单金额、预览_支付转化率、扫码_付费用户转化率
@@ -210,19 +214,19 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
// Integer cameraShotOfMemberNum=statisticsMapper.countCameraShotOfMember(query);
//扫码访问人数
// 扫小程序码或景区码进入访问的用户数,包括授权用户(使用OpenID进行精准统计)和未授权用户(使用 UUID统计访问)。但当用户授权时,获取OpenID并与UUID关联,删除本地UUID,避免重复记录。
Integer scanCodeVisitorOfMemberNum=statisticsMapper.countScanCodeOfMember(query);
Integer scanCodeVisitorOfMemberNum=statsQueryService.countScanCodeOfMember(query);
//上传头像(人脸)人数
// 上传了人脸的用户数(包括本地临时ID和获取到OpenID的,同一设备微信获取到OpenID要覆盖掉之前生成的临时ID),上传多张人脸都只算一个人。
Integer uploadFaceOfMemberNum=statisticsMapper.countUploadFaceOfMember(query);
Integer uploadFaceOfMemberNum=statsQueryService.countUploadFaceOfMember(query);
//推送订阅人数
// 只要点了允许通知,哪怕只勾选1条订阅都算
Integer pushOfMemberNum =statisticsMapper.countPushOfMember(query);
Integer pushOfMemberNum =statsQueryService.countPushOfMember(query);
//生成视频人数
// 生成过Vlog视频的用户ID数,要注意屏蔽掉以前没有片段也能生成的情况
Integer completeVideoOfMemberNum =statisticsMapper.countCompleteVideoOfMember(query);
Integer completeVideoOfMemberNum =statsQueryService.countCompleteVideoOfMember(query);
//预览视频人数
// 购买前播放了5秒的视频条数。
Integer previewVideoOfMemberNum =statisticsMapper.countPreviewVideoOfMember(query);
Integer previewVideoOfMemberNum =statsQueryService.countPreviewVideoOfMember(query);
if (previewVideoOfMemberNum==null){
previewVideoOfMemberNum=0;
}
@@ -233,13 +237,13 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
Integer payOfMemberNum =statisticsMapper.countPayOfMember(query);
//总访问人数
// 通过任何途径访问到小程序的总人数,包括授权用户和未授权用户。
Integer totalVisitorOfMemberNum =statisticsMapper.countTotalVisitorOfMember(query);
Integer totalVisitorOfMemberNum =statsQueryService.countTotalVisitorOfMember(query);
// Integer totalVisitorOfMemberNum =scanCodeVisitorOfMemberNum;
//生成视频条数
// 仅指代生成的Vlog条数,不包含录像原片。
Integer completeOfVideoNum =statisticsMapper.countCompleteOfVideo(query);
Integer completeOfVideoNum =statsQueryService.countCompleteOfVideo(query);
//预览视频条数
Integer previewOfVideoNum =statisticsMapper.countPreviewOfVideo(query);
Integer previewOfVideoNum =statsQueryService.countPreviewOfVideo(query);
//支付订单数
Integer payOfOrderNum =statisticsMapper.countPayOfOrder(query);
//支付订单金额

View File

@@ -1,7 +1,9 @@
package com.ycwl.basic.service.pc.impl;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.clickhouse.service.StatsQueryService;
import com.ycwl.basic.mapper.BrokerRecordMapper;
import com.ycwl.basic.model.pc.broker.entity.BrokerRecord;
import com.ycwl.basic.model.pc.broker.req.BrokerRecordReqQuery;
@@ -11,8 +13,9 @@ import com.ycwl.basic.service.pc.BrokerRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Author:longbinbin
@@ -22,6 +25,8 @@ import java.util.List;
public class BrokerRecordServiceImpl implements BrokerRecordService {
@Autowired
private BrokerRecordMapper brokerRecordMapper;
@Autowired
private StatsQueryService statsQueryService;
@Override
public PageInfo<BrokerRecordRespVO> pageQuery(BrokerRecordReqQuery brokerRecordReqQuery) {
@@ -58,7 +63,52 @@ public class BrokerRecordServiceImpl implements BrokerRecordService {
@Override
public List<DailySummaryRespVO> getDailySummaryByBrokerId(Long brokerId, Date startTime, Date endTime) {
return brokerRecordMapper.getDailySummaryByBrokerId(brokerId, startTime, endTime);
// 从 MySQL 获取订单数据
List<HashMap<String, Object>> orderStats = brokerRecordMapper.getDailyOrderStats(brokerId, startTime, endTime);
// 从 ClickHouse/MySQL 获取扫码数据
List<HashMap<String, Object>> scanStats = statsQueryService.getDailyScanStats(brokerId, startTime, endTime);
// 将扫码数据转换为 Map 便于查找
Map<String, Long> scanCountByDate = new HashMap<>();
if (scanStats != null) {
for (HashMap<String, Object> stat : scanStats) {
Object dateObj = stat.get("date");
String dateKey = dateObj != null ? DateUtil.formatDate((Date) dateObj) : null;
Object scanCountObj = stat.get("scanCount");
Long scanCount = scanCountObj != null ? ((Number) scanCountObj).longValue() : 0L;
if (dateKey != null) {
scanCountByDate.put(dateKey, scanCount);
}
}
}
// 合并数据
List<DailySummaryRespVO> result = new ArrayList<>();
for (HashMap<String, Object> orderStat : orderStats) {
DailySummaryRespVO vo = new DailySummaryRespVO();
Object dateObj = orderStat.get("date");
if (dateObj instanceof Date) {
vo.setDate((Date) dateObj);
}
String dateKey = dateObj != null ? DateUtil.formatDate((Date) dateObj) : null;
vo.setScanCount(scanCountByDate.getOrDefault(dateKey, 0L));
Object orderCountObj = orderStat.get("orderCount");
vo.setOrderCount(orderCountObj != null ? ((Number) orderCountObj).longValue() : 0L);
Object totalOrderPriceObj = orderStat.get("totalOrderPrice");
vo.setTotalOrderPrice(totalOrderPriceObj != null ? new BigDecimal(totalOrderPriceObj.toString()) : BigDecimal.ZERO);
Object totalBrokerPriceObj = orderStat.get("totalBrokerPrice");
vo.setTotalBrokerPrice(totalBrokerPriceObj != null ? new BigDecimal(totalBrokerPriceObj.toString()) : BigDecimal.ZERO);
result.add(vo);
}
return result;
}
}

View File

@@ -2,6 +2,7 @@ package com.ycwl.basic.service.pc.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.clickhouse.service.StatsQueryService;
import com.ycwl.basic.mapper.BrokerMapper;
import com.ycwl.basic.model.pc.broker.entity.BrokerEntity;
import com.ycwl.basic.model.pc.broker.req.BrokerReqQuery;
@@ -27,12 +28,14 @@ public class BrokerServiceImpl implements BrokerService {
private BrokerMapper brokerMapper;
@Autowired
private ScenicRepository scenicRepository;
@Autowired
private StatsQueryService statsQueryService;
@Override
public PageInfo<BrokerRespVO> pageQuery(BrokerReqQuery brokerReqQuery) {
PageHelper.startPage(brokerReqQuery.getPageNum(),brokerReqQuery.getPageSize());
List<BrokerRespVO> list = brokerMapper.list(brokerReqQuery);
// 批量获取景区名称
List<Long> scenicIds = list.stream()
.map(BrokerRespVO::getScenicId)
@@ -40,14 +43,17 @@ public class BrokerServiceImpl implements BrokerService {
.distinct()
.collect(Collectors.toList());
Map<Long, String> scenicNames = scenicRepository.batchGetScenicNames(scenicIds);
// 设置景区名称
// 设置景区名称和扫码次数
list.forEach(item -> {
if (item.getScenicId() != null) {
item.setScenicName(scenicNames.get(item.getScenicId()));
}
// 从 ClickHouse/MySQL 查询分销员扫码次数
Integer scanCount = statsQueryService.countBrokerScanCount(item.getId());
item.setBrokerScanCount(scanCount != null ? scanCount.longValue() : 0L);
});
PageInfo<BrokerRespVO> pageInfo = new PageInfo(list);
return pageInfo;
}
@@ -55,7 +61,7 @@ public class BrokerServiceImpl implements BrokerService {
@Override
public List<BrokerRespVO> list(BrokerReqQuery brokerReqQuery) {
List<BrokerRespVO> list = brokerMapper.list(brokerReqQuery);
// 批量获取景区名称
List<Long> scenicIds = list.stream()
.map(BrokerRespVO::getScenicId)
@@ -63,14 +69,17 @@ public class BrokerServiceImpl implements BrokerService {
.distinct()
.collect(Collectors.toList());
Map<Long, String> scenicNames = scenicRepository.batchGetScenicNames(scenicIds);
// 设置景区名称
// 设置景区名称和扫码次数
list.forEach(item -> {
if (item.getScenicId() != null) {
item.setScenicName(scenicNames.get(item.getScenicId()));
}
// 从 ClickHouse/MySQL 查询分销员扫码次数
Integer scanCount = statsQueryService.countBrokerScanCount(item.getId());
item.setBrokerScanCount(scanCount != null ? scanCount.longValue() : 0L);
});
return list;
}