Activiti7的进阶使用

Activiti7的基础使用


1. 一些操作

1.1 查询流程定义

processDefinitionKey(Key)

    /**
     * 查询流程定义
     */
    @Test
    public void queryProcessDefinition() {
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //获取 ProcessDefinitionQuery 对象
        ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
        //查询当前所有的流程定义(根据 Key 来查询),返回流程定义信息的集合
        List<ProcessDefinition> definitionList = definitionQuery.processDefinitionKey("Test2").orderByProcessDefinitionVersion()          //根据表 act_re_procdef 的 VERSION 字段进行排序
                .desc()                                     //倒序
                .list();
        //输出信息
        for (ProcessDefinition processDefinition : definitionList) {
            System.out.println("流程定义ID=" + processDefinition.getId());
            System.out.println("流程定义名称=" + processDefinition.getName());
            System.out.println("流程定义Key=" + processDefinition.getKey());
            System.out.println("流程定义版本=" + processDefinition.getVersion());
            System.out.println("流程部署ID=" + processDefinition.getDeploymentId());
        }
    }

/*
流程定义ID=Test2:1:2506
流程定义名称=Test2
流程定义Key=Test2
流程定义版本=1
流程部署ID=2501
*/

1.2 删除流程部署信息

deleteDeployment(deploymentId)

    /**
     * 删除流程部署信息
     */
    @Test
    public void deleteDeployMent() {
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //通过部署id来删除流程部署信息,表 act_re_procdef
        String deploymentId = "1";
        //不加第二个参数默认false,说明此流程如果有实例则不删除。如果为true,则无视已经创建出来的实例直接删除。
        repositoryService.deleteDeployment(deploymentId, true);
    }

1.3 下载资源文件

getResourceAsStream(deploymentId,Name)

    /**
     * 下载资源文件
     *
     * @方案1:使用Activiti提供的api来下载资源文件
     * @方案2:自己写代码从数据库中下载文件,使用jdbc对blob类型,clob类型读取出来,保存到文件目录解决io操作解决io操作commons-io.jar
     * @一般使用方案1
     */
    @Test
    public void getDeployment() throws IOException {
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取api,RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //获取查询对象 ProcessDefinitionQuery,查询流程定义信息
        ProcessDefinition test2 = repositoryService.createProcessDefinitionQuery().processDefinitionKey("Test2")               //流程定义的Key,来自表 act_re_procdef
                .singleResult();                                //返回单一结果

        String deploymentId = test2.getDeploymentId();          //通过流程定义信息,获取部署ID
        String pngName = test2.getDiagramResourceName();        //获取png图片名称
        String bpmnName = test2.getResourceName();              //获取bpmn名称

        //通过 RepositoryService ,传递部署ID参数,读取资源信息(png 和 bpmn)
        InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, pngName);
        InputStream bpmnNameInput = repositoryService.getResourceAsStream(deploymentId, bpmnName);

        //将资源文件写到文件目录
        FileOutputStream pngFileStream = null;
        FileOutputStream bpmnFileStream = null;

        try {
            pngFileStream = new FileOutputStream("D:\\Test\\java\\Test1\\activiti7\\src\\main\\resources\\临时\\Test2.png");
            bpmnFileStream = new FileOutputStream("D:\\Test\\java\\Test1\\activiti7\\src\\main\\resources\\临时\\Test2.bpmn20.xml");
        } finally {
            IOUtils.copy(pngInput, pngFileStream);
            IOUtils.copy(bpmnNameInput, bpmnFileStream);
        }
    }

1.4 查询历史信息

getHistoryService() 获取历史服务
createHistoricActivityInstanceQuery() 创建历史活动实例查询
processInstanceId() 需要查询的实例id
processDefinitionId() 需要查询的流程模板id

/**
     * 查询历史信息
     */
    @Test
    public void findHistoryInfo() {
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取 HistoryService
        HistoryService historyService = processEngine.getHistoryService();
        //获取表 act_hi_actinst 查询对象
        HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();

        //两种查询字段,二选一也可都选
        //查询表 act_hi_actinst,参数为 PROC_INST_ID 字段
        instanceQuery.processInstanceId("5001");
        //查询表 act_hi_actinst,参数为 PROC_DEF_ID_ 字段
//        instanceQuery.processDefinitionId("Test2:1:2506");

        //添加排序 根据StartTime的升序来排(可以选择根据其他字段来排序)
        instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
        //查询所有内容
        List<HistoricActivityInstance> historyList = instanceQuery.list();
        //输出
        for (HistoricActivityInstance historicInfo : historyList) {
            System.out.println("ID=" + historicInfo.getActivityId());
            System.out.println("Name=" + historicInfo.getActivityName());
            System.out.println("DefinitionId=" + historicInfo.getProcessDefinitionId());
            System.out.println("InstanceId=" + historicInfo.getProcessInstanceId());
            System.out.println("***********************************************");
        }
    }
/*
ID=sid-0b703557-b739-4789-a805-0b60f5a5b0cf
Name=这个是Test2启动节点
DefinitionId=Test2:1:2506
InstanceId=5001
***********************************************
ID=sid-099df3f1-57a9-4c0b-9bfa-8bc2f06e62dc
Name=这个是Test2的第一个节点
DefinitionId=Test2:1:2506
InstanceId=5001
***********************************************
ID=sid-59e49190-9d28-4d25-8791-ad8af332645b
Name=这个是Test2的第二个节点
DefinitionId=Test2:1:2506
InstanceId=5001
***********************************************
*/

1.5 挂起与激活

ps:
获取流程模板的操作是 getRepositoryService() 获取存储库服务
获取流程实例的操作是 getRuntimeService() 获取运行时服务

1.5.1 全部流程实例的 挂起 和 激活

getRepositoryService 获取存储库服务
createProcessDefinitionQuery() 创建流程定义查询
isSuspended() 获取当前流程定义的实例是否都是挂起状态
activateProcessDefinitionById() 按 ID 激活流程定义。参数1: 流程定义id 参数2:是否激活 参数3:激活时间
suspendProcessDefinitionById() 按 ID 挂起进程定义。 参数1:流程定义id 参数2:是否暂停 参数3:暂停时间

    /**
     * 全部流程实例的 挂起 和 激活
     * suspend 暂停
     */
    @Test
    public void suspendAllProcessInstance() {
        //1.获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.查询流程定义,获取流程定义查询对象
        ProcessDefinition evenction = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("evenction")      //流程模板的Key值
                .singleResult();
        //4.获取当前流程定义的实例是否都是挂起状态
        boolean suspended = evenction.isSuspended();
        //5.获取流程定义id
        String id = evenction.getId();
        //6.如果是挂起则激活 影响表 act_ru_task,act_re_procdef,act_ru_execution 的 SUSPENSION_STATE 字段 -> 1-激活  2-挂起
        // (参数1:流程定义id  参数2:是否激活  参数3:激活时间)
        if (suspended) {
            repositoryService.activateProcessDefinitionById(id, true, null);
            System.out.println("流程定义id:" + id + ",已激活");
        } else {
            //7.如果是激活则挂起    (参数1:流程定义id  参数2:是否暂停  参数3:暂停时间)
            repositoryService.suspendProcessDefinitionById(id, true, null);
            System.out.println("流程定义id:" + id + ",已暂停");
        }
    }

如果挂起成功,act_re_procdef表的SUSPENSION_STATE_ 字段就会为2.现在为1说明是激活状态
suspension字段

1.5.2 单个流程实例的 挂起 和 激活

getRuntimeService() 获取运行时服务
createProcessDefinitionQuery() 创建流程定义查询
isSuspended() 获取当前流程实例是否都是挂起状态
activateProcessInstanceById() 按 ID 激活流程实例
suspendProcessInstanceById() 按 ID 挂起进程实例

    /**
     * 挂起 - 激活 单个流程实例
     */
    @Test
    public void suspendSingleProcessInstance() {
        //1.获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //3.通过 RuntimeService 获取流程实例id
        ProcessInstance instance = runtimeService.createProcessInstanceQuery()
                .processInstanceId("10001")
                .singleResult();
        String id = instance.getId();
        //4.得到实例的暂停状态
        boolean suspended = instance.isSuspended();
        //5.如果是挂起则激活   1-激活 2-挂起
        if (suspended) {
            runtimeService.activateProcessInstanceById(id);
            System.out.println("流程实例id:" + id + ",已激活");
        } else {
            //7.如果是激活则挂起    (参数1:流程定义id)
            runtimeService.suspendProcessInstanceById(id);
            System.out.println("流程实例id:" + id + ",已暂停");
        }
    }

如果挂起成功,act_ru_task表的SUSPENSION_STATE_ 字段就会为2.现在为2说明是挂起状态,挂起状态不能执行下一步,测试如下
在这里插入图片描述

    /**
     * 完成个人任务
     */
    @Test
    public void completTask() {
        //获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取操作任务的服务 TaskService
        TaskService taskService = processEngine.getTaskService();
        //使用 taskService 获取任务
        Task task = taskService.createTaskQuery()
                .processInstanceId("10001")    //参数为流程实例ID,表act_ru_task 的 PROC_INST_ID 字段可获取
                .taskAssignee("zhangsan")
                .singleResult();
        System.out.println("流程实例id:" + task.getProcessInstanceId());
        System.out.println("流程任务id:" + task.getId());
        System.out.println("流程负责人名字:" + task.getAssignee());
        System.out.println("任务名称:" + task.getName());
        //根据任务id完成任务
        taskService.complete(task.getId());
    }

报错:org.activiti.engine.ActivitiException: Cannot complete a suspended task。
无法完成暂停任务

2. 动态设置

2.1 动态设置负责人 Assignee

2.1.1 使用uel表达式读取参数

1. bpmn流程图中 Assignee 原本是写死的,现在使用uel表达式 改为 ${assignee}
在这里插入图片描述

其他几项同理
2. 使用uel表达式动态的部署设置属性

   /**
     * 使用uel表达式动态的部署设置属性
     */
    @Test
    public void testDeploymentUEL() {
        //1.获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.使用 service 进行流程部署,定义一个流程名字,把bpmn和png部署到数据中
        Deployment deploy = repositoryService.createDeployment()
                .name("出差申请-UEL")
                .addClasspathResource("bpmn/evection.bpmn20.xml")
                .deploy();
        System.out.println("流程部署id" + deploy.getId());
        System.out.println("流程部署名称" + deploy.getName());
    }

3. 使用uel表达式设置属性并启动流程实例

/**
     * 使用uel表达式设置属性并启动流程实例
     */
    @Test
    public void testStartUEL() {
        //1.获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取 RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //3.启动流程实例 startProcessInstanceByKey 根据key值(key,map)
        //3.1 设置map,里面是uel表达式的值 表--act-hi-varinst
        HashMap<String, Object> map = new HashMap<>();
        map.put("assignee0","张三");
        map.put("assignee1","李四");
        map.put("assignee2","王五");
        map.put("assignee3","钱六");
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("evenction",map);
    }

效果如下 表 act-hi-varinst
act-hi-varinst

2.1.2 使用监听器设置

注: Activiti BPMN visualizer 这个插件不支持设置监听器,所以需要手动改下xml文件

1. 创建出来的与之前一样,文件名:listener.bpmn20.xml

listener.bpmn20.xml
2.listener.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="listener" name="监听测试" isExecutable="true">
    <startEvent id="testListener" name="监听测试"/>
    <userTask id="_1" name="创建出差申请">
    <!--重点-->
      <extensionElements>
        <activiti:taskListener class="com.uuz.demo.listener.MyTaskListener" event="all"/>
      </extensionElements>
    </userTask>
    <userTask id="_2" name="经理审批"/>
    <userTask id="_3" name="总经理审批"/>
    <userTask id="_4" name="财务审批"/>
    <endEvent id="end" name="EndEvent"/>
    <sequenceFlow id="sid-de4ef1ba-6d8e-4d2f-a6b7-a01c0ccc4da6" sourceRef="testListener" targetRef="_1"/>
    <sequenceFlow id="sid-bac901bb-8972-4fe0-872a-a4a0dc6f77e7" sourceRef="_1" targetRef="_2"/>
    <sequenceFlow id="sid-ba2657da-d2d4-42b9-a59c-466af06a5134" sourceRef="_2" targetRef="_3"/>
    <sequenceFlow id="sid-4c8abe35-997d-4949-9afa-2f67a9ffb1fc" sourceRef="_3" targetRef="_4"/>
    <sequenceFlow id="sid-e95a6a72-f61e-4717-8ebe-adec24cf3017" sourceRef="_4" targetRef="end"/>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_evenction">
    <bpmndi:BPMNPlane bpmnElement="listener" id="BPMNPlane_evenction">
      <bpmndi:BPMNShape id="shape-c6c977d4-e101-439d-8da9-bfcd391c9b9f" bpmnElement="testListener">
        <omgdc:Bounds x="-2005.0" y="-1555.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-4e729324-2457-491a-b162-b85e01069462" bpmnElement="_1">
        <omgdc:Bounds x="-2040.0" y="-1510.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-843d0f2e-3568-4248-8220-b88fe6dad1db" bpmnElement="_2">
        <omgdc:Bounds x="-2040.0001" y="-1395.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-57b666ba-9d46-40d7-ba93-94596a3c263b" bpmnElement="_3">
        <omgdc:Bounds x="-2040.0001" y="-1285.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-2b900cc4-00d8-4151-aee5-6b475095dc03" bpmnElement="_4">
        <omgdc:Bounds x="-2040.0" y="-1175.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-5c08b723-fd52-4b05-8cc4-a81e12801eef" bpmnElement="end">
        <omgdc:Bounds x="-2005.0" y="-1060.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-fdaa9e79-e739-4ac4-bdea-5d830915b8a5" bpmnElement="sid-de4ef1ba-6d8e-4d2f-a6b7-a01c0ccc4da6">
        <omgdi:waypoint x="-1990.0" y="-1525.0"/>
        <omgdi:waypoint x="-1990.0" y="-1510.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-8d829762-92b6-4d1d-b5ee-d371f9a4510e" bpmnElement="sid-bac901bb-8972-4fe0-872a-a4a0dc6f77e7">
        <omgdi:waypoint x="-1990.0" y="-1430.0"/>
        <omgdi:waypoint x="-1990.0001" y="-1395.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-f5916ac5-38a1-4d0d-8cbf-9e16255d2620" bpmnElement="sid-ba2657da-d2d4-42b9-a59c-466af06a5134">
        <omgdi:waypoint x="-1990.0001" y="-1315.0"/>
        <omgdi:waypoint x="-1990.0001" y="-1285.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-2282edfd-1500-494d-9ded-844329633cb1" bpmnElement="sid-4c8abe35-997d-4949-9afa-2f67a9ffb1fc">
        <omgdi:waypoint x="-1990.0001" y="-1205.0"/>
        <omgdi:waypoint x="-1990.0" y="-1175.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-238c8248-f347-4ec0-a8d1-3036b45a637c" bpmnElement="sid-e95a6a72-f61e-4717-8ebe-adec24cf3017">
        <omgdi:waypoint x="-1990.0" y="-1095.0"/>
        <omgdi:waypoint x="-1990.0" y="-1060.0"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

手动新增的在前10行的,class是监听的类,event是监听的事件

event属性:

  • Create:任务创建后触发
  • Assignment:任务分配后触发
  • Delete:任务完成后触发
  • All:所有事件发生都触发
<extensionElements>
    <activiti:taskListener class="com.uuz.demo.listener.MyTaskListener" event="all"/>
</extensionElements>

3. class监听类,实现 TaskListener 接口重写 notify方法

public class MyTaskListener implements TaskListener {

    /**
     * 指定负责人
     * @param delegateTask 委托任务
     */
    @Override
    public void notify(DelegateTask delegateTask) {
        //判断当前任务是 创建申请 且 事件是 create 事件
        if (delegateTask.getName().equals("创建出差申请") && delegateTask.getEventName().equals("create")) {
            delegateTask.setAssignee("addd");
        }
    }
}

3. 启动流程实例

    @Test
    public void startDemoListener() {
        //1.获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RepositoryService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //3.启动流程实例
        ProcessInstance evenction = runtimeService.startProcessInstanceByKey("listener");
    } 

4. 结果如下 表 act_ru_task
act_ru_task

3. 分支流程路径

1. 创建如图所示的bpmn图 evection-global.bpmn20.xml
使用网关更加合适evection-global.bpmn20.xml

assignee1 -< 创建出差申请
assignee2 -< 部门经理
assignee3 -< 总经理
assignee4 -< 财务

2. 设置分支选择条件
双击选中需要判断的线,设置Condition expression 属性 同样是uel表达式。(evection是下面所创建的一个类)
在这里插入图片描述
3. 创建一个实体类 evection ,类中的属性通过启动流程实例的时候可以传入

 //Serializable 实现序列化接口
public class Evection implements Serializable {
	//省略getset方法
    //主键ID
    private Long id;

    //出差实例的名字
    private String evectionName;

    //出差天数
    private Double num;

    //开始时间
    private Date beginDate;

    //结束时间
    private Date endDate;

    //目的地
    private String destination;

    //出差原因
    private String reson;

4.

  • 4.1 部署略
  • 4.2 启动流程实例
/**
     * 启动流程实例
     */
    @Test
    public void testStartProcess() {
        //1.创建 processEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取runTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //3.定义流程变量 上文提到的实体类
        Evection evection = new Evection();
        HashMap<String, Object> variables = new HashMap<>();
        //3.1 设置出差天数 5天
        evection.setNum(5d);
        //3.2 设定任务负责人
        variables.put("evection", evection);
        variables.put("assignee1", "普通员工");
        variables.put("assignee2", "经理");
        variables.put("assignee3", "总经理");
        variables.put("assignee4", "财务");
        //4.根据流程定义key和参数启动实例  表 act_ru_variable 可以看到一个类型为serializable
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("evection-global", variables);

        //4.输出内容
        System.out.println("流程定义ID=" + instance.getProcessDefinitionId());
        System.out.println("流程实列ID=" + instance.getId());
        System.out.println("当前活动的ID=" + instance.getActivityId());
    }
  • 4.3 完成个人任务

注意:
.processInstanceId(ID) 这个ID是任务实例从出生到死亡不会变的ID
task.getId() 这个ID虽然也能查询到,但只是限于当前任务,当前任务执行下一步后每次都会改变此ID值

    /**
     * 完成个人任务
     */
    @Test
    public void completTask() {
        //1.创建 processEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取TaskService
        TaskService taskService = processEngine.getTaskService();
        //3. 查询任务,表 act_ru_task
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("evection-global")        //流程定义key
                .taskAssignee("财务")                         //Assignee
                .processInstanceId("17502")                            //实例id,如果是多个实例满足前两个条件则需要此处判断
                .singleResult();
        if (task != null) {
            //4.根据任务 ID 来完成任务  查看表 act_ru_task 的Assignee字段
            taskService.complete(task.getId());
        }
    }
  • 4.4 结果
    多次执行完成个人任务后到达了总经理审批
    act_ru_task

4. 设置变量

4.1 创建流程时设置变量

如前文中启动流程时设置天数

        //3.定义流程变量
        Evection evection = new Evection();
        HashMap<String, Object> variables = new HashMap<>();
        //3.1 设置出差天数
        evection.setNum(5d);
        //3.2 设定任务负责人
        variables.put("evection", evection);
        variables.put("assignee1", "普通员工");
        variables.put("assignee2", "经理");
        variables.put("assignee3", "总经理");
        variables.put("assignee4", "财务");
        //4.根据流程定义key和参数启动实例  表 act_ru_variable 可以看到一个类型为serializable
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("evection-global", variables);

4.2 任务处理中设置变量

还是拿上面那一部分,只不过这次taskService.complete() 多传了一个参数。
如这里,本来启动流程时是5天,在这里修改为了两天,后续就不会在走总经理审批路线
taskService.complete

    @Test
    public void completTask() {
        //1.创建 processEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取TaskService
        TaskService taskService = processEngine.getTaskService();
        //3. 查询任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("evection-global")        //流程定义key
                .processInstanceId("17502")                            //实例id,如果是多个实例满足前两个条件则需要此处判断
                .singleResult();

        Evection evection = new Evection();
        evection.setNum(2d);
//        taskService.setVariableLocal("35002","evection",evection);

        HashMap<String, Object> map = new HashMap<>();
        map.put("evection",evection);

        System.out.println(task);
        if (task != null) {
            //4.根据任务 ID 来完成任务  查看表 act_ru_task 的Assignee字段
            taskService.complete(task.getId(),map);
        }
    }

4.2.1 任务处理中设置变量的多种方式

1. 全局变量
runtimeService.setVariable()
runtimeService.setVariables()
本地变量
runtimeService.setVariableLocal()
runtimeService.setVariablesLocal()

//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取runTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.创建 Evection 对象
Evection evection = new Evection();
evection.setNum(2d);
//4.通过实例id来设置属性值
runtimeService.setVariable(ID, "evection", evection)
//runtimeService.setVariables(ID, map)通过传入map可以一次修改多个变量

2. 当前任务设置
taskService.setVariable()
taskService.setVariables()
本地变量
taskService.setVariableLocal()
taskService.setVariablesLocal()

//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取TaskService
TaskService taskService = processEngine.getTaskService();
//3.创建 Evection 对象
Evection evection = new Evection();
evection.setNum(2d);
//通过任务设置流程变量
taskService.setVariable(taskId, "evection", evection)
//taskService.setVariables(ID, map)通过传入map可以一次修改多个变量

3. complete
taskService.complete(task.getId(),map);

5. 组任务

  1. 创建如图流程图,注意 Assignee 为空,CandidateUsers用逗号隔开多个
    在这里插入图片描述
    实质是 activiti:candidateUsers=“a,b”
<userTask id="sid-e81d100e-8c42-43bd-acce-aaf72c6c75ac" name="222" activiti:candidateUsers="a,b"/>

略部署
略创建实列
略111
2. 查询组任务 与 拾取,归还任务

核心:
1. 查询 .taskCandidateUser(候选人字段)
2. 拾取 taskService.claim(TaskId, 候选人字段);
3. 归还 taskService.setAssignee(TaskId, null); null 也可以直接将其赋值为其他候选人字段

在这里插入图片描述
当前taskId是17502,可以看到 Assignee 字段为 null,说明没有人处理(没有人处理是指此处没有绑定负责人字段,并不是不可执行,直接调用 complete() 方法依然可以进入到结束流程)

    /**
     * 查询组任务
     */
    @Test
    public void findGroupTaskList() {
        //1.创建 processEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取TaskService
        TaskService taskService = processEngine.getTaskService();
        //3.查询组任务
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("candidate-users")        //流程定义key
                .taskCandidateUser("a")                 //根据候选人查询任务(指此处CandidateUsers绑定了a这个字段,也能传list集合)
//                .taskId("5012")   
                .list();
        System.out.println(taskList);
    }

    /**
     * 候选人拾取任务
     */
    @Test
    public void claimTask() {
        //1.创建 processEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取TaskService
        TaskService taskService = processEngine.getTaskService();
        //3.查询任务
        Task task = taskService.createTaskQuery()
                .taskId("17502")                 //task本段id
                .taskCandidateUser("a")         //可以选择的候选人
                .singleResult();
        if (task != null) {
            //4.拾取任务
            taskService.claim("17502", "b");
            System.out.println("拾取任务完成");
        }
    }

    /**
     * 候选人归还任务
     */
    @Test
    public void AssigneeToGroupTask() {
        //1.创建 processEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取TaskService
        TaskService taskService = processEngine.getTaskService();
        //3.查询任务
        Task task = taskService.createTaskQuery()
                .taskId("17502")                 //task本段id
                .taskAssignee("b")         //根据现在的负责人查询
                .singleResult();
        if (task != null) {
            //4.归还任务(将任务负责人设置为null就清除了候选人,当然也可以直接设置其他候选人)
            taskService.setAssignee("17502", null);
            System.out.println("拾取任务完成");
        }
    }

6. 网关Gateway

安装 Camunda Modeler工作流设计器

6.1 网关的四种类型

  • 排他网关 (ExclusiveGateway)

排他网关

当事件需要多选一的时候可以使用排他网关(如果都符合则选择xml中id小的那条,都不符合抛出异常)类似前文的单独在线路上设置的判断,只不过这里加了网关,好处是都不符合会抛出异常,而没有网关则会直接终止事件

在这里插入图片描述
设置的方法
在这里插入图片描述
传参(此处判断num值,这里传的是2,说明走下面一条路)

HashMap<String, Object> variables = new HashMap<>();
variables.put("num", "2");
runtimeService.startProcessInstanceByKey("ExclusiveGateway", variables);
  • 并行网关 (ParallelGateway)

当事件需要满足多个条件时使用并行网关,并行网关的特点是会无视连线上设置的条件,他会将流程分发给下一步所有的处理,并且末尾会有一个集束的并行网关来收集。
当执行到网关后,表 act_ru_task 会创建多个相同的 PROC_INTS_ID(实例) 字段,这个时候就不能在单独用 processInstanceId(ID) 来查询了因为会返回多个,而是使用.taskId(id) 来具体查询流程步骤。
在满足一个条件后,会删除此步骤等待并行的另一个步骤完成后,到达总经理阶段

在这里插入图片描述

在这里插入图片描述
等待两条并行线步骤
在这里插入图片描述

  • 包含网关 (InclusiveGateway)

类似于排他+并行网关,可以有判断条件,也需要汇集,等待并行的其他条件

在这里插入图片描述
num>3 由项目经理处理,<3由技术经理处理,但无论怎么样都要有人事经理处理(若等于3则只通过人事经理)不设置会报错
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值