# 工作流模块设计文档 **模块**: 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/zkxw.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/zkxw.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白名单)