news 2026/4/16 21:52:20

Flowable多实例任务实战:从会签到或签的配置与变量解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flowable多实例任务实战:从会签到或签的配置与变量解析

1. 理解Flowable多实例任务的核心概念

第一次接触Flowable工作流引擎的多实例任务时,我完全被那些专业术语搞懵了。直到实际项目中需要实现一个OA系统的多人审批功能,才真正弄明白会签和或签的区别。简单来说,会签就像团队开会需要所有人签字确认,而或签则像紧急情况下只要有一个负责人签字就能生效。

在Flowable的可视化设计器中,多实例任务有个很直观的标识 - 活动底部的三条短线。这里有个小细节容易忽略:三条竖线代表并行执行(所有人同时收到任务),而三条横线则是顺序执行(按顺序逐个审批)。在大多数审批场景中,我们用的都是并行模式,毕竟没人希望自己的审批卡在前一个人的待办列表里。

多实例配置包含几个关键属性:

  • 类型:通常选择"并行"或"顺序"
  • 集合:审批人列表,可以是固定名单或动态变量
  • 元素变量:循环处理集合时的当前项变量名
  • 分配表达式:如何将任务分配给具体用户
  • 完成条件:决定任务何时完成的表达式

2. 会签模式的完整配置指南

去年我们团队重构报销审批流程时,财务部特别强调所有部门主管必须全部审批通过。这种场景就是典型的会签需求。下面我分享下具体实现步骤:

首先在设计器中创建用户任务,右键选择"转换为多实例活动"。关键配置参数如下:

<multiInstanceLoopCharacteristics isSequential="false"> <loopCardinality>${taskUserList.size()}</loopCardinality> <loopDataInputRef>taskUserList</loopDataInputRef> <inputDataItem name="currentUser"></inputDataItem> <completionCondition>${nrOfCompletedInstances==nrOfInstances}</completionCondition> </multiInstanceLoopCharacteristics>

这里有几个实战经验值得注意:

  1. isSequential="false"确保并行发送给所有审批人
  2. loopDataInputRef指向流程变量中的审批人列表
  3. currentUser会在每次迭代时自动赋值为当前审批人

在Java代码中启动流程时,需要传入审批人列表:

List<String> approvers = Arrays.asList("user1", "user2", "user3"); runtimeService.startProcessInstanceByKey("expenseApproval", Variables.putValue("taskUserList", approvers));

实际项目中我踩过一个坑:当审批人列表为空时,Flowable默认会跳过该任务。这可能导致审批流程出现漏洞,所以建议在前端做必填校验,或者在网关处添加判断逻辑。

3. 或签模式的灵活实现方案

与会签不同,或签模式只要任意一人审批即可通过。这种模式特别适合紧急事务处理,比如IT故障的应急审批。配置上与会签的主要区别在于完成条件:

<completionCondition>${nrOfCompletedInstances>=1}</completionCondition>

看似简单,但在实际项目中我发现几个需要特别注意的点:

  1. 任务撤回问题:当多人同时处理时,第一个完成的人会使其他任务直接消失。这可能导致用户困惑,建议在界面添加状态提示。

  2. 审批记录完整性:虽然只需要一人审批,但最好记录所有被分配人的处理状态。可以通过监听器实现:

@EventListener public void onTaskCompleted(DelegateTask task) { if(task.getVariable("nrOfCompletedInstances") != null) { // 记录多实例任务处理日志 } }
  1. 动态调整审批人:有时需要在流程运行中调整或签人员列表。这时可以使用runtimeService.setVariable()方法动态更新taskUserList。

4. 深入解析多实例任务的内置变量

理解Flowable的多实例内置变量是掌握高级配置的关键。这些变量就像隐藏在引擎盖下的仪表盘,掌握它们才能精准控制流程走向。主要的内置变量包括:

变量名描述典型使用场景
nrOfInstances总实例数显示审批进度
nrOfActiveInstances活跃实例数监控未处理任务
nrOfCompletedInstances已完成实例数判断完成条件
loopCounter当前迭代索引顺序执行时使用

在审批列表页面,我们可以利用这些变量显示实时状态:

function getApprovalStatus(task) { const total = task.variables.nrOfInstances || 1; const completed = task.variables.nrOfCompletedInstances || 0; return `${completed}/${total}人已审批`; }

有个特别实用的技巧:在会签模式下,如果想实现"超过半数同意即可通过",可以这样配置完成条件:

<completionCondition>${nrOfCompletedInstances >= (nrOfInstances/2 + 1)}</completionCondition>

5. 实战中的常见问题与解决方案

在实施了十几个Flowable项目后,我整理了一些高频问题的解决方法:

问题1:审批人动态变化解决方案:使用监听器在任务创建时动态设置审批人列表

public class DynamicAssigneeListener implements TaskListener { @Override public void notify(DelegateTask task) { List<String> approvers = getApproversFromDB(task); task.setVariable("taskUserList", approvers); } }

问题2:会签任务超时处理解决方案:结合边界定时器事件和补偿机制

<boundaryEvent id="timeoutEvent" attachedToRef="approvalTask"> <timerEventDefinition> <timeDuration>PT24H</timeDuration> </timerEventDefinition> </boundaryEvent>

问题3:审批人重复问题解决方案:在设置审批人列表前进行去重处理

List<String> approvers = new ArrayList<>(new HashSet<>(rawApprovers));

最近一个项目中,客户提出更复杂的需求:会签任务需要根据不同金额级别设置不同的审批规则。我们最终通过网关和变量判断实现了这个需求:

<sequenceFlow id="flow1" sourceRef="gateway" targetRef="approvalTask1"> <conditionExpression xsi:type="tFormalExpression"> ${amount < 10000} </conditionExpression> </sequenceFlow> <sequenceFlow id="flow2" sourceRef="gateway" targetRef="approvalTask2"> <conditionExpression xsi:type="tFormalExpression"> ${amount >= 10000} </conditionExpression> </sequenceFlow>

6. 性能优化与最佳实践

当审批人数量较多时,多实例任务可能成为性能瓶颈。根据我们的压力测试经验,以下优化措施效果显著:

  1. 批量操作:使用runtimeService.createVariableInstanceBatch()批量设置变量,减少数据库交互

  2. 异步执行:对非关键路径上的多实例任务配置异步属性

<userTask id="approvalTask" flowable:async="true"/>
  1. 缓存审批人列表:对于频繁使用的审批规则,可以考虑使用缓存

  2. 分页查询:在显示待办列表时,对多实例任务进行分页处理

SELECT * FROM ACT_RU_TASK WHERE PROC_INST_ID_ = #{processInstanceId} LIMIT #{offset}, #{pageSize}

有个特别实用的技巧是在流程启动时预计算所有多实例任务:

ProcessInstance instance = runtimeService.startProcessInstanceByKey(...); List<Task> tasks = taskService.createTaskQuery() .processInstanceId(instance.getId()) .list(); // 预加载所有任务避免N+1查询问题

7. 扩展应用:复杂审批模式实现

基础会签和或签模式可以组合出更复杂的审批场景。比如去年我们实现的"混合审批模式"就获得了客户好评:

  1. 层级审批:先部门内会签,再跨部门或签
  2. 条件审批:根据风险等级动态调整审批模式
  3. 替补审批:主审批人超时未处理时自动转交

实现层级审批的关键是合理设计子流程:

<subProcess id="deptApproval" flowable:async="true"> <multiInstanceLoopCharacteristics ...> <!-- 部门内会签配置 --> </multiInstanceLoopCharacteristics> </subProcess> <subProcess id="crossDeptApproval" flowable:async="true"> <multiInstanceLoopCharacteristics ...> <!-- 跨部门或签配置 --> </multiInstanceLoopCharacteristics> </subProcess>

对于条件审批,可以使用执行监听器动态调整审批模式:

public class ApprovalModeListener implements ExecutionListener { @Override public void notify(DelegateExecution execution) { String riskLevel = (String) execution.getVariable("riskLevel"); if("high".equals(riskLevel)) { execution.setVariable("approvalMode", "会签"); } else { execution.setVariable("approvalMode", "或签"); } } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 21:51:40

从HTML到性能优化:web.dev.cn最值得学习的5大免费课程推荐

从HTML到性能优化&#xff1a;web.dev.cn最值得学习的5大免费课程推荐 对于想要系统学习Web开发技术的开发者来说&#xff0c;找到高质量且免费的学习资源至关重要。web.dev.cn作为谷歌开发者推出的中文学习平台&#xff0c;提供了大量权威、实用的课程内容&#xff0c;涵盖了从…

作者头像 李华
网站建设 2026/4/16 21:49:46

5步掌握AutoDock Vina:从零开始实现专业级分子对接

5步掌握AutoDock Vina&#xff1a;从零开始实现专业级分子对接 【免费下载链接】AutoDock-Vina AutoDock Vina 项目地址: https://gitcode.com/gh_mirrors/au/AutoDock-Vina AutoDock Vina是一款免费开源的分子对接引擎&#xff0c;专为药物发现和蛋白质-配体相互作用研…

作者头像 李华
网站建设 2026/4/16 21:48:37

SUN-PEG-Fe₃O₄,舒尼替尼-PEG-四氧化三铁纳米颗粒 ,成分与性质

SUN-PEG-Fe₃O₄&#xff0c;舒尼替尼-PEG-四氧化三铁纳米颗粒 &#xff0c;成分与性质SUN-PEG-Fe₃O₄ NPs&#xff08;舒尼替尼-PEG-四氧化三铁纳米颗粒&#xff09;**是一类由无机磁性纳米核心、有机高分子界面层以及小分子药物构建而成的复合纳米体系。该体系以四氧化三…

作者头像 李华
网站建设 2026/4/16 21:47:48

Rational Rose报错全攻略:从License Key Error到Common文件夹配置详解

Rational Rose许可证报错深度解析与系统化解决方案 1. 理解Rational Rose许可证机制的核心原理 Rational Rose作为经典的UML建模工具&#xff0c;其许可证验证体系基于FlexNet Publisher&#xff08;原FlexLM&#xff09;技术架构。这个系统采用客户端-服务器模式进行许可证校…

作者头像 李华
网站建设 2026/4/16 21:46:43

从LED驱动到电机控制:单片机I/O口阻抗的5个实战应用技巧

从LED驱动到电机控制&#xff1a;单片机I/O口阻抗的5个实战应用技巧 在嵌入式硬件设计中&#xff0c;单片机I/O口的阻抗特性往往是最容易被忽视却又至关重要的参数。想象一下&#xff0c;当你精心设计的电路板在实验室完美运行&#xff0c;却在现场频繁出现LED亮度不稳定、继电…

作者头像 李华