• Activiti之 Exclusive Gateway


    一、Exclusive Gateway

      Exclusive Gateway(也称为XOR网关或更多技术基于数据的排他网关)经常用做决定流程的流转方向。当流程到达该网关的时候,所有的流出序列流到按照已定义好的顺序依次执行。当序列流条件的求值结果为true(或没有条件集的时候,在概念上有定义一个“true”定义序列流),就会选择该序列继续的处理。Exclusive Gateway的图标就是菱形里面有一个X符合,如下所示:

      

      XML的代码为:

    <exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" />
    
    <sequenceFlow id="flow2" sourceRef="exclusiveGw" targetRef="theTask1">
      <conditionExpression xsi:type="tFormalExpression">${input == 1}</conditionExpression>
    </sequenceFlow>
    
    <sequenceFlow id="flow3" sourceRef="exclusiveGw" targetRef="theTask2">
      <conditionExpression xsi:type="tFormalExpression">${input == 2}</conditionExpression>
    </sequenceFlow>
    
    <sequenceFlow id="flow4" sourceRef="exclusiveGw" targetRef="theTask3">
      <conditionExpression xsi:type="tFormalExpression">${input == 3}</conditionExpression>
    </sequenceFlow>

     二、示例

      本例子以请假流程为例,流程设计图如下图所示:

      

      当员工提出的请假时间大于2天的时候由总经理审批,当请假时间不大于2天的时候由经理审批。

      1、leave.bpmn内容如下: 

      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <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">
      3   <process id="leave" name="请假流程图" isExecutable="true">
      4     <documentation>请假流程图</documentation>
      5     <startEvent id="startevent1" name="Start"></startEvent>
      6     <endEvent id="endevent1" name="End"></endEvent>
      7     <!-- ${employeeId} 中的employeeId 在启动流程实例的时候,就设置employeeId变量。再根据employeeId获取员工请假任务,最后设置请假时间进行提交-->
      8     <userTask id="usertask1" name="员工请假" activiti:assignee="${employeeId}"></userTask>
      9     <userTask id="usertask2" name="经理审批" activiti:candidateGroups="manager"></userTask>
     10     <userTask id="usertask3" name="总经理审批" activiti:candidateGroups="boss"></userTask>
     11     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
     12     <sequenceFlow id="flow2" name="${flag == true}" sourceRef="usertask2" targetRef="endevent1">
     13       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == true}]]></conditionExpression>
     14     </sequenceFlow>
     15     <sequenceFlow id="flow3" name="${flag == true}" sourceRef="usertask3" targetRef="endevent1">
     16       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == true}]]></conditionExpression>
     17     </sequenceFlow>
     18     <sequenceFlow id="flow4" name="${flag == false}" sourceRef="usertask2" targetRef="usertask1">
     19       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == false}]]></conditionExpression>
     20     </sequenceFlow>
     21     <sequenceFlow id="flow5" name="${flag == false}" sourceRef="usertask3" targetRef="usertask1">
     22       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == false}]]></conditionExpression>
     23     </sequenceFlow>
     24     <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
     25     <sequenceFlow id="flow6" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow>
     26     <sequenceFlow id="flow7" name="${day &lt;= 2}" sourceRef="exclusivegateway1" targetRef="usertask2">
     27       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day <= 2}]]></conditionExpression>
     28     </sequenceFlow>
     29     <sequenceFlow id="flow8" name="${day &gt; 2}" sourceRef="exclusivegateway1" targetRef="usertask3">
     30       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day > 2}]]></conditionExpression>
     31     </sequenceFlow>
     32   </process>
     33   <bpmndi:BPMNDiagram id="BPMNDiagram_leave">
     34     <bpmndi:BPMNPlane bpmnElement="leave" id="BPMNPlane_leave">
     35       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
     36         <omgdc:Bounds height="35.0" width="35.0" x="355.0" y="48.0"></omgdc:Bounds>
     37       </bpmndi:BPMNShape>
     38       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
     39         <omgdc:Bounds height="35.0" width="35.0" x="355.0" y="362.0"></omgdc:Bounds>
     40       </bpmndi:BPMNShape>
     41       <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
     42         <omgdc:Bounds height="55.0" width="105.0" x="320.0" y="112.0"></omgdc:Bounds>
     43       </bpmndi:BPMNShape>
     44       <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
     45         <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="240.0"></omgdc:Bounds>
     46       </bpmndi:BPMNShape>
     47       <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
     48         <omgdc:Bounds height="55.0" width="105.0" x="480.0" y="242.0"></omgdc:Bounds>
     49       </bpmndi:BPMNShape>
     50       <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
     51         <omgdc:Bounds height="40.0" width="40.0" x="352.0" y="247.0"></omgdc:Bounds>
     52       </bpmndi:BPMNShape>
     53       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
     54         <omgdi:waypoint x="372.0" y="83.0"></omgdi:waypoint>
     55         <omgdi:waypoint x="372.0" y="112.0"></omgdi:waypoint>
     56       </bpmndi:BPMNEdge>
     57       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
     58         <omgdi:waypoint x="222.0" y="295.0"></omgdi:waypoint>
     59         <omgdi:waypoint x="222.0" y="379.0"></omgdi:waypoint>
     60         <omgdi:waypoint x="355.0" y="379.0"></omgdi:waypoint>
     61         <bpmndi:BPMNLabel>
     62           <omgdc:Bounds height="14.0" width="100.0" x="183.0" y="309.0"></omgdc:Bounds>
     63         </bpmndi:BPMNLabel>
     64       </bpmndi:BPMNEdge>
     65       <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
     66         <omgdi:waypoint x="532.0" y="297.0"></omgdi:waypoint>
     67         <omgdi:waypoint x="532.0" y="379.0"></omgdi:waypoint>
     68         <omgdi:waypoint x="390.0" y="379.0"></omgdi:waypoint>
     69         <bpmndi:BPMNLabel>
     70           <omgdc:Bounds height="14.0" width="100.0" x="483.0" y="309.0"></omgdc:Bounds>
     71         </bpmndi:BPMNLabel>
     72       </bpmndi:BPMNEdge>
     73       <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
     74         <omgdi:waypoint x="222.0" y="240.0"></omgdi:waypoint>
     75         <omgdi:waypoint x="222.0" y="139.0"></omgdi:waypoint>
     76         <omgdi:waypoint x="320.0" y="139.0"></omgdi:waypoint>
     77         <bpmndi:BPMNLabel>
     78           <omgdc:Bounds height="14.0" width="100.0" x="170.0" y="191.0"></omgdc:Bounds>
     79         </bpmndi:BPMNLabel>
     80       </bpmndi:BPMNEdge>
     81       <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
     82         <omgdi:waypoint x="532.0" y="242.0"></omgdi:waypoint>
     83         <omgdi:waypoint x="532.0" y="139.0"></omgdi:waypoint>
     84         <omgdi:waypoint x="425.0" y="139.0"></omgdi:waypoint>
     85         <bpmndi:BPMNLabel>
     86           <omgdc:Bounds height="14.0" width="100.0" x="485.0" y="191.0"></omgdc:Bounds>
     87         </bpmndi:BPMNLabel>
     88       </bpmndi:BPMNEdge>
     89       <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
     90         <omgdi:waypoint x="372.0" y="167.0"></omgdi:waypoint>
     91         <omgdi:waypoint x="372.0" y="247.0"></omgdi:waypoint>
     92       </bpmndi:BPMNEdge>
     93       <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
     94         <omgdi:waypoint x="352.0" y="267.0"></omgdi:waypoint>
     95         <omgdi:waypoint x="275.0" y="267.0"></omgdi:waypoint>
     96         <bpmndi:BPMNLabel>
     97           <omgdc:Bounds height="14.0" width="100.0" x="283.0" y="247.0"></omgdc:Bounds>
     98         </bpmndi:BPMNLabel>
     99       </bpmndi:BPMNEdge>
    100       <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
    101         <omgdi:waypoint x="392.0" y="267.0"></omgdi:waypoint>
    102         <omgdi:waypoint x="480.0" y="269.0"></omgdi:waypoint>
    103         <bpmndi:BPMNLabel>
    104           <omgdc:Bounds height="14.0" width="100.0" x="400.0" y="247.0"></omgdc:Bounds>
    105         </bpmndi:BPMNLabel>
    106       </bpmndi:BPMNEdge>
    107     </bpmndi:BPMNPlane>
    108   </bpmndi:BPMNDiagram>
    109 </definitions>

      2、测试类LeaveTest代码如下:

      1 package com.shh.test;
      2 
      3 import java.util.HashMap;
      4 import java.util.List;
      5 import java.util.Map;
      6 
      7 import org.activiti.engine.HistoryService;
      8 import org.activiti.engine.ProcessEngine;
      9 import org.activiti.engine.ProcessEngineConfiguration;
     10 import org.activiti.engine.RepositoryService;
     11 import org.activiti.engine.RuntimeService;
     12 import org.activiti.engine.TaskService;
     13 import org.activiti.engine.history.HistoricProcessInstanceQuery;
     14 import org.activiti.engine.task.Task;
     15 import org.junit.Before;
     16 import org.junit.Test;
     17 /**
     18  * 请假流程
     19  */
     20 public class LeaveTest {
     21     ProcessEngine processEngine = null;
     22     RepositoryService repositoryService = null;
     23     RuntimeService runtimeService = null;
     24     TaskService taskService = null; 
     25 
     26     /**
     27      * 加载配置文件
     28      */
     29     @Before
     30     public void init() {
     31         processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")
     32                 .buildProcessEngine();
     33         repositoryService = processEngine.getRepositoryService();
     34         runtimeService = processEngine.getRuntimeService();
     35         taskService = processEngine.getTaskService();
     36     }
     37 
     38     /**
     39      * 部署流程定义
     40      */
     41     @Test
     42     public void deploy(){
     43         repositoryService.createDeployment().addClasspathResource("diagrams/leave.bpmn").deploy();
     44         System.out.println("***************部署流程定义完成***************");
     45     }
     46     
     47     /**
     48      * 启动一个请假流程
     49      */
     50     @Test
     51     public void start() {
     52         Map<String, Object> variables = new HashMap<String, Object>();
     53         variables.put("employeeId", "Kermit"); //请假人
     54         String processId = runtimeService.startProcessInstanceByKey("leave", variables).getId();
     55         System.out.println("***************启动一个请假流程完成***************" + processId);
     56     }
     57 
     58     /**
     59      * 提交请假申请
     60      */
     61     @Test
     62     public void apply(){
     63         System.out.println("***************提交请假申请开始***************");
     64         List<Task> tasks = taskService.createTaskQuery().taskAssignee("Kermit").list();
     65         System.out.println(tasks.size());
     66         for (Task task : tasks) {
     67             System.out.println("Kermit的任务taskname:" + task.getName() + ",id:" + task.getId());
     68             taskService.setVariable(task.getId(), "day", 4);//设置请假天数
     69             taskService.complete(task.getId());//完成任务  
     70             System.out.println("请假4 天");
     71         }
     72         System.out.println("***************提交请假申请完成***************");
     73     }
     74     
     75     @Test
     76     public void step2manager() {
     77         System.out.println("***************经理组审批流程开始***************");
     78         List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("manager").list();// 经理组的任务
     79         System.out.println("经理组的任务:" + tasks.size());
     80         for (Task task : tasks) {
     81             System.out.println("经理组的任务taskname:" + task.getName() + ",id:" + task.getId());
     82             taskService.claim(task.getId(), "李四");//申领任务 
     83             taskService.setVariable(task.getId(), "flag", false);//true批准,false不批准
     84             Object applyUser = taskService.getVariable(task.getId(), "employeeId");
     85             Object day = taskService.getVariable(task.getId(), "day");
     86             System.out.println(String.format("%s请假%s天", applyUser, day));
     87             taskService.complete(task.getId());//完成任务 
     88         }
     89         System.out.println("***************经理组审批流程结束***************");
     90     }
     91     
     92     @Test
     93     public void step2Boss() {
     94         System.out.println("***************总经理组审批流程开始***************");
     95         List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("boss").list();// 总经理组的任务
     96         System.out.println("总经理组的任务:" + tasks.size());
     97         for (Task task : tasks) {
     98             System.out.println("manager的任务taskname:" + task.getName() + ",id:" + task.getId());
     99             taskService.claim(task.getId(), "王五");//申领任务 
    100             taskService.setVariable(task.getId(), "flag", true);//true批准,false不批准
    101             Object applyUser = taskService.getVariable(task.getId(), "employeeId");
    102             Object day = taskService.getVariable(task.getId(), "day");
    103             System.out.println(String.format("%s请假%s天", applyUser, day));
    104             taskService.complete(task.getId());//完成任务 
    105         }
    106         System.out.println("***************总经理组审批流程结束***************");
    107     }
    108 }    

      依次运行deploy()、start()、apply()方法之后,因为申请的请假天数为4天,所以流程已经到了总经理角色,此时运行step2Boss()方法,一个完整的请假流程就已经完成。运行结果如下图所示:

      

      也可对代码进行修改,总经理不批准

     taskService.setVariable(task.getId(), "flag", false);

     流程就回到员工那里,员工继续申请,设置天数为2
    taskService.setVariable(task.getId(), "day", 4);//设置请假天数

      此时流程到达经理角色,经理批准,流程也就结束

     taskService.setVariable(task.getId(), "flag", true);
  • 相关阅读:
    小白的源码阅读之旅_RazorEngine_起因
    Sqlserver_小工具_Json解析
    Sqlserver_小工具_批量字段约束处理
    SqlServer_小工具_获取数据库空间信息获取
    SqlServer_小工具_系统表的使用
    Sqlserver_小工具_字符统计(区分大小写)
    SqlServer_小工具_存储空间单位自适应
    不断优化,重构我的代码-----拖拽jquery插件
    canvas绘制二次贝塞尔曲线----演示二次贝塞尔四个参数的作用
    requestAnimationFrame与setInterval,setTimeout
  • 原文地址:https://www.cnblogs.com/always-online/p/4702394.html
Copyright © 2020-2023  润新知