# 编码规则设定 功能需求文档 > 文档版本: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 段由系统自动取登录信息,无需传入 |