缓存统计信息

This commit is contained in:
2025-06-04 11:02:52 +08:00
parent 1841e43b85
commit 3bd8face68
8 changed files with 281 additions and 121 deletions

View File

@ -18,6 +18,7 @@ public class CommonQueryReq {
private Integer standard; private Integer standard;
@ApiModelProperty(value = "景区id") @ApiModelProperty(value = "景区id")
private Long scenicId; private Long scenicId;
private boolean realtime;
private Date startTime; private Date startTime;
private Date endTime; private Date endTime;
} }

View File

@ -111,10 +111,22 @@ public class AppStatisticsFunnelVO {
.divide(new BigDecimal(clickOnPayOfMemberNum), 2, RoundingMode.HALF_UP) .divide(new BigDecimal(clickOnPayOfMemberNum), 2, RoundingMode.HALF_UP)
.toString(); .toString();
} }
public BigDecimal payOfOrderAmount() {
return payOfOrderAmount;
}
public String getPayOfOrderAmount() { public String getPayOfOrderAmount() {
if (payOfOrderAmount == null) {
return "0.00";
}
return payOfOrderAmount.toString(); return payOfOrderAmount.toString();
} }
public BigDecimal refundOfOrderAmount() {
return refundOfOrderAmount;
}
public String getRefundOfOrderAmount() { public String getRefundOfOrderAmount() {
if (refundOfOrderAmount == null) {
return "0.00";
}
return refundOfOrderAmount.toString(); return refundOfOrderAmount.toString();
} }
} }

View File

@ -2,6 +2,8 @@ package com.ycwl.basic.service.mobile.impl;
import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ycwl.basic.enums.StatisticEnum; import com.ycwl.basic.enums.StatisticEnum;
import com.ycwl.basic.mapper.StatisticsMapper; import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.model.jwt.JwtInfo; import com.ycwl.basic.model.jwt.JwtInfo;
@ -11,17 +13,22 @@ import com.ycwl.basic.model.mobile.statistic.resp.AppSta1VO;
import com.ycwl.basic.model.mobile.statistic.resp.AppSta2VO; import com.ycwl.basic.model.mobile.statistic.resp.AppSta2VO;
import com.ycwl.basic.model.mobile.statistic.resp.AppSta3VO; import com.ycwl.basic.model.mobile.statistic.resp.AppSta3VO;
import com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO; import com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO;
import com.ycwl.basic.model.pc.scenicDeviceStats.resp.ScenicDeviceStatsResp;
import com.ycwl.basic.service.mobile.AppStatisticsService; import com.ycwl.basic.service.mobile.AppStatisticsService;
import com.ycwl.basic.utils.ApiResponse; import com.ycwl.basic.utils.ApiResponse;
import com.ycwl.basic.utils.JwtTokenUtil; import com.ycwl.basic.utils.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/** /**
* @Authorlongbinbin * @Authorlongbinbin
@ -56,11 +63,13 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
standardToNewSpecificTime(query); standardToNewSpecificTime(query);
//查询处理数据逻辑 //查询处理数据逻辑
oneStatisticsHandler(1,query,vo); oneStatisticsHandler(1,query,vo);
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
//---------------------------------------------------- //----------------------------------------------------
//获取上一个周期的具体时间范围 //获取上一个周期的具体时间范围
standardToPreviousSpecificTime(query); standardToPreviousSpecificTime(query);
//查询处理数据逻辑 //查询处理数据逻辑
oneStatisticsHandler(2,query,vo); oneStatisticsHandler(2,query,vo);
}
}else{ }else{
//自定义时间查询,只有当前数据,没有往期对比数据 //自定义时间查询,只有当前数据,没有往期对比数据
//查询处理数据逻辑 //查询处理数据逻辑
@ -82,11 +91,13 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
standardToNewSpecificTime(query); standardToNewSpecificTime(query);
//查询处理数据逻辑 //查询处理数据逻辑
twoStatisticsHandler(1,query,vo); twoStatisticsHandler(1,query,vo);
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
//---------------------------------------------------- //----------------------------------------------------
//获取当前周期的具体时间范围 //获取当前周期的具体时间范围
standardToPreviousSpecificTime(query); standardToPreviousSpecificTime(query);
//查询处理数据逻辑 //查询处理数据逻辑
twoStatisticsHandler(2,query,vo); twoStatisticsHandler(2, query, vo);
}
}else{ }else{
//自定义时间查询,只有当前数据,没有往期对比数据 //自定义时间查询,只有当前数据,没有往期对比数据
//查询处理数据逻辑 //查询处理数据逻辑
@ -108,11 +119,13 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
standardToNewSpecificTime(query); standardToNewSpecificTime(query);
//查询处理数据逻辑 //查询处理数据逻辑
freeStatisticsHandler(1,query,vo); freeStatisticsHandler(1,query,vo);
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
//---------------------------------------------------- //----------------------------------------------------
//获取当前周期的具体时间范围 //获取当前周期的具体时间范围
standardToPreviousSpecificTime(query); standardToPreviousSpecificTime(query);
//查询处理数据逻辑 //查询处理数据逻辑
freeStatisticsHandler(2,query,vo); freeStatisticsHandler(2, query, vo);
}
}else{ }else{
//自定义时间查询,只有当前数据,没有往期对比数据 //自定义时间查询,只有当前数据,没有往期对比数据
//查询处理数据逻辑 //查询处理数据逻辑
@ -121,8 +134,13 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
return ApiResponse.success(vo); return ApiResponse.success(vo);
} }
@Autowired
private RedisTemplate<String, String> redisTemplate;
private ReentrantLock lock = new ReentrantLock();
@Override @Override
public ApiResponse<AppStatisticsFunnelVO> userConversionFunnel(CommonQueryReq query) { public ApiResponse<AppStatisticsFunnelVO> userConversionFunnel(CommonQueryReq query) {
String redisKey = "statistics:tmp_cache:"+query.getScenicId();
AppStatisticsFunnelVO vo = new AppStatisticsFunnelVO(); AppStatisticsFunnelVO vo = new AppStatisticsFunnelVO();
if(query.getEndTime()==null && query.getStartTime()==null){ if(query.getEndTime()==null && query.getStartTime()==null){
// 没有传时间则代表用户没有自定义查询时间使用standard来判断查询时间范围 // 没有传时间则代表用户没有自定义查询时间使用standard来判断查询时间范围
@ -133,11 +151,62 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
//获取当前周期的具体时间范围 //获取当前周期的具体时间范围
standardToNewSpecificTime(query); standardToNewSpecificTime(query);
} }
if (!query.isRealtime()) {
if (!(DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday()))) {
// 查询缓存数据
List<AppStatisticsFunnelVO> list = statisticsMapper.listStatByScenic(query.getScenicId(), query.getStartTime(), query.getEndTime());
AppStatisticsFunnelVO resp = new AppStatisticsFunnelVO();
if (list != null && !list.isEmpty()) {
for (AppStatisticsFunnelVO item : list) {
// Integer fields
resp.setCameraShotOfMemberNum(addIntSafely(resp.getCameraShotOfMemberNum(), item.getCameraShotOfMemberNum()));
resp.setScanCodeVisitorOfMemberNum(addIntSafely(resp.getScanCodeVisitorOfMemberNum(), item.getScanCodeVisitorOfMemberNum()));
resp.setUploadFaceOfMemberNum(addIntSafely(resp.getUploadFaceOfMemberNum(), item.getUploadFaceOfMemberNum()));
resp.setPushOfMemberNum(addIntSafely(resp.getPushOfMemberNum(), item.getPushOfMemberNum()));
resp.setCompleteVideoOfMemberNum(addIntSafely(resp.getCompleteVideoOfMemberNum(), item.getCompleteVideoOfMemberNum()));
resp.setPreviewVideoOfMemberNum(addIntSafely(resp.getPreviewVideoOfMemberNum(), item.getPreviewVideoOfMemberNum()));
resp.setClickOnPayOfMemberNum(addIntSafely(resp.getClickOnPayOfMemberNum(), item.getClickOnPayOfMemberNum()));
resp.setPayOfMemberNum(addIntSafely(resp.getPayOfMemberNum(), item.getPayOfMemberNum()));
resp.setTotalVisitorOfMemberNum(addIntSafely(resp.getTotalVisitorOfMemberNum(), item.getTotalVisitorOfMemberNum()));
resp.setCompleteOfVideoNum(addIntSafely(resp.getCompleteOfVideoNum(), item.getCompleteOfVideoNum()));
resp.setPreviewOfVideoNum(addIntSafely(resp.getPreviewOfVideoNum(), item.getPreviewOfVideoNum()));
resp.setPayOfOrderNum(addIntSafely(resp.getPayOfOrderNum(), item.getPayOfOrderNum()));
resp.setRefundOfOrderNum(addIntSafely(resp.getRefundOfOrderNum(), item.getRefundOfOrderNum()));
// BigDecimal fields
resp.setPayOfOrderAmount(addBigDecimalSafely(resp.payOfOrderAmount(), item.payOfOrderAmount()));
resp.setRefundOfOrderAmount(addBigDecimalSafely(resp.refundOfOrderAmount(), item.refundOfOrderAmount()));
}
}
return ApiResponse.success(resp);
}
}
if (!query.isRealtime()) {
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
// 缓存
if (redisTemplate.hasKey(redisKey)) {
String s = redisTemplate.opsForValue().get(redisKey);
JSONObject cacheObj = JSON.parseObject(s);
return ApiResponse.success(cacheObj.toJavaObject(AppStatisticsFunnelVO.class));
}
}
}
lock.lock();
try {
// 缓存
if (!query.isRealtime()) {
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
// 缓存
if (redisTemplate.hasKey(redisKey)) {
String s = redisTemplate.opsForValue().get(redisKey);
JSONObject cacheObj = JSON.parseObject(s);
return ApiResponse.success(cacheObj.toJavaObject(AppStatisticsFunnelVO.class));
}
}
}
//镜头检测游客数 //镜头检测游客数
Integer cameraShotOfMemberNum=statisticsMapper.countCameraShotOfMember(query); // Integer cameraShotOfMemberNum=statisticsMapper.countCameraShotOfMember(query);
//扫码访问人数 //扫码访问人数
// 扫小程序码或景区码进入访问的用户数包括授权用户使用OpenID进行精准统计和未授权用户(使用 UUID统计访问)。但当用户授权时获取OpenID并与UUID关联删除本地UUID避免重复记录。 // 扫小程序码或景区码进入访问的用户数包括授权用户使用OpenID进行精准统计和未授权用户(使用 UUID统计访问)。但当用户授权时获取OpenID并与UUID关联删除本地UUID避免重复记录。
Integer scanCodeVisitorOfMemberNum=statisticsMapper.countScanCodeOfMember(query); Integer scanCodeVisitorOfMemberNum=statisticsMapper.countScanCodeOfMember(query);
@ -187,9 +256,6 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
vo.setClickOnPayOfMemberNum(clickOnPayOfMemberNum); vo.setClickOnPayOfMemberNum(clickOnPayOfMemberNum);
vo.setPayOfMemberNum(payOfMemberNum); vo.setPayOfMemberNum(payOfMemberNum);
//转化率格式
DecimalFormat df = new DecimalFormat("0.0");
vo.setTotalVisitorOfMemberNum(totalVisitorOfMemberNum); vo.setTotalVisitorOfMemberNum(totalVisitorOfMemberNum);
vo.setCompleteOfVideoNum(completeOfVideoNum); vo.setCompleteOfVideoNum(completeOfVideoNum);
vo.setPreviewOfVideoNum(previewOfVideoNum); vo.setPreviewOfVideoNum(previewOfVideoNum);
@ -197,8 +263,26 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
vo.setPayOfOrderAmount(payOfOrderAmount.setScale(2, RoundingMode.HALF_UP)); vo.setPayOfOrderAmount(payOfOrderAmount.setScale(2, RoundingMode.HALF_UP));
vo.setRefundOfOrderNum(refundOfOrderNum); vo.setRefundOfOrderNum(refundOfOrderNum);
vo.setRefundOfOrderAmount(refundOfOrderAmount.setScale(2, RoundingMode.HALF_UP)); vo.setRefundOfOrderAmount(refundOfOrderAmount.setScale(2, RoundingMode.HALF_UP));
statisticsMapper.insertStat(query.getScenicId(), new Date(), vo);
redisTemplate.opsForValue().set(redisKey, JSON.toJSONString(vo), 60, TimeUnit.SECONDS);
return ApiResponse.success(vo); return ApiResponse.success(vo);
} finally {
lock.unlock();
}
}
private BigDecimal addBigDecimalSafely(BigDecimal bd1, BigDecimal bd2) {
if (bd1 == null) {
bd1 = BigDecimal.ZERO;
}
if (bd2 == null) {
bd2 = BigDecimal.ZERO;
}
return bd1.add(bd2).setScale(2, RoundingMode.HALF_UP);
}
private int addIntSafely(Integer int1, Integer int2) {
return int1 == null ? 0 : int1 + (int2 == null ? 0 : int2);
} }
@Override @Override
@ -255,27 +339,22 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
* @param vo * @param vo
*/ */
private void freeStatisticsHandler(Integer cycle,CommonQueryReq query,AppSta3VO vo){ private void freeStatisticsHandler(Integer cycle,CommonQueryReq query,AppSta3VO vo){
//查询扫码访问人数 ApiResponse<AppStatisticsFunnelVO> resp = userConversionFunnel(query);
int sceneNum=statisticsMapper.countScanCodeOfMember(query); AppStatisticsFunnelVO data = resp.getData();
//查询推送订阅人数
int pushNum=statisticsMapper.countPushOfMember(query);
// 查询预览视频人数
Integer previewNum=statisticsMapper.countPreviewVideoOfMember(query);
if(cycle==1){ if(cycle==1){
//当前周期的扫码访问人数 //当前周期的扫码访问人数
vo.setNowScanCodeOfPeopleNum(sceneNum); vo.setNowScanCodeOfPeopleNum(data.getScanCodeVisitorOfMemberNum());
//当前周期的推送订阅人数 //当前周期的推送订阅人数
vo.setNowPushOfPeopleNum(pushNum); vo.setNowPushOfPeopleNum(data.getPushOfMemberNum());
//当前周期的预览视频人数 //当前周期的预览视频人数
vo.setNowPreviewVideoOfPeopleNum(previewNum); vo.setNowPreviewVideoOfPeopleNum(data.getPreviewOfVideoNum());
}else if(cycle==2){ }else if(cycle==2){
//上一个周期的扫码访问人数 //上一个周期的扫码访问人数
vo.setPreviousScanCodeOfPeopleNum(sceneNum); vo.setPreviousScanCodeOfPeopleNum(data.getScanCodeVisitorOfMemberNum());
//上一个周期的推送订阅人数 //上一个周期的推送订阅人数
vo.setPreviousPushOfPeopleNum(pushNum); vo.setPreviousPushOfPeopleNum(data.getPushOfMemberNum());
//上一个周期的预览视频人数 //上一个周期的预览视频人数
vo.setPreviousPreviewVideoOfPeopleNum(previewNum); vo.setPreviousPreviewVideoOfPeopleNum(data.getPreviewOfVideoNum());
} }
} }
@ -317,23 +396,25 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
* @param vo * @param vo
*/ */
private void oneStatisticsHandler(Integer cycle,CommonQueryReq query,AppSta1VO vo){ private void oneStatisticsHandler(Integer cycle,CommonQueryReq query,AppSta1VO vo){
ApiResponse<AppStatisticsFunnelVO> resp = userConversionFunnel(query);
AppStatisticsFunnelVO data = resp.getData();
//订单金额格式 //订单金额格式
DecimalFormat orderAmountDf = new DecimalFormat("0.0"); DecimalFormat orderAmountDf = new DecimalFormat("0.0");
//转化率格式 //转化率格式
DecimalFormat df = new DecimalFormat("0.00"); DecimalFormat df = new DecimalFormat("0.00");
// 计算当前周期的支付订单金额 // 计算当前周期的支付订单金额
BigDecimal orderAmount=statisticsMapper.countOrderAmount(query).setScale(2, RoundingMode.HALF_UP); String orderAmount=data.getPayOfOrderAmount();
//查询预览视频人数 //查询预览视频人数
int preview=statisticsMapper.countPreviewVideoOfMember(query); int preview=data.getPreviewOfVideoNum();
//查询扫码人数 //查询扫码人数
int scanCode=statisticsMapper.countScanCodeOfMember(query); int scanCode=data.getScanCodeVisitorOfMemberNum();
//查询付费人数 //查询付费人数
int pay=statisticsMapper.countPayOfMember(query); int pay=data.getPayOfMemberNum();
int payCount=statisticsMapper.countPayOfOrder(query); int payCount=data.getPayOfOrderNum();
if(cycle==1){ if(cycle==1){
// 支付过订单的金额,包含已退款的金额。 // 支付过订单的金额,包含已退款的金额。
vo.setNowOrderAmount(orderAmountDf.format(orderAmount)); vo.setNowOrderAmount(orderAmount);
// 订单数÷预览人数。假设一共5个人预览产生了3个订单其实是2个人支付的其中1人购买2单预览-支付转化率是3÷5而不是2÷5。 // 订单数÷预览人数。假设一共5个人预览产生了3个订单其实是2个人支付的其中1人购买2单预览-支付转化率是3÷5而不是2÷5。
if(preview==0){ if(preview==0){
vo.setNowPreviewPay("0.00"); vo.setNowPreviewPay("0.00");
@ -351,7 +432,7 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
}else if(cycle==2){ }else if(cycle==2){
//上一个周期的支付订单金额 //上一个周期的支付订单金额
// 支付过订单的金额,包含已退款的金额。 // 支付过订单的金额,包含已退款的金额。
vo.setPreviousOrderAmount(orderAmountDf.format(orderAmount)); vo.setPreviousOrderAmount(orderAmount);
// 订单数÷预览人数。假设一共5个人预览产生了3个订单其实是2个人支付的其中1人购买2单预览-支付转化率是3÷5而不是2÷5。 // 订单数÷预览人数。假设一共5个人预览产生了3个订单其实是2个人支付的其中1人购买2单预览-支付转化率是3÷5而不是2÷5。
if(preview==0){ if(preview==0){
vo.setPreviousPreviewPay("0.00"); vo.setPreviousPreviewPay("0.00");

View File

@ -27,7 +27,7 @@ public class DeviceStatsServiceImpl implements DeviceStatsService {
end = DateUtil.endOfDay(new Date()); end = DateUtil.endOfDay(new Date());
} }
ScenicDeviceStatsListResp resp = new ScenicDeviceStatsListResp(); ScenicDeviceStatsListResp resp = new ScenicDeviceStatsListResp();
if (DateUtil.isIn(start, DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(start, DateUtil.tomorrow(), DateUtil.yesterday())) { if (DateUtil.isIn(start, DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(end, DateUtil.tomorrow(), DateUtil.yesterday())) {
resp.setRealtime(true); resp.setRealtime(true);
List<ScenicDeviceStatsResp> data = mapper.countRealtimeStatsByScenicId(scenicId, start, end); List<ScenicDeviceStatsResp> data = mapper.countRealtimeStatsByScenicId(scenicId, start, end);
resp.setData(data); resp.setData(data);

View File

@ -2,7 +2,15 @@ package com.ycwl.basic.task;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.ycwl.basic.mapper.ScenicDeviceStatsMapper; import com.ycwl.basic.mapper.ScenicDeviceStatsMapper;
import com.ycwl.basic.mapper.ScenicMapper;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
import com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO;
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
import com.ycwl.basic.model.pc.scenicDeviceStats.entity.ScenicDeviceStatsEntity; import com.ycwl.basic.model.pc.scenicDeviceStats.entity.ScenicDeviceStatsEntity;
import com.ycwl.basic.service.mobile.AppStatisticsService;
import com.ycwl.basic.utils.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
@ -13,9 +21,15 @@ import java.util.List;
@Component @Component
@EnableScheduling @EnableScheduling
public class ScenicDeviceStatsTask { public class ScenicStatsTask {
@Autowired @Autowired
private ScenicDeviceStatsMapper mapper; private ScenicDeviceStatsMapper mapper;
@Autowired
private StatisticsMapper statisticsMapper;
@Autowired
private AppStatisticsService statisticsService;
@Autowired
private ScenicMapper scenicMapper;
@Scheduled(cron = "0 10 0 * * *") @Scheduled(cron = "0 10 0 * * *")
public void countDeviceStats() { public void countDeviceStats() {
Date yesterdayStart = DateUtil.beginOfDay(DateUtil.yesterday()); Date yesterdayStart = DateUtil.beginOfDay(DateUtil.yesterday());
@ -38,4 +52,20 @@ public class ScenicDeviceStatsTask {
}); });
} }
} }
@Scheduled(cron = "0 20 0 * * *")
public void countScenicStats() {
Date yesterdayStart = DateUtil.beginOfDay(DateUtil.yesterday());
Date yesterdayEnd = DateUtil.endOfDay(yesterdayStart);
List<ScenicRespVO> list = scenicMapper.list(new ScenicReqQuery());
list.forEach((scenic) -> {
CommonQueryReq query = new CommonQueryReq();
query.setScenicId(scenic.getId());
query.setStartTime(yesterdayStart);
query.setEndTime(yesterdayEnd);
query.setRealtime(true);
ApiResponse<AppStatisticsFunnelVO> resp = statisticsService.userConversionFunnel(query);
AppStatisticsFunnelVO data = resp.getData();
statisticsMapper.insertStat(scenic.getId(), yesterdayStart, data);
});
}
} }

View File

@ -313,7 +313,7 @@
limit 1 limit 1
</select> </select>
<select id="listStatByScenic" resultType="com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO"> <select id="listStatByScenic" resultType="com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO">
SELECT cs1 AS cameraShotOfMemberNum, v1 AS totalVisitorOfMemberNum, sv1 AS scanCodeVisitorOfMemberNum, u1 AS uploadFaceOfMemberNum, m1 AS pushOfMemberNum, gv1 AS completeVideoOfMemberNum, gv2 AS completeOfVideoNum, pv1 AS previewVideoOfMemberNum, pv2 AS previewOfVideoNum, cp1 AS clickOnPayOfMemberNum, o1 AS payOfMemberNum, o2 AS totalVisitorOfMemberNum, o3 AS payOfOrderAmount, ro2 AS refundOfOrderNum, ro3 AS refundOfOrderAmount SELECT cs1 AS cameraShotOfMemberNum, v1 AS totalVisitorOfMemberNum, sv1 AS scanCodeVisitorOfMemberNum, u1 AS uploadFaceOfMemberNum, m1 AS pushOfMemberNum, gv1 AS completeVideoOfMemberNum, gv2 AS completeOfVideoNum, pv1 AS previewVideoOfMemberNum, pv2 AS previewOfVideoNum, cp1 AS clickOnPayOfMemberNum, o1 AS payOfMemberNum, o2 AS payOfOrderNum, o3 AS payOfOrderAmount, ro2 AS refundOfOrderNum, ro3 AS refundOfOrderAmount
FROM scenic_stats FROM scenic_stats
WHERE scenic_id = #{scenicId} WHERE scenic_id = #{scenicId}
AND date BETWEEN #{startTime} AND #{endTime} AND date BETWEEN #{startTime} AND #{endTime}

View File

@ -1,24 +0,0 @@
package com.ycwl.basic.task;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.jupiter.api.Assertions.*;
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class ScenicDeviceStatsTaskTest {
@Autowired
private ScenicDeviceStatsTask task;
@Test
public void testA() {
task.countDeviceStats();
}
}

View File

@ -0,0 +1,60 @@
package com.ycwl.basic.task;
import cn.hutool.core.date.DateUtil;
import com.ycwl.basic.mapper.ScenicMapper;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
import com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO;
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
import com.ycwl.basic.service.mobile.AppStatisticsService;
import com.ycwl.basic.utils.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Calendar;
import java.util.List;
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class ScenicStatsTaskTest {
@Autowired
private ScenicStatsTask task;
@Autowired
private ScenicMapper scenicMapper;
@Autowired
private AppStatisticsService statisticsService;
@Autowired
private StatisticsMapper statisticsMapper;
@Test
public void testA() {
task.countDeviceStats();
}
@Test
public void testB() {
Calendar calendar = Calendar.getInstance();
calendar.set(2025, Calendar.MAY, 1);
List<ScenicRespVO> list = scenicMapper.list(new ScenicReqQuery());
while (calendar.getTime().getTime() < System.currentTimeMillis()) {
System.out.println(calendar.getTime());
list.forEach((scenic) -> {
CommonQueryReq query = new CommonQueryReq();
query.setScenicId(scenic.getId());
query.setStartTime(DateUtil.beginOfDay(calendar.getTime()));
query.setEndTime(DateUtil.endOfDay(calendar.getTime()));
ApiResponse<AppStatisticsFunnelVO> resp = statisticsService.userConversionFunnel(query);
AppStatisticsFunnelVO data = resp.getData();
statisticsMapper.insertStat(scenic.getId(), DateUtil.beginOfDay(calendar.getTime()), data);
});
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
}
}