Camunda 7多实例任务审批规则实战从请假流程看会签、或签与比例签想象一下这样的场景公司市场部的小张需要申请一周的年假按照公司规定这个请假申请需要经过部门经理、HR主管和分管副总的三重审批。但问题来了——这三位领导是必须全部同意才能通过还是只要其中任意一人同意即可又或者需要超过半数同意这些不同的审批规则正是Camunda工作流引擎中多实例任务Multi-Instance Task的典型应用场景。对于刚接触Camunda的开发者来说理解会签、或签和比例签这些概念可能有些抽象。本文将通过一个完整的请假审批流程示例带你深入理解这三种审批规则的实际应用。我们将从业务需求出发反向推导技术配置重点分析不同规则下Assignee、Collection和Completion Condition的关键差异并提供可直接运行的流程定义XML和Java测试代码。1. 业务场景分析与技术映射在开始编码之前我们需要先明确业务需求与技术实现的对应关系。以请假流程为例常见的审批规则有三种会签全体通过所有审批人必须全部同意请假申请才能通过。适用于重要决策场景如高管休假或长期病假审批。或签一人通过任意一位审批人同意即可通过。适用于紧急情况或简单事务审批如短时请假。比例签多数通过达到特定比例的审批人同意即可通过如超过50%。适用于需要民主决策但又不必全体同意的场景。在Camunda中这三种规则都通过多实例用户任务(Multi-Instance User Task)实现核心区别在于完成条件(Completion Condition)的配置。以下是技术实现的关键要素对照表要素会签或签比例签完成条件表达式${nrOfCompletedInstances nrOfInstances}${nrOfCompletedInstances 1}${nrOfCompletedInstances/nrOfInstances 0.5}业务语义必须全部同意任意一人同意即可超过半数同意适用场景高风险决策低风险常规审批中等重要性决策2. 流程定义设计与XML配置让我们构建一个包含三种审批规则的完整请假流程。流程包含四个主要节点请假申请提交发起人节点或签审批节点一人通过即可比例签审批节点超过30%通过会签审批节点全部通过对应的BPMN XML配置如下bpmn:process idleave_approval isExecutabletrue !-- 发起人节点 -- bpmn:userTask idsubmit_leave name提交请假申请 camunda:assignee${initiator} bpmn:incomingStartEvent_1/bpmn:incoming bpmn:outgoingSequenceFlow_1/bpmn:outgoing /bpmn:userTask !-- 或签审批节点 -- bpmn:userTask idor_approval name或签审批 camunda:assignee${approver} bpmn:multiInstanceLoopCharacteristics camunda:collection${orApprovers} camunda:elementVariableapprover bpmn:completionCondition ${nrOfCompletedInstances 1} /bpmn:completionCondition /bpmn:multiInstanceLoopCharacteristics /bpmn:userTask !-- 比例签审批节点 -- bpmn:userTask idratio_approval name比例签审批 camunda:assignee${approver} bpmn:multiInstanceLoopCharacteristics camunda:collection${ratioApprovers} camunda:elementVariableapprover bpmn:completionCondition ${nrOfCompletedInstances/nrOfInstances 0.3} /bpmn:completionCondition /bpmn:multiInstanceLoopCharacteristics /bpmn:userTask !-- 会签审批节点 -- bpmn:userTask idall_approval name会签审批 camunda:assignee${approver} bpmn:multiInstanceLoopCharacteristics camunda:collection${allApprovers} camunda:elementVariableapprover bpmn:completionCondition ${nrOfCompletedInstances nrOfInstances} /bpmn:completionCondition /bpmn:multiInstanceLoopCharacteristics /bpmn:userTask /bpmn:process关键配置说明camunda:collection指定审批人列表变量camunda:elementVariable定义当前审批人变量completionCondition使用表达式定义完成条件3. Java实现与测试案例下面我们通过Java代码部署流程定义并测试不同审批场景RestController RequestMapping(/leave) public class LeaveApprovalController { Autowired private RuntimeService runtimeService; Autowired private TaskService taskService; // 启动请假流程 PostMapping(/start) public String startProcess(RequestBody LeaveRequest request) { MapString, Object variables new HashMap(); // 设置审批人列表 variables.put(orApprovers, Arrays.asList(manager1, manager2)); variables.put(ratioApprovers, Arrays.asList(hr1, hr2, hr3)); variables.put(allApprovers, Arrays.asList(vp1, vp2, vp3)); variables.put(initiator, request.getApplicantId()); ProcessInstance instance runtimeService.startProcessInstanceByKey( leave_approval, request.getBusinessKey(), variables ); return instance.getId(); } // 完成任务审批 PostMapping(/complete) public void completeTask(RequestBody ApprovalRequest request) { MapString, Object taskVariables new HashMap(); taskVariables.put(approved, request.isApproved()); taskService.complete(request.getTaskId(), taskVariables); } }测试不同审批规则时需要注意以下行为差异或签测试场景两个审批人(manager1, manager2)预期任意一人审批通过后其他待审批任务自动取消验证SQLSELECT * FROM ACT_RU_TASK观察任务状态变化比例签测试场景三个审批人(hr1, hr2, hr3)设置通过比例为30%预期一人同意不足(33%)两人同意则通过(66%)关键日志查看nrOfCompletedInstances值变化会签测试场景三个审批人(vp1, vp2, vp3)预期必须全部审批通过任一拒绝则流程终止异常处理需要在ServiceTask中添加边界事件处理拒绝情况4. 高级配置与性能优化在实际企业应用中我们还需要考虑以下高级配置和优化点4.1 并行与串行执行模式多实例任务支持两种执行模式并行(parallel)默认模式所有审批任务同时创建串行(sequential)按顺序逐个创建审批任务配置示例bpmn:multiInstanceLoopCharacteristics camunda:collection${approvers} camunda:elementVariableapprover isSequentialtrue ... /bpmn:multiInstanceLoopCharacteristics4.2 动态审批人分配审批人列表可以通过表达式动态获取camunda:collection${approvalService.getApprovers(execution)}对应的Java服务类Component public class ApprovalService { public ListString getApprovers(DelegateExecution execution) { String department (String) execution.getVariable(department); // 根部门返回不同的审批人列表 return approverRepository.findByDepartment(department); } }4.3 性能优化建议当审批人数量较多时如超过20人需要考虑以下优化措施批量任务创建// 在流程引擎配置中设置批量大小 processEngineConfiguration.setBatchSize(10);异步延续bpmn:userTask idmass_approval camunda:asyncBeforetrue bpmn:multiInstanceLoopCharacteristics.../ /bpmn:userTask历史级别配置# 适当降低历史记录级别 camunda.history.levelaudit5. 常见问题排查指南在实际开发中可能会遇到以下典型问题问题1审批任务没有按预期创建或完成排查步骤检查collection变量是否正确注入验证表达式语法特别是比较运算符查看ACT_RU_TASK表确认任务是否创建问题2完成条件不生效解决方案确保使用正确的实例计数变量// 正确写法 ${nrOfCompletedInstances 1} // 错误写法缺少Instances后缀 ${nrOfCompleted 1}问题3审批人变量传递错误调试方法在任务监听器中打印变量execution.getVariables().forEach((k,v) - System.out.println(k v));检查elementVariable名称是否与Assignee表达式一致问题4历史记录不完整配置调整process idleave_approval camunda:historyTimeToLive90 ... /process通过这个请假审批流程的完整示例相信你已经掌握了Camunda中多实例任务的三种审批规则实现方式。在实际项目中可以根据业务需求灵活组合这些模式构建出既符合业务流程又高效可靠的审批系统。