IT虾米网

工作流activity的学习总结详解

admin 2018年06月07日 编程语言 1234 0

一、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内容如下:

<?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="leave" name="请假流程图" isExecutable="true">   <documentation>请假流程图</documentation>   <startEvent id="startevent1" name="Start"></startEvent>   <endEvent id="endevent1" name="End"></endEvent>   <!-- ${employeeId} 中的employeeId 在启动流程实例的时候,就设置employeeId变量。再根据employeeId获取员工请假任务,最后设置请假时间进行提交-->   <userTask id="usertask1" name="员工请假" activiti:assignee="${employeeId}"></userTask>   <userTask id="usertask2" name="经理审批" activiti:candidateGroups="manager"></userTask>   <userTask id="usertask3" name="总经理审批" activiti:candidateGroups="boss"></userTask>   <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>   <sequenceFlow id="flow2" name="${flag == true}" sourceRef="usertask2" targetRef="endevent1">      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == true}]]></conditionExpression>   </sequenceFlow>   <sequenceFlow id="flow3" name="${flag == true}" sourceRef="usertask3" targetRef="endevent1">      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == true}]]></conditionExpression>   </sequenceFlow>   <sequenceFlow id="flow4" name="${flag == false}" sourceRef="usertask2" targetRef="usertask1">      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == false}]]></conditionExpression>   </sequenceFlow>   <sequenceFlow id="flow5" name="${flag == false}" sourceRef="usertask3" targetRef="usertask1">      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag == false}]]></conditionExpression>   </sequenceFlow>   <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>   <sequenceFlow id="flow6" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow>   <sequenceFlow id="flow7" name="${day &lt;= 2}" sourceRef="exclusivegateway1" targetRef="usertask2">      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day <= 2}]]></conditionExpression>   </sequenceFlow>   <sequenceFlow id="flow8" name="${day &gt; 2}" sourceRef="exclusivegateway1" targetRef="usertask3">      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day > 2}]]></conditionExpression>   </sequenceFlow>  </process>  <bpmndi:BPMNDiagram id="BPMNDiagram_leave">    <bpmndi:BPMNPlane bpmnElement="leave" id="BPMNPlane_leave">       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">          <omgdc:Bounds height="35.0" width="35.0" x="355.0" y="48.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">          <omgdc:Bounds height="35.0" width="35.0" x="355.0" y="362.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">          <omgdc:Bounds height="55.0" width="105.0" x="320.0" y="112.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">          <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="240.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">          <omgdc:Bounds height="55.0" width="105.0" x="480.0" y="242.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">          <omgdc:Bounds height="40.0" width="40.0" x="352.0" y="247.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">          <omgdi:waypoint x="372.0" y="83.0"></omgdi:waypoint>          <omgdi:waypoint x="372.0" y="112.0"></omgdi:waypoint>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">          <omgdi:waypoint x="222.0" y="295.0"></omgdi:waypoint>          <omgdi:waypoint x="222.0" y="379.0"></omgdi:waypoint>          <omgdi:waypoint x="355.0" y="379.0"></omgdi:waypoint>          <bpmndi:BPMNLabel>              <omgdc:Bounds height="14.0" width="100.0" x="183.0" y="309.0"></omgdc:Bounds>          </bpmndi:BPMNLabel>        </bpmndi:BPMNEdge>        <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">          <omgdi:waypoint x="532.0" y="297.0"></omgdi:waypoint>          <omgdi:waypoint x="532.0" y="379.0"></omgdi:waypoint>          <omgdi:waypoint x="390.0" y="379.0"></omgdi:waypoint>          <bpmndi:BPMNLabel>             <omgdc:Bounds height="14.0" width="100.0" x="483.0" y="309.0"></omgdc:Bounds>          </bpmndi:BPMNLabel>         </bpmndi:BPMNEdge>         <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">           <omgdi:waypoint x="222.0" y="240.0"></omgdi:waypoint>           <omgdi:waypoint x="222.0" y="139.0"></omgdi:waypoint>           <omgdi:waypoint x="320.0" y="139.0"></omgdi:waypoint>           <bpmndi:BPMNLabel>              <omgdc:Bounds height="14.0" width="100.0" x="170.0" y="191.0"></omgdc:Bounds>           </bpmndi:BPMNLabel>          </bpmndi:BPMNEdge>          <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">            <omgdi:waypoint x="532.0" y="242.0"></omgdi:waypoint>            <omgdi:waypoint x="532.0" y="139.0"></omgdi:waypoint>            <omgdi:waypoint x="425.0" y="139.0"></omgdi:waypoint>            <bpmndi:BPMNLabel>               <omgdc:Bounds height="14.0" width="100.0" x="485.0" y="191.0"></omgdc:Bounds>            </bpmndi:BPMNLabel>          </bpmndi:BPMNEdge>          <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">            <omgdi:waypoint x="372.0" y="167.0"></omgdi:waypoint>            <omgdi:waypoint x="372.0" y="247.0"></omgdi:waypoint>          </bpmndi:BPMNEdge>          <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">            <omgdi:waypoint x="352.0" y="267.0"></omgdi:waypoint>            <omgdi:waypoint x="275.0" y="267.0"></omgdi:waypoint>            <bpmndi:BPMNLabel>               <omgdc:Bounds height="14.0" width="100.0" x="283.0" y="247.0"></omgdc:Bounds>            </bpmndi:BPMNLabel>          </bpmndi:BPMNEdge>          <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">            <omgdi:waypoint x="392.0" y="267.0"></omgdi:waypoint>            <omgdi:waypoint x="480.0" y="269.0"></omgdi:waypoint>            <bpmndi:BPMNLabel>               <omgdc:Bounds height="14.0" width="100.0" x="400.0" y="247.0"></omgdc:Bounds>            </bpmndi:BPMNLabel>          </bpmndi:BPMNEdge>        </bpmndi:BPMNPlane>      </bpmndi:BPMNDiagram>   </definitions>



2、测试类LeaveTest代码如下:

package com.shh.test; 
   
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
   
import org.activiti.engine.HistoryService; 
import org.activiti.engine.ProcessEngine; 
import org.activiti.engine.ProcessEngineConfiguration; 
import org.activiti.engine.RepositoryService; 
import org.activiti.engine.RuntimeService; 
import org.activiti.engine.TaskService; 
import org.activiti.engine.history.HistoricProcessInstanceQuery; 
import org.activiti.engine.task.Task; 
import org.junit.Before; 
import org.junit.Test; 
/**  
 * 请假流程 
 */  
public class LeaveTest { 
    ProcessEngine processEngine = null; 
    RepositoryService repositoryService = null; 
    RuntimeService runtimeService = null; 
    TaskService taskService = null;  
  
    /**  
     * 加载配置文件 
     */  
    @Before 
    public void init() { 
        processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml") 
                .buildProcessEngine(); 
        repositoryService = processEngine.getRepositoryService(); 
        runtimeService = processEngine.getRuntimeService(); 
        taskService = processEngine.getTaskService(); 
    } 
  
    /**  
     * 部署流程定义 
     */  
    @Test 
    public void deploy(){ 
        repositoryService.createDeployment().addClasspathResource("diagrams/leave.bpmn").deploy(); 
        System.out.println("***************部署流程定义完成***************"); 
    } 
      
    /**  
     * 启动一个请假流程 
     */  
    @Test 
    public void start() { 
        Map<String, Object> variables = new HashMap<String, Object>(); 
        variables.put("employeeId", "Kermit"); //请假人  
        String processId = runtimeService.startProcessInstanceByKey("leave", variables).getId(); 
        System.out.println("***************启动一个请假流程完成***************" + processId); 
    } 
  
    /**  
     * 提交请假申请 
     */  
    @Test 
    public void apply(){ 
        System.out.println("***************提交请假申请开始***************"); 
        List<Task> tasks = taskService.createTaskQuery().taskAssignee("Kermit").list(); 
        System.out.println(tasks.size()); 
        for (Task task : tasks) { 
            System.out.println("Kermit的任务taskname:" + task.getName() + ",id:" + task.getId()); 
            taskService.setVariable(task.getId(), "day", 4);//设置请假天数  
            taskService.complete(task.getId());//完成任务    
            System.out.println("请假4 天"); 
        } 
        System.out.println("***************提交请假申请完成***************"); 
    } 
      
    @Test 
    public void step2manager() { 
        System.out.println("***************经理组审批流程开始***************"); 
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("manager").list();// 经理组的任务  
        System.out.println("经理组的任务:" + tasks.size()); 
        for (Task task : tasks) { 
            System.out.println("经理组的任务taskname:" + task.getName() + ",id:" + task.getId()); 
            taskService.claim(task.getId(), "李四");//申领任务   
            taskService.setVariable(task.getId(), "flag", false);//true批准,false不批准  
            Object applyUser = taskService.getVariable(task.getId(), "employeeId"); 
            Object day = taskService.getVariable(task.getId(), "day"); 
            System.out.println(String.format("%s请假%s天", applyUser, day)); 
            taskService.complete(task.getId());//完成任务   
        } 
        System.out.println("***************经理组审批流程结束***************"); 
    } 
      
    @Test 
    public void step2Boss() { 
        System.out.println("***************总经理组审批流程开始***************"); 
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("boss").list();// 总经理组的任务  
        System.out.println("总经理组的任务:" + tasks.size()); 
        for (Task task : tasks) { 
            System.out.println("manager的任务taskname:" + task.getName() + ",id:" + task.getId()); 
            taskService.claim(task.getId(), "王五");//申领任务  
            taskService.setVariable(task.getId(), "flag", true);//true批准,false不批准 
            Object applyUser = taskService.getVariable(task.getId(), "employeeId"); 
            Object day = taskService.getVariable(task.getId(), "day"); 
            System.out.println(String.format("%s请假%s天", applyUser, day)); 
            taskService.complete(task.getId());//完成任务  
        } 
        System.out.println("***************总经理组审批流程结束***************"); 
    } 
}

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


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

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

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

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

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


发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

ZooKeeper学习第一期---Zookeeper简单介绍详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。