Flowable—多实例任务:会签
多实例任务 会签
什么是会签?
举个例子:比如我们有一个任务 可能需要多人审批,审批通过的条件可能比较多样,比如五个人审批。3个人审批过了就算过了,再或者有一个人权限比较高,拥有一票否决权。 即是其余所有人都过了,他点了个否定 就算不过了,这种就是会签。

我们从上面可以清楚看到,这个流程有两个任务节点,分别是多实例任务节点,和任务2. 任务2就是普通的userTask,多实例任务1 其实也是userTask,
只不过是参数设置不同罢了,下面我们上流程的xml定义文件。
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
<process id="multiinstance" name="MultiInstance" isExecutable="true">
<documentation>测试多实例模型</documentation>
<startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent>
<userTask id="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95" name="多实例任务1" flowable:assignee="${assignee}" flowable:formFieldValidation="true">
<extensionElements>
<modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
<multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee">
<loopCardinality>5</loopCardinality>
<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.50}</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
<sequenceFlow id="sid-78DB6DB5-22CF-406D-9B4A-B4F14A7E062B" sourceRef="startEvent1" targetRef="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95"></sequenceFlow>
<userTask id="sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C" name="任务2" flowable:formFieldValidation="true"></userTask>
<sequenceFlow id="sid-B452CC02-56EA-46D2-8485-FB5B788200C1" sourceRef="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95" targetRef="sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C"></sequenceFlow>
<endEvent id="sid-15CEF7DC-E073-484D-9B36-4EB3DA9A059F"></endEvent>
<sequenceFlow id="sid-69D6B9D5-A369-4708-B74B-2DECD1D0F308" sourceRef="sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C" targetRef="sid-15CEF7DC-E073-484D-9B36-4EB3DA9A059F"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_multiinstance">
<bpmndi:BPMNPlane bpmnElement="multiinstance" id="BPMNPlane_multiinstance">
<bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
<omgdc:Bounds height="30.0" width="30.0" x="90.0" y="150.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95" id="BPMNShape_sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95">
<omgdc:Bounds height="80.0" width="100.0" x="300.0" y="120.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C" id="BPMNShape_sid-F1BBCD6F-3153-4139-9101-D3C8C2F6151C">
<omgdc:Bounds height="80.0" width="100.0" x="630.0" y="125.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-15CEF7DC-E073-484D-9B36-4EB3DA9A059F" id="BPMNShape_sid-15CEF7DC-E073-484D-9B36-4EB3DA9A059F">
<omgdc:Bounds height="28.0" width="28.0" x="1095.0" y="151.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sid-69D6B9D5-A369-4708-B74B-2DECD1D0F308" id="BPMNEdge_sid-69D6B9D5-A369-4708-B74B-2DECD1D0F308">
<omgdi:waypoint x="729.9499999999999" y="165.0"></omgdi:waypoint>
<omgdi:waypoint x="1095.0" y="165.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-B452CC02-56EA-46D2-8485-FB5B788200C1" id="BPMNEdge_sid-B452CC02-56EA-46D2-8485-FB5B788200C1">
<omgdi:waypoint x="399.9499999999835" y="160.0"></omgdi:waypoint>
<omgdi:waypoint x="515.0" y="160.0"></omgdi:waypoint>
<omgdi:waypoint x="515.0" y="165.0"></omgdi:waypoint>
<omgdi:waypoint x="629.9999999999847" y="165.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-78DB6DB5-22CF-406D-9B4A-B4F14A7E062B" id="BPMNEdge_sid-78DB6DB5-22CF-406D-9B4A-B4F14A7E062B">
<omgdi:waypoint x="119.94999834279307" y="165.0"></omgdi:waypoint>
<omgdi:waypoint x="210.0" y="165.0"></omgdi:waypoint>
<omgdi:waypoint x="210.0" y="160.0"></omgdi:waypoint>
<omgdi:waypoint x="299.9999999999682" y="160.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
上面是整个流程定义,内容比较繁多,下面我们主要看一下多实例任务1的节点内容片段进行详解:
<userTask id="sid-AFB0AD6E-5B65-457F-8E99-F3B8104CBA95" name="多实例任务1" flowable:assignee="${assignee}" flowable:formFieldValidation="true">
<extensionElements>
<modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
<multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee">
<loopCardinality>5</loopCardinality>
<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.50}</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
上面我们已经知道了,会签的应用场景,有点想投票一样的感觉,既然是多个人参与的场景,也就意味着这是一个多人的任务,所以就有了上面的多实例任务,什么叫多实例任务呢?就是这个任务会产生多个实例,想java 的类和实例的关系一样,你需要多少个实例你new多少次这个类就行了。所以这个多实例任务是可以通过配置参数,来决定执行这个任务的时候会产生多少个一样的任务的实例,来给每个指定人的人执行,然后汇总结果,来判断是否通过。也就是说还会有个条件来判断是否通过。
至于是多少个实例呢?这个是通过
<loopCardinality>5</loopCardinality>
配置的吗,这里我们配置的是5个实例,也就是说要把它分给五个人执行。
- flowable:assignee="${assignee}"
- flowable:collection=“assigneeList”
- flowable:elementVariable=“assignee”
- isSequential=“false”
理解了上面我们再看一下上面的属性
- isSequential=“false”
false 代表并行,true代表串行,是什么意思呢?并行就是上面这5个任务可以同时执行,不受约束,串行就是一个个轮着来执行。
flowable:assignee="${assignee}"
该属性代表任务分配给谁,这里用的EL表达式,因为我们可能将五个不同的任务分配给五个不同的人,而且可能是我们运行时决定的(就是提前不能确定)。flowable:collection=“assigneeList”
这里是一个运行时的变量的名字,举个例子我们运行时变量里面必须有个变量名字叫assigneeListflowable:elementVariable=“assignee”
这里的assignee对应于上面的assigneeList, 如果 assigneeList是一个集合类型,那么assignee就对应于集合中的一个单元,然后,上面的EL表达式${assignee} 对应的就是这些单元。类似于Mybatis中的foreach标签。
<foreach collection="list" item="emp" separator=";">
INSERT INTO t_employee(username, gender, email) VALUES
(#{emp.username}, #{emp.gender}, #{emp.email})
</foreach>
assigneeList对应于上面的list, assignee对应于上面的emp。
<loopCardinality>5</loopCardinality>
<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.50}</completionCondition>
- loopCardinality
该属性的意思是这个任务循环的基数是多少,这个任务类型就是多实例任务,根据上面的解释,这个属性就是设置究竟是多少个实例的地方,比如我们需要五个人审批投票,然后就在这里设置个5就行了,为什么叫循环基数呢?就是因为如果我们的通过条件是3个人通过就ok的话,那么可能只需要3个实例就结束,进入到下一个环节了,而不是要5个实例。 - completionCondition
完成的条件,这里就是设置这个多实例任务完成的地方,这里面你可以设置自己的结束条件,比如这里的条件:<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.50}</completionCondition>
这里仍然用的是EL表达式,这里面有两个变量:nrOfCompletedInstances和nrOfInstances, 这里的nr是number的简写,所以你可以看明白这个条件是什么了,完成的任务实例超过实例的50%就算完成这个节点了。当然你也可以设置别的条件,可以通过EL表达式进行设置。
这里的变量nrOfCompletedInstances和nrOfInstances是系统自动生成的,要是你需要设置自己的变量吗,可以自己控制。
多实例任务的数据库状态
当我们启动一个上面的流程定义实例的时候传入的数据结构参数如下:
{
"deployId":"multiinstance:1:f9d0c4e2-2873-11ea-9aeb-1c872c5f4209",
"processKey":"multiinstance",
"processStarter":"sunlutong",
"varibales":{
"assigneeList":[
"m1",
"m2",
"m3",
"m4",
"m5"
]
}
}
实例化后,返回的流程实例ID是:22b6508d-2b76-11ea-af60-1c872c5f4209
进入到多实例任务节点之后,根据实例ID22b6508d-2b76-11ea-af60-1c872c5f4209。我们看一下实时的该实例的任务在表ACT_RU_TASK的数据表现:
我们可以看到上面自动生成了五个任务实例,assignee正是我们上面传入的参数assigneeList中的数据。
再来看一下多实例任务相关的实时的属性表,ACT_RU_VARIABLE表中的数据状态如下:
我们可以看到除了自己传入的参数assignee,assigneeList,会自动生成一些任务属性。
实际操作对应的数据表得变化
我们上面设置的完成属性是完成的实例超过50%就算完成了实例,也就是说我们只要完成三个实例就会结束多任务节点进入到 任务2。
提交一个任务实例
ACT_RU_TASK表得数据:
我们可以看到此时上面的assignee的任务消失了。
ACT_RU_VARIABLE表得数据:

我们可以看到数据nrOfCompletedInstances变成了1,
在连续提交两个任务实例:
发现表ACT_RU_TASK和表ACT_RU_VARIABLE的多任务实例相关的数据都没了。
流程的进展如下:
以上就是会签。
Flowable—多实例任务:会签的更多相关文章
- Activiti学习之 多实例实现会签功
转: Activiti学习之 多实例实现会签功能 2014年11月26日 11:27:11 程诺 阅读数:26185 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...
- 基于springboot的flowable工作流实例实现
基于springboot的flowable工作流实例实现 flowableUI 创建实例教程 https://www.cnblogs.com/nanstar/p/11959389.html Flowa ...
- flowable的多人会签和一票否决
项目结构: 接下来代码: Duorenhuiqian.bpmn20.xml: <?xml version="1.0" encoding="UTF-8"?& ...
- flowable 实现多实例-会签-动态配置人员 参考demo
会签 即多人执行当前任务 设置判断数 通过 例如:设置了是半数通过即可通过当前节点 如果当前是4人那就是2人即通过 如果是6人那就是三人即通过 如果是5人 即三人通过 看各位的判断值是如何书写 这个值 ...
- 最近学习工作流 推荐一个activiti 的教程文档
全文地址:http://www.mossle.com/docs/activiti/ Activiti 5.15 用户手册 Table of Contents 1. 简介 协议 下载 源码 必要的软件 ...
- jBPM4.3+ssh+会签 整合配置及完整实例
大佬们的项目里有用到会签,所以趁双休日研究了下. 其实也是简单的会签情况,不过开始的时候研究了4.4,(因为先前研究的都是4.4),发现4.4跟4.3的处理方法完全不一样,搞的我比较郁闷……弄了一天, ...
- flowable ui 界面请假流程操作实例
如题,网上的教程多是代码居多,UI界面操作实例那更是一页难求,楼主分享下几天来的入坑经历,希望有需要了解,但是不知道去哪里了解的小伙伴,看完我的文章后能有所启发,文章有不足之处还请指正,若有相关问题请 ...
- flowable 任务多实例
项目地址:https://gitee.com/lwj/flowable.git 分支flowable-base*业务场景:收集每个员工的绩效考核信息:收集一次组织活动的信息:一个合同需要三个经理审批, ...
- activiti会签 多实例例子
在实际的业务中,可能存在存在这么一种情况,当流程运行到某一个环节时,可能需要同时多个人的参与,才可以完成此环节.此时就可以用到activiti的多实例来解决此问题. 一.将一个节点设置成多实例的方法: ...
随机推荐
- 论如何优雅的抛出SpringBoot注解的异常
平时我们在写代码的时候肯定要进行很多参数验证,最开始的时候我们一般都是这样处理的 如下图 看起来好像也没什么,但是 如果参数多了呢?你就会看到这样的校验 OMG!!! 有没有感觉稍微有点视觉 ...
- vs2019 Com组件初探-通过IDispatch接口调用Com
vs2019 Com组件初探-简单的COM编写以及实现跨语言调用 上一篇实现了如何编写基于IDipatch接口的COM以及vbs如何调用编写的COM 本次主要是实现VBS的CreateObject函数 ...
- sql中count(1)、count(*)与count(列名)的区别
1. count(1) and count(*) 当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了!从执行计划来看,count(1)和count(*)的效果是 ...
- 第8.2节 Python类的__init__方法深入剖析:构造方法案例详解
前面一节介绍了构造方法定义的语法,并进行了语法解释说明,本节将通过案例来说明构造方法参数传递及返回值的情况. 一. 案例说明 本节定义一个汽车类,它有四个实例变量:wheelcount, pow ...
- 开源脉冲神经网络深度学习框架——惊蛰(SpikingJelly)
开源脉冲神经网络深度学习框架--惊蛰(SpikingJelly) 背景 近年来神经形态计算芯片发展迅速,大量高校企业团队跟进,这样的芯片运行SNN的能效比与速度都超越了传统的通用计算设备.相应的,神经 ...
- csv 如何将txt文件转换成csv文件
import csvdef convert_txt_to_csv(out_file_path, input_file_path, txt_sep): #定义输出路径,输入文件路径,txt的分隔符 wi ...
- pytorch 实践中遇到的问题
1. SGD训练时,初始化学习率为0.05时,loss出现了 nan (百度: pytorch loss nan, 但是目前暂未看懂解释,大概是loss出现了inf,学习率偏大?)
- .Net Core ABP应用如何在阿里云Linux Docker中开启Https
.Net Core应用开启Https本身就有很多种方式:1.代码配置2.环境变量3.反向代理 这里主要记录下阿里云的ECS,加阿里云免费的SSL证书,通过程序代码,如何进行配置. 首先从阿里云下载证书 ...
- 【Alpha冲刺阶段】Scrum Meeting Daily5
[Alpha冲刺阶段]Scrum Meeting Daily5 1.会议简述 会议开展时间 2020/5/27 8:30-9:00 PM 会议基本内容摘要 大家讲述了自己的任务完成情况以及遇到的问题 ...
- js 导出div 中的类容为 word 文件
//引入包 <script src="/FileSaver.js"></script> <script src="/jquery.word ...