1 简介
做工作流,根本会遇到会签、或签的需要。而 flowable 是通过多任务形式来实现的
2 次要实现形式
在流程运行到工作节点时不是依照默认规定只生成一条工作记录,而是依据须要同时生成多条工作记录,甚至生成的多条工作都能别离对应到指定的各个审批人。而不再须要支付。这种就叫多任务
要实现多任务,则须要对 须要的工作节点须要做相干解决
上面介绍理解到两种形式解决
2.1 xml 形式
此种形式是间接通过在 xml 的相应节点来定义多任务, 这种官网有大量的 xml 例子
【官网】多任务的 xml
应用 flowable 官网的套件来配置多任务的交互见面大略如下 (图片来源于网上):
最终对应到理论的外围 xml 具体如下 (上面 xml 不严格对应上图)
<bpmn2:userTask id="Activity_1g65lke" name="审批啊 14" flowable:assignee="${assignee}" flowable:candidateGroups="2317,2347" flowable:category="CHECK">
<bpmn2:extensionElements>
<flowable:executionListener class="***.listens.MultiInstanceListen" event="start" />
</bpmn2:extensionElements>
<bpmn2:incoming>Flow_1666168081285</bpmn2:incoming>
<bpmn2:outgoing>Flow_03sldqb</bpmn2:outgoing>
<bpmn2:multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee">
<bpmn2:extensionElements>
</bpmn2:extensionElements>
<bpmn2:completionCondition>${nrOfCompletedInstances>=1}</bpmn2:completionCondition>
</bpmn2:multiInstanceLoopCharacteristics>
</bpmn2:userTask>
如果你不是用的官网的 UI 来生成的 xml, 那么你的本人想方法也须要结构出下面的 xml
2.2 java 类后端解决
此种形式是我在调研时看到的,我并未尝试过,不太切合咱们的需要,然而也是一种形式
此种形式就是运行到相应节点,后端通过调用 api 来生成多任务所须要的所有
这边就不放外围代码了,间接能够点击网友曾经做好的整顿
- activiti 多实例设置 (会签 / 或签)
3 外围参数解释
下面应该能看到咱们须要配置一些货色能力反对多任务。这里具体说下相干参数及重要点
3.1 相干参数
- isSequential: 示意并行,还是程序。(xml 跟配图可能有出入)
-
loop cardinality:循环基数。可选项。能够间接填整数,示意会签、或签的人数 – (会创立基数个工作实例)
应用该参数只能保障生成相应的工作,然而生成的工作没有 assign
该参数跟上面 collection 二选一就行
- flowable:collection: 此种形式是示意的会签、或签的具体人。这里 xml 只须要约定好固定的格局 即可。比方 flowable:collection=”assigneeList”
- flowable:elementVariable: 元素变量, 这里 xml 只须要约定好固定的格局 即可 flowable:elementVariable=”assignee”
-
completionCondition:实现条件。这个条件管制着这里是会签、或签如何能力算实现。
- nrOfCompletedInstances: 实现的工作实例数
- nrOfInstances: 总共生成的工作实例数 (依据会签、或签指定的人数生成相应的工作数)
参考配置
当是或签时,间接固定配置:${nrOfCompletedInstances>=1} 即可
当是会签时,固定配置:${nrOfCompletedInstances==nrOfInstances} 即可
3.2 重要点
- 在会签、或签节点减少 multiInstanceLoopCharacteristics 相应的标签
- 指定生成的工作数。这里更倡议应用 collection。因为它能够相干配置做到 给生成的工作实例时就有 assign
-
工作标签上属性 flowable:assignee=”${assignee}” 必须固定这么指定,否则创立的多任务记录外面 assign 还是没值
属性 assignee 取 Element varible 的值,比方 Element varible 设置为 assignee,Assignents 就设置为 ${assignee}
- 如果节点是审批节点,那么肯定须要在用户工作节点 的
extensionElements
下增加 监听器
4 collection 赋值
4.1 应用起因
首先咱们为什么要应用 collection 再次简略说下,通过下面的配置,当指定了 collection 的流程变量后,在引擎主动生成多任务时每个工作的 assign 都有值了。就不再须要减少业务逻辑解决 (遍历多任务后而后拿到审批人,顺次给每个工作塞 解决人)
4.2 如何赋值
做下来感觉最难的中央就是 collection 赋值的问题。思路线索很多,然而都存在问题
4.2.1 官网
首先说还是说官网的例子 点击查看 MultiInstanceTest
外面居然是通过在发动流程就指定了审批人。这种也太 DEMO 了点。审批人即便是配置时固定的人,在开始发动流程就有晓得审批人,那么就须要去解析 xml, 找到相应节点的审批人。这种一开始只被我用来做最初的打算
官网还给出另一种表达式计划 点击查看 multiinstancemodel.bpmn
<endEvent id="sid-194696BA-1A7D-47D7-95A9-A77390D25048"></endEvent>
<userTask id="userTask1" name="User task 1" flowable:async="true" flowable:exclusive="false">
<multiInstanceLoopCharacteristics isSequential="false" flowable:elementVariable="participant">
<extensionElements>
<flowable:collection flowable:class="org.flowable.engine.test.bpmn.multiinstance.JSONCollectionHandler">
<flowable:string>
<![CDATA[[
{
"principalType" : "User",
"role" : "PotentialOwner",
"principal" : "wfuser1",
"version" : 1
},
{
"principalType" : "User",
"role" : "PotentialOwner",
"principal" : "wfuser2",
"version" : 1
}
]]]>
</flowable:string>
</flowable:collection>
</extensionElements>
</multiInstanceLoopCharacteristics>
</userTask>
而后这种形式我是各种尝试,然而在流程走到该节点就呈现解析不胜利问题
最初我也查到了这种形式的起源是这篇帖子 Multi-instance collection syntax proposal 有更感兴趣的能够去看看
4.2.2 事件
在尝试应用下面形式失败后,我开始尝试用监听事件的形式来赋值 collection。
我尝试过 FlowableEngineEventType.ACTIVITY_STARTED
事件 , FlowableEngineEventType.TASK_CREATED
事件
然而发现都不行,他们都是在多任务曾经创立完后才会执行相干的事件办法。这个时候曾经生成的多个工作,然而它们的 assign 都是空的
4.2.3 执行监听器
我在网上查问计划,终于在一篇文中 activiti 多实例设置 (会签 / 或签) 看到能在工作创立前赋值 collection 的可能。
而后我依据这个信息查到配置执行监听器最终做到在正确机会给 collection 赋值
首先,须要在 xml 须要增加监听器 (残缺能够看看下面的 xml)
<flowable:executionListener class="***.listens.MultiInstanceListen" event="start" />
而后看看实现
/**
* 多任务监听,次要是把 多人工作 xml 设置的汇合给填充掉
*/
@Component
@Slf4j
public class MultiInstanceListen implements ExecutionListener {
@Override
public void notify(DelegateExecution execution) {FlowElement element = execution.getCurrentFlowElement();
if (element instanceof UserTask) {UserTask userTask = (UserTask) element;
List<String> candidateGroups = userTask.getCandidateGroups();
// 设置 setVariableLocal 会导致找不到 assigneeList 变量
execution.setVariable("assigneeList", candidateGroups);
}
}
}
通过此形式,就会在创立多任务之前执行该监听器,从而让 assigneeList 汇合寄存在流程变量中