zoukankan      html  css  js  c++  java
  • 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);
        }
    }
    
  • 相关阅读:
    LeetCode105 从前序遍历和中序遍历构造二叉树
    LeetCode61 扑克牌中的顺子
    LeetCode141 环形链表
    LeetCode103 二叉树的锯齿形层次遍历
    509 斐波那契数
    剑指29 顺时针打印矩阵
    malloc分配内存2种方式:brk和mmap
    Python学习第139天(Django的分页器(paginator))
    Python学习第138天(Django的用户认真组件)
    Python学习第137天(admin部分参数补充)
  • 原文地址:https://www.cnblogs.com/xuweiweiwoaini/p/13660407.html
Copyright © 2011-2022 走看看