251 lines
11 KiB
Markdown
251 lines
11 KiB
Markdown
# 模块管理功能设计
|
||
|
||
> 范围:模块管理这一功能本身的设计定义,覆盖 **模块、字段定义、菜单、多语言、权限** 五大能力。
|
||
> 定位:本文档描述「模块管理页面能配置什么、各能力如何分工」,**不描述**通用 `ModuleTable`/`ModuleForm` 的渲染实现,也不描述角色赋权页面(授权在另一处)。
|
||
> 配套原型:`fms-vue/src/views/ModuleManageDemo.vue`(纯前端,仅作演示)。
|
||
|
||
---
|
||
|
||
## 1. 设计目标与边界
|
||
|
||
模块管理是一个**配置中枢**,让实施人员用「填表」的方式定义一套业务功能,而不必改代码。它同时服务于四类下游消费者:
|
||
|
||
| 消费者 | 从模块管理取走什么 |
|
||
| --- | --- |
|
||
| 通用列表 `ModuleTable` | 字段清单、列标题、列表/表单开关、排序 |
|
||
| 通用表单 `ModuleForm` | 字段控件类型、校验、表单分组 |
|
||
| 菜单投影 | 哪些功能节点可见、显示什么名字 |
|
||
| 权限内核 | 该模块声明了哪些操作(编码)可供授权 |
|
||
|
||
### 核心原则:各自负责各自
|
||
|
||
1. **权限负责「有什么操作」**,只声明编码目录,不持有任何界面文案。
|
||
2. **多语言负责「所有界面显示名」**,是唯一文案数据源;但**只覆盖菜单 / 模块 / 字段三类显示名,不覆盖权限项**(权限名是给管理员看的配置标签,不是给终端用户的按钮文案)。
|
||
3. **字段定义驱动列表与表单**,自身不关心权限、不关心翻译落点。
|
||
4. **菜单是功能树的可投影子集**,不单独存一份菜单数据。
|
||
|
||
---
|
||
|
||
## 2. 模块(Module)
|
||
|
||
模块是配置的中心对象,聚合「数据源 + 字段 + 表单分组 + 操作目录」。
|
||
|
||
### 2.1 基本信息
|
||
|
||
| 项 | 说明 |
|
||
| --- | --- |
|
||
| 模块编码 `b_id` | 唯一主键,如 `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 菜单投影规则
|
||
|
||
一个节点真正出现在某角色的菜单里,需同时满足:
|
||
|
||
1. 节点类型 ∈ {`directory`, `page`};
|
||
2. `showInMenu = true`;
|
||
3. 当前角色对该节点拥有「查看」权限。
|
||
|
||
### 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` |
|
||
|
||
> **权限项名称不在此列**(见 §6 说明)。
|
||
|
||
### 5.2 数据结构
|
||
|
||
```js
|
||
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 权限项结构
|
||
|
||
```js
|
||
// 模块声明
|
||
actions: [
|
||
{ code: 1, name: "新增" },
|
||
{ code: 5, name: "审核" },
|
||
{ code: 7, name: "导出" }
|
||
]
|
||
```
|
||
|
||
- `code`:稳定操作编码,前端与后端统一引用(如 `5` 永远代表「审核」)。**授权与校验只认 `code`,不认名字。**
|
||
- `name`:管理员可读的默认标签,仅一份(简体)。它是「这个编码是干嘛的」的配置注释,**不是终端用户的按钮文案**。
|
||
|
||
### 6.2 为什么不进多语言
|
||
|
||
- 授权逻辑只认 `code`,名字不参与校验,因此没有翻译必要。
|
||
- 界面上的按钮文案常与权限名不同(权限叫「审核」,按钮可能写「通过」),把权限名塞进 i18n 反而把「权限定义」与「按钮文案」错误耦合。
|
||
- 结论:**权限定义自洽于 `{code, name}`,与多语言彻底解耦**;终端用户看到的按钮文案由各自页面/组件自行在多语言里维护。
|
||
|
||
### 6.3 与授权层的关系(边界)
|
||
|
||
- 本页面**只负责声明**操作目录(`code` 集合)。
|
||
- 真正的「角色 → 节点 → 允许哪些 `code`」赋权在**另一页面**配置,不在模块管理内。
|
||
- 模块管理里的菜单预览可用一份写死的授权结果做示意,但不在此维护。
|
||
|
||
### 6.4 扩展约定
|
||
|
||
- 模块新增一个权限项(如 `8=核销`),授权层无需改结构,直接照单收编码即可——两层天然对齐。
|
||
|
||
---
|
||
|
||
## 7. 五者关系总览
|
||
|
||
```
|
||
功能树 (directory/page/module/group)
|
||
│ page 节点绑定 模块
|
||
▼
|
||
模块 (Module: 查询/保存对象, 字段, 分组, 操作目录)
|
||
├─ 字段 ─────────────► 驱动 ModuleTable / ModuleForm
|
||
├─ 分组 ─────────────► 组织 Form
|
||
└─ 操作目录(code) ────► 权限内核(角色赋权页另行消费)
|
||
▲
|
||
│ 各自只声明,不持有文案
|
||
│
|
||
多语言 (i18nKey → 多语言值) ──► 菜单名 / 模块名 / 字段标题 的唯一文案源
|
||
(权限名不在内)
|
||
|
||
菜单 = 功能树中 showInMenu=1 且角色有查看权限的节点投影
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 与当前原型(Demo)的对应关系
|
||
|
||
| 设计项 | 原型位置 | 备注 |
|
||
| --- | --- | --- |
|
||
| 功能树四类节点 | `functionTree` | 已是响应式可编辑 |
|
||
| 模块基本信息/字段/分组 | `modules` | `M_MODULE/M_USER/M_BIZ/M_FEE` |
|
||
| 字段驱动列表/表单 | `字段配置` Tab | 列表/表单/必填开关 |
|
||
| 菜单投影 | `菜单预览` Tab | 按角色 + 语言渲染 |
|
||
| 多语言 | `多语言` Tab | Key + 三语,含缺失标红 |
|
||
| 权限目录 | `权限项` Tab | `code + name`,可增删 |
|
||
|
||
### 与原型的对齐情况
|
||
|
||
原型已按本文设计落地:
|
||
|
||
- **多语言仅覆盖菜单 / 模块 / 字段三类显示名**;`action.*` 条目已从 `i18nData` 彻底移除,权限项名不再进多语言(符合 §6)。
|
||
- **权限项仅含 `{code, name}`**,`name` 为管理员可读标签,不在多语言维护;新增权限项不再生成 i18nKey。
|
||
- **字段多语言可在字段配置处点击设置**:标题单元格带多语言按钮,点击打开该字段的简体/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` 校验权限,不能只依赖前端隐藏。
|