Activiti多人会签,1/3的人同意则审批通过的实现

Activiti多人会签,1/3的人同意则审批通过的实现

第一步:配置流程

1. 配置审批通过的条件,如下,

线条上配置审批通过条件:${passCount/totalCount >=1/3}

线条上配置审批退回条件:${passCount/totalCount < 1/3}

 

2. 申请节点添加结束监听器

3. 配置该审批节点结束的条件

Sequential:false,false为并行执行,true为串行执行,此处要设置为并行

Collection: ${partyList},用于执行该会签环节的参与人,此处使用partyList的流程变量

Element variable: party,此处表示的是每一个分支都有一个叫party的流程变量,和上方的assignee结合使用就可以决定该分支应该由谁执行

Completion condition:该节点的结束条件(该条件一定要配置,否则要等所有人都执行完才会结束该节点

4. 为该审批节点添加创建时的监听器

二:代码部分

1. 申请节点结束时,设置下个审批节点的参与人

监听器内容如下,主要用于设置下个审批节点的参与人

package com.ylkj.base.flow.listener;

 

import java.util.ArrayList;

import java.util.List;

 

import org.activiti.engine.delegate.DelegateTask;

import org.activiti.engine.delegate.TaskListener;

 

public class MyCompeteistener implements TaskListener {

@Override

public void notify(DelegateTask arg0) {

      List<String> userList = new ArrayList<String>();

      userList.add("111");

      userList.add("222");

      userList.add("333");

      arg0.setVariable("partyList", userList);

}

}

 

2. 审批节点创建时的监听器,主要用于分配任务执行人

监听器内容如下:

package com.ylkj.base.flow.listener;

 

import org.activiti.engine.delegate.DelegateTask;

import org.activiti.engine.delegate.TaskListener;

/**

 * 节点创建监听器

 * 为节点设置处理人

 */

public class MutiGroupsListener implements TaskListener {

//节点完成的时候调用此监听器

@Override

public void notify(DelegateTask arg0) {

      //将通过人数,未通过人数,总数,重新置为0,退回的时候才能重新计算

      arg0.setVariable("passCount", "0");

      arg0.setVariable("totalCount", "0");

      arg0.setVariable("noPassCount", "0");

      //为每一个任务设置处理人

      String party = (String)arg0.getVariable("party");

     arg0.setAssignee(party);

}

}

3. 审批节点有人执行任务时,需要统计执行情况

/* ( Javadoc)

* <p>Title: completeTask1</p>

* <p>Description: </p>

* @param procInstId 流程实例id

* @param taskId     任务id

* @param variables  流程变量

* @param passflag   审批同意标志(yes/no

* @see com.ylkj.base.activiti.service.ActivitiService#completeTask1(java.lang.String, java.lang.String, java.util.Map, java.lang.String)

*/

     

public void completeTask1(String procInstId,String taskId, Map<String, Object> variables,String passflag) {

      //获取当前节点的task_def_key_,此段代码主要用于区分多个节点时,审批通过记录数与总数

      Task taskQuery = processEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult();

      List<Task> tasks = processEngine.getTaskService().createTaskQuery().taskName(taskQuery.getName()).processInstanceId(procInstId).list();

     

      int passCount = 0;//审批同意人数

      int noPassCount = 0;//审批不同意人数

      int totalCount = 0;//任务总人数

      //当前的执行情况

      String tmpPassCount = processEngine.getRuntimeService().getVariable(procInstId, taskQuery.getTaskDefinitionKey()+"#passCount")+"";

      String tmpNoPassCount = processEngine.getRuntimeService().getVariable(procInstId, taskQuery.getTaskDefinitionKey()+"#noPassCount")+"";

      String tmpTotal = processEngine.getRuntimeService().getVariable(procInstId, taskQuery.getTaskDefinitionKey()+"#totalCount")+"";

     

      if(!tmpPassCount.equals("null") && !tmpPassCount.trim().equals("")){

           passCount = Integer.parseInt(tmpPassCount);

      }

     

      if(!tmpNoPassCount.equals("null") && !tmpNoPassCount.trim().equals("")){

           noPassCount = Integer.parseInt(tmpNoPassCount);

      }

     

      if(tmpTotal.equals("null") || tmpTotal.trim().equals("")){

           totalCount = tasks.size();

      } else if(!tmpTotal.equals("null") && !tmpTotal.trim().equals("")){

           totalCount = Integer.parseInt(tmpTotal);

      }

      for (Task tmp:tasks) {

         if(passflag.equals("yes") && tmp.getId().equals(taskId)){//选择通过则通过人数+1

               passCount++;

           }

          

           if(passflag.equals("no") && tmp.getId().equals(taskId)){//选择不通过则不通过人数+1

               noPassCount++;

           }

          

      }

      //变量回写记录

      variables.put("passCount", passCount);

      variables.put("noPassCount", noPassCount);

      variables.put("totalCount", totalCount);

      variables.put(taskQuery.getTaskDefinitionKey()+"#passCount", passCount);

      variables.put(taskQuery.getTaskDefinitionKey()+"#noPassCount", noPassCount);

      variables.put(taskQuery.getTaskDefinitionKey()+"#totalCount", totalCount);    

      processEngine.getTaskService().complete(taskId,variables);

}

4. 流程配置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="myProcess090301" name="My process090301" isExecutable="true">

    <startEvent id="startevent1" name="开始节点"></startEvent>

    <userTask id="usertask1" name="申请节点1">

      <extensionElements>

        <activiti:taskListener event="complete" class="com.ylkj.base.flow.listener.MyCompeteistener"></activiti:taskListener>

      </extensionElements>

    </userTask>

    <userTask id="usertask2" name="审批节点1" activiti:candidateGroups="role1">

      <extensionElements>

        <activiti:taskListener event="create" class="com.ylkj.base.flow.listener.MutiGroupsListener"></activiti:taskListener>

      </extensionElements>

      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${partyList}" activiti:elementVariable="party">

        <completionCondition>${passCount/totalCount >=1/3}</completionCondition>

      </multiInstanceLoopCharacteristics>

    </userTask>

    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>

    <sequenceFlow id="flow1" name="所有人都不同意" sourceRef="exclusivegateway1" targetRef="usertask1">

      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${passCount/totalCount < 1/3}]]></conditionExpression>

    </sequenceFlow>

    <sequenceFlow id="flow2" name="链接1" sourceRef="usertask2" targetRef="exclusivegateway1"></sequenceFlow>

    <sequenceFlow id="flow7" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>

    <sequenceFlow id="flow8" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>

    <endEvent id="endevent1" name="End"></endEvent>

    <sequenceFlow id="flow9" name="1/3同意" sourceRef="exclusivegateway1" targetRef="endevent1">

      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${passCount/totalCount >=1/3}]]></conditionExpression>

    </sequenceFlow>

  </process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess090301">

    <bpmndi:BPMNPlane bpmnElement="myProcess090301" id="BPMNPlane_myProcess090301">

      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">

        <omgdc:Bounds height="35.0" width="35.0" x="60.0" y="140.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">

        <omgdc:Bounds height="55.0" width="105.0" x="200.0" y="130.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">

        <omgdc:Bounds height="55.0" width="105.0" x="440.0" y="130.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">

        <omgdc:Bounds height="40.0" width="40.0" x="472.0" y="290.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">

        <omgdc:Bounds height="35.0" width="35.0" x="670.0" y="293.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">

        <omgdi:waypoint x="472.0" y="310.0"></omgdi:waypoint>

        <omgdi:waypoint x="252.0" y="310.0"></omgdi:waypoint>

        <omgdi:waypoint x="252.0" y="185.0"></omgdi:waypoint>

        <bpmndi:BPMNLabel>

          <omgdc:Bounds height="14.0" width="100.0" x="331.0" y="317.0"></omgdc:Bounds>

        </bpmndi:BPMNLabel>

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">

        <omgdi:waypoint x="492.0" y="185.0"></omgdi:waypoint>

        <omgdi:waypoint x="492.0" y="290.0"></omgdi:waypoint>

        <bpmndi:BPMNLabel>

          <omgdc:Bounds height="14.0" width="30.0" x="492.0" y="185.0"></omgdc:Bounds>

        </bpmndi:BPMNLabel>

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">

        <omgdi:waypoint x="95.0" y="157.0"></omgdi:waypoint>

        <omgdi:waypoint x="200.0" y="157.0"></omgdi:waypoint>

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">

        <omgdi:waypoint x="305.0" y="157.0"></omgdi:waypoint>

        <omgdi:waypoint x="440.0" y="157.0"></omgdi:waypoint>

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">

        <omgdi:waypoint x="512.0" y="310.0"></omgdi:waypoint>

        <omgdi:waypoint x="670.0" y="310.0"></omgdi:waypoint>

        <bpmndi:BPMNLabel>

          <omgdc:Bounds height="14.0" width="39.0" x="520.0" y="317.0"></omgdc:Bounds>

        </bpmndi:BPMNLabel>

      </bpmndi:BPMNEdge>

    </bpmndi:BPMNPlane>

  </bpmndi:BPMNDiagram>

</definitions>

猜你喜欢

转载自blog.csdn.net/qq_25927437/article/details/82462575