Commit e37748783f38d23913afe1c540b3defa2490cb52
1 parent
fded1045
✨ feat(mes): 修改流水号字段类型并更新相关逻辑
将流水号字段类型从 Integer 修改为 Long,以支持更大的序号范围。更新相关的增量生成逻辑,确保在 Redis 中正确处理初始值和步长。同时,调整测试用例以反映这一变化。
Showing
6 changed files
with
29 additions
and
18 deletions
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 { |
| 38 | 38 | */ |
| 39 | 39 | private String result; |
| 40 | 40 | /** |
| 41 | + * 传入的参数 | |
| 42 | + */ | |
| 43 | + private String inputChar; | |
| 44 | + /** | |
| 41 | 45 | * 生成的流水号 |
| 42 | 46 | * |
| 43 | 47 | * 当规则组成中包含流水号分段({@link MesMdAutoCodePartTypeEnum#SERIAL_NUMBER})时记录,方便追溯和调试 |
| 44 | 48 | */ |
| 45 | - private Integer serialNo; | |
| 46 | - /** | |
| 47 | - * 传入的参数 | |
| 48 | - */ | |
| 49 | - private String inputChar; | |
| 49 | + private Long serialNo; | |
| 50 | 50 | |
| 51 | 51 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/redis/md/autocode/MesMdAutoCodeRedisDAO.java
| ... | ... | @@ -19,19 +19,29 @@ public class MesMdAutoCodeRedisDAO { |
| 19 | 19 | private StringRedisTemplate stringRedisTemplate; |
| 20 | 20 | |
| 21 | 21 | /** |
| 22 | - * 递增序号(带循环) | |
| 22 | + * 递增序号(带初始值和循环) | |
| 23 | 23 | * |
| 24 | 24 | * @param keySuffix key 后缀(不包含 prefix) |
| 25 | 25 | * @param duration 过期时间 |
| 26 | 26 | * @param step 步长 |
| 27 | + * @param start 起始值(仅在 key 不存在时使用) | |
| 27 | 28 | * @return 递增后的值 |
| 28 | 29 | */ |
| 29 | - public Long increment(String keySuffix, Duration duration, Integer step) { | |
| 30 | - // 递增值 | |
| 30 | + public Long increment(String keySuffix, Duration duration, Integer start, Integer step) { | |
| 31 | 31 | String key = RedisKeyConstants.AUTO_CODE + keySuffix; |
| 32 | - Long value = stringRedisTemplate.opsForValue().increment(key, step); | |
| 33 | 32 | |
| 34 | - // 设置过期时间 | |
| 33 | + // 情况一:如果 key 不存在,初始化为 startNo | |
| 34 | + Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(key, String.valueOf(start)); | |
| 35 | + if (Boolean.TRUE.equals(success)) { | |
| 36 | + // 设置成功,说明是第一次,设置过期时间并返回 startNo | |
| 37 | + if (duration != null) { | |
| 38 | + stringRedisTemplate.expire(key, duration); | |
| 39 | + } | |
| 40 | + return start.longValue(); | |
| 41 | + } | |
| 42 | + | |
| 43 | + // 情况二:key 已存在,递增 | |
| 44 | + Long value = stringRedisTemplate.opsForValue().increment(key, step); | |
| 35 | 45 | if (duration != null) { |
| 36 | 46 | stringRedisTemplate.expire(key, duration); |
| 37 | 47 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/MesMdAutoCodeContext.java
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 |
| 37 | 37 | // 1.2 获取过期时间 |
| 38 | 38 | Duration duration = Boolean.TRUE.equals(part.getCycleFlag()) ? getExpireDuration(part.getCycleMethod()) : null; |
| 39 | 39 | |
| 40 | - // 2.1 获取流水号 | |
| 40 | + // 2. 获取流水号 | |
| 41 | 41 | Integer step = part.getSerialStep() != null ? part.getSerialStep() : 1; |
| 42 | - Long serialNo = redisDAO.increment(keySuffix, duration, step); | |
| 43 | - // 2.2 保存流水号到上下文 | |
| 44 | - context.setSerialNo(serialNo.intValue()); | |
| 42 | + Integer startNo = part.getSerialStartNo() != null ? part.getSerialStartNo() : 1; | |
| 43 | + Long serialNo = redisDAO.increment(keySuffix, duration, startNo, step); | |
| 45 | 44 | |
| 46 | 45 | // 3. 格式化输出(补零) |
| 47 | 46 | String serialStr = String.valueOf(serialNo); |
| 48 | 47 | if (serialStr.length() < part.getLength()) { |
| 49 | 48 | serialStr = StrUtil.padPre(serialStr, part.getLength(), '0'); |
| 50 | 49 | } |
| 50 | + context.setSerialNo(serialNo); | |
| 51 | 51 | return serialStr; |
| 52 | 52 | } |
| 53 | 53 | |
| ... | ... | @@ -104,7 +104,8 @@ public class MesMdAutoCodeSerialNumberPartStrategy implements MesMdAutoCodePartS |
| 104 | 104 | } else if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.MINUTE.getMethod())) { |
| 105 | 105 | return Duration.ofMinutes(2); |
| 106 | 106 | } else if (cycleMethod.equals(MesMdAutoCodeCycleMethodEnum.INPUT_CHAR.getMethod())) { |
| 107 | - return Duration.ofDays(30); | |
| 107 | + // 永不过期 | |
| 108 | + return null; | |
| 108 | 109 | } else { |
| 109 | 110 | throw new IllegalArgumentException("未知的循环方式:" + cycleMethod); |
| 110 | 111 | } | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java
| ... | ... | @@ -81,7 +81,7 @@ public class MesMdAutoCodeRecordServiceImplTest { |
| 81 | 81 | when(fixedCharStrategy.generate(eq(part1), any(MesMdAutoCodeContext.class))).thenReturn("ITEM_"); |
| 82 | 82 | when(serialNumberStrategy.generate(eq(part2), any(MesMdAutoCodeContext.class))).thenAnswer(invocation -> { |
| 83 | 83 | MesMdAutoCodeContext context = invocation.getArgument(1); |
| 84 | - context.setSerialNo(1); | |
| 84 | + context.setSerialNo(1L); | |
| 85 | 85 | return "0001"; |
| 86 | 86 | }); |
| 87 | 87 | when(recordMapper.selectByResult("ITEM_0001")).thenReturn(null); | ... | ... |
yudao-module-mes/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -53,7 +53,7 @@ CREATE TABLE IF NOT EXISTS "mes_md_auto_code_record" ( |
| 53 | 53 | "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, |
| 54 | 54 | "rule_id" bigint NOT NULL, |
| 55 | 55 | "result" varchar(64) DEFAULT NULL, |
| 56 | - "serial_no" int DEFAULT NULL, | |
| 56 | + "serial_no" bigint DEFAULT NULL, | |
| 57 | 57 | "input_char" varchar(64) DEFAULT NULL, |
| 58 | 58 | "creator" varchar(64) DEFAULT '', |
| 59 | 59 | "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | ... | ... |