35 KiB
title, description
| title | description |
|---|---|
| 数据表结构 | 核心元数据表、组织与权限表、日志表、工作流表的完整字段说明 |
数据表结构
本文记录 G3ERP 库的结构与约定,字段以真库为准。
按前缀分四类,本文只写系统级表(业务表详见各自业务域):
| 前缀 | 类别 | 本文是否覆盖 |
|---|---|---|
s_ |
系统 / 元数据 / 权限 / 日志 | ✅ 全部 20 张 |
wf_ |
工作流 | ✅ 全部 13 张 |
bf_ |
文件附件 | ✅ 2 张 |
b_ |
业务与主数据 | 只写组织用户等基础表;业务字典表不写 |
v_ |
视图 | 查询入口,见文末 |
1. 命名与字段约定
1.1 表名
- 统一小写
snake_case,下划线分词。 - 系统表
s_;业务与主数据b_;业务域表用明确的域前缀(如bf_files);工作流wf_(属业务域前缀,不用s_)。 - 表名表达稳定的业务含义,不用页面名或路由名当表名。
1.2 字段命名
| 用途 | 约定 |
|---|---|
| 主键 | 业务编码主键 b_id;关系表用联合主键 |
| 关联 | <对象>_id,如 b_module_id、b_dept_id |
| 排序 | b_xh,默认 0 |
| 启用 | b_canuse,0/1,默认 1 |
| 备注 | b_bz |
| 名称 | b_name |
| 多语言 | b_i18n(指向 s_i18n.b_key) |
| 主表字段 | b_ 前缀 |
| 明细 / 子表字段 | mx_ 前缀 |
1.3 类型选择
| 用途 | 类型 |
|---|---|
| 名称、备注、多语言文本 | nvarchar |
| 编码、状态、类型、SQL 标识 | varchar |
| 日期时间 | datetime2 |
| 启用、顺序标记 | tinyint(0/1) |
| 数量、金额 | 按业务精度设 precision / scale |
1.4 审计字段
| 字段 | 含义 |
|---|---|
b_created_by / b_created_at |
创建人(用户编码)/ 创建时间 |
b_updated_by / b_updated_at |
最后修改人 / 最后修改时间 |
不建触发器,由写入方维护(通用保存在服务端统一填,前端不能指定)。
审计字段不是所有表都必须有:客户维护、需追溯变更的业务表才需要;系统内部关联表、字典表可省略。授权类表例外——s_user_power / s_user_field_power / s_user_data_power 由用户在授权界面操作,需追溯授权变更人,因此保留审计字段。s_power 是开发期维护的系统元数据,不设审计字段。
这些字段只表示系统层面的创建/修改信息,不替代业务字段里的录入人、审核人、负责人。
1.5 约束
- 不依赖数据库外键、
CHECK约束和触发器保证业务规则,合法性由业务层校验。 - 状态、类型、动作的取值写在列注释里,不用
CHECK枚举——加值不需要改表。 - 关联完整性与删除规则由业务层处理,删除策略见
s_relation.b_on_delete与s_delete_rule。
2. 键与 ID 策略
| 场景 | 策略 | 示例 |
|---|---|---|
| 配置表(模块、菜单、权限、流程定义) | varchar 业务编码主键(人可读、跨环境稳定) |
s_module.b_id、wf_definition.b_id |
| 业务数据 | 应用层生成的 bigint 雪花 ID | bf_files.subid、业务表 b_id |
| 工作流运行对象 | UUIDv7(uniqueidentifier,按时间有序) |
wf_instance.b_id、wf_task.b_id |
| 日志 | UUIDv7 | s_log_audit.b_id |
跨表引用业务主键时统一按字符串保存(如 wf_instance.b_business_id、s_log_audit.b_data_id),不依赖业务表物理主键类型——业务表可能是 bigint,老表可能是 varchar。
3. 模块元数据
系统以「模块」为配置单元,五张表配合完成查询与界面配置。
3.1 s_module — 模块定义
| 列 | 类型 | 说明 |
|---|---|---|
b_id |
varchar(50) PK |
模块编码 |
b_parent_id |
varchar(50) |
父模块,NULL 为根 |
b_depth |
int 默认 0 |
树层级,根为 0 |
b_path |
varchar(1000) |
根到当前节点路径,如 /sea/container/ |
b_name |
nvarchar(200) |
模块名称 |
b_i18n |
varchar(150) |
多语言资源键 |
b_module_type |
varchar(20) |
module / data / virtual |
b_view_table |
varchar(128) |
默认查询表或视图 |
b_save_table |
varchar(128) |
默认保存目标表 |
b_key_field |
varchar(50) |
主键字段 |
b_scope_field |
varchar(50) |
数据范围判定字段(记录归属人字段) |
b_order_sql |
varchar(500) |
默认排序 SQL |
b_query_sql |
nvarchar(max) |
可选查询 SQL 或模板 |
b_config_json |
nvarchar(max) |
低频扩展配置 |
b_canuse |
tinyint 默认 1 |
是否启用 |
b_xh |
int 默认 0 |
同级显示顺序 |
b_bz |
nvarchar(2000) |
备注 |
索引:ix_s_module_parent(b_parent_id, b_canuse, b_depth, b_xh, b_id)、ix_s_module_path(b_path, b_canuse, b_id)、ix_s_module_type(b_module_type, b_canuse, b_xh, b_id)、ix_s_module_view_table、ix_s_module_save_table。
模块类型:
| 取值 | 含义 |
|---|---|
module |
业务分组(海运、财务…),默认不配字段与表 |
data |
具体数据对象,必须配 b_view_table 或 b_query_sql |
virtual |
不适合标准表表达的能力,由 SQL 或业务处理器实现 |
b_scope_field是数据范围权限的唯一判定依据,配在模块上而非授权行上:同一模块的所有用户必须用同一字段判范围(如b_inputuser_id)。
3.2 s_field — 模块字段
| 列 | 类型 | 说明 |
|---|---|---|
b_module_id |
varchar(50) PK |
所属模块 |
b_field |
varchar(50) PK |
字段编码 / 查询别名 |
b_name |
nvarchar(200) |
字段名称 |
b_i18n |
varchar(150) |
多语言资源键 |
b_type |
varchar(30) |
业务类型 |
b_canuse |
tinyint 默认 1 |
是否启用 |
b_xh |
int 默认 0 |
默认顺序 |
主键 (b_module_id, b_field);索引 ix_s_field_module_order(b_module_id, b_canuse, b_xh, b_field)。
s_field不保存数据库类型、长度、精度——这些由后端在运行时直接读表/视图结构(MetadataReader)。字段同步按来源结构对齐,但不覆盖人工维护的名称与业务类型。b_type的取值集合由业务层维护,本设计不做固定枚举。
3.3 s_module_schema — 界面配置
列表 / 表单 / 查询配置统一存 JSON,不再各建一张表。
| 列 | 类型 | 说明 |
|---|---|---|
b_module_id |
varchar(50) PK |
模块编码 |
b_schema_type |
varchar(20) PK |
view / edit / query |
b_schema_json |
nvarchar(max) |
完整 JSON 配置 |
b_canuse |
tinyint 默认 1 |
是否启用 |
b_updated_by |
varchar(50) |
最后修改人 |
b_updated_at |
datetime2 |
最后修改时间 |
主键 (b_module_id, b_schema_type)。JSON 顶层含 schemaVersion 便于结构升级。
3.4 s_relation — 模块关系
| 列 | 类型 | 说明 |
|---|---|---|
b_source_module_id |
varchar(50) PK |
源模块 |
b_source_field |
varchar(50) PK |
源字段 |
b_target_module_id |
varchar(50) PK |
目标模块 |
b_target_field |
varchar(50) PK |
目标字段 |
b_relation_type |
varchar(20) |
one_to_one / one_to_many / many_to_one |
b_on_delete |
varchar(20) 默认 restrict |
删除策略:restrict / cascade / set_null |
b_canuse / b_xh |
— | 启用 / 顺序 |
索引:ix_s_relation_source、ix_s_relation_target。
3.5 s_autocode — 自动编码
| 列 | 类型 | 默认 | 说明 |
|---|---|---|---|
b_module_id |
varchar(50) PK |
— | 模块编码 |
b_field |
varchar(50) PK |
— | 字段编码 |
b_prefix |
nvarchar(200) |
'' |
前缀 |
b_dateformat |
varchar(30) |
yyyyMM |
日期段格式 |
b_separator |
nvarchar(20) |
- |
分隔符 |
b_seqwidth |
int |
5 | 流水号位数 |
b_resettype |
varchar(10) |
month |
重置周期 |
b_startvalue |
bigint |
1 | 起始值 |
b_currentperiod |
varchar(20) |
— | 当前周期 |
b_currentvalue |
bigint |
0 | 当前值 |
b_canuse |
tinyint |
1 | 是否启用 |
3.6 s_menu / s_menu_module
菜单树与模块挂载关系。
s_menu:b_id(PK) / b_parent_id / b_depth / b_path / b_name / b_i18n / b_menu_type / b_route(路由) / b_icon / b_xh / b_canuse。
s_menu_module:b_menu_id + b_module_id(联合 PK) / b_xh / b_canuse——把菜单挂到一个或多个模块上。
索引:ix_s_menu_parent、ix_s_menu_path、ix_s_menu_route、ix_s_menu_module_module。
3.7 多语言
| 表 | 结构 |
|---|---|
s_i18n |
b_key + b_locale(联合 PK) / b_value nvarchar(1000) / b_canuse |
s_i18n_type |
b_id(PK, 如 zh-CN) / b_name / b_canuse / b_default(是否默认语言) / b_xh |
3.8 s_user_module_pref — 用户个性化
用户对模块界面的个人偏好(列宽、顺序等),覆盖模块默认配置。
b_user_id + b_module_id + b_schema_type(联合 PK) / b_schema_json / b_updated_by / b_updated_at。
3.9 s_delete_rule — 删除规则
| 列 | 说明 |
|---|---|
b_id |
bigint 主键 |
b_module_id |
模块编码 |
b_sql |
删除前检查/处理的 SQL |
b_message |
不满足条件时给用户的提示 |
b_canuse / b_xh |
启用 / 顺序 |
b_created_by / b_created_at / b_updated_by / b_updated_at |
审计字段 |
4. 组织与用户
| 表 | 主键 | 说明 |
|---|---|---|
b_user |
b_id varchar(50) |
用户账号 |
b_dept |
b_id varchar(50) |
部门树 |
b_position |
b_id varchar(50) |
岗位 |
b_org_role |
b_id varchar(50) |
组织角色 |
b_user_position |
b_user_id + b_position_id |
用户-岗位关联 |
b_user_org_role |
b_user_id + b_role_id |
用户-组织角色关联 |
两个对工作流审批人解析至关重要的字段:
| 字段 | 含义 | 用于 |
|---|---|---|
b_dept.b_manager_id |
部门负责人(用户编码) | dept_manager 规则 |
b_user.b_leader_id |
用户的直属领导(用户编码) | initiator_manager 规则 |
部门树用 b_parent_id 作权威关系,b_depth / b_path 是派生字段;b_path 的节点编码前缀用于查下级部门(数据范围 dept_tree 依赖)。
关联表都有 b_canuse 与审计字段,并建了反向索引(如 ix_b_user_position_position)。
5. 权限
权限只保留四张表,分别回答四个问题:
5.1 s_power — 有哪些权限点
| 列 | 类型 | 说明 |
|---|---|---|
b_id |
varchar(150) PK |
权限点编码,如 action.{模块}.{动作} |
b_name |
nvarchar(200) |
权限点名称 |
b_type |
varchar(20) |
权限点类型 |
b_object_type |
varchar(20) |
对象类型,动作权限为 module |
b_object_id |
varchar(50) |
对象编码(模块编码) |
b_action |
varchar(30) |
动作编码,如 submit / approve / export |
b_canuse / b_xh / b_bz / b_i18n |
— | — |
唯一索引 ux_s_power_object_action(b_object_type, b_object_id, b_action) —— 保证同一对象同一动作只有一个权限点。
另有 ix_s_power_object、ix_s_power_type。
s_power不设审计字段(开发期维护的系统元数据)。
5.2 s_user_power — 用户有哪些权限点
| 列 | 说明 |
|---|---|
b_user_id + b_power_id |
联合主键 |
b_canuse |
是否启用 |
b_created_by / b_created_at / b_updated_by / b_updated_at |
审计字段(授权变更需可追溯) |
索引 ix_s_user_power_power(b_power_id, b_user_id)。
5.3 s_user_field_power — 字段级权限
| 列 | 默认 | 说明 |
|---|---|---|
b_user_id + b_module_id + b_field_id |
联合 PK | — |
b_view |
1 | 是否可见 |
b_edit |
0 | 是否可编辑 |
b_query |
1 | 是否可作为查询条件 |
b_export |
1 | 是否可导出 |
b_canuse |
1 | 是否启用 |
b_created_by / b_created_at / b_updated_by / b_updated_at |
— | 审计字段 |
无记录按模块默认(可看可导出)。
b_view=0或b_export=0的列会在导出时被移除。
5.4 s_user_data_power — 数据范围
| 列 | 类型 | 默认 | 说明 |
|---|---|---|---|
b_user_id |
varchar(50) PK |
— | 用户编码 |
b_module_id |
varchar(50) PK |
— | 模块编码 |
b_operation |
varchar(30) PK |
* |
操作;* 表示适用于所有操作 |
b_xh |
int PK |
0 | 同组内的排序 / 区分序号 |
b_scope_type |
varchar(20) |
— | 范围类型,见下 |
b_scope_field |
varchar(50) |
— | 判定字段(实际取值以模块配置 s_module.b_scope_field 为准) |
b_condition_sql |
nvarchar(max) |
— | custom 类型的条件片段 |
b_canuse |
tinyint |
1 | 是否启用 |
| 审计字段 | — | — | b_created_* / b_updated_* |
主键 (b_user_id, b_module_id, b_operation, b_xh);索引 ix_s_user_data_power_module。
b_scope_type |
含义 |
|---|---|
all 或空 |
全部数据,不追加条件 |
self |
只本人:判定字段 = 当前用户 |
dept |
只本部门:判定字段 = 当前用户所属部门 |
dept_tree |
本部门及下级:按 b_dept.b_path 前缀匹配 |
custom |
自定义:使用 b_condition_sql |
判定规则:
- 按操作精确匹配优先——命中精确规则就不再叠加
'*'规则;没有精确规则时才用'*'。 - 多条规则之间 OR,整体再与其它条件 AND。
- 判定字段取自模块配置而不是授权行:同一模块的所有用户必须用同一字段判范围。
- 未归属部门时
dept/dept_tree规则不生效(不报错,等于不追加条件)。 custom的b_condition_sql只由管理员配置,运行时仅替换{userId}/{deptId}受控占位符,并做只读校验(禁分号、禁注释、禁写关键字)。
6. 日志
三张日志表都以 UUIDv7 为主键,都建了按时间与业务维度的索引。
6.1 s_log_audit — 数据变更审计
| 列 | 类型 | 默认 | 说明 |
|---|---|---|---|
b_id |
uniqueidentifier PK |
— | UUIDv7 |
b_event_code |
varchar(50) |
— | 事件编码 |
b_module_id |
varchar(50) |
— | 模块编码 |
b_data_id |
varchar(50) |
— | 业务主键(统一字符串保存) |
b_business_no |
varchar(50) |
— | 业务单号 |
b_operation |
varchar(100) |
— | 操作名(如「审批状态投影」) |
b_operator_id |
varchar(50) |
— | 操作人 |
b_operator_name |
nvarchar(200) |
— | 操作人姓名 |
b_source_type |
varchar(20) |
user |
来源类型(user / system) |
b_visibility |
varchar(20) |
internal |
可见性 |
b_request_id / b_trace_id |
varchar(64) |
— | 请求 / 链路 ID |
b_payload_text |
nvarchar(max) |
— | 事件载荷 |
b_occurdatetime |
datetime2 |
getdate() |
发生时间 |
索引:ix_s_log_audit_module(b_module_id, b_data_id, b_occurdatetime)、ix_s_log_audit_occur(b_occurdatetime, b_id)。
6.2 s_log_audit_field — 字段级前后值
| 列 | 说明 |
|---|---|
b_id |
PK |
b_event_id |
关联 s_log_audit.b_id |
b_module_id / b_data_id |
冗余存储,便于直接按数据查 |
b_field |
字段编码 |
b_field_label |
字段名称 |
b_before_value / b_after_value |
原始值 |
b_before_display / b_after_display |
展示值(如枚举翻译后的文本) |
b_visibility |
可见性 |
索引 ix_s_log_audit_field_event(b_event_id, b_id)。
原始值与展示值分开存:原始值用于比对与回放,展示值用于界面直接呈现,避免查日志时再翻译一遍。
6.3 s_log_login — 登录日志
| 列 | 说明 |
|---|---|
b_id |
PK(UUIDv7) |
b_user_id |
用户账号(失败时也可能有值) |
b_login_type |
登录方式 |
b_login_result |
tinyint,0 失败 / 1 成功 |
b_fail_reason |
失败原因(「账号不存在」/「密码错误」) |
b_ip / b_ip_location |
来源 IP 与归属地 |
b_browser / b_browser_version |
浏览器 |
b_os / b_os_version |
操作系统 |
b_device_type |
设备类型 |
b_user_agent |
原始 UA |
b_session_id |
会话 ID(成功时) |
b_request_id / b_trace_id |
请求 / 链路 ID |
b_occurdatetime |
发生时间 |
索引:ix_s_log_login_occur、ix_s_log_login_user(b_user_id, b_occurdatetime)。
对外提示不区分「账号不存在」与「密码错误」(都是 401 同一句),但日志里分别记录 —— 既能防账号探测,又能支撑排查。
6.4 s_log_technical — 技术日志
| 列 | 说明 |
|---|---|
b_id |
PK(UUIDv7) |
b_user_id |
用户编码 |
b_sourcetype |
来源类型 |
b_loglevel |
日志级别 |
b_logcategory |
日志分类 |
b_operation |
操作名 |
b_module_id |
模块编码 |
b_request_id / b_trace_id |
请求 / 链路 ID |
b_server_node |
服务节点 |
b_duration_ms |
耗时(毫秒) |
b_result_code |
结果码 |
b_error_code / b_error_message |
错误码与说明 |
b_exception_text |
异常堆栈 |
b_context_text |
上下文 |
b_occurdatetime |
发生时间 |
索引:ix_s_log_technical_occur、ix_s_log_technical_trace(b_trace_id, b_occurdatetime)——按链路 ID 串起一次请求的全部日志。
7. 附件
7.1 bf_files — 文件记录
| 列 | 类型 | 说明 |
|---|---|---|
subid |
bigint PK |
雪花 ID(应用层取号,非自增) |
father |
bigint |
宿主业务主键,不建外键 |
mx_filename |
nvarchar(500) |
原始文件名 |
mx_filesize |
varchar(50) |
文件大小 |
mx_fileext |
varchar(50) |
扩展名 |
mx_mapfilename |
nvarchar(500) |
访问地址(预览/下载直接用) |
mx_moduleid |
varchar(50) |
模块编码 |
mx_cate_id |
bigint |
分类 ID(关联 bf_files_category.b_id) |
mx_xh / mx_sh |
int / tinyint |
顺序 / 审核标记(保留,当前未用) |
mx_inputuser_id / mx_inputdatetime |
— | 录入人 / 录入时间 |
mx_shuser_id / mx_shdatetime |
— | 审核人 / 审核时间(保留) |
mx_cutfilename / mx_cutfilesize |
— | 缩略图文件名 / 大小(保留) |
mx_updateuser_id / mx_updatedatetime |
— | 最后修改人 / 时间(保留) |
mx_orderid / mx_bz |
— | 排序 / 备注(保留) |
索引 ix_bf_files_host(father, mx_moduleid, mx_cate_id, mx_xh, subid) —— 列表查询按宿主 + 模块 + 分类过滤。
旧库遗留字段
mx_sh*/mx_cut*/mx_orderid/mx_bz/mx_update*保留以兼容历史数据迁移,新代码不使用(写入 0 或空值)。但subid/father/mx_*的列名已被前后端实现引用,保持现状。
7.2 bf_files_category — 文件分类
| 列 | 类型 | 说明 |
|---|---|---|
b_id |
bigint PK |
雪花 ID(与 bf_files.mx_cate_id 类型一致) |
b_module_id |
varchar(50) |
所属模块;为空表示跨模块通用分类 |
b_name |
nvarchar(50) |
分类名称 |
b_i18n |
varchar(150) |
多语言资源键 |
b_files_type |
varchar(50) |
文件类型 |
b_xh / b_canuse |
int / tinyint |
顺序 / 启用 |
b_bz |
nvarchar(200) |
备注 |
| 审计字段 | — | b_created_* / b_updated_* |
索引 ix_bf_files_category_module(b_module_id, b_canuse, b_xh, b_id)。
分类树按当前模块过滤:b_module_id IS NULL OR b_module_id = 当前模块。
8. 工作流
工作流是独立子系统:配置表用 varchar 业务编码主键,运行表用 UUIDv7。全部 13 张表。
配置:wf_definition → wf_version → { wf_node, wf_edge, wf_actor_rule }
wf_binding(模块+事件 → 版本)
运行:wf_instance → wf_node_run → wf_task → wf_action
wf_cc(抄送) wf_delegation(委托) wf_outbox(通知)
8.1 wf_definition — 流程定义
稳定逻辑身份,执行内容在版本表。
b_id varchar(50) PK(编码,创建后不可修改)/ b_name nvarchar(200) / b_i18n / b_canuse / b_bz / 审计字段。
索引:ix_wf_definition_canuse(b_canuse, b_id)。
8.2 wf_version — 流程版本
| 列 | 类型 | 默认 | 说明 |
|---|---|---|---|
b_id |
varchar(50) PK |
— | 版本 ID |
b_definition_id |
varchar(50) |
— | 所属定义 |
b_version_no |
int |
— | 版本号(同流程内递增) |
b_status |
varchar(20) |
draft |
draft / published / retired |
b_schema_version |
int |
1 | 配置结构版本 |
b_canvas_json |
nvarchar(max) |
— | 设计器布局,不参与执行 |
b_checksum |
varchar(128) |
— | 发布时计算的配置摘要 |
b_published_by / b_published_at |
— | — | 发布人与时间 |
四个索引,其中两个是筛选唯一索引:
| 索引 | 作用 |
|---|---|
ux_wf_version_draft(b_definition_id) WHERE b_status='draft' |
同一定义只能有一条草稿 |
ux_wf_version_no(b_definition_id, b_version_no) |
版本号不重复 |
ix_wf_version_status |
按状态查询 |
已发布版本不可原地修改;运行中的实例固定引用提交时的
b_version_id。
8.3 wf_node — 节点
| 列 | 类型 | 说明 |
|---|---|---|
b_id |
varchar(50) PK |
节点 ID |
b_version_id |
varchar(50) |
所属版本 |
b_node_key |
varchar(80) |
版本内稳定编码(历史记录引用它) |
b_name / b_i18n |
— | 名称 / 多语言键 |
b_node_type |
varchar(30) |
见下 |
b_approval_mode |
varchar(30) |
见下 |
b_reject_mode |
varchar(30) |
见下 |
b_due_hours |
decimal(10,2) |
审批时限(小时);不配则该节点任务永不过期 |
b_config_json |
nvarchar(max) |
扩展配置(requiredCount / requiredRatio / formPolicy 等) |
b_xh / b_canuse |
— | 顺序 / 启用 |
| 列 | 取值 |
|---|---|
b_node_type |
start / user_task / cc_task / service_task / exclusive_gateway / parallel_gateway / end |
b_approval_mode |
single / any / all / serial / n_of_m / percentage |
b_reject_mode |
terminate / return_initiator / return_previous |
唯一索引 ux_wf_node_key(b_version_id, b_node_key)——同一版本内节点编码唯一。
8.4 wf_edge — 连线
| 列 | 说明 |
|---|---|
b_id |
连线 ID(varchar(50) PK) |
b_from_node_key / b_to_node_key |
两端节点编码 |
b_condition_json |
条件 AST,留空 = 无条件(默认边) |
b_priority |
判断优先级,小的先判断 |
b_name |
连线名称(画布标签) |
b_canuse / b_bz |
— |
索引:ix_wf_edge_from、ix_wf_edge_to(都含 b_canuse, b_priority)。
8.5 wf_actor_rule — 审批人规则
| 列 | 说明 |
|---|---|
b_id |
规则 ID |
b_node_key |
适用节点 |
b_actor_type |
解析类型,见下 |
b_actor_ref |
用户 / 岗位 / 角色 / 字段编码 |
b_resolve_json |
解析参数 |
b_condition_json |
规则适用条件 AST |
b_fallback_type |
解析为空时的兜底:none / admin / initiator / custom |
b_fallback_ref |
兜底引用 |
b_priority |
优先级——串行会签的顺序来源 |
b_canuse / b_bz |
— |
b_actor_type |
含义 | 依赖字段 |
|---|---|---|
user |
指定用户 | b_actor_ref |
initiator |
发起人 | — |
initiator_manager |
发起人直属领导 | b_user.b_leader_id |
dept_manager |
部门负责人 | b_dept.b_manager_id |
position |
岗位 | b_user_position |
org_role |
组织角色 | b_user_org_role |
field_user |
业务字段里的用户 | b_actor_ref 指定的字段 |
custom |
自定义解析器 | — |
索引 ix_wf_actor_rule_node(b_version_id, b_node_key, b_canuse, b_priority, b_actor_type)。
规则顺序即优先级顺序,也是串行会签的先后。组织主数据(岗位 / 角色表)不存在时对应类型会降级为空并记原因,由
b_fallback_type兜底。
8.6 wf_binding — 模块绑定
决定「哪个模块的哪个业务事件走哪个流程版本」。
| 列 | 说明 |
|---|---|
b_module_id |
模块编码(data / virtual 模块) |
b_event |
submit / resubmit / change |
b_version_id |
必须是已发布版本 |
b_match_json |
业务匹配条件 AST |
b_org_scope_json |
公司 / 组织范围 |
b_status_field |
业务状态列名(状态投影写这一列) |
b_status_map_json |
流程状态 → 业务状态值映射 |
b_priority |
匹配优先级,小的先匹配 |
b_effective_from / b_effective_to |
生效区间 |
b_canuse / b_bz / 审计字段 |
— |
关键筛选唯一索引:
ux_wf_binding_active_priority(b_module_id, b_event, b_priority) WHERE b_canuse = 1
→ 同一模块同一事件下不能有两条同优先级的启用绑定(否则无法确定用哪个流程)。
另有 ix_wf_binding_select、ix_wf_binding_version。
8.7 wf_instance — 流程实例
| 列 | 类型 | 说明 |
|---|---|---|
b_id |
uniqueidentifier PK |
UUIDv7 |
b_definition_id / b_version_id / b_binding_id |
varchar(50) |
定义 / 版本(提交时固定)/ 命中的绑定 |
b_module_id / b_event |
varchar |
业务模块与事件 |
b_business_id |
varchar(50) |
业务主键,统一按字符串保存 |
b_business_no |
nvarchar(200) |
业务单号(列表展示) |
b_org_id |
varchar(50) |
公司 / 组织编码 |
b_initiator_id / b_initiator_dept_id |
varchar(50) |
发起人及其部门 |
b_status |
varchar(30) |
见下 |
b_context_json |
nvarchar(max) |
运行变量(条件分支与审批人解析的输入) |
b_snapshot_json |
nvarchar(max) |
提交时业务快照 |
b_current_summary_json |
nvarchar(max) |
列表展示用当前节点摘要 |
b_row_version |
bigint 默认 0 |
乐观锁版本号 |
b_idempotency_key |
varchar(100) |
幂等键 |
b_started_at / b_completed_at |
datetime2 |
开始 / 结束时间 |
b_status |
含义 |
|---|---|
running |
运行中 |
approved / rejected / returned |
已通过 / 已驳回 / 已退回 |
withdrawn / cancelled |
已撤回 / 已取消 |
error |
异常待处理(审批人解析为空、路由走不通、配置损坏) |
列注释里还列了
expired,但实现中实例从不进入该状态——超时只作用于任务(见 §8.9)。
关键筛选唯一索引:
ux_wf_instance_idempotency(b_module_id, b_business_id, b_idempotency_key)
WHERE b_idempotency_key IS NOT NULL
→ 送审幂等的唯一保证。代码靠捕获唯一键冲突(SQL 2601/2627/23000)回查既有实例返回 duplicated,索引不存在则幂等完全失效。
另有 ix_wf_instance_business、ix_wf_instance_initiator、ix_wf_instance_version。
8.8 wf_node_run — 节点运行
| 列 | 类型 | 说明 |
|---|---|---|
b_id |
uniqueidentifier PK |
UUIDv7 |
b_instance_id |
uniqueidentifier |
所属实例 |
b_node_key |
varchar(80) |
节点编码 |
b_run_no |
int 默认 1 |
同一节点的第几次运行(退回、循环用) |
b_status |
varchar(30) |
pending / running / completed / skipped |
b_required_count |
int |
应签人数(按比例时激活时换算) |
b_completed_count / b_rejected_count |
int 默认 0 |
已通过 / 已驳回人数 |
b_entered_at / b_exited_at |
datetime2 |
进入 / 离开时间 |
b_actor_snapshot_json |
nvarchar(max) |
审批人规则快照(含解析结果与说明) |
节点状态是
completed,不是任务的approved—— 若这里写approved,并行汇合的「入线来源节点都已完成」判定与「退回上一节点」查找都会失效。
审批人快照必须落库:组织架构以后变了,也不能改动已产生的历史审批责任。
8.9 wf_task — 待办任务
| 列 | 类型 | 说明 |
|---|---|---|
b_id |
uniqueidentifier PK |
UUIDv7 |
b_instance_id / b_node_run_id |
uniqueidentifier |
实例 / 节点运行(会签聚合判断用) |
b_node_key |
varchar(80) |
节点编码 |
b_actor_rule_id |
varchar(50) |
命中的审批人规则 |
b_assignee_type |
varchar(30) |
user / position / role / delegate(委托物化) |
b_assignee_id |
varchar(50) |
实际受理人 |
b_seq |
int 默认 0 |
同节点内处理顺序(串行会签生效) |
b_status |
varchar(30) |
见下 |
b_due_at |
datetime2 |
应处理时间(由节点 b_due_hours 算出) |
b_claimed_by / b_claimed_at |
— | 抢占人与时间 |
b_completed_by / b_completed_at |
— | 处理人与时间 |
b_rule_snapshot_json |
nvarchar(max) |
审批人解析快照(委托时含原审批人与委托单号) |
b_status |
含义 |
|---|---|
waiting |
串行会签排队中(未轮到) |
pending / claimed |
待处理 / 已抢占 |
approved / rejected |
已通过 / 已驳回 |
cancelled |
被撤回、取消,或同节点他人已处理而取消 |
expired |
已超期(仅由超时扫描写入) |
索引:ix_wf_task_assignee(b_assignee_id, b_status, b_due_at, b_id)(待办列表)、
ix_wf_task_due(b_status, b_due_at, b_id)(超时扫描)、
ix_wf_task_node_run(b_node_run_id, b_status, b_seq, b_id)(串行推进)、
ix_wf_task_instance、ix_wf_task_completed_by(已办列表)。
b_due_at为空 = 永不超时:节点没配b_due_hours时不设应处理时间。
8.10 wf_action — 审批动作历史
| 列 | 说明 |
|---|---|
b_id |
PK(UUIDv7) |
b_instance_id |
实例 |
b_node_run_id / b_task_id |
节点运行 / 任务(实例级动作为 null) |
b_action |
动作编码,见下 |
b_operator_id |
操作人(系统动作为 null) |
b_from_status / b_to_status |
变更前后状态 |
b_comment |
审批意见 |
b_payload_json |
动作载荷(命中的条件、边、加签位置等) |
b_request_id / b_trace_id |
请求 / 链路 ID |
b_occurdatetime |
发生时间 |
b_action |
含义 |
|---|---|
submit / approve / reject / return |
送审 / 通过 / 驳回 / 退回 |
withdraw / cancel |
撤回 / 取消 |
claim / transfer / add_approver / urge |
抢占 / 转交 / 加签 / 催办 |
cc |
抄送 |
activate |
串行会签激活下一位 |
service |
服务节点自动完成 |
route |
分支点路由留痕 |
expire |
任务超期(系统动作,操作人为 null) |
筛选唯一索引:
ux_wf_action_request(b_request_id) WHERE b_request_id IS NOT NULL
→ 审批幂等的保证(与 wf_instance 的幂等键同理)。
该列无
CHECK约束,加动作码不需要改表;但下游若按枚举过滤需同步。wf_action是不可变历史,与s_log_audit分工:前者记流程动作,后者记数据变更。
8.11 wf_cc — 抄送
b_id(PK) / b_instance_id / b_node_run_id / b_node_key / b_recipient_id / b_actor_rule_id / b_status(unread 默认 / read)/ b_read_at / b_rule_snapshot_json。
索引:ix_wf_cc_recipient(b_recipient_id, b_status, b_created_at, b_id)(抄送列表)、ix_wf_cc_instance。
抄送节点不产生待办,也不参与节点完成判定(写入即完成)。
8.12 wf_delegation — 委托
| 列 | 说明 |
|---|---|
b_id |
varchar(50) PK |
b_from_user_id / b_to_user_id |
委托 / 受托人 |
b_scope_json |
委托范围:{moduleIds, actions, orgIds},空数组 = 不限 |
b_start_at / b_end_at |
生效 / 失效时间 |
b_reason |
委托原因 |
b_canuse / 审计字段 |
— |
索引 ix_wf_delegation_user(b_from_user_id, b_canuse, b_start_at, b_end_at, b_to_user_id)。
委托在任务生成时就物化:候选人若有生效中的委托,任务直接建给代理人(
b_assignee_type='delegate'),这样代理人能在待办里看到它。原审批人与委托单号进任务快照,动作期复核actions范围。
8.13 wf_outbox — 通知消息
| 列 | 默认 | 说明 |
|---|---|---|
b_id |
— | PK(UUIDv7) |
b_event_code |
— | 事件编码 |
b_aggregate_type |
— | instance / task |
b_aggregate_id |
— | 聚合 ID |
b_payload_json |
— | 消息载荷 |
b_status |
pending |
pending / sent / failed |
b_retry_count |
0 | 重试次数 |
b_next_retry_at |
— | 下次重试时间 |
b_last_error |
— | 最后错误 |
b_occurdatetime |
— | 发生时间 |
索引 ix_wf_outbox_dispatch(b_status, b_next_retry_at, b_occurdatetime, b_id)。
事件码词表:
| 事件码 | 触发 |
|---|---|
instance.submitted / instance.withdrawn / instance.cancelled |
实例级状态变化 |
instance.approved / instance.rejected / instance.returned |
实例结束 |
instance.error |
实例进入异常 |
task.created / task.activated |
建任务 / 串行激活下一位 |
task.transferred / task.approver_added / task.urged |
转交 / 加签 / 催办 |
task.expired |
任务超期(超时扫描写) |
cc.created |
抄送产生 |
instance.projection_skipped |
业务主键类型不匹配,跳过投影 |
instance.projection_missing |
状态投影影响行数 ≠ 1(静默丢更新的留痕) |
audit.skipped |
s_log_audit 不存在,审计无法落库 |
最后三个是降级留痕:出问题时不会阻断审批,但会在 outbox 里留下可追溯的记录。
9. 超时机制(与表结构的关系)
超时是唯一会主动改任务状态的后台行为,涉及 wf_task 与上述三张表:
节点 b_due_hours → 建任务时算出 b_due_at
↓
[后台扫描,默认 5 分钟]
选出 b_status in ('pending','claimed') and b_due_at < sysutcdatetime()
↓
wf_task.b_status = 'expired'
wf_action += 一条 expire(操作人为 null)
wf_outbox += task.expired
明确不做:不动 wf_node_run、不动 wf_instance(仍 running)、不自动通过/否决、不置 error、不提升串行后继。
几个由此而来的结论:
- 到期任务从待办列表(只查
pending/claimed)自动消失,但实例仍在运行,需管理员加签或转派。 - 没有「我的超期任务」出口:
doneList查的是b_completed_by,超期任务没人处理过,所以也查不到。 - 串行链上当前审批人超期会停住:那把唯一的
pending失效后,waiting的不会自动提升,整条链停在那里。 - 配
erp.workflow.expire-sweep-interval: 0s可完全关闭扫描。
10. 视图
查询入口以视图为主,业务模块通常指向视图而不是物理表:
| 视图 | 说明 |
|---|---|
v_wf_definition / v_wf_version / v_wf_binding / v_wf_instance |
工作流配置与实例(配置侧列表用) |
v_s_log_audit / v_s_log_login / v_s_log_technical |
日志查询 |
v_b_othercompany / v_b_contact / v_b_user |
业务与主数据 |