74 lines
7.7 KiB
Markdown
74 lines
7.7 KiB
Markdown
# FMS 删除规则改造待做
|
||
|
||
> 创建:设计阶段已闭合、实施未开始。明日开工照此清单执行。
|
||
> 设计依据:`FMS删除规则引擎设计.md` **v2.0**(权威实现规格)、`FMS模块设计评审.md` v1.2(决策记录)。
|
||
> 前提确认:库中无存量规则/关系数据(`sql/` 种子脚本中 `s_relation` 零 insert),**全部按新结构直接建,不做迁移**。
|
||
|
||
## 已定案的设计决策(不需要再讨论)
|
||
|
||
| # | 决策 | 出处 |
|
||
| --- | --- | --- |
|
||
| 1 | `s_relation.b_on_delete` 单列四值:`restrict`(默认)/ `cascade` / `archive` / `none`;语义统一为「删除**被引用方**时,**引用方**怎么办」;被引用方由基数判定(many_to_one=目标 / one_to_many=源 / one_to_one=源) | 删除规则 v2.0 §3 |
|
||
| 2 | 引用保护退出 `s_rule`,由 `b_on_delete='restrict'`(默认)表达;「有引用时拒绝删除」假列及全部联动补丁删除 | 删除规则 v2.0 §3 |
|
||
| 3 | `s_rule` 新结构:`b_module_id` 直存、显式 `b_kind`(condition/sql)、去掉 `b_scope_type`/`b_scope_id`/`b_hook` | 删除规则 v2.0 §6.2 |
|
||
| 4 | 中间表模块挂业务域 `module` 节点下、与主表模块平级(规范已写入核心表结构设计 §4.3) | 评审 v1.2 问题四 |
|
||
| 5 | 模块管理分节改为「数据行为 / 访问控制」,只改 `configGroups` 分组,面板/路由/数据不动;与删除规则前端改造同批实施 | 评审 v1.2 问题二 |
|
||
|
||
## 待做清单(按执行顺序)
|
||
|
||
### ① 重写 SQL 脚本 —— 对应设计 v2.0 §6.1 / §6.2
|
||
|
||
现状:两个脚本还是 v1 结构(`b_on_delete` 默认 `none` 三值、`s_rule` 带 `b_scope_type`/`b_scope_id`/`b_hook`)。
|
||
|
||
- [ ] `sql/fms_delete_rule.sql` 重写:
|
||
- `s_relation.b_on_delete`:四值,**默认 `'restrict'`**(现脚本 L18 默认是 `'none'`)
|
||
- `s_rule` 按新结构重建:`b_module_id varchar(50) not null`、`b_kind varchar(20) not null`(condition / sql)、`b_predicate not null`、`b_message`、`b_canuse`、`b_xh`、审计四列;去掉 `b_scope_type`/`b_scope_id`/`b_hook`
|
||
- 索引:`ix_s_rule_module on s_rule (b_module_id, b_canuse, b_xh)`
|
||
- 保留脚本头「可重复执行」说明与执行方式注释
|
||
- [ ] `sql/fms_core.sql` 同步:L208 的 `b_on_delete` 注释与默认值、L228-256 的 `s_rule` 段整体替换(与 `fms_delete_rule.sql` 保持一致,注意两脚本职责分工——core 建全表、delete_rule 只做本特性增量,按现有模式来)
|
||
- [ ] 建表 SQL 的 `b_archived` / `b_archive_datetime` 通用列暂不加——它是 `archive` 行为的**运行时前提**(引用方表需有此列),到后端实现时再决定加在哪些业务表
|
||
|
||
### ② 后端引擎 —— 对应设计 v2.0 §6.4 / §6.5 / §6.6
|
||
|
||
- [ ] 新建 `DeleteRuleChecker`(检查器):`check(connection, 模块, ids, 小闭包)`
|
||
- 模块条件:清单内每个模块的 `s_rule`(`b_canuse=1`)逐条执行;condition → JSON AST 翻译参数化 SQL(AST 格式见 §6.3,嵌套 ≤8 层、节点 ≤100);sql → `:ids` 替换(OPENJSON 数组参数,绕开 2100 绑定变量上限),查出有结果即记错误,**全程写技术日志**(实际 SQL+参数+行数)
|
||
- 引用保护:清单内每条记录查它作为被引用方的 `restrict` 入边(`b_on_delete='restrict'` 且 `b_canuse=1`),引用方存在且不在清单内 → 记错误(带引用方单号)
|
||
- [ ] 新建 `DeleteRuleExecutor`(执行器):从 ids 出发沿 `b_on_delete ∈ {cascade, archive}` 的关系逐层展开删除清单(被删的是被引用方;已装过跳过防环;超 10 层报配置错误)
|
||
- [ ] `DataController` 加 `POST /data/deleteobj`:`{ moduleCode, ids, dryRun }`;dryRun 返回「将删除 X + Y」摘要;真删开事务**重跑检查**(预览通过不算数)→ archive 打标记 → 先子后父物理删 → 审计日志
|
||
- [ ] `DataSaveService.saveTable()` delete 分支接入(§6.5,**重要**):
|
||
- 真删前按表名反查模块(`b_savetable`),查不到跳过(日志表等)
|
||
- 同事务调检查器;**小闭包语义**:本次 saveobjt 所有 deletes 覆盖的 id 传给检查器,引用方也在被删之列不算外部引用
|
||
- 不过 → 抛 BusinessException → 整个 saveobjt 回滚
|
||
- [ ] 错误消息生成:condition 自动生成人话(带实际值 + 字段格式化:金额 ¥、日期格式);sql 规则用 `b_message` 的 `{列名}` 占位符填充;错误按规则归类、每类带数量和前几条示例
|
||
|
||
### ③ 前端改造 —— 对应设计 v2.0 §8 步骤 5 + 评审问题二
|
||
|
||
- [ ] `ModuleRelationPanel.vue`:删除相关从三栏位(`b_relation_type` / `b_on_delete` / `_hasRefRule`)收敛为 `b_relation_type` + `b_on_delete`(四值下拉,默认 restrict)
|
||
- 删掉:`_hasRefRule` 假列、`setRefRule`、改关系主键时作废旧键规则及提示(L326-334)、填不全四列禁用 checkbox
|
||
- `many_to_one` + `cascade` 不再界面禁用,改保存校验拦截(对齐「校验落后端」原则——若后端引擎做此校验,前端可只做提示)
|
||
- [ ] `ModuleRulePanel.vue`:去掉引用规则只读区 + `navigate` 跳转;列表只剩模块级规则(condition / sql)
|
||
- [ ] `ModuleRuleEditModal.vue` + `ruleUtils.js`:
|
||
- `parseRulePredicate` 三态推断改两态(读 `b_kind`,不再看首字符 `{`)
|
||
- 删掉 `relationScopeId` / `parseRelationScopeId` / `isCompleteRelationKey` / `REF_RULE_HINT` / `createRefRuleRow` / `RULE_SCOPE_RELATION`
|
||
- `createRuleRow` 带 `b_kind`;新增默认 `condition`
|
||
- [ ] `module-management/index.vue`:
|
||
- 删 `refRules` / `refRules_org` / `refRulesReverse` 三组数据及加载、diff、清理逻辑(L875-898 关系级规则清理段改为只清模块级)
|
||
- `configGroups` 分节调整:「数据行为 → 模块关联(含删除行为) / 删除规则 / 自动编码」「访问控制 → 权限」;section key 不动
|
||
- [ ] `FmsModuleListPage.vue` `deleteSelected`(L877):直删改两步——先 `deleteobj dryRun=true`,有错误弹错误列表,无错误弹确认框(含连带摘要),确认后真删
|
||
|
||
### ④ 验收检查
|
||
|
||
- [ ] 全局搜索无旧导出残留:`relationScopeId`、`createRefRuleRow`、`REF_RULE_HINT`、`b_scope_type`、`b_scope_id`、`_hasRefRule`、`setRefRule`
|
||
- [ ] `pnpm check`(lint + fmt + build)通过
|
||
- [ ] 跑受影响模块的前端测试;`ruleUtils` / 面板相关 spec 按新契约更新(测试约定见 `fms-vue/tests/README.md`:文件同名、中文用例名)
|
||
- [ ] 后端:`mvnw test`;引擎核心逻辑(检查器翻译、闭包语义、环检测)补测试
|
||
- [ ] 手工链路验证:配一条「审核中不可删」→ 列表删被拦(人话提示)→ 表单里删行同样被拦(saveobjt 回滚)→ cascade 关系连带展开预览 → restrict 默认生效
|
||
|
||
## 注意事项(动工前再读一遍)
|
||
|
||
1. **`sql/fms_delete_rule.sql` 现有 L22 是 `drop table if exists s_rule`**——虽然确认无数据,重写后仍保留 drop+create 模式,但执行前先 `select count(*)` 确认一次
|
||
2. 规则引擎是**当前最大缺口**:现在界面上配的删除规则完全不生效(后端 `s_rule` 相关零实现)。②完成后配置才有意义,①③可以和②并行
|
||
3. 执行 SQL 用 `RunSqlFile`:`java -cp "tools/migration/mssql-jdbc-13.4.0.jre11.jar" tools/migration/RunSqlFile.java ../sql/fms_delete_rule.sql --dry-run` 先 dry-run
|
||
4. 改前端遵守 `开发规范.md`:改前先读、最小修改、不为兼容旧名留转发别名(调用方可控,直接迁移删旧代码)
|
||
5. `s_rule` 主键仍是雪花 `b_id`(前端 `nextIdApi` 取号,与业务表一致);**配置表不用 nextIdApi 的规则是「模块配置表用业务键」**——`s_rule` 无天然业务键,属例外(v2.0 §6.2 已注明)
|