Activiti6.0(十一)多實例節點(會籤)

目錄

一、前言

二、多實例功能

1、多實例特殊變量

2、多實例配置

3、驗證


一、前言

在實際業務流程中,多實例節點是非常常見的一種場景,常用在多人審批環節,簡單說就是某個環節的處理人指派給了多個人,需要這些人全部審批完或部分審批完流程能自動流轉的功能。以我們開發人員的角度看,其本質就是給定一個處理人員範圍集合,然後循環該集合,爲每一個集合中的元素都執行一遍當前環節,既可以順序依次執行也可以併發同步執行,即依次會籤or普通會籤

 

二、多實例功能

多實例是在一個普通節點上添加額外的多實例屬性,這樣被多實例修飾的節點就會執行多次,在BPMN規範中,絕大多數常用節點都可以成爲一個多實例節點,最常用的便是 userTask 。

1、多實例特殊變量

每個上級流程在爲每個實例創建分支的時候都會提供如下變量,這些變量可用於多實例結束條件表達式:

  • nrOfInstances: 實例總數
  • nrOfActiveInstances: 當前活動的實例數量, 對於順序執行的多實例, 該值始終爲1
  • nrOfCompletedInstances: 已經完成的實例數量
  • loopCounter: 當前實例所在循環的索引值, 其他實例不可見, 不會保存到流程實例級別

可以通過如下方式獲得這些變量:

taskService.getVariable(String taskId, String variableName)

2、多實例配置

接下去的配置都是基於Activiti-app進行的,基於BomnModel的方式當然也可以,先看整體流程圖:

首先配置 多實例類型 ,一共有三種可選枚舉,默認爲NONE,即非會籤:

  • NONE:非會籤
  • PARALLEL:會籤模式,並行觸發,同時生成多個任務,即普通會籤
  • SEQUENTIAL:會籤模式,順序觸發,依次生成任務,即順序會籤

然後配置多實例的 人員範圍集合 以及集合中的 元素名 ,這裏採用變量的方式爲該節點分配集合:

最後配置當前節點的 處理人變量,注意該變量名與集合中的元素名也就是user一定要一樣!

到這裏一個最簡單的配置方式就完成了,除此之外我們還可以配置 多實例節點的結束條件 ,默認情況下所有實例任務全部完成纔算結束,但是你也可以使用上面提到的特殊變量來動態配置:

表達式可根據業務而來,比如:只要50%的人審批完後就直接流轉當前實例(${nrOfCompletedInstances/nrOfInstances >= 0.6})

配置後的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/processdef">
  <process id="multiInstance" name="多實例會籤" isExecutable="true">
    <startEvent id="startEvent1"></startEvent>
    <endEvent id="sid-0A0EABAB-F9B6-4673-941C-91C9F88F73AA"></endEvent>
    <userTask id="sid-ACFA83C3-37AA-4912-94E2-806A969E12BE" name="會籤審批環節" activiti:assignee="${user}">
      <extensionElements>
        <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${userList}" activiti:elementVariable="user"></multiInstanceLoopCharacteristics>
    </userTask>
    <sequenceFlow id="sid-4618D0A7-F5CA-4BEA-8FF7-1E4D222EF989" sourceRef="startEvent1" targetRef="sid-ACFA83C3-37AA-4912-94E2-806A969E12BE"></sequenceFlow>
    <sequenceFlow id="sid-EA45E614-56CF-4C54-8494-EA4C96FB995C" sourceRef="sid-ACFA83C3-37AA-4912-94E2-806A969E12BE" targetRef="sid-0A0EABAB-F9B6-4673-941C-91C9F88F73AA"></sequenceFlow>
  </process>
</definitions>

3、驗證

調用如下代碼即可

@Test
    public void multiInstanceTest() {
        // 1、發佈流程,當流程的key相同時則以版本來控制,每次啓動流程實例時默認取最新版本
        Deployment deployment = repositoryService.createDeployment().name("多實例會籤流程").addClasspathResource("processes/multiInstance.bpmn20.xml").deploy();

        Map<String, Object> variable = new HashMap<>();
        variable.put("userList", Lists.newArrayList("張三", "李四", "王五", "趙六"));
        // 2、啓動一個流程實例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("multiInstance", variable);

        // 3、查詢當前任務
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).list();
        System.out.println("當前任務數量:" + tasks.size());

        for (Task task : tasks) {
            System.out.println("任務名:" + task.getName() + ",任務處理人:" + task.getAssignee());
        }

        // 下面演示先完成一個任務,看流程是否會流轉
        taskService.complete(tasks.get(0).getId());

        tasks = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).list();
        System.out.println("完成一個任務後,當前任務數量:" + tasks.size());
        for (Task task : tasks) {
            System.out.println("任務名:" + task.getName() + ",任務處理人:" + task.getAssignee());
        }
    }

查看控制檯輸出:

當前任務數量:4
任務名:會籤審批環節,任務處理人:張三
任務名:會籤審批環節,任務處理人:李四
任務名:會籤審批環節,任務處理人:王五
任務名:會籤審批環節,任務處理人:趙六
完成一個任務後,當前任務數量:3
任務名:會籤審批環節,任務處理人:李四
任務名:會籤審批環節,任務處理人:王五
任務名:會籤審批環節,任務處理人:趙六

當增加一個結束條件後,即 ${nrOfCompletedInstances > 0} ,xml配置變爲:

      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${userList}" activiti:elementVariable="user">
        <completionCondition>${nrOfCompletedInstances &gt; 0}</completionCondition>
      </multiInstanceLoopCharacteristics>

再次調用上面的代碼,會發現一旦一個任務完成,其餘任務均被刪除:

當前任務數量:4
任務名:會籤審批環節,任務處理人:張三
任務名:會籤審批環節,任務處理人:李四
任務名:會籤審批環節,任務處理人:王五
任務名:會籤審批環節,任務處理人:趙六
完成一個任務後,當前任務數量:0

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章