代码提交 采番组件上传

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);
}
/**
* 日期型字符串转化为日期 格式
*/

View File

@@ -4,10 +4,14 @@
package com.openhis.web.datadictionary.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.core.common.enums.AssignSeqEnum;
import com.core.common.utils.AssignSeqUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -53,6 +57,8 @@ public class ItemDefinitionController {
// private IDeviceDefinitionService deviceDefinitionService;
// @Autowired(required = false)
// private IActivityDefinitionService activityDefinitionService;
@Autowired(required = false)
private AssignSeqUtil assignSeqUtil;
/**
* 项目定价列表
@@ -127,8 +133,10 @@ public class ItemDefinitionController {
}
// 通过 DefinitionType 区分药品定价/器具定价/手术定价
if (DefinitionTypeEnum.MEDICATION.getCode().equals(itemDefSearchParam.getDefinitionType())) {
//获取定价列表
chargeItemDefinitionList =
chargeItemDefSearchMapper.getMedList(itemDefSearchParam, pageNo, pageSize, skipCount);
//设置分页条件
chargeItemDefinitionPage.setSize(pageSize);
chargeItemDefinitionPage.setCurrent(pageNo);
if (chargeItemDefinitionList.size() > 0) {
@@ -141,8 +149,10 @@ public class ItemDefinitionController {
return R.ok(chargeItemDefinitionPage,
MessageUtils.createMessage(PromptMsgConstant.Common.M00009, null));
} else if (DefinitionTypeEnum.DEVICE.getCode().equals(itemDefSearchParam.getDefinitionType())) {
//获取定价列表
chargeItemDefinitionList =
chargeItemDefSearchMapper.getDevList(itemDefSearchParam, pageNo, pageSize, skipCount);
//设置分页条件
chargeItemDefinitionPage.setSize(pageSize);
chargeItemDefinitionPage.setCurrent(pageNo);
if (chargeItemDefinitionList.size() > 0) {
@@ -155,8 +165,10 @@ public class ItemDefinitionController {
return R.ok(chargeItemDefinitionPage,
MessageUtils.createMessage(PromptMsgConstant.Common.M00009, null));
} else if (DefinitionTypeEnum.ACTIVITY.getCode().equals(itemDefSearchParam.getDefinitionType())) {
//获取定价列表
chargeItemDefinitionList =
chargeItemDefSearchMapper.getActList(itemDefSearchParam, pageNo, pageSize, skipCount);
//设置分页条件
chargeItemDefinitionPage.setSize(pageSize);
chargeItemDefinitionPage.setCurrent(pageNo);
if (chargeItemDefinitionList.size() > 0) {
@@ -197,4 +209,45 @@ public class ItemDefinitionController {
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"费用定价"}))
: R.fail(PromptMsgConstant.Common.M00007, null);
}
/**
* 采番测试(例子,非常规代码,请勿调用)
*
* @return 采番测试结果
*/
@GetMapping(value = "/test-assign")
public R<?> getTestAssign() {
// 基础采番
String code = assignSeqUtil.getSeq(AssignSeqEnum.TEST.getPrefix());
// 控制长度采番(seqLength: 总长度)
String code1 = assignSeqUtil.getSeq(AssignSeqEnum.TEST.getPrefix(),8);
// 控制长度批量采番
List<String> code2 = assignSeqUtil.getSeq(AssignSeqEnum.TEST.getPrefix(),8,3);
// 获取编号
Integer code3 = assignSeqUtil.getSeqNo(AssignSeqEnum.TEST.getPrefix());
// 批量获取编号
List<Integer> code4 = assignSeqUtil.getSeqNo(AssignSeqEnum.TEST.getPrefix(),3);
// 每日采番
String code5 = assignSeqUtil.getSeqByDay(AssignSeqEnum.TEST.getPrefix());
// 每日按长度采番(seqLength: 日期后的数字位数)
String code6 = assignSeqUtil.getSeqByDay(AssignSeqEnum.TEST.getPrefix(),8);
// 每日批量采番
List<String> code7 = assignSeqUtil.getSeqByDay(AssignSeqEnum.TEST.getPrefix(),8,3);
// 每日获取编号
Integer code8 = assignSeqUtil.getSeqNoByDay(AssignSeqEnum.TEST.getPrefix());
// 每日批量获取编号
List<Integer> code9 = assignSeqUtil.getSeqNoByDay(AssignSeqEnum.TEST.getPrefix(),3);
Map<String, Object> map = new HashMap<>();
map.put("code",code);
map.put("code1",code1);
map.put("code2",code2);
map.put("code3",code3);
map.put("code4",code4);
map.put("code5",code5);
map.put("code6",code6);
map.put("code7",code7);
map.put("code8",code8);
map.put("code9",code9);
return R.ok(map);
}
}