feat: 新增编码预览功能

- 后端新增 /rpc-api/base/code-gen/preview 接口
- SequenceAllocator.preview 查询序号但不消耗
- 前端操作列新增预览按钮,弹窗展示下一个编码
This commit is contained in:
zhouz
2026-07-15 18:14:40 +08:00
parent f3ef75f990
commit fbc5554c6a
7 changed files with 125 additions and 3 deletions

View File

@@ -8,9 +8,11 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import static cn.code.nl.framework.common.pojo.CommonResult.success;
@@ -39,4 +41,11 @@ public class CodeGenController {
return success(code);
}
@GetMapping("/preview")
@Operation(summary = "预览下一个编码(不消耗序号)")
public CommonResult<String> preview(@RequestParam("ruleCode") String ruleCode) {
String code = codeGenService.preview(ruleCode);
return success(code);
}
}

View File

@@ -15,4 +15,12 @@ public interface CodeGenService {
*/
String generate(String ruleCode);
/**
* 预览下一个编码(不消耗序号)
*
* @param ruleCode 规则编码
* @return 预览的编码
*/
String preview(String ruleCode);
}

View File

@@ -54,6 +54,26 @@ public class CodeGenServiceImpl implements CodeGenService {
return postProcess(sb.toString(), rule);
}
@Override
public String preview(String ruleCode) {
// 1. 获取规则配置
CodeRuleDO rule = codeRuleService.getRuleByCode(ruleCode);
// 2. 遍历分段SEQUENCE 段用 preview不消耗序号
List<SegmentConfig> segments = rule.getSegmentConfig();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < segments.size(); i++) {
String segmentValue = buildPreviewSegment(rule, segments.get(i));
sb.append(segmentValue);
if (i < segments.size() - 1 && StrUtil.isNotBlank(rule.getSeparator())) {
sb.append(rule.getSeparator());
}
}
// 3. 后处理
return postProcess(sb.toString(), rule);
}
/**
* 根据段类型分发处理,生成段值
*/
@@ -66,6 +86,18 @@ public class CodeGenServiceImpl implements CodeGenService {
};
}
/**
* 预览模式分发SEQUENCE 段不消耗序号)
*/
private String buildPreviewSegment(CodeRuleDO rule, SegmentConfig segment) {
return switch (segment.getType()) {
case "PREFIX" -> buildPrefixSegment(segment);
case "DATE" -> buildDateSegment(segment);
case "SEQUENCE" -> sequenceAllocator.preview(rule.getId(), segment);
default -> throw new IllegalArgumentException("不支持的段类型: " + segment.getType());
};
}
/**
* 生成固定前缀段
*/

View File

@@ -189,4 +189,19 @@ public class SequenceAllocator {
return paddingChar.repeat(paddingLen - raw.length()) + raw;
}
/**
* 预览下一个序号(不实际分配,不更新数据库)
*
* @param ruleId 规则ID
* @param segment 序号段配置
* @return 格式化后的序号字符串
*/
public String preview(Long ruleId, SegmentConfig segment) {
String resetKey = buildResetKey(segment.getResetBy());
CodeSequenceDO seq = codeSequenceMapper.selectByRuleIdAndResetKey(ruleId, resetKey);
Long startAt = segment.getStartAt() != null ? segment.getStartAt() : 1L;
long nextValue = (seq != null) ? seq.getCurrentValue() + 1 : startAt;
return formatSequence(nextValue, segment);
}
}