Activiti basic use 2

Table of contents

3. Process example

3.1, what is a process instance

3.2. Associate the actual business with the activiti table (BusinessKey)

3.3. Suspend and activate the process instance

3.3.1. All process instances are suspended

3.3.2. A single process instance hangs

4. Task assignment

4.1. Fixed distribution

4.2. Expression assignment

4.2.1、UEL-value

4.2.2, UEL-method

4.3. Listener assignment

5. Process variables

5.1, what is a process variable

5.2, the scope of process variables

5.2.1, global variables

5.2.2, local variables

5.3. How to use process variables

5.4, ​​set the global variable

5.4.1. Set variables when starting the process

5.4.2. Set process variables when handling tasks

5.4.3, through the current process instance settings

5.5. Set Local variables

6. Task group

6.1, Candidate-users candidates

6.2. Group task handling process

6.3. Key code

6.3.1, deployment and start

6.3.2. Query group tasks

6.3.2. Pick up group tasks

6.3.3. Query personal to-do tasks

6.3.4. Handle personal tasks

6.3.5. Return group tasks

6.3.6. Task handover

7. Gateway

7.1. Exclusive Gateway

7.2. Parallel Gateway

7.3, including the gateway


3. Process example

Basic operation reference: Basic use of Activiti_Relievedz's Blog-CSDN Blog

3.1, what is a process instance

Process definition ProcessDefinition and process instance ProcessInstance are important concepts of Activiti, similar to the relationship between Java classes and Java instances

Starting a process instance means starting a business process operation. For example, the deployment of the employee leave process is completed. If Zhang San wants to ask for leave, he can start a process instance. If Li Si wants to ask for leave, he can also start a process instance. The execution of the two processes does not affect each other. , just like defining a java class and instantiating two objects, the deployment process is like a java class, starting a process instance is like new a java object

3.2. Associate the actual business with the activiti table (BusinessKey)

For example, if we fill out a leave form, there must be a unique identification of the leave form. We usually use this identification to associate activiti. This identification is called businesskey in activiti

BusinessKey: business identifier, usually the primary key of the business, the business identifier and the process identifier correspond one-to-one, the business identifier comes from the business system, and the storage of the business identifier is to associate and query the data of the business system according to the business identifier

For example: when the leave process starts a process instance, the id of the leave request can be stored in activiti as a business identifier. In the future, the id of the leave request can be obtained by querying the process instance information of activiti, so as to query the business system database to obtain the leave request information

/** 
 * Start the process instance, add businessKey 
 */ 
@Test 
public void startUpProcessAddBusinessKey(){ 
    String businessKey = "1"; 
    // Start the process instance, specify the business identifier businessKey, which is the leave application form id 
    ProcessInstance processInstance = 
            runtimeService.startProcessInstanceByKey ("qingjia",businessKey); 
    // output 
    System.out.println("business id:"+processInstance.getBusinessKey()); 
}

3.3. Suspend and activate the process instance

In some cases, it may be necessary to suspend the currently running process instead of directly deleting it due to process changes. After the process is suspended, it will not be executed;

3.3.1. All process instances are suspended

The operation process definition is in a suspended state, and all process instances under the process definition are suspended: The process definition is in a suspended state, and the process definition will not allow new process instances to be started, and at the same time, all process instances under the process definition will be suspended suspend execution

//Suspend all process instances 
@Test 
public void suspendProcessInstanceAll() { 
    //1 Get the process definition object 
    ProcessDefinition qingjia = repositoryService.createProcessDefinitionQuery() 
            .processDefinitionKey("qingjia").singleResult(); 

    //2 Call the process definition object The method to judge the current state: suspend activation 
    boolean suspended = qingjia.isSuspended(); 

    //3 judge if suspended, realize activation 
    if(suspended) { 
        //The first parameter process definition id 
        //The second parameter is activated true 
        //The third parameter time point 
        repositoryService 
                .activateProcessDefinitionById(qingjia.getId(), 
                        true,null); 
        System.out.println(qingjia.getId()+"activated"); 
    } else { 
        //If activated, implement suspension 
        repositoryService 
                .suspendProcessDefinitionById(qingjia.getId(), 
                        true,null); 
        System.out.println(qingjia.getId()+"suspend"); 
    } 
}

3.3.2. A single process instance hangs

Operate the process instance object, execute the suspend operation for a single process, if a process instance is suspended, the process will not continue to execute, and an exception will be reported when the current task of the process instance is completed;

//单个流程实例挂起
@Test
public void SingleSuspendProcessInstance() {
    String processInstanceId = "b98e42b3-df27-11ed-b184-005056c00001";
    ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
            .processInstanceId(processInstanceId)
            .singleResult();
    boolean suspended = processInstance.isSuspended();
    if (suspended) {
        //激活
        runtimeService.activateProcessInstanceById(processInstanceId);
        System.out.println(processInstanceId + "激活");
    } else {
        runtimeService.suspendProcessInstanceById(processInstanceId);
        System.out.println(processInstanceId + "Pending"); 
    }
}

4. Task assignment

There are three ways to assign tasks

  1. fixed allocation

  2. UEL expression assignment

  3. listener assignment

4.1. Fixed distribution

Specify a fixed task leader in the previous business process modeling, such as: Assignee: zhangsan/lisi

4.2. Expression assignment

activiti uses UEL expressions. UEL is part of the java EE6 specification. UEL is the unified expression language. activiti supports two UEL expressions: UEL-value and UEL-method.

4.2.1、UEL-value

New: an overtime process

As shown in the picture:

assignee1 This variable is a process variable of activiti

We start the process instance. The method of starting the instance is basically the same as the previous method. The only difference is that a parameter is added at startup

@Test 
public void deployProcess01() { 
    // Process deployment 
    Deployment deploy = repositoryService.createDeployment() 
            .addClasspathResource("process/jiaban.bpmn20.xml") 
            .name("Overtime application process") 
            .deploy(); 
    System.out .println(deploy.getId()); 
    System.out.println(deploy.getName()); 
} 

/** 
 * Start process instance 
 */ 
@Test 
public void startUpProcess01() { 
    Map<String, Object> map = new HashMap<>(); 
    map.put("assignee1","lucy"); 
    map.put("assignee2","mary"); 
    //To create a process instance, we need to know the key of the process definition 
    ProcessInstance processInstance =
            runtimeService.startProcessInstanceByKey("jiaban", map); 
    //Output instance related information 
    System.out.println("process definition id:" + processInstance.getProcessDefinitionId()); 
    System.out.println("process instance id:" + processInstance. getId()); 
}

4.2.2, UEL-method

As shown in the picture:

userBean is a bean in the spring container, which means calling the bean's getUsername(int id) method.

Manager approval: ${userBean.getUsername(1)}

Personnel approval: ${userBean.getUsername(2)}

package com.atguigu.auth.activiti; 

import org.springframework.stereotype.Component; 

/** 
 * @program: guigu-oa-perent 
 * @description: userBean is a bean in the spring container, which means calling the bean's getUsername( int id) method. 
 * @author: Mr.Zhang 
 * @create: 2023-04-20 11:42 
 **/ 
@Component 
public class UserBean { 

    public String getUsername(int id) { 
        if(id == 1) { 
            return "lilei"; 
        } 
        if(id == 2) { 
            return "wyz"; 
        } 
        return "admin"; 
    } 
}

Deploy and start

/
//uel-method
@Test
public void deployProcess01() {
    Deployment deployment = repositoryService.createDeployment()
            .addClasspathResource("process/jiaban01.bpmn20.xml")
            .name("加班申请流程01")
            .deploy();
    System.out.println(deployment.getId());
    System.out.println(deployment.getName());
}

@Test
public void startProcessInstance01() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban01");
    System.out.println(processInstance.getProcessDefinitionId());
    System.out.println(processInstance.getId());
}

When the process instance is started, the bean method will be called, the parameter is: 1, after the manager approves, then the bean method is called, the parameter is: 2

4.3. Listener assignment

Use the listener method to specify the person in charge, so you don't need to specify the assignee when designing the process.

The task listener is to execute custom java logic or expression when the corresponding task-related event occurs

Event options include:

Create: Triggered after the task is created 
Assignment: Triggered after the task is assigned 
Delete: Triggered after the task is completed 
All: Triggered when all events occur

Define the task listening class, and the class must implement the org.activiti.engine.delegate.TaskListener interface

package com.atguigu.auth.activiti; 

import org.activiti.engine.delegate.DelegateTask; 
import org.activiti.engine.delegate.TaskListener; 

/** 
 * @program: guigu-oa-perent 
 * @description: Define task listener class 
 * @author: Mr.Zhang 
 * @create: 2023-04-21 08:55 
 **/ 
public class MyTaskListener implements TaskListener { 
    @Override 
    public void notify(DelegateTask task) { 
        if(task.getName().equals(" Manager Approval")){ 
            // Assign task 
            task.setAssignee("jack"); 
        } else if (task.getName().equals("Personnel Approval")) { 
            task.setAssignee("tom"); 
        } 
    } 
}

Configure the listener

Both manager approval and personnel approval can be set to the same monitor

Deploy and test

//
//监听器分配任务
@Test
public void deployProcess02() {
    Deployment deployment = repositoryService.createDeployment()
            .addClasspathResource("process/jiaban02.bpmn20.xml")
            .name("加班申请流程02")
            .deploy();
    System.out.println(deployment.getId());
    System.out.println(deployment.getName());
}

@Test
public void startProcessInstance02() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban02");
    System.out.println(processInstance.getProcessDefinitionId());
    System.out.println(processInstance.getId());
}

 When the process instance is started, the MyTaskListener listening method will be called

5. Process variables

5.1, what is a process variable

Process variables play a very important role in activiti. Process operation sometimes depends on process variables. When combining business systems and activiti, process variables are indispensable. Process variables are variables that activiti sets according to management needs when managing workflow. For example: when the leave application process flows, if the number of days of leave is more than 2 days, it will be reviewed by the general manager, otherwise it will be directly reviewed by the department manager. The number of days of leave can be set as a process variable and used during process flow.

5.2, the scope of process variables

The role of a process variable can be a process instance, but it can also be a task (task) or an execution instance

5.2.1, global variables

The default scope of process variables is the process instance. When the scope of a process variable is the process instance, it can be called a global variable

The variable name in the global variable is not allowed to be repeated. If you set a variable with the same name, the value set later will overwrite the variable value set before.

5.2.2, local variables

Tasks and execution instances are only for one task and one execution instance range, and the scope is not as large as the process instance, which is called local variables.

Because the scope of Local variables does not affect each other in different tasks or different execution instances, the variable names can be the same without any influence. The local variable name can also be the same as the global variable name, it has no effect.

5.3. How to use process variables

Using process variables through UEL expressions

1. We have also used UEL expressions to set the task handler before, such as ${assignee1}, activiti obtains the value of the UEL expression, that is, the value of the process variable assignee1, and assigns the value as the person in charge of the task. 2. We You can also use UEL expressions on the connection between tasks to determine the direction of the process, such as ${day > 2 } and ${day <= 2}, day is a process variable name, and the execution result of the UEL expression is Boolean type

5.4, ​​set the global variable

5.4.1. Set variables when starting the process

Set the process variable when starting the process, and the scope of the variable is the entire process instance. Set the process variable through Map<key,value>, multiple variables can be set in the map, this key is the name of the process variable

This is the previous example code

@Test 
public void startUpProcess() { 
    Map<String, Object> variables = new HashMap<>(); 
    variables.put("assignee1", "zhangsan"); 
    variables.put("assignee2", "lisi"); 
    / /To create a process instance, we need to know the key of the process definition 
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia", variables); 
    //Output related information of the instance 
    System.out.println("process definition id:" + processInstance.getProcessDefinitionId( )); 
    System.out.println("Process instance id: " + processInstance.getId()); 
}

5.4.2. Set process variables when handling tasks

Its scope is the entire process instance . If the key of the set process variable already has the same name in the process instance, the variable set later will replace the variable set earlier.

Simulation example code:

@Test 
public void completTask() { 
    Task task = taskService.createTaskQuery() 
            .taskAssignee("zhangsan") //The person in charge to be queried.singleResult 
            ();//Return a 
Map
    <String, Object> variables = new HashMap <>(); 
    variables.put("assignee2", "zhao"); 
    //Complete the task, parameter: task id 
    taskService.complete(task.getId(), variables); 
}

5.4.3, through the current process instance settings

The global variable is set through the process instance id, and its scope is the entire process instance , which must not be completed.

Simulation example code:

@Test
public void processInstanceIdSetVariables() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("assignee2", "wang");
    runtimeService.setVariables("1c347a90-82c6-11ed-96ca-7c57581a7819", variables);
}

5.5. Set Local variables

The scope of local process variables is only available under the current task node

When a task is processed, a local process variable is set. The currently running process instance can only be used before the end of the task. The variable cannot be used in the current process instance after the task ends.

Simulation example code:

@Test 
public void completLocalTask() { 
    Task task = taskService.createTaskQuery() 
            .taskAssignee("zhangsan") //The person in charge to be queried.singleResult 
            ();//Return an item 
​//
    Set the local variable, the scope is this Task 
    taskService.setVariableLocal(task.getId(),"assignee2","li"); 
    // View local variables 
    System.out.println(taskService.getVariableLocal(task.getId(), "assignee2")); 
    //Complete Task, parameter: task id 
    taskService.complete(task.getId()); 
}

6. Task group

6.1, Candidate-users candidates

1. Requirements 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 you want to temporarily change the task leader, you need to modify the process definition. System scalability Very poor, for this situation, we can set multiple candidates for the task, and select participants from the candidates to complete the task

2. Set task candidates

 

6.2. Group task handling process

Step 1: Query Group Tasks

Designate a candidate and query the candidate's current to-do tasks Candidates cannot handle tasks Step 2: Claim tasks

All candidates for this group of tasks can be picked up. Turn the candidate's group task into a personal task, and the original candidate becomes the person in charge of the task. If you do not want to handle the task after picking it up, you need to pick it up Step 3 : Query personal tasks

The query method is the same as the personal task part, and the personal task that the user is responsible for is queried according to the assignee. Step 4: Handle personal tasks

6.3. Key code

6.3.1, deployment and start

 

@Test
public void deployProcess04() {
    // 流程部署
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("process/jiaban04.bpmn20.xml")
            .name("请假申请流程")
            .deploy();
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
​
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban04");
    System.out.println(processInstance.getId());
}

6.3.2. Query group tasks

@Test 
public void findGroupTaskList() { 
    //Query group task 
    List<Task> list = taskService.createTaskQuery() 
            .taskCandidateUser("zhangsan01")//Query based on candidate.list 
            (); 
    for (Task task : list) { 
        System.out.println("----------------------------"); 
        System.out.println("Process instance id:" + task.getProcessInstanceId()); 
        System.out.println("Task id: " + task.getId()); 
        System.out.println("Task owner: " + task.getAssignee()); 
        System.out .println("Task name: " + task.getName()); 
    } 
}

6.3.2. Pick up group tasks

@Test 
public void claimTask(){ 
    //Pick up a task, even if the user is not a candidate (it is recommended to check whether the user is eligible) 
    //Check whether the user is eligible to pick up the task 
    Task task = taskService.createTaskQuery () 
            .taskCandidateUser("zhangsan01")//Query according to the candidate.singleResult 
            (); 
    if(task!=null){ 
        //Pick up the task 
        taskService.claim(taskId, "zhangsan01"); 
        System.out.println(" Task picked up successfully"); 
    } 
}

Zhang San 01 has picked up the task, but Zhang San 02 cannot pick it up

6.3.3. Query personal to-do tasks

The query method is the same as personal task query

@Test 
public void findGroupPendingTaskList() { 
    //Task leader 
    String assignee = "zhangsan01"; 
    List<Task> list = taskService.createTaskQuery() 
            .taskAssignee(assignee)//Only query the tasks of the task leader.list 
            () ; 
    for (Task task : list) { 
        System.out.println("Process instance id: " + task.getProcessInstanceId()); 
        System.out.println("Task id: " + task.getId()); 
        System. out.println("Task owner: " + task.getAssignee()); 
        System.out.println("Task name: " + task.getName()); 
    } 
}

6.3.4. Handle personal tasks

with personal tasks

@Test 
public void completGroupTask() { 
    Task task = taskService.createTaskQuery() 
            .taskAssignee("zhangsan01") //The person in charge to be queried.singleResult 
            ();//Return a 
    taskService.complete(task.getId()); 
}

6.3.5. Return group tasks

If an individual does not want to handle the group task, he can return the group task, after which the user is no longer the person in charge of the task

@Test 
public void assigneeToGroupTask() { 
    String taskId = "d96c3f28-825e-11ed-95b4-7c57581a7819"; 
    // Task leader 
    String userId = "zhangsan01"; 
    // Check whether userId is the person in charge of taskId, if it is responsible Talents can return group tasks 
    Task task = taskService 
            .createTaskQuery() 
            .taskId(taskId) 
            .taskAssignee(userId) 
            .singleResult(); 
    if (task != null) { 
        // If set to null, return group tasks, the task does not Assignee 
        taskService.setAssignee(taskId, null); 
    } 
}

6.3.6. Task handover

Task handover, the task leader hands over the task to other candidates to handle the task

@Test 
public void assigneeToCandidateUser() { 
    // Current to-do task 
    String taskId = "d96c3f28-825e-11ed-95b4-7c57581a7819"; 
    // Check whether zhangsan01 is the person in charge of the taskId, and if so, can return the group task 
    Task task = taskService 
            .createTaskQuery() 
            .taskId(taskId) 
            .taskAssignee("zhangsan01") 
            .singleResult(); 
    if (task != null) { 
        // Give this task to other candidate zhangsan02 to handle the task 
        taskService.setAssignee( taskId, "zhangsan02"); 
    } 
}

7. Gateway

Gateways are used to control the flow of processes and are usually used together with process variables.

7.1. Exclusive Gateway

  • Exclusive gateway: only one path will be chosen

When there is such a scenario in your process: leave application, within two days, the approval process of the department manager is over, and the general manager needs to approve it directly after more than two days. At this time, an exclusive gateway is needed.

7.2. Parallel Gateway

  • Parallel (parallel) gateways: all paths will be selected at the same time

When such a scenario occurs: the leave application needs to be approved by both the department manager and the general manager. If there is no before and after the two, both people need to approve it before proceeding to the next node for personnel approval. At this time, a parallel gateway is required

 

The main difference from exclusive gateways is that parallel gateways do not resolve conditions. Even if a condition is defined in the sequence flow, it will be ignored.

7.3, including the gateway

Inclusive gateway: Multiple routes can be executed at the same time, and conditions can also be set on the gateway, which can be regarded as a combination of exclusive gateway and parallel gateway. When such a scenario occurs: the leave application must be approved by the general manager of the department for more than or equal to 2 days, and the department manager for less than 2 days, and the leave application must be approved by the HR manager. At this time, the gateway needs to be included

 

Guess you like

Origin blog.csdn.net/Relievedz/article/details/130259635