From f3ef75f9904ebf56b0727c5242963d9d8ef23de1 Mon Sep 17 00:00:00 2001 From: zhouz <> Date: Wed, 15 Jul 2026 18:08:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=94=BE=E5=BC=83Jackson=E5=A4=9A?= =?UTF-8?q?=E6=80=81=EF=BC=8C=E6=94=B9=E7=94=A8=E6=99=AE=E9=80=9ADTO?= =?UTF-8?q?=E9=81=BF=E5=85=8Dtype=E5=BA=8F=E5=88=97=E5=8C=96=E5=86=B2?= =?UTF-8?q?=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SegmentConfig改为普通POJO,移除@JsonTypeInfo和子类 - CodeGenServiceImpl/SequenceAllocator直接用SegmentConfig - 彻底消除type字段序列化/反序列化的冲突问题 --- .../service/codegen/CodeGenServiceImpl.java | 23 +++---- .../service/codegen/SequenceAllocator.java | 12 ++-- .../base/service/codegen/dto/DateSegment.java | 20 ------ .../service/codegen/dto/PrefixSegment.java | 20 ------ .../service/codegen/dto/SegmentConfig.java | 62 +++++++++++++++---- .../service/codegen/dto/SequenceSegment.java | 40 ------------ 6 files changed, 65 insertions(+), 112 deletions(-) delete mode 100644 nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/DateSegment.java delete mode 100644 nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/PrefixSegment.java delete mode 100644 nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/SequenceSegment.java diff --git a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/CodeGenServiceImpl.java b/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/CodeGenServiceImpl.java index 5ca18d0b..4d2623e7 100644 --- a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/CodeGenServiceImpl.java +++ b/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/CodeGenServiceImpl.java @@ -1,10 +1,7 @@ package cn.code.nl.module.base.service.codegen; import cn.code.nl.module.base.dal.dataobject.codegen.CodeRuleDO; -import cn.code.nl.module.base.service.codegen.dto.DateSegment; -import cn.code.nl.module.base.service.codegen.dto.PrefixSegment; import cn.code.nl.module.base.service.codegen.dto.SegmentConfig; -import cn.code.nl.module.base.service.codegen.dto.SequenceSegment; import cn.code.nl.module.base.service.codegen.enums.LetterCaseEnum; import cn.code.nl.module.base.service.codegen.enums.SeqStrategyEnum; import cn.hutool.core.util.StrUtil; @@ -61,27 +58,25 @@ public class CodeGenServiceImpl implements CodeGenService { * 根据段类型分发处理,生成段值 */ private String buildSegment(CodeRuleDO rule, SegmentConfig segment) { - if (segment instanceof PrefixSegment) { - return buildPrefixSegment((PrefixSegment) segment); - } else if (segment instanceof DateSegment) { - return buildDateSegment((DateSegment) segment); - } else if (segment instanceof SequenceSegment) { - return buildSequenceSegment(rule, (SequenceSegment) segment); - } - throw new IllegalArgumentException("不支持的段类型: " + segment.getClass().getSimpleName()); + return switch (segment.getType()) { + case "PREFIX" -> buildPrefixSegment(segment); + case "DATE" -> buildDateSegment(segment); + case "SEQUENCE" -> buildSequenceSegment(rule, segment); + default -> throw new IllegalArgumentException("不支持的段类型: " + segment.getType()); + }; } /** * 生成固定前缀段 */ - private String buildPrefixSegment(PrefixSegment segment) { + private String buildPrefixSegment(SegmentConfig segment) { return segment.getValue() != null ? segment.getValue() : ""; } /** * 生成日期段 */ - private String buildDateSegment(DateSegment segment) { + private String buildDateSegment(SegmentConfig segment) { String format = StrUtil.isNotBlank(segment.getFormat()) ? segment.getFormat() : "yyyyMMdd"; return LocalDate.now().format(DateTimeFormatter.ofPattern(format)); @@ -90,7 +85,7 @@ public class CodeGenServiceImpl implements CodeGenService { /** * 生成流水序号段 */ - private String buildSequenceSegment(CodeRuleDO rule, SequenceSegment segment) { + private String buildSequenceSegment(CodeRuleDO rule, SegmentConfig segment) { String strategy = rule.getSeqStrategy(); if (SeqStrategyEnum.LOCK.getCode().equals(strategy)) { return sequenceAllocator.allocateByLock(rule.getId(), segment); diff --git a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/SequenceAllocator.java b/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/SequenceAllocator.java index 852dab90..40081672 100644 --- a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/SequenceAllocator.java +++ b/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/SequenceAllocator.java @@ -2,7 +2,7 @@ package cn.code.nl.module.base.service.codegen; import cn.code.nl.module.base.dal.dataobject.codegen.CodeSequenceDO; import cn.code.nl.module.base.dal.mysql.codegen.CodeSequenceMapper; -import cn.code.nl.module.base.service.codegen.dto.SequenceSegment; +import cn.code.nl.module.base.service.codegen.dto.SegmentConfig; import cn.code.nl.module.base.service.codegen.enums.ResetByEnum; import cn.hutool.core.util.StrUtil; import com.baomidou.lock.annotation.Lock4j; @@ -57,7 +57,7 @@ public class SequenceAllocator { * @param segment 序号段配置 * @return 格式化后的序号字符串 */ - public String allocateBySegment(Long ruleId, SequenceSegment segment) { + public String allocateBySegment(Long ruleId, SegmentConfig segment) { String resetKey = buildResetKey(segment.getResetBy()); String cacheKey = ruleId + ":" + resetKey; @@ -87,7 +87,7 @@ public class SequenceAllocator { * @param segment 序号段配置 * @return 格式化后的序号字符串 */ - public String allocateByLock(Long ruleId, SequenceSegment segment) { + public String allocateByLock(Long ruleId, SegmentConfig segment) { String resetKey = buildResetKey(segment.getResetBy()); String lockKey = "codegen:seq:lock:" + ruleId + ":" + resetKey; return self.allocateWithLock(lockKey, ruleId, resetKey, segment); @@ -98,7 +98,7 @@ public class SequenceAllocator { */ @Lock4j(keys = "#lockKey", acquireTimeout = 3000, expire = 5000) public long fetchSegmentWithLock(String lockKey, String cacheKey, Long ruleId, - String resetKey, SequenceSegment segment) { + String resetKey, SegmentConfig segment) { // double-check:其他线程可能已经预取了 AtomicLong existing = localSegmentCache.get(cacheKey); if (existing != null) { @@ -136,7 +136,7 @@ public class SequenceAllocator { * Lock4j 保护下实时分配序号 */ @Lock4j(keys = "#lockKey", acquireTimeout = 3000, expire = 5000) - public String allocateWithLock(String lockKey, Long ruleId, String resetKey, SequenceSegment segment) { + public String allocateWithLock(String lockKey, Long ruleId, String resetKey, SegmentConfig segment) { Long startAt = segment.getStartAt() != null ? segment.getStartAt() : 1L; // step=1 每次只取一个号 codeSequenceMapper.updateCurrentValueBySegment(ruleId, resetKey, 1, startAt, segment.getMaxValue()); @@ -178,7 +178,7 @@ public class SequenceAllocator { * @param segment 序号段配置 * @return 格式化后的字符串 */ - public String formatSequence(long value, SequenceSegment segment) { + public String formatSequence(long value, SegmentConfig segment) { String raw = String.valueOf(value); int paddingLen = segment.getPaddingLen() != null ? segment.getPaddingLen() : 0; if (paddingLen <= 0 || raw.length() >= paddingLen) { diff --git a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/DateSegment.java b/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/DateSegment.java deleted file mode 100644 index 382fd548..00000000 --- a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/DateSegment.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.code.nl.module.base.service.codegen.dto; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * 日期段配置 - * - * @author zhouz - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class DateSegment extends SegmentConfig { - - /** - * 日期格式,如 "yyyyMMdd"、"yyyyMM"、"yyyy" - */ - private String format; - -} diff --git a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/PrefixSegment.java b/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/PrefixSegment.java deleted file mode 100644 index cd61a833..00000000 --- a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/PrefixSegment.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.code.nl.module.base.service.codegen.dto; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * 固定前缀段配置 - * - * @author zhouz - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class PrefixSegment extends SegmentConfig { - - /** - * 固定前缀值,如 "ORD" - */ - private String value; - -} diff --git a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/SegmentConfig.java b/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/SegmentConfig.java index df20c511..75cf785c 100644 --- a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/SegmentConfig.java +++ b/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/SegmentConfig.java @@ -1,22 +1,60 @@ package cn.code.nl.module.base.service.codegen.dto; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; import lombok.Data; /** - * 分段配置基类,使用 Jackson 多态序列化/反序列化。 - * 注意:type 字段由 @JsonTypeInfo 自动管理,不要在子类中重复定义, - * 否则会导致序列化时 type 被覆盖为 null,反序列化时找不到子类型。 + * 分段配置 —— 通用 DTO,不做 Jackson 多态。 + * type 决定了哪些字段有效:PREFIX→value, DATE→format, SEQUENCE→resetBy/startAt/paddingLen/paddingChar/maxValue * * @author zhouz */ @Data -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true) -@JsonSubTypes({ - @JsonSubTypes.Type(value = PrefixSegment.class, name = "PREFIX"), - @JsonSubTypes.Type(value = DateSegment.class, name = "DATE"), - @JsonSubTypes.Type(value = SequenceSegment.class, name = "SEQUENCE") -}) -public abstract class SegmentConfig { +public class SegmentConfig { + + /** + * 段类型:PREFIX / DATE / SEQUENCE + */ + private String type; + + // ========== PREFIX 段 ========== + + /** + * 固定值,如 "ORD" + */ + private String value; + + // ========== DATE 段 ========== + + /** + * 日期格式,如 "yyyyMMdd" + */ + private String format; + + // ========== SEQUENCE 段 ========== + + /** + * 重置维度:DAY / MONTH / YEAR / GLOBAL + */ + private String resetBy; + + /** + * 起始值,默认 1 + */ + private Long startAt; + + /** + * 补位后的总长度,如 4 → 0001 + */ + private Integer paddingLen; + + /** + * 补位字符,默认 "0" + */ + private String paddingChar; + + /** + * 序号最大值上限 + */ + private Long maxValue; + } diff --git a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/SequenceSegment.java b/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/SequenceSegment.java deleted file mode 100644 index 0b0d6057..00000000 --- a/nl-module-base/nl-module-base-server/src/main/java/cn/code/nl/module/base/service/codegen/dto/SequenceSegment.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.code.nl.module.base.service.codegen.dto; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * 流水序号段配置 - * - * @author zhouz - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class SequenceSegment extends SegmentConfig { - - /** - * 重置维度:DAY / MONTH / YEAR / GLOBAL - */ - private String resetBy; - - /** - * 起始值,默认 1 - */ - private Long startAt; - - /** - * 补位后的总长度,如 4 → 0001 - */ - private Integer paddingLen; - - /** - * 补位字符,默认 "0" - */ - private String paddingChar; - - /** - * 序号最大值上限 - */ - private Long maxValue; - -}