Files
workspace/code/g3soft-erp/sql/README.md
T
2026-10-13 17:29:55 +08:00

86 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# sql —— 工作流模块 SQL 脚本
本目录是从原型 `fms-api` 迁移工作流引擎时一并带过来的 SQL Server 脚本,用于把工作流的
表、视图、模块/菜单/权限注册和示例数据建到目标库。
> **本目录不包含 `fms_core.sql`。** 目标项目 g3soft-erp 的库已经具备核心表
> (`s_module` / `s_field` / `s_module_schema` / `s_menu` / `s_power` / `s_user_power` /
> `b_user` / `b_dept` 等)。**如果目标库缺少这些核心表,本目录的脚本无法独立完成初始化**,
> 请先建好核心表再执行。
## 执行顺序
按目录名前缀的数字顺序执行:
| 顺序 | 脚本 | 作用 | 幂等 |
|---|---|---|---|
| 1 | `00_core_companion/workflow_audit_tables.sql` | `s_log_audit` / `s_log_audit_field`(**可选**,用于 §11 审计) | 是 |
| 2 | `10_workflow/01_fms_workflow.sql` | 13 张 `wf_*` 表 + 索引(只建表,不含数据) | 否(重复执行会报表已存在) |
| 3 | `10_workflow/02_fms_workflow_org_ext.sql` | 组织主数据扩展:`b_dept.b_manager_id`、`b_user.b_leader_id`、`b_position` / `b_user_position` / `b_org_role` / `b_user_org_role` | 是 |
| 4 | `20_registration/10_fms_workflow_module.sql` | 4 个只读视图 + `s_module` / `s_field` / `s_module_schema` / `s_menu_module` 注册 | 是(先删后建) |
| 5 | `20_registration/11_fms_workflow_menu.sql` | 流程管理 / 审批中心菜单 + `s_i18n` | 是 |
| 6 | `20_registration/12_fms_workflow_power.sql` | 菜单权限点 + 动作权限点 + 授予 `g3soft` | 是 |
| 7 | `30_patches/01_fms_workflow_index_patch.sql` | 补充索引(见下) | 是 |
| 8 | `90_mock/01_fms_workflow_mock.sql` | **示例**流程定义 `expense_approval`(14 节点 / 17 连线 / 13 审批人规则) | 否 |
| 9 | `90_mock/02_fms_workflow_runtime_mock.sql` | **示例**运行数据:演示机构/用户 + 6 个实例 | 否 |
**第 2 步不幂等**:`01_fms_workflow.sql` 是纯 `create table`。表已存在时会报错,需要先 drop
(脚本头部有说明)。第 8、9 步是示例数据,**生产环境不要执行**。
### 第 6 步的顺序陷阱
`12_fms_workflow_power.sql` 的动作权限点是这样生成的:
```sql
select distinct b_module_id from dbo.wf_binding where b_canuse = 1
```
**`wf_binding` 为空时,动作权限点会生成 0 条。** 三个缓解手段,按需选用:
1. 先跑 mock(第 8 步,它含一条 binding)再跑第 6 步;或先在应用里保存一条流程绑定;
2. 应用侧本身会自愈——`WorkflowConfigService.saveBinding` 每次保存绑定都会调用
`ensureActionPowers(moduleId)`,按 `action.{模块}.{动作}` 幂等补点;
3. 该脚本可重复执行,binding 补上后再跑一次即可。
动作权限点写入 `s_power (b_type='action', b_object_type='module', b_object_id=模块, b_action=动作)`,
与 `SqlPermissionService.requireAction` 的匹配列一致,两边天然对齐。
## 组织主数据扩展(第 3 步)不是可选项
`02_fms_workflow_org_ext.sql` 建的表/列是 8 种审批人里 4 种的前提:
| 审批人类型 | 依赖 |
|---|---|
| `dept_manager` | `b_dept.b_manager_id` |
| `initiator_manager` | `b_user.b_leader_id` |
| `position` | `b_position` / `b_user_position` |
| `org_role` | `b_org_role` / `b_user_org_role` |
不执行该脚本时,这 4 类审批人会**静默解析为空**,再由节点兜底策略(fallback / 置 `error`)接管。
## mock 数据的模块依赖
`90_mock/02_fms_workflow_runtime_mock.sql` 使用模块 `v_b_othercompany` 作为绑定目标。
目标库若没有该 `s_module` 行,请把它替换为库里真实存在的业务模块,或先补建该模块。
## 运行时语义备忘(与本目录脚本相关的两条约定)
- **任务超时只标记、不自动改流程**:超时任务会被置 `expired` 并从待办列表过滤掉,
实例保持 `running`,由管理员通过加签 / 转派处理。**不自动提升串行后继、不置 `error`、不自动通过。**
因此串行会签链中若当前审批人超时,链路会停住等待人工介入。
- **审计探写**:`WorkflowAuditWriter` 每事务探测 `s_log_audit` 是否存在;不存在时写一条
`wf_outbox(audit.skipped)` 并继续。**库里没有审计表不算故障**,不会阻断审批。
## 补充索引说明(第 7 步)
| 索引 | 解决什么 |
|---|---|
| `ix_wf_binding_version (b_version_id)` | 发布校验与删除定义按 `b_version_id` 直查,原索引不以它打头 |
| `ix_wf_task_completed_by (b_completed_by, b_completed_at)` | 「我已处理」列表过滤列原无索引 |
| `ix_wf_task_node_run (b_node_run_id, b_status, b_seq, b_id)` | 串行会签提升、兄弟任务取消 |
## 行尾
本目录 `*.sql` 一律 LF(根 `.gitattributes` 已声明 `*.sql text eol=lf`)。
从 fms 仓拷贝时已做 LF 转换。