Files
shanxia2.0/docs/superpowers/specs/2026-05-13-workflow-module-design.md
T
2026-05-30 14:03:11 +08:00

352 lines
13 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.
# 工作流模块设计文档
**模块**: 2.1.11 流程管理
**日期**: 2026-05-13
**状态**: 待审核
**决策记录**:
- 流程设计器: AntV X6(蚂蚁图编辑引擎)
- V1范围: 全量实现(配置管理+设计器+待办中心+已办中心+后端引擎)
- 业务集成: API调用+回调模式
- 引擎架构: 图遍历引擎(方案A)
---
## 1. 整体架构与模块划分
### 1.1 后端(`backend/app/`)
```
models/models.py ← 新增6个wf_* SQLAlchemy模型
schemas/workflow.py ← Pydantic schemas(请求/响应模型)
crud/workflow.py ← 数据库CRUD操作
services/
workflow_engine.py ← 核心引擎:节点分发、条件评估、审批人解析
workflow_callback.py ← 回调服务:通知业务模块状态变更
api/workflow.py ← API路由(注册到admin前缀)
```
### 1.2 前端(`web-admin/src/`)
```
api/workflow.ts ← API调用
types/api.d.ts ← 新增Workflow相关TS类型
views/system/workflow/
process/index.vue ← 流程配置管理(列表+设计器弹窗)
designer/
FlowDesigner.vue ← AntV X6流程设计器组件
nodes/ ← 自定义节点组件(Start/End/Approval/Condition)
config/ ← 节点属性配置面板
task-pending/index.vue ← 待办中心
task-completed/index.vue ← 已办中心
components/
ApprovalDialog.vue ← 审批操作弹窗(通过/驳回+意见)
ProcessStatusTag.vue ← 流程状态标签
router/modules/sqxp.ts ← 新增3个路由
```
### 1.3 核心数据流
1. 管理员在流程配置页 → AntV X6设计器画流程 → 保存 `graph_json` + 同步写 `wf_node`/`wf_transition`
2. 业务模块调用 `POST /api/admin/workflow/instances` 发起流程 → 引擎锁定当前版本 → 创建 start 任务
3. 引擎按 `wf_transition` 遍历节点 → 审批节点创建 `wf_task` → 待办人收到待办
4. 待办人审批 → 引擎判断 any/all 策略 → 推进到下一节点 → 到达 end 节点 → 回调业务模块
---
## 2. 数据库模型
已有 6 张表 DDL 见全库导出 `docs/sql/`(搜索 `wf_process_def` 等表名);基线表结构以当前导出为准。
| 表名 | 用途 | 关键字段 |
|------|------|----------|
| `wf_process_def` | 流程定义 | process_code, process_name, status |
| `wf_process_version` | 流程版本 | process_def_id, version_no, graph_json, is_latest |
| `wf_node` | 流程节点 | process_version_id, node_key, node_type, config_json |
| `wf_transition` | 流程连线 | process_version_id, from_node_key, to_node_key, condition_expr |
| `wf_process_instance` | 流程实例 | process_version_id, business_type, business_id, variables_json, status |
| `wf_task` | 流程任务 | instance_id, node_key, assignee_user_id, status, comment_text |
**node_type 枚举值**: `start`, `end`, `approval`, `condition`
**instance.status 枚举值**: `running`, `completed`, `rejected`, `cancelled`
**task.status 枚举值**: `pending`, `approved`, `rejected`, `withdrawn`
所有表均遵循公共字段规范:id(VARCHAR 64 UUID) → 业务字段 → tenant_no → order_num → remark → create_by → create_dept_id → create_time → update_by → update_time → del_flag
### 2.1 Schema 变更(需新增字段)
`wf_process_instance` 需新增 `callback_url` 字段(VARCHAR 512, 可空),用于业务回调地址。DDL 变更将在实施阶段维护到 `docs/sql/`(全量基线为 `docs/sql/`,或附加增量脚本)。
### 2.2 双存储语义
工作流存在两套数据,各有用途:
- **`graph_json`**(wf_process_version): 前端设计器画布快照,用于设计器加载/编辑/渲染。仅供前端使用,后端引擎不解析此字段。
- **`wf_node` + `wf_transition`**(关系表): 后端引擎运行时使用的规范化数据。引擎只读这些表来执行节点分发和条件评估。
- 两者在"发布版本"时同步写入,保持一致。
---
## 3. 工作流引擎核心设计
### 3.1 节点分发器模式
每种节点类型对应一个 handler,引擎根据 node_type 调度:
```
WorkflowEngine
├── StartNodeHandler → 自动推进到下一个节点
├── EndNodeHandler → 标记实例完成,触发回调
├── ApprovalNodeHandler → 解析审批人,创建wf_task记录
└── ConditionNodeHandler → 评估条件表达式,选择分支
```
引擎入口方法:`advance(instance_id, from_node_key)` — 从指定节点开始,执行当前节点逻辑,然后沿出边推进到下一个节点。
### 3.2 条件表达式格式
`wf_transition.condition_expr` 字段存储的是 JSON 规则格式(VARCHAR 512),不是任意文本表达式。安全可控,不支持任意代码执行:
```json
{
"rules": [
{"field": "amount", "op": "<=", "value": 100},
{"field": "amount", "op": ">", "value": 100, "and": [{"field": "amount", "op": "<", "value": 300}]},
{"field": "amount", "op": ">=", "value": 300}
]
}
```
**支持的操作符**: `==`, `!=`, `>`, `<`, `>=`, `<=`, `in`, `not_in`, `contains`
**字段取值**: 从 `wf_process_instance.variables_json` 中读取。支持嵌套路径用 `.` 分隔(如 `applicant.dept_id`)。
**条件评估逻辑**: ConditionNodeHandler 遍历所有出边(wf_transition),依次评估每条边的 condition_expr。第一条匹配的边即为执行路径。最后一条边可省略条件作为"其他情况"默认分支。
### 3.3 审批人解析
`config_json` 中的 `approver` 字段定义解析策略:
```json
{
"strategy": "users",
"pass_type": "any",
"user_ids": ["uuid1", "uuid2"]
}
```
**strategy 枚举**:
| 策略 | 配置字段 | 说明 |
|------|----------|------|
| `users` | `user_ids: string[]` | 指定具体用户 |
| `roles` | `role_ids: string[]` | 指定角色,运行时解析角色下的所有用户 |
| `sql` | `sql: string` | SQL查询,返回user_id列表 |
**pass_type 枚举**:
- `any` — 任一审批人通过即推进
- `all` — 所有审批人都必须通过才推进
**SQL策略安全约束**:
- 只允许 SELECT 语句
- 禁止包含 INSERT/UPDATE/DELETE/DROP/ALTER
- 只取结果第一列作为 user_id
- 流程变量作为参数注入(`:var_name` 占位符)
- 查询结果受 tenant_no 隐式过滤
### 3.4 版本锁定
- 发起流程时,`wf_process_instance.process_version_id` 锁定当前 `is_latest=1` 的版本
- 发布新版本时:将旧版本的 `is_latest` 置为 0,创建新版本记录 `is_latest=1`
- 已发起的实例始终使用锁定的版本运行,不受后续版本变更影响
### 3.5 实例状态流转
```
发起 → running → completed(到达end节点)
→ rejected(审批驳回,无其他分支时)
→ cancelled(业务主动取消)
```
### 3.6 任务状态流转
```
创建 → pending → approved(审批通过)
→ rejected(审批驳回)
→ withdrawn(发起人撤回)
```
---
## 4. API路由设计
共13个路由,全部走 `/api/admin/workflow/` 前缀,带JWT认证和租户隔离。
### 4.1 流程定义管理
| 路由 | 方法 | 说明 |
|------|------|------|
| `/api/admin/workflow/defs` | GET | 流程定义列表(分页+搜索,支持按名称/编码/状态筛选) |
| `/api/admin/workflow/defs` | POST | 新建流程定义 |
| `/api/admin/workflow/defs/{id}` | PUT | 更新流程定义基本信息 |
| `/api/admin/workflow/defs/{id}` | DELETE | 软删除流程定义(del_flag=1) |
| `/api/admin/workflow/defs/{id}/publish` | POST | 发布新版本(接收graph_json+nodes+transitions,创建新版本) |
| `/api/admin/workflow/defs/{id}/versions` | GET | 版本历史列表 |
### 4.2 流程实例
| 路由 | 方法 | 说明 |
|------|------|------|
| `/api/admin/workflow/instances` | POST | 发起流程(业务模块调用,传入process_code+business_type+business_id+variables) |
| `/api/admin/workflow/instances/{id}` | GET | 流程实例详情(含任务列表和流程图高亮当前节点) |
### 4.3 任务办理
| 路由 | 方法 | 说明 |
|------|------|------|
| `/api/admin/workflow/tasks/pending` | GET | 我的待办列表(按assignee_user_id=当前用户+status=pending过滤) |
| `/api/admin/workflow/tasks/completed` | GET | 我的已办列表(按assignee_user_id=当前用户+status in [approved,rejected]过滤) |
| `/api/admin/workflow/tasks/{id}/approve` | POST | 审批通过(传comment_text) |
| `/api/admin/workflow/tasks/{id}/reject` | POST | 审批驳回(传comment_text) |
### 4.4 请求/响应格式
**发起流程请求**:
```json
POST /api/admin/workflow/instances
{
"process_code": "agreement_payment",
"business_type": "agreement",
"business_id": "agr_uuid_123",
"variables": {
"amount": 5000,
"dept_id": "dept_001",
"applicant_id": "user_001"
},
"callback_url": "/api/admin/agreements/workflow-callback"
}
```
**审批操作请求**:
```json
POST /api/admin/workflow/tasks/{id}/approve
{
"comment_text": "同意,费用已核实"
}
```
---
## 5. 前端页面设计
### 5.1 流程配置管理(`process/index.vue`)
**模式**: 标准列表页(参考 `unit/index.vue` 模板)
**列表字段**: 流程编码、流程名称、状态(启用/停用)、最新版本号、创建时间、操作
**操作按钮**: 新增、编辑、**流程设计**(打开X6设计器弹窗)、发布新版本、停用/启用、删除
**设计器入口**: 点击"流程设计"→ 全屏弹窗打开 AntV X6 设计器
### 5.2 AntV X6 流程设计器(`designer/FlowDesigner.vue`)
**三栏布局**:
- **左侧**: 节点组件面板(开始/结束/审批人/条件分支),拖拽到画布
- **中间**: 画布区域(AntV X6 Graph),支持节点拖拽、连线、删除、缩放
- **右侧**: 属性配置面板(选中节点后展示,根据节点类型动态切换)
- 审批人节点: 策略选择(用户/角色/SQL)、具体配置、通过策略(any/all)
- 条件分支节点: 每条出边的条件规则编辑
- 开始/结束节点: 只显示名称编辑
**顶部工具栏**: 保存草稿、发布新版本、撤销/重做、放大/缩小/适应画布
**保存逻辑**: 保存时序列化为 `{graph_json, nodes: [{node_key, node_type, config_json, ...}], transitions: [{from_node_key, to_node_key, condition_expr, ...}]}` 提交到后端
**自定义节点样式**: 每种节点类型使用不同的形状和颜色
- 开始节点: 圆形,绿色
- 结束节点: 圆形,红色
- 审批人节点: 矩形,蓝色
- 条件分支节点: 菱形,橙色
### 5.3 待办中心(`task-pending/index.vue`)
**模式**: 复杂列表页(参考 `order/index.vue`)
**筛选**: 流程名称、业务类型、发起时间范围
**列表字段**: 流程名称、业务类型、业务单号、发起人、发起时间、到达时间、操作
**操作**: 审批(打开审批弹窗)、查看详情
**审批弹窗**(`ApprovalDialog.vue`): 通过/驳回选择 + 审批意见输入框 + 查看流程图(只读模式,高亮当前节点)
### 5.4 已办中心(`task-completed/index.vue`)
**模式**: 标准列表页
**筛选**: 同待办中心 + 审批结果筛选(通过/驳回)
**列表字段**: 流程名称、业务类型、业务单号、发起人、审批结果、审批意见、审批时间
**操作**: 查看详情
---
## 6. 回调与业务集成
### 6.1 回调机制
引擎在以下事件触发 HTTP POST 回调到 `callback_url`:
**实例完成**:
```json
{
"event": "completed",
"instance_id": "inst_uuid",
"process_code": "agreement_payment",
"business_type": "agreement",
"business_id": "agr_uuid_123"
}
```
**实例驳回**:
```json
{
"event": "rejected",
"instance_id": "inst_uuid",
"process_code": "agreement_payment",
"business_type": "agreement",
"business_id": "agr_uuid_123",
"reject_comment": "费用异常,请核实"
}
```
### 6.2 业务模块集成步骤
1. 在流程配置页创建流程定义,发布版本
2. 业务模块在需要触发审批的地方调用 `POST /api/admin/workflow/instances`
3. 业务模块实现回调接口接收审批结果
4. 用户在待办中心处理审批任务
---
## 7. 安全与权限
- 所有API带JWT认证,租户隔离(tenant_no过滤)
- SQL审批人解析策略限制为只读SELECT,禁止DDL/DML
- 流程定义管理需要系统管理权限
- 待办/已办中心只展示当前用户的任务
- 审批操作只能操作 status=pending 且 assignee_user_id=当前用户 的任务
---
## 8. 已确认的约束
- 遵循项目公共字段规范(id→业务→tenant_no→...→del_flag)
- 软删除(del_flag 0/1)
- 默认排序(create_time DESC)
- Element Plus组件自动导入,不手动导入
- Fresh Mint主题色 #10b981
- label-position="top",.form-grid-2 布局
- 操作列固定右侧(2按钮260px,3按钮320px)
- 标题绿色竖条(需注册到App.vue白名单)