BPM 端到端示例
BPMN Designer 讲设计器的节点与画布,BPM Workflows 讲流程与 Command 的关系。本页把这些概念接到一个可以真正跑起来的例子上:随开源演示栈提供的 workflow-demo 插件。
workflow-demo 是一个纯配置 + 一个轻量后端 jar 的开源插件(命名空间 wd),用一条「请假审批」业务流串起 BPM 的全部环节:
- 设计器:
wd_leave_approval流程图覆盖开始/结束事件、用户任务、排他网关,以及 AuraBoot 扩展的规则任务、记录更新任务、通知任务。 - 运行时:提交申请触发 Smart Engine 实例化流程,按图驱动任务分派与流转。
- 规则引擎:用 Drools 规则决定「谁来审批」,并在提交前做前置校验。
- SLA:给审批任务挂截止时间、预警与升级策略。
读完本页,你会知道这些环节在配置里长什么样,如何在本地把它跑起来,以及哪些脚本可复用来补 BPM/Rule/SLA 截图。
代码取证地图
本文只引用能在代码仓里 grep 到的对象。核对时从下面这些文件开始:
| 能力 | 事实源 |
|---|---|
| 插件入口 | plugins/workflow-demo/plugin.json |
| 流程图与节点 | plugins/workflow-demo/config/processes.json |
| 页面与表单 | plugins/workflow-demo/config/pages/wd_leave_request_*.json |
| 命令触发 | plugins/workflow-demo/config/commands.json |
| 规则配置 | plugins/workflow-demo/config/rules.json + plugins/workflow-demo/rules/*.drl |
| SLA 配置 | plugins/workflow-demo/config/sla.json |
| 任务工作台前端 | web-admin/app/plugins/core-bpm/services/bpmWorkbenchService.ts |
| 任务操作后端 | platform/src/main/java/com/auraboot/framework/bpm/controller/TaskController.java |
| 截图 seed | web-admin/scripts/seed-workflow-demo.mjs + 本仓 docs/screenshot-seeds/seed_workflow_demo.mjs |
演示场景:请假审批
一条请假申请从草稿到归档,要经过校验、按时长分派审批人、人工审批、回写状态、通知申请人。workflow-demo 把它建成一个流程定义 wd_leave_approval,绑定到模型 wd_leave_request,由命令 wd:submit_leave_request 触发。
草稿 (draft)
└─ wd:submit_leave_request
├─ 前置规则 wd_leave_validation 校验(余额 / 病假附件)
├─ 启动流程 wd_leave_approval(postActions.start_process)
└─ 状态流转 draft|rejected → submitted
└─ 流程按图运行:规则路由 → 网关 → 审批任务(带 SLA)
→ 结果网关 → 回写状态 → 通知 → 结束流程全貌
wd_leave_approval 的流程图(设计器中的 designerJson)用到了下面这些节点。它覆盖请假审批业务主线的全部节点;设计器 palette 里其它节点(如 HTTP serviceTask、receiveTask、callActivity、parallel / inclusive gateway、多实例 userTask)由 web-admin/tests/e2e/bpm-designer/* 补齐回归覆盖,不强行塞进这条业务流。
| 节点 | 类型(type) | 作用 |
|---|---|---|
开始 (start_1) | startEvent | 流程入口 |
路由规则 (svc_rule_route) | rule-task | 调用 Drools 规则 wd_leave_routing,产出 approverRole |
审批人分派 (gw_approver) | exclusiveGateway | 按 approverRole 选 manager / hr 分支 |
主管审批 (task_manager_approve) | userTask | 分派给角色 wd_manager,挂 SLA wd_manager_approve_sla |
HR 审批 (task_hr_approve) | userTask | 分派给角色 wd_hr,挂 SLA wd_hr_approve_sla |
审批结果 (gw_result) | exclusiveGateway | 按 taskResult 选通过 / 驳回分支 |
更新状态 (svc_set_approved / svc_set_rejected) | record-update-task | 回写 wd_req_status 字段 |
通知申请人 (svc_notify_approved / svc_notify_rejected) | notification-task | 发事件 wd_request_approved / wd_request_rejected |
审批通过 / 已驳回 (end_*) | endEvent | 流程出口 |
节点之间的边同样是配置的一部分,不是前端画布临时状态:
| 边 | 条件 |
|---|---|
start_1 → svc_rule_route → gw_approver | 无条件进入规则路由 |
gw_approver → task_manager_approve | ${approverRole == 'manager'} |
gw_approver → task_hr_approve | ${approverRole == 'hr'} |
task_manager_approve / task_hr_approve → gw_result | 人工任务完成后进入结果判断 |
gw_result → svc_set_approved | ${taskResult == 'approved'} |
gw_result → svc_set_rejected | ${taskResult == 'rejected'} |
svc_set_approved → svc_notify_approved → end_approved | 通过分支收口 |
svc_set_rejected → svc_notify_rejected → end_rejected | 驳回分支收口 |

设计器:节点怎么配
流程图存为设计器 JSON(节点 + 边 + 流程级 aura 策略),发布时编译成 BPMN 2.0 交给运行时。下面是几个关键节点在 designerJson.nodes 里的真实写法。
规则任务——用 ruleCode 引用一条规则,factsVars 声明从流程变量里取哪些字段作为事实:
{
"id": "svc_rule_route",
"type": "rule-task",
"data": {
"label:zh-CN": "路由规则",
"ruleCode": "wd_leave_routing",
"factsVars": "days,type"
}
}用户任务——config.assignee 声明分派策略(本例按角色),slaKey 把任务和一条 SLA 关联,taskActions 定义审批人能点的动作:
{
"id": "task_manager_approve",
"type": "userTask",
"data": {
"label:zh-CN": "主管审批",
"formPageKey": "wd_leave_request_detail",
"slaKey": "wd_manager_approve_sla",
"config": { "assignee": { "type": "role", "roleIds": ["wd_manager"] } },
"taskActions": [
{ "key": "approve", "type": "complete", "resultVariable": "taskResult", "resultValue": "approved" },
{ "key": "reject", "type": "complete", "resultVariable": "taskResult", "resultValue": "rejected", "requireComment": true }
]
}
}记录更新任务 / 通知任务——这是 AuraBoot 在标准 BPMN 之上提供的扩展节点,让流程不必写 serviceTask 胶水代码就能回写记录字段、发出业务事件:
{
"id": "svc_set_approved",
"type": "record-update-task",
"data": { "modelCode": "wd_leave_request", "recordIdVar": "recordId", "fieldName": "wd_req_status", "fieldValue": "approved" }
}边上挂条件表达式来分流。审批人分派网关的两条出边分别是 ${approverRole == 'manager'} 与 ${approverRole == 'hr'},结果网关用 ${taskResult == 'approved'} / ${taskResult == 'rejected'}。
设计器核心场景
以 workflow-demo 为主线时,设计器要验证四件事:
- 打开流程:从流程定义列表进入
wd_leave_approval,画布能还原designerJson.nodes/designerJson.edges,节点 label 使用label:zh-CN。 - 配置节点:规则任务写
ruleCode/factsVars,用户任务写formPageKey/formBinding/taskActions/slaKey,扩展节点写业务字段(modelCode、recordIdVar、eventCode)。 - 校验发布:保存前调用
POST /api/bpm/process-definitions/validate,发布走POST /api/bpm/process-definitions/{pid}/deploy;plugin.json里autoDeployProcesses: true会在插件导入时自动发布。 - 导出可运行 BPMN:rule-task / record-update-task / notification-task 在后端转换为可执行的
serviceTaskdelegate;标准 userTask / gateway / event 保留 BPMN 语义。

设计器面板当前可见的是角色分派、审批模式、优先级和表单绑定入口;taskActions、formBinding、slaKey 的完整绑定值以本节配置片段和运行时 API 验证为准。
运行时:Smart Engine
AuraBoot 内嵌 Smart Engine(AuraBoot 维护的 BPMN 引擎 fork)作为流程运行时。发布(deploy)后,流程实例由 Command Pipeline 触发——wd:submit_leave_request 命令的 postActions 在状态流转成功后启动流程,并把实例 id 写回记录字段 wd_req_process_instance:
{
"code": "wd:submit_leave_request",
"type": "state_transition",
"modelCode": "wd_leave_request",
"stateField": "wd_req_status",
"fromStates": ["draft", "rejected"],
"toState": "submitted",
"preActions": [
{
"type": "bpm:run-rule",
"ruleCode": "wd_leave_validation",
"contextLookup": [
{
"modelCode": "wd_leave_balance",
"filters": [
{ "field": "wd_bal_employee", "op": "=", "value": "${currentRecord.wd_req_applicant}" }
],
"exposeAs": "balance"
}
],
"facts": {
"type": "${currentRecord.wd_req_type}",
"days": "${currentRecord.wd_req_days}",
"balanceRemaining": "${balance.wd_bal_annual_remaining}",
"attachmentCount": "${currentRecord.wd_req_attachments.size}"
}
}
],
"postActions": [
{
"type": "start_process",
"processKey": "wd_leave_approval",
"businessKey": "${recordId}",
"variables": { "days": "${payload.wd_req_days}", "type": "${payload.wd_req_type}", "recordId": "${recordId}", "applicantUserId": "${payload.wd_req_applicant}" },
"storeInstanceIdIn": "wd_req_process_instance"
}
]
}同一条前置规则也挂在 wd:create_and_submit_leave_request 上,区别只是事实来源从 currentRecord.* 换成 payload.*。因此无论用户先保存草稿再提交,还是在表单里直接“创建并提交”,都会先执行 wd_leave_validation;规则返回 valid=false 时,命令失败、流程不启动,业务记录不会写入 wd_req_process_instance。
实例启动后,引擎按图推进:规则任务求值 → 网关选分支 → 创建审批任务并按角色分派 → 等人工完成 → 结果网关 → 回写状态 → 通知 → 结束。Command Pipeline 仍是数据变更的唯一可信源,Smart Engine 只负责编排「下一步由谁、在何时执行」。
流程定义与运行时通过 /api/bpm/* 暴露,关键端点:
| 操作 | 端点 |
|---|---|
| 校验流程 JSON(发布前) | POST /api/bpm/process-definitions/validate |
| 发布流程 | POST /api/bpm/process-definitions/{pid}/deploy |
| 挂起 / 恢复实例 | POST /api/bpm/process-definitions/{pid}/suspend …/resume |
| 待办 / 已办任务 | GET /api/bpm/tasks/todo …/completed |
| 审批通过 / 驳回 | POST /api/bpm/tasks/{taskId}/approve …/reject |
撤销走
wd:cancel_leave_request命令,其postActions用withdraw_process关闭运行中的审批任务。
运行时核心场景
workflow-demo 的运行时不是只有一个 API 调用,而是页面、命令、流程实例和详情页联动:
| 场景 | 入口 | 关键契约 |
|---|---|---|
| 新建草稿 | /p/wd_leave_request → wd_leave_request_form | 保存草稿按钮执行 wd:create_leave_request,状态为 draft |
| 新建并提交 | wd_leave_request_form 提交按钮 | 执行 wd:create_and_submit_leave_request,创建记录后立即启动 wd_leave_approval |
| 草稿提交 | 列表/详情页提交按钮 | 执行 wd:submit_leave_request,从 `draft |
| 撤销申请 | 详情页取消按钮 | 执行 wd:cancel_leave_request,从 `submitted |
| 查看实例 | wd_leave_request_detail 的 workflow_diagram tab | bpm-panel 读取 wd_req_process_instance,展示状态、图、操作、历史 |
| 查看历史 | detail 的 approval_history tab | named query wd_leave_request_approval_history,参数来自流程实例 id |
任务工作台与转办
审批任务统一进入 /bpm/task-center。前端服务是 bpmWorkbenchService.ts,后端是 TaskController;文档和截图不要绕过这层 API。
| 工作台能力 | 前端调用 | 后端端点 | 权限 |
|---|---|---|---|
| 待办 / 已办 | getTodoTasks / getCompletedTasks | GET /api/bpm/tasks/todo / completed | WORKFLOW_READ |
| 查看任务详情 | getTaskDetail | GET /api/bpm/tasks/{taskId} | WORKFLOW_READ |
| 通过 / 驳回 | approveTask / rejectTask | POST /api/bpm/tasks/{taskId}/approve / reject | WORKFLOW_EXECUTE |
| 领取 | claimTask | POST /api/bpm/tasks/{taskId}/claim | WORKFLOW_EXECUTE |
| 委托 | delegateTask | POST /api/bpm/tasks/{taskId}/delegate | WORKFLOW_EXECUTE |
| 转办 | transferTask | POST /api/bpm/tasks/{taskId}/transfer | WORKFLOW_EXECUTE |
| 加签 / 减签 | addSign / removeSign | POST /api/bpm/tasks/{taskId}/add-sign / remove-sign | WORKFLOW_ADMIN |
| 回退 | rollbackTask | POST /api/bpm/tasks/{taskId}/rollback | WORKFLOW_ADMIN |
| 抄送 | ccTask | POST /api/bpm/tasks/{taskId}/cc | WORKFLOW_EXECUTE |
| 批量处理 | batchProcessTasks | POST /api/bpm/workbench/batch-process-tasks | WORKFLOW_EXECUTE |
转办和委托要分开写:
- 委托:
delegateTask(taskId, targetUserId, comment)会先校验当前用户是否可委托,再调用 Smart Engine 的transferWithReason,并写recordTaskDelegate审计。 - 转办:
transferTask(taskId, targetUserId, comment)直接转移任务办理人,并写recordTaskTransfer审计。截图时应选择任务行的更多菜单 → 「转办」,打开用户选择器与备注框。 - 审批变量兜底:通过/驳回 API 即使前端没有显式传
taskResult,后端也会根据taskActions.resultVariable/resultValue注入,确保${taskResult == 'approved'}/${taskResult == 'rejected'}能命中。


打通规则引擎
workflow-demo 用两条 Drools 规则,演示规则引擎的两种接入位置。
前置校验(命令前)——wd_leave_validation(ruleType: VALIDATION)在 wd:submit_leave_request 启动流程之前跑,挡掉余额不足的年假、缺附件的长病假:
{
"ruleCode": "wd_leave_validation",
"ruleType": "VALIDATION",
"outputSchema": { "type": "object", "properties": { "valid": { "type": "boolean" }, "reason": { "type": "string" } } },
"ruleContentFile": "rules/wd_leave_validation.drl"
}流程内路由(rule-task)——wd_leave_routing(ruleType: CONDITION)被流程里的 svc_rule_route 节点调用,根据请假天数产出 approverRole,交给后面的排他网关选分支:
rule "route_short_to_manager"
when
$req: Map( ((Number) this["days"]).doubleValue() < 3.0 )
then
((Map) $req.get("_ruleResult")).put("approverRole", "manager");
end
rule "route_long_to_hr"
when
$req: Map( ((Number) this["days"]).doubleValue() >= 3.0 )
then
((Map) $req.get("_ruleResult")).put("approverRole", "hr");
end规则不会被编译进 BPMN——流程里只存 ruleCode 引用,运行到 rule-task 时引擎回调规则服务求值。规则本身可独立通过 POST /api/bpm/rules/{pid}/evaluate 试算,方便和流程解耦地调试。
打通 SLA
两个审批任务各挂一条 SLA(config/sla.json),给审批加上时效问责:截止时间、预警、超时升级、挂起策略。
{
"slaKey": "wd_manager_approve_sla",
"name:zh-CN": "主管审批 SLA",
"targetType": "NODE",
"targetKey": "task_manager_approve",
"processKey": "wd_leave_approval",
"deadlineMode": "FIXED",
"deadlineValue": "PT30S",
"warningRules": [ { "beforeSeconds": 10, "eventType": "sla_warning", "notifyTargets": ["assignee"] } ],
"suspendPolicy": "pause",
"escalationTargetType": "role_parent",
"escalationTargetValue": "wd_manager",
"enabled": true
}几个字段的含义:
targetType: NODE+targetKey—— SLA 绑定到流程里的某个节点(也支持PROCESS/TASK)。deadlineMode: FIXED+deadlineValue—— 用 ISO-8601 时长定截止时间。demo 用PT30S(30 秒)是为了让 E2E 能快速观察升级;生产应改成PT24H这类真实值。warningRules—— 配置层表达预警意图;当前硬验证以 SLA record 的running/overdue状态为准,详见 BPM SLA 示例。suspendPolicy: pause—— 流程被挂起时暂停计时,恢复后接着算,不会把挂起时间算成超时。escalationTargetType / escalationTargetValue—— 超时后升级给谁。
任务的 SLA 状态在「任务中心」(Task Center)里可见;运行中的 SLA 记录会随任务领取、完成、挂起/恢复而更新。
自己跑起来
workflow-demo 默认随开源演示环境一起导入。手动导入与撒数据:
# 1) 导入插件(纯配置 + 后端 jar;首次需先 build backend jar)
aura plugin-import plugins/workflow-demo --conflict-strategy overwrite --yes
# 2) 在产品仓内通过产品 API 撒演示数据(请假余额 + 申请 + 任务历史)
node scripts/seed-workflow-demo.mjs
# 3) 在网站仓内复用同一入口(方便截图任务统一调用)
node docs/screenshot-seeds/seed_workflow_demo.mjs --base-url=http://127.0.0.1:5173 --min-requests=12导入机制(plugin.json / resourceDirs / 后端 jar)见 纯配置 Plugin 与 Plugin 开发。
跑起来后,从侧栏 请假 demo 进入:
- 我的申请(
/p/wd_leave_request)—— 列表里对某条草稿点「提交」,确认后即触发wd:submit_leave_request、启动流程。 - 请假余额(
/p/wd_leave_balance)—— 前置校验用到的余额数据。 - 任务中心 —— 找到对应
businessKey的审批任务,点「通过 / 驳回」推进流程,并观察 SLA 状态。


截图推荐顺序:
- 先跑
docs/screenshot-seeds/seed_workflow_demo.mjs,保证有草稿、待办、已办和被驳回的申请。 - 抓
wd_leave_request_list列表:能看到状态、提交入口和干净中文原因。 - 抓
wd_leave_request_detail的 workflow_diagram tab:能看到流程状态、图、操作与历史。 - 抓
/bpm/task-center:先拍任务行,再拍更多菜单,最后拍「转办」弹窗。 - 抓
/bpm/sla-monitor:打开 overdue drill-down,确认task_manager_approve/task_hr_approve记录、deadline 与 remaining 状态。 - 抓 Rule/SLA 独立页需要的截图时,复用同一批实例和
businessKey。
验证清单
把这条链路跑通,应当能逐一验证:
- 提交一条年假天数不足余额的申请,被
wd_leave_validation挡下(流程不启动)。 - 提交
days < 3的申请 → 路由到主管;days >= 3→ 路由到 HR(规则 + 网关生效)。 - 审批任务出现在任务中心,且按角色分派。
- 不在截止时间内处理,触发 SLA 预警 / 升级。
- 点「通过」→
wd_req_status回写为approved+ 申请人收到通知;「驳回」→rejected。 - 审计轨迹记录 process_start + 规则 / 网关 / userTask 活动事件 + 审批操作。