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

16 KiB
Raw Blame History

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 的模块执行:

  1. 后端校验视图名并读取列名、SQL 类型和可空性等结构信息。
  2. 按列名查找同模块的 b_module_field;新列创建字段基础记录。
  3. 同步更新 b_field、b_field_type 和 b_canuse。SQL 类型映射为 string、text、number、date、datetime、boolean 等基础类型;select_id、select_input 由管理员在同步后按业务语义调整。
  4. 本次视图中不存在的已有字段保留其记录和全部场景配置,但将 b_canuse 置为 0。
  5. 不覆盖人工维护的 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) 唯一。

权限规则:

  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: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

迁移步骤:

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