diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java index 657dbbc07..94439f9c3 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java @@ -1,9 +1,9 @@ package org.dromara.common.redis.utils; -import cn.hutool.core.date.DatePattern; -import cn.hutool.core.date.DateUtil; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.redisson.api.RIdGenerator; @@ -17,6 +17,7 @@ import java.time.Duration; * @author 秋辞未寒 * @date 2024-12-10 */ +@Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE) public class SequenceUtils { @@ -33,12 +34,17 @@ public class SequenceUtils { /** * 默认过期时间-天 */ - public static final Duration DEFAULT_EXPIRE_TIME_DAY = Duration.ofDays(1); + public static final Duration DEFAULT_EXPIRE_DAY = Duration.ofDays(1); /** * 默认过期时间-分钟 */ - public static final Duration DEFAULT_EXPIRE_TIME_MINUTE = Duration.ofMinutes(1); + public static final Duration DEFAULT_EXPIRE_MINUTE = Duration.ofMinutes(1); + + /** + * 默认前缀 + */ + public static final String DEFAULT_PREFIX = "SEQ:"; /** * 获取Redisson客户端实例 @@ -46,7 +52,7 @@ public class SequenceUtils { private static final RedissonClient REDISSON_CLIENT = SpringUtils.getBean(RedissonClient.class); /** - * 获取ID生成器 + * 获取 Redisson ID生成器(仅初始化一次) * * @param key 业务key * @param expireTime 过期时间 @@ -55,20 +61,32 @@ public class SequenceUtils { * @return ID生成器 */ private static RIdGenerator getIdGenerator(String key, Duration expireTime, Long initValue, Long stepValue) { - if (initValue == null || initValue <= 0) { - initValue = DEFAULT_INIT_VALUE; + if (StringUtils.isBlank(key)) { + throw new IllegalArgumentException("key 不能为空"); } - if (stepValue == null || stepValue <= 0) { - stepValue = DEFAULT_STEP_VALUE; + initValue = (initValue == null || initValue <= 0) ? DEFAULT_INIT_VALUE : initValue; + stepValue = (stepValue == null || stepValue <= 0) ? DEFAULT_STEP_VALUE : stepValue; + + RIdGenerator idGenerator = REDISSON_CLIENT.getIdGenerator(DEFAULT_PREFIX + key); + try { + // 初始化成功后设置过期时间,避免多线程反复设置 + if (idGenerator.tryInit(initValue, stepValue)) { + idGenerator.expire(expireTime); + } + } catch (Exception e) { + log.error("ID生成器初始化失败: key={}, initValue={}, stepValue={}", key, initValue, stepValue, e); + throw e; } - RIdGenerator idGenerator = REDISSON_CLIENT.getIdGenerator(key); - // 设置初始值和步长 - idGenerator.tryInit(initValue, stepValue); - // 设置过期时间 - idGenerator.expire(expireTime); return idGenerator; } + /** + * 构建标准的业务 key:加上默认前缀 + */ + private static String generateKey(String prefix, String suffix) { + return StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), suffix); + } + /** * 获取指定业务key的唯一id * @@ -145,12 +163,8 @@ public class SequenceUtils { * @return 唯一id */ public static String nextIdDate(String prefix) { - // 前缀+日期 构建 prefixKey - String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_FORMATTER)); - // 获取下一个id - long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_DAY, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId(); - // 返回完整id - return StringUtils.format("{}{}", prefixKey, nextId); + String key = generateKey(prefix, DateUtils.getCurrentDate()); + return key + nextId(key, DEFAULT_EXPIRE_DAY); } /** @@ -169,12 +183,8 @@ public class SequenceUtils { * @return 唯一id */ public static String nextIdDateTime(String prefix) { - // 前缀+日期时间 构建 prefixKey - String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_FORMATTER)); - // 获取下一个id - long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_MINUTE, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId(); - // 返回完整id - return StringUtils.format("{}{}", prefixKey, nextId); + String key = generateKey(prefix, DateUtils.dateTimeNow()); + return key + nextId(key, DEFAULT_EXPIRE_MINUTE); } }