1. 程式人生 > >Activiti 分配組任務(三種方式)

Activiti 分配組任務(三種方式)

方式一:定義流程時指定組任務候選人(該方式不夠靈活,使用較少)

這裡寫圖片描述

方式二:使用流程變數指定組任務候選人

這裡寫圖片描述
流程圖程式碼

<?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="groupTask1" name="GroupTask1"
isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent> <userTask id="usertask1" name="審批" activiti:candidateUsers="#{userIds}"></userTask> <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> <endEvent
id="endevent1" name="End">
</endEvent> <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow> </process> <bpmndi:BPMNDiagram id="BPMNDiagram_groupTask1"> <bpmndi:BPMNPlane bpmnElement="groupTask1" id="BPMNPlane_groupTask1"> <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> <omgdc:Bounds height="35.0" width="35.0" x="410.0" y="40.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> <omgdc:Bounds height="55.0" width="105.0" x="375.0" y="120.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> <omgdc:Bounds height="35.0" width="35.0" x="410.0" y="220.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> <omgdi:waypoint x="427.0" y="75.0"></omgdi:waypoint> <omgdi:waypoint x="427.0" y="120.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> <omgdi:waypoint x="427.0" y="175.0"></omgdi:waypoint> <omgdi:waypoint x="427.0" y="220.0"></omgdi:waypoint> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions>

方式三:使用監聽類設定組成員

這裡寫圖片描述
這裡寫圖片描述
流程圖程式碼

<?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="groupTask3" name="GroupTask3" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="usertask1" name="審批">
      <extensionElements>
        <activiti:taskListener event="create" class="com.activiti.test.GroupTaskListenerImpl"></activiti:taskListener>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_groupTask3">
    <bpmndi:BPMNPlane bpmnElement="groupTask3" id="BPMNPlane_groupTask3">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="390.0" y="40.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="355.0" y="120.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="390.0" y="220.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="407.0" y="75.0"></omgdi:waypoint>
        <omgdi:waypoint x="407.0" y="120.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="407.0" y="175.0"></omgdi:waypoint>
        <omgdi:waypoint x="407.0" y="220.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

java測試程式碼

package com.activiti.test;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

public class GroupTaskListenerImpl implements TaskListener {

    /**
     * 指定個人任務和組任務的辦理人
     */
    @Override
    public void notify(DelegateTask delegateTask) {
        delegateTask.addCandidateUser("crystal");//分配組任務的辦理人
        delegateTask.addCandidateUser("barry");
    }
}
package com.activiti.test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.history.HistoricIdentityLink;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.junit.Test;

public class GroupTask {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 部署流程定義,啟動流程例項
     */
    @Test
    public void deployAndStart() {
        processEngine.getRepositoryService()
            .createDeployment()
            .name("指定組任務")
            .addClasspathResource("diagrams/groupTask3.bpmn")
            .addClasspathResource("diagrams/groupTask3.png")
            .deploy();
        System.out.println("部署成功!");
        // 方式一
        /*ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey("groupTask1");*/
        // 方式二
        /*Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("userIds", "crystal,lina,barry");
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey("groupTask1", variables);*/
        // 方式三
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey("groupTask3");
        System.out.println("流程例項啟動成功!例項ID:" + pi.getId());
    }

    /**
     * 查詢我的個人任務列表
     */
    @Test
    public void findMyTaskList(){
        String userId = "張三";
        List<Task> list = processEngine.getTaskService()
                        .createTaskQuery()
                        .taskAssignee(userId)//指定個人任務查詢
                        .list();
        if (list != null && list.size()>0) {
            for(Task task : list){
                System.out.println("task id="+task.getId());
                System.out.println("name="+task.getName());
                System.out.println("assinee="+task.getAssignee());
                System.out.println("executionId="+task.getExecutionId());
                System.out.println("=====================================");
            }
        }
    }

    /**
     * 檢視組任務
     * 個人認領任務後,組任務不再存在,若將個人任務回退到組任務,又可以看到組任務
     */
    @Test
    public void findMyGroupTask() {
        String userId = "crystal";
        List<Task> list = processEngine.getTaskService()
                .createTaskQuery()
                .taskCandidateUser(userId)// 指定組任務查詢
                .list();
        if (list != null && list.size()>0) {
            for(Task task : list){
                System.out.println("task id="+task.getId());
                System.out.println("name="+task.getName());
                System.out.println("assinee="+task.getAssignee());
                System.out.println("executionId="+task.getExecutionId());
                System.out.println("=====================================");
            }
        }
    }

    /**
     * 檢視組任務成員列表
     */
    @Test
    public void findGroupUser() {
        String taskId = "20008";
        List<IdentityLink> list = processEngine.getTaskService()
                .getIdentityLinksForTask(taskId);// 獲取列表
        if (list != null && list.size() > 0) {
            for (IdentityLink il : list) {
                System.out.println("使用者ID:" + il.getUserId());
            }
        }
    }

    /**
     * 查詢組任務成員歷史列表
     */
    @Test
    public void findHisGroupUser() {
        String taskId = "20008";
        List<HistoricIdentityLink> list = processEngine.getHistoryService()
                .getHistoricIdentityLinksForTask(taskId);
        if (list != null && list.size() > 0) {
            for (HistoricIdentityLink il : list) {
                System.out.println("使用者ID:" + il.getUserId());
            }
        }
    }

    /**
     * 將組任務分配給個人任務,拾取任務
     * 注意:認領任務的時候,可以是組任務成員中的人,也可以不是組任務成員的人,此時通過Type的型別為participant來指定任務的辦理人
     * 由1個人去完成任務
     */
    @Test
    public void claim() {
        String taskId = "20008";//任務ID
        String userId = "crystal";//分配的辦理人
        processEngine.getTaskService()
                    .claim(taskId, userId);
    }

    /**
     * 完成我的個人任務
     */
    @Test
    public void complete() {
        String taskId = "20008";
        processEngine.getTaskService().complete(taskId);
        System.out.println("完成任務");
    }

    /**
     * 可以分配個人任務回退到組任務,(前提:之前是個組任務)
     */
    @Test
    public void setAssigneeTask(){
        String taskId = "20008";//任務ID
        processEngine.getTaskService()//
                .setAssignee(taskId, null);
    }

    /**
     * 新增組成員
     */
    @Test
    public void addGroupUser(){
        String taskId = "20008";
        String userId = "ken";
        processEngine.getTaskService().addCandidateUser(taskId, userId);
    }

    /**
     * 刪除組成員
     */
    @Test
    public void deleteGroupUser(){
        String taskId = "2509";
        String userId = "ken";
        processEngine.getTaskService()
            .deleteCandidateUser(taskId, userId);
    }
}

總結:

組任務及三種分配方式: 
1:在taskProcess.bpmn中直接寫 candidate-users=“張三,李四,王五” 
2:在taskProcess.bpmn中寫 candidate-users =“#{userIds}”,變數的值要是String的(使用流程變數指定辦理人)。 
3:使用TaskListener介面,使用類實現該介面,在類中定義新增組任務的使用者 
個人任務和組任務存放辦理人對應的表: 
act_ru_identitylink表存放任務的辦理人,包括個人任務和組任務,表示正在執行的任務 
act_hi_identitylink表存放任務的辦理人,包括個人任務和組任務,表示歷史任務 
區別在於:如果是個人任務TYPE的型別表示participant(參與者), 如果是組任務TYPE的型別表示candidate(候選者)和participant(參與者)

相關推薦

Activiti 分配任務方式

方式一:定義流程時指定組任務候選人(該方式不夠靈活,使用較少) 方式二:使用流程變數指定組任務候選人 流程圖程式碼 <?xml version="1.0" encoding="UTF-8"?> <definitions

Activiti工作流筆記之——分配任務方式

目錄 1.直接指定辦理人 測試程式碼: package cn.itcast.l_groupTask; import java.io.InputStream; import java.util.HashMap; import java.util.Li

個執行緒輪流執行順序列印ABC,依次是ABCABCABC......方式

1.使用synchronized悲觀鎖 (秋招阿里的一個筆試題,應該寫的比較複雜,然後就沒有然後了o(╥﹏╥)o) public class ThreadThreadp { private int flag = 0; public synch

MQ傳送普通訊息方式

MQ 傳送普通訊息有三種實現方式:可靠同步傳送、可靠非同步傳送、單向(Oneway)傳送。本文介紹了每種實現的原理、使用場景以及三種實現的異同,同時提供了程式碼示例以供參考。 可靠

Java 指定執行緒執行順序方式

     方法一:通過共享物件鎖加上可見變數來實現。 public class MyService { private volatile int orderNum = 1; pub

python如何不生成pyc檔案方式

pyc檔案的生成是什麼情況下生成呢: 當 import匯入另一個模組的時候會生成 python3會生成 __pycache__ 如何不生成編譯檔案呢: 1.使用 -B引數 即 python3 -B

Vue---兄弟元件通訊方式

第一種:eventBus     新建一個js檔案, 我這裡叫做 bus.js,     檔案內容:           import Vue from 'vue';            export default new Vue();    然後在你需要觸發的 

python之收集網站資料方式

方式一:python之收集整個網站資料 目的: 建立一個爬蟲和資料收集程式(資料列印) 1:程式碼 # coding=utf-8 """ @author: jiajiknag 程式功能:收集整個網站資料 建立一個爬蟲和資料收集程式(

Java 設計模式—工廠模式方式

  來看下它的組成:        1)抽象工廠角色: 這是工廠方法模式的核心,它與應用程式無關。是具體工廠角色必須實現的介面或者必須繼承的父類。在java中它由抽象類或者介面來實現。        2)具體工廠角色:它含有和具體業務邏輯有關的程式碼。由應用程式呼叫以建立對應的具體產品的物件。      

分散式鎖的實現方式

很多小夥伴在學習Java的時候,總是感覺Java多執行緒在實際的業務中很少使用,以至於不會花太多的時間去學習,技術債不斷累積!等到了一定程度的時候對於與Java多執行緒相關的東西就很難理解,今天需要探討的東西也是一

RocketMQ(6)---傳送普通訊息方式

傳送普通訊息(三種方式) RocketMQ 傳送普通訊息有三種實現方式:可靠同步傳送、可靠非同步傳送、單向(Oneway)傳送。 注意 :順序訊息只支援可靠同步傳送。 GitHub地址: https://github.com/yudiandemingzi/SpringBootBlog 一、概念 1、可靠同步

java數擴增的方式

實現 arrays 數組復制 當我 自身 ++ new 復制 log java數組聲明的時候必須聲明其長度,但當我們想對數組進行擴增的時候該怎麽辦呢? 下面三種方式都可以進行擴增,最後一種也最為方便。 1 /** 2 * 手動循環擴增

react創建件的方式

ffffff fff es5 code nbsp 實例對象 展示 utc 操作 react創建組件的三種方式:   1、函數式無狀態組件   2、es5方式React.createClass組件   3、es6方式extends React.Component 三種創建

Java中數定義的方式

++ pan stat div 方式 clas 空間 inf bsp 方法一:   1.先聲明   2.分配空間  3.賦值     public class arr{ public static void main(String[] args){

單例模式新談包含方式

  設計模式是一套被反覆使用,多數人知曉,經過分類編目的,程式碼設計的總結,也可以說是前人的智慧結晶。學習設計模式能讓我們對一些應用場景使用相同的套路達到很好的效果,我會不定時更新一些自己對設計模式的理解的文章,從定義,實現,應用場景來說說設計模式,今天我要說的物件是單例模式一,定義  什麼是單例模式,字面理

egg 伺服器叢集情況下的定時任務執行操作2方式

第一種做法不是很好 但是可以花很少成本解決定時器多臺伺服器執行的一些問題 disable:該引數為 false時,定時任務會被啟動。 這樣的話多臺機器上面都會執行,相當於增加了一個開關當執行到改機器主機名和配置主機名相同時 執行定時任務。(如果服務是部署在doc

linux服務之nginx-隨筆-2nginx配置站點的方式

三種方式: 1.域名  2.埠  3.IP 直接上配置檔案  一.域名  server { listen 80; server_name www.e

四十一、瀑布流佈局js,jquery,css3方式

一、 簡介 1. 實現瀑布流的方法: JavaScript 原生方法、 jquery 方法、 css3 的多欄佈局 二、js 原生方法實現 -- 思想 1. 瀑布流的特點: 等寬不等高 <

js對url進行編碼和解碼方式區別

*** 只有 0-9[a-Z] $ - _ . + ! * ' ( ) , 以及某些保留字,才能不經過編碼直接用於 URL。 ***例如:搜尋的中文關鍵字,複製網址之後再貼上就會發現該URL已經被轉碼。 1、escape 和 unescape 原理:對除ASCII字母、數字、標點符號 @  *  _  +

Linux 中執行Shell 指令碼的方式方法

Shell 指令碼的執行方式通常有如下三種: (1)bash script-name 或者 sh script-name;(2)path/script-name或者./script-name;(3)sourcescript-name或者. script-name。下面,分別