You've already forked FrameTour-BE
refactor(statistics): 重构应用统计漏斗服务的Redis缓存逻辑
- 移除固定的Redis缓存key,改为包含日期维度的动态key - 修复日期范围检查逻辑中的时间顺序问题 - 统一多处相同的日期范围条件判断代码 - 移除实时模式下的数据持久化操作以避免缓存污染
This commit is contained in:
@@ -145,7 +145,6 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
|
||||
|
||||
@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来判断查询时间范围
|
||||
@@ -156,8 +155,12 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
|
||||
//获取当前周期的具体时间范围
|
||||
standardToNewSpecificTime(query);
|
||||
}
|
||||
// 构建包含日期维度的 Redis 缓存 key
|
||||
String redisKey = String.format("statistics:tmp_cache:%s:%s",
|
||||
query.getScenicId(),
|
||||
query.getStartTime() != null ? DateUtil.formatDate(query.getStartTime()) : "null");
|
||||
if (!query.isRealtime()) {
|
||||
if (!(DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday()))) {
|
||||
if (!(DateUtil.isIn(query.getStartTime(), DateUtil.yesterday(), DateUtil.tomorrow()) && DateUtil.isIn(query.getEndTime(), DateUtil.yesterday(), DateUtil.tomorrow()))) {
|
||||
// 查询缓存数据
|
||||
List<AppStatisticsFunnelVO> list = statisticsMapper.listStatByScenic(query.getScenicId(), query.getStartTime(), query.getEndTime());
|
||||
AppStatisticsFunnelVO resp = new AppStatisticsFunnelVO();
|
||||
@@ -189,7 +192,7 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
|
||||
}
|
||||
}
|
||||
if (!query.isRealtime()) {
|
||||
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
|
||||
if (DateUtil.isIn(query.getStartTime(), DateUtil.yesterday(), DateUtil.tomorrow()) && DateUtil.isIn(query.getEndTime(), DateUtil.yesterday(), DateUtil.tomorrow())) {
|
||||
// 缓存
|
||||
if (redisTemplate.hasKey(redisKey)) {
|
||||
String s = redisTemplate.opsForValue().get(redisKey);
|
||||
@@ -203,7 +206,7 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
|
||||
try {
|
||||
// 缓存
|
||||
if (!query.isRealtime()) {
|
||||
if (DateUtil.isIn(query.getStartTime(), DateUtil.tomorrow(), DateUtil.yesterday()) && DateUtil.isIn(query.getEndTime(), DateUtil.tomorrow(), DateUtil.yesterday())) {
|
||||
if (DateUtil.isIn(query.getStartTime(), DateUtil.yesterday(), DateUtil.tomorrow()) && DateUtil.isIn(query.getEndTime(), DateUtil.yesterday(), DateUtil.tomorrow())) {
|
||||
// 缓存
|
||||
if (redisTemplate.hasKey(redisKey)) {
|
||||
String s = redisTemplate.opsForValue().get(redisKey);
|
||||
@@ -270,14 +273,6 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
|
||||
vo.setPayOfOrderAmount(payOfOrderAmount.setScale(2, RoundingMode.HALF_UP));
|
||||
vo.setRefundOfOrderNum(refundOfOrderNum);
|
||||
vo.setRefundOfOrderAmount(refundOfOrderAmount.setScale(2, RoundingMode.HALF_UP));
|
||||
// 仅在非 realtime 模式下写入缓存
|
||||
// realtime=true 时由调用方(如定时任务)自行控制写入目标日期,不污染当天缓存
|
||||
if (!query.isRealtime()) {
|
||||
if (query.getScenicId() != null) {
|
||||
statisticsMapper.insertStat(query.getScenicId(), new Date(), vo);
|
||||
}
|
||||
redisTemplate.opsForValue().set(redisKey, JacksonUtil.toJSONString(vo), 60, TimeUnit.SECONDS);
|
||||
}
|
||||
return ApiResponse.success(vo);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
|
||||
@@ -93,8 +93,8 @@ public class ScenicStatsTask {
|
||||
// 写入数据库(REPLACE INTO 会自动更新已存在的记录)
|
||||
statisticsMapper.insertStat(scenicId, startTime, data);
|
||||
|
||||
// 删除该景区的缓存,确保下次查询时获取最新数据
|
||||
invalidateStatisticsCache(scenicId);
|
||||
// 删除该景区该日期的缓存,确保下次查询时获取最新数据
|
||||
invalidateStatisticsCache(scenicId, startTime);
|
||||
} catch (Exception e) {
|
||||
log.error("统计景区 {} 在日期 {} 的数据时发生错误", scenic.getId(), DateUtil.formatDate(startTime), e);
|
||||
}
|
||||
@@ -109,9 +109,12 @@ public class ScenicStatsTask {
|
||||
/**
|
||||
* 删除景区统计缓存
|
||||
* @param scenicId 景区ID
|
||||
* @param date 统计日期
|
||||
*/
|
||||
private void invalidateStatisticsCache(Long scenicId) {
|
||||
String redisKey = "statistics:tmp_cache:" + scenicId;
|
||||
private void invalidateStatisticsCache(Long scenicId, Date date) {
|
||||
String redisKey = String.format("statistics:tmp_cache:%s:%s",
|
||||
scenicId,
|
||||
DateUtil.formatDate(date));
|
||||
redisTemplate.delete(redisKey);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user