Flowable会签与或签实战:5分钟搞定多实例任务配置(附避坑指南)
Flowable会签与或签实战:5分钟搞定多实例任务配置(附避坑指南)
在流程引擎开发中,会签和或签是两种常见的多人任务处理模式。它们能够有效模拟现实业务场景中的多人协作审批流程,比如部门集体决策、多级审核等场景。本文将深入探讨如何在Flowable中快速配置这两种模式,并分享实际项目中积累的实战经验。
1. 会签与或签的核心概念解析
会签(Counter-signature)是指需要多个参与者共同完成同一任务节点的审批场景。根据业务需求不同,会签又可分为以下几种典型模式:
- 全员通过:所有参与者必须全部同意(如重大财务审批)
- 比例通过:达到设定比例即视为通过(如2/3以上同意)
- 一票否决:任何一位参与者反对即终止流程(如安全评审)
- 一票通过:任意一位参与者同意即可推进(如紧急预案)
或签(Or-signature)则更为灵活,只需任意一位指定参与者完成处理即可继续流程。这种模式常见于:
- 多主管平行审批(任何一位主管均可处理)
- 值班人员任务分配(任何在岗人员均可响应)
- 多备份联系人通知(联系到任意一位即算成功)
<!-- 典型会签配置示例 --> <userTask id="counterSignTask" name="会签审批"> <multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee"> <completionCondition>${nrOfInstances == nrOfCompletedInstances}</completionCondition> </multiInstanceLoopCharacteristics> </userTask>2. 多实例任务配置全流程
2.1 基础配置步骤
- 标识多实例节点:在流程设计器中勾选UserTask的"Multi-instance"属性
- 设置循环类型:
- 并行(parallel):参与者可同时处理
- 顺序(sequential):按指定顺序依次处理
- 指定参与者集合:
- 直接指定静态列表(如
user1,user2,user3) - 引用流程变量(如
${approvers}) - 动态查询(如
${userService.findDeptManagers(execution)})
- 直接指定静态列表(如
注意:集合变量与元素变量名需保持唯一性,避免与系统变量冲突
2.2 动态参与者分配技巧
实际项目中,参与者列表往往需要动态确定。以下是几种实用方案:
| 方案类型 | 实现方式 | 适用场景 |
|---|---|---|
| 固定列表 | 直接定义assignee列表 | 审批人固定的场景 |
| 表达式 | 使用UEL表达式调用服务方法 | 需要动态计算的场景 |
| 监听器注入 | 通过ExecutionListener设置变量 | 复杂业务逻辑场景 |
| 外部存储查询 | 连接数据库或API获取列表 | 审批规则复杂的系统 |
// 通过监听器动态设置参与者示例 public class DynamicAssigneeListener implements ExecutionListener { @Override public void notify(DelegateExecution execution) { String deptId = (String) execution.getVariable("deptId"); List<String> users = userService.findByDept(deptId); execution.setVariable("assigneeList", users); } }3. 完成条件的高级配置
3.1 内置变量说明
Flowable为多实例任务提供了三个关键变量:
nrOfInstances:总实例数nrOfCompletedInstances:已完成实例数nrOfActiveInstances:活动实例数
基于这些变量,可以构建各种完成条件:
<!-- 不同完成条件示例 --> <completionCondition> <!-- 全员通过 --> ${nrOfInstances == nrOfCompletedInstances} <!-- 或签模式 --> ${nrOfCompletedInstances >= 1} <!-- 比例通过(超过50%) --> ${nrOfCompletedInstances > nrOfInstances/2} <!-- 一票否决 --> ${!rejected && nrOfCompletedInstances == nrOfInstances} </completionCondition>3.2 自定义完成条件
对于复杂业务规则,可通过JavaDelegate实现自定义逻辑:
public class CustomCompletionCondition implements JavaDelegate { @Override public void execute(DelegateExecution execution) { int agreeCount = (int) execution.getVariable("agreeCount"); int total = (int) execution.getVariable("nrOfInstances"); boolean isPassed = agreeCount > total * 0.7; execution.setVariable("signResult", isPassed); } }在流程定义中引用:
<completionCondition>${signResult == true}</completionCondition>4. 实战避坑指南
4.1 常见配置错误
- 变量作用域问题:多实例任务内定义的变量默认只在当前实例有效,需要跨实例共享时需明确设置作用域
- 集合变量格式错误:确保集合类型与预期一致(List而非String)
- 表达式解析失败:复杂的UEL表达式可能因环境差异导致解析异常
4.2 性能优化建议
避免超大参与者集合:
- 超过50人的会签建议拆分子流程
- 使用分组代表机制(如部门负责人代表全员)
异步化处理:
<multiInstanceLoopCharacteristics flowable:async="true" flowable:exclusive="false"> </multiInstanceLoopCharacteristics>历史数据清理:定期归档已完成实例数据,保持运行库轻量
4.3 特殊场景处理
会签中途新增参与者:
- 通过API动态扩展实例集合
- 更新nrOfInstances计数
- 重置完成条件判断逻辑
或签中的优先级处理:
<completionCondition> <!-- 优先处理人完成则立即结束 --> ${priorityCompleted || nrOfCompletedInstances >= 1} </completionCondition>在最近的一个OA系统升级项目中,我们遇到一个典型场景:部门预算审批需要全体经理会签,但任意副经理同意即可推进。最终通过组合条件实现了这个需求:
<completionCondition> ${(nrOfCompletedInstances == nrOfInstances) || (deputyApproved && nrOfCompletedInstances >= 1)} </completionCondition>