2023 latest version Activiti7 series – identity service

Identity Services

In the process definition, the task leader is fixed in the assignee of the task node, and the participants are fixed in the .bpmn file when the process is defined. If the temporary task leader changes, the process definition needs to be modified, and the system has poor scalability. For this situation, multiple candidates or candidate groups can be set for the task, and participants can be selected from the candidates to complete the task.

1. Approver

The processing of users who are directly assigned approval in the previous case

2. Candidate

An approval node may have multiple people with approval authority at the same time. That’s when we can deal with candidates.

2.1 Drawing a flowchart

We define a simple approval flow chart. as follows:

In the personnel approval process, we set up multiple candidates for processing, namely Zhang San, Li Si, Wang Wu

In the position of general manager, we uniformly set up several candidates for approval

The content of the xml file of the created corresponding flow chart is as follows:

2.2 Deployment and startup process

After the flow chart is designed, we can deploy the process and start the process instance.

/**
 * Process deployment operation
 */
@Test
public void test1(){<!-- -->
    // 1. Get the ProcessEngine object
    ProcessEngine processEngine = ProcessEngines. getDefaultProcessEngine();
    // 2. To complete the deployment operation of the process, it needs to be completed through RepositoryService
    RepositoryService repositoryService = processEngine. getRepositoryService();
    // 3. Complete the deployment operation
    Deployment deploy = repositoryService. createDeployment()
            .addClasspathResource("flow/test5.bpmn20.xml")
            .name("Candidate")
            .deploy(); // is the behavior of a process deployment and can deploy multiple process definitions
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
}

/**
 * Initiate a process
 */
@Test
public void test3(){<!-- -->
    ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
    // Initiating the process needs to be implemented through runtimeService
    RuntimeService runtimeService = engine. getRuntimeService();
    // Start the process through the process definition ID and return the process instance object
    ProcessInstance processInstance = runtimeService
            .startProcessInstanceById("holiday1:2:90003");
    System.out.println("processInstance.getId() = " + processInstance.getId());
    System.out.println("processInstance.getDeploymentId() = " + processInstance.getDeploymentId());
    System.out.println("processInstance.getDescription() = " + processInstance.getDescription());
}

After starting the process instance. The approver in act_ru_task is empty,

But in the corresponding act_ru_identitylink we can see the corresponding candidate information

1.3 Pickup of tasks

Candidates need to be operated by picking to convert candidate into processor. Then the candidate needs to be able to find out after logging in Tasks that can be picked.

 /**
     * Candidate approval task query
     * Zhang San logs into the OA system
     */
    @Test
    public void test4(){<!-- -->
        ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
        TaskService taskService = engine. getTaskService();
        List<Task> list = taskService. createTaskQuery()
                .taskCandidateUser("Zhang San") // Query and approve tasks based on candidates
                .list();
        if(list != null & amp; & amp; list. size() > 0){<!-- -->
            for (Task task : list) {<!-- -->
                System.out.println("task.getId() = " + task.getId());
                //taskService.complete(task.getId());
            }
        }
    }

/**
 * Pickup operation for pending tasks
 * from candidate --> handler
 * A quest if picked up. Other candidates will not be able to query the task information
 */
@Test
public void test5(){<!-- -->
    ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
    TaskService taskService = engine. getTaskService();
    List<Task> list = taskService. createTaskQuery()
            .taskCandidateUser("Wang Wu") // Query and approve tasks based on candidates
            .list();
    if(list != null & amp; & amp; list. size() > 0){<!-- -->
        for (Task task : list) {<!-- -->
            // Li Si picked up the approval authority of this task --> became the approver of this task
            taskService.claim(task.getId(),"Wang Wu");
        }
    }
}

1.4. Task return

After picking up the task, if you don’t want to operate it, you can return the task

/**
 * Return: The user who picked it up will not be approved. just abandon the approver's operation
 * Other candidates can pick people up again
 */
@Test
public void test6(){<!-- -->
    ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
    TaskService taskService = engine. getTaskService();
    List<Task> list = taskService. createTaskQuery()
            .taskCandidateOrAssigned("Li Si") // Query to-do tasks according to the approver or candidate
            .list();
    if(list != null & amp; & amp; list. size() > 0){<!-- -->
        for (Task task : list) {<!-- -->
            // System.out.println("task.getId() = " + task.getId());
            // The essence of the return operation is actually to set the approver to be empty
            taskService.unclaim(task.getId());
        }
    }
}

3. Candidate group

When there are a lot of candidates, we can handle them in groups. Create a group first, and then assign users to this group.

3.1 Flow chart drawing

Then set through the candidate group when setting the approver

Definition information in the corresponding flowchart xml

3.2 Process operation

Process operations include deploy, start, pickup, return and handover, etc. operate

/**
 * Process deployment operation
 */
@Test
public void test1(){<!-- -->
    // 1. Get the ProcessEngine object
    ProcessEngine processEngine = ProcessEngines. getDefaultProcessEngine();
    // 2. To complete the deployment operation of the process, it needs to be completed through RepositoryService
    RepositoryService repositoryService = processEngine. getRepositoryService();
    // 3. Complete the deployment operation
    Deployment deploy = repositoryService. createDeployment()
            .addClasspathResource("flow/test6.bpmn20.xml")
            .name("Candidate group")
            .deploy(); // is the behavior of a process deployment and can deploy multiple process definitions
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
}

/**
 * Initiate a process
 */
@Test
public void test3(){<!-- -->
    ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
    // Initiating the process needs to be implemented through runtimeService
    RuntimeService runtimeService = engine. getRuntimeService();
    // Start the process through the process definition ID and return the process instance object
    ProcessInstance processInstance = runtimeService
            .startProcessInstanceById("holiday1:3:97503");
    System.out.println("processInstance.getId() = " + processInstance.getId());
    System.out.println("processInstance.getDeploymentId() = " + processInstance.getDeploymentId());
    System.out.println("processInstance.getDescription() = " + processInstance.getDescription());
}

/**
 * Candidate group:
 * Specific users. For example, Zhang San logged into the system
 * Query the corresponding group of Zhang San to query the tasks to be done according to the group
 */
@Test
public void test4(){<!-- -->
    ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
    TaskService taskService = engine. getTaskService();
    String group = "Sales Department"; // Query based on the currently logged in user
    List<Task> list = taskService. createTaskQuery()
            .taskCandidateGroup(group)
            .list();
    if(list != null & amp; & amp; list. size() > 0){<!-- -->
        for (Task task : list) {<!-- -->
            System.out.println("task.getId() = " + task.getId());
            //taskService.complete(task.getId());
        }
    }
}

/**
 * Pickup operation for pending tasks
 * from candidate --> handler
 * A quest if picked up. Other candidates will not be able to query the task information
 */
@Test
public void test5(){<!-- -->
    ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
    TaskService taskService = engine. getTaskService();
    String group = "Sales Department"; // Query based on the currently logged in user
    List<Task> list = taskService. createTaskQuery()
            .taskCandidateGroup(group) // query according to the group
            .list();
    if(list != null & amp; & amp; list. size() > 0){<!-- -->
        for (Task task : list) {<!-- -->
            // Zhang San 1 picked up the approval authority of this task --> became the approver of this task
            taskService.claim(task.getId(),"Zhang San 1");
        }
    }
}

/**
 * Return: The user who picked it up will not be approved. just abandon the approver's operation
 * Other candidates can pick people up again
 */
@Test
public void test6(){<!-- -->
    ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
    TaskService taskService = engine. getTaskService();
    String group = "Sales Department"; // Query based on the currently logged in user
    List<Task> list = taskService. createTaskQuery()
            .taskAssignee("Zhang San 1")
            .list();
    if(list != null & amp; & amp; list. size() > 0){<!-- -->
        for (Task task : list) {<!-- -->
            // System.out.println("task.getId() = " + task.getId());
            // The essence of the return operation is actually to set the approver to be empty
            taskService.unclaim(task.getId());
        }
    }
}

/**
 * Users who have obtained user approval permission have no time to approve
 * But he can also hand over the task instead of returning it. Have this task approved by another person
 */
@Test
public void test8(){<!-- -->
    ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
    TaskService taskService = engine. getTaskService();
    String group = "Sales Department"; // Query based on the currently logged in user
    List<Task> list = taskService. createTaskQuery()
            .taskAssignee("Zhang San 1")
            .list();
    if(list != null & amp; & amp; list. size() > 0){<!-- -->
        for (Task task : list) {<!-- -->
            // System.out.println("task.getId() = " + task.getId());
            // task handover
            taskService.setAssignee(task.getId(),"Li Si 1");
        }
    }
}

/**
 * Task approval
 */
@Test
public void test7(){<!-- -->
    ProcessEngine engine = ProcessEngines. getDefaultProcessEngine();
    TaskService taskService = engine. getTaskService();
    taskService.complete("92505");
}

The candidate group information in the corresponding process is also recorded in act_ru_identitylink