Flowable会签实战:从“按比例通过”到“一票否决”,4种业务场景的BPMN配置详解

Flowable会签实战:从“按比例通过”到“一票否决”,4种业务场景的BPMN配置详解 Flowable会签实战从“按比例通过”到“一票否决”4种业务场景的BPMN配置详解在企业流程管理中会签机制的设计往往直接关系到决策效率与风险控制。想象这样一个场景某跨国公司的产品上线流程需要市场、法务、技术三个部门负责人审批但规则是任意两人同意即可推进——这种看似简单的需求背后却需要精确的流程引擎配置。本文将深入解析Flowable中四种典型会签模式的BPMN实现方案让你掌握从基础配置到复杂条件的完整实现路径。1. 会签机制的核心原理与多实例任务Flowable的会签功能本质上是基于BPMN 2.0规范的**多实例任务(Multi-instance Task)**特性实现的。与普通用户任务不同多实例任务会在运行时动态创建多个任务实例这些实例可以并行或顺序执行。1.1 多实例任务的关键属性在BPMN XML中多实例任务通过multiInstanceLoopCharacteristics元素定义其核心配置参数包括userTask idreviewTask name会签审批 multiInstanceLoopCharacteristics isSequentialfalse flowable:collection${approverList} flowable:elementVariableapprover completionCondition${nrOfCompletedInstances 2}/completionCondition /multiInstanceLoopCharacteristics /userTaskisSequential控制实例执行方式false表示并行执行典型会签场景true表示顺序执行适用于层级审批collection指定参与者集合的表达式elementVariable单个实例的参与者变量名1.2 内置流程变量解析Flowable在执行多实例任务时会自动生成三个关键变量变量名描述典型用法示例nrOfInstances总实例数${nrOfInstances}nrOfCompletedInstances已完成实例数${nrOfCompletedInstances 3}nrOfActiveInstances当前活跃实例数${nrOfActiveInstances 1}提示这些变量可在completionCondition中直接引用无需额外声明2. 按数量通过的会签实现当业务规则要求至少N人同意时这种配置最为常见。例如技术方案评审需要3位专家中至少2位认可。2.1 基础配置方案completionCondition ${nrOfCompletedInstances 2} /completionCondition这种写法简单直接但存在一个潜在问题它无法区分同意和拒绝的实例。更完善的实现需要结合任务结果变量completionCondition ${approveCount 2 || rejectCount 1} /completionCondition2.2 完整实现案例以下是包含结果统计的完整配置userTask idtechReview name技术方案评审 extensionElements flowable:taskListener eventcomplete classorg.flowable.approval.CountApprovalResultListener/ /extensionElements multiInstanceLoopCharacteristics isSequentialfalse flowable:collection${expertGroup} flowable:elementVariablereviewer completionCondition ${approveCount 2 or rejectCount 1} /completionCondition /multiInstanceLoopCharacteristics /userTask对应的监听器实现public class CountApprovalResultListener implements TaskListener { Override public void notify(DelegateTask task) { Boolean approved (Boolean) task.getVariable(approved); ExecutionEntity execution (ExecutionEntity) task.getExecution(); Integer approveCount (Integer) execution.getVariable(approveCount); Integer rejectCount (Integer) execution.getVariable(rejectCount); if(approved) { execution.setVariable(approveCount, approveCount ! null ? approveCount 1 : 1); } else { execution.setVariable(rejectCount, rejectCount ! null ? rejectCount 1 : 1); } } }3. 按比例通过的会签实现金融行业的风险评审常常要求超过70%委员同意这种场景需要计算完成比例。与按数量通过不同比例计算需要动态判断总实例数。3.1 数学表达式配置completionCondition ${nrOfCompletedInstances / nrOfInstances 0.7} /completionCondition这种写法虽然简洁但在实际业务中往往需要结合审批结果。更健壮的实现方式completionCondition ![CDATA[ ${approveCount / nrOfInstances 0.7 || rejectCount / nrOfInstances 0.3} ]] /completionCondition3.2 动态阈值处理某些业务场景可能需要根据参与人数动态调整通过比例。例如5人以下需要全票通过5-10人需要80%同意10人以上需要2/3多数这种复杂逻辑可以通过Groovy脚本实现completionCondition flowable:script scriptLanguagegroovy ![CDATA[ def threshold nrOfInstances 5 ? 1.0 : nrOfInstances 10 ? 0.8 : 0.6667 approveCount / nrOfInstances threshold ]] /flowable:script /completionCondition4. 一票否决制的实现在合规审查等高敏感场景中常见一人反对即终止的规则。这种配置看似简单实则需要注意几个关键点。4.1 基础否决逻辑completionCondition ${rejectCount 0} /completionCondition这种配置下只要出现一个拒绝就会立即终止整个会签。但实际业务中我们可能希望收集所有已开始的审批意见出现否决时立即终止未开始的实例记录完整的决策过程4.2 增强型否决实现userTask idlegalReview name法务合规审查 multiInstanceLoopCharacteristics isSequentialfalse flowable:collection${legalTeam} flowable:elementVariablereviewer completionCondition ${rejectCount 0 or nrOfCompletedInstances nrOfInstances} /completionCondition /multiInstanceLoopCharacteristics /userTask配合流程变量监听器public class VetoListener implements ExecutionListener { Override public void notify(DelegateExecution execution) { if(execution.getVariable(rejectCount) ! null (Integer)execution.getVariable(rejectCount) 0) { // 触发终止事件 execution.setVariable(vetoTriggered, true); } } }5. 一票通过制的特殊处理在紧急预案启动等场景中可能采用任一负责人批准即可的快速通道机制。这种配置需要特别注意并发控制。5.1 最小化通过条件completionCondition ${approveCount 1} /completionCondition5.2 并发冲突预防当多个审批人同时操作时需要确保流程不会重复推进。最佳实践是结合异步锁userTask idemergencyApprove name紧急预案审批 extensionElements flowable:asynctrue/flowable:async flowable:taskListener eventcomplete classorg.flowable.approval.EmergencyLockListener/ /extensionElements multiInstanceLoopCharacteristics isSequentialfalse flowable:collection${directors} flowable:elementVariableapprover completionCondition ${approveCount 1 !lockAcquired} /completionCondition /multiInstanceLoopCharacteristics /userTask对应的锁控制监听器public class EmergencyLockListener implements TaskListener { Override public void notify(DelegateTask task) { Boolean approved (Boolean) task.getVariable(approved); if(Boolean.TRUE.equals(approved)) { task.getExecution().setVariable(lockAcquired, true); } } }6. 高级技巧与性能优化当会签参与者数量较大时如超过20人需要考虑性能优化方案。6.1 分批处理策略completionCondition ${approveCount 5 || batchComplete} /completionCondition配合批次控制监听器public class BatchControlListener implements TaskListener { private static final int BATCH_SIZE 5; Override public void notify(DelegateTask task) { Integer batchIndex (Integer) task.getVariable(batchIndex); if(batchIndex null) { batchIndex 0; } if(task.getVariable(batchComplete) null batchIndex * BATCH_SIZE nrOfInstances) { task.setVariable(batchComplete, true); } } }6.2 异步化处理对于超大规模会签如全员投票建议采用异步任务分片serviceTask idasyncVoting flowable:asynctrue flowable:classorg.flowable.AsyncVotingDelegate multiInstanceLoopCharacteristics isSequentialfalse flowable:collection${voters} flowable:elementVariablevoter completionCondition ${nrOfCompletedInstances nrOfInstances} /completionCondition /multiInstanceLoopCharacteristics /serviceTask