• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Y-wee
博客园    首页    新随笔    联系   管理     

Activit 流程变量

Activit 流程变量

流程变量在 activiti 中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和 activiti 结合时少不了流程变量

流程变量就是 activiti 在管理工作流时根据管理需要而设置的变量,比如:在出差申请流程流转时如果出差天数大于 3 天则由总经理审核,否则由人事直接审核, 出差天数就可以设置为流程变量,在流程流转时使用

动态分配任务负责人时,负责人变量就是流程变量

虽然流程变量中可以存储业务数据可以通过 activiti 的 api 查询流程变量从而实现查询业务数据,但是不建议这样使用,因为业务数据查询由业务系统负责,activiti设置流程变量是为了流程执行需要而创建

流程变量作用域

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

流程实例是 global 变量,变量名不允许重复,设置相同名称的变量,后设置的值会覆盖前设置的变量值

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

local 变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同没有影响;Local 变量名也可以和 global 变量名相同,没有影响

流程变量的使用

  • 在用户任务属性上使用,比如:通过 uel 表达式设置用户任务 Assignee 为 $

  • 在连线属性上使用,比如:通过 uel 表达式设置连线的 Condition 为 $

代码实战

需求:员工创建出差申请单,由部门经理审核,部门经理审核通过后出差3天以下由人财务直接审批,3天及以上先由总经理审核,总经理审核通过再由财务审批

创建流程定义 evection-variable.bpmn20.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="evection-variable" name="evection-variable" isExecutable="true">
    <startEvent id="sid-e9b611c5-f349-47c0-8e64-fce81ebcaef9" name="出差申请流程开始"/>
    <userTask id="sid-a0892ee6-958b-4587-88f5-22ae84518d08" name="经理审批" activiti:assignee="${assignee1}"/>
    <userTask id="sid-a0568e26-9f86-4bca-8884-34c9bf719478" name="申请出差" activiti:assignee="${assignee0}"/>
    <userTask id="sid-ffbf825b-a0ec-4e99-b845-f056c40a5d3c" name="总经理审批" activiti:assignee="${assignee2}"/>
    <endEvent id="sid-689662c6-57b7-4aeb-b45e-ab7e7b489bca" name="出差申请流程结束"/>
    <sequenceFlow id="sid-02bcbc4c-4564-4e81-8cc2-75ababbdb550" sourceRef="sid-e9b611c5-f349-47c0-8e64-fce81ebcaef9" targetRef="sid-a0568e26-9f86-4bca-8884-34c9bf719478"/>
    <sequenceFlow id="sid-a86c082f-5c19-4856-9546-153c26e28f8f" sourceRef="sid-a0568e26-9f86-4bca-8884-34c9bf719478" targetRef="sid-a0892ee6-958b-4587-88f5-22ae84518d08"/>
    <sequenceFlow id="sid-a31d3331-c574-4449-a7e7-8f1d121dcdf5" sourceRef="sid-a0892ee6-958b-4587-88f5-22ae84518d08" targetRef="sid-ffbf825b-a0ec-4e99-b845-f056c40a5d3c">
      <conditionExpression>${evection.day&gt;=3}</conditionExpression>
    </sequenceFlow>
    <userTask id="sid-72e4fc1a-580f-4431-a099-8719b0914864" name="财务审批" activiti:assignee="${assignee3}"/>
    <sequenceFlow id="sid-f98b37b3-9a6b-4792-b026-524610b5310c" sourceRef="sid-a0892ee6-958b-4587-88f5-22ae84518d08" targetRef="sid-72e4fc1a-580f-4431-a099-8719b0914864">
      <conditionExpression>${evection.day&lt;3}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-c3382648-152a-4f21-99af-fc37b2f8e102" sourceRef="sid-ffbf825b-a0ec-4e99-b845-f056c40a5d3c" targetRef="sid-72e4fc1a-580f-4431-a099-8719b0914864"/>
    <sequenceFlow id="sid-fe7c0db2-d94a-46b7-b28d-97fbb0ae1053" sourceRef="sid-72e4fc1a-580f-4431-a099-8719b0914864" targetRef="sid-689662c6-57b7-4aeb-b45e-ab7e7b489bca"/>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_evection-variable">
    <bpmndi:BPMNPlane bpmnElement="evection-variable" id="BPMNPlane_evection-variable">
      <bpmndi:BPMNShape id="shape-c3d1bdc6-6931-49e1-a012-cf95de2f2af7" bpmnElement="sid-e9b611c5-f349-47c0-8e64-fce81ebcaef9">
        <omgdc:Bounds x="-440.0" y="-130.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-bb326f08-b3d5-4837-bfe4-a26ec9955201" bpmnElement="sid-a0892ee6-958b-4587-88f5-22ae84518d08">
        <omgdc:Bounds x="-124.17816" y="-155.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-91190fa9-bd05-4c5f-b03b-bd660239c3cc" bpmnElement="sid-a0568e26-9f86-4bca-8884-34c9bf719478">
        <omgdc:Bounds x="-317.0736" y="-155.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-5a72cb0f-352b-406b-8997-5895455020af" bpmnElement="sid-ffbf825b-a0ec-4e99-b845-f056c40a5d3c">
        <omgdc:Bounds x="65.0" y="-155.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-d83dbd93-b2b7-4ec0-b048-5db66e26cad1" bpmnElement="sid-689662c6-57b7-4aeb-b45e-ab7e7b489bca">
        <omgdc:Bounds x="-271.4048" y="51.5216" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-694c7c56-6880-4653-8249-4aa295561768" bpmnElement="sid-02bcbc4c-4564-4e81-8cc2-75ababbdb550">
        <omgdi:waypoint x="-410.0" y="-115.0"/>
        <omgdi:waypoint x="-317.0736" y="-115.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-6bdd6ad6-c3a1-47a2-bd03-0b3be222df79" bpmnElement="sid-a86c082f-5c19-4856-9546-153c26e28f8f">
        <omgdi:waypoint x="-217.07361" y="-115.0"/>
        <omgdi:waypoint x="-124.17816" y="-115.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-fc682d53-58b9-48c9-9906-16b97635abaf" bpmnElement="sid-a31d3331-c574-4449-a7e7-8f1d121dcdf5">
        <omgdi:waypoint x="-24.178162" y="-115.0"/>
        <omgdi:waypoint x="65.0" y="-115.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="shape-04890e4b-a95c-4bf9-bfed-0019bb53056d" bpmnElement="sid-72e4fc1a-580f-4431-a099-8719b0914864">
        <omgdc:Bounds x="-125.0" y="20.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-9e053774-fa8f-4802-b1a1-6f6d79107bc6" bpmnElement="sid-f98b37b3-9a6b-4792-b026-524610b5310c">
        <omgdi:waypoint x="-74.17816" y="-75.0"/>
        <omgdi:waypoint x="-75.0" y="20.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-9e7a651c-d874-4658-8988-5cc4a786d6f4" bpmnElement="sid-c3382648-152a-4f21-99af-fc37b2f8e102">
        <omgdi:waypoint x="115.0" y="-75.00001"/>
        <omgdi:waypoint x="115.0" y="60.0"/>
        <omgdi:waypoint x="-25.000002" y="60.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-42dca40d-66c1-469e-b2f4-953b5dd41872" bpmnElement="sid-fe7c0db2-d94a-46b7-b28d-97fbb0ae1053">
        <omgdi:waypoint x="-125.0" y="60.0"/>
        <omgdi:waypoint x="-241.40479" y="59.0216"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

设置连线属性 Condition|Condition expression 为 ${evection.day>=3} 控制出差3天及以上由总经理审批后再由财务审批

设置连线属性 Condition|Condition expression 为 ${evection.day<3} 控制出差3天以下由财务直接审批

流程图如下

创建实体类

package com.yl.entity;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

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

/**
 * 出差申请
 *
 * @author Y-wee
 */
@Getter
@Setter
@ToString
public class Evection implements Serializable {
    /**
     * 主键id
     */
    private Long id;
    /**
     * 出差申请单名称
     */
    private String evectionName;
    /**
     * 出差天数
     */
    private Double day;
    /**
     * 预计开始时间
     */
    private Date beginDate;
    /**
     * 预计结束时间
     */
    private Date endDate;
    /**
     * 目的地
     */
    private String destination;
    /**
     * 出差事由
     */
    private String reson;
}

如果将实体存储到流程变量中,必须实现序列化接口 serializable,为了防止由于新增字段无法反序列化,需要生成 serialVersionUID

将流程定义部署后,在启动流程时设置流程变量

/**
     * 启动流程实例,设置流程变量的值
     */
    @Test
    public void startProcess(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        String key = "evection-variable";
        // 存储流程变量,key的值要和流程变量保持一致
        Map<String, Object> map = new HashMap<>(1);

        Evection evection = new Evection();
        evection.setDay(2d);
        map.put("evection",evection);
        // 任务负责人
        map.put("assignee0","张三");
        map.put("assignee1","李经理");
        map.put("assignee2","王总经理");
        map.put("assignee3","赵财务");

        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey(key, map);
        System.out.println("流程实例名称="+processInstance.getName());
        System.out.println("流程定义id=="+processInstance.getProcessDefinitionId());
    }

完成任务

/**
  * 处理用户任务
  */
@Test
public void complete(){
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    Task task = taskService.createTaskQuery()
        .processDefinitionKey("evection-variable")
        .taskAssignee("李经理")
        .singleResult();
    if (!ObjectUtils.isEmpty(task)){
        // 完成任务
        taskService.complete(task.getId());
    }
}

任务依次完成,当经理审批任务完成后 act_ru_task 表显示当前运行任务为财务审批;修改出差日期为大于3天,当经理审批任务完成后 act_ru_task 表显示当前运行任务为总经理审批

流程变量的设置方式

流程变量也可以在完成任务时设置

 // 完成任务时设置流程变量
 taskService.complete(task.getId(),map);

流程变量还可以通过流程实例设置

 @Test
public void setGlobalVariableByExecutionId(){
    // 当前流程实例执行id
    String executionId="2601";

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RuntimeService runtimeService = processEngine.getRuntimeService();

    Evection evection = new Evection();
    evection.setNum(3d);
    // 通过流程实例设置流程变量(参数二:流程变量名,参数三:流程变量值),该方式只能设置单个流程变量值
    runtimeService.setVariable(executionId, "evection", evection);
    //  一次设置多个值
    //      runtimeService.setVariables(executionId, map)
}

通过流程实例id设置全局变量,该流程实例必须未执行完成,可以通 runtimeService.getVariable() 获取流程变量

流程变量还可以通过流程任务设置

@Test
public void setGlobalVariableByTaskId(){
    // 当前待办任务id
    String taskId="1404";

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    
    Evection evection = new Evection();
    evection.setNum(3);
    // 通过任务设置流程变量(参数二:流程变量名,参数三:流程变量值),该方式只能设置单个流程变量值
    taskService.setVariable(taskId, "evection", evection);
    // 一次设置多个值 
    //taskService.setVariables(taskId, map)
}

任务 id 必须是当前待办任务 id,act_ru_task 中存在,如果该任务已结束,会报错;可以通过 taskService.getVariable() 获取流程变量

注意事项

  • 如果 UEL 表达式中流程变量名不存在则报错
  • 如果 UEL 表达式中流程变量值为空(NULL),流程不按 UEL 表达式去执行,而流程结束
  • 如果 UEL 表达式都不符合条件,流程结束
  • 如果连线不设置条件,会走 flow 序号小的那条线

设置 Local 类型流程变量

处理任务时设置

/**
  * 处理任务时设置local流程变量
  */
@Test
public void completTask() {
   String taskId = "1404";

   ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
   TaskService taskService = processEngine.getTaskService();
   // 存储流程变量
   Map<String, Object> variables = new HashMap<String, Object>();
    
   Evection evection = new Evection ();
   evection.setNum(3d);
   variables.put("evection", evection);
   // 设置local变量(作用域为该任务)
   taskService.setVariablesLocal(taskId, variables);

   taskService.complete(taskId);
}

任务办理时设置 local 流程变量,当前运行的流程实例只能在该任务结束前使用,任务结束该变量无法在当前流程实例使用,可以通过查询历史任务查询

设置作用域为任务的 local 变量,每个任务可以设置同名的变量,互不影响

通过当前任务设置

@Test
public void setLocalVariableByTaskId(){

    String taskId="1404";

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    
    Evection evection = new Evection ();
    evection.setNum(3d);
	//  通过任务设置流程变量(参数二:流程变量名,参数三:流程变量值),该方式只能设置单个流程变量值
    taskService.setVariableLocal(taskId, "evection", evection);
	//  一次设置多个值 
    //taskService.setVariablesLocal(taskId, map)
}
记得快乐
posted @ 2022-07-24 18:19  Y-wee  阅读(448)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3