16 KiB
FMS 新数据库结构
设计原则
b_module是核心元数据对象,统一表示菜单目录、页面和数据模块。- 字段来源于数据模块配置的查询视图。系统不创建业务字段,只同步视图字段,并维护其展示、编辑、查询和权限配置。
- 页面和业务逻辑不完全元数据化。海运等复杂业务页面由 Vue 页面显式组合多个数据模块,元数据只提供 Table、Form 和 Query 配置。
- 字段基础定义、列表、编辑、查询四个职责分离;一个字段可以只参与其中任一场景。
- 模块权限控制访问,操作权限控制按钮动作;操作权限必须依赖模块访问权限。
- 表名和字段名沿用旧系统的
b_风格。全部b_id使用bigint雪花 ID,返回前端时序列化为字符串。 - 布尔字段统一使用
int,1表示是、0表示否;b_xh数值越小越靠前。 - 当前按机构使用独立数据库,表中不保存机构编号。表名、视图名和字段名必须由后端白名单校验,不能直接拼接 SQL。
整体关系
b_module
|-- parent_id --> b_module
|-- 1:N --------> b_module_field
|-- 1:N --------> b_module_field_edit_group
|-- 1:N --------> b_module_power ---- 1:N ----> b_user_power
`-- 1:N --------> b_user_module
b_module_field
|-- 0:N --------> b_module_field_list -- parent_id --> b_module_field_list
|-- 0:1 --------> b_module_field_edit
`-- 0:1 --------> b_module_field_query
b_module / b_module_field / b_module_field_list / b_module_field_edit_group / b_module_power
`-- b_i18n --> b_i18n.b_key
模块
dbo.b_module
统一保存目录、页面和数据模块。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
不可变雪花 ID 主键 |
b_code |
varchar(50) |
可修改的唯一模块编码,例如 m_sea、d_container |
b_parent_id |
bigint |
上级模块 ID;根节点为空 |
b_name |
nvarchar(100) |
默认中文名称 |
b_i18n |
varchar(150) |
多语言键 |
b_module_type |
varchar(20) |
directory、page 或 data |
b_route |
varchar(200) |
页面路由,例如 /sea/list |
b_viewtable |
varchar(128) |
查询来源表或视图;数据模块字段从此处同步 |
b_savetable |
varchar(128) |
保存目标表 |
b_keyfield |
varchar(50) |
主键字段,例如 b_id |
b_orderfield |
varchar(500) |
默认排序,例如 b_xh ASC, b_id DESC |
b_canmenu |
int |
是否显示在菜单,默认 0 |
b_canuse |
int |
是否启用,默认 1 |
b_xh |
int |
同级显示顺序,默认 0 |
约束:
b_parent_id外键引用b_module.b_id;保存服务校验父节点不形成循环。b_code唯一,格式为^[a-z][a-z0-9_]{1,49}$;b_route非空时唯一。directory不能配置b_route、b_viewtable或b_savetable。page必须配置b_route,用于路由、菜单和页面编排;其业务数据由页面组合的数据模块提供。data不能显示菜单;应配置b_viewtable,保存场景再按需配置b_savetable与b_keyfield。b_canmenu、b_canuse只能为0或1。建议建立(b_parent_id, b_xh, b_id)索引。
字段来源与同步
dbo.b_module_field
保存字段的基础定义,不保存列宽、表单位置、是否显示或查询位置等场景属性。字段来自数据模块的 b_viewtable,并以 (b_module_id, b_field) 作为稳定标识。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
雪花 ID 主键 |
b_module_id |
bigint |
所属数据模块 ID |
b_field |
varchar(50) |
视图字段名 |
b_name |
nvarchar(100) |
默认字段名称,由管理员维护 |
b_i18n |
varchar(150) |
多语言键 |
b_field_type |
varchar(30) |
string、text、number、date、datetime、boolean、select_id 或 select_input |
b_value |
nvarchar(500) |
新增时默认值 |
b_dict_code |
varchar(100) |
字典编码;非字典字段为空 |
b_canuse |
int |
是否启用 |
b_remark |
nvarchar(500) |
字段说明 |
b_inputdatetime |
datetime |
首次同步创建时间 |
约束:
b_module_id外键引用b_module.b_id,(b_module_id, b_field)唯一。b_canuse只能为0或1。建议建立(b_module_id, b_canuse, b_id)索引。- 字段没有 list、edit 或 query 配置记录时,不参与对应场景。
select_id保存选项 ID;select_input支持从选项中选择或直接输入文本。字典型选择器使用b_dict_code;视图型选择器的来源配置保存在b_module_field_edit.b_editor_options。
视图同步规则
字段同步服务仅面向 b_module_type = 'data' 且配置了 b_viewtable 的模块执行:
- 后端校验视图名并读取列名、SQL 类型和可空性等结构信息。
- 按列名查找同模块的
b_module_field;新列创建字段基础记录。 - 同步更新
b_field、b_field_type和b_canuse。SQL 类型映射为string、text、number、date、datetime、boolean等基础类型;select_id、select_input由管理员在同步后按业务语义调整。 - 本次视图中不存在的已有字段保留其记录和全部场景配置,但将
b_canuse置为0。 - 不覆盖人工维护的
b_name、b_i18n、b_value、b_dict_code和b_remark,不物理删除字段或场景配置。
列表配置
dbo.b_module_field_list
控制 Table 列、显示方式和多级表头。分组节点与字段节点通过 b_parent_id 组成任意层级的表头树;只读列表和可编辑 Table 共用本表。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
雪花 ID 主键 |
b_module_id |
bigint |
所属模块 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 |
是否显示,默认 1 |
b_xh |
int |
同一父节点下的显示顺序,默认 0 |
b_width |
int |
字段列宽;分组节点为空 |
b_sortable |
int |
是否允许排序,默认 0 |
b_display_type |
varchar(30) |
显示器类型,例如 text、money、date、datetime、tag;前端按类型使用统一显示规则 |
b_canedit |
int |
是否允许表格单元格编辑,默认 0 |
约束:
b_module_id外键引用b_module.b_id,b_parent_id外键引用本表b_id,b_field_id外键引用b_module_field.b_id。group节点必须没有b_field_id、b_width,且b_canedit = 0;field节点必须有b_field_id。- 同一字段在同一模块的列树中最多出现一次,使用非空
b_field_id的过滤唯一索引约束。 b_parent_id必须指向同模块的group节点,且不能形成循环,由保存服务校验。b_visible、b_sortable、b_canedit只能为0或1;b_canedit = 1时必须存在对应编辑规则。b_display_type决定显示器及其格式化规则,例如money、date、datetime均由前端按统一规则渲染。建议建立(b_module_id, b_parent_id, b_xh, b_id)索引。- 不保存
level、colspan、rowspan;前端一次加载全部节点后,按b_parent_id、b_xh组装嵌套children并计算表头。隐藏分组的后代不显示;没有可见字段后代的分组不渲染。
示例:
费用(group)
|-- 人工费(field)
`-- 海运费(field)
编辑配置
dbo.b_module_field_edit
控制 Form 和可编辑 Table 的共享编辑规则,以及字段在 Form 中的布局。表单分组仅是视觉分组,不表示页签、动态页面区域或主子表关系;分组标题和多语言由独立分组表维护。
| 字段 | 类型 | 说明 |
|---|---|---|
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、switch |
b_edit_format |
varchar(100) |
编辑值格式 |
b_editor_options |
nvarchar(max) |
编辑器专属 JSON 配置 |
b_required |
int |
是否必填,默认 0 |
b_readonly |
int |
是否只读,默认 0 |
b_disabled |
int |
是否禁用,默认 0 |
b_placeholder |
nvarchar(200) |
输入提示 |
b_canform |
int |
是否进入 Form,默认 1 |
b_edit_group |
varchar(100) |
关联 b_module_field_edit_group.b_code;不分组时为空 |
b_edit_xh |
int |
编辑区域中的全局顺序,默认 0 |
b_edit_span |
int |
Form 栅格宽度,默认 24,范围 1 至 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_editor_options非空时通过ISJSON校验。- 非空
b_edit_group必须引用同模块的启用分组;保存服务校验模块一致性。 - 已分组字段按所属分组的
b_xh排列,组内按b_edit_xh排列;未分组字段作为末尾默认区域,按b_edit_xh排列。建议建立(b_module_id, b_edit_xh, b_id)索引。 b_canform = 0时,编辑规则仍可由可编辑 Table 使用。
dbo.b_module_field_edit_group
保存 Form 的视觉分组标题和多语言配置。一个模块可以有多个分组,字段通过 b_edit_group 引用其稳定编码。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
雪花 ID 主键 |
b_module_id |
bigint |
所属模块 ID |
b_code |
varchar(100) |
分组稳定编码,例如 basic、booking |
b_title |
nvarchar(100) |
默认分组标题 |
b_i18n |
varchar(150) |
分组标题多语言键 |
b_xh |
int |
分组显示顺序,默认 0 |
b_canuse |
int |
是否启用,默认 1 |
约束:
b_module_id外键引用b_module.b_id,(b_module_id, b_code)唯一。b_canuse只能为0或1。建议建立(b_module_id, b_canuse, b_xh, b_id)索引。- 无字段引用的分组不渲染;分组停用时,其关联字段不在 Form 中显示。
视图型选择器的 b_editor_options 示例:
{
"source": "view",
"view": "v_partner",
"valueField": "b_id",
"labelField": "b_name",
"allowInput": false
}
select_id 使用 allowInput: false 并保存 valueField 的值;select_input 可使用 allowInput: true 并保存选择值或用户输入文本。视图名、值字段和标签字段均须由后端校验。
查询配置
dbo.b_module_field_query
独立控制主列表查询条件,不依赖字段是否配置为可见列表列。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
雪花 ID 主键 |
b_module_id |
bigint |
所属模块 ID |
b_field_id |
bigint |
关联 b_module_field.b_id |
b_component |
varchar(30) |
查询组件 |
b_operator |
varchar(20) |
=、like、between 或 in |
b_default_value |
nvarchar(500) |
默认查询值 |
b_xh |
int |
查询条件显示顺序,默认 0 |
b_canuse |
int |
是否启用,默认 1 |
约束:
b_module_id外键引用b_module.b_id,b_field_id外键引用b_module_field.b_id;(b_module_id, b_field_id)唯一,保存服务校验模块一致性。b_canuse只能为0或1;b_operator必须属于定义的操作符集合。- 查询组件与操作符由后端白名单校验;查询值必须参数化,不能由配置直接拼接 SQL。
- 建议建立
(b_module_id, b_canuse, b_xh, b_id)索引。
权限与多语言
dbo.b_module_power
定义模块内可授权的按钮操作。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
雪花 ID 主键 |
b_module_id |
bigint |
所属模块 ID |
b_code |
varchar(50) |
操作编码,例如 create、update、delete、audit、export |
b_name |
nvarchar(100) |
操作名称 |
b_i18n |
varchar(150) |
多语言键 |
b_xh |
int |
显示顺序 |
b_canuse |
int |
是否启用,默认 1 |
约束:b_module_id 外键引用 b_module.b_id,(b_module_id, b_code) 唯一,b_canuse 只能为 0 或 1。
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) 唯一。
权限规则:
- 用户必须拥有
b_user_module记录,才能进入或调用该模块。 - 用户必须同时拥有模块权限和对应
b_user_power记录,才能执行按钮动作。 - 前端据此控制路由进入和按钮可用性;后端接口后续实施同等权限校验。
dbo.b_i18n
统一保存菜单、模块、字段、权限、按钮、提示和校验信息等界面文案。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
雪花 ID 主键 |
b_key |
varchar(150) |
多语言键 |
b_locale |
varchar(20) |
语言编码,例如 zh-CN |
b_value |
nvarchar(500) |
翻译文本 |
约束:(b_key, b_locale) 唯一。
页面组合示例
海运业务页面由 Vue 显式组合数据模块,不通过字段配置创建动态页面区域:
海运页面 m_sea(page:路由、菜单、权限、页面编排)
|-- 海运主单 d_sea(data:Table / Form / Query)
|-- 费用 d_charge(data:可编辑 Table)
|-- 订舱 d_booking(data:独立表和主键时)
`-- 箱明细 d_container(data:可编辑 Table)
若订舱字段实际保存于海运主单表,不创建 d_booking,而在 d_sea 的 Form 中用 b_module_field_edit_group 和 b_edit_group 表达视觉分组。主子表关联、加载时机、保存顺序和页面布局均由业务 Vue 页面明确实现。
现有字段迁移
当前 b_module_field 混合保存基础、列表、编辑和查询属性。迁移应分阶段实施:
| 当前字段 | 目标位置 |
|---|---|
b_type |
b_module_field.b_field_type |
b_canlist |
b_module_field_list.b_visible |
b_width |
b_module_field_list.b_width |
b_xh |
初始化 b_module_field_list.b_xh、b_module_field_edit.b_edit_xh 与 b_module_field_query.b_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_canquery |
创建 b_module_field_query 记录 |
b_value |
保留在 b_module_field.b_value |
迁移步骤:
- 新建 list、edit、edit_group、query 表和必要索引,新增
b_module.b_module_type与b_module_field.b_field_type的兼容列。 - 为原有字段创建顶层
field列配置;根据原b_canform、b_canquery创建编辑和查询配置;初始b_canedit = 0。 - 前端和后端改为读取新场景表,查询不再读取 list 配置;模块类型切换为读取
b_module_type。 - 完成视图同步服务并验证新结构的读写稳定后,删除旧混合列和兼容字段。