大数跨境
0
0

Springboot整合工作流引擎Activiti(八)之并行网关

Springboot整合工作流引擎Activiti(八)之并行网关 Spring全家桶实战案例
2021-12-27
0
导读:Springboot整合工作流引擎Activiti(八)之并行网关

环境:Springboot2.3.12.RELEASE + Activiti7.1.0.M6


本篇内容:主要介绍并行网关的使用。

简介

并行网关是指流程中需要并行执行的用户任务,他允许流程从一个流程分出多个分支,也可以把多个流程合并成一个。

并行网关有两个功能,分别是分支汇聚

分支:由一个分支分成多个分支,为每个顺序流都创建一个并发分支。

汇聚:所有到达并行网关的多条分支会合成一个分支来往下执行。

并行网关排他网关的主要区别是,并行网关不会解析条件。即使顺序流中定义了条件,也会被忽略。

实例

这里以一个报销单审批的例子来看并行网关的分支汇聚功能。

流程设计

4个用户任务,都分别动态指定了assignee执行人。

首先 "员工报销单" 任务填写报销单,由并行网关设计两个分支,分别由副经理和经理审批

最后 "副经理"和"经理" 都审批通过了以后才会由并行网关汇聚进入到"总经理"。

流程设计代码如下:

<?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/test">  <process id="ps" name="ps" isExecutable="true">    <startEvent id="startEvent" name="开始"></startEvent>    <parallelGateway id="parallelgateway" name="并行执行"></parallelGateway>    <userTask id="usertask1" name="副经理" activiti:assignee="${fjl}"></userTask>    <userTask id="usertask2" name="经理" activiti:assignee="${jl}"></userTask>    <parallelGateway id="parallelgateway1" name="Parallel Gateway"></parallelGateway>    <sequenceFlow id="flow4" sourceRef="parallelgateway" targetRef="usertask1"></sequenceFlow>    <sequenceFlow id="flow5" sourceRef="parallelgateway" targetRef="usertask2"></sequenceFlow>    <sequenceFlow id="flow6" sourceRef="usertask1" targetRef="parallelgateway1"></sequenceFlow>    <sequenceFlow id="flow7" sourceRef="usertask2" targetRef="parallelgateway1"></sequenceFlow>    <userTask id="usertask3" name="总经理" activiti:assignee="${zjl}"></userTask>    <sequenceFlow id="flow8" sourceRef="parallelgateway1" targetRef="usertask3"></sequenceFlow>    <endEvent id="endevent1" name="End"></endEvent>    <sequenceFlow id="flow9" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>    <userTask id="usertask4" name="员工报销单" activiti:assignee="${userId}"></userTask>    <sequenceFlow id="flow10" sourceRef="usertask4" targetRef="parallelgateway"></sequenceFlow>    <sequenceFlow id="flow11" sourceRef="startEvent" targetRef="usertask4"></sequenceFlow>  </process>  <!-- ... --></definitions>

启动流程

@GetMapping("/start")public R startProcess(String processDefinitionId, String userId) {  Map<String, Object> variables = new HashMap<>() ;  variables.put("userId", userId) ;  // 启动流程实例(同时启动第一步任务,当前启动审批流程及填写审批单一步完成)  ProcessInstance instance = ps.startProcessInstanceAssignVariables(processDefinitionId, variables) ;  // 当前执行的任务节点是“员工请假”  // 设置下一步执行的人  variables.put("fjl", "20000") ;  variables.put("jl", "20001") ;  ps.executionTask(variables, instance.getId());  return R.success() ;}

运行时任务节点表( act_ru_task )

2个执行的任务节点,分别是副经理和经理审批的任务

运行时流程执行实例表( act_ru_execution )

实例表中一个流程实例和2个执行的任务对象


在上面启动任务的代码中已经制定了 副经理 和 经理 执行人的ID。

审批任务

先来分别查询下需要我处理的任务

@GetMapping("/tasks")public R myTasks(String userId) {  List<Task> list = ps.queryTasks(userId) ;  List<Map<String, Object>> result = list.stream().map(task -> {    Map<String, Object> res = new HashMap<String, Object>() ;    res.put("id", task.getId()) ;    res.put("assignee", task.getAssignee()) ;    res.put("createTime", task.getCreateTime()) ;    res.put("bussinessKey", task.getBusinessKey()) ;    res.put("category", task.getCategory()) ;    res.put("dueDate", task.getDueDate()) ; // 到期日期    res.put("desc", task.getDescription()) ;    res.put("name", task.getName()) ;    res.put("owner", task.getOwner()) ;    res.put("instanceId", task.getProcessInstanceId()) ;    res.put("variables", task.getProcessVariables()) ;    res.put("state", task.isSuspended()) ;    return res ;  }).collect(Collectors.toList()) ;  return R.success(result) ;}

副经理

经理

接下来就是审批处理了

@GetMapping("/approve")public R approve(@RequestParam Map<String, Object> variables) {  String instanceId = (String) variables.remove("instanceId") ;  if (StringUtils.isEmpty(instanceId)) {    return R.failure("未知任务") ;  }  ps.executionTask(variables, instanceId);  return R.success() ; }

副经理审批

act_ru_task

任务只有经理

act_ru_execution

运行时流程实例表中只有usertask2是活动的,此时的汇聚并行网关的状态为0

经理审批

act_ru_task

任务节点到了总经理

act_ru_execution

运行时流程实例表中只有usertask3(总经理),此时的并行网关 汇聚的活动状态转为1

总经理审批

act_ru_task

流程结束了

到此整个流程就执行结束了,并行网关的执行是不是很简单,没有什么逻辑就是起到一个分支汇聚的作用。

完毕!!!

求个关注谢谢


【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读38
粉丝0
内容832