Files
workspace/code/fms/新数据库结构.md
T
2026-07-27 22:51:41 +08:00

16 KiB
Raw Blame History

FMS 新数据库结构

设计原则

  • s_module 是核心元数据对象,统一表示菜单目录、页面和数据模块。
  • 字段来源于数据模块配置的查询视图。系统不创建业务字段,只同步视图字段,并维护其展示、编辑、查询和权限配置。
  • 页面和业务逻辑不完全元数据化。海运等复杂业务页面由 Vue 页面显式组合多个数据模块,元数据只提供 Table、Form 和 Query 配置。
  • 字段基础定义、列表、编辑、查询四个职责分离;一个字段可以只参与其中任一场景。
  • 编辑规则与列表布局解耦:s_module_field_edit 是通用编辑配置,FmsForm 和 FmsTable 可按自身规则消费;s_module_field_list 只描述列表展示,不保存编辑状态。
  • 模块权限控制访问,操作权限控制按钮动作;操作权限必须依赖模块访问权限。
  • 模块元数据表沿用旧系统的 s_module* 命名;基础资料和用户授权表使用 b_,字段名继续使用 b_。全部 b_id 使用 bigint 雪花 ID,返回前端时序列化为字符串。
  • 布尔字段统一使用 int,1 表示是、0 表示否;b_xh 数值越小越靠前。
  • 当前按机构使用独立数据库,表中不保存机构编号。表名、视图名和字段名必须由后端白名单校验,不能直接拼接 SQL。

整体关系

s_module
  |-- parent_id --> s_module
  |-- 1:N --------> s_module_field
  |-- 1:N --------> s_module_field_group -- parent_id --> s_module_field_group
  |-- 1:N --------> s_module_power ---- 1:N ----> b_user_power
  `-- 1:N --------> b_user_module

s_module_field
  |-- 0:N --------> s_module_field_list -- group_id --> s_module_field_group
  |-- 0:1 --------> s_module_field_edit -- group_id --> s_module_field_group
  `-- 0:1 --------> s_module_field_query

s_module / s_module_field / s_module_field_list / s_module_field_group / s_module_power
  `-- b_i18n --> b_i18n.b_key

模块

dbo.s_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 外键引用 s_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.s_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 外键引用 s_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 的模块执行:

  1. 后端校验视图名并读取列名、SQL 类型和可空性等结构信息。
  2. 按列名查找同模块的 s_module_field;新列创建字段基础记录。
  3. 新字段按 SQL 类型初始化 b_type,例如字符串映射为 input、长文本映射为 textarea、数值映射为 number、日期映射为 date 或 datetime、位值映射为 switch。已有字段不覆盖管理员维护的 b_type 与 b_options;select、money 等业务类型由管理员按语义调整。
  4. 本次视图中不存在的已有字段保留其记录和全部场景配置,但将 b_canuse 置为 0。
  5. 不覆盖人工维护的 b_name、b_i18n、b_default_value 与 b_options,不物理删除字段或场景配置。

列表配置

dbo.s_module_field_list

控制列表字段列。多级表头由 s_module_field_group 的 list 分组树表达;本表不保存编辑状态。

字段 类型 说明
b_id bigint 雪花 ID 主键
b_module_id bigint 所属模块 ID
b_field_id bigint 关联 s_module_field.b_id
b_group_id bigint 所属分组 ID;为空时为顶层列
b_i18n varchar(150) 字段标题多语言键覆盖值
b_visible int 是否显示,默认 1
b_xh int 同一分组内的显示顺序,默认 0
b_width int 字段列宽

约束:

  • b_module_id 外键引用 s_module.b_id,b_field_id 外键引用 s_module_field.b_id,b_group_id 引用同模块的 s_module_field_group。
  • b_field_id 必填;同一字段在同一模块的列表中最多出现一次,使用 (b_module_id, b_field_id) 唯一约束。
  • b_visible 只能为 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 组装嵌套表头。隐藏分组的后代不显示;没有可见字段后代的分组不渲染。

示例:

费用(`s_module_field_group`)
|-- 人工费(`s_module_field_list.b_group_id` 指向费用)
`-- 海运费(`s_module_field_list.b_group_id` 指向费用)

编辑配置

dbo.s_module_field_edit

控制字段的通用编辑属性与编辑分组。控件类型、显示规则和类型专属参数统一由 s_module_field.b_type、b_options 决定;FmsForm 与 FmsTable 自行决定何时使用本配置。

字段 类型 说明
b_id bigint 雪花 ID 主键
b_module_id bigint 所属模块 ID
b_field_id bigint 关联 s_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 外键引用 s_module.b_id,b_field_id 外键引用 s_module_field.b_id;(b_module_id, b_field_id) 唯一,保存服务校验字段属于同一模块。
  • b_required、b_readonly、b_disabled 只能为 0 或 1。
  • b_group_id 必须关联同模块的 s_module_field_group;分组为空时字段进入默认编辑区域。
  • 已分组字段按分组的 b_xh 排列,组内按 b_xh 排列;默认区域字段按 b_xh 排列。

布局分组

dbo.s_module_field_group

统一保存列表多级表头和编辑分组。分组只负责布局,不定义编辑能力;列表或编辑用途由引用它的配置表决定。

被 s_module_field_list 引用时,分组组成同一份 FmsTable 的多级表头;被 s_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 外键引用 s_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.s_module_field_query

独立控制主列表查询条件,不依赖字段是否配置为可见列表列。

字段 类型 说明
b_id bigint 雪花 ID 主键
b_module_id bigint 所属模块 ID
b_field_id bigint 关联 s_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 外键引用 s_module.b_id,b_field_id 外键引用 s_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.s_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 外键引用 s_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 外键引用 s_module.b_id,(b_user_id, b_module_id) 唯一。目录不单独授权;用户拥有下级模块时自动显示上级目录。

dbo.b_user_power

控制用户可执行的按钮操作。

字段 类型 说明
b_id bigint 雪花 ID 主键
b_user_id bigint 用户雪花 ID
b_module_id bigint 所属模块 ID
b_power_id bigint s_module_power.b_id
b_inputuser_id bigint 授权人雪花 ID
b_inputdatetime datetime 授权时间

逻辑关联:b_module_id 对应 s_module.b_id,b_power_id 对应 s_module_power.b_id;(b_user_id, b_power_id) 唯一。建议建立 (b_module_id, b_user_id) 索引。

权限规则:

  1. 用户必须拥有 b_user_module 记录,才能进入或调用该模块。
  2. 用户必须同时拥有模块权限和对应 b_user_power 记录,才能执行按钮动作。
  3. 前端据此控制路由进入和按钮可用性;后端接口后续实施同等权限校验。

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 定义编辑分组与顺序,分组标题来自 s_module_field_group。主子表关联、加载时机、保存顺序和页面布局均由业务 Vue 页面明确实现。

现有字段迁移

当前 s_module_field 混合保存基础、列表、编辑和查询属性。迁移应分阶段实施:

当前字段 目标位置
b_type s_module_field.b_type
b_canlist s_module_field_list.b_visible
b_width s_module_field_list.b_width
b_xh 初始化 s_module_field_list.b_xh、s_module_field_edit.b_xh 与 s_module_field_query.b_xh
b_canform 为原 Form 字段创建 s_module_field_edit 记录
b_must s_module_field_edit.b_required
b_readonly s_module_field_edit.b_readonly
b_canquery 创建 s_module_field_query 记录
b_value 迁移为 s_module_field.b_default_value

迁移步骤:

  1. 新建 list、edit、group、query 表和必要索引,新增 s_module.b_module_type 与 s_module_field.b_type 的兼容列。
  2. 为原有字段创建列表配置;根据原 b_canform、b_canquery 初始化编辑和查询配置。
  3. 前端和后端改为读取新场景表,查询不再读取 list 配置;模块类型切换为读取 b_module_type。
  4. 完成视图同步服务并验证新结构的读写稳定后,删除旧混合列和兼容字段。