会签,或签,依次审批借助于multi-instance
Multi-Instance | Camunda Cloud Docs
Activiti User Guide
多实例任务:
可以理解为可重复执行的任务
如何定义重复执行的次数 ?
一. loopCardinality 可以设置一个固定的循环上限。
1
2
3
|
<multiInstanceLoopCharacteristics isSequential="true">
<loopCardinality>5</loopCardinality>
</multiInstanceLoopCharacteristics>
|
当然你也可以在这里写一个表达式,用于计算出一个正整数循环次数
1
2
3
|
<multiInstanceLoopCharacteristics isSequential="true">
<loopCardinality>${nrOfOrders-nrOfCancellations}</loopCardinality>
</multiInstanceLoopCharacteristics>
|
二. Collection 设置一个循环访问集合
- 设置固定的可循环访问的集合:
collection=["marin", "monkey"]
1
2
3
4
5
|
<userTask id="miTasks" name="My Task" activiti:assignee="${assignee}">
<multiInstanceLoopCharacteristics isSequential="false"
activiti:collection="["marin","monkey"]" activiti:elementVariable="assigner" >
</multiInstanceLoopCharacteristics>
</userTask>
|
并通过elementVariable
将循环取出的值赋值给一个变量。
在上面的这个例子中,我们设置一个固定的集合["marin","monkey"]
,将elementVariable
设置为assigner
。并将userTask
的assignee
设置为${assigner}
。
这也就是代表着,在这个多例任务中,会创建两个userTask
,并依次将这两个任务分配给marin
,monkey
。
- 使用变量填充
collection
。
1
2
3
4
5
|
<userTask id="miTasks" name="My Task" activiti:assignee="${assigner}">
<multiInstanceLoopCharacteristics isSequential="true"
activiti:collection="assignerList" activiti:elementVariable="assigner" >
</multiInstanceLoopCharacteristics>
</userTask>
|
我们可以在发起实例的时候传入一个变量assignerList
1
2
3
4
5
|
RuntimeService runtimeService = processEngine.getRuntimeService();
Map<String, Object> variables = new HashMap<>();
variables.put("assignerList", Arrays.asList("marin", "monkey", "roy"));
runtimeService.startProcessInstanceByKey("multiple", variables);
|
- 使用spring,服务
1
2
3
4
5
|
<userTask id="miTasks" name="My Task" activiti:assignee="${assigner}">
<multiInstanceLoopCharacteristics isSequential="false"
activiti:collection="${userService.getApprovalAssigners()}" activiti:elementVariable="assigner" >
</multiInstanceLoopCharacteristics>
</userTask>
|
如果我们使用spring boot,我们可以在这里调用代码中的某个服务某个方法来获取一个集合
注意⚠️,这里的userService 必须在spring 中注册为 Spring Bean Service
注意⚠️,一个多实例活动必须要有loopCardinality
,或者collection
其中一个,否则执行出错。
如何终止运行?
默认在所有多实例任务都完成之后,那么这个多实例任务也就完成了。
或者你可以定一个完成条件:completionCondition
1
2
3
4
5
6
|
<userTask id="miTasks" name="My Task" activiti:assignee="${assigner}">
<multiInstanceLoopCharacteristics isSequential="false"
activiti:collection="${userService.getApprovalAssigners()}" activiti:elementVariable="assigner" >
<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.6 }</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
|
以下为默认的多实例变量。
- nrOfInstances: 实例总数(任务总数),对应
collection
的size,loopCardinality
的值
- nrOfActiveInstances: 当前活动的实例数,对于串行的多实例来说,这个值一直都是1
- nrOfCompletedInstances: 已完成实例数
上面的例子代表,如果有60%的任务已经完成,那么当前多实例就完成了。
当然,这里也可以写表达式,或者调用spring 的service,只要返回的是一个bool值就ok
并签:
并签对应 parallel multi-instance
并行的多实例,如下图(图片来自canmunda)
例如:这一次多实例审批,指定了两个人。 会同时生成两个task,这两个task是相互独立的,只有当这两个独立的task都完成时才会走到下一步。
当然我们可以在多实例任务上定义终止条件,提前结束多例任务。 后文的或签就是基于此实现。
并行的多实例是在流程运行至此的时候,一次生成多个任务。
依次审批:
依次审批对应 sequential multi-instance
串行的多实例
首先生成第一个任务,只有第一个任务完成后才会生成第二个任务,直到所有的任务完成
或签:
或签对应的也是parallel multi-instance
, 不同的是,我们会设置一个completionCondition="${nrOfCompletedInstances==1}"
也就是我们会一次生成多个任务,只要有其中一个任务完成,那么整个多实例任务都被视为完成了。