【Activiti工作流】5. 简单请假流程

1. 画出流程图

使用之前安装的Eclipse的流程设计器,画出如下流程图:
这里写图片描述

1.1 设置开始节点

这里写图片描述
在properties中选中Main config;设置如下:
这里写图片描述
然后选中Form,设置如下:
这里写图片描述
具体操作方式是:点击右边New,
设置请假开始日期:
这里写图片描述
设置请假结束日期:
这里写图片描述
设置请假原因:
这里写图片描述
开始节点对应的XML代码:

 <startEvent id="startevent" name="开始" activiti:initiator="applUserId">
      <extensionElements>
        <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyy-MM-dd" required="true"></activiti:formProperty>
        <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty>
        <activiti:formProperty id="reason" name="请假原因" type="string" required="true"></activiti:formProperty>
      </extensionElements>
    </startEvent>

1.2 设置部门领导审批任务

具体操作如下:
这里写图片描述
在properties中选中General;设置如下:
这里写图片描述
选中Main config;设置如下:
这里写图片描述
选中Form设置如下:
这里写图片描述
具体设置如下:
设置请假开始日期:
这里写图片描述
设置请假结束日期:
这里写图片描述
设置请假原因:
这里写图片描述
设置审核意见:
这里写图片描述
审核节点对应XML代码如下:

    <userTask id="deptLeaderAudit" name="部门领导审批" activiti:assignee="wangwu">
      <extensionElements>
        <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
        <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
        <activiti:formProperty id="reason" name="请假原因" type="string" writable="false"></activiti:formProperty>
        <activiti:formProperty id="deptLeaderApprove" name="审核意见" type="enum" required="true">
          <activiti:value id="true" name="同意"></activiti:value>
          <activiti:value id="false" name="不同意"></activiti:value>
        </activiti:formProperty>
      </extensionElements>
    </userTask>

需要注意的是Eclipse的流程设计器页面上没有Value属性的设置,所以只能在XML中进行修改配置:

    <userTask id="deptLeaderAudit" name="部门领导审批" activiti:assignee="wangwu">
      <extensionElements>
        <activiti:formProperty id="startDate" name="请假开始日期" type="date" value="${startDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
        <activiti:formProperty id="endDate" name="请假结束日期" type="date" value="${endDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
        <activiti:formProperty id="reason" name="请假原因" type="string" value="${reason}" writable="false"></activiti:formProperty>
        <activiti:formProperty id="deptLeaderApprove" name="审核意见" type="enum" required="true">
          <activiti:value id="true" name="同意"></activiti:value>
          <activiti:value id="false" name="不同意"></activiti:value>
        </activiti:formProperty>
      </extensionElements>
    </userTask>

1.3 设置排他网关流出连线的设置

选中一条连线(同意)设置如下:
这里写图片描述
设置Main Config如下:
这里写图片描述

设置不同意连线如下:
这里写图片描述

这里写图片描述

调整申请任务节点和部门经理审核节点类似。

点击流程图空处,设置如下:
这里写图片描述

完整流程图XML如下:

<?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="LeaveProcess" name="LeaveProcess" isExecutable="true">
    <startEvent id="startevent" name="开始" activiti:initiator="applUserId">
      <extensionElements>
        <activiti:formProperty id="startDate" name="请假开始日期" type="date" datePattern="yyy-MM-dd" required="true"></activiti:formProperty>
        <activiti:formProperty id="endDate" name="请假结束日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty>
        <activiti:formProperty id="reason" name="请假原因" type="string" required="true"></activiti:formProperty>
      </extensionElements>
    </startEvent>
    <userTask id="deptLeaderAudit" name="部门领导审批" activiti:assignee="wangwu">
      <extensionElements>
        <activiti:formProperty id="startDate" name="请假开始日期" type="date" value="${startDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
        <activiti:formProperty id="endDate" name="请假结束日期" type="date" value="${endDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty>
        <activiti:formProperty id="reason" name="请假原因" type="string" value="${reason}" writable="false"></activiti:formProperty>
        <activiti:formProperty id="deptLeaderApprove" name="审核意见" type="enum" required="true">
          <activiti:value id="true" name="同意"></activiti:value>
          <activiti:value id="false" name="不同意"></activiti:value>
        </activiti:formProperty>
      </extensionElements>
    </userTask>
    <endEvent id="endevent" name="结束"></endEvent>
    <sequenceFlow id="flow1" sourceRef="startevent" targetRef="deptLeaderAudit"></sequenceFlow>
    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow2" sourceRef="deptLeaderAudit" targetRef="exclusivegateway1"></sequenceFlow>
    <sequenceFlow id="flow3" name="同意" sourceRef="exclusivegateway1" targetRef="endevent">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApprove=='true'}]]></conditionExpression>
    </sequenceFlow>
    <userTask id="modifyAppl" name="调整申请" activiti:assignee="${applUserId}">
      <extensionElements>
        <activiti:formProperty id="startDate" name="请假开始日期" type="date" value="${startDate}" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty>
        <activiti:formProperty id="endDate" name="请假结束日期" type="date" value="${endDate}" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty>
        <activiti:formProperty id="reason" name="请假原因" type="string" value="${reason}" required="true"></activiti:formProperty>
        <activiti:formProperty id="reAppl" name="重新申请" type="enum" required="true">
          <activiti:value id="true" name="重新申请"></activiti:value>
          <activiti:value id="false" name="取消申请"></activiti:value>
        </activiti:formProperty>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow4" name="不同意" sourceRef="exclusivegateway1" targetRef="modifyAppl">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApprove=='false'}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow5" sourceRef="modifyAppl" targetRef="exclusivegateway2"></sequenceFlow>
    <sequenceFlow id="flow6" name="取消申请" sourceRef="exclusivegateway2" targetRef="endevent">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reAppl=='false'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow7" name="重新申请" sourceRef="exclusivegateway2" targetRef="deptLeaderAudit">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reAppl=='true'}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_LeaveProcess">
    <bpmndi:BPMNPlane bpmnElement="LeaveProcess" id="BPMNPlane_LeaveProcess">
      <bpmndi:BPMNShape bpmnElement="startevent" id="BPMNShape_startevent">
        <omgdc:Bounds height="35.0" width="35.0" x="215.0" y="41.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="deptLeaderAudit" id="BPMNShape_deptLeaderAudit">
        <omgdc:Bounds height="55.0" width="105.0" x="180.0" y="130.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent" id="BPMNShape_endevent">
        <omgdc:Bounds height="35.0" width="35.0" x="217.0" y="370.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="214.0" y="250.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="modifyAppl" id="BPMNShape_modifyAppl">
        <omgdc:Bounds height="55.0" width="105.0" x="350.0" y="243.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
        <omgdc:Bounds height="40.0" width="40.0" x="550.0" y="250.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="232.0" y="76.0"></omgdi:waypoint>
        <omgdi:waypoint x="232.0" y="130.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="232.0" y="185.0"></omgdi:waypoint>
        <omgdi:waypoint x="234.0" y="250.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="234.0" y="290.0"></omgdi:waypoint>
        <omgdi:waypoint x="234.0" y="370.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="241.0" y="320.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="254.0" y="270.0"></omgdi:waypoint>
        <omgdi:waypoint x="350.0" y="270.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="36.0" x="269.0" y="278.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
        <omgdi:waypoint x="455.0" y="270.0"></omgdi:waypoint>
        <omgdi:waypoint x="550.0" y="270.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
        <omgdi:waypoint x="570.0" y="290.0"></omgdi:waypoint>
        <omgdi:waypoint x="570.0" y="387.0"></omgdi:waypoint>
        <omgdi:waypoint x="252.0" y="387.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="48.0" x="580.0" y="332.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
        <omgdi:waypoint x="570.0" y="250.0"></omgdi:waypoint>
        <omgdi:waypoint x="569.0" y="157.0"></omgdi:waypoint>
        <omgdi:waypoint x="285.0" y="157.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="48.0" x="581.0" y="211.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

2. 测试流程

2.1 部署流程图

流程图所在的目录如下:
这里写图片描述
部署流程图代码如下:

package com.activiti;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.FormService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;

public class LeaveTest {

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**部署流程定义*/  
    @Test  
    public void deploymentProcessDefinition(){  
        RepositoryService repositoryService = processEngine.getRepositoryService();  
        DeploymentBuilder deploymentBuilder=repositoryService.createDeployment(); 
        deploymentBuilder.name("请假流程");
        deploymentBuilder.addClasspathResource("diagrams/LeaveProcess.bpmn");
        deploymentBuilder.addClasspathResource("diagrams/LeaveProcess.png");
        Deployment deployment = deploymentBuilder.deploy();
        //打印我们的流程信息  
        System.out.println("流程Id:"+deployment.getId());  
        System.out.println("流程Name:"+deployment.getName());  
        System.out.println("——————————————————————————————————————————————————"); 
    }
}

测试结果如下:

流程Id:1
流程Name:请假流程
——————————————————————————————————————————————————

2.2 启动流程图

    /**启动流程引擎*/  
    @Test  
    public void startProcessInstance(){
        RepositoryService repositoryService = processEngine.getRepositoryService();  
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("LeaveProcess").singleResult();
        //设置动态表单
        processEngine.getIdentityService().setAuthenticatedUserId("zhaoliu");
        Map<String , String > params = new HashMap<String , String  >();
        SimpleDateFormat  sdt  = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        String startDate = sdt.format(calendar.getTime());
        calendar.add(Calendar.DAY_OF_MONTH, 2);
        String endDate = sdt.format(calendar.getTime());
        params.put("startDate", startDate);
        params.put("endDate", endDate);
        params.put("reason", "我要休息");
        FormService formService = processEngine.getFormService();
        ProcessInstance processInstance = formService.submitStartFormData(processDefinition.getId(), params);
        System.out.println("流程实例ID:"+processInstance.getId());  
        System.out.println("流程定义ID:"+processInstance.getProcessDefinitionId());
        System.out.println("——————————————————————————————————————————————————"); 
    } 

测试结果如下:

流程实例ID:2501
流程定义IDLeaveProcess:1:4
——————————————————————————————————————————————————

2.3 部门经理审核

审核通过: params.put(“deptLeaderApprove”, “true”);
审核拒绝: params.put(“deptLeaderApprove”, “false”);

 /**部门领导审批通过**/ 
    @Test  
    public void deptLeaderAuditPass(){  
        String assignee="wangwu";  
        FormService formService = processEngine.getFormService();
        TaskService taskService = processEngine.getTaskService();  
        Task deptLeaderTask = taskService.createTaskQuery().taskAssignee(assignee).singleResult(); 
        //打印请假人提交的表单信息
        List<FormProperty> formProperties = formService.getTaskFormData(deptLeaderTask.getId()).getFormProperties();
        for (FormProperty formProperty : formProperties) {
             if(!"enum".equals(formProperty.getType().getName())) {
                 System.out.println(  " id : " + formProperty.getId() +" | name : "+ formProperty.getName() +"| value : "+ formProperty.getValue());
             }
        }
        //审核通过
        Map<String , String > params = new HashMap<String , String  >();
        params.put("deptLeaderApprove", "true");
        formService.submitTaskFormData(deptLeaderTask.getId(), params);
        System.out.println("部门经理审核通过");
        boolean isFlag = isEnded(deptLeaderTask.getProcessInstanceId());
        if(isFlag) {
              System.out.println("流程结束");
              System.out.println("——————————————————————————————————————————————————"); 
        }
    }  

    public boolean isEnded(String processInstanceId) {
        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if(processInstance == null){
            return true;
        }else{
            return false;
        }
    }

测试结果如下:

 id : startDate | name : 请假开始日期| value : 2018-06-07
 id : endDate | name : 请假结束日期| value : 2018-06-09
 id : reason | name : 请假原因| value : 我要休息
部门经理审核通过
流程结束
——————————————————————————————————————————————————

调整申请代码与审核代码类似。

代码下载:请假流程代码

猜你喜欢

转载自blog.csdn.net/yk10010/article/details/80611188