Files
workspace/code/fms/新数据库结构.md
T
2026-07-22 17:31:48 +08:00

294 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# FMS 新数据库结构
## 设计约定
- 表名和字段名沿用旧系统的 `b_` 风格。
- 所有表的 `b_id` 使用 `bigint` 雪花 ID,返回前端时序列化为字符串。
- `b_module.b_code` 是可修改的模块编码,使用小写字母、数字和下划线,例如 `m_biz`。
- 布尔字段使用 `int`:`1` 表示是,`0` 表示否,并限制只能写入 `0` 或 `1`。
- `b_xh` 表示显示顺序,数值越小越靠前。
- 当前按机构使用独立数据库,表中不保存机构编号。
- 模块管理界面只区分目录和普通模块;普通模块配置路由时保存为 `page`,未配置路由时保存为 `data`。
- 字段配置按两个使用状态设计:`list` 列表状态和 `edit` 编辑状态;连同字段基础定义共三张表。该结构为目标设计,需通过后续迁移替换当前 `b_module_field` 中混合保存的列表和表单属性。
## 模块管理
### 表关系
```text
b_module
|-- parent_id --> b_module
|-- 1:N --------> b_module_field
|-- 1:N --------> b_module_field_list -- parent_id --> b_module_field_list
|-- 1:N --------> b_user_module
|-- 1:N --------> b_module_power ---- 1:N ----> b_user_power
b_module_field
|-- 0:1 --------> b_module_field_list
|-- 0:1 --------> b_module_field_edit
b_module / b_module_field / b_module_field_list / b_module_field_edit / b_module_power
|-- b_i18n --> b_i18n.b_key
```
### `dbo.b_module`
保存目录、页面和数据模块。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 不可变雪花 ID 主键 |
| `b_code` | `varchar(50)` | 可修改的唯一模块编码,例如 `m_biz` |
| `b_parent_id` | `bigint` | 上级模块 ID,根节点为空 |
| `b_name` | `nvarchar(100)` | 默认中文名称 |
| `b_i18n` | `varchar(150)` | 多语言键 |
| `b_type` | `varchar(20)` | `directory`、`page` 或 `data` |
| `b_route` | `varchar(200)` | 页面路由 |
| `b_viewtable` | `varchar(128)` | 查询表或视图 |
| `b_savetable` | `varchar(128)` | 保存目标表 |
| `b_keyfield` | `varchar(50)` | 主键字段 |
| `b_orderfield` | `varchar(500)` | 排序条件,例如 `b_xh ASC, b_id DESC` |
| `b_canmenu` | `int` | 是否显示在菜单,默认 `0` |
| `b_canuse` | `int` | 是否启用,默认 `1` |
| `b_xh` | `int` | 同级显示顺序 |
约束:
- `b_parent_id` 外键引用 `b_module.b_id`。
- `b_code` 唯一,格式为 `^[a-z][a-z0-9_]{1,49}$`。
- `b_route` 非空时唯一。
- 目录不能配置路由和数据表;数据模块不能显示在菜单中。
- 表名、视图名和字段名必须由后端校验,不能直接拼接 SQL。
### `dbo.b_module_field`
保存字段本身的稳定定义,不保存列表位置、表单位置等界面场景属性。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 雪花 ID 主键 |
| `b_module_id` | `bigint` | 所属模块 ID |
| `b_field` | `varchar(50)` | 数据库字段名 |
| `b_name` | `nvarchar(100)` | 默认中文名称 |
| `b_i18n` | `varchar(150)` | 多语言键 |
| `b_type` | `varchar(20)` | `string`、`text`、`number`、`select`、`date`、`boolean` |
| `b_value` | `nvarchar(500)` | 新增时的默认值 |
| `b_dict_code` | `varchar(100)` | 字典编码,非字典字段为空 |
| `b_canuse` | `int` | 是否启用 |
| `b_remark` | `nvarchar(500)` | 字段说明 |
约束:
- `b_module_id` 外键引用 `b_module.b_id`。
- `(b_module_id, b_field)` 唯一。
- `b_canuse` 只能为 `0` 或 `1`。
- 字段未配置对应的表格列或编辑字段记录时,表示该字段不参与对应场景。
- `select` 的选项来源优先使用 `b_dict_code`,复杂选项来源后续单独设计。
- 建立 `(b_module_id, b_canuse, b_id)` 索引,用于按模块加载字段定义。
### `dbo.b_module_field_list`
保存字段在 `list` 状态下的列结构和显示配置。只读列表和可编辑 Table 都使用本表;表头分组节点与字段节点保存在同一张自关联表中,通过 `b_parent_id` 组成任意层级的表头树。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 雪花 ID 主键 |
| `b_module_id` | `bigint` | 所属模块 ID;分组节点没有字段关系,因此必须直接保存模块 ID |
| `b_parent_id` | `bigint` | 上级表头分组 ID,顶层节点为空 |
| `b_kind` | `varchar(20)` | 节点类型:`group` 或 `field` |
| `b_field_id` | `bigint` | 字段节点关联 `b_module_field.b_id`;分组节点为空 |
| `b_title` | `nvarchar(100)` | 分组标题或字段列标题覆盖值;字段节点为空时使用字段默认名称 |
| `b_i18n` | `varchar(150)` | 分组多语言键或字段列多语言键覆盖值 |
| `b_visible` | `int` | 当前是否显示;分组隐藏时其全部后代都不显示 |
| `b_xh` | `int` | 在同一父节点下的显示顺序 |
| `b_width` | `int` | 字段列宽;分组节点为空,由子列计算 |
| `b_sortable` | `int` | 是否允许排序 |
| `b_display_type` | `varchar(30)` | 显示方式,例如 `text`、`date`、`money`、`dict`、`tag`、`link` |
| `b_display_format` | `varchar(100)` | 显示格式,例如日期格式或数字格式 |
| `b_display_options` | `nvarchar(max)` | 少量显示器专属配置,保存 JSON;无配置时为空 |
| `b_canedit` | `int` | 是否允许在表格单元格内编辑;仅字段节点可为 `1` |
| `b_canquery` | `int` | 是否作为列表查询条件 |
约束:
- `b_module_id` 外键引用 `b_module.b_id`,`b_parent_id` 外键引用本表 `b_id`。
- `group` 节点的 `b_field_id` 必须为空,`field` 节点的 `b_field_id` 必须非空。
- 同一字段在同一模块的表格列树中最多出现一次,使用过滤唯一索引约束非空 `b_field_id`。
- `b_parent_id` 必须指向同一模块的 `group` 节点,且不能形成循环;由保存服务校验。
- `b_visible`、`b_sortable`、`b_canedit`、`b_canquery` 只能为 `0` 或 `1`。
- `group` 节点的 `b_canedit` 必须为 `0`;`field` 节点 `b_canedit = 1` 时,必须存在对应的 `b_module_field_edit` 编辑规则。
- `b_display_options` 非空时必须通过 SQL Server `ISJSON` 校验。
- 不保存 `level`、`colspan` 和 `rowspan`,由表头树及可见叶子节点计算。
- 分组下没有可见字段节点时,不渲染该分组。
- 列表分组节点与字段节点统一使用 `b_xh` 表示同级顺序,因此分组和顶层字段可以混合排序。
- 建立 `(b_module_id, b_parent_id, b_xh, b_id)` 索引,用于一次加载并组装表格列树。
示例:
```text
基础信息(group)
|-- 订单号(field)
|-- 客户名称(field)
`-- 运输信息(group)
|-- 起运港(field)
`-- 目的港(field)
```
加载模块的全部列后,按 `b_parent_id` 和 `b_xh` 在前端组装为 `FmsTable` 使用的嵌套 `children`,不需要为每一级表头执行单独查询。只读列表忽略 `b_canedit`;可编辑子表根据 `b_canedit` 和对应编辑规则生成单元格编辑器。
### `dbo.b_module_field_edit`
保存字段在 `edit` 状态下的编辑规则,以及字段在 Form 中的布局。编辑状态同时供 Form 和可编辑 Table 复用;表单分组只是同一个表单中的视觉分组,不代表页签或动态页面区域。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 雪花 ID 主键 |
| `b_module_id` | `bigint` | 所属模块 ID,便于通过通用接口直接按模块加载 |
| `b_field_id` | `bigint` | 关联 `b_module_field.b_id` |
| `b_editor` | `varchar(30)` | 编辑控件,例如 `input`、`textarea`、`select`、`date-picker`、`switch` |
| `b_edit_format` | `varchar(100)` | 编辑值格式,例如日期格式或数字精度格式 |
| `b_editor_options` | `nvarchar(max)` | 少量编辑控件专属配置,保存 JSON;无配置时为空 |
| `b_required` | `int` | 是否必填 |
| `b_readonly` | `int` | 是否只读 |
| `b_disabled` | `int` | 是否禁用 |
| `b_placeholder` | `nvarchar(200)` | 输入提示 |
| `b_canform` | `int` | 是否在 Form 中显示;为 `0` 时编辑规则仍可供可编辑 Table 使用 |
| `b_edit_group` | `varchar(100)` | 编辑分组 key;不分组时为空 |
| `b_edit_xh` | `int` | 整个编辑区域内的全局显示顺序 |
| `b_edit_span` | `int` | Form 编辑时的栅格宽度,例如 `6`、`8`、`12`、`24` |
约束:
- `b_module_id` 外键引用 `b_module.b_id`,`b_field_id` 外键引用 `b_module_field.b_id`。
- `(b_module_id, b_field_id)` 唯一,且字段必须属于同一模块;模块一致性由保存服务校验。
- `b_required`、`b_readonly`、`b_disabled`、`b_canform` 只能为 `0` 或 `1`。
- `b_edit_span` 必须大于 `0` 且不超过 `24`。
- `b_editor_options` 非空时必须通过 SQL Server `ISJSON` 校验。
- `b_edit_group` 为空表示不分组;非空时使用页面代码中声明的分组 key,例如 `basic`、`booking`。
- 编辑分组按组内最小的 `b_edit_xh` 排序,组内字段也按 `b_edit_xh` 排序;不重复保存分组顺序。
- 分组标题、主表、子表和页面组合仍由具体 Vue 页面显式维护,不建立动态页面区域模型。
- 建立 `(b_module_id, b_edit_xh, b_id)` 索引,用于按模块顺序加载编辑字段并计算分组顺序。
### 字段配置语义
- 字段没有表格列配置记录:不参与 Table 及主列表查询。
- 字段有表格列配置且 `b_visible = 0`:保留列配置但当前不显示,仍可通过 `b_canquery = 1` 作为主列表查询条件。
- 字段没有编辑字段配置记录:不能用于 Form 或可编辑 Table。
- `b_canform = 0`:字段不出现在 Form 中,但编辑规则仍可供可编辑 Table 使用。
- `b_canedit = 1`:表格单元格使用对应 `b_module_field_edit` 的编辑器、格式、必填和只读规则。
- 表格显示、表格位置、Form 布局和编辑方式相互独立,可以只使用其中一个场景。
- 子表使用独立模块及字段配置,不在字段配置中增加区域、页签或子表类型。
### 海运页面组合示例
海运业务页面是显式编写的 Vue 页面,只负责组合数据模块,不通过字段配置自动生成区域。
```text
海运业务页面 m_sea(路由、菜单、权限、页面编排)
|-- 海运主单 d_sea
| |-- 海运列表:Table,读取 b_module_field_list,全部 b_canedit = 0
| `-- 主单编辑:Form,读取 b_module_field_edit 且 b_canform = 1
|-- 订舱主单 d_booking(订舱有独立表和主键时)
| `-- 订舱编辑:Form,读取 b_module_field_edit 且 b_canform = 1
`-- 装箱明细 d_container
`-- 装箱编辑表:Table,读取 b_module_field_list;b_canedit = 1 的字段读取 b_module_field_edit
```
若订舱字段实际保存于海运主单表,不建立 `d_booking`,而是在 `d_sea` 的 Form 中使用不同的 `b_edit_group`。主表、订舱主表和装箱子表的保存关联、加载时机和页面布局由业务页面代码明确处理。
### 现有字段迁移
当前 `b_module_field` 的混合配置迁移到目标结构时按以下规则处理:
| 当前字段 | 目标字段 |
| --- | --- |
| `b_canlist` | `b_module_field_list.b_visible` |
| `b_width` | `b_module_field_list.b_width` |
| `b_canquery` | `b_module_field_list.b_canquery` |
| `b_xh` | 分别初始化 `b_module_field_list.b_xh` 和 `b_module_field_edit.b_edit_xh` |
| `b_canform` | `b_module_field_edit.b_canform` |
| `b_must` | `b_module_field_edit.b_required` |
| `b_readonly` | `b_module_field_edit.b_readonly` |
| `b_value` | 保留在 `b_module_field.b_value` |
迁移时先为现有字段创建顶层 `field` 列表状态节点,`b_parent_id` 为空、`b_canedit = 0`;多级表头分组及可编辑子表列由后续配置补充。迁移、前端适配和旧字段删除应分阶段实施,确认新结构读写稳定后再删除旧列。
### `dbo.b_module_power`
定义模块内可以授权的按钮操作。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 雪花 ID 主键 |
| `b_module_id` | `bigint` | 所属模块 ID |
| `b_code` | `varchar(50)` | 操作编码,例如 `create`、`update`、`delete` |
| `b_name` | `nvarchar(100)` | 操作名称 |
| `b_i18n` | `varchar(150)` | 多语言键 |
| `b_xh` | `int` | 显示顺序 |
| `b_canuse` | `int` | 是否启用 |
约束:
- `b_module_id` 外键引用 `b_module.b_id`。
- `(b_module_id, b_code)` 唯一。
- 模块使用权限不在本表定义。
### `dbo.b_user_module`
控制用户能否进入和使用模块。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 雪花 ID 主键 |
| `b_user_id` | `bigint` | 用户雪花 ID |
| `b_module_id` | `bigint` | 模块 ID |
| `b_inputuser_id` | `bigint` | 授权人雪花 ID |
| `b_inputdatetime` | `datetime` | 授权时间 |
约束:
- `b_module_id` 外键引用 `b_module.b_id`。
- `(b_user_id, b_module_id)` 唯一。
- 目录不单独授权;拥有下级模块时自动显示上级目录。
### `dbo.b_user_power`
保存用户拥有的操作权限。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 雪花 ID 主键 |
| `b_user_id` | `bigint` | 用户雪花 ID |
| `b_power_id` | `bigint` | `b_module_power.b_id` |
| `b_inputuser_id` | `bigint` | 授权人雪花 ID |
| `b_inputdatetime` | `datetime` | 授权时间 |
约束:
- `b_power_id` 外键引用 `b_module_power.b_id`。
- `(b_user_id, b_power_id)` 唯一。
### `dbo.b_i18n`
统一保存菜单、模块、权限、字段、按钮、提示和校验信息等界面文案;业务对象只绑定稳定的 `b_key`。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 雪花 ID 主键 |
| `b_key` | `varchar(150)` | 多语言键 |
| `b_locale` | `varchar(20)` | 语言编码,例如 `zh-CN` |
| `b_value` | `nvarchar(500)` | 翻译文本 |
| `b_inputuser_id` | `bigint` | 创建人雪花 ID |
| `b_inputdatetime` | `datetime` | 创建时间 |
| `b_updateuser_id` | `bigint` | 修改人雪花 ID |
| `b_updatedatetime` | `datetime` | 修改时间 |
约束:`(b_key, b_locale)` 唯一。
### 权限规则
1. `b_user_module` 决定用户能否看到、进入和调用模块。
2. `b_user_power` 决定用户进入模块后可以执行哪些按钮操作。
3. 操作权限必须在拥有模块权限时才生效。
4. 当前阶段由前端负责页面进入控制和按钮禁用,后端权限校验后续单独实施。