activiti, camunda, 会签 或签

会签,或签,依次审批借助于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 设置一个循环访问集合
  1. 设置固定的可循环访问的集合: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。并将userTaskassignee设置为${assigner}

这也就是代表着,在这个多例任务中,会创建两个userTask,并依次将这两个任务分配给marin,monkey

  1. 使用变量填充 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);
  1. 使用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}"

也就是我们会一次生成多个任务,只要有其中一个任务完成,那么整个多实例任务都被视为完成了。

Built with Hugo
主题 StackJimmy 设计