缓存统计信息

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;
@ApiModelProperty(value = "景区id")
private Long scenicId;
private boolean realtime;
private Date startTime;
private Date endTime;
}

View File

@@ -111,10 +111,22 @@ public class AppStatisticsFunnelVO {
.divide(new BigDecimal(clickOnPayOfMemberNum), 2, RoundingMode.HALF_UP)
.toString();
}
public BigDecimal payOfOrderAmount() {
return payOfOrderAmount;
}
public String getPayOfOrderAmount() {
if (payOfOrderAmount == null) {
return "0.00";
}
return payOfOrderAmount.toString();
}
public BigDecimal refundOfOrderAmount() {
return refundOfOrderAmount;
}
public String getRefundOfOrderAmount() {
if (refundOfOrderAmount == null) {
return "0.00";
}
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.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ycwl.basic.enums.StatisticEnum;
import com.ycwl.basic.mapper.StatisticsMapper;
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.AppSta3VO;
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.utils.ApiResponse;
import com.ycwl.basic.utils.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Author:longbinbin
@@ -56,11 +63,13 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
standardToNewSpecificTime(query);
//查询处理数据逻辑
oneStatisticsHandler(1,query,vo);
//----------------------------------------------------
//获取上一个周期的具体时间范围
standardToPreviousSpecificTime(query);
//查询处理数据逻辑
oneStatisticsHandler(2,query,vo);
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
//----------------------------------------------------
//获取上一个周期的具体时间范围
standardToPreviousSpecificTime(query);
//查询处理数据逻辑
oneStatisticsHandler(2,query,vo);
}
}else{
//自定义时间查询,只有当前数据,没有往期对比数据
//查询处理数据逻辑
@@ -82,11 +91,13 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
standardToNewSpecificTime(query);
//查询处理数据逻辑
twoStatisticsHandler(1,query,vo);
//----------------------------------------------------
//获取当前周期的具体时间范围
standardToPreviousSpecificTime(query);
//查询处理数据逻辑
twoStatisticsHandler(2,query,vo);
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
//----------------------------------------------------
//获取当前周期的具体时间范围
standardToPreviousSpecificTime(query);
//查询处理数据逻辑
twoStatisticsHandler(2, query, vo);
}
}else{
//自定义时间查询,只有当前数据,没有往期对比数据
//查询处理数据逻辑
@@ -108,11 +119,13 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
standardToNewSpecificTime(query);
//查询处理数据逻辑
freeStatisticsHandler(1,query,vo);
//----------------------------------------------------
//获取当前周期的具体时间范围
standardToPreviousSpecificTime(query);
//查询处理数据逻辑
freeStatisticsHandler(2,query,vo);
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
//----------------------------------------------------
//获取当前周期的具体时间范围
standardToPreviousSpecificTime(query);
//查询处理数据逻辑
freeStatisticsHandler(2, query, vo);
}
}else{
//自定义时间查询,只有当前数据,没有往期对比数据
//查询处理数据逻辑
@@ -121,8 +134,13 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
return ApiResponse.success(vo);
}
@Autowired
private RedisTemplate<String, String> redisTemplate;
private ReentrantLock lock = new ReentrantLock();
@Override
public ApiResponse<AppStatisticsFunnelVO> userConversionFunnel(CommonQueryReq query) {
String redisKey = "statistics:tmp_cache:"+query.getScenicId();
AppStatisticsFunnelVO vo = new AppStatisticsFunnelVO();
if(query.getEndTime()==null && query.getStartTime()==null){
// 没有传时间,则代表用户没有自定义查询时间,使用standard来判断查询时间范围
@@ -133,72 +151,138 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
//获取当前周期的具体时间范围
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()));
//镜头检测游客数
Integer cameraShotOfMemberNum=statisticsMapper.countCameraShotOfMember(query);
//扫码访问人数
// 扫小程序码或景区码进入访问的用户数,包括授权用户(使用OpenID进行精准统计)和未授权用户(使用 UUID统计访问)。但当用户授权时,获取OpenID并与UUID关联,删除本地UUID,避免重复记录。
Integer scanCodeVisitorOfMemberNum=statisticsMapper.countScanCodeOfMember(query);
//上传头像(人脸)人数
// 上传了人脸的用户数(包括本地临时ID和获取到OpenID的,同一设备微信获取到OpenID要覆盖掉之前生成的临时ID),上传多张人脸都只算一个人。
Integer uploadFaceOfMemberNum=statisticsMapper.countUploadFaceOfMember(query);
//推送订阅人数
// 只要点了允许通知,哪怕只勾选1条订阅都算
Integer pushOfMemberNum =statisticsMapper.countPushOfMember(query);
//生成视频人数
// 生成过Vlog视频的用户ID数,要注意屏蔽掉以前没有片段也能生成的情况
Integer completeVideoOfMemberNum =statisticsMapper.countCompleteVideoOfMember(query);
//预览视频人数
// 购买前播放了5秒的视频条数。
Integer previewVideoOfMemberNum =statisticsMapper.countPreviewVideoOfMember(query);
if (previewVideoOfMemberNum==null){
previewVideoOfMemberNum=0;
// BigDecimal fields
resp.setPayOfOrderAmount(addBigDecimalSafely(resp.payOfOrderAmount(), item.payOfOrderAmount()));
resp.setRefundOfOrderAmount(addBigDecimalSafely(resp.refundOfOrderAmount(), item.refundOfOrderAmount()));
}
}
return ApiResponse.success(resp);
}
}
//点击购买人数
// 点了立即购买按钮的用户ID就算,包括支付的和未支付的都算,只要点击了。
Integer clickOnPayOfMemberNum =statisticsMapper.countClickPayOfMember(query);
//支付订单人数
Integer payOfMemberNum =statisticsMapper.countPayOfMember(query);
//总访问人数
// 通过任何途径访问到小程序的总人数,包括授权用户和未授权用户。
Integer totalVisitorOfMemberNum =statisticsMapper.countTotalVisitorOfMember(query);
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);
//扫码访问人数
// 扫小程序码或景区码进入访问的用户数,包括授权用户(使用OpenID进行精准统计)和未授权用户(使用 UUID统计访问)。但当用户授权时,获取OpenID并与UUID关联,删除本地UUID,避免重复记录。
Integer scanCodeVisitorOfMemberNum=statisticsMapper.countScanCodeOfMember(query);
//上传头像(人脸)人数
// 上传了人脸的用户数(包括本地临时ID和获取到OpenID的,同一设备微信获取到OpenID要覆盖掉之前生成的临时ID),上传多张人脸都只算一个人。
Integer uploadFaceOfMemberNum=statisticsMapper.countUploadFaceOfMember(query);
//推送订阅人数
// 只要点了允许通知,哪怕只勾选1条订阅都算
Integer pushOfMemberNum =statisticsMapper.countPushOfMember(query);
//生成视频人数
// 生成过Vlog视频的用户ID数,要注意屏蔽掉以前没有片段也能生成的情况
Integer completeVideoOfMemberNum =statisticsMapper.countCompleteVideoOfMember(query);
//预览视频人数
// 购买前播放了5秒的视频条数。
Integer previewVideoOfMemberNum =statisticsMapper.countPreviewVideoOfMember(query);
if (previewVideoOfMemberNum==null){
previewVideoOfMemberNum=0;
}
//点击购买人数
// 点了立即购买按钮的用户ID就算,包括支付的和未支付的都算,只要点击了。
Integer clickOnPayOfMemberNum =statisticsMapper.countClickPayOfMember(query);
//支付订单人数
Integer payOfMemberNum =statisticsMapper.countPayOfMember(query);
//总访问人数
// 通过任何途径访问到小程序的总人数,包括授权用户和未授权用户。
Integer totalVisitorOfMemberNum =statisticsMapper.countTotalVisitorOfMember(query);
// Integer totalVisitorOfMemberNum =scanCodeVisitorOfMemberNum;
//生成视频条数
// 仅指代生成的Vlog条数,不包含录像原片。
Integer completeOfVideoNum =statisticsMapper.countCompleteOfVideo(query);
//预览视频条数
Integer previewOfVideoNum =statisticsMapper.countPreviewOfVideo(query);
//支付订单数
Integer payOfOrderNum =statisticsMapper.countPayOfOrder(query);
//支付订单金额
BigDecimal payOfOrderAmount =statisticsMapper.countOrderAmount(query);
//退款订单数
Integer refundOfOrderNum =statisticsMapper.countRefundOfOrder(query);
//退款订单金额
BigDecimal refundOfOrderAmount =statisticsMapper.countRefundAmount(query);
//生成视频条数
// 仅指代生成的Vlog条数,不包含录像原片。
Integer completeOfVideoNum =statisticsMapper.countCompleteOfVideo(query);
//预览视频条数
Integer previewOfVideoNum =statisticsMapper.countPreviewOfVideo(query);
//支付订单数
Integer payOfOrderNum =statisticsMapper.countPayOfOrder(query);
//支付订单金额
BigDecimal payOfOrderAmount =statisticsMapper.countOrderAmount(query);
//退款订单数
Integer refundOfOrderNum =statisticsMapper.countRefundOfOrder(query);
//退款订单金额
BigDecimal refundOfOrderAmount =statisticsMapper.countRefundAmount(query);
vo.setScanCodeVisitorOfMemberNum(scanCodeVisitorOfMemberNum);
vo.setUploadFaceOfMemberNum(uploadFaceOfMemberNum);
vo.setPushOfMemberNum(pushOfMemberNum);
vo.setCompleteVideoOfMemberNum(completeVideoOfMemberNum);
vo.setPreviewVideoOfMemberNum(previewVideoOfMemberNum);
vo.setClickOnPayOfMemberNum(clickOnPayOfMemberNum);
vo.setPayOfMemberNum(payOfMemberNum);
vo.setScanCodeVisitorOfMemberNum(scanCodeVisitorOfMemberNum);
vo.setUploadFaceOfMemberNum(uploadFaceOfMemberNum);
vo.setPushOfMemberNum(pushOfMemberNum);
vo.setCompleteVideoOfMemberNum(completeVideoOfMemberNum);
vo.setPreviewVideoOfMemberNum(previewVideoOfMemberNum);
vo.setClickOnPayOfMemberNum(clickOnPayOfMemberNum);
vo.setPayOfMemberNum(payOfMemberNum);
//转化率格式
DecimalFormat df = new DecimalFormat("0.0");
vo.setTotalVisitorOfMemberNum(totalVisitorOfMemberNum);
vo.setCompleteOfVideoNum(completeOfVideoNum);
vo.setPreviewOfVideoNum(previewOfVideoNum);
vo.setPayOfOrderNum(payOfOrderNum);
vo.setPayOfOrderAmount(payOfOrderAmount.setScale(2, RoundingMode.HALF_UP));
vo.setRefundOfOrderNum(refundOfOrderNum);
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);
} finally {
lock.unlock();
}
}
vo.setTotalVisitorOfMemberNum(totalVisitorOfMemberNum);
vo.setCompleteOfVideoNum(completeOfVideoNum);
vo.setPreviewOfVideoNum(previewOfVideoNum);
vo.setPayOfOrderNum(payOfOrderNum);
vo.setPayOfOrderAmount(payOfOrderAmount.setScale(2, RoundingMode.HALF_UP));
vo.setRefundOfOrderNum(refundOfOrderNum);
vo.setRefundOfOrderAmount(refundOfOrderAmount.setScale(2, RoundingMode.HALF_UP));
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);
}
return ApiResponse.success(vo);
private int addIntSafely(Integer int1, Integer int2) {
return int1 == null ? 0 : int1 + (int2 == null ? 0 : int2);
}
@Override
@@ -255,27 +339,22 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
* @param vo
*/
private void freeStatisticsHandler(Integer cycle,CommonQueryReq query,AppSta3VO vo){
//查询扫码访问人数
int sceneNum=statisticsMapper.countScanCodeOfMember(query);
//查询推送订阅人数
int pushNum=statisticsMapper.countPushOfMember(query);
// 查询预览视频人数
Integer previewNum=statisticsMapper.countPreviewVideoOfMember(query);
ApiResponse<AppStatisticsFunnelVO> resp = userConversionFunnel(query);
AppStatisticsFunnelVO data = resp.getData();
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){
//上一个周期的扫码访问人数
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
*/
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 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 payCount=statisticsMapper.countPayOfOrder(query);
int pay=data.getPayOfMemberNum();
int payCount=data.getPayOfOrderNum();
if(cycle==1){
// 支付过订单的金额,包含已退款的金额。
vo.setNowOrderAmount(orderAmountDf.format(orderAmount));
vo.setNowOrderAmount(orderAmount);
// 订单数÷预览人数。假设一共5个人预览,产生了3个订单,其实是2个人支付的(其中1人购买2单),预览-支付转化率是3÷5,而不是2÷5。
if(preview==0){
vo.setNowPreviewPay("0.00");
@@ -351,7 +432,7 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
}else if(cycle==2){
//上一个周期的支付订单金额
// 支付过订单的金额,包含已退款的金额。
vo.setPreviousOrderAmount(orderAmountDf.format(orderAmount));
vo.setPreviousOrderAmount(orderAmount);
// 订单数÷预览人数。假设一共5个人预览,产生了3个订单,其实是2个人支付的(其中1人购买2单),预览-支付转化率是3÷5,而不是2÷5。
if(preview==0){
vo.setPreviousPreviewPay("0.00");

View File

@@ -27,7 +27,7 @@ public class DeviceStatsServiceImpl implements DeviceStatsService {
end = DateUtil.endOfDay(new Date());
}
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);
List<ScenicDeviceStatsResp> data = mapper.countRealtimeStatsByScenicId(scenicId, start, end);
resp.setData(data);

View File

@@ -2,7 +2,15 @@ package com.ycwl.basic.task;
import cn.hutool.core.date.DateUtil;
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.service.mobile.AppStatisticsService;
import com.ycwl.basic.utils.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
@@ -13,9 +21,15 @@ import java.util.List;
@Component
@EnableScheduling
public class ScenicDeviceStatsTask {
public class ScenicStatsTask {
@Autowired
private ScenicDeviceStatsMapper mapper;
@Autowired
private StatisticsMapper statisticsMapper;
@Autowired
private AppStatisticsService statisticsService;
@Autowired
private ScenicMapper scenicMapper;
@Scheduled(cron = "0 10 0 * * *")
public void countDeviceStats() {
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);
});
}
}