Activiti 用戶任務並行動態多實例(多用戶執行流程)


轉載 https://www.cnblogs.com/adversary/p/9854707.html


在很多情況下,我們需要多用戶共同執行余下流程,比如開會流程

  1. 領導發起開會,選擇開會人員(多個)
  2. 每個開會人員接收到通知后需要簽到(一名用戶簽到不會影響到另一位用戶的簽到)
  3. 簽到完成后則流程結束

  如果只使用代理(Assignee、Candidate users、Candidate groups) 將無法解決上述問題,因為即使使用 Candidate users ,但每個用戶實際上還是在一個任務里面,其中一個用戶完成任務,另外的用戶任務也隨之完成,此時,就需要用到多實例(多任務)。


以上面開會流程為例:

1. 創建模型

2. 模型相關配置

【領導發起開會】
由於具體是哪個領導發起開會有不確定性(只要是領導都可以發起),所以需要設置代理人屬性:
Assignee: ${leader}  -- 此處采用變量形式

為了方便后面的【開發人員簽到】流程,我們還需要在【 領導發起開會】流程處設置一個 流程執行監聽器(此操作不是必須,此處只是為了解釋動態多實例),在Activiti中,配置監聽器需要在模型和JAVA中都進行相應配置:
在JAVA中我們想要創建監聽器只需要創建一個類,並實現系統監聽器類  ExecutionListener 即可,代碼如下:
復制代碼
package com.kenary.activiti.listener;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

/**
 * 自定義監聽器
 */
public class MyExecutionListener implements ExecutionListener {
    @Override
    public void notify(DelegateExecution delegateExecution) throws Exception {

    }
}
復制代碼

可見此時監聽器沒做任何處理,我們稍安勿躁。
接下來就是模型中的配置,由於我們想在領導指派了開會人員后進行監聽,所以需要如下設置

其中 Event 代表事件觸發類型,作用如其名
Class 代表監聽器全路徑,此處為 
com.kenary.activiti.listener.MyExecutionListener,則是之前創建的 MyExecutionListener
監聽器配置完成后領導發起開會流程就配置完成了!

 

【開會人員簽到】
相對於【領導發起開會】流程,【 開發人員簽到】流程則需要配置更多東西

其中,集合(Collection) 設置的是存儲開會人員集合的變量名,注意:此處不需要${},並且 變量的值必須是 Collection的子類,即List、Set等

多實例類型 設置的是 並行、串行 等方式

  並行代表同時進行,如把任務分給5個人來處理,這5個人同時會收到任務,並且可以同時處理,不受各自的影響。

  串行代表工作或任務由一個人完成后,再由另一個人去處理,直至全部完成,每個任務依賴於前一個任務完成。

元素變量(Element variable) 設置的是集合(Collection)每遍歷一次設置的變量值的變量名,即迭代集合時存儲集合里面單個元素的變量名,集合遍歷時會根據內容創建任務

代理 設置的是處理該任務的用戶,由於集合每遍歷一次就創建了一個任務,所以這里和領導發起開會流程無太大差異,指定代理人即可,不過代理人員需要使用元素變量(Element variable)(Item 迭代的值)

 

至此,流程配置基本完成

3. 部署流程

復制代碼
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;

......


private RepositoryService repositoryService;
......


Deployment deployment = repositoryService.createDeployment() .name(modelData.getName()) .addString(processName, new String(bpmnBytes, "UTF-8")) .deploy(); modelData.setDeploymentId("99999"); repositoryService.saveModel(modelData);
復制代碼

其中,99999 為模型id

4. 領導發起開會

復制代碼
import org.activiti.engine.RuntimeService;
.......
@Autowired
private RuntimeService runtimeService;
......

// 開始-》開啟領導發起開會流程(指定領導) Map<String,Object> p1 = new HashMap<>(); p1.put("leader","jjh"); runtimeService.startProcessInstanceByKey("10001",map);
復制代碼

其中,"jjh" 為設置的變量值,因為我內部通過用戶名來區分,所以直接設置 jjh

 runtimeService.startProcessInstanceByKey("10001",map);   為啟動流程,10001 為流程id

當這步執行完成后,我們來查詢 屬於 jjh 的任務

5. 開會人員簽到
開會人員簽到需要設置多個用戶

復制代碼
import org.activiti.engine.TaskService;

.......
@Autowired
private TaskService taskService;
.......

Map<String,Object> map = new HashMap<>(); map.put("assigneeList","jjh,yxc"); // 完成任務
teskService.complete("75167", map);
復制代碼

可以看見,我們的用戶設置了多個,並且使用逗號隔開,但是剛才也介紹了 集合(Colloection) 必須是 Collection的子類,也就是 List、Set等,而String不是

所以此時可以回到監聽器,並將其改為:

復制代碼
public class MyExecutionListener implements ExecutionListener {
    @Override
    public void notify(DelegateExecution delegateExecution) throws Exception {
        String assigneeList = String.valueOf(delegateExecution.getVariable("assigneeList"));
        if(assigneeList != null){
            // 根據逗號分割並以數組形式重新設置進去
            delegateExecution.setVariable("assigneeList", Arrays.asList(assigneeList.split(",")));
        }
    }
}
復制代碼

作用是將變量中的字符串根據逗號分割成了集合,其實此步驟完全多余,在設置變量時直接設置集合即可,但是為了順帶加上監聽器的作用,所以則以此種方式說明

 

6. 效果預覽

當任務執行后,我們分別看看 jjh 和 yxc 雙用戶的任務

可以看到,兩個不同的用戶的任務id是不相同的,所以他們不會互不干擾,Activiti動態多實例完成。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM