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@Slf4jpublic 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 汇合寄存在流程变量中