文章目录

  • 1. 会签说明
  • 2. 多实例
  • 3.流程实现
    • 3.1 设计流程图

1. 会签说明

会签,是指多个人员针对同一个事务进行协商处理,共同签署决定一件事情。
在工作流中会签,是指多个人员在同一个环节进行处理,同一环节的有多个处理人并行处理,按照配置规则,固定比例的人员办理完成后即可继续扭转至下一环节。

2. 多实例

多实例节点是在业务流程中定义重复环节的一个方法。 从开发角度讲,多实例和循环是一样的: 它可以根据给定的集合,为每个元素执行一个环节甚至一个完整的子流程, 既可以顺序依次执行也可以并发同步执行。

多实例是在一个普通的节点上添加了额外的属性定义 (所以叫做’多实例特性’),这样运行时节点就会执行多次。 下面的节点都可以成为一个多实例节点:

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:已经完成实例的数目。

可以通过execution.getVariable(x)方法获得这些变量。

另外,每个创建的分支都会有分支级别的本地变量(比如,其他实例不可见, 不会保存到流程实例级别):

loopCounter:表示特定实例的在循环的索引值。可以使用activiti的elementIndexVariable属性修改loopCounter的变量名。
图形标记
如果节点是多实例的,会在节点底部显示三条短线。 三条竖线表示实例会并行执行。 三条横线表示顺序执行。

Xml内容
要把一个节点设置为多实例,节点xml元素必须设置一个multiInstanceLoopCharacteristics子元素。

<multiInstanceLoopCharacteristics isSequential="false|true">...
</multiInstanceLoopCharacteristics>

isSequential属性表示节点是进行 顺序执行还是并行执行。

实例的数量会在进入节点时计算一次。 有一些方法配置它。一种方法是使用loopCardinality子元素直接指定一个数字。

<multiInstanceLoopCharacteristics isSequential="false|true"><loopCardinality>5</loopCardinality>
</multiInstanceLoopCharacteristics>

也可以使用结果为整数的表达式:

<multiInstanceLoopCharacteristics isSequential="false|true"><loopCardinality>${nrOfOrders-nrOfCancellations}</loopCardinality>
</multiInstanceLoopCharacteristics>

另一个定义实例数目的方法是,通过loopDataInputRef子元素,设置一个类型为集合的流程变量名。 对于集合中的每个元素,都会创建一个实例。 也可以通过inputDataItem子元素指定集合。 下面的代码演示了这些配置:

<userTask id="miTasks" name="My Task ${loopCounter}" activiti:assignee="${assignee}"><multiInstanceLoopCharacteristics isSequential="false"><loopDataInputRef>assigneeList</loopDataInputRef><inputDataItem name="assignee" /></multiInstanceLoopCharacteristics>
</userTask>

假设assigneeList变量包含这些值[kermit, gonzo, foziee]。 在上面代码中,三个用户任务会同时创建。每个分支都会拥有一个用名为assignee的流程变量, 这个变量会包含集合中的对应元素,在例子中会用来设置用户任务的分配者。

loopDataInputRef和inputDataItem的缺点是1)名字不好记, 2)根据BPMN 2.0格式定义,它们不能包含表达式。activiti通过在 multiInstanceCharacteristics中设置 collection和 elementVariable属性解决了这个问题:

<userTask id="miTasks" name="My Task" activiti:assignee="${assignee}"><multiInstanceLoopCharacteristics isSequential="true"activiti:collection="${myService.resolveUsersForTask()}" activiti:elementVariable="assignee" ></multiInstanceLoopCharacteristics>
</userTask>

多实例节点在所有实例都完成时才会结束。也可以指定一个表达式在每个实例结束时执行。 如果表达式返回true,所有其他的实例都会销毁,多实例节点也会结束,流程会继续执行。 这个表达式必须定义在completionCondition子元素中。

<userTask id="miTasks" name="My Task" activiti:assignee="${assignee}"><multiInstanceLoopCharacteristics isSequential="false"activiti:collection="assigneeList" activiti:elementVariable="assignee" ><completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.6 }</completionCondition></multiInstanceLoopCharacteristics>
</userTask>

在这里例子中,会为assigneeList集合的每个元素创建一个并行的实例。 当60%的任务完成时,其他任务就会删除,流程继续执行。
以上内容为Activiti用户手册的内容,下面实现一个简单地流程。

3.流程实现

3.1 设计流程图

第一张为:${nrOfCompletedInstances/nrOfInstances >= 1 },表示需要所有会签任务全部完成才会往下执行。

Bpmn文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 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" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1597109014081" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema"><process id="jointlySign" isClosed="false" isExecutable="true" processType="None"><startEvent id="_2" name="开始"/><userTask activiti:assignee="${assignee}" activiti:candidateGroups="生产部领导" activiti:exclusive="true" id="_3" name="生产部领导会签"><multiInstanceLoopCharacteristics activiti:collection="${assignees}" activiti:elementVariable="assignee" isSequential="false"><completionCondition><![CDATA[${nrOfCompletedInstances/nrOfInstances>1}]]></completionCondition></multiInstanceLoopCharacteristics></userTask><endEvent id="_4" name="结束"/><sequenceFlow id="_5" sourceRef="_2" targetRef="_3"/><sequenceFlow id="_6" sourceRef="_3" targetRef="_4"/></process><bpmndi:BPMNDiagram documentation="background=#000000;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram"><bpmndi:BPMNPlane bpmnElement="jointlySign"><bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2"><omgdc:Bounds height="32.0" width="32.0" x="45.0" y="290.0"/><bpmndi:BPMNLabel><omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3"><omgdc:Bounds height="55.0" width="85.0" x="260.0" y="285.0"/><bpmndi:BPMNLabel><omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4"><omgdc:Bounds height="32.0" width="32.0" x="560.0" y="295.0"/><bpmndi:BPMNLabel><omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNShape><bpmndi:BPMNEdge bpmnElement="_5" id="BPMNEdge__5" sourceElement="_2" targetElement="_3"><omgdi:waypoint x="77.0" y="306.0"/><omgdi:waypoint x="260.0" y="312.5"/><bpmndi:BPMNLabel><omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="_6" id="BPMNEdge__6" sourceElement="_3" targetElement="_4"><omgdi:waypoint x="345.0" y="312.5"/><omgdi:waypoint x="560.0" y="311.0"/><bpmndi:BPMNLabel><omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>

测试类

package com.yb;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.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;/*** @author liangjie@itcast.cn* @version 1.0* @date 2020/8/5*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiJpaTest04 {@Resourceprivate RepositoryService repositoryService;@Resourceprivate RuntimeService runtimeService;@Resourceprivate TaskService taskService;@Resourceprivate HistoryService historyService;@Resourceprivate HttpServletRequest request;/*** 部署流程,测试会签功能*/@Testpublic void repositoryDeploy(){Deployment deploy = repositoryService.createDeployment().addClasspathResource("processes/activiti_jointlySign.bpmn").addClasspathResource("processes/activiti_jointlySign.png").name("测试会签功能-1").deploy();System.out.println("部署ID:"+deploy.getId());System.out.println("部署名称"+deploy.getName());}/*** 发布流程*/@Testpublic void runtimeRelease(){ArrayList<String> list = new ArrayList<>();list.add("tom");list.add("jack");list.add("mary");HashMap<String, Object> map = new HashMap<>();map.put("assignees",list);ProcessInstance pi = runtimeService.startProcessInstanceByKey("jointlySign",map);System.out.println("流程实例ID:"+pi.getId());System.out.println("流程定义ID:"+pi.getProcessDefinitionId());}/*** 查询及完成任务-需要所有会签全部完成*/@Testpublic void taskQueryComplete(){List<Task> list = taskService.createTaskQuery().taskAssignee("tom").list();for (Task task : list) {System.out.println("--------------------------------------------");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());taskService.complete(task.getId());}}
}

数据库历史记录:
需要三个人全部完成才能结束,通过结束时间可以看出这三个人都是必须完成任务的。

第二张为:${nrOfCompletedInstances/nrOfInstances >= 0.6},表示需要两个会签任务完成就会往下执行。

Bpmn文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 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" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1597111769369" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema"><process id="jointlySign2" isClosed="false" isExecutable="true" processType="None"><startEvent id="_2" name="开始"/><userTask activiti:assignee="${assignee}" activiti:candidateGroups="生产部领导" activiti:exclusive="true" id="_3" name="生产部领导会签"><multiInstanceLoopCharacteristics activiti:collection="${assignees}" activiti:elementVariable="assignee" isSequential="false"><completionCondition><![CDATA[${nrOfCompletedInstances/nrOfInstances>0.6}]]></completionCondition></multiInstanceLoopCharacteristics></userTask><endEvent id="_4" name="结束"/><sequenceFlow id="_5" sourceRef="_2" targetRef="_3"/><sequenceFlow id="_6" sourceRef="_3" targetRef="_4"/></process><bpmndi:BPMNDiagram documentation="background=#000000;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram"><bpmndi:BPMNPlane bpmnElement="jointlySign2"><bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2"><omgdc:Bounds height="32.0" width="32.0" x="400.0" y="15.0"/><bpmndi:BPMNLabel><omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3"><omgdc:Bounds height="55.0" width="85.0" x="375.0" y="170.0"/><bpmndi:BPMNLabel><omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4"><omgdc:Bounds height="32.0" width="32.0" x="405.0" y="345.0"/><bpmndi:BPMNLabel><omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNShape><bpmndi:BPMNEdge bpmnElement="_5" id="BPMNEdge__5" sourceElement="_2" targetElement="_3"><omgdi:waypoint x="416.0" y="47.0"/><omgdi:waypoint x="416.0" y="170.0"/><bpmndi:BPMNLabel><omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="_6" id="BPMNEdge__6" sourceElement="_3" targetElement="_4"><omgdi:waypoint x="421.0" y="225.0"/><omgdi:waypoint x="421.0" y="345.0"/><bpmndi:BPMNLabel><omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/></bpmndi:BPMNLabel></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>

测试类

package com.yb;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.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;/*** @author liangjie@itcast.cn* @version 1.0* @date 2020/8/5*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiJpaTest05 {@Resourceprivate RepositoryService repositoryService;@Resourceprivate RuntimeService runtimeService;@Resourceprivate TaskService taskService;@Resourceprivate HistoryService historyService;@Resourceprivate HttpServletRequest request;/*** 部署流程,测试会签功能*/@Testpublic void repositoryDeploy(){Deployment deploy = repositoryService.createDeployment().addClasspathResource("processes/activiti_jointlySign2.bpmn").addClasspathResource("processes/activiti_jointlySign2.png").name("测试会签功能-2").deploy();System.out.println("部署ID:"+deploy.getId());System.out.println("部署名称"+deploy.getName());}/*** 发布流程*/@Testpublic void runtimeRelease(){ArrayList<String> list = new ArrayList<>();list.add("tom");list.add("jack");list.add("mary");HashMap<String, Object> map = new HashMap<>();map.put("assignees",list);ProcessInstance pi = runtimeService.startProcessInstanceByKey("jointlySign2",map);System.out.println("流程实例ID:"+pi.getId());System.out.println("流程定义ID:"+pi.getProcessDefinitionId());}/*** 查询及完成任务*/@Testpublic void taskQueryComplete(){List<Task> list = taskService.createTaskQuery().taskAssignee("tom").list();for (Task task : list) {System.out.println("--------------------------------------------");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());taskService.complete(task.getId());}}
}

数据库历史记录:
需要二个人完成就可以结束,通过结束时间可以看出这有两个人的结束时间是相同的,说明只要有两个人完成任务就可以结束流程了。

Activiti6+SpringBoot---会签功能学习-1相关推荐

  1. Springboot中国古代史在线学习网站 毕业设计-附源码260839

    Springboot中国古代史在线学习网站 摘要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为 ...

  2. SpringBoot整合Shiro学习(上)

    SpringBoot整合Shiro(上) 基于[编程不良人]2020最新版Shiro教程,整合SpringBoot项目实战教程 哔哩哔哩链接:https://www.bilibili.com/vide ...

  3. springboot在线教育学习系统在线视频点播系统毕业设计毕设作品开题报告开题答辩PPT

    springboot在线教育学习系统在线视频点播系统毕业设计毕设作品开题报告开题答辩PPT 用户注册:填写手机账号和密码,注册新用户 登录功能:注册普通账号登录:登录后可以修改用户的基本信息,也可以退 ...

  4. 基于Springboot的书籍学习平台

    摘要 首先,论文一开始便是清楚的论述了平台的研究内容.其次,剖析平台需求分析,弄明白"做什么",分析包括业务分析和业务流程的分析以及用例分析,更进一步明确平台的需求.然后在明白了平 ...

  5. 基于Springboot实现在线学习管理平台

    项目编号:BS-XX-064 运行环境: 开发工具:IDEA / ECLIPSE 数据库:MYSQL5.7 应用服务器:TOMCAT8.5.31 JDK:1.8 后台开发技术:Springboot+m ...

  6. Springboot中国古代史在线学习网站毕业设计源码260839

    Springboot中国古代史在线学习网站 摘要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为 ...

  7. java springboot VUE 在线学习平台系统开发mysql数据库web结构java编程计算机网页源码maven项目前后端分离

    一.源码特点   springboot VUE 在线学习平台系统是一套完善的完整信息管理类型系统 前后端分离,结合springboot框架和VUE完成本系统,对理解JSP java编程开发语言有帮助系 ...

  8. 一文带你看懂Springboot核心功能及优缺点

    点击上方[视学算法]→右上角[...]→[设为星标⭐] SpringBoot核心功能 1.独立运行Spring项目 Spring boot 可以以jar包形式独立运行,运行一个Spring Boot项 ...

  9. 图片裁剪功能学习小结

    图片裁剪功能学习小结 近期有需要使用图片裁剪的功能,在使用插件和自己写裁剪组件之间犹豫了很久,后来根据需求经过反复的考虑,还是自己封装吧,毕竟自己动手,丰衣足食,对吧?嗯,??????是的!最后生成裁 ...

最新文章

  1. thinkphp-条件判断-范围判断-range标签
  2. 关东升的《从零开始学Swift》3月9日已经上架
  3. python基础第六天
  4. XMPP接受发送消息
  5. c语言日期编程,C语言编程计算第二天日期示例代码
  6. Java 将 Word 文档转换为 PDF 的完美工具
  7. java解密方法,java加密,解密方法
  8. java流与文件——java生成解压缩文件(夹)
  9. 使用Spring Security保护REST服务
  10. 重装Microsoft .NET Framework 4.0
  11. 写这么骚的代码,不怕被揍么?
  12. 34款管理系统、ERP、CRM、OA等(冠唐\金蝶等)
  13. 电脑分辨率怎么调?教你调整电脑屏幕分辨率
  14. 6. LaTeX 参考文献的排版与引用
  15. google play 爬虫项目
  16. 关于求余和取模的区别以及负数取摸
  17. monthcalendar_Python日历模块| 带有示例的monthcalendar()方法
  18. 软考高级系统架构设计师你想知道的全在这
  19. oracle12c创建监听,Oracle 12c为PDB创建专用监听
  20. FTDI FTD2XX 驱动学习笔记(一)

热门文章

  1. 前端基础(二)----- CSS初识
  2. TwinCAT PLC 使用
  3. python多线程图片处理
  4. Le Chapitre IV
  5. 计算机专业英语教学反思,高中英语课堂教学反思
  6. 客户端iOS 的自动化测试
  7. LuoguP1710 地铁涨价
  8. 区块链已成主流,BATJ纷纷加速布局
  9. 说一下zoom:1的原理,万一被问到呢?
  10. B1192 [HNOI2006]超级英雄Hero 二分图匹配