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