流程变量

目录

流程变量

应用说明

activity的基础用法中,bpmn各个节点的负责人assignee都是写死的,实际上可以使用流程变量进行占位,当启动流程实例时,再根据业务传递参数

节点之间的连线,有一个属性名condition,可以在这里保存一些信息,比如员工申请的请假时长,这样工作流引擎就可以根据这个属性值,判断如果请假时长大于3天则走A流程,否则就走B流程

流程变量作用域

流程变量的作用域默认是一个流程实例(processInstance),也可以是一个任务(task)或一个执行实例
(execution)。

流程实例的范围最大,可以称为 global 变量

任务和执行实例仅仅是针对一个任务和一个执行实例范围,范围没有流程实例大, 称为 local 变量

代码通用部分

这里先给出后续代码需要用到的包和我个人封装好的函数

import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

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

//创建操作activity的核心对象 ProcessEngine 所有操作都需要用它完成
public ProcessEngine createProcessEngine(){
    //创建ProcessEngineConfiguration
    ProcessEngineConfiguration configuration =ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
    //通过ProcessEngineConfiguration创建ProcessEngine,此时根据配置文件设置决定是否创建数据库的表或者更新表
    ProcessEngine processEngine =configuration.buildProcessEngine();
    System.out.println("创建完成:"+processEngine);
    return processEngine;
}

使用方式

bpmn设置UEL表达式

在bpmn文件各个节点assignee处使用UEL 表达式,比如: ${assignee}, assignee 就是一个流程变量名称

在连线处condition使用UEL 表达式,比如:${num>=3},num就是一个流程变量名,UEL表达式结果类型为布尔类型

  1. 如果 UEL 表达式中流程变量名不存在则报错。

  2. 如果 UEL 表达式中流程变量值为空 NULL,流程不按 UEL 表达式去执行,而流程结束 。

  3. 如果 UEL 表达式都不符合条件,流程结束

  4. 如果连线不设置条件,会走 flow 序号小的那条线

启动流程时设置全局流程变量

只需要创建一个map,然后key为UEL表达式中的流程变量名,value为具体值

// 启动流程时设置流程变量
@Test
public void startProcessInstance() {
    //创建ProcessEngine
    ProcessEngine processEngine =createProcessEngine();

    // 流程id
    String processDefinitionKey = "liuchen";

    // 定义流程变量
    Map<String, Object> variables = new HashMap<String, Object>();
    //变量名是num,变量值是holiday.getNum(),变量名也可以是一个对象
    variables.put("num", 3);
    variables.put("assignee", "zhangsan");
    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
    System.out.println(" 流 程 实 例 id:" + processInstance.getProcessInstanceId());
}

完成任务时设置全局\局部流程变量

在A节点调用complete函数,将流程实例推到B节点时,设置全局流程变量。

  1. 此时设置的全局流程变量,只能在B节点使用

  2. 如果设置的全局流程变量key在之前已经存在,会被覆盖

@Test
public void completTask2() {
    //创建ProcessEngine
    ProcessEngine processEngine =createProcessEngine();

    //任务id 用task.getId()拿到的数字 而不是流程实例id
    //流程实例每经过一个节点,其任务id就会发生变更
    String taskId = "25002";
    // 创建TaskService
    TaskService taskService = processEngine.getTaskService();

    // 定义流程变量
    variables.put("num", 1);
    //完成任务的同时将全局流程变量添加到流程实例中
    taskService.complete(taskId, variables);
    //如果要在这个阶段使用本地流程变量 就先使用taskService.setVariableLocal 再执行taskService.complete(taskIdS)

    //完成后,上面的任务负责人,比如发起请假申请的员工,就看不到这个任务了,因为已经推给下一个人了
    System.out.println("完成任务id="+taskId);
}

直接设置全局\局部流程变量

除了创建任务时设置全局流程变量、将流程推向下一节点时顺带设置全局、局部流程变量

还可以啥也不干,就单单设置流程变量,只需要通过任务id

任务id必须是当前待办任务id,如果该任务已结束,会报错

由于流程实例每经过一个节点,其任务id就会发生变更 所以当某个用户将流程推进后,他无法知道最新的任务id,此时也不可能再去修改变量

@Test
public void setGlobalVariableByTaskId(){
    //创建ProcessEngine
    ProcessEngine processEngine =createProcessEngine();

    //当前待办任务id
    String taskId="25002";
    TaskService taskService = processEngine.getTaskService();
    //通过任务设置全局流程变量
    taskService.setVariable(taskId, "num", 1);
    //一次设置多个全局流程变量 传入Map类型变量
    //taskService.setVariables(taskId, variables)
    
    //如果需要设置本地流程变量 使用taskService.setVariableLocal

    //也可以通过getVariable()获取流程变量
    //Object variable = taskService.getVariable(taskId,"num");
}

获取流程变量

通过taskService.getVariable(任务id,流程变量key);获取流程变量

可以在查看个人待办任务时查看,总之只要有任务id以及流程变量key就行

// 查询当前个人待执行的任务
@Test
public void findPersonalTaskList() {
    //创建ProcessEngine
    ProcessEngine processEngine =createProcessEngine();

    // 任务负责人 比如发起请假申请的员工
    String assignee = "zhangsan";
    // 创建TaskService
    TaskService taskService = processEngine.getTaskService();

    //下面的Task类是org.activiti.engine.task
    List<Task> list = taskService.createTaskQuery()//
            .processDefinitionKey("liuchen")//这里的key就是上面创建实例时的key 很好理解 其实就是查询这个请假流程
            .taskAssignee(assignee)//只查询该任务负责人的任务 上面的key都一样 所以在这里 每个人借此区分出自己的任务
            .list();
    for (Task task : list) {
        System.out.println(" 流 程 实 例 id : " +
                task.getProcessInstanceId());
        System.out.println("任务id: " + task.getId());
        System.out.println("任务负责人: " + task.getAssignee());
        System.out.println("任务名称: " + task.getName());
        
        //查看流程变量
        Object num = taskService.getVariable(task.getId(), "assignee");
        System.out.println(num.toString());
    }
}
posted @ 2022-11-08 13:58  夏·舍  阅读(52)  评论(0编辑  收藏  举报