11 KiB
模块管理功能设计
范围:模块管理这一功能本身的设计定义,覆盖 模块、字段定义、菜单、多语言、权限 五大能力。 定位:本文档描述「模块管理页面能配置什么、各能力如何分工」,不描述通用
ModuleTable/ModuleForm的渲染实现,也不描述角色赋权页面(授权在另一处)。 配套原型:fms-vue/src/views/ModuleManageDemo.vue(纯前端,仅作演示)。
1. 设计目标与边界
模块管理是一个配置中枢,让实施人员用「填表」的方式定义一套业务功能,而不必改代码。它同时服务于四类下游消费者:
| 消费者 | 从模块管理取走什么 |
|---|---|
通用列表 ModuleTable |
字段清单、列标题、列表/表单开关、排序 |
通用表单 ModuleForm |
字段控件类型、校验、表单分组 |
| 菜单投影 | 哪些功能节点可见、显示什么名字 |
| 权限内核 | 该模块声明了哪些操作(编码)可供授权 |
核心原则:各自负责各自
- 权限负责「有什么操作」,只声明编码目录,不持有任何界面文案。
- 多语言负责「所有界面文案」,是菜单、模块、权限、字段、提示、按钮和校验信息的统一文案数据源。
- 字段定义驱动列表与表单,自身不关心权限、不关心翻译落点。
- 菜单是功能树的可投影子集,不单独存一份菜单数据。
2. 模块(Module)
模块是配置的中心对象,聚合「数据源 + 字段 + 表单分组 + 操作目录」。
2.1 基本信息
| 项 | 说明 |
|---|---|
模块编码 b_code |
可修改的唯一小写编码,如 m_biz、m_user |
| 模块名称 | 在「多语言」中以 module.<编码> 维护(见 §5) |
查询对象 view_name |
只读裸对象名(视图),如 v_bs_business |
保存对象 save_name |
可写裸表名,如 b_business;只读模块允许为空 |
| 业务主键 | 可选,用于展示与去重的业务字段,不代替系统主键 b_id |
| 默认排序 | 如 b_id DESC |
| 表单分组 | 见 §3.3 |
2.2 操作目录(权限项来源,见 §6)
模块声明它拥有哪些操作:actions: [{ code, name }, ...]。例如 m_biz 声明 1=新增 … 7=导出。
2.3 与其它能力的关联
Module
├─ fields[] → 驱动 ModuleTable / ModuleForm(§3)
├─ groups[] → 组织 Form 分组(§3.3)
├─ actions[] → 声明可被授权的操作编码(§6)
└─ 被功能树 page/module 节点引用 → 投影进菜单(§4)
3. 字段定义(Field)
字段是模块下的最小元数据单元,通用列表与通用表单都由字段配置驱动。
3.1 字段属性
| 属性 | 说明 |
|---|---|
字段编码 code |
模块对前端暴露的稳定字段名,如 b_ywno、b_amount |
标题 caption |
在「多语言」中以 field.<模块>.<字段> 维护,列表/表单共用 |
数据类型 dataType |
string / text / number / select / date / boolean |
表单分组 groupId |
指向模块的分组,Form 按分组渲染 |
列表显示 showInList |
是否作为列表列 |
表单显示 showInForm |
是否在表单中出现 |
必填 required |
表单校验 |
字段配置不保存查询操作符、不保存固定 SQL;高级查询运行时按字段类型给出合法操作符。
3.2 驱动关系
- 列表列 =
fields中showInList = true的子集,按所属分组/排序渲染列与标题。 - 表单控件 =
fields中showInForm = true的子集,dataType决定控件(文本/数字/下拉/日期/布尔),required决定校验。
3.3 表单分组(Group)
模块下可设多个分组(如「主信息」「费用信息」),字段通过 groupId 归属分组。简单表单可不配置分组,落入默认分组。
4. 菜单(Menu / 功能树)
菜单不是独立数据,而是「功能树」中满足条件的节点投影。
4.1 功能树节点
统一功能树 s_function_node 组织全部入口,节点类型:
| 类型 | 含义 | 能否投影菜单 |
|---|---|---|
directory |
业务域/目录 | 可(showInMenu) |
page |
已注册手写页面,可绑定模块 | 可(showInMenu) |
module |
纯配置定位,供技术归类 | 否 |
group |
配置分组 | 否 |
4.2 菜单投影规则
一个节点真正出现在某角色的菜单里,需同时满足:
- 节点类型 ∈ {
directory,page}; showInMenu = true;- 当前角色对该节点拥有「查看」权限。
4.3 关键场景:同模块、不同页面、不同权限
多个 page 节点可绑定同一个模块(如 m_biz 被 海运业务单 / 业务单查询 / 业务单审核 三个页面引用)。它们共享字段与操作目录,但:
- 可见性各自独立(
业务单审核设showInMenu=false,不进菜单); - 权限各自独立(操作员在「海运业务单」可提交,在「业务单审核」仅可审核)——授权由角色赋权页另配(不在本页面)。
- 模块父子关系(含
module节点)仅用于技术归类与定位,不定义保存事务、主子表外键或业务流程。
5. 多语言(i18n)
所有界面显示名唯一数据源,以稳定 i18nKey 为中心,多种语言并列。
5.1 覆盖范围
| 命名空间 | i18nKey 规则 | 示例 |
|---|---|---|
| 菜单/功能树 | menu.<节点id> |
menu.page_biz |
| 模块 | module.<模块编码> |
module.m_biz |
| 字段 | field.<模块>.<字段code> |
field.m_biz.b_ywno |
| 权限 | power.<模块>.<权限code> |
power.m_biz.audit |
| 按钮 | button.<模块>.<动作> |
button.m_biz.approve |
| 占位提示 | placeholder.<模块>.<字段> |
placeholder.m_biz.customer |
| 校验提示 | validation.<模块>.<规则> |
validation.m_biz.customer_required |
| 通用文案 | common.<名称> |
common.save |
5.2 数据结构
i18nData = {
"menu.page_biz": { "zh-CN": "海运业务单", "en-US": "Sea Business Orders", "zh-TW": "海運業務單" },
"field.m_biz.b_ywno": { "zh-CN": "业务单号", "en-US": "Order No.", "zh-TW": "業務單號" }
// ...
}
- 实体本身只持有
i18nKey,不持有任何文案,显示一律走t(i18nKey)。 - 回退顺序:当前语言 →
zh-CN→i18nKey本身。 - 切换语言时,功能树、字段标题、菜单预览实时联动。
5.3 管理界面要求
- 「多语言管理」是主配置中心,模块下的多语言面板是按当前模块过滤后的快捷编辑入口;两处写入同一张多语言表。
- 支持按命名空间、模块、语言和缺失翻译状态筛选。
- 以「Key + 各语言列」并列编辑;某语言留空即回退简体。
- 缺失翻译检测:非默认语言留空时标红,并汇总「N 条缺失」,提示补录。
6. 权限(Permission)
权限负责声明一个模块有哪些可授权操作,仅此而已。
6.1 权限项结构
// 模块声明
actions: [
{ code: 1, name: "新增", i18nKey: "power.m_biz.create" },
{ code: 5, name: "审核", i18nKey: "power.m_biz.audit" },
{ code: 7, name: "导出", i18nKey: "power.m_biz.export" }
]
code:稳定操作编码,前端与后端统一引用(如5永远代表「审核」)。授权与校验只认code,不认名字。name:管理员可读的默认中文回退标签。i18nKey:权限显示名绑定的多语言键;终端按钮如果需要不同文案,使用独立的button.*Key。
6.2 权限与按钮文案的边界
- 授权与校验始终只认
code,不依赖任何语言文本。 - 权限名称和按钮文案都进入统一多语言资源,但使用不同 Key,避免把「审核」与「通过」错误耦合。
- 权限定义保持
{code, name, i18nKey}自洽;按钮、提示和校验信息按各自命名空间独立维护。
6.3 与授权层的关系(边界)
- 本页面只负责声明操作目录(
code集合)。 - 真正的「角色 → 节点 → 允许哪些
code」赋权在另一页面配置,不在模块管理内。 - 模块管理里的菜单预览可用一份写死的授权结果做示意,但不在此维护。
6.4 扩展约定
- 模块新增一个权限项(如
8=核销),授权层无需改结构,直接照单收编码即可——两层天然对齐。
7. 五者关系总览
功能树 (directory/page/module/group)
│ page 节点绑定 模块
▼
模块 (Module: 查询/保存对象, 字段, 分组, 操作目录)
├─ 字段 ─────────────► 驱动 ModuleTable / ModuleForm
├─ 分组 ─────────────► 组织 Form
└─ 操作目录(code) ────► 权限内核(角色赋权页另行消费)
▲
│ 各自只声明稳定编码并绑定 i18nKey
│
多语言 (i18nKey → 多语言值) ──► 菜单 / 模块 / 权限 / 字段 / 按钮 / 提示 / 校验的唯一文案源
菜单 = 功能树中 showInMenu=1 且角色有查看权限的节点投影
8. 与当前原型(Demo)的对应关系
| 设计项 | 原型位置 | 备注 |
|---|---|---|
| 功能树四类节点 | functionTree |
已是响应式可编辑 |
| 模块基本信息/字段/分组 | modules |
m_module/m_user/m_biz/m_fee |
| 字段驱动列表/表单 | 字段配置 Tab |
列表/表单/必填开关 |
| 菜单投影 | 菜单预览 Tab |
按角色 + 语言渲染 |
| 多语言 | 多语言 Tab |
Key + 三语,含缺失标红 |
| 权限目录 | 权限项 Tab |
code + name,可增删 |
与原型的对齐情况
原型已按本文设计落地:
- 多语言覆盖所有界面文案;权限名称使用
power.*,终端按钮使用独立的button.*,两者不耦合。 - 权限项包含
{code, name, i18nKey};授权仍只认code,name作为默认中文回退。 - 字段多语言可在字段配置处点击设置:标题单元格带多语言按钮,点击打开该字段的简体/English/繁體编辑框(i18nKey 形如
field.<模块>.<字段>)。 - 字段
i18nKey统一为field.<模块>.<字段>,与模块/菜单<id>前缀、整体「命名空间.容器.标识」规则一致。 - 授权
roleNodePerm仍为写死 mock,仅用于菜单预览示意,符合 §6.3 边界(角色赋权在另一页面,不在模块管理内)。
9. 数据模型概览(落库参考)
| 表 | 用途 |
|---|---|
s_module |
模块定义(查询/保存对象、排序) |
s_module_field |
字段配置(编码、标题键、类型、列表/表单/必填、分组) |
s_module_group |
表单分组 |
s_function_node |
功能树(目录/页面/分组/模块定位) |
s_i18n |
统一多语言键值(key → 各语言值),覆盖所有界面文案 |
| 权限相关表 | 独立系统表,不属于 Table/Form 渲染配置 |
角色与权限内核使用独立系统表,不写入模块渲染配置;后端按
module_id+ 操作code校验权限,不能只依赖前端隐藏。