Activiti7進階之個人任務和流程變量


1 個人任務

1.1 分配任務負責人

1.1.1 固定分配

  • 在進行業務流程建模的時候指定固定的任務負責人。

固定分配

  • 在properties視圖中,添加Assignee項為任務負責人。

由於固定分配方式,任務只管一步一步執行任務,執行到每一個任務將按照BPMN的配置去分配任務負責人。

1.1.2 表達式分配

1.1.2.1 UEL表達式

  • Activiti使用UEL表達式,UEL是JavaEE規范的一部分,URL(Unified Expression Language)即統一表達式語言,Activiti支持兩種UEL表達式:UEL-value和UEL-method。

  • UEL-value定義如下:

    • assignee這個變量是Activiti的一個流程變量。

    UEL-value

    • user這個變量也是Activiti的一個流程變量,user.assignee表示通過調用user的getter方法獲取值。

    另外一種UEL-value

  • UEL-method定義如下:

    • holidayBean是Spring容器中的一個Bean,下圖UEL-method的含義是調用該Bean的一個getHolidayId()方法。

UEL-method

1.1.2.2 使用流程變量分配任務

  • 定義任務分配流程變量:

UEL-value

  • 設置流程變量:在啟動流程實例的時候設置流程變量
package com.sunxiaping;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
 * @version 1.0
 * 2020-08-01 14:35
 */
public class ActivitiStartProcessInstanceTest {

    /**
     * act_hi_actinst 活動實例
     * act_hi_identitylink 參與者信息
     * act_hi_procinst 流程實例
     * act_hi_taskinst 任務實例
     * act_ru_execution 執行表
     * act_ru_identitylink 參與者信息
     * act_ru_task   任務表
     */
    @Test
    public void test() {
        //創建ProcessEngineConfiguration對象
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
        ProcessEngine processEngine = configuration.buildProcessEngine();
        //獲取RuntimeService對象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //設置流程變量
        Map<String, Object> variables = new HashMap<>();
        variables.put("assignee0", "張三");
        variables.put("assignee1", "李四");
        variables.put("assignee2", "王五");

        //根據流程定義的key啟動流程實例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday", variables);
        //獲取流程實例的相關信息
        String processDefinitionId = processInstance.getProcessDefinitionId();
        System.out.println("流程定義的id = " + processDefinitionId);
        String deploymentId = processInstance.getDeploymentId();
        System.out.println("流程部署的id = " + deploymentId);
        String id = processInstance.getId();
        System.out.println("流程實例的id = " + id);
        String activityId = processInstance.getActivityId();
        System.out.println("當前活動的id = " + activityId);

    }
}

1.1.2.3 注意事項

  • 由於使用了表達式分配,必須保證在任務執行過程中表達式執行成功,比如某個任務使用了表達式${order.price > 100 && order.price <250},當執行該任務時必須保證order在流程變量中存在,否則Activiti將拋出異常。

1.1.3 監聽器分配

  • 任務監聽器是發生對應的任務相關事件時執行自定義的Java邏輯或表達式。
  • 任務相關事件包括:
    • Event:
      • Create:任務創建后觸發。
      • Assignment:任務分配后觸發。
      • Delete:任務完成后觸發。
      • All:所有事件發生都觸發。

監聽器分配

  • 自定義一個任務監聽器類,然后此類必須實現org.activiti.engine.delegate.TaskListener接口:
package com.sunxiaping.task;

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

/**
 * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
 * @version 1.0
 * 2020-08-05 15:44
 */
public class SelfTaskListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
    	//指定任務的負責人
    	delegateTask.setAssignee("張三");
    }
}

在實際開發中,一般也不使用監聽器分配方式,太麻煩了。

2 流程變量

2.1 什么是流程變量?

  • 流程變量在Activiti中是一個非常重要的角色,流程運轉有時需要靠流程變量,業務系統和Activiti結合時少不了流程變量,流程變量就是Activiti在管理工作流時根據管理需要而設置的變量。
  • 比如在請假流程流轉時如果請假天數>3天則有總經理審批,否則由人事直接審批,請假天數就可以設置流程變量,在流程流轉時使用。

注意:雖然流程變量中可以存儲業務數據,可以通過Activiti的API查詢流程變量從而實現查詢業務數據,但是不建議這么使用,因為業務數據查詢由業務系統負責,Activiti設置流程變量是為了流程執行需要而創建的。

2.2 流程變量類型

流程變量類型.

注意:

  • 如果將POJO存儲到流程變量中,必須實現序列化接口Serializable,為了防止由於新增字段無法反序列化。

2.3 流程變量的作用域

  • 流程變量的作用域范圍可以是一個流程實例(ProcessInstance)、一個任務(Task)或一個執行實例(Execution)。

  • 流程變量的作用域范圍的默認值是流程實例,作用域范圍最大,可以稱為global變量。

  • 流程變量的作用域范圍如果僅僅針對一個任務或一個執行實例,那么作用域范圍沒有流程實例大,可以稱為local變量。

  • global變量中變量名不允許重復,設置相同名稱的變量,后設置的值會覆蓋前設置的變量值。

  • local變量由於在不同的任務或不同的執行實例中,作用域互不影響,變量名可以相同沒有影響。local變量名也可以和global變量名相同,沒有影響。

2.4 流程變量的使用方法

  • ①設置流程變量。

  • ②通過UEL表達式使用流程變量。

    • 1️⃣可以在assignee處設置UEL表達式,表達值的值就是任務的負責人。例如:${assignee},assignee就是一個流程變量的名稱。

    在assignee處設置UEL表達式

    • 2️⃣可以在連線上設置UEL表達式,決定流程的走向。例如:${holidayNum>=3}${holidayNum<3}中holidayNum就是一個流程變量名稱,UEL表達式的結果類型為boolean類型,如果UEL表達式的值是true,則總經理審批,否則直接人事存檔。

    在連線上設置UEL表達式

2.5 使用global變量控制流程

2.5.1 需求

  • 員工創建請假流程申請單,由部門經理審批,部門經理審批通過后請假3天以下的由人事經理直接審批,3天及3天以上的由總經理審批,總經理審批通過再通過人事經理存檔。

使用global變量控制流程的需求

2.5.2 畫流程定義

  • 請假大於等於3天的連線條件:

請假大於等於3天的連線條件

  • 請假小於3天的連線條件:

請假小於3天的連線條件

本人在畫BPMN文件的時候將填寫請假申請單的assignee設置為張三,部門經理審批的assignee設置為李四,總經理審批的assignee設置為王五,人事經理存檔設置為趙六。

2.5.3 設置global流程變量

2.5.3.1 准備工作

  • 導入相關jar包的Maven坐標:
<properties>
    <activiti.version>7.0.0.GA</activiti.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-engine</artifactId>
        <version>7.0.0.GA</version>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-spring</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-bpmn-model</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-bpmn-converter</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-json-converter</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-bpmn-layout</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <dependency>
        <groupId>org.activiti.cloud</groupId>
        <artifactId>activiti-cloud-services-api</artifactId>
        <version>7-201802-EA</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.19</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <!-- log start -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.13.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.13.3</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.30</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.13.3</version>
    </dependency>
    <!-- log end -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.5</version>
    </dependency>
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.activiti.cloud.dependencies</groupId>
            <artifactId>activiti-cloud-dependencies</artifactId>
            <version>7.0.0.GA</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>
  • 日志文件(log4j2.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!--日志級別以及優先級排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status用於設置log4j2自身內部的信息輸出,可以不設置,當設置成trace時,可以看到log4j2內部各種詳細輸出-->
<configuration status="INFO">
    <!--先定義所有的appender-->
    <appenders>
        <!--輸出日志信息到控制台-->
        <console name="Console" target="SYSTEM_OUT">
            <!--控制日志輸出的格式-->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </console>
    </appenders>
    <!--然后定義logger,只有定義了logger並引入的appender,appender才會生效-->
    <!--root:用於指定項目的根日志,如果沒有單獨指定Logger,則會使用root作為默認的日志輸出-->
    <loggers>
        <root level="INFO">
            <appender-ref ref="Console"/>
        </root>
    </loggers>
</configuration>
  • Activiti的核心配置文件(activiti-cfg.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--  配置數據源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="url"
                  value="jdbc:mysql://192.168.1.146:3306/activiti?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true"/>
        <property name="password" value="123456"/>
        <property name="maxActive" value="3"/>
        <property name="maxIdle" value="1"/>
    </bean>

    <!-- Activiti單獨運行的ProcessEngine配置 -->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <!-- 數據源 -->
        <property name="dataSource" ref="dataSource"/>
        <!--
            activiti數據庫表處理策略
                false(默認值):檢查數據庫的版本和依賴庫的版本,如果不匹配就拋出異常
                true:構建流程引擎時,執行檢查,如果需要就執行更新。如果表不存在,就創建。
                create-drop:構建流程引擎時創建數據庫報表,關閉流程引擎時就刪除這些表。
                drop-create:先刪除表再創建表。
                create:構建流程引擎時創建數據庫表,關閉流程引擎時不刪除這些表
        -->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>
  • 請假實體類(Holiday.java)
package com.sunxiaping.task;

import java.io.Serializable;
import java.util.Date;

/**
 * 請假實體類
 *
 * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
 * @version 1.0
 * 2020-08-06 14:30
 */
public class Holiday implements Serializable {

    /**
     * 主鍵
     */
    private Integer id;

    /**
     * 申請人名字
     */
    private String holidayName;

    /**
     * 開始時間
     */
    private Date beginDate;

    /**
     * 結束時間
     */
    private Date endDate;

    /**
     * 請假天數
     */
    private Float num;

    /**
     * 請假事由
     */
    private String reason;

    /**
     * 請假類型:病假、婚假、喪假等
     */
    private String type;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getHolidayName() {
        return holidayName;
    }

    public void setHolidayName(String holidayName) {
        this.holidayName = holidayName;
    }

    public Date getBeginDate() {
        return beginDate;
    }

    public void setBeginDate(Date beginDate) {
        this.beginDate = beginDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public Float getNum() {
        return num;
    }

    public void setNum(Float num) {
        this.num = num;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}
  • 將流程定義和對應的圖片放入到resources目錄下:

在classpath下放入流程定義文件和圖片

2.5.3.2 啟動流程時設置

  • 示例:
package com.sunxiaping.test;

import com.sunxiaping.task.Holiday;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * global流程變量測試:啟動流程時設置
 *
 * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
 * @version 1.0
 * 2020-08-06 14:28
 */
public class ActivitiGlobalVariableStartProcessInstanceTest {
    ProcessEngine processEngine = null;

    @Before
    public void before() {
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
        processEngine = configuration.buildProcessEngine();
    }

    @After
    public void after() {
        if (processEngine != null) {
            processEngine.close();
        }
    }

    /**
     * 流程定義部署
     */
    @Test
    public void testDeployment() {
        //獲取RepositoryService對象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //獲取Deployment對象
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("diagram/holiday.bpmn")
                .addClasspathResource("diagram/holiday.png")
                .name("請假申請流程")
                .deploy();
        String id = deployment.getId();
        System.out.println("流程部署的id = " + id);
        String name = deployment.getName();
        System.out.println("流程部署的名稱 = " + name);
        String key = deployment.getKey();
        System.out.println("流程部署的key = " + key);
    }

    /**
     * 啟動流程的時候給流程變量賦值
     */
    @Test
    public void testStartProcessInstance() {
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取RuntimeService對象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //封裝global流程變量
        Holiday holiday = new Holiday();
        holiday.setNum(3f);
        holiday.setHolidayName("如花");
        holiday.setId(1);
        holiday.setType("年假");
        holiday.setReason("想男友了");
        holiday.setBeginDate(new Date());
        LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
        Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
        holiday.setEndDate(endDate);

        Map<String, Object> variables = new HashMap<>();
        variables.put("holiday", holiday);

        //根據流程定義的key啟動流程實例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);

        String id = processInstance.getId();
        System.out.println("流程實例的id = " + id);

        String name = processInstance.getName();
        System.out.println("流程實例的名稱 = " + name);

        String processDefinitionId = processInstance.getProcessDefinitionId();
        System.out.println("流程定義的id = " + processDefinitionId);
    }

    /**
     * 測試張三完成任務
     */
    @Test
    public void testZhangSanTask() {
        String assignee = "張三";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取張三任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("張三任務的id = " + id);
            taskService.complete(id);
        }
    }

    /**
     * 測試李四完成任務
     */
    @Test
    public void testLiSiTask() {
        String assignee = "李四";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取李四任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("李四任務的id = " + id);
            taskService.complete(id);
        }
    }

    /**
     * 測試王五和趙六的任務,查看到底是王五還是趙六有任務
     */
    @Test
    public void testWangWuTask() {
        String assignee = "王五";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取王五任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("王五任務的id = " + id);
        }

        assignee = "趙六";
        taskService = processEngine.getTaskService();
        //獲取趙六任務的列表
        taskList = taskService.createTaskQuery().taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("趙六任務的id = " + id);
        }
    }
}

2.5.3.3 完成任務時設置

  • 示例:
package com.sunxiaping.test;

import com.sunxiaping.task.Holiday;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * global流程變量測試:完成任務時設置
 *
 * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
 * @version 1.0
 * 2020-08-06 14:28
 */
public class ActivitiGlobalVariableCompleteTaskTest {
    ProcessEngine processEngine = null;

    @Before
    public void before() {
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
        processEngine = configuration.buildProcessEngine();
    }

    @After
    public void after() {
        if (processEngine != null) {
            processEngine.close();
        }
    }

    /**
     * 流程定義部署
     */
    @Test
    public void testDeployment() {
        //獲取RepositoryService對象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //獲取Deployment對象
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("diagram/holiday.bpmn")
                .addClasspathResource("diagram/holiday.png")
                .name("請假申請流程")
                .deploy();
        String id = deployment.getId();
        System.out.println("流程部署的id = " + id);
        String name = deployment.getName();
        System.out.println("流程部署的名稱 = " + name);
        String key = deployment.getKey();
        System.out.println("流程部署的key = " + key);
    }

    /**
     * 啟動流程
     */
    @Test
    public void testStartProcessInstance() {
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取RuntimeService對象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //根據流程定義的key啟動流程實例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);

        String id = processInstance.getId();
        System.out.println("流程實例的id = " + id);

        String name = processInstance.getName();
        System.out.println("流程實例的名稱 = " + name);

        String processDefinitionId = processInstance.getProcessDefinitionId();
        System.out.println("流程定義的id = " + processDefinitionId);
    }

    /**
     * 測試張三完成任務,張三完成任務的時候給global變量賦值
     */
    @Test
    public void testZhangSanTask() {
        String assignee = "張三";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取張三任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("張三任務的id = " + id);

            //封裝global流程變量
            Holiday holiday = new Holiday();
            holiday.setNum(3f);
            holiday.setHolidayName("如花");
            holiday.setId(1);
            holiday.setType("年假");
            holiday.setReason("想男友了");
            holiday.setBeginDate(new Date());
            LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
            Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
            holiday.setEndDate(endDate);

            Map<String, Object> variables = new HashMap<>();
            variables.put("holiday", holiday);

            taskService.complete(id, variables);
        }
    }

    /**
     * 測試李四完成任務
     */
    @Test
    public void testLiSiTask() {
        String assignee = "李四";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取李四任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("李四任務的id = " + id);
            taskService.complete(id);
        }
    }

    /**
     * 測試王五和趙六的任務,查看到底是王五還是趙六有任務
     */
    @Test
    public void testWangWuTask() {
        String assignee = "王五";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取王五任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("王五任務的id = " + id);
        }

        assignee = "趙六";
        taskService = processEngine.getTaskService();
        //獲取趙六任務的列表
        taskList = taskService.createTaskQuery().taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("趙六任務的id = " + id);
        }
    }
}

2.5.3.4 通過當前流程實例設置

  • 通過流程實例的id設置全局流程變量,該流程實例必須沒有執行完畢。

  • 示例:

package com.sunxiaping.test;

import com.sunxiaping.task.Holiday;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * global流程變量測試:通過當前流程實例設置
 *
 * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
 * @version 1.0
 * 2020-08-06 14:28
 */
public class ActivitiGlobalVariableCurrentExecutionIdTest {
    ProcessEngine processEngine = null;

    @Before
    public void before() {
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
        processEngine = configuration.buildProcessEngine();
    }

    @After
    public void after() {
        if (processEngine != null) {
            processEngine.close();
        }
    }

    /**
     * 流程定義部署
     */
    @Test
    public void testDeployment() {
        //獲取RepositoryService對象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //獲取Deployment對象
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("diagram/holiday.bpmn")
                .addClasspathResource("diagram/holiday.png")
                .name("請假申請流程")
                .deploy();
        String id = deployment.getId();
        System.out.println("流程部署的id = " + id);
        String name = deployment.getName();
        System.out.println("流程部署的名稱 = " + name);
        String key = deployment.getKey();
        System.out.println("流程部署的key = " + key);
    }

    /**
     * 啟動流程
     */
    @Test
    public void testStartProcessInstance() {
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取RuntimeService對象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //根據流程定義的key啟動流程實例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);

        String id = processInstance.getId();
        System.out.println("流程實例的id = " + id);

        String name = processInstance.getName();
        System.out.println("流程實例的名稱 = " + name);

        String processDefinitionId = processInstance.getProcessDefinitionId();
        System.out.println("流程定義的id = " + processDefinitionId);
    }


    /**
     * 通過流程實例的id設置流程變量,該流程必須沒有執行完畢
     */
    @Test
    public void testSetVariable(){
        String executionId = "2501";

        //封裝global流程變量
        Holiday holiday = new Holiday();
        holiday.setNum(3f);
        holiday.setHolidayName("如花");
        holiday.setId(1);
        holiday.setType("年假");
        holiday.setReason("想男友了");
        holiday.setBeginDate(new Date());
        LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
        Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
        holiday.setEndDate(endDate);

        Map<String, Object> variables = new HashMap<>();
        variables.put("holiday", holiday);

        //獲取RuntimeService對象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //設置流程變量
        runtimeService.setVariables(executionId,variables);
    }



    /**
     * 測試張三完成任務
     */
    @Test
    public void testZhangSanTask() {
        String assignee = "張三";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取張三任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("張三任務的id = " + id);

            taskService.complete(id);
        }
    }

    /**
     * 測試李四完成任務
     */
    @Test
    public void testLiSiTask() {
        String assignee = "李四";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取李四任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("李四任務的id = " + id);
            taskService.complete(id);
        }
    }

    /**
     * 測試王五和趙六的任務,查看到底是王五還是趙六有任務
     */
    @Test
    public void testWangWuTask() {
        String assignee = "王五";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取王五任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("王五任務的id = " + id);
        }

        assignee = "趙六";
        taskService = processEngine.getTaskService();
        //獲取趙六任務的列表
        taskList = taskService.createTaskQuery().taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("趙六任務的id = " + id);
        }
    }
}

2.5.3.5 通過當前任務設置

  • 該任務必須待辦任務,act_ru_task表中存在。如果該任務已經結束,就會報錯。

  • 示例:

package com.sunxiaping.test;

import com.sunxiaping.task.Holiday;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * global流程變量測試:通過當前流程實例設置
 *
 * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
 * @version 1.0
 * 2020-08-06 14:28
 */
public class ActivitiGlobalVariableCurrentTaskIdTest {
    ProcessEngine processEngine = null;

    @Before
    public void before() {
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
        processEngine = configuration.buildProcessEngine();
    }

    @After
    public void after() {
        if (processEngine != null) {
            processEngine.close();
        }
    }


    /**
     * 流程定義部署
     */
    @Test
    public void testDeployment() {
        //獲取RepositoryService對象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //獲取Deployment對象
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("diagram/holiday.bpmn")
                .addClasspathResource("diagram/holiday.png")
                .name("請假申請流程")
                .deploy();
        String id = deployment.getId();
        System.out.println("流程部署的id = " + id);
        String name = deployment.getName();
        System.out.println("流程部署的名稱 = " + name);
        String key = deployment.getKey();
        System.out.println("流程部署的key = " + key);
    }

    /**
     * 啟動流程
     */
    @Test
    public void testStartProcessInstance() {
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取RuntimeService對象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //根據流程定義的key啟動流程實例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);

        String id = processInstance.getId();
        System.out.println("流程實例的id = " + id);

        String name = processInstance.getName();
        System.out.println("流程實例的名稱 = " + name);

        String processDefinitionId = processInstance.getProcessDefinitionId();
        System.out.println("流程定義的id = " + processDefinitionId);
    }
    

    /**
     * 測試張三完成任務
     */
    @Test
    public void testZhangSanTask() {
        String assignee = "張三";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取張三任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();

            //封裝global流程變量
            Holiday holiday = new Holiday();
            holiday.setNum(3f);
            holiday.setHolidayName("如花");
            holiday.setId(1);
            holiday.setType("年假");
            holiday.setReason("想男友了");
            holiday.setBeginDate(new Date());
            LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
            Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
            holiday.setEndDate(endDate);

            Map<String, Object> variables = new HashMap<>();
            variables.put("holiday", holiday);


            taskService.setVariables(id,variables);

            System.out.println("張三任務的id = " + id);

            taskService.complete(id);
        }
    }

    /**
     * 測試李四完成任務
     */
    @Test
    public void testLiSiTask() {
        String assignee = "李四";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取李四任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("李四任務的id = " + id);
            taskService.complete(id);
        }
    }

    /**
     * 測試王五和趙六的任務,查看到底是王五還是趙六有任務
     */
    @Test
    public void testWangWuTask() {
        String assignee = "王五";
        //流程定義的key
        String processDefinitionKey = "holiday";
        //獲取TaskService對象
        TaskService taskService = processEngine.getTaskService();
        //獲取王五任務的列表
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("王五任務的id = " + id);
        }

        assignee = "趙六";
        taskService = processEngine.getTaskService();
        //獲取趙六任務的列表
        taskList = taskService.createTaskQuery().taskAssignee(assignee).list();

        for (Task task : taskList) {
            //任務的id
            String id = task.getId();
            System.out.println("趙六任務的id = " + id);
        }
    }

}

2.5.4 注意事項

  • 如果UEL表達式中流程變量名不存在則報錯。
  • 如果UEL表達式中流程變量值為null,流程不按UEL表達式去執行,而流程結束。
  • 如果UEL表達式都不符合條件,流程結束。
  • 如果連接不設置條件,會走flow序號小的那條線。

2.5.5 操作的數據庫表

  • 設置流程變量會在當前執行流程變量表(act_ru_variable)插入記錄,同時也會在歷史流程變量表(act_hi_varinst)中也插入記錄。

2.6 設置Local流程變量(實際開發中一般不用)

2.6.1 完成任務前設置

  • 在任務完成前設置Local流程變量,當前運行的Local流程變量只能在該任務結束前使用,任務結束該變量無法在當前流程實例使用,可以通過查詢歷史任務查詢。

  • 示例:

/**
     * 測試張三完成任務
     */
@Test
public void testZhangSanTask() {
    String assignee = "張三";
    //流程定義的key
    String processDefinitionKey = "holiday";
    //獲取TaskService對象
    TaskService taskService = processEngine.getTaskService();
    //獲取張三任務的列表
    List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

    for (Task task : taskList) {
        //任務的id
        String id = task.getId();
        System.out.println("張三任務的id = " + id);

        //封裝global流程變量
        Holiday holiday = new Holiday();
        holiday.setNum(3f);
        holiday.setHolidayName("如花");
        holiday.setId(1);
        holiday.setType("年假");
        holiday.setReason("想男友了");
        holiday.setBeginDate(new Date());
        LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
        Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
        holiday.setEndDate(endDate);

        Map<String, Object> variables = new HashMap<>();
        variables.put("holiday", holiday);

        taskService.setVariablesLocal(id,variables);

        taskService.complete(id);
    }
}

2.6.2 通過當前任務設置

  • 示例:
/**
     * 測試張三完成任務
     */
@Test
public void testZhangSanTask() {
    String assignee = "張三";
    //流程定義的key
    String processDefinitionKey = "holiday";
    //獲取TaskService對象
    TaskService taskService = processEngine.getTaskService();
    //獲取張三任務的列表
    List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();

    for (Task task : taskList) {
        //任務的id
        String id = task.getId();

        //封裝global流程變量
        Holiday holiday = new Holiday();
        holiday.setNum(3f);
        holiday.setHolidayName("如花");
        holiday.setId(1);
        holiday.setType("年假");
        holiday.setReason("想男友了");
        holiday.setBeginDate(new Date());
        LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
        Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
        holiday.setEndDate(endDate);

        Map<String, Object> variables = new HashMap<>();
        variables.put("holiday", holiday);


        taskService.setVariables(id,variables);

        System.out.println("張三任務的id = " + id);

        taskService.complete(id);
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM