16 KiB
FMS 新数据库结构
设计原则
b_module是核心元数据对象,统一表示菜单目录、页面和数据模块。- 字段来源于数据模块配置的查询视图。系统不创建业务字段,只同步视图字段,并维护其展示、编辑、查询和权限配置。
- 页面和业务逻辑不完全元数据化。海运等复杂业务页面由 Vue 页面显式组合多个数据模块,元数据只提供 Table、Form 和 Query 配置。
- 字段基础定义、列表、编辑、查询四个职责分离;一个字段可以只参与其中任一场景。
- 编辑规则与列表布局解耦:
b_module_field_edit是通用编辑配置,FmsForm 和 FmsTable 可按自身规则消费;b_module_field_list只描述列表展示,不保存编辑状态。 - 模块权限控制访问,操作权限控制按钮动作;操作权限必须依赖模块访问权限。
- 表名和字段名沿用旧系统的
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_group -- parent_id --> b_module_field_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 -- group_id --> b_module_field_group
|-- 0:1 --------> b_module_field_edit -- group_id --> b_module_field_group
`-- 0:1 --------> b_module_field_query
b_module / b_module_field / b_module_field_list / b_module_field_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_route;必须配置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_type |
varchar(30) |
字段控件类型:input、textarea、number、money、date、datetime、switch 或 select |
b_default_value |
nvarchar(500) |
新增记录时的默认值 |
b_options |
nvarchar(max) |
类型专属 JSON 配置,例如选择器来源、日期格式或金额精度 |
b_canuse |
int |
是否启用 |
约束:
b_module_id外键引用b_module.b_id,(b_module_id, b_field)唯一。b_canuse只能为0或1;b_options非空时通过ISJSON校验。建议建立(b_module_id, b_canuse, b_id)索引。- 字段没有 list、edit 或 query 配置记录时,不参与对应场景。
b_type是展示和编辑的唯一类型来源:Table 按它渲染默认显示器,Form 或可编辑 Table 按它选择控件。select是否允许自由输入、选项来源、值字段和显示字段均由b_options控制。
视图同步规则
字段同步服务仅面向 b_module_type = 'data' 且配置了 b_viewtable 的模块执行:
- 后端校验视图名并读取列名、SQL 类型和可空性等结构信息。
- 按列名查找同模块的
b_module_field;新列创建字段基础记录。 - 新字段按 SQL 类型初始化
b_type,例如字符串映射为input、长文本映射为textarea、数值映射为number、日期映射为date或datetime、位值映射为switch。已有字段不覆盖管理员维护的b_type与b_options;select、money等业务类型由管理员按语义调整。 - 本次视图中不存在的已有字段保留其记录和全部场景配置,但将
b_canuse置为0。 - 不覆盖人工维护的
b_name、b_i18n、b_default_value与b_options,不物理删除字段或场景配置。
列表配置
dbo.b_module_field_list
控制列表字段列。多级表头由 b_module_field_group 的 list 分组树表达;本表不保存编辑状态。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
雪花 ID 主键 |
b_module_id |
bigint |
所属模块 ID |
b_field_id |
bigint |
关联 b_module_field.b_id |
b_group_id |
bigint |
所属分组 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_module_id外键引用b_module.b_id,b_field_id外键引用b_module_field.b_id,b_group_id引用同模块的b_module_field_group。b_field_id必填;同一字段在同一模块的列表中最多出现一次,使用(b_module_id, b_field_id)唯一约束。b_visible、b_sortable只能为0或1。- 字段列的显示器由关联字段的
b_type与b_options决定,例如money、date、datetime均由前端按统一规则渲染。建议建立(b_module_id, b_group_id, b_xh, b_id)索引。 - 不保存
level、colspan、rowspan;前端加载 Table 分组树和字段列后,按分组的b_parent_id、b_xh组装嵌套表头。隐藏分组的后代不显示;没有可见字段后代的分组不渲染。
示例:
费用(`b_module_field_group`)
|-- 人工费(`b_module_field_list.b_group_id` 指向费用)
`-- 海运费(`b_module_field_list.b_group_id` 指向费用)
编辑配置
dbo.b_module_field_edit
控制字段的通用编辑属性与编辑分组。控件类型、显示规则和类型专属参数统一由 b_module_field.b_type、b_options 决定;FmsForm 与 FmsTable 自行决定何时使用本配置。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
雪花 ID 主键 |
b_module_id |
bigint |
所属模块 ID |
b_field_id |
bigint |
关联 b_module_field.b_id |
b_required |
int |
是否必填,默认 0 |
b_readonly |
int |
是否只读,默认 0 |
b_disabled |
int |
是否禁用,默认 0 |
b_group_id |
bigint |
所属编辑分组 ID;不分组时为空 |
b_xh |
int |
编辑场景中的显示顺序,默认 0 |
约束:
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只能为0或1。b_group_id必须关联同模块的b_module_field_group;分组为空时字段进入默认编辑区域。- 已分组字段按分组的
b_xh排列,组内按b_xh排列;默认区域字段按b_xh排列。
布局分组
dbo.b_module_field_group
统一保存列表多级表头和编辑分组。分组只负责布局,不定义编辑能力;列表或编辑用途由引用它的配置表决定。
被 b_module_field_list 引用时,分组组成同一份 FmsTable 的多级表头;被 b_module_field_edit 引用时,分组组成同一份编辑界面中的业务区块,例如提单、订舱、报关、备注,不代表拆分为多个 Form。
| 字段 | 类型 | 说明 |
|---|---|---|
b_id |
bigint |
雪花 ID 主键 |
b_module_id |
bigint |
所属模块 ID |
b_parent_id |
bigint |
上级分组 ID;顶层为空 |
b_title |
nvarchar(100) |
默认分组标题 |
b_i18n |
varchar(150) |
分组标题多语言键 |
b_xh |
int |
分组显示顺序,默认 0 |
b_canuse |
int |
是否启用,默认 1 |
约束:
b_module_id外键引用b_module.b_id;b_id是分组的稳定关联键。b_parent_id必须引用同模块的分组且不能形成循环。- 多级分组可用于 FmsTable 表头;FmsForm 与 FmsTable 如何消费编辑分组由各自实现决定。
b_canuse只能为0或1。建议建立(b_module_id, b_canuse, b_xh, b_id)索引。- 无字段引用的分组不渲染;分组停用时,其关联字段或列不显示。
视图型选择器的 b_options 示例:
{
"source": "view",
"view": "v_partner",
"valueField": "b_id",
"labelField": "b_name",
"allowInput": false
}
select 使用 allowInput: false 时保存 valueField 的值;设为 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)
|-- 费用 d_charge(data)
|-- 订舱 d_booking(data,独立表和主键时)
`-- 箱明细 d_container(data)
若订舱字段实际保存于海运主单表,不创建 d_booking,而在 d_sea 的编辑配置中用 b_group_id 和 b_xh 定义编辑分组与顺序,分组标题来自 b_module_field_group。主子表关联、加载时机、保存顺序和页面布局均由业务 Vue 页面明确实现。
现有字段迁移
当前 b_module_field 混合保存基础、列表、编辑和查询属性。迁移应分阶段实施:
| 当前字段 | 目标位置 |
|---|---|
b_type |
b_module_field.b_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_xh 与 b_module_field_query.b_xh |
b_canform |
为原 Form 字段创建 b_module_field_edit 记录 |
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_default_value |
迁移步骤:
- 新建 list、edit、group、query 表和必要索引,新增
b_module.b_module_type与b_module_field.b_type的兼容列。 - 为原有字段创建列表配置;根据原
b_canform、b_canquery初始化编辑和查询配置。 - 前端和后端改为读取新场景表,查询不再读取 list 配置;模块类型切换为读取
b_module_type。 - 完成视图同步服务并验证新结构的读写稳定后,删除旧混合列和兼容字段。