6.8 KiB
FMS 模块架构
目标
模块架构只解决五类稳定职责:
Module 可复用模块资源
FunctionNode 菜单目录和页面入口
PageNode 页面内部编排
Profile 数据模块的使用方式
Capability 字段、列表、表单、查询、操作等能力
业务表、业务数据和手写 Vue 页面不进入元数据模型。通用读写继续使用 /data/loaddata、/data/page、/data/saveobjt,不增加模块专用接口。
设计规则
- 所有主键使用不可变
bigint雪花 ID,前端按字符串处理。 - 技术编码创建后不可修改;显示名称可以修改。
s_module只保存资源公共属性,类型专属字段进入子类型表。- 数据模块必须自动创建一个
defaultProfile。 - 字段和操作属于 Module;列表、表单、查询、导入、导出属于 Profile。
- 树结构使用明确父子外键和循环检测,不把树路径保存为 JSON。
- 关系和授权使用稳定 ID,不依赖名称或技术编码。
- 只有控件扩展参数、渲染器参数等不可预知属性使用 JSON。
- 不保留旧模块元数据兼容表、双写或页面专用模型。
资源模型
dbo.s_module
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
不可变雪花 ID |
b_code |
varchar(50) |
全局唯一、不可变技术编码 |
b_name |
nvarchar(100) |
默认名称 |
b_i18n |
varchar(150) |
meta.module.<id> |
b_module_type |
varchar(20) |
page/data/report/dashboard/workflow |
b_canuse |
int |
是否启用 |
每个 Module 必须且只能有一个对应子类型记录:
| 子类型表 | 主要字段 |
|---|---|
s_module_page |
b_route、b_page_mode、b_component_key |
s_module_data |
b_viewtable、b_savetable、b_keyfield、b_orderfield |
s_module_report |
来源数据模块/Profile、b_renderer_key、b_options |
s_module_dashboard |
b_component_key、b_options |
s_module_workflow |
b_engine_key、b_options |
报表、仪表盘和工作流只定义运行时契约,本阶段不提供报表引擎、设计器或流程引擎。
dbo.s_module_profile
Profile 只属于数据模块。同一模块内 b_code 唯一,并且只能有一个 b_default = 1。
| 字段 | 说明 |
|---|---|
b_id |
不可变雪花 ID |
b_module_id |
所属数据模块 |
b_code |
模块内唯一、不可变技术编码,如 default、selector |
b_name / b_i18n |
默认名称及 meta.profile.<id> |
b_default / b_canuse / b_xh |
默认、启用和排序 |
运行时列表通过 module_id + profile_id 定位;手写页面可以通过模块/Profile 技术编码解析稳定 ID。
功能结构
dbo.s_function_node
节点类型:
directory:只负责分组,不引用模块。entry:引用一个pageModule。
规则:
- 技术编码全局唯一且不可修改。
- 子节点只能放在
directory下。 - 入口节点不能包含子节点。
- 数据库触发器和维护界面同时阻止循环移动。
- 删除前必须清除角色和用户授权。
菜单运行时读取 v_s_function_node,路由组件仍由前端白名单显式注册。
页面编排
dbo.s_page_node
节点类型:group、tab、section、module_ref。
- 所有节点属于一个
pageModule。 - 容器节点不引用模块。
module_ref可以引用data/report/dashboard/workflowModule。- 引用数据模块时必须同时引用属于该模块的 Profile。
module_ref不能包含子节点。b_permission_required = 1时需要页面节点授权。b_fixed_condition与b_param_mapping只保存运行时组合参数。
页面运行时读取 v_s_page_node。otherdata 的分类和模块树迁入该表,不再保留 b_other_bmfl。
能力模型
Module 级能力
| 表 | 职责 |
|---|---|
s_module_field |
数据字段基础定义,(module_id, field) 唯一 |
s_module_action |
稳定操作定义,(module_id, code) 唯一 |
s_module_relation |
主子模块字段关系 |
s_module_auto_code |
模块业务编号规则 |
s_module_file |
模块文件能力契约 |
s_module_workflow_binding |
模块事件/操作与工作流资源绑定 |
Profile 级能力
| 表 | 职责 |
|---|---|
s_module_layout_group |
Profile 内列表/表单布局分组 |
s_module_field_list |
列表列、分组、可见性、顺序、宽度 |
s_module_field_form |
表单必填、只读、禁用、可见性和顺序 |
s_module_field_query |
查询控件、操作符、默认值和顺序 |
s_module_import |
导入方式与扩展参数 |
s_module_export |
导出方式与扩展参数 |
字段同步按字段技术名合并:保留已有人工配置,新字段补默认列表/表单配置,数据源中失效的字段只停用、不删除。
权限
角色是主授权,用户授权只做加法:
b_role
-> b_role_function_node
-> b_role_page_node
-> b_role_action
-> b_role_data_scope
b_user
-> b_user_role
-> b_user_function_node
-> b_user_page_node
-> b_user_action
有效权限视图:
v_s_user_function_permissionv_s_user_page_permissionv_s_user_action_permission
超级角色自动拥有全部启用权限。授权关系始终保存节点或操作 ID,不保存名称。当前由前端执行菜单、路由、页面节点和操作控制;后端数据范围和写操作拦截为后续扩展点。
b_role_data_scope 预留 all/self/department/custom 数据范围契约及扩展参数。本阶段不在查询接口中执行该规则。
多语言
固定前端文案使用语义键,例如 common.save。动态元数据使用 ID 键:
meta.module.<id>
meta.node.<id>
meta.profile.<id>
meta.group.<id>
meta.field.<id>
meta.action.<id>
meta.role.<id>
动态实体保存 b_name 与 b_i18n,Vue 统一调用:
appStore.t(record.b_i18n, record.b_name);
翻译缺失时回退 b_name,不会阻塞配置使用。
运行时视图
034_module_runtime_views.sql 建立:
v_s_function_nodev_s_page_nodev_s_module_profilev_s_module_runtimev_s_module_field_listv_s_module_field_formv_s_module_field_queryv_s_module_action- 三个用户有效权限视图
视图只组合读取契约,不承载保存逻辑。所有多表配置仍通过一次 /data/saveobjt 在同一事务内提交。
迁移与校验
按顺序人工执行:
033_create_module_structure.sql:一次性迁移有效旧元数据并删除旧模型。034_module_runtime_views.sql:建立运行时视图和领域约束触发器。verify_module_architecture.sql:只读检查子类型、Profile、父子规则、循环、旧表和多语言键。
执行前必须备份数据库。迁移脚本不由应用启动自动执行。