maven
3 天以前 0ce689b428cf9ceb58972db2bdd42a1a176f8f20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package com.ruoyi.approve.utils;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.approve.mapper.ApproveProcessMapper;
import com.ruoyi.approve.pojo.ApproveProcess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
 
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;
 
 
//基于redis的一个每日计数器
@Component
public class DailyRedisCounter {
    private static final String KEY_PREFIX = "daily_counter:";
    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
    private final StringRedisTemplate redisTemplate;
 
    public DailyRedisCounter(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
 
    /**查缓存
     * 获取指定计数器在今日的数值,并自增1
     * @param counterName 计数器名称(例如:login_count、order_count)
     * @return 今日自增后的计数值
     */
    public long incrementAndGet(String counterName) {
        String key = getKey(counterName);
        long count = redisTemplate.opsForValue().increment(key, 1);
 
        // 仅在第一次设置时设置过期时间(避免重复设置)
        if (count == 1) {
            long secondsUntilMidnight = calculateSecondsUntilMidnight();
            redisTemplate.expire(key, secondsUntilMidnight, TimeUnit.SECONDS);
        }
 
        return count;
    }
 
    @Autowired
    private ApproveProcessMapper approveProcessMapper;
 
    /**
     * 获取当前时间的  开始日期  ,结束日期
     * @return
     */
    public static StartAndEndDateDto getDateTime(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE,1);
        String startDateTime = simpleDateFormat.format(date);
        String endDateTime = simpleDateFormat.format(cal.getTime());
        StartAndEndDateDto startAndEndDateDto = new StartAndEndDateDto();
        startAndEndDateDto.setStartDate(startDateTime);
        startAndEndDateDto.setEndDate(endDateTime);
        return startAndEndDateDto;
    }
 
    /**查数据库
     * 获取指定计数器在今日的数值,并自增1
     * @return 今日自增后的计数值
     */
    public long incrementAndGetByDb() {
        StartAndEndDateDto dateTime = getDateTime();
        LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
        approveProcessLambdaQueryWrapper
                .eq(ApproveProcess::getApproveDelete,0)
                .gt(ApproveProcess::getCreateTime,dateTime.getStartDate())
        .lt(ApproveProcess::getCreateTime,dateTime.getEndDate());
        Long aLong = approveProcessMapper.selectCount(approveProcessLambdaQueryWrapper);
 
        return aLong == null ? 1 : aLong + 1;
    }
 
    /**
     * 获取指定计数器在今日的当前数值
     * @param counterName 计数器名称
     * @return 今日当前计数值,若不存在则返回0
     */
    public long getCurrentCount(String counterName) {
        String key = getKey(counterName);
        String value = redisTemplate.opsForValue().get(key);
        return value != null ? Long.parseLong(value) : 0;
    }
 
    /**
     * 计算距离次日凌晨的秒数
     */
    private long calculateSecondsUntilMidnight() {
        LocalDate tomorrow = LocalDate.now().plusDays(1);
        LocalDate midnight = tomorrow.atStartOfDay().toLocalDate();
        return java.time.Duration.between(
                LocalDate.now().atTime(23, 59, 59),
                midnight.atTime(0, 0, 0)
        ).getSeconds() + 1;
    }
 
    /**
     * 生成Redis键
     */
    private String getKey(String counterName) {
        String today = LocalDate.now().format(DATE_FORMAT);
        return KEY_PREFIX + counterName + ":" + today;
    }
}