352 lines
13 KiB
Markdown
352 lines
13 KiB
Markdown
# 工作流模块设计文档
|
||
|
||
**模块**: 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白名单)
|