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
截图 seedweb-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)exclusiveGatewayapproverRole 选 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)exclusiveGatewaytaskResult 选通过 / 驳回分支
更新状态 (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_1svc_rule_routegw_approver无条件进入规则路由
gw_approvertask_manager_approve${approverRole == 'manager'}
gw_approvertask_hr_approve${approverRole == 'hr'}
task_manager_approve / task_hr_approvegw_result人工任务完成后进入结果判断
gw_resultsvc_set_approved${taskResult == 'approved'}
gw_resultsvc_set_rejected${taskResult == 'rejected'}
svc_set_approvedsvc_notify_approvedend_approved通过分支收口
svc_set_rejectedsvc_notify_rejectedend_rejected驳回分支收口

BPMN Designer 中的 wd_leave_approval 全节点画布

设计器:节点怎么配

流程图存为设计器 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 为主线时,设计器要验证四件事:

  1. 打开流程:从流程定义列表进入 wd_leave_approval,画布能还原 designerJson.nodes / designerJson.edges,节点 label 使用 label:zh-CN
  2. 配置节点:规则任务写 ruleCode / factsVars,用户任务写 formPageKey / formBinding / taskActions / slaKey,扩展节点写业务字段(modelCoderecordIdVareventCode)。
  3. 校验发布:保存前调用 POST /api/bpm/process-definitions/validate,发布走 POST /api/bpm/process-definitions/{pid}/deploy;plugin.jsonautoDeployProcesses: true 会在插件导入时自动发布。
  4. 导出可运行 BPMN:rule-task / record-update-task / notification-task 在后端转换为可执行的 serviceTask delegate;标准 userTask / gateway / event 保留 BPMN 语义。

设计器中选中 task_manager_approve 后的节点属性面板

设计器面板当前可见的是角色分派、审批模式、优先级和表单绑定入口;taskActionsformBindingslaKey 的完整绑定值以本节配置片段和运行时 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 命令,其 postActionswithdraw_process 关闭运行中的审批任务。

运行时核心场景

workflow-demo 的运行时不是只有一个 API 调用,而是页面、命令、流程实例和详情页联动:

场景入口关键契约
新建草稿/p/wd_leave_requestwd_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 tabbpm-panel 读取 wd_req_process_instance,展示状态、图、操作、历史
查看历史detail 的 approval_history tabnamed query wd_leave_request_approval_history,参数来自流程实例 id

任务工作台与转办

审批任务统一进入 /bpm/task-center。前端服务是 bpmWorkbenchService.ts,后端是 TaskController;文档和截图不要绕过这层 API。

工作台能力前端调用后端端点权限
待办 / 已办getTodoTasks / getCompletedTasksGET /api/bpm/tasks/todo / completedWORKFLOW_READ
查看任务详情getTaskDetailGET /api/bpm/tasks/{taskId}WORKFLOW_READ
通过 / 驳回approveTask / rejectTaskPOST /api/bpm/tasks/{taskId}/approve / rejectWORKFLOW_EXECUTE
领取claimTaskPOST /api/bpm/tasks/{taskId}/claimWORKFLOW_EXECUTE
委托delegateTaskPOST /api/bpm/tasks/{taskId}/delegateWORKFLOW_EXECUTE
转办transferTaskPOST /api/bpm/tasks/{taskId}/transferWORKFLOW_EXECUTE
加签 / 减签addSign / removeSignPOST /api/bpm/tasks/{taskId}/add-sign / remove-signWORKFLOW_ADMIN
回退rollbackTaskPOST /api/bpm/tasks/{taskId}/rollbackWORKFLOW_ADMIN
抄送ccTaskPOST /api/bpm/tasks/{taskId}/ccWORKFLOW_EXECUTE
批量处理batchProcessTasksPOST /api/bpm/workbench/batch-process-tasksWORKFLOW_EXECUTE

转办和委托要分开写:

  • 委托:delegateTask(taskId, targetUserId, comment) 会先校验当前用户是否可委托,再调用 Smart Engine 的 transferWithReason,并写 recordTaskDelegate 审计。
  • 转办:transferTask(taskId, targetUserId, comment) 直接转移任务办理人,并写 recordTaskTransfer 审计。截图时应选择任务行的更多菜单 → 「转办」,打开用户选择器与备注框。
  • 审批变量兜底:通过/驳回 API 即使前端没有显式传 taskResult,后端也会根据 taskActions.resultVariable/resultValue 注入,确保 ${taskResult == 'approved'} / ${taskResult == 'rejected'} 能命中。

任务中心中 wd_leave_approval 待办任务的更多菜单

任务中心的转办任务弹窗

打通规则引擎

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)见 纯配置 PluginPlugin 开发

跑起来后,从侧栏 请假 demo 进入:

  • 我的申请(/p/wd_leave_request)—— 列表里对某条草稿点「提交」,确认后即触发 wd:submit_leave_request、启动流程。
  • 请假余额(/p/wd_leave_balance)—— 前置校验用到的余额数据。
  • 任务中心 —— 找到对应 businessKey 的审批任务,点「通过 / 驳回」推进流程,并观察 SLA 状态。

任务中心中的 wd_leave_approval 待办任务

SLA 监控中 task_manager_approve 的 overdue 记录

截图推荐顺序:

  1. 先跑 docs/screenshot-seeds/seed_workflow_demo.mjs,保证有草稿、待办、已办和被驳回的申请。
  2. wd_leave_request_list 列表:能看到状态、提交入口和干净中文原因。
  3. wd_leave_request_detail 的 workflow_diagram tab:能看到流程状态、图、操作与历史。
  4. /bpm/task-center:先拍任务行,再拍更多菜单,最后拍「转办」弹窗。
  5. /bpm/sla-monitor:打开 overdue drill-down,确认 task_manager_approve / task_hr_approve 记录、deadline 与 remaining 状态。
  6. 抓 Rule/SLA 独立页需要的截图时,复用同一批实例和 businessKey

验证清单

把这条链路跑通,应当能逐一验证:

  1. 提交一条年假天数不足余额的申请,被 wd_leave_validation 挡下(流程不启动)。
  2. 提交 days < 3 的申请 → 路由到主管;days >= 3 → 路由到 HR(规则 + 网关生效)。
  3. 审批任务出现在任务中心,且按角色分派。
  4. 不在截止时间内处理,触发 SLA 预警 / 升级。
  5. 点「通过」→ wd_req_status 回写为 approved + 申请人收到通知;「驳回」→ rejected
  6. 审计轨迹记录 process_start + 规则 / 网关 / userTask 活动事件 + 审批操作。

后续步骤