# 编码规则设定 功能需求文档
> 文档版本:1.0
> 编写日期:2026-07-16
> 状态:已实现
---
## 1. 概述
### 1.1 文档目的
本文档描述 Forge 平台「编码规则设定」功能的功能性需求,作为产品验收、用户使用及后续迭代的依据。
### 1.2 功能背景
Forge 原有编码规则能力(`ai_code_rule`)采用单表+模板字符串方式(如 `WL${yyyyMMdd}${seq:3}`),仅满足简单自动编号场景。面对 MES/ERP/WMS 等企业级场景,业务方对编码规则提出了更结构化、可视化、分段可控的要求,包括按段定义、实时预览、流水号重置与分组计数等。
为此,平台将编码规则重构为**分段式模型**(主表 + 分段明细子表),升级为平台级基础能力,统一服务于单据编号、载具编码、料箱编码、物料编码等所有业务模块。
### 1.3 功能目标
1. 提供结构化、可视化的分段式编码规则配置能力
2. 支持日期、固定字元、流水号、变量值、系统变量五种段类型
3. 支持流水号按时间周期重置与按业务字段分组独立计数
4. 提供编码实时预览能力,所见即所得
5. 提供统一的编码生成接口,供各业务模块调用
6. 平滑迁移旧编码规则数据,保证业务连续性
---
## 2. 用户角色与使用场景
| 角色 | 权限范围 | 典型场景 |
|------|---------|---------|
| 系统管理员 | 规则的新增/修改/删除/启停/预览/生成 | 配置载具编码、料箱编码、单据编号等平台规则 |
| 业务系统(调用方) | 调用生成接口获取编号 | 低代码业务对象新增时自动编号、单据生成时取号 |
| 普通用户 | 查看启用规则列表 | 业务表单中选择/查看可用编码规则 |
---
## 3. 功能需求
### FR1. 编码规则主表管理(CRUD)
**需求描述**:系统管理员可对编码规则主记录进行新增、修改、删除、分页查询、查看详情及启用/停用操作。
**功能要点**:
- 新增规则时填写:规则编码、规则名称、编码分类、版本号、说明、是否列入编码列表、状态(分组在分段级以"前置码"形式配置)
- 规则编码(rule_code)在同一租户下唯一,格式为大写字母+数字+下划线,建议格式 `模块_实体_ID`(如 `CARRIER_ID`、`PO_ORDER_NO`)
- 编码分类使用数据字典管理,内置载具编码、料箱编码、料盒编码、单据编码、物料编码、设备编码、库位编码等分类,用户可扩展
- 状态支持启用/停用切换;停用的规则不参与生成,调用时报错提示
- 内置规则标记为内置(builtin),内置规则不允许删除,仅允许修改名称与说明
- 删除规则采用逻辑删除,保留历史数据
**验收标准**:
- 可成功新增、修改、删除、启停编码规则
- 规则编码重复时保存报错
- 内置规则删除按钮禁用/拦截
- 支持按规则编码、规则名称、分类、状态进行分页筛选查询
---
### FR2. 分段明细配置
**需求描述**:在规则编辑界面内,以可视化表格形式维护编码规则的分段明细,支持动态增删与排序。
**功能要点**:
- 每个规则包含若干分段,按段序号(从1开始)决定拼接顺序
- 支持添加分段、删除分段、上移/下移调整顺序
- 每段可配置:段类型、编码格式/值、长度、是否补位、补位字符、补位方向、**是否分组(前置码)**、是否列入编码
- **前置码即分组**:将某段标记为"前置码"(is_prefix=Y),即表示该段值作为 SEQ 流水号的分组依据;例如把 SYS_VAR(orgCode) 段标记为前置码,则不同 orgCode 各自独立计数
- 顺序位数(SEQ)段额外配置:进制类型、是否重置、重置周期、起始值(**分组无需单独配置分组字段,由前置码段自动决定**)
- 段类型切换时,相关配置项自动联动(如非 SEQ 段的重置相关字段置灰)
- SEQ 类型行高亮显示以便识别
- 保存规则时,分段明细以全量覆盖方式更新(先删后插)
**验收标准**:
- 可在弹窗内增删改分段并调整顺序
- 分段配置项随段类型联动正确
- 保存后分段顺序与配置正确持久化
---
### FR3. 五种段类型支持
**需求描述**:系统支持五种段类型,覆盖企业编码的全部场景。
| 段类型 | 说明 | 格式值示例 | 典型用途 |
|--------|------|-----------|---------|
| DATE 日期变数 | 按当前时间格式化 | `yyyyMMdd`、`yyyyMM`、`yyyy` | 单据日期前缀 |
| FIXED 固定字元 | 常量字符串直接拼接 | `WL`、`HT`、`CG` | 业务标识前缀 |
| SEQ 顺序位数 | 流水号递增 | `DECIMAL`、`HEX`、`ALPHA_UPPER`、`ALPHA_LOWER`、`ALPHANUMERIC` | 序号、字母递增编码 |
| VARIABLE 变量值 | 运行时由调用方传入变量取值(合并原字典值与字段引用) | `warehouseCode`、`warehouseType` | 按业务字段/字典分类编码、分组计数 |
| SYS_VAR 系统变量 | 取当前系统上下文值 | `tenantId`、`orgCode`、`userId` | 租户/组织维度 |
**功能要点**:
- DATE 段支持年(y/yy/yyyy)、月(M/MM)、日(d/dd)、时(H/HH)、分(m/mm)、秒(s/ss)格式符
- SEQ 段支持5种进制,**字母也是流水号的一种进制形式**,统一通过进制类型配置:
- `DECIMAL` 十进制:0-9(最常用,如 `0001`、`9999`)
- `HEX` 十六进制:0-9A-F(如 `000A`、`00FF`)
- `ALPHA_UPPER` 大写字母:默认 A-Z 全集26个字符;可选去除易混淆字符后为 A-H、J-N、P-Y 共23个字符
- `ALPHA_LOWER` 小写字母:默认 a-z 全集26个字符;可选去除易混淆字符后为 a-h、j-n、p-y 共23个字符
- `ALPHANUMERIC` 字母数字:默认 0-9A-Z 全集36个字符;可选去除易混淆字符后为 0-9 + A-H + J-N + P-Y 共33个字符(容量最大)
- **去除易混淆字符**(可选开关,仅字母进制生效):SEQ 段配置 `excludeAmbiguous`(Y/N),开启后字母进制去除 `I`、`O`、`Z`(及小写 `i`、`o`、`z`),因与数字 `1`、`0`、`2` 相似易混淆;默认关闭(使用完整字符集)
- SEQ 段支持补位(默认左补 `0`)与溢出检测(超出长度范围时报错)
- **VARIABLE 变量值段使用方式**(合并原 DICT 字典值与 FIELD 字段引用):
- 配置时:`seg_format` 填写**变量名**(即取值 key),可表示业务字段(如 `warehouseCode`)或字典分类(如 `warehouseType`),长度按需设置
- 生成时:变量值由调用方通过入参 `fields` **统一传入**,不在规则中固定;不再区分 dictValues 与 fields
- 取值逻辑:生成遍历到 VARIABLE 段时,按 `seg_format`(变量名)从 `fields` Map 取值并拼入编码
- 缺值报错:取不到值时抛异常 `变量值[xxx]未提供`,调用方必须提供
- 可分组:VARIABLE 段可标记为"前置码"(is_prefix=Y),其值作为 SEQ 流水号的分组依据
- **VARIABLE 段使用示例**:
- 示例1(业务字段):FIXED("WH") + VARIABLE(`warehouseCode`, 长度4) + SEQ(DECIMAL, 3位);调用传入 `fields: { "warehouseCode": "WH01" }` -> `WHWH01001`
- 示例2(字典分类):FIXED("M") + VARIABLE(`warehouseType`, 长度2) + SEQ(DECIMAL, 4位);调用传入 `fields: { "warehouseType": "01" }` -> `M010001`、`M010002`
- 示例3(前置码分组):VARIABLE(`orgCode`, 前置码=Y) + DATE(yyyyMMdd) + SEQ(DECIMAL, 4位, 按日);不同 orgCode 各自独立计数
- SYS_VAR 段支持租户ID、用户ID、用户名、部门编码、组织编码、套件编码、对象编码等变量
**典型场景**:
- 数字流水号:FIXED("CG") + SEQ(DECIMAL, 4位) -> `CG0001`、`CG0002`
- 字母流水号:FIXED("A") + SEQ(ALPHA_UPPER, 2位) -> `AA`、`AB`、`AC`(适用于货架库位编码;可开启去除易混淆字符避免 I/O/Z 与 1/0/2 混淆)
- 十六进制流水号:SEQ(HEX, 4位) -> `0001`、`000A`、`000F`、`0010`
**流水号进制组合示例**:
下表针对 SEQ 段的 5 种进制,分别给出「规则配置 + 前 5 个生成序列 + 溢出边界」的完整示例,便于直观理解每种进制的递增与进位规则。
| 进制类型 | 规则组合(段配置) | 补位 | 长度 | 生成序列示例(前5个) | 进位示例 | 最大值(溢出边界) | 适用场景 |
|---------|-------------------|------|------|---------------------|---------|-------------------|---------|
| `DECIMAL`
十进制 0-9 | FIXED("C") + SEQ(DECIMAL) | 左补 `0` | 6 | `C000001`→`C000002`→`C000003`→`C000004`→`C000005` | `C000009`→`C000010`(9→10 进位) | `C999999`(第 100 万个后溢出报错) | 客户编码、采购单号、出库单号 |
| `DECIMAL`
十进制 0-9 | FIXED("CG") + DATE(yyyyMMdd) + SEQ(DECIMAL) | 左补 `0` | 4 | `CG202607160001`→`...0002`→`...0003`→`...0004`→`...0005` | `...0009`→`...0010` | `CG202607169999`(当日第 1 万个溢出) | 按日重置的日单据编号 |
| `HEX`
十六进制 0-9A-F | SEQ(HEX) | 左补 `0` | 4 | `0000`→`0001`→`0002`→`...0009`→`000A` | `000F`→`0010`(F→10 进位) | `FFFF`(65536 个后溢出) | 短码高容量编号(如二维码批次号) |
| `HEX`
十六进制 0-9A-F | FIXED("BX") + SEQ(HEX) | 左补 `0` | 3 | `BX000`→`BX001`→`...BX009`→`BX00A`→`BX00B` | `BX00F`→`BX010` | `BXFFF`(4096 个后溢出) | 料箱批次编码 |
| `ALPHA_UPPER`
大写字母 A-Z | FIXED("A") + SEQ(ALPHA_UPPER) | 左补 `A` | 2 | `AA`->`AB`->`AC`->`AD`->`AE` | `AZ`->`BA`(Z->A 进位,十位+1) | `ZZ`(676 个后溢出) | 货架库位编码(A区-AA货架) |
| `ALPHA_UPPER`
大写字母 去除IOZ | FIXED("A") + SEQ(ALPHA_UPPER, excludeAmbiguous=Y) | 左补 `A` | 2 | `AA`->`AB`->`AC`->`AD`->`AE` | `AY`->`BA`(Y->A 进位) | `YY`(529 个后溢出) | 需避免 I/O/Z 与 1/0/2 混淆的场景 |
| `ALPHA_UPPER`
大写字母 A-Z | SEQ(ALPHA_UPPER) | 左补 `A` | 3 | `AAA`→`AAB`→`AAC`→`AAD`→`AAE` | `AAZ`→`ABA`;`AZZ`→`BAA` | `ZZZ`(17576 个后溢出) | 仓库分区/库区三级编码 |
| `ALPHA_LOWER`
小写字母 a-z | FIXED("b") + SEQ(ALPHA_LOWER) | 左补 `a` | 2 | `baa`->`bab`->`bac`->`bad`->`bae` | `baz`->`bba`(z->a 进位) | `bzz`(676 个后溢出) | 内部短码、与大小写敏感场景区分 |
| `ALPHA_LOWER`
小写字母 去除ioz | FIXED("b") + SEQ(ALPHA_LOWER, excludeAmbiguous=Y) | 左补 `a` | 2 | `baa`->`bab`->`bac`->`bad`->`bae` | `bay`->`bba`(y->a 进位) | `byy`(529 个后溢出) | 需避免 i/o/z 混淆的内部短码 |
| `ALPHANUMERIC`
字母数字 0-9A-Z | SEQ(ALPHANUMERIC) | 左补 `0` | 4 | `0000`->`0001`->`0002`->`...0009`->`000A` | `000Z`->`0010`(Z->10 进位) | `ZZZZ`(约 168 万个后溢出,容量最大) | 高容量短码(如券码、兑换码) |
| `ALPHANUMERIC`
字母数字 去除IOZ | SEQ(ALPHANUMERIC, excludeAmbiguous=Y) | 左补 `0` | 4 | `0000`->`0001`->`...0009`->`000A` | `000Y`->`0010`(Y->10 进位) | `YYYY`(约 119 万个后溢出) | 高容量短码且避免混淆字符 |
| `ALPHANUMERIC`
字母数字 0-9A-Z | FIXED("Q") + SEQ(ALPHANUMERIC) | 左补 `0` | 3 | `Q000`→`Q001`→`...Q009`→`Q00A`→`Q00B` | `Q00Z`→`Q010` | `QZZZ`(46656 个后溢出) | 优惠券/兑换券编码 |
> **进位规则说明**:
> - `DECIMAL`:逢 10 进 1(9→10)
> - `HEX`:逢 16 进 1(F→10)
> - `ALPHA_UPPER`/`ALPHA_LOWER`:默认逢 26 进 1(Z->BA);开启去除易混淆字符后逢 23 进 1(Y->BA)
> - `ALPHANUMERIC`:默认逢 36 进 1(Z->10);开启去除易混淆字符后逢 33 进 1(Y->10)
> - 补位字符:DECIMAL/HEX/ALPHANUMERIC 默认补 `0`;ALPHA_UPPER 默认补 `A`;ALPHA_LOWER 默认补 `a`
**验收标准**:
- 各段类型均可正确配置并生成对应内容
- SEQ 段5种进制转换正确,含字母进制(A-Z/a-z/0-9A-Z)的递增与进位正确
- 字母流水号进位正确(如 Z -> AA,Z -> 10 在字母数字进制下)
- 开启去除易混淆字符后,字母进制不再生成 I/O/Z(及小写),进位按 23/33 进制正确递增
- 关闭去除易混淆字符时,使用完整字符集(26/36 进制)
- SEQ 段溢出时报错而非截断
---
### FR4. 流水号重置与分组计数
**需求描述**:顺序位数(SEQ)段支持按时间周期重置与按业务字段分组独立计数两个维度。
**功能要点**:
- **是否重置**:可选重置(Y,按周期归零)或不重置(N,全局递增永不归零)
- **重置周期**(重置=Y时生效):
- `NONE` 不重置
- `YEAR` 按年重置(如合同编号、年度单号)
- `MONTH` 按月重置(如月结单据)
- `DAY` 按日重置(最常用,如出库单/采购单/调拨单)
- `HOUR` 按时重置(高频编码场景)
- 不提供分钟/秒级重置,避免计数 key 爆炸
- **分组(前置码)**(可选):通过将某分段标记为"前置码"(is_prefix=Y)实现分组,流水号按该前置码段的值独立递增;无前置码段表示不分组(全局计数)
- 例如将 VARIABLE(warehouseCode) 段标记为前置码,则不同仓库各自独立计数
- **起始值**:每个新计数 key 首次访问返回该值(默认1),后续依次递增
- **前置码段值来源**两种方式并存:
- 方式一:调用生成接口时通过上下文(context)显式传入字段值
- 方式二:规则配置中绑定业务对象字段编码,低代码场景自动从业务数据提取
- 优先取显式传入值,取不到再用绑定字段提取
- **重置本质**:通过切换底层计数 key 实现(而非主动清零),旧 key 保留可用于审计
**典型场景**:
- 客户编码 `C000001`(不重置):FIXED("C") + SEQ(6位, 不重置),跨年不归零
- 合同编号 `HT202600001`(按年):FIXED("HT") + DATE(yyyy) + SEQ(5位, 按年)
- 采购单号 `CG202607140001`(按日):FIXED("CG") + DATE(yyyyMMdd) + SEQ(4位, 按日)
- 组织日流水 `ORG001202607140001`(按日+分组):SYS_VAR(orgCode) + DATE(yyyyMMdd) + SEQ(4位, 按日, group=orgCode)
**重置周期 × 分组字段 组合示例**:
下表覆盖「重置周期」与「分组字段」两个维度的全部组合,每行给出规则配置、计数 key 结构与生成序列示例。
| 重置周期 | 分组字段 | 规则配置 | 计数 key(period/group) | 生成序列示例 | 场景说明 |
|---------|---------|---------|--------------------------|-------------|---------|
| `NONE` 不重置 | 无 | FIXED("C") + SEQ(DECIMAL, 6位, reset=N) | `...:global:global` | `C000001`->`C000002`->...->`C000099`(跨年持续) | 客户/物料/供应商主数据编码,永不归零 |
| `NONE` 不重置 | 有
(warehouseCode) | FIXED("WH") + VARIABLE(warehouseCode, 前置码=Y) + SEQ(DECIMAL, 3位, reset=N) | `...:WH001:global`
`...:WH002:global` | 仓库WH001:`WHWH001001`->`001002`
仓库WH002:`WHWH002001`->`001002` | 按仓库独立计数,各仓库从1开始且永不归零 |
| `YEAR` 按年 | 无 | FIXED("HT") + DATE(yyyy) + SEQ(DECIMAL, 5位, reset=Y, policy=YEAR) | `...:global:2026`
`...:global:2027` | 2026年:`HT202600001`->`0002`
2027年1月:`HT202700001`(归零) | 合同编号、年度单据,每年从1开始 |
| `YEAR` 按年 | 有
(deptCode) | FIXED("HT") + DATE(yyyy) + SEQ(DECIMAL, 4位, reset=Y, policy=YEAR, group=deptCode) | `...:D001:2026`
`...:D002:2026` | 部门D001:`HT2026D0010001`->`0002`
部门D002:`HT2026D0020001`(独立) | 按部门分组的年度合同,各部门每年独立从1开始 |
| `MONTH` 按月 | 无 | FIXED("MJ") + DATE(yyyyMM) + SEQ(DECIMAL, 4位, reset=Y, policy=MONTH) | `...:global:202607`
`...:global:202608` | 7月:`MJ2026070001`->`0002`
8月1日:`MJ2026080001`(归零) | 月结单据,每月从1开始 |
| `MONTH` 按月 | 有
(warehouseCode) | FIXED("MJ") + DATE(yyyyMM) + SEQ(DECIMAL, 3位, reset=Y, policy=MONTH, group=warehouseCode) | `...:WH01:202607`
`...:WH02:202607` | 仓库WH01 7月:`MJ202607WH01001`
仓库WH02 7月:`MJ202607WH02001` | 按仓库分组的月结单,各仓库每月独立 |
| `DAY` 按日 | 无 | FIXED("CG") + DATE(yyyyMMdd) + SEQ(DECIMAL, 4位, reset=Y, policy=DAY) | `...:global:20260716`
`...:global:20260717` | 7/16:`CG202607160001`->`0002`
7/17:`CG202607170001`(归零) | 采购单/出库单/调拨单,每天从1开始 |
| `DAY` 按日 | 有
(orgCode) | SYS_VAR(orgCode) + DATE(yyyyMMdd) + SEQ(DECIMAL, 4位, reset=Y, policy=DAY, group=orgCode) | `...:ORG001:20260716`
`...:ORG002:20260716` | 组织ORG001 7/16:`ORG001202607160001`
组织ORG002 7/16:`ORG002202607160001` | 组织日流水,各组织每天独立从1开始 |
| `HOUR` 按时 | 无 | FIXED("HF") + DATE(yyyyMMddHH) + SEQ(DECIMAL, 3位, reset=Y, policy=HOUR) | `...:global:2026071614`
`...:global:2026071615` | 14时:`HF2026071614001`->`002`
15时:`HF2026071615001`(归零) | 高频编码(如扫码批次),每小时从1开始 |
| `HOUR` 按时 | 有
(lineCode) | FIXED("HF") + DATE(yyyyMMddHH) + SEQ(DECIMAL, 3位, reset=Y, policy=HOUR, group=lineCode) | `...:L01:2026071614`
`...:L02:2026071614` | 产线L01 14时:`HF2026071614L01001`
产线L02 14时:`HF2026071614L02001` | 按产线分组的高频编码,各产线每小时独立 |
> **计数 key 结构说明**:`sys-code-rule:{租户ID}:{规则ID}:seg{段序号}:{分组值}:{周期}`
> - 不重置时:分组值=`global`、周期=`global`,key 永不变(全局递增)
> - 重置时:周期随时间变化(YEAR->`2026`、MONTH->`202607`、DAY->`20260716`、HOUR->`2026071614`)
> - 分组时:分组值为字段值(如 `WH001`),不同值各自独立计数
**验收标准**:
- 不重置规则跨周期流水号持续递增
- 按年/月/日/时重置规则在新周期首号从起始值开始
- 分组字段不同值各自独立计数,互不影响
- 并发生成不产生重复编号
---
### FR5. 编码实时预览
**需求描述**:在规则编辑过程中,实时预览当前配置产出的编码效果。
**功能要点**:
- 实时展示:格式表达式(如 `y + M + xxxxx`)、生成示例值(如 `25M00001`)、总长度、分段彩色标识
- 分段切换为不同颜色标签便于识别
- 预览输入防抖(300ms)后调用后端预览接口,避免频繁请求
- 离开页面时自动清理定时器,避免内存泄漏
**验收标准**:
- 修改任意分段配置后预览结果实时刷新
- 格式表达式与示例值展示正确
- 总长度为所有列入编码段长度之和
---
### FR6. 编码生成接口
**需求描述**:提供统一的编码生成接口,供业务系统调用以获取下一个编号。
**功能要点**:
- 调用方式:传入规则编码 + 业务上下文(可选变量值 fields)
- 生成逻辑:按段顺序遍历所有"列入编码"的段依次拼接
- DATE 段按当前时间格式化
- FIXED 段直接使用常量值
- SEQ 段按重置周期与分组字段计算计数 key,递增取号并按进制转换补位
- **取值方式支持调用方传变量调用**(核心能力):
- **VARIABLE 变量值段**:调用方通过入参 `fields` 传入变量,系统按段配置的 `seg_format`(变量名)从 `fields` Map 取值;取不到时报错
- **SEQ 分组**:前置码段(VARIABLE 类型)的值同样由调用方通过 `fields` 传入变量,系统按前置码段值作为分组维度计算计数 key
- **SYS_VAR 系统变量段**:由系统自动从登录上下文取值(租户ID/用户ID/组织编码等),无需调用方传入
- 调用方可在业务代码中先查询/计算变量值,再传入生成接口,实现动态取值
- 支持按规则编码直接生成(无需规则ID)
- 生成结果返回完整编码与流水号值
**调用示例**:
```json
POST /system/code-rule/generate
{
"ruleCode": "PURCHASE_NO",
"fields": {
"warehouseCode": "WH001",
"supplierCode": "SUP001",
"warehouseType": "01"
}
}
```
说明:`fields` 统一传入 VARIABLE 段及 SEQ 分组所需变量(含业务字段与字典分类值),SYS_VAR 段由系统自动取登录信息,调用方无需传入。
**验收标准**:
- 调用生成接口返回符合规则的完整编码
- 调用方传入的变量(fields)能正确被 VARIABLE/SEQ分组 段使用
- 未提供必需变量时报错提示具体缺失项
- 流水号正确递增与重置
- 并发调用不产生重复编号
- 调用停用规则时报错提示
---
### FR7. 规则列表与详情查询
**需求描述**:提供编码规则的分页查询、启用列表查询与详情查询能力。
**功能要点**:
- 分页查询:支持按规则编码、规则名称、分类、状态筛选
- 启用列表查询:返回所有启用状态的规则,供业务方选择引用
- 详情查询:返回规则主表信息 + 分段明细列表
- 超级管理员(租户ID为空)可查看所有租户数据
**验收标准**:
- 各筛选条件查询结果正确
- 详情包含完整分段明细且顺序正确
- 超级管理员查询不受租户限制
---
### FR8. 段类型与格式符查询
**需求描述**:提供接口返回系统支持的所有段类型及可用格式符,供前端动态渲染提示。
**功能要点**:
- 返回所有段类型(DATE/FIXED/SEQ/VARIABLE/SYS_VAR)
- 返回各段类型对应的可用格式符列表(如日期格式符、系统变量名列表)
- 返回段类型标签与说明,便于前端展示
**验收标准**:
- 接口返回段类型与格式符完整准确
- 前端可据此动态渲染配置提示
---
### FR9. 菜单与权限管理
**需求描述**:在应用中心下提供「编码规则」菜单入口,并配置相应操作权限。
**功能要点**:
- 菜单路径:`/app-center/code-rules`(恢复原路径,便于用户习惯)
- 权限标识:`system:codeRule:list/add/edit/remove`
- 操作权限:查询、新增、修改、删除分别授权
- 超级管理员角色默认绑定全部权限
- 临时创建的系统管理菜单已隐藏,权限点已迁移回原菜单
**验收标准**:
- 有权限用户可见菜单并操作
- 无权限用户不可见菜单
- 各操作权限独立校验
---
### FR10. 数据迁移
**需求描述**:将旧 `ai_code_rule` 表中的编码规则数据平滑迁移到新分段式模型。
**功能要点**:
- 迁移范围:11条内置规则(含载具、料箱、单据、客户、供应商、仓库、采购、出库、调拨等)
- 迁移逻辑:将旧模板字符串解析为分段记录(FIXED 段 + DATE 段 + SEQ 段)
- 重置策略降级:旧 SECOND/MINUTE 重置统一降级为 HOUR,避免计数 key 爆炸
- 序号续接:迁移时读取旧计数器当前值作为起始值,避免编号冲突
- 幂等保护:迁移脚本可重复执行,已迁移数据不重复插入
- 新环境兼容:旧表不存在时跳过迁移,不影响新部署
**验收标准**:
- 迁移后内置规则在新模型中配置正确
- 迁移前后生成的编码结果一致(除重置策略降级外)
- 迁移脚本可重复执行不报错
- 新部署环境正常初始化
---
### FR11. 低代码业务兼容
**需求描述**:保持低代码业务对象字段「自动编号」能力正常工作。
**功能要点**:
- 低代码设计器属性面板的自动编号配置项保持兼容
- 低代码业务对象新增时自动调用新编码生成接口
- 旧 `/ai/code-rule` 接口保留为兼容层(list/preview/generate),供低代码设计器继续引用
- 旧接口内部委托新服务实现,避免功能重复
**验收标准**:
- 低代码业务对象字段自动编号功能正常
- 旧接口调用结果与新接口一致
- 表单设计器预览编码功能正常
---
## 4. 非功能性需求
| 类别 | 要求 |
|------|------|
| 并发安全 | 流水号生成基于分布式锁,并发场景不产生重复编号 |
| 数据安全 | 接口支持请求加解密;写操作记录操作日志;权限校验 |
| 参数校验 | 接口入参使用 JSR303 校验,非法参数拒绝处理 |
| 兼容性 | 旧接口保留兼容层,平滑过渡,不中断现有业务 |
| 可扩展性 | 编码分类、段类型、进制类型均支持字典扩展 |
| 性能 | 预览接口防抖处理;生成接口基于 Redis 高性能计数 |
| 数据完整性 | 分段保存采用事务,主表与子表一致;逻辑删除保留历史 |
---
## 5. 业务规则汇总
### 5.1 主表业务规则
1. 规则编码同租户唯一,格式为大写字母+数字+下划线
2. 编码分类使用数据字典,可扩展
3. 状态启用/停用,停用规则不可生成
4. 内置规则不可删除,仅可改名称/说明
5. 删除为逻辑删除,保留历史
### 5.2 分段业务规则
1. 段序号从1开始,决定拼接顺序
2. 仅"列入编码"的段出现在最终编码中
3. 不列入编码的段仅用于流水分组计算
4. SEQ 段补位默认左补 `0`,FIXED 段无需补位
5. 补位字符仅允许单字符
6. 段实际值超长时报错而非截断
### 5.3 生成业务规则
1. 按段序号顺序遍历"列入编码"段拼接
2. SEQ 段计数 key = `sys-code-rule:{租户ID}:{规则ID}:seg{段序号}:{分组值}:{周期}`
3. 不重置时分组值与周期均为 global,key 永不变
4. 重置时周期随时间变化,新周期首号返回起始值
5. 分组时不同字段值各自独立计数
---
## 6. 验收清单
- [ ] 应用中心菜单下可见「编码规则」页面
- [ ] 可新增/编辑/删除/启停编码规则
- [ ] 分段明细可在弹窗内增删改排序
- [ ] 五种段类型(DATE/FIXED/SEQ/VARIABLE/SYS_VAR)均可正确配置生成
- [ ] SEQ 段5种进制转换正确,溢出时报错
- [ ] SEQ 段可配置是否去除易混淆字符(I/O/Z),开启后字母进制不含这些字符
- [ ] 流水号按年/月/日/时重置正确
- [ ] 流水号按分组字段独立计数正确
- [ ] 不重置规则跨周期持续递增
- [ ] 保存时实时预览编码格式与示例值
- [ ] 调用生成接口按规则产出正确编号
- [ ] 并发生成不重复
- [ ] 内置规则预置可用且不可删除
- [ ] 旧 ai_code_rule 数据迁移后生成结果一致
- [ ] 低代码业务对象字段自动编号功能正常
- [ ] 超级管理员可查看所有租户数据
- [ ] 接口权限校验与操作日志正常
---
## 7. 术语表
| 术语 | 说明 |
|------|------|
| 编码规则 | 一套编码生成规则,由若干分段组成 |
| 分段(Segment) | 编码规则的一个组成部分,如日期段、流水号段 |
| 段类型 | 分段的类型,共5种:DATE/FIXED/SEQ/VARIABLE/SYS_VAR |
| 流水号(SEQ) | 顺序递增的序号段,支持进制转换与补位 |
| 重置周期 | 流水号归零的时间维度:年/月/日/时 |
| 分组字段 | 流水号按该字段值独立计数的维度;本功能中通过将该段标记为"前置码"实现分组 |
| 前置码(is_prefix) | 分段的分组标记,标记为前置码的段其值作为 SEQ 流水号的分组依据;前置码即分组 |
| 进制 | 流水号数字的表示方式,字母也是其中一种:十进制(0-9)/十六进制(0-9A-F)/大写字母(A-Z)/小写字母(a-z)/字母数字(0-9A-Z) |
| 易混淆字符(excludeAmbiguous) | SEQ 段可选开关,开启后字母进制去除 I/O/Z(及小写 i/o/z),避免与数字 1/0/2 混淆;默认关闭 |
| 内置规则 | 系统预置的编码规则,不可删除 |
| 上下文(Context) | 调用生成接口时由调用方传入的变量集合(`fields` Map),供 VARIABLE 段及 SEQ 分组取值;SYS_VAR 段由系统自动取登录信息,无需传入 |