scaffold-bpm 业务流程管理模块
模块概述
scaffold-bpm 是 Scaffold v2 平台的业务流程管理(BPM)模块,提供流程定义、流程实例、任务管理、流程可视化、统计分析等功能。支持通过飞书、钉钉、企业微信三大外部平台的审批集成。
模块采用自研流程引擎,不依赖 Activiti/Flowable 等第三方引擎,业务模块通过 businessUrl + callbackUrl 与 BPM 交互。流程状态变更时通过 Spring 事件机制(ProcessCallbackEvent)异步回调业务模块,最多重试 3 次。
功能列表
- 流程定义管理:创建、编辑、发布、停用、激活、版本管理、复制
- 流程定义验证:JSON 格式验证、条件表达式模板、条件表达式测试
- 流程实例管理:启动、挂起、恢复、终止、完成、转交、进度查询
- 任务管理:认领、完成、转交、委派、驳回、撤回、加签、优先级设置
- 任务评论:添加、查询、标记已读
- 流程变量:创建、更新、批量创建、按实例查询、按 key 查询
- 流程可视化:流程定义可视化、流程实例可视化、流程轨迹
- 统计分析:流程统计、任务统计、趋势分析、用户效率排名、分类统计、瓶颈分析、超时统计
- 多平台监控:飞书/钉钉/企业微信平台健康状态、连接测试、统计数据
- 外部审批集成:飞书、钉钉、企业微信审批实例同步(Webhook 回调)
核心组件
实体
| 实体 |
表名 |
说明 |
| ProcessDefinition |
bpm_process_definition |
流程定义 |
| ProcessInstance |
bpm_process_instance |
流程实例 |
| Task |
bpm_task |
任务 |
| TaskComment |
bpm_task_comment |
任务评论 |
| ProcessVariable |
bpm_process_variable |
流程变量 |
| ProcessHistory |
bpm_process_history |
流程历史 |
状态流转
流程定义:DRAFT(草稿) -> PUBLISHED(已发布) -> INACTIVE(已停用)
流程实例:RUNNING(运行中) -> COMPLETED(已完成) / TERMINATED(已终止) / SUSPENDED(已挂起)
任务:PENDING(待处理) -> CLAIMED(已认领) -> IN_PROGRESS(处理中) -> COMPLETED(已完成)
注意:BPM 模块的状态枚举使用大写英文常量,为多态状态机,不遵循布尔语义规范。
服务层
| 服务 |
说明 |
| ProcessDefinitionService |
流程定义 CRUD、发布/停用/激活、版本管理、复制 |
| ProcessInstanceService |
流程实例生命周期管理、变量操作、历史记录查询 |
| TaskService |
任务操作、待办/已办/抄送列表、任务统计 |
| TaskCommentService |
任务评论管理 |
| ProcessVariableService |
流程变量管理 |
| ProcessFlowService |
流程可视化数据生成 |
| ProcessCallbackService |
流程回调通知(Spring 事件机制) |
| BpmStatisticsService |
统计分析 |
| PlatformMonitorService |
多平台监控 |
外部平台适配器
| 适配器 |
配置前缀 |
说明 |
| FeishuAdapter |
scaffold.feishu |
飞书审批集成 |
| DingTalkAdapter |
scaffold.dingtalk |
钉钉审批集成 |
| WeChatWorkAdapter |
scaffold.wechatwork |
企业微信审批集成 |
配置参数
飞书集成(scaffold.feishu)
| 参数 |
类型 |
默认值 |
说明 |
| enabled |
boolean |
false |
是否启用飞书集成 |
| appId |
String |
- |
飞书应用 ID |
| appSecret |
String |
- |
飞书应用秘钥 |
| baseUrl |
String |
https://open.feishu.cn |
飞书 API 基础 URL |
| approvalAppId |
String |
- |
审批应用 ID |
| webhookUrl |
String |
- |
Webhook 回调地址 |
| encryptKey |
String |
- |
加密密钥 |
| signKey |
String |
- |
签名密钥 |
钉钉集成(scaffold.dingtalk)
| 参数 |
类型 |
默认值 |
说明 |
| enabled |
boolean |
false |
是否启用钉钉集成 |
| appKey |
String |
- |
钉钉应用 AppKey |
| appSecret |
String |
- |
钉钉应用 AppSecret |
| corpId |
String |
- |
企业 CorpId |
| webhookUrl |
String |
- |
Webhook 回调地址 |
| secret |
String |
- |
消息签名密钥 |
| approvalAppId |
String |
- |
审批应用 ID |
| baseUrl |
String |
https://oapi.dingtalk.com |
钉钉 API 基础 URL |
企业微信集成(scaffold.wechatwork)
| 参数 |
类型 |
默认值 |
说明 |
| enabled |
boolean |
false |
是否启用企业微信集成 |
| corpId |
String |
- |
企业 CorpID |
| corpSecret |
String |
- |
应用 Secret |
| agentId |
String |
- |
应用 AgentId |
| approvalEnabled |
boolean |
false |
是否启用审批 |
| messageEnabled |
boolean |
false |
是否启用消息通知 |
| messageType |
String |
markdown |
消息通知类型(text/markdown/textcard) |
| callbackUrl |
String |
- |
回调 URL |
| callbackToken |
String |
- |
回调 Token |
| callbackAesKey |
String |
- |
回调 EncodingAESKey |
API 接口列表
流程定义管理(/v1/bpm/process-definition)
| 方法 |
路径 |
说明 |
| POST |
/page |
分页查询流程定义 |
| GET |
/get?id={id} |
根据 ID 查询流程定义 |
| POST |
/create |
创建流程定义 |
| POST |
/update |
更新流程定义 |
| POST |
/delete?id={id} |
删除流程定义 |
| POST |
/publish?id={id} |
发布流程定义 |
| POST |
/deactivate?id={id} |
停用流程定义 |
| POST |
/activate?id={id} |
激活流程定义 |
| GET |
/getLatestByName?name={name} |
根据名称查询最新版本 |
| GET |
/getAllByName?name={name} |
根据名称查询所有版本 |
| POST |
/copy?id={id}&newName={name} |
复制流程定义 |
| GET |
/getVersions?name={name} |
获取版本列表 |
| POST |
/validate |
验证流程定义 JSON |
| GET |
/condition-templates |
获取条件模板列表 |
| POST |
/test-condition |
测试条件表达式 |
流程实例管理(/v1/bpm/process-instance)
| 方法 |
路径 |
说明 |
| POST |
/page |
分页查询流程实例 |
| GET |
/get?id={id} |
根据 ID 查询流程实例 |
| GET |
/getByProcessNo?processNo={no} |
根据编号查询流程实例 |
| POST |
/create |
创建流程实例(启动流程) |
| POST |
/update |
更新流程实例 |
| POST |
/delete?id={id} |
删除流程实例 |
| POST |
/terminate?id={id}&reason={reason} |
终止流程实例 |
| POST |
/suspend?id={id} |
挂起流程实例 |
| POST |
/resume?id={id} |
恢复流程实例 |
| GET |
/getVariables?id={id} |
获取流程变量 |
| POST |
/setVariables?id={id} |
设置流程变量 |
| GET |
/getCurrentNode?id={id} |
获取当前节点 |
| GET |
/getHistory?id={id} |
获取历史记录 |
| GET |
/getProgress?id={id} |
获取流程进度(百分比) |
| POST |
/transfer?id={id}&targetUserId={uid} |
转交流程实例 |
| POST |
/complete?id={id}&comment={c} |
完成流程实例 |
| GET |
/getStatistics |
获取统计信息 |
| GET |
/getStatisticsByInitiator?initiatorId={uid} |
按发起人统计 |
| GET |
/getPendingInstances?limit={n} |
获取待处理实例 |
| GET |
/queryByBusiness?businessKey={k}&businessType={t} |
根据业务 key 查询 |
任务管理(/v1/bpm/task)
| 方法 |
路径 |
说明 |
| POST |
/page |
分页查询任务 |
| GET |
/get?id={id} |
根据 ID 查询任务 |
| GET |
/getTodoList?userId={uid} |
查询待办任务 |
| GET |
/getDoneList?userId={uid} |
查询已办任务 |
| GET |
/getCopyList?userId={uid} |
查询抄送任务 |
| POST |
/claim |
认领任务 |
| POST |
/complete |
完成任务 |
| POST |
/transfer |
转交任务 |
| POST |
/delegate?taskId={id}&targetUserId={uid} |
委派任务 |
| POST |
/reject?taskId={id}&comment={c} |
驳回任务 |
| POST |
/withdraw?taskId={id}&reason={r} |
撤回任务 |
| POST |
/delete?id={id} |
删除任务 |
| POST |
/batchDelete |
批量删除任务 |
| GET |
/getByProcessInstanceId?processInstanceId={id} |
按流程实例查任务 |
| GET |
/getCountStatistics?userId={uid} |
获取任务数量统计 |
| POST |
/setPriority?taskId={id}&priority={p} |
设置优先级 |
| POST |
/addComment?taskId={id}&comment={c} |
添加评论 |
| GET |
/getComments?taskId={id} |
获取评论列表 |
| POST |
/addSignatory?taskId={id}&type={t} |
加签任务 |
任务评论(/v1/bpm/task-comment)
| 方法 |
路径 |
说明 |
| POST |
/add |
添加评论 |
| GET |
/list?taskId={id} |
获取评论列表 |
| GET |
/get?commentId={id} |
获取评论详情 |
| POST |
/delete?commentId={id} |
删除评论 |
| POST |
/mark-read?taskId={id}&userId={uid} |
标记已读 |
流程变量(/v1/bpm/process-variable)
| 方法 |
路径 |
说明 |
| POST |
/page |
分页查询变量 |
| GET |
/{id} |
根据 ID 获取变量 |
| GET |
/process-instance/{processInstanceId} |
按流程实例获取所有变量 |
| GET |
/value/{processInstanceId}/{variableKey} |
获取指定变量值 |
| POST |
/create |
创建变量 |
| POST |
/batch-create?processInstanceId={id}&scope={s} |
批量创建变量 |
| POST |
/set-variable?processInstanceId={id}&variableKey={k} |
设置变量值 |
| POST |
/update |
更新变量 |
| POST |
/delete/{id} |
删除变量 |
| POST |
/delete-by-instance/{processInstanceId} |
按实例删除所有变量 |
| POST |
/batch-delete |
批量删除变量 |
流程可视化(/v1/bpm/flow)
| 方法 |
路径 |
说明 |
| GET |
/definition/{definitionId} |
获取流程定义可视化数据 |
| GET |
/instance/{instanceId} |
获取流程实例可视化数据 |
| GET |
/instance/byProcessNo?processNo={no} |
按编号获取实例可视化 |
| GET |
/track/{instanceId} |
获取流程实例轨迹 |
统计分析(/v1/bpm/statistics)
| 方法 |
路径 |
说明 |
| GET |
/process?period={p} |
流程统计(today/week/month) |
| GET |
/task?period={p} |
任务统计 |
| GET |
/process-trend?period={p} |
流程趋势 |
| GET |
/user-ranking?period={p}&limit={n} |
用户效率排名 |
| GET |
/category?period={p} |
分类统计 |
| GET |
/bottleneck?period={p} |
瓶颈节点分析 |
| GET |
/overdue?period={p} |
超时任务统计 |
多平台监控(/v1/bpm/platform-monitor)
| 方法 |
路径 |
说明 |
| GET |
/dashboard |
综合监控仪表盘 |
| GET |
/status |
所有平台健康状态 |
| GET |
/status/{platform} |
指定平台健康状态(FEISHU/DINGTALK/WECHAT) |
| GET |
/test-connection/{platform} |
测试平台连接 |
| GET |
/statistics/{platform} |
平台统计数据 |
飞书集成(/v1/bpm/feishu)
| 方法 |
路径 |
说明 |
| GET |
/config |
获取飞书配置 |
| POST |
/config |
更新飞书配置 |
| POST |
/test-connection |
测试连接 |
| GET |
/templates |
获取审批模板列表 |
| GET |
/templates/{templateId} |
获取审批模板详情 |
| POST |
/templates |
创建审批模板 |
| GET |
/user/list |
获取飞书用户列表 |
| POST |
/message/send |
发送飞书消息 |
| POST |
/approval/create |
创建飞书审批实例 |
| GET |
/approval/{approvalId} |
获取飞书审批详情 |
| GET |
/stats |
获取集成统计 |
飞书 Webhook(/api/v1/bpm/feishu/webhook)
| 方法 |
路径 |
说明 |
| POST |
/approval/status |
接收审批状态变更事件 |
| POST |
/task/assign |
接收任务分配事件 |
| GET |
/verify?echo_str={str} |
Webhook URL 验证 |
钉钉集成(/v1/bpm/dingtalk)
| 方法 |
路径 |
说明 |
| GET |
/config |
获取钉钉配置 |
| POST |
/config |
更新钉钉配置 |
| POST |
/test-connection |
测试连接 |
| POST |
/template/page |
分页查询审批模板 |
| POST |
/sync |
同步流程到钉钉 |
| GET |
/instance/{dingtalkInstanceId} |
获取钉钉审批实例详情 |
| POST |
/instance/{dingtalkInstanceId}/open |
打开钉钉审批实例 |
| GET |
/stats |
获取集成统计 |
钉钉 Webhook(/api/v1/bpm/dingtalk/webhook)
| 方法 |
路径 |
说明 |
| POST |
/approval/status |
接收审批状态变更事件 |
| POST |
/message |
接收消息推送事件 |
| GET |
/health |
健康检查 |
企业微信集成(/v1/bpm/wechat)
| 方法 |
路径 |
说明 |
| GET |
/config |
获取企业微信配置 |
| POST |
/config |
更新配置 |
| POST |
/test-connection |
测试连接 |
| POST |
/template/page |
查询审批模板 |
| POST |
/sync |
同步流程到企业微信 |
| GET |
/instance/{wechatWorkInstanceId} |
获取审批实例详情 |
| POST |
/instance/{wechatWorkInstanceId}/open |
打开审批实例 |
| GET |
/stats |
获取集成统计 |
| POST |
/message/send |
发送企业微信消息 |
企业微信 Webhook(/api/v1/bpm/wechat/webhook)
| 方法 |
路径 |
说明 |
| POST |
/approval/status |
接收审批状态变更事件 |
| POST |
/approval/task |
接收审批任务事件 |
| POST |
/verify |
回调 URL 验证 |
业务模块集成方式
业务模块与 BPM 通过以下机制交互:
1. 启动流程
业务模块调用 ProcessInstanceService.create(),传入 ProcessInstanceCreateDTO,其中包含:
businessKey:业务数据 ID
businessType:业务类型编码(如 leave、purchase)
businessUrl:业务表单 URL(如 /leave/detail/456),供审批人查看
callbackUrl:流程状态变更时回调业务模块的 URL
2. 接收回调
BPM 在流程状态变更(完成/终止)时通过 ProcessCallbackService 发布 ProcessCallbackEvent。回调 payload 包含 processInstanceId、processNo、businessKey、businessType、status、action、comment。
3. 查询状态
业务模块可通过 GET /v1/bpm/process-instance/queryByBusiness 根据业务 key 查询流程状态。
注意事项
- 流程定义 JSON 通过前端树格式设计器生成,后端使用
FlowValidator 进行验证
- 条件表达式使用
ConditionEvaluator 执行,支持 SpEL 风格的表达式(如 amount > 10000)
- 任务加签支持前加签(BEFORE)和后加签(AFTER)两种方式
- 外部平台适配器(飞书/钉钉/企业微信)当前为框架实现,部分 API 方法有 TODO 标记待完善
- Webhook 回调路径使用
/api/v1/bpm/ 前缀(与内部 API 的 /v1/bpm/ 前缀区分),需在 Nginx/安全配置中放行
- 状态枚举:流程定义、流程实例、任务的状态枚举使用大写英文常量,为多态状态机,不遵循布尔语义规范
待完善功能
- 飞书 Webhook 中的签名验证逻辑当前跳过验证(开发模式),需实现 HMAC-SHA256 验签
- 飞书适配器的审批状态同步和任务分配逻辑(syncApprovalInstanceStatus、handleTaskAssignment)标记为 TODO
- 钉钉适配器的审批开始/完成/拒绝事件中的 BPM 引擎集成标记为 TODO(processInstanceService 调用被注释)
- 钉钉任务变更事件中的任务创建/完成/终止逻辑标记为 TODO
- 企业微信 Webhook 控制器仅在
scaffold.wechatwork.enabled=true 时激活