diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/autocode/MesMdAutoCodeRecordDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/autocode/MesMdAutoCodeRecordDO.java index 5ef12a0..e2079e9 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/autocode/MesMdAutoCodeRecordDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/autocode/MesMdAutoCodeRecordDO.java @@ -38,14 +38,14 @@ public class MesMdAutoCodeRecordDO extends BaseDO { */ private String result; /** + * 传入的参数 + */ + private String inputChar; + /** * 生成的流水号 * * 当规则组成中包含流水号分段({@link MesMdAutoCodePartTypeEnum#SERIAL_NUMBER})时记录,方便追溯和调试 */ - private Integer serialNo; - /** - * 传入的参数 - */ - private String inputChar; + private Long serialNo; } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/md/autocode/MesMdAutoCodeRedisDAO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/md/autocode/MesMdAutoCodeRedisDAO.java index edd837f..9163900 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/md/autocode/MesMdAutoCodeRedisDAO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/md/autocode/MesMdAutoCodeRedisDAO.java @@ -19,19 +19,29 @@ public class MesMdAutoCodeRedisDAO { private StringRedisTemplate stringRedisTemplate; /** - * 递增序号(带循环) + * 递增序号(带初始值和循环) * * @param keySuffix key 后缀(不包含 prefix) * @param duration 过期时间 * @param step 步长 + * @param start 起始值(仅在 key 不存在时使用) * @return 递增后的值 */ - public Long increment(String keySuffix, Duration duration, Integer step) { - // 递增值 + public Long increment(String keySuffix, Duration duration, Integer start, Integer step) { String key = RedisKeyConstants.AUTO_CODE + keySuffix; - Long value = stringRedisTemplate.opsForValue().increment(key, step); - // 设置过期时间 + // 情况一:如果 key 不存在,初始化为 startNo + Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(key, String.valueOf(start)); + if (Boolean.TRUE.equals(success)) { + // 设置成功,说明是第一次,设置过期时间并返回 startNo + if (duration != null) { + stringRedisTemplate.expire(key, duration); + } + return start.longValue(); + } + + // 情况二:key 已存在,递增 + Long value = stringRedisTemplate.opsForValue().increment(key, step); if (duration != null) { stringRedisTemplate.expire(key, duration); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/MesMdAutoCodeContext.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/MesMdAutoCodeContext.java index 528cc88..bb1a13b 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/MesMdAutoCodeContext.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/MesMdAutoCodeContext.java @@ -33,6 +33,6 @@ public class MesMdAutoCodeContext { * * 由流水号策略生成并设置,用于保存到生成记录表。例如:当规则包含流水号分段时,生成编码 "ITEM_20260304_0001",此字段值为 1 */ - private Integer serialNo; + private Long serialNo; } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategy.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategy.java index 7a2ecb8..3a5c055 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategy.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategy.java @@ -37,17 +37,17 @@ public class MesMdAutoCodeSerialNumberPartStrategy implements MesMdAutoCodePartS // 1.2 获取过期时间 Duration duration = Boolean.TRUE.equals(part.getCycleFlag()) ? getExpireDuration(part.getCycleMethod()) : null; - // 2.1 获取流水号 + // 2. 获取流水号 Integer step = part.getSerialStep() != null ? part.getSerialStep() : 1; - Long serialNo = redisDAO.increment(keySuffix, duration, step); - // 2.2 保存流水号到上下文 - context.setSerialNo(serialNo.intValue()); + Integer startNo = part.getSerialStartNo() != null ? part.getSerialStartNo() : 1; + Long serialNo = redisDAO.increment(keySuffix, duration, startNo, step); // 3. 格式化输出(补零) String serialStr = String.valueOf(serialNo); if (serialStr.length() < part.getLength()) { serialStr = StrUtil.padPre(serialStr, part.getLength(), '0'); } + context.setSerialNo(serialNo); return serialStr; } @@ -104,7 +104,8 @@ public class MesMdAutoCodeSerialNumberPartStrategy implements MesMdAutoCodePartS } else if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.MINUTE.getMethod())) { return Duration.ofMinutes(2); } else if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.INPUT_CHAR.getMethod())) { - return Duration.ofDays(30); + // 永不过期 + return null; } else { throw new IllegalArgumentException("未知的循环方式:" + cycleMethod); } diff --git a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java index bf56b99..a566df9 100644 --- a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java +++ b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java @@ -81,7 +81,7 @@ public class MesMdAutoCodeRecordServiceImplTest { when(fixedCharStrategy.generate(eq(part1), any(MesMdAutoCodeContext.class))).thenReturn("ITEM_"); when(serialNumberStrategy.generate(eq(part2), any(MesMdAutoCodeContext.class))).thenAnswer(invocation -> { MesMdAutoCodeContext context = invocation.getArgument(1); - context.setSerialNo(1); + context.setSerialNo(1L); return "0001"; }); when(recordMapper.selectByResult("ITEM_0001")).thenReturn(null); diff --git a/yudao-module-mes/src/test/resources/sql/create_tables.sql b/yudao-module-mes/src/test/resources/sql/create_tables.sql index ea7d525..6dd7bd2 100644 --- a/yudao-module-mes/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mes/src/test/resources/sql/create_tables.sql @@ -53,7 +53,7 @@ CREATE TABLE IF NOT EXISTS "mes_md_auto_code_record" ( "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "rule_id" bigint NOT NULL, "result" varchar(64) DEFAULT NULL, - "serial_no" int DEFAULT NULL, + "serial_no" bigint DEFAULT NULL, "input_char" varchar(64) DEFAULT NULL, "creator" varchar(64) DEFAULT '', "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,