【弄nèng - Activiti6】Activiti6入门篇(七)—— 多实例任务
文章目录
- 1. 多实例
- 1.1 流程设计
- 1.2 测试类
- 1.3 运行
- 1.3.1 查询任务
- 1.3.2 完成发起会议任务
- 1.3.3 完成一个签到任务
- 1.3.4 完成第二个签到任务
- 2. 多实例-- 一票否决
- 2.1 流程设计
- 2.2 测试类
- 2.3 运行
- 2.3.1 查询任务
- 2.3.2 完成发起会议任务
- 2.3.3 完成一个签到任务
- 源码地址
- 项目推荐
Activiti中提供了多实例任务,多实例实在任务节点上添加额外的属性,使任务可以变成多实例,以下节点都可以添加:
- User Task
- Script Task
- Java Service Task
- Web Service Task
- Business Rule Task
- Email Task
- Manual Task
- Receive Task
- (Embedded) Sub-Process
- Call Activity
多实例内置变量
- nrOfInstances:实例总数
- nrOfActiveInstances:当前活动的实例数,对于顺序执行的多实例,值一直为1。
- nrOfCompletedInstances:已经完成实例的数目。
*后台服务基于Springboot2 + Activiti6,整合文章请参考:https://blog.csdn.net/yy756127197/article/details/101211510 不需要流程设计器就排除3,4步骤 *
1. 多实例
1.1 流程设计
节点设置
说明:
- Multi-instance type : 有两种类型,并行和串行
- Collection(Multi-instance): 动态集合,根据变量传入
- Completion condition(Multi-instance): 任务结束条件,默认全部完成
- Element variable(Multi-instance): 遍历后每一项的别名
- Cardinality(multi-instance) : 手动指定多实例循环几次
流程图
流程文件bpmn
<?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:activiti="http://activiti.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.activiti.org/processdef"><process id="multiInstance" name="多实例测试" isExecutable="true"><startEvent id="startEvent1"></startEvent><userTask id="task1" name="发起会议" activiti:assignee="admin"><extensionElements><modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete></extensionElements></userTask><sequenceFlow id="sid-AB72BCEE-4568-4240-A4A8-23A79506CAC1" sourceRef="startEvent1" targetRef="task1"></sequenceFlow><userTask id="task2" name="会议签到" activiti:assignee="${user}"><extensionElements><modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete></extensionElements><multiInstanceLoopCharacteristics isSequential="false" activiti:collection="users" activiti:elementVariable="user"><completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.5}</completionCondition></multiInstanceLoopCharacteristics></userTask><sequenceFlow id="sid-98BE643F-B247-46B2-94BA-EA9E06EBD9AC" sourceRef="task1" targetRef="task2"></sequenceFlow><endEvent id="sid-EA4EA283-C5CF-43C5-8401-E0BF40132529"></endEvent><sequenceFlow id="sid-BFD094C8-66EC-4ED2-8A35-0100E0B4E8B2" sourceRef="task2" targetRef="sid-EA4EA283-C5CF-43C5-8401-E0BF40132529"></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="210.0" y="195.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="task1" id="BPMNShape_task1"><omgdc:Bounds height="80.0" width="100.0" x="375.0" y="170.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="task2" id="BPMNShape_task2"><omgdc:Bounds height="80.0" width="100.0" x="600.0" y="170.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="sid-EA4EA283-C5CF-43C5-8401-E0BF40132529" id="BPMNShape_sid-EA4EA283-C5CF-43C5-8401-E0BF40132529"><omgdc:Bounds height="28.0" width="28.0" x="795.0" y="196.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNEdge bpmnElement="sid-AB72BCEE-4568-4240-A4A8-23A79506CAC1" id="BPMNEdge_sid-AB72BCEE-4568-4240-A4A8-23A79506CAC1"><omgdi:waypoint x="240.0" y="210.0"></omgdi:waypoint><omgdi:waypoint x="375.0" y="210.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-98BE643F-B247-46B2-94BA-EA9E06EBD9AC" id="BPMNEdge_sid-98BE643F-B247-46B2-94BA-EA9E06EBD9AC"><omgdi:waypoint x="475.0" y="210.0"></omgdi:waypoint><omgdi:waypoint x="600.0" y="210.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-BFD094C8-66EC-4ED2-8A35-0100E0B4E8B2" id="BPMNEdge_sid-BFD094C8-66EC-4ED2-8A35-0100E0B4E8B2"><omgdi:waypoint x="700.0" y="210.0"></omgdi:waypoint><omgdi:waypoint x="795.0" y="210.0"></omgdi:waypoint></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>
1.2 测试类
MultiInstanceTaskTest.java
import com.it.cloud.modules.activiti.service.IActReModelService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** 多实例测试*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class MultiInstanceTaskTest {@Autowiredprivate IActReModelService actReModelService;@Autowiredprivate RuntimeService runtimeService;@Autowiredprivate RepositoryService repositoryService;@Autowiredprivate TaskService taskService;@Autowiredprivate HistoryService historyService;/*** 部署流程定义*/@Testpublic void deploy() {Deployment deployment = repositoryService.createDeployment() // 创建部署.addClasspathResource("diagrams/multiInstance.bpmn20.xml") // 加载流程资源文件.name("multiInstance流程") // 流程名称.deploy(); // 部署System.out.println("流程部署ID:" + deployment.getId());System.out.println("流程部署Name:" + deployment.getName());}/*** 启动流程实例*/@Testpublic void start() {ProcessInstance pi = runtimeService.startProcessInstanceByKey("multiInstance"); // 流程定义表的KEY字段值System.out.println("流程实例ID:" + pi.getId());System.out.println("流程定义ID:" + pi.getProcessDefinitionId());}/*** 查看任务*/@Testpublic void queryTask() {List<Task> taskList = taskService.createTaskQuery() // 创建任务查询.taskAssignee("admin") // 指定某个人.list();for (Task task : taskList) {System.out.println("任务ID:" + task.getId());System.out.println("任务名称:" + task.getName());System.out.println("任务创建时间:" + task.getCreateTime());System.out.println("任务委派人:" + task.getAssignee());System.out.println("流程实例ID:" + task.getProcessInstanceId());}}/*** 完成任务*/@Testpublic void completeTask() {taskService.complete("42536");}/*** 完成任务2*/@Testpublic void completeTask2() {Map<String, Object> variables = new HashMap<String, Object>();variables.put("users", Arrays.asList("test1,test2,test3,test4".split(",")));taskService.complete("40005", variables);}
}
1.3 运行
运行deploy(),start()
1.3.1 查询任务
运行queryTask(),流程运行完服务任务,直接结束
效果:
1.3.2 完成发起会议任务
运行completeTask2(),设置变量users
效果:
数据表 ACT_RU_TASK
1.3.3 完成一个签到任务
运行completeTask()
效果:
数据表 ACT_RU_TASK
1.3.4 完成第二个签到任务
运行completeTask(),到达完成条件,流程结束
效果:
数据表 ACT_RU_TASK
2. 多实例-- 一票否决
2.1 流程设计
节点设置
说明:
跟前一个不同的地方在于完成条件,${nrOfCompletedInstances/nrOfInstances >= 0.5 || flag==false}
如果flag变量为false 就直接结束当前节点
流程图
流程文件bpmn
<?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:activiti="http://activiti.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.activiti.org/processdef"><process id="multiInstance-reject" name="多实例一票否决测试" isExecutable="true"><startEvent id="startEvent1"></startEvent><userTask id="task1" name="发起会议" activiti:assignee="admin"><extensionElements><modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete></extensionElements></userTask><sequenceFlow id="sid-AB72BCEE-4568-4240-A4A8-23A79506CAC1" sourceRef="startEvent1" targetRef="task1"></sequenceFlow><userTask id="task2" name="会议签到" activiti:assignee="${user}"><extensionElements><modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete></extensionElements><multiInstanceLoopCharacteristics isSequential="false" activiti:collection="users" activiti:elementVariable="user"><completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.5 || flag==false}</completionCondition></multiInstanceLoopCharacteristics></userTask><sequenceFlow id="sid-98BE643F-B247-46B2-94BA-EA9E06EBD9AC" sourceRef="task1" targetRef="task2"></sequenceFlow><endEvent id="sid-EA4EA283-C5CF-43C5-8401-E0BF40132529"></endEvent><sequenceFlow id="sid-BFD094C8-66EC-4ED2-8A35-0100E0B4E8B2" sourceRef="task2" targetRef="sid-EA4EA283-C5CF-43C5-8401-E0BF40132529"></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_multiInstance-reject"><bpmndi:BPMNPlane bpmnElement="multiInstance-reject" id="BPMNPlane_multiInstance-reject"><bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1"><omgdc:Bounds height="30.0" width="30.0" x="210.0" y="195.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="task1" id="BPMNShape_task1"><omgdc:Bounds height="80.0" width="100.0" x="375.0" y="170.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="task2" id="BPMNShape_task2"><omgdc:Bounds height="80.0" width="100.0" x="600.0" y="170.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="sid-EA4EA283-C5CF-43C5-8401-E0BF40132529" id="BPMNShape_sid-EA4EA283-C5CF-43C5-8401-E0BF40132529"><omgdc:Bounds height="28.0" width="28.0" x="795.0" y="196.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNEdge bpmnElement="sid-AB72BCEE-4568-4240-A4A8-23A79506CAC1" id="BPMNEdge_sid-AB72BCEE-4568-4240-A4A8-23A79506CAC1"><omgdi:waypoint x="240.0" y="210.0"></omgdi:waypoint><omgdi:waypoint x="375.0" y="210.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-98BE643F-B247-46B2-94BA-EA9E06EBD9AC" id="BPMNEdge_sid-98BE643F-B247-46B2-94BA-EA9E06EBD9AC"><omgdi:waypoint x="475.0" y="210.0"></omgdi:waypoint><omgdi:waypoint x="600.0" y="210.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-BFD094C8-66EC-4ED2-8A35-0100E0B4E8B2" id="BPMNEdge_sid-BFD094C8-66EC-4ED2-8A35-0100E0B4E8B2"><omgdi:waypoint x="700.0" y="210.0"></omgdi:waypoint><omgdi:waypoint x="795.0" y="210.0"></omgdi:waypoint></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>
2.2 测试类
MultiInstanceRejectTaskTest.java
import com.it.cloud.modules.activiti.service.IActReModelService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** 多实例测试*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class MultiInstanceTaskTest {@Autowiredprivate IActReModelService actReModelService;@Autowiredprivate RuntimeService runtimeService;@Autowiredprivate RepositoryService repositoryService;@Autowiredprivate TaskService taskService;@Autowiredprivate HistoryService historyService;/*** 部署流程定义*/@Testpublic void deploy() {Deployment deployment = repositoryService.createDeployment() // 创建部署.addClasspathResource("diagrams/multiInstance.bpmn20.xml") // 加载流程资源文件.name("multiInstance流程") // 流程名称.deploy(); // 部署System.out.println("流程部署ID:" + deployment.getId());System.out.println("流程部署Name:" + deployment.getName());}/*** 启动流程实例*/@Testpublic void start() {ProcessInstance pi = runtimeService.startProcessInstanceByKey("multiInstance"); // 流程定义表的KEY字段值System.out.println("流程实例ID:" + pi.getId());System.out.println("流程定义ID:" + pi.getProcessDefinitionId());}/*** 查看任务*/@Testpublic void queryTask() {List<Task> taskList = taskService.createTaskQuery() // 创建任务查询.taskAssignee("admin") // 指定某个人.list();for (Task task : taskList) {System.out.println("任务ID:" + task.getId());System.out.println("任务名称:" + task.getName());System.out.println("任务创建时间:" + task.getCreateTime());System.out.println("任务委派人:" + task.getAssignee());System.out.println("流程实例ID:" + task.getProcessInstanceId());}}/*** 完成任务*/@Testpublic void completeTask() {taskService.complete("42536");}/*** 完成任务2*/@Testpublic void completeTask2() {Map<String, Object> variables = new HashMap<String, Object>();variables.put("users", Arrays.asList("test1,test2,test3,test4".split(",")));taskService.complete("40005", variables);}
}
2.3 运行
运行deploy(),start()
2.3.1 查询任务
运行queryTask(),流程运行完服务任务,直接结束
效果:
2.3.2 完成发起会议任务
运行completeTask2(),设置变量users
效果:
数据表 ACT_RU_TASK
2.3.3 完成一个签到任务
运行completeTask3(), 设置flag=dalse, 到达完成条件,流程结束
效果:
数据表 ACT_RU_TASK
这就实现了一票否决的效果,更多效果,可以设置完成条件来实现
源码地址
IT-CLOUD-ACTIVITI6
开源项目,持续更新中,喜欢请 Star~
项目推荐
IT-CLOUD :IT服务管理平台,集成基础服务,中间件服务,监控告警服务等。
开源项目,持续更新中,喜欢请 Star~
【弄nèng - Activiti6】Activiti6入门篇(七)—— 多实例任务相关推荐
- 【弄nèng - Skywalking】入门篇(二)—— Skywalking集群部署
文章目录 一. 安装OAP 1.1 前置 1.2 下载 1.3 修改配置application.yml 1.4 高级部署 1.5 webapp配置 1.6 启动 二. 使用Agent 2.1 修改配置 ...
- 【弄nèng - Grafana】入门篇(十)—— Dashboard默认时间范围和刷新时间设置
文章目录 1. Dashboard通用设置 General 2. 修改Dashboard默认时间范围 3. 修改某个Panel时间 项目推荐 Dashboard修改默认时间范围 1. Dashboar ...
- 算法入门篇七 前缀树
牛客网 左程云老师的算法入门课 找二叉树的节点的后继节点 原则 如果节点有右子树,那么后继节点就是右子树的最左边的第一个节点 如果节点没有右子树,如果节点是父节点的右孩子,就继续往上找,直到找到一个父 ...
- 【弄nèng - SpringCloud】应用篇 —— 整合Zipkin【Finchley版】
文章目录 1. Zipkin简介 2.术语 N. 插一杠子 N.1 下载Zipkin-server jar N.2 启动jar 3. 使用 3.1 it-zipkin-server 3.2 gatew ...
- 运动控制器编程_快速入门 | 篇二十一:运动控制器ZHMI组态编程简介一
点击上方"正运动小助手",随时关注新动态! 运动控制器ZHMI组态编程简介一 今天我们来学习一下,运动控制器的ZHMI组态编程简介.本文主要从产品概述.控制器连接触摸屏使用.HM ...
- 明解C语言 入门篇 第七章练习题
明解C语言 入门篇 第七章练习题 7-1 7-2 7-3 7-4 7-5 7-6 7-7(问题已解决) 7-8 7-9 7-10(此处借鉴了@野猪力量的代码) 7-11 7-1 #include &l ...
- EGE基础入门篇(七):组合图形
EGE专栏:EGE专栏 上一篇:EGE基础入门篇(六):基本图形 下一篇:EGE基础入门篇(八):清屏与重绘 一. 组合图形 1. 复杂图形由基本图形组合而成 复杂的图形可以由基本图形组合而成,如 ...
- 【分享】 [教学]破解完全入门篇
[分享] [教学]破解完全入门篇 3PtVw f q85y)_c? #r."#)pD 第一章--前言 /.$hZ$ q 好多哥们儿说看教程跟老大的书都看不太明白,所以,我尽量 ...
- C# 学习笔记入门篇(上)
文章目录 C# 学习笔记入门篇 〇.写在前面 Hello World! 这篇学习笔记适合什么人 这篇学习笔记到底想记什么 附加说明 一.命名空间 "进入"命名空间 嵌套的命名空间. ...
- 每天15分钟JMeter入门篇(二):使用JMeter实现并发测试
每天15分钟JMeter入门篇(一):Hello JMeter 每天15分钟JMeter入门篇(二):使用JMeter实现并发测试 每天15分钟JMeter入门篇(三):认识JMeter的逻辑控制器 ...
最新文章
- 从零搭建一套结构光3D重建系统[理论+源码+实践]
- string to xml java_Java String to XML - Parse String to XML DOM Example - 入门小站-rumenz.com
- wireshark tcp data中文_wireshark流量分析入门
- AWS — AWS Direct Connect
- C#中的get和post请求(工具类)
- jsp实现mysql存储过程_JSP调用MySQL存储过程收藏
- php csrf攻击 xss区别,用大白话谈谈XSS与CSRF
- 开源软件 cadsurf 阅读笔记
- 从物理服务器拷贝文件到容器,docker容器与物理机的文件传输—docker cp命令
- 手机浏览器网址_打开URL(在其他应用中访问网址)app下载-打开URL(在其他应用中访问网址)v2.6安卓版下载...
- 使用JSSDK分享页面
- c语言学习进阶-C语言程序稳定性测试
- cck8graphpad作图_Graphpad Prism 的 4 个隐藏技能助你轻松发表 SCI
- PAT:1031. 查验身份证(15) AC
- Linux文件压缩,解压常用命令
- java json.stringify_浅谈 JSON.stringify 方法
- word封面下划线对齐
- 【第十一篇】字体设置css变形(transfom)4种
- 微信{errcode:48001,errmsg:api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]}
- 撒罗满:2019年收集的最佳3D打印模型下载网站