代码提交 采番组件上传

This commit is contained in:
Zhuangxingyu
2025-02-24 13:31:39 +08:00
parent 517123f996
commit ced81f823e
6 changed files with 406 additions and 0 deletions

View File

@@ -40,4 +40,9 @@ public class CacheConstants {
* 登录账户密码错误次数 redis key
*/
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
/**
* 超出上限,排番失败(时间:{}KEY{}
*/
public static final String ASSIGN_SEQ_FAILED = "排番失败(时间:{}KEY{},异常信息:{超出上限}";
}

View File

@@ -3,6 +3,7 @@ package com.core.common.core.redis;
import java.util.*;
import java.util.concurrent.TimeUnit;
import com.core.common.exception.UtilException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
@@ -240,4 +241,19 @@ public class RedisCache {
public Collection<String> keys(final String pattern) {
return redisTemplate.keys(pattern);
}
/**
* 递增
*
* @param key 缓存Key
* @param delta 要增加的幅度(大于0)
* @return 递增后的值
*/
public long incr(String key, long delta) {
if (delta < 0L) {
throw new UtilException("递增因子必须大于0");
} else {
return this.redisTemplate.opsForValue().increment(key, delta);
}
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.core.common.enums;
import com.core.common.utils.StringUtils;
/**
* 采番前缀枚举
*
* @author zxy
* @date 2025-02-24
*/
public enum AssignSeqEnum {
/**
* 例子
*/
TEST("1", "例子", "TE");
private final String code;
private final String info;
private final String prefix;
AssignSeqEnum(String code, String info, String prefix) {
this.code = code;
this.info = info;
this.prefix = prefix;
}
public String getCode() {
return code;
}
public String getInfo() {
return info;
}
public String getPrefix() {
return prefix;
}
}

View File

@@ -0,0 +1,267 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.core.common.utils;
import java.util.ArrayList;
import java.util.List;
import com.core.common.constant.CacheConstants;
import com.core.common.core.redis.RedisCache;
import com.core.common.exception.UtilException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* 排番组件
*
* @author zxy
* @date 2024-11-29
*/
@Component
public final class AssignSeqUtil {
private final RedisCache redisCache;
// 缓存Key格式包含前缀
private static final String FORMAT_CACHE_KEY = "assign-seq:%s";
// 缓存Key格式包含前缀
private static final String FORMAT_CACHE_KEY_BY_DAY = "assign-seq:%s:%s";
// 默认序号长度
private static final int DEFAULT_SUFFIX_LENGTH = 8;
// 默认序号长度(每日重新排番)
private static final int DEFAULT_SUFFIX_LENGTH_DAY = 4;
// 编号格式前缀
private static final String FORMAT_SEQ_PREFIX = "%s%0";
// 编号格式前缀
private static final String FORMAT_SEQ_PREFIX_DAY = "%s%s%0";
// 编号格式后缀
private static final String FORMAT_SEQ_SUFFIX = "d";
// 失效时长48小时
private static final int EXPIRE_SECONDS = 172800;
private AssignSeqUtil(RedisCache redisCache) {
this.redisCache = redisCache;
}
private static final Logger log = LoggerFactory.getLogger(AssignSeqUtil.class);
/**
* 编号排番
*
* @param prefix 编号前缀
* @return 番号示例XXX00000001
*/
public String getSeq(String prefix) {
return this.getSeq(prefix, DEFAULT_SUFFIX_LENGTH);
}
/**
* 编号排番
*
* @param prefix 编号前缀
* @param seqLength 序号长度(去除前缀后位数)
* @return 番号示例XXX00000001
*/
public String getSeq(String prefix, int seqLength) {
return String.format(FORMAT_SEQ_PREFIX + seqLength + FORMAT_SEQ_SUFFIX, prefix, this.getSeqNo(prefix));
}
/**
* 编号排番(批量)
*
* @param prefix 编号前缀
* @param seqLength 序号长度(去除前缀后位数)
* @param count 排番数量
* @return 番号示例XXX00000001XXX00000002
*/
public List<String> getSeq(String prefix, int seqLength, int count) {
// 获取最新编号
int seqEnd = this.getSeqNoCore(String.format(FORMAT_CACHE_KEY, prefix), count);
// 返回番号集合
List<String> seqS = new ArrayList<>();
long seq = seqEnd - count + 1;
while (seq <= seqEnd) {
// 拼接番号
seqS.add(String.format(FORMAT_SEQ_PREFIX + seqLength + FORMAT_SEQ_SUFFIX, prefix, seq++));
}
return seqS;
}
/**
* 编号排番
*
* @param key 编号主键
* @return 番号示例XXX00000001
*/
public int getSeqNo(String key) {
return this.getSeqNoCore(String.format(FORMAT_CACHE_KEY, key), 1);
}
/**
* 编号排番(批量)
*
* @param key 编号主键
* @param count 排番数量
* @return 番号示例XXX00000001XXX00000002
*/
public List<Integer> getSeqNo(String key, int count) {
// 获取最新编号
int seqEnd = this.getSeqNoCore(String.format(FORMAT_CACHE_KEY, key), count);
// 返回番号集合
List<Integer> seqS = new ArrayList<>();
int seq = seqEnd - count + 1;
while (seq <= seqEnd) {
// 拼接番号
seqS.add(seq++);
}
return seqS;
}
/**
* 编号排番(每日重新排番)
*
* @param prefix 编号前缀
* @return 番号
*/
public String getSeqByDay(String prefix) {
return this.getSeqByDay(prefix, DEFAULT_SUFFIX_LENGTH_DAY);
}
/**
* 编号排番(每日重新排番)
*
* @param prefix 编号前缀
* @param seqLength 序号长度(去除前缀后位数)
* @return 番号
*/
public String getSeqByDay(String prefix, int seqLength) {
// 获取当前日期
String today = DateUtils.today();
// 获取最新编号
int seq = this.getSeqNoByDay(prefix, today, 1);
// 拼接番号并返回
return String.format(FORMAT_SEQ_PREFIX_DAY + seqLength + FORMAT_SEQ_SUFFIX, prefix, today, seq);
}
/**
* 编号排番(每日重新排番)(批量)
*
* @param prefix 编号前缀
* @param seqLength 序号长度(去除前缀后位数)
* @param count 排番数量
* @return 番号(最小值)
*/
public List<String> getSeqByDay(String prefix, int seqLength, int count) {
// 获取当前日期
String today = DateUtils.today();
// 获取最新编号
int seqEnd = this.getSeqNoByDay(prefix, today, count);
// 返回番号集合
List<String> seqS = new ArrayList<>();
long seq = seqEnd - count + 1;
while (seq <= seqEnd) {
// 拼接番号
seqS.add(String.format(FORMAT_SEQ_PREFIX_DAY + seqLength + FORMAT_SEQ_SUFFIX, prefix, today, seq++));
}
return seqS;
}
/**
* 编号排番(每日重新排番)
*
* @param prefix 编号前缀
* @return 番号
*/
public int getSeqNoByDay(String prefix) {
return this.getSeqNoByDay(prefix, DateUtils.today(), 1);
}
/**
* 编号排番(每日重新排番)(批量)
*
* @param prefix 编号前缀
* @param count 排番数量
* @return 番号(最小值)
*/
public List<Integer> getSeqNoByDay(String prefix, int count) {
// 获取当前日期
String today = DateUtils.today();
// 获取最新编号
int seqEnd = this.getSeqNoByDay(prefix, today, count);
// 返回番号集合
List<Integer> seqS = new ArrayList<>();
int seq = seqEnd - count + 1;
while (seq <= seqEnd) {
// 拼接番号
seqS.add(seq++);
}
return seqS;
}
/**
* 编号排番(每日重新排番)
*
* @param prefix 编号前缀
* @param date 序号长度(去除前缀后位数)
* @param count 排番数量
* @return 番号
*/
private int getSeqNoByDay(String prefix, String date, int count) {
// 拼接缓存Key包含当日日期
String cacheKeyByDay = String.format(FORMAT_CACHE_KEY_BY_DAY, prefix, date);
// 获取最新编号
int seq = this.getSeqNoCore(cacheKeyByDay, count);
// 当最小编号为1时设置保存期限
if (seq - count + 1 == 1) {
redisCache.expire(cacheKeyByDay, EXPIRE_SECONDS);
}
// 拼接番号并返回
return seq;
}
/**
* 编号排番(批量)
*
* @param cacheKey 缓存Key
* @param count 排番数量
* @return 番号示例XXX00000001XXX00000002
*/
private int getSeqNoCore(String cacheKey, int count) {
// 获取最新编号
long seq = redisCache.incr(cacheKey, count);
// 达到最大值时重置番号
if (seq >= Integer.MAX_VALUE) {
log.error(CacheConstants.ASSIGN_SEQ_FAILED, DateUtils.getStrYmdHmsRead(), cacheKey);
throw new UtilException("排番失败!");
}
// 番号返回
return (int)seq;
}
}

View File

@@ -22,8 +22,12 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYYMMDD = "yyyyMMdd";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static String YMDHMS_FOR_READ = "yyyy年MM月dd日 HH时mm分ss秒";
private static String[] parsePatterns =
{"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss",
"yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
@@ -90,6 +94,25 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
return DateFormatUtils.format(now, "yyyyMMdd");
}
/**
* 获取当日日期
*
* @return 当日日期
*/
public static final String today()
{
return dateTimeNow(YYYYMMDD);
}
/**
* 获取当日日期(可读)
* @return
*/
public static final String getStrYmdHmsRead()
{
return dateTimeNow(YMDHMS_FOR_READ);
}
/**
* 日期型字符串转化为日期 格式
*/