天天看點

【flowable】九、flowable候選人和候選人組

flowable候選人和候選人組

之前在流程定義中的任務節點設定的負責人assignee都是固定的負責人,在流程定義設計時将參與者與檔案固定設定了,如需變更任務負責人需要修改流程定義,系統可擴充性差。

針對這種情況可以給任務設定多個候選人或者候選人組,可以從候選人中選擇參與者來完成任務。

這裡讨論的是組任務,不同于流程變量來控制任務負責人。

1 候選人

1.1 設計流程

設計一個簡單的新流程。

首先是“請假申請”,在配置設定使用者項設定兩個候選使用者。

【flowable】九、flowable候選人和候選人組
【flowable】九、flowable候選人和候選人組

“經理稽核”就設定一個

${assignee0}

流程變量即可。

1.2 部署流程和啟動流程執行個體
/**
     * 部署流程
     */
    @Test
    public void deployment() {
        //擷取ProcessEngine對象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //擷取RepositoryService對象,部署流程定義
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //執行部署
        repositoryService.createDeployment()
                .addClasspathResource("flowable-4.bpmn20.xml")
                .deploy();
    }

    /**
     * 啟動流程
     */
    @Test
    public void startProcess() {
        //擷取ProcessEngine對象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //通過RuntimeService啟動流程
        //通過流程定義ID啟動流程執行個體
        //流程定義的ID在流程部署成功後,act_re_procdef表生成的資料主鍵ID就是流程定義ID
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //設定候選人流程變量
        Map<String, Object> variables = new HashMap<>();
        variables.put("candidate0", "員工1");
        variables.put("candidate1", "員工2");

        ProcessInstance processInstance = runtimeService.startProcessInstanceById("flowable-4:1:10004", variables);
        // 輸出相關的流程執行個體資訊
        System.out.println("流程定義的ID:" + processInstance.getProcessDefinitionId());
        System.out.println("流程執行個體的ID:" + processInstance.getId());
    }
           

流程啟動後,

act_ru_variable

表可以看到候選人流程變量

【flowable】九、flowable候選人和候選人組

act_ru_task

表的

ASSIGNEE_

字段是null

【flowable】九、flowable候選人和候選人組

說明目前任務并沒有配置設定給任何人,無人受理

1.3 任務查詢

可以通過候選人進行查詢任務

/**
     * 候選人任務查詢
     */
    @Test
    public void queryTaskCandidate() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //擷取TaskService
        TaskService taskService = processEngine.getTaskService();
        List<Task> taskList = taskService.createTaskQuery().processInstanceId("12501")
                //設定taskCandidateUser候選人條件來查詢任務,這裡的參數值就是候選人流程變量綁定的值
                //員工1和員工2都是可以查詢到資料的
                .taskCandidateUser("員工1")
                .list();
        for (Task task : taskList) {
            System.out.println("task.getId() = " + task.getId());
            System.out.println("task.getName() = " + task.getName());
        }
    }
           
1.4 任務拾取

根據候選人查詢到任務後就可以拾取該任務。注意:當一個任務被拾取後,其他使用者是無法拾取該任務的。

任務拾取成功後,就會變成個人任務

/**
     * 候選人拾取任務
     */
    @Test
    public void claimTaskCandidate() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //擷取TaskService
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId("12501")
                //設定taskCandidateUser候選人條件來查詢任務,這裡的參數值就是候選人流程變量綁定的值
                //員工1和員工2都是可以查詢到資料的
                .taskCandidateUser("員工1")
                .singleResult();


        if (task != null) {
            /**
             * 拾取任務
             * 即使該使用者不是任務的候選人也可以拾取任務,建議拾取時做校驗,根據候選人查詢
             * 任務拾取成功後,就會變成個人任務,之後的操作就和之前一樣了,complete即可
             */
            taskService.claim(task.getId(), "員工1");
        }
    }
           
【flowable】九、flowable候選人和候選人組

說明:即使不是任務的候選人也可以進行拾取任務,是以需要根據任務候選人去查詢任務再去進行拾取

1.5 任務歸還

如果任務拾取之後不想操作或者誤拾取任務也可以進行歸還任務。

/**
     * 任務歸還
     */
    @Test
    public void unClaimTaskCandidate() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //擷取TaskService
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId("12501")
                //員工1拾取的任務,需要通過員工1查詢
                .taskAssignee("員工1")
                .singleResult();

        if (task != null) {
            taskService.unclaim(task.getId());
        }
    }
           

任務成功歸還後,

ASSIGNEE_

就會為null,需要由任務候選人重新拾取

【flowable】九、flowable候選人和候選人組
1.6 任務交接

如果任務拾取後,不想操作也不想歸還,可以交接給他人進行處理。

/**
     * 任務交接
     */
    @Test
    public void taskCandidate() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //擷取TaskService
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId("12501")
                //員工1拾取的任務,需要通過員工1查詢
                .taskAssignee("員工1")
                .singleResult();

        if (task != null) {
            /**
             * 任務交接,就是更新任務的配置設定人字段
             * 由于可配置設定給任意的人員,是以建議實際開發中做判斷處理,隻将任務配置設定給候選人
             */
            taskService.setAssignee(task.getId(), "員工3");
        }
    }
           
1.7 任務完成

就是之前正常處理流程,調用complete方法

/**
     * 任務完成
     */
    @Test
    public void taskComplete() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //擷取TaskService
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId("12501")
                .taskAssignee("員工3")
                .singleResult();

        if (task != null) {
            //流程設計的時候,經理審批有個`assignee0`流程變量,是以這裡設定下
            Map<String, Object> variables = new HashMap<>();
            variables.put("assignee0", "經理");
            taskService.complete(task.getId(), variables);
        }
    }
           

2 候選人組

當候選人很多的情況下,我們可以分組來處理。先建立組,然後把使用者配置設定到這個組中。

2.1 管理使用者群組

2.1.1 使用者管理

通過

act_id_user

表維護使用者

/**
     * 維護使用者
     */
    @Test
    public void createUser() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 通過 IdentityService 完成相關的使用者群組的管理
        IdentityService identityService = processEngine.getIdentityService();

        User user = null;
        for (int i = 1; i <= 3; i++) {
            user = identityService.newUser("員工" + i);
            user.setFirstName(i+"");
            user.setEmail(i+"@qq.com");
            identityService.saveUser(user);
        }
    }
           

2.1.2 使用者組管理

通過

act_id_group

表維護

/**
     * 維護使用者組
     */
    @Test
    public void createGroup() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 通過 IdentityService 完成相關的使用者群組的管理
        IdentityService identityService = processEngine.getIdentityService();

        Group group = identityService.newGroup("group1");
        group.setName("研發部");
        group.setType("1");
        identityService.saveGroup(group);

    }
           

2.1.3 使用者和使用者組關聯

通過

act_id_membership

表維護

/**
     * 使用者和使用者組關聯
     */
    @Test
    public void userGroup() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        IdentityService identityService = processEngine.getIdentityService();

        // 根據組的編号找到對應的Group對象
        Group group = identityService.createGroupQuery().groupId("group1").singleResult();
        //找到使用者
        List<User> users = identityService.createUserQuery().list();
        for (User user : users) {
            //使用者配置設定給使用者組
            identityService.createMembership(user.getId(), group.getId());
        }

    }
           
2.2 候選人組應用

使用者和使用者組的建立及關聯搞清楚後,就可以使用候選人組實作流程任務配置設定了

2.2.1 設計流程

設計一個新的流程。

【flowable】九、flowable候選人和候選人組
【flowable】九、flowable候選人和候選人組

2.2.2 部署流程和啟動流程執行個體

/**
     * 部署流程
     */
    @Test
    public void deployment() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        RepositoryService repositoryService = processEngine.getRepositoryService();

        repositoryService.createDeployment().addClasspathResource("flowable-5.bpmn20.xml").name("候選人組流程").deploy();
    }

    /**
     * 啟動流程
     */
    @Test
    public void startProcess() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //查詢到使用者組
        IdentityService identityService = processEngine.getIdentityService();
        Group group = identityService.createGroupQuery().groupId("group1").singleResult();

        //然後給流程設計裡面的${group1}流程變量指派
        Map<String, Object> variables = new HashMap<>();
        variables.put("group1", group.getId());

        runtimeService.startProcessInstanceById("flowable-5:1:32504", variables);
    }
           

act_ru_identitylink

表中可以看到流程任務綁定的候選人組

【flowable】九、flowable候選人和候選人組

2.2.3 任務的拾取和完成

/**
     * 查詢候選人組任務
     */
    @Test
    public void queryTaskCandidateGroup() {
        //擷取ProcessEngine引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //根據使用者擷取候選組
        IdentityService identityService = processEngine.getIdentityService();
        Group group = identityService.createGroupQuery().groupMember("員工1").singleResult();

        //擷取組任務
        TaskService taskService = processEngine.getTaskService();
        List<Task> taskList = taskService.createTaskQuery()
                .processInstanceId("35001")
                .taskCandidateGroup(group.getId())
                .list();

        for (Task task : taskList) {
            System.out.println("task.getId() = " + task.getId());
            System.out.println("task.getName() = " + task.getName());
        }
    }
           
/**
     * 拾取組任務
     * 就是通過候選組綁定查詢出來的任務,然後拾取,和普通的流程任務操作一樣
     * 正常業務開發下,該組下的任務隻能由該組人員拾取
     * 拾取之後,不想操作的話也可以退還或者交接給他人
     */
    @Test
    public void claimTaskCandidate() {
//擷取ProcessEngine引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //根據使用者擷取候選組
        IdentityService identityService = processEngine.getIdentityService();
        Group group = identityService.createGroupQuery().groupMember("員工1").singleResult();

        //擷取組任務
        TaskService taskService = processEngine.getTaskService();
        List<Task> taskList = taskService.createTaskQuery()
                .processInstanceId("35001")
                .taskCandidateGroup(group.getId())
                .list();

        for (Task task : taskList) {
            System.out.println("task.getId() = " + task.getId());
            System.out.println("task.getName() = " + task.getName());
            //拾取
            taskService.claim(task.getId(), "員工1");
            System.out.println("任務:"+task.getName()+"拾取成功");
        }
    }
           
/**
     * 完成組任務
     * 就是完成正常的一個流程任務
     */
    @Test
    public void completeTask() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        Task task = taskService.createTaskQuery().processInstanceId("35001").taskAssignee("員工1").singleResult();
        Assert.assertNotNull(task);
        //流程設計的時候有個assignee0流程變量,這裡需要設定下
        Map<String, Object> variables = new HashMap<>();
        variables.put("assignee0", "經理");
        taskService.complete(task.getId(), variables);
    }
           

啟動流程執行個體之後,查詢目前任務執行表:

記錄了目前執行的任務,由于該任務是組任務,

assignee_

字段值是null,讓拾取任務之後該字段才會有拾取使用者的資訊。

查詢任務參與者:

select * from act_ru_identitylink
           

記錄了參與任務使用者或組,目前任務如果設定了候選人,就會向該表插入候選人記錄,有幾個候選人就插入幾條記錄,與

act_ru_identitylink

對應的還有一張曆史表

act_hi_identitylink

,向

act_ru_identitylink

插入記錄的同時也會向

act_hi_identitylink

插入記錄。

繼續閱讀