u
This commit is contained in:
1 parent
e99a9fb274
commit
0be0b0767a
788 files changed
+112023
-14941
No files matched your search
@@ -0,0 +1,317 @@
|
||||
# FMS 模块管理简化与架构收敛方案
|
||||
|
||||
> 文档状态:方案评审稿
|
||||
> 目标:降低新增业务模块的配置成本,明确元数据配置与业务代码的边界
|
||||
> 约束:不迁移旧模块配置或旧业务数据;不提供旧表、旧接口、旧配置格式的兼容层
|
||||
|
||||
## 1. 结论摘要
|
||||
|
||||
当前模块管理的主要问题不是能力不足,而是把“登记业务对象”“定义字段”“设计页面”“配置查询”“配置权限”“定义删除规则”等不同职责,集中成了一个通用模块配置器。简单模块因此也要理解和维护一套近似低代码平台的概念。
|
||||
|
||||
建议将系统收敛为以下模式:
|
||||
|
||||
```text
|
||||
业务域代码包(表、SQL、服务、API、页面)
|
||||
│
|
||||
├── 代码清单登记业务对象、页面和权限点
|
||||
└── 数据库维护模块启停、菜单结构和角色授权
|
||||
```
|
||||
|
||||
核心决策:
|
||||
|
||||
1. **业务域代码包成为业务实现的唯一中心。**业务表、查询、保存、校验、业务动作和页面由业务域负责。
|
||||
2. **模块管理不再设计业务页面。**它只管理代码中已经存在的业务对象及其启停、名称和顺序。
|
||||
3. **菜单和权限分别管理。**菜单只能指向代码清单中已登记的页面;权限由代码声明,数据库维护用户或角色授权。
|
||||
4. **保留共享组件,不保留通用业务解释器作为核心路径。**简单资料可复用列表、表单、查询组件;复杂行为进入明确的业务服务。
|
||||
5. **从全新数据库和新接口开始。**旧 `s_module` 配置、旧 schema JSON、旧通用模块运行时和旧接口不迁移、不兼容、不双写。
|
||||
|
||||
## 2. 当前设计的主要负担
|
||||
|
||||
当前配置模型大致是:
|
||||
|
||||
```text
|
||||
s_module
|
||||
├── s_field
|
||||
├── s_module_schema(view / edit / query JSON)
|
||||
├── s_autocode
|
||||
├── s_power
|
||||
├── s_relation
|
||||
├── s_delete_rule
|
||||
└── s_i18n
|
||||
```
|
||||
|
||||
这套设计能让通用列表和表单快速出现,但也产生了几类持续成本:
|
||||
|
||||
- **配置入口太多。**新增模块要在多个面板间切换;字段定义与列表、表单、查询布局分别维护,用户需要理解内部元数据结构。
|
||||
- **模块概念混杂。**导航树节点、数据对象、虚拟查询对象和页面入口都被叫作“模块”,导致一个模块既像目录又像数据模型和页面定义。
|
||||
- **运行时过度依赖配置解释。**配置错误会在运行时才表现为页面空白、字段不可写或保存失败,而不是在编译、启动或发布阶段尽早暴露。
|
||||
- **业务规则被推向通用化。**关系、级联删除、公式、权限和 SQL 配置逐渐形成跨业务解释规则;规则越多,编辑器、校验器和运行时之间的耦合越高。
|
||||
- **安全边界需要后端兜底。**模块中心在前端限制管理员访问,但元数据和业务写入权限不能依赖路由隐藏或前端角色判断。
|
||||
|
||||
问题的根因是:**把少数简单 CRUD 的便利,扩展成所有业务都必须经过的运行时模型。**
|
||||
|
||||
## 3. 目标与非目标
|
||||
|
||||
### 3.1 目标
|
||||
|
||||
- 新增业务对象时,业务规则和数据访问可以在代码中搜索、评审、测试和发布。
|
||||
- 管理员只做运行配置:菜单组织、对象启停、角色授权和少量展示偏好。
|
||||
- 简单资料复用统一组件;单据、库存、财务、审批等复杂业务使用专用 API 和服务。
|
||||
- 页面引用的数据字段、权限点和业务动作可由代码清单静态登记并校验。
|
||||
- 配置改动有明确的操作权限、审计信息和发布责任。
|
||||
|
||||
### 3.2 非目标
|
||||
|
||||
- 不建设新的通用低代码平台或通用 JSON 规则引擎。
|
||||
- 不让数据库配置动态创建业务表、推断保存逻辑或执行任意业务 SQL。
|
||||
- 不要求每个业务页面都可由管理员拖拽生成。
|
||||
- 不迁移旧模块配置、旧业务数据或旧接口调用方。
|
||||
- 不为兼容旧版而保留双运行时、双字段定义或旧配置转换器。
|
||||
- 第一阶段不做通用代码生成平台;先用一个真实业务域验证代码模板。
|
||||
|
||||
## 4. 目标概念模型
|
||||
|
||||
必须把四个概念分开:
|
||||
|
||||
| 概念 | 含义 | 权威来源 |
|
||||
| --- | --- | --- |
|
||||
| 业务域 | 一组共同业务职责,如 customer、sales、inventory | 后端和前端代码目录 |
|
||||
| 业务对象 | 可被查询或操作的对象,如 customer、sales_order | 业务域代码清单 |
|
||||
| 页面 | 列表、详情、工作台等用户界面 | 前端代码路由/页面清单 |
|
||||
| 菜单 | 用户进入页面的导航结构 | 数据库菜单配置 |
|
||||
|
||||
菜单不再承担业务对象树的职责;业务对象不再通过树节点推断页面行为;页面也不能靠数据库中任意组件名动态加载。
|
||||
|
||||
### 4.1 业务域代码包
|
||||
|
||||
建议沿用新架构草案中的业务域组织方式:
|
||||
|
||||
```text
|
||||
domains/
|
||||
customer/
|
||||
migration/
|
||||
sql/
|
||||
repository/
|
||||
service/
|
||||
api/
|
||||
page/
|
||||
i18n/
|
||||
sales/
|
||||
inventory/
|
||||
```
|
||||
|
||||
每个业务域明确拥有自己的数据库变更、查询 SQL、保存方式、业务动作、API、页面和多语言资源。跨域调用通过接口或明确的业务关系完成,不通过任意 JSON 规则互相解释。
|
||||
|
||||
### 4.2 代码清单
|
||||
|
||||
每个业务域提供静态清单,列出可供系统登记的对象、页面和权限点。清单是可执行代码的一部分,不能由数据库传入任意类名或组件名覆盖。
|
||||
|
||||
示意:
|
||||
|
||||
```text
|
||||
customer 域
|
||||
对象:customer
|
||||
页面:customer-list、customer-detail
|
||||
权限:customer.read、customer.create、customer.update、customer.disable
|
||||
```
|
||||
|
||||
启动或发布校验至少检查:
|
||||
|
||||
- 菜单引用的页面 key 必须存在于代码清单;
|
||||
- 模块登记的业务对象必须存在于代码清单;
|
||||
- 授权引用的权限 key 必须已声明;
|
||||
- 一个页面声明使用的对象必须在清单中登记;
|
||||
- 数据库表、视图和必要字段必须通过业务域校验。
|
||||
|
||||
## 5. 新的模块管理体验
|
||||
|
||||
将“模块管理”改名为 **业务对象与模块登记**,不再展示字段设计器、列表设计器、表单设计器、查询设计器、自动编码、模块关系和删除 SQL 规则等运行时配置面板。
|
||||
|
||||
### 5.1 业务对象登记
|
||||
|
||||
业务对象由代码包提供,管理页面只允许维护少量运行属性:
|
||||
|
||||
- 显示名称或启用的多语言资源;
|
||||
- 是否启用;
|
||||
- 管理列表中的排序;
|
||||
- 必要的说明信息。
|
||||
|
||||
不允许在这里填写保存表、查询 SQL、字段列表或业务规则。对象登记不是“凭空创建一个业务模块”:新增对象先有代码,再由清单登记。
|
||||
|
||||
### 5.2 菜单管理
|
||||
|
||||
菜单继续负责导航树和页面入口:
|
||||
|
||||
- 只能从代码清单选择页面 key;
|
||||
- 菜单层级、排序、名称和启停保存在数据库;
|
||||
- 菜单到业务对象的绑定明确记录,不从父子树或模块类型推断;
|
||||
- 不允许数据库配置任意前端路由组件。
|
||||
|
||||
### 5.3 权限管理
|
||||
|
||||
- 权限点由业务域清单声明,代码决定具体操作含义。
|
||||
- 管理界面只分配已声明的权限给角色或用户。
|
||||
- 页面入口权限、对象读写权限、业务动作权限分别判定。
|
||||
- 后端 API 对每次请求重新校验登录身份、对象/动作权限和业务数据范围;前端隐藏按钮只作为体验优化。
|
||||
|
||||
## 6. 页面和数据配置边界
|
||||
|
||||
### 6.1 业务页面
|
||||
|
||||
页面默认由代码实现,并复用现有通用列表、表单、查询、选择器和附件等 UI 组件。业务页面的字段、校验、动作和调用哪个 API 由页面和业务域代码明确声明。
|
||||
|
||||
建议的简单资料实现链路:
|
||||
|
||||
```text
|
||||
Migration
|
||||
→ 业务表 / 查询视图
|
||||
→ list/detail/save SQL
|
||||
→ repository / service
|
||||
→ API
|
||||
→ 共享列表与表单组件
|
||||
→ 页面
|
||||
```
|
||||
|
||||
复杂单据的提交、撤回、审批、过账、库存变更等动作必须由业务服务实现,不由表单 JSON、通用保存接口或可编辑 SQL 字段推断。
|
||||
|
||||
### 6.2 允许的展示偏好
|
||||
|
||||
只在多个业务域确实重复需要时,才保留受限展示配置,例如:
|
||||
|
||||
- 用户个人列表列顺序、列宽;
|
||||
- 少量查询默认值;
|
||||
- 只影响展示的格式偏好。
|
||||
|
||||
这些配置不得改变字段真实类型、保存映射、数据权限、业务校验或事务行为。默认布局优先由代码提供;个人偏好是覆盖,不是创建业务页面的必要步骤。
|
||||
|
||||
### 6.3 数据库是事实来源
|
||||
|
||||
- Migration 定义真实表结构;
|
||||
- SQL 文件或受控 repository 实现查询和保存;
|
||||
- 代码模型定义 API 输入输出和字段语义;
|
||||
- 代码或受控资源维护系统文案;
|
||||
- 数据库运行配置只登记启停、菜单和授权。
|
||||
|
||||
可以保留 `describe` 能力用于开发期校验或脚手架辅助,但不把数据库实时反射变成生产运行时的字段定义器。
|
||||
|
||||
## 7. 数据表与接口调整方向
|
||||
|
||||
以下是职责方向,不要求为每个旧表设计转换路径:
|
||||
|
||||
| 当前职责 | 目标处理方式 |
|
||||
| --- | --- |
|
||||
| `s_module` 中的模块树、视图表、保存表、通用 SQL | 模块登记表只保留稳定对象编码、业务域/对象 key、名称、启停和排序;业务 SQL 移入域代码 |
|
||||
| `s_field` 运行时字段定义 | 不作为业务页面运行时字段事实来源;字段由业务 API 和页面代码定义 |
|
||||
| `s_module_schema` 的 view/edit/query JSON | 移除通用解释器依赖;页面结构由代码定义,只可选保留受限展示偏好 |
|
||||
| `s_autocode` | 编号规则归业务域所有,由业务服务原子获取和验证 |
|
||||
| `s_relation` | 真实数据关系由 SQL 约束、查询和业务服务表达;不由全局模块关系解释器驱动 |
|
||||
| `s_delete_rule` | 删除保护和级联行为由业务域服务及数据库约束明确实现 |
|
||||
| `s_power` 权限点定义 | 权限 key 由代码清单声明,数据库维护角色授权;禁止客户端任意造权限 key |
|
||||
| `s_menu` / 菜单绑定 | 保留导航职责,但页面目标必须指向代码清单中的安全 page key |
|
||||
| `s_user_module_pref` | 如有真实用户偏好需求,可保留为展示偏好;不可承载权限或业务规则 |
|
||||
|
||||
模块登记表的候选字段:
|
||||
|
||||
```text
|
||||
b_id 业务对象编码
|
||||
b_domain_code 业务域编码
|
||||
b_object_code 域内对象编码
|
||||
b_name 显示名称
|
||||
b_i18n 多语言资源 key
|
||||
b_canuse 是否启用
|
||||
b_xh 管理列表排序
|
||||
b_bz 说明
|
||||
```
|
||||
|
||||
`(b_domain_code, b_object_code)` 应有唯一约束。最终字段名和表结构在确认代码清单、权限模型和菜单模型后再定;不要把 `view_table`、`save_table`、任意 SQL 或业务配置 JSON 原样搬进新表。
|
||||
|
||||
## 8. 安全要求
|
||||
|
||||
这次收敛必须同时明确服务端边界:
|
||||
|
||||
1. 模块登记、菜单配置、角色授权的写接口必须有服务端系统管理员权限校验。
|
||||
2. 通用数据写入不能只按客户端传入的 `table` 和 `key_field` 决定是否允许写;应使用受控表清单或专用业务 API。
|
||||
3. 业务 API 必须校验用户对对象和动作的权限,以及公司、组织等数据范围。
|
||||
4. 权限定义和页面 key 来自代码清单,不接受页面传入任意字符串作为授权依据。
|
||||
5. SQL 参数值使用参数绑定;表、列和排序标识符必须来自服务端登记的标识符清单。
|
||||
6. 关键管理操作记录操作人、对象、变更前后值和请求追踪信息。
|
||||
|
||||
## 9. 全新替换策略
|
||||
|
||||
本方案不提供旧数据或旧接口的兼容路径:
|
||||
|
||||
- 新环境从新的 Migration 基线建库;
|
||||
- 不迁移旧 `s_module`、`s_field`、`s_module_schema` 或其他模块配置数据;
|
||||
- 不实现旧 JSON 转换器、双读、双写、旧 API 代理或回退到旧页面的逻辑;
|
||||
- 新版模块中心不读取旧配置表;
|
||||
- 旧模块运行时、旧管理路由和仅服务旧运行时的接口随新实现整体移除;
|
||||
- 旧业务数据迁移不属于本方案范围,需另立项目决策,不在新模块管理中隐式处理。
|
||||
|
||||
因此部署策略是新系统按新 schema 初始化,而不是在旧数据库上做无损升级。旧环境如需留档,由环境和备份策略处理,不由新版运行时兼容。
|
||||
|
||||
## 10. 实施顺序
|
||||
|
||||
### 阶段 A:锁定边界
|
||||
|
||||
- 定义业务域代码清单格式;
|
||||
- 定义对象、页面和权限 key 的命名规则;
|
||||
- 明确模块登记、菜单和角色授权三者关系;
|
||||
- 明确简单 CRUD 与复杂业务 API 的使用边界;
|
||||
- 完成后端管理员授权和通用写接口策略设计。
|
||||
|
||||
### 阶段 B:建立新内核
|
||||
|
||||
- 使用全新 Migration 建立最小模块登记、菜单、权限和审计结构;
|
||||
- 实现代码清单校验;
|
||||
- 实现服务端菜单/授权管理 API;
|
||||
- 新模块中心只提供登记、启停、排序和菜单/授权入口。
|
||||
|
||||
### 阶段 C:验证一个简单业务域
|
||||
|
||||
选择客户或产品资料,完整实现:
|
||||
|
||||
```text
|
||||
Migration → SQL → repository/service → API → 页面 → 菜单 → 授权 → 审计
|
||||
```
|
||||
|
||||
该对象必须不依赖 `s_field`、`s_module_schema` 或通用模块解释器才能运行。
|
||||
|
||||
### 阶段 D:验证一个复杂业务动作
|
||||
|
||||
选择一个真实动作(例如单据提交或审批绑定),验证业务校验、事务和权限均在明确的业务服务中完成;工作流只调用已登记的业务动作。
|
||||
|
||||
### 阶段 E:移除旧模块中心实现
|
||||
|
||||
- 移除旧模块配置面板和仅供其使用的 JSON 解释逻辑;
|
||||
- 移除旧运行时对模块字段/schema 的依赖;
|
||||
- 删除旧模块专属接口与无调用点代码;
|
||||
- 确认所有菜单页面来自代码清单,所有关键写操作经服务端权限校验。
|
||||
|
||||
不为旧数据补转换步骤,也不设置旧新并行期。
|
||||
|
||||
## 11. 验收标准
|
||||
|
||||
- 开发者新增业务对象时,有一致的业务域模板和单一 API/服务入口。
|
||||
- 管理员新增菜单时只能选择已编译、已登记的页面和对象。
|
||||
- 建立简单资料不需要分别维护字段表、列表 JSON、表单 JSON、查询 JSON 才能运行。
|
||||
- 复杂业务动作的校验、事务和 SQL 均可在对应业务域代码中定位。
|
||||
- 没有业务页面依赖全局模块 JSON 解释器才能启动。
|
||||
- 未授权用户直接调用 API 不能修改模块、菜单、权限或业务数据。
|
||||
- 新数据库初始化后,完整业务示例不需要导入任何旧模块配置即可工作。
|
||||
- 配置偏好只影响展示,不能放宽数据权限或改变保存行为。
|
||||
|
||||
## 12. 代价与风险
|
||||
|
||||
- **优点:**运行时更容易理解和测试;业务逻辑可代码评审;减少管理员配置步骤;SQL、权限和事务责任明确。
|
||||
- **代价:**新增业务对象需要开发和发布,不再承诺管理员零代码创建任意模块。
|
||||
- **控制新增代码成本:**先建立简单资料业务域模板并复用共享组件;只有至少两个业务域出现相同重复后,再抽取脚手架或通用能力。
|
||||
- **主要风险:**若大多数模块都要求管理员自行创建且业务结构高度同质,完全代码化会降低业务人员自助能力。应先用真实客户/产品模块验证开发成本,再决定是否增加“生成代码”的开发工具;不要因此恢复生产运行时的通用配置解释器。
|
||||
|
||||
## 13. 评审时需要确认
|
||||
|
||||
1. 新模块由开发者通过代码清单登记,管理员只能启停和配置菜单/授权,是否作为默认流程?
|
||||
2. 列表列宽和列顺序是否只保留用户个人偏好,系统级默认布局是否完全由代码维护?
|
||||
3. 简单 CRUD 的代码模板是否足够,是否先不做自动代码生成器?
|
||||
4. 新数据库 schema 是否允许直接移除旧模块配置表和旧通用模块 API?
|
||||
|
||||
以上四项确定后,再据此制定数据库表结构、API 清单和分阶段实施任务。本方案本身不改代码、不执行数据库变更,也不包含旧数据兼容或迁移实现。
|
||||
Reference in new issue
Block a user