工具类
@Component
public class RedisIdWorker {/*** 开始时间戳(2023-01-01)*/private static final long BEGIN_TIMESTAMP = 1672531200L;/*** 序列号的位数(32位)*/private static final int COUNT_BITS = 32;/*** 生成分布式 ID* @param keyPrefix ID 的业务前缀,如 "YYD"、"QBD" 等。如果为空或 null,默认使用 "ASD"* @return 全局唯一递增的 Long 型 ID*/public static long nextId(String keyPrefix) {// 如果 keyPrefix 为 null 或空字符串,则使用默认值 "ASD"String safePrefix = (StrUtil.isBlank(keyPrefix)) ? "ASD" : keyPrefix;LocalDateTime now = LocalDateTime.now();long nowSecond = now.toEpochSecond(ZoneOffset.UTC);long timestamp = nowSecond - BEGIN_TIMESTAMP;String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));// 构建 redis的KeyString redisKey = "ICR:" + safePrefix + ":" + date;long count = RedissonUtil.incrementWithExpire(redisKey,Duration.ofDays(2)); //缓存两天// 拼接返回结果:时间戳左移 COUNT_BITS 位,与自增序列进行按位或return (timestamp << COUNT_BITS) | count;}/*** 生成带业务前缀的 ID 字符串* @param keyPrefix 如 "QBD", "YYD",允许为 null 或空字符串,会自动替换为 "ASD"* @return 带前缀的字符串 ID,如 "QBD1234567890"*/public static String nextIdWithPrefix(String keyPrefix) {long id = nextId(keyPrefix); // 调用 nextId,已处理 null 和空字符串String safePrefix = (StrUtil.isEmpty(keyPrefix)) ? "ASD" : keyPrefix;return safePrefix + id;}
}
redis工具类
/*** 自增并设置过期时间(仅当 value == 1 的时候)* @param key 要自增的 key* @param expireDuration 过期时间(如 Duration.ofDays(3))* @return 自增后的值*/public static long incrementWithExpire(String key, Duration expireDuration) {RAtomicLong atomicLong = redissonClient.getAtomicLong(key);long value = atomicLong.incrementAndGet();if (value == 1) {// Duration 转换为 Instant:当前时间 + 持续时间Instant expirationTime = Instant.now().plus(expireDuration);atomicLong.expire(expirationTime); // 设置过期时间}return value;}