Activiti之多实例任务
所谓多实例任务,就是一个任务,需要多个人协作完成,大致可以分为两种:(1)并行多实例:完成任务没有先后顺序的要求,并行执行(2)串行多实例:完成任务有先后顺序,也就是说,必须等待前一个人完成了任务,下一个人的任务才开始在流程图中也可以体现出并行多实例与串行多实例的区别,注意看领导审批节点,多了3条线,如果3条线是竖直的,那就是并行多实例,如下所示:如果3条线是水平的,那就是串行多实例,如下所示:b
所谓多实例任务,就是一个任务,需要多个人协作完成,大致可以分为两种:
(1)并行多实例:完成任务没有先后顺序的要求,并行执行
(2)串行多实例:完成任务有先后顺序,也就是说,必须等待前一个人完成了任务,下一个人的 任务才开始
在流程图中也可以体现出并行多实例与串行多实例的区别,注意看领导审批节点,多了3条线,如果3条线是竖直的,那就是并行多实例,如下所示:
如果3条线是水平的,那就是串行多实例,如下所示:
bpmn文件的流程图,本质就是一个xml文件,普通的用户任务和多实例的任务区别如下:
<userTask activiti:exclusive="true" id="_3" name="请假申请"/>
<userTask activiti:assignee="${leader}" activiti:exclusive="true" id="_4" name="领导审批">
<multiInstanceLoopCharacteristics activiti:collection="${leaderList}" activiti:elementVariable="leader" isSequential="true">
<completionCondition><![CDATA[${nrOfInstances == nrOfCompletedInstances}]]></completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
区别就在于多实例任务里面多了一个multiInstanceLoopCharacteristics 节点
下面简单解释一些其含义:
- isSequential,为true表示是串行多实例,false表示是并行多实例
- activiti:collection,表示多实例的人员集合,${leaderList}是取变量leaderList的值
- activiti:elementVariable,人员集合中的元素变量,这里要UserTask中activiti:assignee的值对应,这里变量名称都是leader
- nrOfInstances,实例总数(nr是number的简写)
- nrOfCompletedInstances,已完成的实例数
- completionCondition,表示多实例任务的完成条件
下面以并行多实例为例,看看多实例任务的流转过程,下面是本次示例的流程图
主要的xml如下:
<process id="test_huiqian_2" isClosed="false" isExecutable="true" name="测试多实例会签" processType="None">
<startEvent id="_2" name="StartEvent"/>
<userTask activiti:assignee="${applyUser}" activiti:exclusive="true" id="_3" name="申请人确认">
<extensionElements>
<activiti:taskListener delegateExpression="${huiQianTaskListener}" event="complete"/>
</extensionElements>
<multiInstanceLoopCharacteristics activiti:collection="${applyUserList}" activiti:elementVariable="applyUser" isSequential="false">
<completionCondition><![CDATA[${agreeCnt/nrOfInstances>=0.5}]]></completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
<exclusiveGateway gatewayDirection="Unspecified" id="_4" name="ExclusiveGateway"/>
<userTask activiti:assignee="${leader}" activiti:exclusive="true" id="_5" name="领导审批"/>
<exclusiveGateway gatewayDirection="Unspecified" id="_6" name="ExclusiveGateway"/>
<endEvent id="_7" name="EndEvent"/>
<sequenceFlow id="_8" sourceRef="_2" targetRef="_3"/>
<sequenceFlow id="_9" sourceRef="_3" targetRef="_4"/>
<sequenceFlow id="_10" name="确认申请" sourceRef="_4" targetRef="_5">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${isApply == 'true'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="_11" sourceRef="_5" targetRef="_6"/>
<sequenceFlow id="_12" name="领导审批通过" sourceRef="_6" targetRef="_7">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${leaderAudit == 'true'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="_13" name="放弃申请" sourceRef="_4" targetRef="_7">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${isApply == 'false'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="_14" name="领导审批不通过" sourceRef="_6" targetRef="_3">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${leaderAudit == 'false'}]]></conditionExpression>
</sequenceFlow>
</process>
注意到:
<completionCondition><![CDATA[${agreeCnt/nrOfInstances>=0.5}]]></completionCondition>
说明只要有一半的人同意了,多实例任务就完成了,进入到下一个节点
启动流程
启动流程,设置多实例任务的参与者:张三、李四、王五
String key = "test_huiqian_2";
// 申请人列表
List<String> applyUserList = new ArrayList<>(3);
applyUserList.add("张三");
applyUserList.add("李四");
applyUserList.add("王五");
Map<String,Object> variables = new HashMap<>(1);
variables.put("applyUserList",applyUserList);
// 申请人同意的数量
variables.put("agreeCnt",0);
variables.put("isApply","false");
// 启动流程
runtimeService.startProcessInstanceByKey(key, variables);
启动流程后,进入到多实例任务,留意以下几张表的数据变化:
- 用户任务表,act_ru_task
- 节点执行表,act_ru_execution
- 用户与流程关联表,act_ru_identitylink
- 变量表,act_ru_variable
(1)用户任务表,act_ru_task,可以看到插入了3条数据,张三、李四、王五都有了待办任务
(2)节点执行表,act_ru_execution,可以看到插入了5条数据,其中parent_id_为空的是父执行流,整个过程都会保留。而id_为120013的数据是活动节点的执行流,会根据流程的流转进行更新。剩下的3条数据就和act_ru_task表的3条数据一一对应了。
(3)用户与流程关联表,act_ru_identitylink,插入了流程的参与者
(4)变量表,act_ru_variable
完成多实例任务
- 当张三完成任务后
act_ru_task表删除了张三的任务
但是,并没有删除act_ru_execution对应的数据,而是更新了版本号REV_和是否激活标志IS_ACTIVE
- 当李四完成任务后
act_ru_task表删除了李四的任务
同样的,并没有删除act_ru_execution对应的数据,而是更新了版本号REV_和是否激活标志IS_ACTIVE
- 当王五完成任务后
因为此时满足了多实例的完成条件,有50%以上的人同意了。所以删除了对应的act_ru_task和act_ru_execution表等数据
同时插入下一环节的数据到act_ru_task和act_ru_execution
任务完成之后,act_ru开头的表都会被清空。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)