1. 程式人生 > >Activiti 學習筆記13:分配組任務

Activiti 學習筆記13:分配組任務

一、流程圖

這裡寫圖片描述

二、分配組任務方式一(直接指定辦理人)

1:流程圖中任務節點的配置
這裡寫圖片描述
2:測試程式碼

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //部署流程定義,啟動流程例項
    @Test
    public void testTask() throws Exception {
        // 1 釋出流程
        InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn"
); InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("userTask.bpmn", inputStreamBpmn)// .addInputStream("userTask.png"
, inputStreamPng)// .deploy(); // 2 啟動流程 ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("taskProcess"); System.out.println("pid:" + pi.getId()); } //3 查詢我的個人任務列表 @Test public void findMyTaskList(){ String userId = "小A"
; List<Task> list = processEngine.getTaskService()// .createTaskQuery()// .taskAssignee(userId)//指定個人任務查詢 .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("createTime="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); } } //4 查詢組任務列表 @Test public void findGroupList(){ String userId = "小A"; List<Task> list = processEngine.getTaskService()// .createTaskQuery()// .taskCandidateUser(userId)//指定組任務查詢 .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("createTime ="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); System.out.println("##################################"); } } //5 查詢組任務成員列表 @Test public void findGroupUser(){ String taskId = "3709"; List<IdentityLink> list = processEngine.getTaskService()// .getIdentityLinksForTask(taskId); //List<IdentityLink> list = processEngine.getRuntimeService()// // .getIdentityLinksForProcessInstance(instanceId); for(IdentityLink identityLink:list ){ System.out.println("userId="+identityLink.getUserId()); System.out.println("taskId="+identityLink.getTaskId()); System.out.println("piId="+identityLink.getProcessInstanceId()); System.out.println("######################"); } } //6 查詢組任務成員歷史列表 @Test public void findGroupHisUser(){ String taskId = "3709"; List<HistoricIdentityLink> list = processEngine.getHistoryService()// .getHistoricIdentityLinksForTask(taskId); // List<HistoricIdentityLink> list = processEngine.getHistoryService()// // .getHistoricIdentityLinksForProcessInstance(processInstanceId); for(HistoricIdentityLink identityLink:list ){ System.out.println("userId="+identityLink.getUserId()); System.out.println("taskId="+identityLink.getTaskId()); System.out.println("piId="+identityLink.getProcessInstanceId()); System.out.println("######################"); } } //完成任務 @Test public void completeTask(){ String taskId = "3709"; processEngine.getTaskService()// .complete(taskId);// System.out.println("完成任務"); } /**將組任務分配給個人任務,拾取任務*/ //由1個人去完成任務 @Test public void claim(){ //任務ID String taskId = "5908"; //分配的辦理人 String userId = "小B"; processEngine.getTaskService()// .claim(taskId, userId); }

說明:
1)小A,小B,小C,小D是組任務的辦理人
2)但是這樣分配組任務的辦理人不夠靈活,因為專案開發中任務的辦理人不要放置XML檔案中。
3)act_ru_identitylink表存放任務的辦理人,包括個人任務和組任務,表示正在執行的任務
4)act_hi_identitylink表存放任務的辦理人,包括個人任務和組任務,表示歷史任務
區別在於:如果是個人任務TYPE的型別表示participant(參與者)
如果是組任務TYPE的型別表示candidate(候選者)和participant(參與者)
這裡寫圖片描述

三、分配個人任務方式二(使用流程變數)

1:流程圖中任務節點的配置
這裡寫圖片描述
2、測試程式碼

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**部署流程定義(從inputStream)*/
    @Test
    public void deploymentProcessDefinition_inputStream(){
        InputStream inputStreamBpmn = this.getClass().getResourceAsStream("task.bpmn");
        InputStream inputStreamPng = this.getClass().getResourceAsStream("task.png");
        Deployment deployment = processEngine.getRepositoryService()//與流程定義和部署物件相關的Service
                        .createDeployment()//建立一個部署物件
                        .name("任務")//新增部署的名稱
                        .addInputStream("task.bpmn", inputStreamBpmn)//
                        .addInputStream("task.png", inputStreamPng)//
                        .deploy();//完成部署
        System.out.println("部署ID:"+deployment.getId());//
        System.out.println("部署名稱:"+deployment.getName());//
    }

    /**啟動流程例項*/
    @Test
    public void startProcessInstance(){
        //流程定義的key
        String processDefinitionKey = "task";
        /**啟動流程例項的同時,設定流程變數,使用流程變數用來指定任務的辦理人,對應task.pbmn檔案中#{userIDs}*/
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("userIDs", "大大,中中,小小");
        ProcessInstance pi = processEngine.getRuntimeService()//與正在執行的流程例項和執行物件相關的Service
                        .startProcessInstanceByKey(processDefinitionKey,variables);//使用流程定義的key啟動流程例項,key對應helloworld.bpmn檔案中id的屬性值,使用key值啟動,預設是按照最新版本的流程定義啟動
        System.out.println("流程例項ID:"+pi.getId());//流程例項ID  
        System.out.println("流程定義ID:"+pi.getProcessDefinitionId());//流程定義ID   
    }

    /**查詢當前人的個人任務*/
    @Test
    public void findMyPersonalTask(){
        String assignee = "小A";
        List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service
                        .createTaskQuery()//建立任務查詢物件
                        /**查詢條件(where部分)*/
                        .taskAssignee(assignee)//指定個人任務查詢,指定辦理人
//                      .taskCandidateUser(candidateUser)//組任務的辦理人查詢
                        /**排序*/
                        .orderByTaskCreateTime().asc()//使用建立時間的升序排列
                        /**返回結果集*/
                        .list();//返回列表
        if(list!=null && list.size()>0){
            for(Task task:list){
                System.out.println("任務ID:"+task.getId());
                System.out.println("任務名稱:"+task.getName());
                System.out.println("任務的建立時間:"+task.getCreateTime());
                System.out.println("任務的辦理人:"+task.getAssignee());
                System.out.println("流程例項ID:"+task.getProcessInstanceId());
                System.out.println("執行物件ID:"+task.getExecutionId());
                System.out.println("流程定義ID:"+task.getProcessDefinitionId());
                System.out.println("########################################################");
            }
        }
    }

    /**查詢當前人的組任務*/
    @Test
    public void findMyGroupTask(){
        String candidateUser = "大大";
        List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service
                        .createTaskQuery()//建立任務查詢物件
                        /**查詢條件(where部分)*/
                        .taskCandidateUser(candidateUser)//組任務的辦理人查詢
                        /**排序*/
                        .orderByTaskCreateTime().asc()//使用建立時間的升序排列
                        /**返回結果集*/
                        .list();//返回列表
        if(list!=null && list.size()>0){
            for(Task task:list){
                System.out.println("任務ID:"+task.getId());
                System.out.println("任務名稱:"+task.getName());
                System.out.println("任務的建立時間:"+task.getCreateTime());
                System.out.println("任務的辦理人:"+task.getAssignee());
                System.out.println("流程例項ID:"+task.getProcessInstanceId());
                System.out.println("執行物件ID:"+task.getExecutionId());
                System.out.println("流程定義ID:"+task.getProcessDefinitionId());
                System.out.println("########################################################");
            }
        }
    }

    /**完成我的任務*/
    @Test
    public void completeMyPersonalTask(){
        //任務ID
        String taskId = "6905";
        processEngine.getTaskService()//與正在執行的任務管理相關的Service
                    .complete(taskId);
        System.out.println("完成任務:任務ID:"+taskId);
    }


    /**查詢正在執行的任務辦理人表*/
    @Test
    public void findRunPersonTask(){
        //任務ID
        String taskId = "6204";
        List<IdentityLink> list = processEngine.getTaskService()//
                    .getIdentityLinksForTask(taskId);
        if(list!=null && list.size()>0){
            for(IdentityLink identityLink:list){
                System.out.println(identityLink.getTaskId()+"   "+identityLink.getType()+"   "+identityLink.getProcessInstanceId()+"   "+identityLink.getUserId());
            }
        }
    }
    /**查詢歷史任務的辦理人表*/
    @Test
    public void findHistoryPersonTask(){
        //流程例項ID
        String processInstanceId = "6201";
        List<HistoricIdentityLink> list = processEngine.getHistoryService()//
                        .getHistoricIdentityLinksForProcessInstance(processInstanceId);
        if(list!=null && list.size()>0){
            for(HistoricIdentityLink identityLink:list){
                System.out.println(identityLink.getTaskId()+"   "+identityLink.getType()+"   "+identityLink.getProcessInstanceId()+"   "+identityLink.getUserId());
            }
        }
    }


    /**拾取任務,將組任務分給個人任務,指定任務的辦理人欄位*/
    @Test
    public void claim(){
        //將組任務分配給個人任務
        //任務ID
        String taskId = "6905";
        //分配的個人任務(可以是組任務中的成員,也可以是非組任務的成員)
        String userId = "大大";
        processEngine.getTaskService()//
                    .claim(taskId, userId);
    }


    /**將個人任務回退到組任務,前提,之前一定是個組任務*/
    @Test
    public void setAssigee(){
        //任務ID
        String taskId = "6204";
        processEngine.getTaskService()//
                    .setAssignee(taskId, null);
    }

    /**向組任務中新增成員*/
    @Test
    public void addGroupUser(){
        //任務ID
        String taskId = "6204";
        //成員辦理人
        String userId = "大H";
        processEngine.getTaskService()//
                    .addCandidateUser(taskId, userId);
    }

    /**從組任務中刪除成員*/
    @Test
    public void deleteGroupUser(){
        //任務ID
        String taskId = "6204";
        //成員辦理人
        String userId = "小B";
        processEngine.getTaskService()//
                    .deleteCandidateUser(taskId, userId);
    }

說明:
1)大大,中中,小小是組任務的辦理人
2)在開發中,可以在頁面中指定下一個組任務的辦理人,通過流程變數設定下一個任務的辦理人

四、分配個人任務方式三(使用類)

1:流程圖中任務節點的配置
這裡寫圖片描述
這裡寫圖片描述
此時流程圖的XML檔案,如圖:
這裡寫圖片描述
2:TaskListenerImpl類,用來設定任務的辦理人

@SuppressWarnings("serial")
public class TaskListenerImpl implements TaskListener {

    /**用來指定任務的辦理人*/
    @Override
    public void notify(DelegateTask delegateTask) {
        //指定個人任務的辦理人,也可以指定組任務的辦理人
        //個人任務:通過類去查詢資料庫,將下一個任務的辦理人查詢獲取,然後通過setAssignee()的方法指定任務的辦理人
        //delegateTask.setAssignee("滅絕師太");
        //組任務:
        delegateTask.addCandidateUser("郭靖");
        delegateTask.addCandidateUser("黃蓉");
    }

}

3:測試程式碼

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**部署流程定義(從inputStream)*/
    @Test
    public void deploymentProcessDefinition_inputStream(){
        InputStream inputStreamBpmn = this.getClass().getResourceAsStream("task.bpmn");
        InputStream inputStreamPng = this.getClass().getResourceAsStream("task.png");
        Deployment deployment = processEngine.getRepositoryService()//與流程定義和部署物件相關的Service
                        .createDeployment()//建立一個部署物件
                        .name("任務")//新增部署的名稱
                        .addInputStream("task.bpmn", inputStreamBpmn)//
                        .addInputStream("task.png", inputStreamPng)//
                        .deploy();//完成部署
        System.out.println("部署ID:"+deployment.getId());//
        System.out.println("部署名稱:"+deployment.getName());//
    }

    /**啟動流程例項*/
    @Test
    public void startProcessInstance(){
        //流程定義的key
        String processDefinitionKey = "task";
        ProcessInstance pi = processEngine.getRuntimeService()//與正在執行的流程例項和執行物件相關的Service
                        .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key啟動流程例項,key對應helloworld.bpmn檔案中id的屬性值,使用key值啟動,預設是按照最新版本的流程定義啟動
        System.out.println("流程例項ID:"+pi.getId());//流程例項ID  
        System.out.println("流程定義ID:"+pi.getProcessDefinitionId());//流程定義ID   
    }

    /**查詢當前人的個人任務*/
    @Test
    public void findMyPersonalTask(){
        String assignee = "郭靖";
        List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service
                        .createTaskQuery()//建立任務查詢物件
                        /**查詢條件(where部分)*/
                        .taskAssignee(assignee)//指定個人任務查詢,指定辦理人
//                      .taskCandidateUser(candidateUser)//組任務的辦理人查詢
                        /**排序*/
                        .orderByTaskCreateTime().asc()//使用建立時間的升序排列
                        /**返回結果集*/
                        .list();//返回列表
        if(list!=null && list.size()>0){
            for(Task task:list){
                System.out.println("任務ID:"+task.getId());
                System.out.println("任務名稱:"+task.getName());
                System.out.println("任務的建立時間:"+task.getCreateTime());
                System.out.println("任務的辦理人:"+task.getAssignee());
                System.out.println("流程例項ID:"+task.getProcessInstanceId());
                System.out.println("執行物件ID:"+task.getExecutionId());
                System.out.println("流程定義ID:"+task.getProcessDefinitionId());
                System.out.println("########################################################");
            }
        }
    }

    /**查詢當前人的組任務*/
    @Test
    public void findMyGroupTask(){
        String candidateUser = "郭靖";
        List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service
                        .createTaskQuery()//建立任務查詢物件
                        /**查詢條件(where部分)*/
                        .taskCandidateUser(candidateUser)//組任務的辦理人查詢
                        /**排序*/
                        .orderByTaskCreateTime().asc()//使用建立時間的升序排列
                        /**返回結果集*/
                        .list();//返回列表
        if(list!=null && list.size()>0){
            for(Task task:list){
                System.out.println("任務ID:"+task.getId());
                System.out.println("任務名稱:"+task.getName());
                System.out.println("任務的建立時間:"+task.getCreateTime());
                System.out.println("任務的辦理人:"+task.getAssignee());
                System.out.println("流程例項ID:"+task.getProcessInstanceId());
                System.out.println("執行物件ID:"+task.getExecutionId());
                System.out.println("流程定義ID:"+task.getProcessDefinitionId());
                System.out.println("########################################################");
            }
        }
    }

    /**完成我的任務*/
    @Test
    public void completeMyPersonalTask(){
        //任務ID
        String taskId = "7204";
        processEngine.getTaskService()//與正在執行的任務管理相關的Service
                    .complete(taskId);
        System.out.println("完成任務:任務ID:"+taskId);
    }


    /**查詢正在執行的任務辦理人表*/
    @Test
    public void findRunPersonTask(){
        //任務ID
        String taskId = "6204";
        List<IdentityLink> list = processEngine.getTaskService()//
                    .getIdentityLinksForTask(taskId);
        if(list!=null && list.size()>0){
            for(IdentityLink identityLink:list){
                System.out.println(identityLink.getTaskId()+"   "+identityLink.getType()+"   "+identityLink.getProcessInstanceId()+"   "+identityLink.getUserId());
            }
        }
    }
    /**查詢歷史任務的辦理人表*/
    @Test
    public void findHistoryPersonTask(){
        //流程例項ID
        String processInstanceId = "6201";
        List<HistoricIdentityLink> list = processEngine.getHistoryService()//
                        .getHistoricIdentityLinksForProcessInstance(processInstanceId);
        if(list!=null && list.size()>0){
            for(HistoricIdentityLink identityLink:list){
                System.out.println(identityLink.getTaskId()+"   "+identityLink.getType()+"   "+identityLink.getProcessInstanceId()+"   "+identityLink.getUserId());
            }
        }
    }


    /**拾取任務,將組任務分給個人任務,指定任務的辦理人欄位*/
    @Test
    public void claim(){
        //將組任務分配給個人任務
        //任務ID
        String taskId = "7204";
        //分配的個人任務(可以是組任務中的成員,也可以是非組任務的成員)
        String userId = "郭靖";
        processEngine.getTaskService()//
                    .claim(taskId, userId);
    }


    /**將個人任務回退到組任務,前提,之前一定是個組任務*/
    @Test
    public void setAssigee(){
        //任務ID
        String taskId = "6204";
        processEngine.getTaskService()//
                    .setAssignee(taskId, null);
    }

    /**向組任務中新增成員*/
    @Test
    public void addGroupUser(){
        //任務ID
        String taskId = "6204";
        //成員辦理人
        String userId = "大H";
        processEngine.getTaskService()//
                    .addCandidateUser(taskId, userId);
    }

    /**從組任務中刪除成員*/
    @Test
    public void deleteGroupUser(){
        //任務ID
        String taskId = "6204";
        //成員辦理人
        String userId = "小B";
        processEngine.getTaskService()//
                    .deleteCandidateUser(taskId, userId);
    }

說明:
1)在類中使用delegateTask.addCandidateUser (userId);的方式分配組任務的辦理人,此時孫悟空和豬八戒是下一個任務的辦理人。
2)通過processEngine.getTaskService().claim (taskId, userId);將組任務分配給個人任務,也叫認領任務,即指定某個人去辦理這個任務,此時由如來去辦理任務。
注意:認領任務的時候,可以是組任務成員中的人,也可以不是組任務成員的人,此時通過Type的型別為participant來指定任務的辦理人
3)addCandidateUser()即向組任務新增成員,deleteCandidateUser()即刪除組任務的成員。
4)在開發中,可以將每一個任務的辦理人規定好,例如張三的領導是李四和王五,這樣張三提交任務,由李四或者王五去查詢組任務,可以看到對應張三的申請,李四或王五再通過認領任務(claim)的方式,由某個人去完成這個任務。

五、總結

組任務及三種分配方式:
1:在taskProcess.bpmn中直接寫 candidate-users=“小A,小B,小C,小D”
2:在taskProcess.bpmn中寫 candidate-users =“#{userIDs}”,變數的值要是String的。
使用流程變數指定辦理人

  Map<String, Object> variables = new HashMap<String, Object>();
              variables.put("userIDs", "大大,小小,中中");

3,使用TaskListener介面,使用類實現該介面,在類中定義:

//新增組任務的使用者
delegateTask.addCandidateUser(userId1);
delegateTask.addCandidateUser(userId2);

組任務分配給個人任務(認領任務):

processEngine.getTaskService().claim(taskId, userId);

個人任務分配給組任務:

 processEngine.getTaskService(). setAssignee(taskId, null);

向組任務新增人員:

 processEngine.getTaskService().addCandidateUser(taskId, userId);

向組任務刪除人員:

 processEngine.getTaskService().deleteCandidateUser(taskId, userId);

個人任務和組任務存放辦理人對應的表:
act_ru_identitylink表存放任務的辦理人,包括個人任務和組任務,表示正在執行的任務
act_hi_identitylink表存放任務的辦理人,包括個人任務和組任務,表示歷史任務
區別在於:如果是個人任務TYPE的型別表示participant(參與者)
如果是組任務TYPE的型別表示candidate(候選者)和participant(參與者)