activiti工作流5.22.0 多人會審功能實現

背景

因業務需求需要實現指定多人來進行一個task,傳統做法是使用網關來達到目的,但是顯示情況是會審的人員是可變且易變的,比如我指定安全組來做一個檢驗任務,安全組今天可能是5個人,明天又有人離職變成了3個人,因此網關不大適合該場景,這裏就需要用到activiti提供的parallel。

環境

activiti 5.19.0~5.22.0皆可

概念

Activiti User Guide 8.5.14. Multi-instance (for each)中有介紹,即設定一個task爲sequentially(順序執行)或parallel(並行執行)。前者在數據庫中一次只產生一個task記錄,順序執行;後者產生多個記錄,並行執行。
並行
這裏寫圖片描述

實現

本文流程要實現以下功能
提交一個測試申請,流轉到並行任務,並行任務中各個執行人通過條件選擇是否通過(網上流傳的${nrOfCompletedInstances/nrOfInstances >= x }並沒有提供條件選擇的情況,且nrOfCompletedInstances與form表單條件無關)。

總體流程圖如下
總體流程

幾個需要編輯的地方

1、第一個任務(t1)

需要添加一個自定義的task listener用來處理變量以及設置t2中會審的人員,比如在這個監聽器中就可以通過groupID之類的參數去獲取成員列表。

面板
設置類

這裏提供類代碼,以作參考

public class MutiGroupsListener implements TaskListener {
    public static final Logger LOGGER = LoggerFactory
            .getLogger(MutiGroupsListener.class);
    @Override
    public void notify(DelegateTask arg0) {
        //清0操作,如果t2會審步驟被駁回,回到t1,需要將通過數,總數重新清空
        if(arg0.getVariable("passCount")!=null){
            arg0.setVariable("passCount", 0);
        }
        if(arg0.getVariable("totalCount")!=null){
            arg0.setVariable("totalCount", 0);
        }
         //添加會籤的人員,這裏可以根據自己的業務邏輯去動態獲取列表
        List<String> assigneeList = new ArrayList<String>();
        assigneeList.add("kermit");
        assigneeList.add("gonzo");
        arg0.setVariable("partyList",assigneeList);
    }

}

2、第二個任務(t2)

在這裏我們需要將task設置爲parallel,XML採用如下設置:

<multiInstanceLoopCharacteristics isSequential="false">
 ...
</multiInstanceLoopCharacteristics>

設計器如圖:

explorer

eclipse

其後,設置會籤人員集合名稱以及集合項名稱,任務的辦理人使用項名稱獲取。

元素設置

表單選擇項:

這裏寫圖片描述

t2完成任務需要調用的方法

    public void completeTask(String taskId,String instanceId,String passflag){
        ProcessEngine processEngine =ProcessEngines.getDefaultProcessEngine();
        List<Task> tasks = processEngine.getTaskService().createTaskQuery().taskName("t2").processInstanceId("instanceId").list();
        int count = 0;
        int totalCount = 0;
        for(Task tmp:tasks){

            String tmpCount = processEngine.getTaskService().getVariable(tmp.getId(), "passCount")+"";//獲取通過記錄數,這裏不能使用nrOfCompletedInstances,因爲與我們業務無關
            String tmpTotal = processEngine.getTaskService().getVariable(tmp.getId(), "totalCount")+"";//獲取記錄總數
            if(!tmpCount.equals("null") && !tmpCount.trim().equals("")){
                        count = Integer.parseInt(tmpCount);
                    }
                    if(!tmpTotal.equals("null") && !tmpTotal.trim().equals("")){
                        totalCount = Integer.parseInt(tmpTotal);
                    }
            System.out.println(tmp.getId()+"var = "+passflag);
            if(passflag.equals("yes")){//選擇通過則+1
                count++;
            }
            totalCount++;
        }
        Map<String, Object> vars = new HashMap<String,Object>();
        //變量回寫記錄
        vars.put("passCount", count);
        vars.put("totalCount", totalCount);
        processEngine.getTaskService().complete(taskId,vars);
    }

表單條件查詢,可以返回給頁面,根據內容初始化頁面組件

public void queryFormMsg(String taskId) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskFormData td = processEngine.getFormService().getTaskFormData(taskId);
        List<FormProperty> pros = td.getFormProperties();
        for(FormProperty tmp:pros){
             System.out.println("pid:"+tmp.getId());
             System.out.println("pname:"+tmp.getName());
             System.out.println("pvalue:"+tmp.getValue());
             System.out.println("ptype:"+tmp.getType().getName());
             System.out.println("=========");
        }
    }

這裏寫圖片描述

3、條件判斷

這裏設置如果全票通過則結束流程,否則返回t1,重新上傳文件或是設置信息,這裏根據業務而定。
這裏寫圖片描述
這裏寫圖片描述

測試,第一次循環一人選擇”no”一人選擇”yes”,然後第二次全部選擇“yes”,通過歸檔。(這裏流程啓動、執行全部使用了自己寫的方法,流程設計、記錄查詢借用了activiti explorer)

這裏寫圖片描述

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