# FMS 新系统核心表结构设计 ## 1. 说明 本文档给出 FMS 新系统核心平台表的 SQL Server 建表语句,范围包括元数据中心(模块、实体、字段、关系、页面菜单、视图、表单、多语言)、Schema Compiler、权限中心、技术日志、登录日志与业务审计。 设计原则: - 业务实体(订舱、集装箱、发票等)由 Schema Compiler 根据 `s_module_entity` + `s_module_field` 生成真实物理表,本文档只定义平台核心表。 - 实体是数据和字段的所有者,页面只是实体的一种展示方式;字段挂实体(`s_module_entity`),不挂菜单。 - 页面和菜单合并为一条 `s_module_menu` 记录(导航节点 = 页面入口),用 `b_menu_type` 区分节点性质。 - 元数据变更通过服务层校验后立即生效,DDL 同步执行、失败回滚,不做异步迁移任务表,也不建立配置变更集、版本快照或运行时状态表。 约定如下: - 所有表名以 `s_` 开头,字段名以 `b_` 开头。 - 表名、字段名、索引名和约束名统一使用 `snake_case`。 - 不创建物理外键,关联字段只作为逻辑外键使用。 - 逻辑外键必须创建必要的普通索引或唯一索引。 - 一个租户使用一个独立业务数据库,普通业务表不重复保存 `b_tenant_id` 或 `b_org_id`;集中技术日志和登录日志允许使用 `b_org_id` 标识日志来源。 - 内部主键统一使用 `bigint identity(1, 1)`,跨环境标识使用稳定的 `b_*_key`。 - 同库内的逻辑关联 ID(例如 `b_form_id`)统一使用 `bigint`,不使用 `uniqueidentifier`。 - 时间点统一使用 `datetime2(3)`,应用层按 UTC 写入。 - 稳定业务标识统一使用 `b_*_key`,跨环境导入导出不得依赖内部 `b_id`。 - 扩展内容统一使用 `nvarchar(max)` 普通文本保存,由应用层按业务约定解析和校验,不使用 JSON 字段类型。 - 原布尔语义字段统一使用 `tinyint`,取值约定为 `0`(否)或 `1`(是)。 - 核心业务字段使用真实数据库列,不采用全量 EAV;不设置无业务含义的通用扩展列(如 `b_bz1~n`、`mx_varchar_n`),字段必须有明确的 `b_field_key` 与语义。 - 下面的 `b_*_id`、`b_*_key` 关联均为逻辑外键,由应用服务负责校验一致性。 ## 2. 元数据中心 ### 2.1 模块 模块是业务能力边界,不是数据库表的别名。模块只保存身份、依赖与启用状态,不承载菜单、路由或数据源职责。 ```sql create table dbo.s_module ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_module_key nvarchar(128) not null, -- 模块稳定业务标识(如 ocean、finance、master-data) b_name_key nvarchar(256) not null, -- 模块显示名多语言 key b_description nvarchar(1000) null, -- 模块描述 b_origin nvarchar(32) not null -- 来源:platform 平台内置 / tenant 租户定制 constraint df_s_module_origin default N'platform', b_enabled tinyint not null -- 是否启用(1启用/0停用) constraint df_s_module_enabled default 1, b_sort_no int not null -- 模块排序号 constraint df_s_module_sort_no default 0, b_icon_key nvarchar(128) null, -- 模块图标 key b_config_text nvarchar(max) null, -- 模块扩展配置(应用自定义解析) b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module primary key (b_id), constraint ux_s_module_key unique (b_module_key) ); create index ix_s_module_key on dbo.s_module (b_module_key, b_enabled); ``` ### 2.2 模块依赖 模块依赖必须形成有向无环图,不允许循环依赖。 ```sql create table dbo.s_module_dependency ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_module_key nvarchar(128) not null, -- 依赖方模块 key(如 ocean) b_depends_on_module_key nvarchar(128) not null, -- 被依赖模块 key(如 master-data) b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_dependency_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_dependency primary key (b_id), constraint ux_s_module_dependency_key unique ( b_module_key, b_depends_on_module_key ) ); create index ix_s_module_dependency_depends_on on dbo.s_module_dependency (b_depends_on_module_key); ``` ### 2.3 实体 实体是数据和字段的所有者,映射一张真实物理表。页面、列表、表单都只是实体的展示方式。 ```sql create table dbo.s_module_entity ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_entity_key nvarchar(192) not null, -- 实体稳定业务标识(如 ocean.booking) b_module_key nvarchar(128) not null, -- 所属模块 key b_name_key nvarchar(256) not null, -- 实体显示名多语言 key b_description nvarchar(1000) null, -- 实体描述 b_physical_table sysname not null, -- 真实物理表名(如 ocean_booking) b_delete_policy nvarchar(32) not null -- 删除策略(默认 lifecycle) constraint df_s_module_entity_delete_policy default N'lifecycle', b_origin nvarchar(32) not null -- 来源:platform / tenant constraint df_s_module_entity_origin default N'platform', b_enabled tinyint not null -- 是否启用 constraint df_s_module_entity_enabled default 1, b_config_text nvarchar(max) null, -- 实体扩展配置 b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_entity_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_entity primary key (b_id), constraint ux_s_module_entity_key unique (b_entity_key) ); create index ix_s_module_entity_module_key on dbo.s_module_entity (b_module_key, b_enabled); ``` 删除策略取值(`b_delete_policy`): ```text restrictWhenReferenced 主数据:有引用时拒绝删除,只能停用或合并 lifecycle 业务单据:草稿且无下游时可删,正式后只能取消/作废 cascadeOwned 主表拥有的从数据:随主表同一事务级联删除 hardDelete 临时记录:校验权限后直接物理删除 ``` ### 2.4 字段 字段属于实体,同时携带数据库列定义、UI 行为与业务语义(供 UI 和 AI 理解)。 ```sql create table dbo.s_module_field ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_entity_key nvarchar(192) not null, -- 所属实体 key b_field_key nvarchar(128) not null, -- 字段稳定业务标识(如 carrier_id) b_name_key nvarchar(256) not null, -- 字段显示名多语言 key b_label nvarchar(256) not null, -- 字段标签(可随时改,不改数据库) b_description nvarchar(1000) null, -- 字段描述 b_physical_column_name sysname not null, -- 真实数据库列名(通常与 b_field_key 相同) b_data_type nvarchar(64) not null, -- 存储数据类型(如 varchar/decimal/datetime) b_semantic_type nvarchar(128) null, -- 语义类型(如 email/money/phone,供 UI/AI 理解) b_write_mode nvarchar(32) not null -- 后端写入模式(如 direct/compute/readonly) constraint df_s_module_field_write_mode default N'direct', b_required tinyint not null -- 是否必填 constraint df_s_module_field_required default 0, b_enabled tinyint not null -- 是否启用(停用则隐藏并保留数据) constraint df_s_module_field_enabled default 1, b_queryable tinyint not null -- 是否出现在查询条件中 constraint df_s_module_field_queryable default 0, b_sortable tinyint not null -- 是否可排序 constraint df_s_module_field_sortable default 0, b_list_visible tinyint not null -- 是否显示在固定列表组件 constraint df_s_module_field_list_visible default 1, b_edit_visible tinyint not null -- 是否显示在固定编辑组件 constraint df_s_module_field_edit_visible default 1, b_readonly tinyint not null -- 编辑组件中是否只读 constraint df_s_module_field_readonly default 0, b_sort_no int not null -- 列表/表单默认排序 constraint df_s_module_field_sort_no default 0, b_width int null, -- 列表列宽(px) b_component_type nvarchar(64) null, -- 固定表单组件类型(input/select/date) b_auditable tinyint not null -- 是否记录字段级审计 constraint df_s_module_field_auditable default 0, b_audit_visibility nvarchar(32) null, -- 审计可见性(内部/客户可见) b_sensitive tinyint not null -- 是否敏感字段(涉及脱敏/导出控制) constraint df_s_module_field_sensitive default 0, b_max_length int null, -- 字符串最大长度 b_numeric_precision tinyint null, -- 数值精度(总位数) b_numeric_scale tinyint null, -- 数值小数位 b_temporal_type nvarchar(32) null, -- 时间类型(如 date/datetime) b_unit_key nvarchar(128) null, -- 计量单位 key b_default_value_text nvarchar(max) null, -- 默认值(文本表达) b_aliases_text nvarchar(max) null, -- 字段别名(搜索/AI 理解用) b_validation_text nvarchar(max) null, -- 校验规则(文本表达) b_ai_hints_text nvarchar(max) null, -- 给 AI 理解的提示信息 b_origin nvarchar(32) not null -- 来源:platform / tenant constraint df_s_module_field_origin default N'platform', b_required_by_code tinyint not null -- 是否被代码强依赖 constraint df_s_module_field_required_by_code default 0, b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_field_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_field primary key (b_id), constraint ux_s_module_field_key unique ( b_entity_key, b_field_key ) ); create index ix_s_module_field_entity_key on dbo.s_module_field (b_entity_key, b_enabled, b_sort_no, b_field_key); create index ix_s_module_field_physical_column_name on dbo.s_module_field (b_entity_key, b_physical_column_name); ``` 写入模式取值(`b_write_mode`): ```text direct 可通过 saveobjt 普通保存(如备注、ETD、件数) createOnly 仅创建时允许写入(如来源系统、初始业务类型) readOnly 前端和普通接口只读(如汇总金额、关联展示值) computed 由公式或计算服务生成(如毛利、计费重量) actionOnly 只能通过指定业务动作修改(如审核状态、确认时间) system 仅平台内部维护(如创建人、版本、流水状态) ``` ### 2.5 关系 `b_relation` 描述实体之间的引用与主子关系,通用运行时据此执行外键校验、主子事务、级联删除和子表区域渲染。 ```sql create table dbo.s_module_relation ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_relation_key nvarchar(192) not null, -- 关系稳定业务标识 b_entity_key nvarchar(192) not null, -- 主实体 key b_relation_type nvarchar(32) not null, -- 关系类型:one-to-one/one-to-many/many-to-one/many-to-many b_target_entity_key nvarchar(192) not null, -- 目标实体 key b_ownership nvarchar(32) not null -- 所有权(默认 reference 引用) constraint df_s_module_relation_ownership default N'reference', b_required tinyint not null -- 是否必填 constraint df_s_module_relation_required default 0, b_delete_policy nvarchar(32) null, -- 删除策略:restrict/set-null/cascade/archive b_save_strategy nvarchar(32) null, -- 保存策略:separate 独立保存 / with-parent 随主实体事务保存 b_order_field nvarchar(256) null, -- 子表排序字段表达式 b_unique_constraint tinyint not null -- 是否唯一约束 constraint df_s_module_relation_unique_constraint default 0, b_name_key nvarchar(256) not null, -- 关系显示名多语言 key b_enabled tinyint not null -- 是否启用 constraint df_s_module_relation_enabled default 1, b_config_text nvarchar(max) null, -- 关系扩展配置 b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_relation_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_relation primary key (b_id), constraint ux_s_module_relation_key unique (b_relation_key) ); create index ix_s_module_relation_entity_key on dbo.s_module_relation (b_entity_key, b_enabled); create index ix_s_module_relation_target_entity_key on dbo.s_module_relation (b_target_entity_key); ``` ### 2.6 页面菜单入口 每条菜单记录同时代表一个导航节点和一个页面入口。`directory` 仅表示目录节点,`page` 使用固定 Vue 页面组件,`data_category` 表示数据目录,`data` 表示由通用列表与表单组件维护的数据模块,`external` 表示外链。 ```sql create table dbo.s_module_menu ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_menu_key nvarchar(192) not null, -- 菜单/页面稳定业务标识 b_module_key nvarchar(128) null, -- 所属平台模块 key b_parent_menu_key nvarchar(192) null, -- 父菜单 key(导航树自引用) b_name_key nvarchar(256) not null, -- 菜单显示名多语言 key b_menu_type nvarchar(32) not null, -- 菜单类型:directory/page/data_category/data/external b_route nvarchar(256) null, -- 固定页面或外链路由 b_entity_key nvarchar(192) null, -- data 类型绑定的实体 key b_view_key nvarchar(192) null, -- 绑定的列表视图 key b_form_key nvarchar(192) null, -- 绑定的表单 key b_permission_key nvarchar(192) null, -- 页面访问权限 key b_icon_key nvarchar(128) null, -- 菜单图标 key b_sort_no int not null -- 菜单排序号 constraint df_s_module_menu_sort_no default 0, b_can_menu tinyint not null -- 是否显示在菜单中 constraint df_s_module_menu_can_menu default 1, b_enabled tinyint not null -- 是否启用 constraint df_s_module_menu_enabled default 1, b_config_text nvarchar(max) null, -- 菜单/页面扩展配置 b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_menu_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_menu primary key (b_id), constraint ux_s_module_menu_key unique (b_menu_key) ); create index ix_s_module_menu_module_key on dbo.s_module_menu (b_module_key, b_enabled); create index ix_s_module_menu_parent_key on dbo.s_module_menu (b_parent_menu_key, b_sort_no, b_enabled); create index ix_s_module_menu_route on dbo.s_module_menu (b_route, b_enabled); create index ix_s_module_menu_entity_key on dbo.s_module_menu (b_entity_key, b_enabled); ``` 约束由元数据校验器执行:`directory` 节点不能填写业务表或外链路由;`page` 节点必须填写 `b_route`,并绑定 `b_view_key`/`b_form_key`;`data` 节点必须填写 `b_entity_key` 和 `b_view_key`(列表)、`b_form_key`(表单);`external` 节点必须填写 `b_route` 和 `b_permission_key`。固定页面组件负责布局,表中只保存实体与视图/表单引用和导航配置。目录仅在至少存在一个可访问子页面时显示。 ### 2.7 视图(列表) 视图定义"一个实体的一种列表展示方式",一个实体可以有多个视图。列表字段配置在 `s_module_view_field`。 ```sql create table dbo.s_module_view ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_view_key nvarchar(192) not null, -- 视图稳定业务标识(如 ocean.booking.default-list) b_entity_key nvarchar(192) not null, -- 所属实体 key b_name_key nvarchar(256) not null, -- 视图显示名多语言 key b_queryable tinyint not null -- 是否提供查询条件区 constraint df_s_module_view_queryable default 1, b_exportable tinyint not null -- 是否允许导出 constraint df_s_module_view_exportable default 1, b_page_size int null, -- 默认分页大小 b_config_text nvarchar(max) null, -- 视图扩展配置 b_enabled tinyint not null -- 是否启用 constraint df_s_module_view_enabled default 1, b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_view_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_view primary key (b_id), constraint ux_s_module_view_key unique (b_view_key) ); create index ix_s_module_view_entity_key on dbo.s_module_view (b_entity_key, b_enabled); create table dbo.s_module_view_field ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_view_key nvarchar(192) not null, -- 所属视图 key b_field_key nvarchar(128) not null, -- 引用的字段 key b_sort_no int not null -- 列排序号 constraint df_s_module_view_field_sort_no default 0, b_width int null, -- 列宽(px) b_visible tinyint not null -- 是否显示 constraint df_s_module_view_field_visible default 1, b_frozen tinyint not null -- 是否固定列 constraint df_s_module_view_field_frozen default 0, b_align nvarchar(16) null, -- 对齐方式(left/center/right) b_format_text nvarchar(256) null, -- 显示格式(如日期、千分位) b_queryable tinyint not null -- 是否作为查询条件 constraint df_s_module_view_field_queryable default 0, b_query_operator nvarchar(32) null, -- 查询运算符(eq/contains/gte/...) b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_view_field_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_view_field primary key (b_id), constraint ux_s_module_view_field_key unique ( b_view_key, b_field_key ) ); create index ix_s_module_view_field_view_key on dbo.s_module_view_field (b_view_key, b_sort_no); ``` ### 2.8 表单 表单定义"一个实体的一种编辑展示方式",一个实体可以有多个表单(默认编辑表单、详情表单)。子表区域通过 `s_module_form_relation` 引用关系并绑定子表视图/表单。 ```sql create table dbo.s_module_form ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_form_key nvarchar(192) not null, -- 表单稳定业务标识(如 ocean.booking.default-form) b_entity_key nvarchar(192) not null, -- 所属实体 key b_name_key nvarchar(256) not null, -- 表单显示名多语言 key b_form_type nvarchar(32) not null -- 表单类型(默认 default) constraint df_s_module_form_form_type default N'default', b_config_text nvarchar(max) null, -- 表单扩展配置(控件特有属性与布局 JSON) b_enabled tinyint not null -- 是否启用 constraint df_s_module_form_enabled default 1, b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_form_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_form primary key (b_id), constraint ux_s_module_form_key unique (b_form_key) ); create index ix_s_module_form_entity_key on dbo.s_module_form (b_entity_key, b_enabled); create table dbo.s_module_form_field ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_form_key nvarchar(192) not null, -- 所属表单 key b_field_key nvarchar(128) not null, -- 引用的字段 key b_group_key nvarchar(128) null, -- 所属分组 key(逻辑分组) b_sort_no int not null -- 表单内排序号 constraint df_s_module_form_field_sort_no default 0, b_required tinyint not null -- 是否必填(覆盖字段默认) constraint df_s_module_form_field_required default 0, b_readonly tinyint not null -- 是否只读(覆盖字段默认) constraint df_s_module_form_field_readonly default 0, b_visible tinyint not null -- 是否显示 constraint df_s_module_form_field_visible default 1, b_span int null, -- 布局占宽(栅格) b_component_type nvarchar(64) null, -- 控件类型(覆盖字段默认) b_config_text nvarchar(max) null, -- 控件扩展配置 b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_form_field_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_form_field primary key (b_id), constraint ux_s_module_form_field_key unique ( b_form_key, b_field_key ) ); create index ix_s_module_form_field_form_key on dbo.s_module_form_field (b_form_key, b_sort_no); create table dbo.s_module_form_relation ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_form_key nvarchar(192) not null, -- 所属表单 key b_relation_key nvarchar(192) not null, -- 引用的主子关系 key b_child_view_key nvarchar(192) null, -- 子表列表配置 key b_child_form_key nvarchar(192) null, -- 子表编辑配置 key(可选) b_display_mode nvarchar(16) not null -- 子表显示模式(默认 table) constraint df_s_module_form_relation_display_mode default N'table', b_editable tinyint not null -- 是否可编辑 constraint df_s_module_form_relation_editable default 1, b_allow_add tinyint not null -- 是否允许新增行 constraint df_s_module_form_relation_allow_add default 1, b_allow_delete tinyint not null -- 是否允许删除行 constraint df_s_module_form_relation_allow_delete default 1, b_allow_sort tinyint not null -- 是否允许排序行 constraint df_s_module_form_relation_allow_sort default 1, b_sort_no int not null -- 子表区域排序号 constraint df_s_module_form_relation_sort_no default 0, b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_form_relation_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_form_relation primary key (b_id), constraint ux_s_module_form_relation_key unique ( b_form_key, b_relation_key ) ); create index ix_s_module_form_relation_form_key on dbo.s_module_form_relation (b_form_key, b_sort_no); ``` ### 2.9 多语言 多语言是元数据运行时的一部分,统一解析模块、菜单、实体、字段、动作和主数据的显示名称。 ```sql create table dbo.s_module_i18n ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_resource_key nvarchar(256) not null, -- 多语言资源 key(如 nameKey) b_locale nvarchar(32) not null, -- 语言区域(如 zh-CN/en-US) b_resource_value nvarchar(max) not null, -- 该语言下的显示文本 b_source_type nvarchar(32) not null -- 来源类型(默认 manual 人工 / ai AI 生成) constraint df_s_module_i18n_source_type default N'manual', b_resource_status nvarchar(32) not null -- 资源状态(默认 confirmed 已确认) constraint df_s_module_i18n_resource_status default N'confirmed', b_model_key nvarchar(128) null, -- 生成翻译的 AI 模型标识(追溯用) b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_module_i18n_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_module_i18n primary key (b_id), constraint ux_s_module_i18n_key_locale unique ( b_resource_key, b_locale ) ); create index ix_s_module_i18n_resource_key on dbo.s_module_i18n (b_resource_key, b_locale); ``` ## 3. Schema Compiler 元数据变更通过服务层校验后立即生效。Schema Compiler 根据 `s_module_entity` 的物理表配置和 `s_module_field` 的物理字段配置生成所需的 `CREATE TABLE`、`ALTER TABLE`、索引和约束语句,并由应用服务直接执行;执行成功后提交元数据变更,失败则回滚本次操作并返回错误。 执行机制: - DDL 同步执行,单租户库内加锁,同一时间只允许一个结构变更任务;其他租户不受影响。 - 每个变更步骤记录开始时间、结束时间、checksum 和执行结果;重启或网络中断后可以从最后一个已确认步骤继续执行。 - DDL、数据转换和结构校验全部成功后,才提交元数据变更;提交失败保持原结构,进入可修复状态。 - 变更审计统一写入现有审计日志;本阶段不建立配置变更集、版本快照或迁移任务表,如果未来需要异步执行、失败重试、断点恢复或版本回滚,再增加专用任务表。 - 破坏性变更(删除字段、缩短长度、改变类型)采用 expand-contract:先新增兼容结构、双写或分批迁移数据、校验新旧数据、停止写入旧结构、经过保留期后归档或删除旧结构。 ## 4. 统一权限中心 ### 4.1 角色与用户角色关系 ```sql create table dbo.s_auth_role ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_role_key nvarchar(128) not null, -- 角色稳定业务标识 b_role_name nvarchar(256) not null, -- 角色名称 b_description nvarchar(1000) null, -- 角色描述 b_role_type nvarchar(32) not null -- 角色类型(默认 custom 自定义) constraint df_s_auth_role_role_type default N'custom', b_enabled tinyint not null -- 是否启用 constraint df_s_auth_role_enabled default 1, b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_auth_role_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 b_updated_at datetime2(3) null, -- 更新时间 b_updated_by nvarchar(128) null, -- 更新人 constraint pk_s_auth_role primary key (b_id), constraint ux_s_auth_role_key unique (b_role_key) ); create table dbo.s_auth_user_role ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_user_key nvarchar(128) not null, -- 用户稳定 key b_role_key nvarchar(128) not null, -- 角色 key b_enabled tinyint not null -- 是否启用(该用户角色关系) constraint df_s_auth_user_role_enabled default 1, b_effective_from datetime2(3) null, -- 生效开始时间(可定时) b_effective_to datetime2(3) null, -- 生效结束时间(可定时) b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_auth_user_role_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_auth_user_role primary key (b_id), constraint ux_s_auth_user_role_key unique (b_user_key, b_role_key) ); create index ix_s_auth_user_role_role_key on dbo.s_auth_user_role (b_role_key, b_enabled); ``` ### 4.2 功能权限 首期只做 RBAC 功能授权(页面、实体、动作、字段)。数据范围策略(`auth_data_policy`)和字段查看/导出/脱敏策略(`auth_field_policy`)作为后续扩展,不在本版本建表。 ```sql create table dbo.s_auth_permission ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_permission_key nvarchar(192) not null, -- 权限稳定业务标识 b_module_key nvarchar(128) null, -- 所属模块 key b_resource_type nvarchar(32) not null, -- 资源类型(如 menu/entity/field/action) b_resource_key nvarchar(256) not null, -- 资源稳定 key(被授权的对象) b_action_type nvarchar(64) null, -- 操作类型(如 view/create/update/delete/confirm) b_name_key nvarchar(256) not null, -- 权限显示名多语言 key b_description nvarchar(1000) null, -- 权限描述 b_enabled tinyint not null -- 是否启用 constraint df_s_auth_permission_enabled default 1, b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_auth_permission_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_auth_permission primary key (b_id), constraint ux_s_auth_permission_key unique (b_permission_key) ); create table dbo.s_auth_role_permission ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_role_key nvarchar(128) not null, -- 角色 key b_permission_key nvarchar(192) not null, -- 权限 key b_permission_effect nvarchar(16) not null -- 权限效果(默认 allow 允许) constraint df_s_auth_role_permission_effect default N'allow', b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_auth_role_permission_created_at default sysutcdatetime(), b_created_by nvarchar(128) not null, -- 创建人 constraint pk_s_auth_role_permission primary key (b_id), constraint ux_s_auth_role_permission_key unique ( b_role_key, b_permission_key ) ); create index ix_s_auth_permission_resource_key on dbo.s_auth_permission (b_resource_type, b_resource_key, b_enabled); create index ix_s_auth_role_permission_permission_key on dbo.s_auth_role_permission (b_permission_key, b_permission_effect); ``` 菜单显示继承页面访问权限:用户拥有 `s_module_menu.b_permission_key` 对应权限时菜单才显示;目录菜单在无可访问子页面时自动隐藏。前端只控制显示,后端通用数据运行时和动作引擎必须再次检查同一个权限 key。 ## 5. 日志与审计 ### 5.1 技术日志 技术日志主要用于请求链路、SQL、异常、性能和外部接口排查,推荐写入 Loki、OpenSearch、Elasticsearch 等日志平台。下面的表适合集中日志库或短期数据库兜底,不建议把所有高频技术日志长期写入租户业务库。 ```sql create table dbo.s_log_technical ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_occurred_at datetime2(3) not null -- 发生时间(UTC) constraint df_s_log_technical_occurred_at default sysutcdatetime(), b_log_level nvarchar(16) not null, -- 日志级别(如 INFO/WARN/ERROR) b_log_category nvarchar(64) not null, -- 日志分类(如 sql/exception/performance) b_operation nvarchar(192) not null, -- 操作名(如 loadData/saveObject) b_org_id nvarchar(128) null, -- 租户/组织 ID(日志来源标识) b_user_key nvarchar(128) null, -- 操作用户 key b_source_type nvarchar(32) null, -- 来源类型(如 web/api) b_module_key nvarchar(128) null, -- 相关模块 key b_operation_key nvarchar(192) null, -- 相关操作 key(如 saveObject.submit) b_request_id nvarchar(128) null, -- 请求 ID b_trace_id nvarchar(128) null, -- 追踪 ID(串联链路) b_application_version nvarchar(128) null, -- 应用版本 b_server_node nvarchar(128) null, -- 服务节点标识 b_duration_ms bigint null, -- 耗时(毫秒) b_result_code nvarchar(128) null, -- 结果码 b_error_code nvarchar(128) null, -- 错误码 b_error_message nvarchar(2000) null, -- 错误信息 b_exception_text nvarchar(max) null, -- 异常堆栈(文本) b_context_text nvarchar(max) null, -- 上下文信息(文本) constraint pk_s_log_technical primary key (b_id) ); create index ix_s_log_technical_trace_id on dbo.s_log_technical (b_trace_id, b_occurred_at desc); create index ix_s_log_technical_org_time on dbo.s_log_technical (b_org_id, b_occurred_at desc); create index ix_s_log_technical_level_time on dbo.s_log_technical (b_log_level, b_occurred_at desc); ``` ### 5.2 登录日志 登录日志记录登录成功、失败、退出、刷新令牌和账号锁定等安全事件。它可以与技术日志使用相同的 `b_request_id`、`b_trace_id` 关联,但业务职责独立。 ```sql create table dbo.s_log_login ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_org_id nvarchar(128) null, -- 租户/组织 ID b_user_key nvarchar(128) null, -- 用户 key b_login_name nvarchar(256) null, -- 登录名 b_login_type nvarchar(32) not null, -- 登录类型(如 password/token) b_login_status nvarchar(32) not null, -- 登录状态(如 success/failed) b_auth_method nvarchar(32) null, -- 认证方式(如 ldap/oidc) b_failure_reason nvarchar(512) null, -- 失败原因 b_ip_address varchar(64) null, -- 登录 IP b_user_agent nvarchar(1000) null, -- 客户端 UA b_device_key nvarchar(256) null, -- 设备标识 b_request_id nvarchar(128) null, -- 请求 ID b_trace_id nvarchar(128) null, -- 追踪 ID b_occurred_at datetime2(3) not null -- 发生时间(UTC) constraint df_s_log_login_occurred_at default sysutcdatetime(), b_created_at datetime2(3) not null -- 创建时间(UTC) constraint df_s_log_login_created_at default sysutcdatetime(), constraint pk_s_log_login primary key (b_id) ); create index ix_s_log_login_user_time on dbo.s_log_login (b_user_key, b_occurred_at desc); create index ix_s_log_login_name_time on dbo.s_log_login (b_login_name, b_occurred_at desc); create index ix_s_log_login_status_time on dbo.s_log_login (b_login_status, b_occurred_at desc); create index ix_s_log_login_trace_id on dbo.s_log_login (b_trace_id, b_occurred_at desc); ``` ### 5.3 业务审计事件与字段变更 ```sql create table dbo.s_log_audit ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_event_key nvarchar(192) not null, -- 业务事件稳定标识 b_module_key nvarchar(128) not null, -- 被审计的数据模块 key b_entity_id nvarchar(128) not null, -- 被审计的业务数据 ID b_business_no nvarchar(192) null, -- 业务单号(如订舱号) b_operation_key nvarchar(192) null, -- 触发的操作 key(如 saveObject.submit) b_operator_key nvarchar(128) not null, -- 操作人 key b_operator_name nvarchar(256) null, -- 操作人名称(快照) b_source_type nvarchar(32) not null, -- 来源类型(如 user/ai/api) b_visibility nvarchar(32) not null, -- 可见性(内部/客户可见) b_request_id nvarchar(128) null, -- 请求 ID b_trace_id nvarchar(128) not null, -- 追踪 ID(关联技术日志) b_business_event_id bigint null, -- 关联的业务事件 ID b_payload_text nvarchar(max) null, -- 事件载荷(文本,如前后快照) b_occurred_at datetime2(3) not null -- 发生时间(UTC) constraint df_s_log_audit_occurred_at default sysutcdatetime(), constraint pk_s_log_audit primary key (b_id) ); create table dbo.s_log_audit_field ( b_id bigint identity(1, 1) not null, -- 内部自增主键 b_event_id bigint not null, -- 所属审计事件 ID b_module_key nvarchar(128) not null, -- 数据模块 key b_entity_id nvarchar(128) not null, -- 业务数据 ID b_field_key nvarchar(128) not null, -- 变更的字段 key b_field_label_snapshot nvarchar(256) null, -- 字段标签快照 b_before_value_text nvarchar(max) null, -- 变更前原始值 b_after_value_text nvarchar(max) null, -- 变更后原始值 b_before_display_value nvarchar(1000) null, -- 变更前显示值(如引用字段 label) b_after_display_value nvarchar(1000) null, -- 变更后显示值 b_visibility nvarchar(32) not null, -- 可见性(内部/客户可见) constraint pk_s_log_audit_field primary key (b_id) ); create index ix_s_log_audit_module on dbo.s_log_audit (b_module_key, b_entity_id, b_occurred_at desc); create index ix_s_log_audit_trace_id on dbo.s_log_audit (b_trace_id); create index ix_s_log_audit_field_audit_event_id on dbo.s_log_audit_field (b_event_id); ``` ## 6. 逻辑外键清单 以下关联不创建物理外键,由服务层、变更校验器和 Schema Compiler 负责检查: | 表 | 字段 | 逻辑目标 | | --- | --- | --- | | `s_module_dependency` | `b_module_key` | `s_module.b_module_key` | | `s_module_dependency` | `b_depends_on_module_key` | `s_module.b_module_key` | | `s_module_entity` | `b_module_key` | `s_module.b_module_key` | | `s_module_field` | `b_entity_key` | `s_module_entity.b_entity_key` | | `s_module_relation` | `b_entity_key` | `s_module_entity.b_entity_key` | | `s_module_relation` | `b_target_entity_key` | `s_module_entity.b_entity_key` | | `s_module_menu` | `b_module_key` | `s_module.b_module_key` | | `s_module_menu` | `b_parent_menu_key` | `s_module_menu.b_menu_key` | | `s_module_menu` | `b_entity_key` | `s_module_entity.b_entity_key` | | `s_module_menu` | `b_view_key` | `s_module_view.b_view_key` | | `s_module_menu` | `b_form_key` | `s_module_form.b_form_key` | | `s_module_menu` | `b_permission_key` | `s_auth_permission.b_permission_key` | | `s_module_view` | `b_entity_key` | `s_module_entity.b_entity_key` | | `s_module_view_field` | `b_view_key` | `s_module_view.b_view_key` | | `s_module_view_field` | `b_field_key` | 实体范围内的 `s_module_field.b_field_key` | | `s_module_form` | `b_entity_key` | `s_module_entity.b_entity_key` | | `s_module_form_field` | `b_form_key` | `s_module_form.b_form_key` | | `s_module_form_field` | `b_field_key` | 实体范围内的 `s_module_field.b_field_key` | | `s_module_form_relation` | `b_form_key` | `s_module_form.b_form_key` | | `s_module_form_relation` | `b_relation_key` | `s_module_relation.b_relation_key` | | `s_module_form_relation` | `b_child_view_key` | `s_module_view.b_view_key` | | `s_module_form_relation` | `b_child_form_key` | `s_module_form.b_form_key` | | `s_auth_user_role` | `b_role_key` | `s_auth_role.b_role_key` | | `s_auth_role_permission` | `b_permission_key` | `s_auth_permission.b_permission_key` | | `s_log_audit_field` | `b_event_id` | `s_log_audit.b_id` | | `s_log_technical` | `b_user_key` | 当前身份系统的用户 `b_user_key` | | `s_log_login` | `b_user_key` | 当前身份系统的用户 `b_user_key` | 逻辑外键写入时应执行以下校验: ```text 稳定 key 是否存在 -> 目标资源是否启用 -> 跨模块引用是否合法(依赖图中可达) -> 字段、实体类型和视图/表单配置是否匹配 -> 删除或停用前是否仍被其他资源引用 ``` ## 7. 实施建议 建议按以下顺序创建和启用这些表: ```text 元数据基础表(模块/依赖/实体/字段/关系) -> 视图与表单表 -> 页面菜单入口表 -> 多语言表 -> 权限表 -> 日志与审计表 ``` 正式执行前还应补充: - 根据实际 SQL Server 2022 环境确认过滤索引和 `datetime2` 支持情况。 - 根据现有用户表确定 `b_user_key`、`b_created_by` 和 `b_updated_by` 的实际数据类型。 - 根据最终稳定 key 长度评估唯一索引的键长度。 - 为高数据量审计表制定归档及清理策略。 - 用独立测试数据库执行完整建表脚本,并验证重复安装和 Schema 迁移流程。 - 选择一条真实业务纵向验证(例如"基础资料 + 海运订舱 + 确认动作"),验证售后新增字段、Schema Compiler 加列、生成列表/表单和 DDL 失败回滚的完整链路。