Commit 6734be4f8a1092c5bd68dc97275e4a4508186fa7
1 parent
f938ee11
refactor: 统一日期解析、优惠券和 MES 修复代码风格
Showing
8 changed files
with
77 additions
and
68 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/databind/TimestampLocalDateTimeDeserializer.java
| ... | ... | @@ -11,6 +11,7 @@ import java.io.IOException; |
| 11 | 11 | import java.time.Instant; |
| 12 | 12 | import java.time.LocalDateTime; |
| 13 | 13 | import java.time.format.DateTimeFormatter; |
| 14 | +import java.util.regex.Pattern; | |
| 14 | 15 | |
| 15 | 16 | /** |
| 16 | 17 | * LocalDateTime 反序列化器,支持毫秒时间戳、常见日期时间字符串和 ISO-8601 日期。 |
| ... | ... | @@ -21,6 +22,8 @@ public class TimestampLocalDateTimeDeserializer extends JsonDeserializer<LocalDa |
| 21 | 22 | |
| 22 | 23 | public static final TimestampLocalDateTimeDeserializer INSTANCE = new TimestampLocalDateTimeDeserializer(); |
| 23 | 24 | |
| 25 | + private static final Pattern TIMESTAMP_PATTERN = Pattern.compile("-?\\d+"); | |
| 26 | + | |
| 24 | 27 | @Override |
| 25 | 28 | public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { |
| 26 | 29 | String text = p.getText(); |
| ... | ... | @@ -28,14 +31,16 @@ public class TimestampLocalDateTimeDeserializer extends JsonDeserializer<LocalDa |
| 28 | 31 | return null; |
| 29 | 32 | } |
| 30 | 33 | text = text.trim(); |
| 31 | - if (text.matches("-?\\d+")) { | |
| 34 | + // 情况一:毫秒时间戳 | |
| 35 | + if (TIMESTAMP_PATTERN.matcher(text).matches()) { | |
| 32 | 36 | return LocalDateTimeUtil.of(Long.parseLong(text)); |
| 33 | 37 | } |
| 34 | - // Hutool 5.x 的自动解析会忽略部分负时区偏移,并截断纳秒。 | |
| 38 | + // 情况二:ISO-8601 日期;标准解析保留时区偏移与纳秒精度 | |
| 35 | 39 | if (text.contains("T")) { |
| 36 | 40 | return LocalDateTimeUtil.of(DateTimeFormatter.ISO_DATE_TIME.parseBest( |
| 37 | 41 | text, Instant::from, LocalDateTime::from)); |
| 38 | 42 | } |
| 43 | + // 情况三:常见日期时间字符串 | |
| 39 | 44 | return LocalDateTimeUtil.of(DateUtil.parse(text).toInstant()); |
| 40 | 45 | } |
| 41 | 46 | ... | ... |
yudao-framework/yudao-common/src/test/java/cn/iocoder/yudao/framework/common/util/json/databind/TimestampLocalDateTimeDeserializerTest.java
| ... | ... | @@ -4,30 +4,28 @@ import com.fasterxml.jackson.databind.ObjectMapper; |
| 4 | 4 | import com.fasterxml.jackson.databind.module.SimpleModule; |
| 5 | 5 | import org.junit.jupiter.api.Test; |
| 6 | 6 | |
| 7 | +import java.time.Instant; | |
| 7 | 8 | import java.time.LocalDateTime; |
| 9 | +import java.time.OffsetDateTime; | |
| 10 | +import java.time.ZoneId; | |
| 8 | 11 | |
| 9 | 12 | import static org.junit.jupiter.api.Assertions.assertEquals; |
| 10 | -import static org.junit.jupiter.api.Assertions.assertThrows; | |
| 11 | 13 | import static org.junit.jupiter.api.Assertions.assertNull; |
| 14 | +import static org.junit.jupiter.api.Assertions.assertThrows; | |
| 12 | 15 | |
| 13 | 16 | /** |
| 14 | 17 | * {@link TimestampLocalDateTimeDeserializer} 的单元测试 |
| 15 | 18 | * |
| 16 | - * 覆盖全部在用格式(epoch 毫秒 / 常见字符串 / ISO / 纯日期), | |
| 17 | - * 以及非法输入抛清晰错误(不再静默落 1970-01-01)。 | |
| 18 | - * | |
| 19 | 19 | * @author 芋道源码 |
| 20 | 20 | */ |
| 21 | 21 | public class TimestampLocalDateTimeDeserializerTest { |
| 22 | 22 | |
| 23 | - private static final ObjectMapper MAPPER; | |
| 23 | + private static final ObjectMapper MAPPER = new ObjectMapper(); | |
| 24 | 24 | |
| 25 | 25 | static { |
| 26 | - ObjectMapper mapper = new ObjectMapper(); | |
| 27 | 26 | SimpleModule module = new SimpleModule(); |
| 28 | 27 | module.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE); |
| 29 | - mapper.registerModule(module); | |
| 30 | - MAPPER = mapper; | |
| 28 | + MAPPER.registerModule(module); | |
| 31 | 29 | } |
| 32 | 30 | |
| 33 | 31 | private LocalDateTime parse(String json) throws Exception { |
| ... | ... | @@ -37,13 +35,15 @@ public class TimestampLocalDateTimeDeserializerTest { |
| 37 | 35 | @Test |
| 38 | 36 | public void testEpochMilliNumber() throws Exception { |
| 39 | 37 | // 1700000000000 = 2023-11-14T22:13:20Z(本地时区换算后) |
| 40 | - LocalDateTime expected = LocalDateTime.ofInstant(java.time.Instant.ofEpochMilli(1700000000000L), java.time.ZoneId.systemDefault()); | |
| 38 | + LocalDateTime expected = LocalDateTime.ofInstant(Instant.ofEpochMilli(1700000000000L), | |
| 39 | + ZoneId.systemDefault()); | |
| 41 | 40 | assertEquals(expected, parse("1700000000000")); |
| 42 | 41 | } |
| 43 | 42 | |
| 44 | 43 | @Test |
| 45 | 44 | public void testEpochMilliString() throws Exception { |
| 46 | - LocalDateTime expected = LocalDateTime.ofInstant(java.time.Instant.ofEpochMilli(1700000000000L), java.time.ZoneId.systemDefault()); | |
| 45 | + LocalDateTime expected = LocalDateTime.ofInstant(Instant.ofEpochMilli(1700000000000L), | |
| 46 | + ZoneId.systemDefault()); | |
| 47 | 47 | assertEquals(expected, parse("\"1700000000000\"")); |
| 48 | 48 | } |
| 49 | 49 | |
| ... | ... | @@ -71,24 +71,24 @@ public class TimestampLocalDateTimeDeserializerTest { |
| 71 | 71 | @Test |
| 72 | 72 | public void testIsoWithOffset() throws Exception { |
| 73 | 73 | // 前端 Date 对象序列化:带 Z(UTC)。2026-09-11T00:00:00Z 换算到系统时区 |
| 74 | - LocalDateTime expected = java.time.OffsetDateTime.parse("2026-09-11T00:00:00Z") | |
| 75 | - .atZoneSameInstant(java.time.ZoneId.systemDefault()).toLocalDateTime(); | |
| 74 | + LocalDateTime expected = OffsetDateTime.parse("2026-09-11T00:00:00Z") | |
| 75 | + .atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime(); | |
| 76 | 76 | assertEquals(expected, parse("\"2026-09-11T00:00:00Z\"")); |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | @Test |
| 80 | 80 | public void testIsoWithOffsetMillis() throws Exception { |
| 81 | 81 | // JSON.stringify(Date) 实际产物:带毫秒 + Z(无 value-format 的 Date 对象控件提交格式) |
| 82 | - LocalDateTime expected = java.time.OffsetDateTime.parse("2026-09-11T00:00:00.000Z") | |
| 83 | - .atZoneSameInstant(java.time.ZoneId.systemDefault()).toLocalDateTime(); | |
| 82 | + LocalDateTime expected = OffsetDateTime.parse("2026-09-11T00:00:00.000Z") | |
| 83 | + .atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime(); | |
| 84 | 84 | assertEquals(expected, parse("\"2026-09-11T00:00:00.000Z\"")); |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | @Test |
| 88 | 88 | public void testIsoWithOffsetPlus() throws Exception { |
| 89 | 89 | // 带 +08:00 时区偏移的形式 |
| 90 | - LocalDateTime expected = java.time.OffsetDateTime.parse("2026-09-11T08:00:00.000+08:00") | |
| 91 | - .atZoneSameInstant(java.time.ZoneId.systemDefault()).toLocalDateTime(); | |
| 90 | + LocalDateTime expected = OffsetDateTime.parse("2026-09-11T08:00:00.000+08:00") | |
| 91 | + .atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime(); | |
| 92 | 92 | assertEquals(expected, parse("\"2026-09-11T08:00:00.000+08:00\"")); |
| 93 | 93 | } |
| 94 | 94 | |
| ... | ... | @@ -99,16 +99,16 @@ public class TimestampLocalDateTimeDeserializerTest { |
| 99 | 99 | |
| 100 | 100 | @Test |
| 101 | 101 | public void testIsoWithNegativeOffsetAndMillis() throws Exception { |
| 102 | - LocalDateTime expected = java.time.OffsetDateTime.parse("2026-09-11T23:30:00.123-05:30") | |
| 103 | - .atZoneSameInstant(java.time.ZoneId.systemDefault()).toLocalDateTime(); | |
| 102 | + LocalDateTime expected = OffsetDateTime.parse("2026-09-11T23:30:00.123-05:30") | |
| 103 | + .atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime(); | |
| 104 | 104 | assertEquals(expected, parse("\"2026-09-11T23:30:00.123-05:30\"")); |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | @Test |
| 108 | 108 | public void testZeroAndNegativeEpochMilli() throws Exception { |
| 109 | 109 | for (long millis : new long[]{0L, -1L}) { |
| 110 | - LocalDateTime expected = LocalDateTime.ofInstant(java.time.Instant.ofEpochMilli(millis), | |
| 111 | - java.time.ZoneId.systemDefault()); | |
| 110 | + LocalDateTime expected = LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), | |
| 111 | + ZoneId.systemDefault()); | |
| 112 | 112 | assertEquals(expected, parse(Long.toString(millis))); |
| 113 | 113 | assertEquals(expected, parse("\"" + millis + "\"")); |
| 114 | 114 | } |
| ... | ... | @@ -134,9 +134,8 @@ public class TimestampLocalDateTimeDeserializerTest { |
| 134 | 134 | |
| 135 | 135 | @Test |
| 136 | 136 | public void testInvalidThrows() { |
| 137 | - // 非法输入抛清晰错误,不再静默落 1970 | |
| 137 | + // 调用,并断言异常 | |
| 138 | 138 | assertThrows(Exception.class, () -> parse("\"not-a-date\"")); |
| 139 | - | |
| 140 | 139 | } |
| 141 | 140 | |
| 142 | 141 | } | ... | ... |
yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
| ... | ... | @@ -216,13 +216,16 @@ public class CouponServiceImpl implements CouponService { |
| 216 | 216 | public void takeCouponByRegister(Long userId) { |
| 217 | 217 | List<CouponTemplateDO> templates = couponTemplateService.getCouponTemplateListByTakeType(CouponTakeTypeEnum.REGISTER); |
| 218 | 218 | // 1. 过滤不可领取(如已过期)的模板,避免单张异常中断整批 |
| 219 | - List<CouponTemplateDO> takeableTemplates = templates.stream() | |
| 220 | - .filter(this::isCouponTemplateNotExpired) | |
| 221 | - .collect(Collectors.toList()); | |
| 222 | - if (takeableTemplates.size() < templates.size()) { | |
| 223 | - log.info("[takeCouponByRegister][用户({}) 过滤 {} 张不可领取的模板]", userId, templates.size() - takeableTemplates.size()); | |
| 224 | - } | |
| 225 | - // 2. 逐个发放,单张失败不影响其余 | |
| 219 | + List<CouponTemplateDO> takeableTemplates = filterList(templates, template -> { | |
| 220 | + boolean expired = CouponTemplateValidityTypeEnum.DATE.getType().equals(template.getValidityType()) | |
| 221 | + && LocalDateTimeUtils.beforeNow(template.getValidEndTime()); | |
| 222 | + if (expired) { | |
| 223 | + log.warn("[takeCouponByRegister][用户({}) 模板({}) 已过期,跳过发放]", userId, template.getId()); | |
| 224 | + } | |
| 225 | + return !expired; | |
| 226 | + }); | |
| 227 | + | |
| 228 | + // 2.1 逐个发放,单张失败不影响其余 | |
| 226 | 229 | int successCount = 0; |
| 227 | 230 | for (CouponTemplateDO template : takeableTemplates) { |
| 228 | 231 | try { |
| ... | ... | @@ -232,17 +235,12 @@ public class CouponServiceImpl implements CouponService { |
| 232 | 235 | log.error("[takeCouponByRegister][用户({}) 模板({}) 发放失败]", userId, template.getId(), e); |
| 233 | 236 | } |
| 234 | 237 | } |
| 235 | - // 3. 应发全失败时留一条 ERROR 标记,供监控告警 | |
| 238 | + // 2.2 应发全失败时留一条 ERROR 标记,供监控告警 | |
| 236 | 239 | if (CollUtil.isNotEmpty(takeableTemplates) && successCount == 0) { |
| 237 | 240 | log.error("[takeCouponByRegister][用户({}) 全部 {} 张新人券发放失败]", userId, takeableTemplates.size()); |
| 238 | 241 | } |
| 239 | 242 | } |
| 240 | 243 | |
| 241 | - private boolean isCouponTemplateNotExpired(CouponTemplateDO template) { | |
| 242 | - return !CouponTemplateValidityTypeEnum.DATE.getType().equals(template.getValidityType()) | |
| 243 | - || !LocalDateTimeUtils.beforeNow(template.getValidEndTime()); | |
| 244 | - } | |
| 245 | - | |
| 246 | 244 | @Override |
| 247 | 245 | public int expireCoupon() { |
| 248 | 246 | // 1. 查询待过期的优惠券 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/autocode/MesMdAutoCodePartMapper.java
| ... | ... | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.mes.dal.mysql.md.autocode; |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 5 | 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO; |
| 6 | -import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum; | |
| 7 | 6 | import org.apache.ibatis.annotations.Mapper; |
| 8 | 7 | |
| 9 | 8 | import java.util.List; |
| ... | ... | @@ -22,8 +21,8 @@ public interface MesMdAutoCodePartMapper extends BaseMapperX<MesMdAutoCodePartDO |
| 22 | 21 | .orderByAsc(MesMdAutoCodePartDO::getSort)); |
| 23 | 22 | } |
| 24 | 23 | |
| 25 | - default List<MesMdAutoCodePartDO> selectFixedCharPartList() { | |
| 26 | - return selectList(MesMdAutoCodePartDO::getType, MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType()); | |
| 24 | + default List<MesMdAutoCodePartDO> selectByType(Integer type) { | |
| 25 | + return selectList(MesMdAutoCodePartDO::getType, type); | |
| 27 | 26 | } |
| 28 | 27 | |
| 29 | 28 | default void deleteByRuleId(Long ruleId) { | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodePartServiceImpl.java
| ... | ... | @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.part.MesMdAut |
| 7 | 7 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO; |
| 8 | 8 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO; |
| 9 | 9 | import cn.iocoder.yudao.module.mes.dal.mysql.md.autocode.MesMdAutoCodePartMapper; |
| 10 | -import cn.iocoder.yudao.module.mes.dal.mysql.md.autocode.MesMdAutoCodeRuleMapper; | |
| 11 | 10 | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum; |
| 12 | 11 | import jakarta.annotation.Resource; |
| 13 | 12 | import org.springframework.stereotype.Service; |
| ... | ... | @@ -21,6 +20,7 @@ import java.util.Map; |
| 21 | 20 | import java.util.stream.Collectors; |
| 22 | 21 | |
| 23 | 22 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 23 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; | |
| 24 | 24 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.AUTO_CODE_PART_FIXED_CHAR_DUPLICATE; |
| 25 | 25 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.AUTO_CODE_PART_NOT_EXISTS; |
| 26 | 26 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.AUTO_CODE_PART_SERIAL_NUMBER_DUPLICATE; |
| ... | ... | @@ -36,10 +36,6 @@ public class MesMdAutoCodePartServiceImpl implements MesMdAutoCodePartService { |
| 36 | 36 | |
| 37 | 37 | @Resource |
| 38 | 38 | private MesMdAutoCodePartMapper partMapper; |
| 39 | - | |
| 40 | - @Resource | |
| 41 | - private MesMdAutoCodeRuleMapper ruleMapper; | |
| 42 | - | |
| 43 | 39 | @Resource |
| 44 | 40 | private MesMdAutoCodeRuleService ruleService; |
| 45 | 41 | |
| ... | ... | @@ -125,10 +121,10 @@ public class MesMdAutoCodePartServiceImpl implements MesMdAutoCodePartService { |
| 125 | 121 | * 从源头避免不同规则生成相同编码;生成编码时的全局查重仍保留,兜底存量配置的冲突。 |
| 126 | 122 | */ |
| 127 | 123 | private void validateFixedCharUnique(Long id, MesMdAutoCodePartSaveReqVO reqVO) { |
| 128 | - // 1. 全租户固定字符分段,按规则分组 | |
| 129 | - Map<Long, List<MesMdAutoCodePartDO>> fixedPartsByRuleId = partMapper.selectFixedCharPartList().stream() | |
| 130 | - .collect(Collectors.groupingBy(MesMdAutoCodePartDO::getRuleId)); | |
| 131 | - // 2. 本次保存后,本规则的前缀指纹(排除正在修改的分段,加入本次保存的分段) | |
| 124 | + // 1.1 所有固定字符分段,按规则分组 | |
| 125 | + Map<Long, List<MesMdAutoCodePartDO>> fixedPartsByRuleId = convertMultiMap( | |
| 126 | + partMapper.selectByType(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType()), MesMdAutoCodePartDO::getRuleId); | |
| 127 | + // 1.2 本次保存后,本规则的前缀指纹(排除正在修改的分段,加入本次保存的分段) | |
| 132 | 128 | List<MesMdAutoCodePartDO> myFixedParts = new ArrayList<>( |
| 133 | 129 | fixedPartsByRuleId.getOrDefault(reqVO.getRuleId(), Collections.emptyList())); |
| 134 | 130 | myFixedParts.removeIf(part -> ObjUtil.equal(id, part.getId())); |
| ... | ... | @@ -136,20 +132,23 @@ public class MesMdAutoCodePartServiceImpl implements MesMdAutoCodePartService { |
| 136 | 132 | myFixedParts.add(BeanUtils.toBean(reqVO, MesMdAutoCodePartDO.class)); |
| 137 | 133 | } |
| 138 | 134 | String myFingerprint = buildFixedCharFingerprint(myFixedParts); |
| 139 | - // 3. 与租户内其他未删除规则的前缀指纹逐一比对 | |
| 140 | - for (MesMdAutoCodeRuleDO rule : ruleMapper.selectList()) { | |
| 135 | + | |
| 136 | + // 2. 与租户内其他未删除规则的前缀指纹逐一比对 | |
| 137 | + List<MesMdAutoCodeRuleDO> rules = ruleService.getAutoCodeRuleList(); | |
| 138 | + for (MesMdAutoCodeRuleDO rule : rules) { | |
| 141 | 139 | if (ObjUtil.equal(rule.getId(), reqVO.getRuleId())) { |
| 142 | 140 | continue; |
| 143 | 141 | } |
| 144 | 142 | List<MesMdAutoCodePartDO> otherFixedParts = fixedPartsByRuleId.getOrDefault(rule.getId(), Collections.emptyList()); |
| 145 | - if (myFingerprint.equals(buildFixedCharFingerprint(otherFixedParts))) { | |
| 143 | + String otherFingerprint = buildFixedCharFingerprint(otherFixedParts); | |
| 144 | + if (myFingerprint.equals(otherFingerprint)) { | |
| 146 | 145 | throw exception(AUTO_CODE_PART_FIXED_CHAR_DUPLICATE); |
| 147 | 146 | } |
| 148 | 147 | } |
| 149 | 148 | } |
| 150 | 149 | |
| 151 | 150 | /** |
| 152 | - * 构建前缀指纹:固定字符分段按分段排序,拼接截取到分段长度内的固定字符(空值按空串) | |
| 151 | + * 构建固定字符分段的前缀指纹:按分段排序,拼接截取到分段长度内的固定字符 | |
| 153 | 152 | */ |
| 154 | 153 | private String buildFixedCharFingerprint(List<MesMdAutoCodePartDO> fixedParts) { |
| 155 | 154 | return fixedParts.stream() | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRuleService.java
| ... | ... | @@ -46,6 +46,13 @@ public interface MesMdAutoCodeRuleService { |
| 46 | 46 | MesMdAutoCodeRuleDO getAutoCodeRule(Long id); |
| 47 | 47 | |
| 48 | 48 | /** |
| 49 | + * 获得编码规则列表 | |
| 50 | + * | |
| 51 | + * @return 编码规则列表 | |
| 52 | + */ | |
| 53 | + List<MesMdAutoCodeRuleDO> getAutoCodeRuleList(); | |
| 54 | + | |
| 55 | + /** | |
| 49 | 56 | * 获得编码规则分页 |
| 50 | 57 | * |
| 51 | 58 | * @param pageReqVO 分页查询 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRuleServiceImpl.java
| ... | ... | @@ -73,6 +73,11 @@ public class MesMdAutoCodeRuleServiceImpl implements MesMdAutoCodeRuleService { |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | 75 | @Override |
| 76 | + public List<MesMdAutoCodeRuleDO> getAutoCodeRuleList() { | |
| 77 | + return ruleMapper.selectList(); | |
| 78 | + } | |
| 79 | + | |
| 80 | + @Override | |
| 76 | 81 | public PageResult<MesMdAutoCodeRuleDO> getAutoCodeRulePage(MesMdAutoCodeRulePageReqVO pageReqVO) { |
| 77 | 82 | return ruleMapper.selectPage(pageReqVO); |
| 78 | 83 | } | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodePartServiceImplTest.java
| ... | ... | @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.part.MesMdAut |
| 5 | 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO; |
| 6 | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO; |
| 7 | 7 | import cn.iocoder.yudao.module.mes.dal.mysql.md.autocode.MesMdAutoCodePartMapper; |
| 8 | -import cn.iocoder.yudao.module.mes.dal.mysql.md.autocode.MesMdAutoCodeRuleMapper; | |
| 9 | 8 | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum; |
| 10 | 9 | import org.junit.jupiter.api.Test; |
| 11 | 10 | import org.junit.jupiter.api.extension.ExtendWith; |
| ... | ... | @@ -37,8 +36,6 @@ public class MesMdAutoCodePartServiceImplTest { |
| 37 | 36 | @Mock |
| 38 | 37 | private MesMdAutoCodePartMapper partMapper; |
| 39 | 38 | @Mock |
| 40 | - private MesMdAutoCodeRuleMapper ruleMapper; | |
| 41 | - @Mock | |
| 42 | 39 | private MesMdAutoCodeRuleService ruleService; |
| 43 | 40 | |
| 44 | 41 | private static MesMdAutoCodePartDO fixedPart(Long id, Long ruleId, Integer sort, String fixCharacter, Integer length) { |
| ... | ... | @@ -61,9 +58,9 @@ public class MesMdAutoCodePartServiceImplTest { |
| 61 | 58 | @Test |
| 62 | 59 | public void testCreateAutoCodePart_fixedCharDuplicate() { |
| 63 | 60 | // 准备:其他规则已占用相同前缀 "ITEM_" |
| 64 | - when(partMapper.selectFixedCharPartList()).thenReturn(Arrays.asList( | |
| 61 | + when(partMapper.selectByType(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType())).thenReturn(Arrays.asList( | |
| 65 | 62 | fixedPart(1L, 1L, 1, "ITEM_", 5))); |
| 66 | - when(ruleMapper.selectList()).thenReturn(Arrays.asList( | |
| 63 | + when(ruleService.getAutoCodeRuleList()).thenReturn(Arrays.asList( | |
| 67 | 64 | new MesMdAutoCodeRuleDO().setId(1L), new MesMdAutoCodeRuleDO().setId(10L))); |
| 68 | 65 | |
| 69 | 66 | // 断言:保存被拒,且未插入 |
| ... | ... | @@ -76,9 +73,9 @@ public class MesMdAutoCodePartServiceImplTest { |
| 76 | 73 | @Test |
| 77 | 74 | public void testCreateAutoCodePart_fixedCharUnique() { |
| 78 | 75 | // 准备:其他规则前缀 "ITEM_",本次保存 "SN_" |
| 79 | - when(partMapper.selectFixedCharPartList()).thenReturn(Arrays.asList( | |
| 76 | + when(partMapper.selectByType(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType())).thenReturn(Arrays.asList( | |
| 80 | 77 | fixedPart(1L, 1L, 1, "ITEM_", 5))); |
| 81 | - when(ruleMapper.selectList()).thenReturn(Arrays.asList( | |
| 78 | + when(ruleService.getAutoCodeRuleList()).thenReturn(Arrays.asList( | |
| 82 | 79 | new MesMdAutoCodeRuleDO().setId(1L), new MesMdAutoCodeRuleDO().setId(10L))); |
| 83 | 80 | |
| 84 | 81 | // 断言:保存成功 |
| ... | ... | @@ -89,9 +86,9 @@ public class MesMdAutoCodePartServiceImplTest { |
| 89 | 86 | @Test |
| 90 | 87 | public void testCreateAutoCodePart_fixedCharTruncatedDuplicate() { |
| 91 | 88 | // 准备:其他规则固定字符 "IT_X" 长度 2(生成时截断为 "IT") |
| 92 | - when(partMapper.selectFixedCharPartList()).thenReturn(Arrays.asList( | |
| 89 | + when(partMapper.selectByType(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType())).thenReturn(Arrays.asList( | |
| 93 | 90 | fixedPart(1L, 1L, 1, "IT_X", 2))); |
| 94 | - when(ruleMapper.selectList()).thenReturn(Arrays.asList( | |
| 91 | + when(ruleService.getAutoCodeRuleList()).thenReturn(Arrays.asList( | |
| 95 | 92 | new MesMdAutoCodeRuleDO().setId(1L), new MesMdAutoCodeRuleDO().setId(10L))); |
| 96 | 93 | |
| 97 | 94 | // 断言:本次保存 "IT" 截断后同为 "IT",保存被拒 |
| ... | ... | @@ -104,8 +101,8 @@ public class MesMdAutoCodePartServiceImplTest { |
| 104 | 101 | @Test |
| 105 | 102 | public void testCreateAutoCodePart_bothRulesWithoutFixedChar() { |
| 106 | 103 | // 准备:租户内另一规则无任何固定字符分段(前缀为空串),本次保存流水号分段(本规则也无固定字符) |
| 107 | - when(partMapper.selectFixedCharPartList()).thenReturn(Collections.emptyList()); | |
| 108 | - when(ruleMapper.selectList()).thenReturn(Arrays.asList( | |
| 104 | + when(partMapper.selectByType(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType())).thenReturn(Collections.emptyList()); | |
| 105 | + when(ruleService.getAutoCodeRuleList()).thenReturn(Arrays.asList( | |
| 109 | 106 | new MesMdAutoCodeRuleDO().setId(1L), new MesMdAutoCodeRuleDO().setId(10L))); |
| 110 | 107 | |
| 111 | 108 | MesMdAutoCodePartSaveReqVO reqVO = new MesMdAutoCodePartSaveReqVO(); |
| ... | ... | @@ -127,9 +124,9 @@ public class MesMdAutoCodePartServiceImplTest { |
| 127 | 124 | // 准备:本规则已有固定字符 "OLD_",修改为与其他规则相同的 "ITEM_" |
| 128 | 125 | MesMdAutoCodePartDO myPart = fixedPart(100L, 10L, 1, "OLD_", 4); |
| 129 | 126 | when(partMapper.selectById(100L)).thenReturn(myPart); |
| 130 | - when(partMapper.selectFixedCharPartList()).thenReturn(Arrays.asList( | |
| 127 | + when(partMapper.selectByType(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType())).thenReturn(Arrays.asList( | |
| 131 | 128 | myPart, fixedPart(1L, 1L, 1, "ITEM_", 5))); |
| 132 | - when(ruleMapper.selectList()).thenReturn(Arrays.asList( | |
| 129 | + when(ruleService.getAutoCodeRuleList()).thenReturn(Arrays.asList( | |
| 133 | 130 | new MesMdAutoCodeRuleDO().setId(1L), new MesMdAutoCodeRuleDO().setId(10L))); |
| 134 | 131 | |
| 135 | 132 | // 断言:保存被拒,且未更新 |
| ... | ... | @@ -144,9 +141,9 @@ public class MesMdAutoCodePartServiceImplTest { |
| 144 | 141 | // 准备:本规则已有固定字符 "ITEM_"(与其他规则重复),修改为 "SN_" |
| 145 | 142 | MesMdAutoCodePartDO myPart = fixedPart(100L, 10L, 1, "ITEM_", 5); |
| 146 | 143 | when(partMapper.selectById(100L)).thenReturn(myPart); |
| 147 | - when(partMapper.selectFixedCharPartList()).thenReturn(Arrays.asList( | |
| 144 | + when(partMapper.selectByType(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType())).thenReturn(Arrays.asList( | |
| 148 | 145 | myPart, fixedPart(1L, 1L, 1, "WO_", 3))); |
| 149 | - when(ruleMapper.selectList()).thenReturn(Arrays.asList( | |
| 146 | + when(ruleService.getAutoCodeRuleList()).thenReturn(Arrays.asList( | |
| 150 | 147 | new MesMdAutoCodeRuleDO().setId(1L), new MesMdAutoCodeRuleDO().setId(10L))); |
| 151 | 148 | |
| 152 | 149 | // 断言:修改后前缀不再重复,保存成功 | ... | ... |