activiti——网关配置

文章目录

  • 前言
  • 网关介绍
  • 代码案例测试各项网关
    • 排他网关 ExclusiveGateway
      • 1、绘制流程图
      • 2、编写测试代码
    • 并行网关ParallelGateway
      • 1、绘制流程图
      • 2、编写测试代码
    • 包含网关InclusiveGateway
      • 1、绘制流程图
      • 2、编写测试代码

前言

activiti工作流中,还有一个组件也很重要,那就是网关,并在许多的流程设计中都会进行使用操作。

网关介绍

常见的网关有以下4种,分别如下所示。

  • 排他网关 ExclusiveGateway
    多条分支线路,执行满足条件的一条流程。
    当流程执行到这个网关,所有分支都会判断条件是否为true,如果为true则执行该分支。

    按照对应的条件执行,选择满足条件true的分支。如果多条分支都不会满足条件,流程会被异常结束。

    在这里插入图片描述
    在这里插入图片描述

    请假天数大于等于3天时,需要总经理审批后,再进行财务审批。
    请假天数小于 3 天时,财务直接审批即可,无需 总经理进行审批。

  • 并行网关 ParallelGateway
    并行流允许为一个流程设置多条链路同步执行。
    并行网关需要前后两个配置,当所有的分支流程都执行完成后,才会通过当前聚合网关,流程向下执行。
    财务系统中涉及到贷审会的配置点,一般使用该网关实现。
    fork分支:并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
    join汇聚: 所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。

    如果并行网关中配置了条件,条件会被忽略!

    在这里插入图片描述
    在这里插入图片描述

    并行网关条件会忽略。
    请假流程需要 项目经理 和 技术经理 都审批,才能将流程向下执行。

  • 包含网关InclusiveGateway
    包含网关也和 并行网关类似,需要前后两个网关节点配置,分为分支网关和汇聚网关。
    与并行网关的最大区别:
    并行网关需要所有的分支都执行完成后,才能继续进行下面的其他节点任务流程操作。其次并行网关不会考虑分支条件。
    包含网关在开始时,会根据每个连线设置的条件,执行满足条件的分支。当所有满足条件的分支均执行完成后,才会进入汇聚网关中继续向下执行流程。
    在这里插入图片描述
    在这里插入图片描述

请假流程一定需要人事经理审批。
如果请假天数等于或超过3天,需要项目经理审批,方便管理项目事项安排。
如果请假天数小于3天,只需要技术经理审批。

  • 事件网关EventGateway (只做了解)
    事件网关允许根据事件判断流向。网关的每个外出顺序流都要连接到一个中间捕获事件。 当流程到达一个基于事件网关,网关会进入等待状态:会暂停执行。与此同时,会为每个外出顺序流创建相对的事件订阅。
    事件网关的外出顺序流和普通顺序流不同,这些顺序流不会真的"执行", 相反它们让流程引擎去决定执行到事件网关的流程需要订阅哪些事件。 要考虑以下条件:

    1. 事件网关必须有两条或以上外出顺序流;
    2. 事件网关后,只能使用intermediateCatchEvent类型(activiti不支持基于事件网关后连接ReceiveTask)
    3. 连接到事件网关的中间捕获事件必须只有一个入口顺序流。

    与事件网关配合使用的intermediateCatchEvent:
    在这里插入图片描述
    这个事件支持多种事件类型:
    Message Event:消息事件
    Singal Event: 信号事件
    Timer Event: 定时事件

在这里插入图片描述
使用事件网关定义流程:
在这里插入图片描述

代码案例测试各项网关

以对象方式传递参数信息。

package cn.bugs.vo;

import lombok.Data;

import java.io.Serializable;

// 必须实现 Serializable  ,否则 实例化流程对象时,会报错
@Data
public class Evection implements Serializable {

    // 请假天数
    private Integer num;
}

排他网关 ExclusiveGateway

1、绘制流程图

在这里插入图片描述

模板代码如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/testm1715603344601" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1715603344601" name="" targetNamespace="http://www.activiti.org/testm1715603344601" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="exclusive" isClosed="false" isExecutable="true" name="排他网关" processType="None">
    <startEvent id="_2" name="StartEvent"/>
    <userTask activiti:assignee="worker1" activiti:exclusive="true" id="_3" name="出差申请"/>
    <userTask activiti:assignee="worker2" activiti:exclusive="true" id="_4" name="部门经理审批"/>
    <exclusiveGateway gatewayDirection="Unspecified" id="_5" name="ExclusiveGateway"/>
    <userTask activiti:assignee="worker3" activiti:exclusive="true" id="_6" name="总经理审批"/>
    <userTask activiti:assignee="worker4" activiti:exclusive="true" id="_7" name="财务审批"/>
    <endEvent id="_8" name="EndEvent"/>
    <sequenceFlow id="_9" sourceRef="_2" targetRef="_3"/>
    <sequenceFlow id="_10" sourceRef="_3" targetRef="_4"/>
    <sequenceFlow id="_11" sourceRef="_4" targetRef="_5"/>
    <sequenceFlow id="_12" name="请假大于等于3天" sourceRef="_5" targetRef="_6">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[${evection.num >= 3}]]>
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_13" name="请假小于3天" sourceRef="_5" targetRef="_7">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[${evection.num < 3}]]>
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_14" sourceRef="_6" targetRef="_7"/>
    <sequenceFlow id="_15" sourceRef="_7" targetRef="_8"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="exclusive">
      <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
        <dc:Bounds height="32.0" width="32.0" x="85.0" y="315.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
        <dc:Bounds height="55.0" width="85.0" x="185.0" y="305.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
        <dc:Bounds height="55.0" width="85.0" x="350.0" y="305.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5" isMarkerVisible="false">
        <dc:Bounds height="32.0" width="32.0" x="375.0" y="460.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6">
        <dc:Bounds height="55.0" width="85.0" x="555.0" y="405.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_7" id="Shape-_7">
        <dc:Bounds height="55.0" width="85.0" x="555.0" y="520.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_8" id="Shape-_8">
        <dc:Bounds height="32.0" width="32.0" x="740.0" y="530.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_13" id="BPMNEdge__13" sourceElement="_5" targetElement="_7">
        <di:waypoint x="407.0" y="476.0"/>
        <di:waypoint x="555.0" y="547.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_12" id="BPMNEdge__12" sourceElement="_5" targetElement="_6">
        <di:waypoint x="407.0" y="476.0"/>
        <di:waypoint x="555.0" y="432.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_15" id="BPMNEdge__15" sourceElement="_7" targetElement="_8">
        <di:waypoint x="640.0" y="547.5"/>
        <di:waypoint x="740.0" y="546.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_14" id="BPMNEdge__14" sourceElement="_6" targetElement="_7">
        <di:waypoint x="597.5" y="460.0"/>
        <di:waypoint x="597.5" y="520.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_2" targetElement="_3">
        <di:waypoint x="117.0" y="331.0"/>
        <di:waypoint x="185.0" y="332.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_11" id="BPMNEdge__11" sourceElement="_4" targetElement="_5">
        <di:waypoint x="391.0" y="360.0"/>
        <di:waypoint x="391.0" y="460.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="_3" targetElement="_4">
        <di:waypoint x="270.0" y="332.5"/>
        <di:waypoint x="350.0" y="332.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

2、编写测试代码

案例代码包含部署创造流程实例(2个)审批验证查询

addTable()–>startProcess()–>completTask()–>queryTask()–>completTask()–>queryTask()

package com.bugs.activity;

import cn.bugs.vo.Evection;
import cn.hutool.core.collection.CollectionUtil;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

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

@SpringBootTest
public class GateWayExclusive {

    /**
     * 部署
     */
    @Test
    public void addTable(){
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
        Deployment demo1 = repositoryService.createDeployment()
                .addClasspathResource("bpmn/gateway-exclusive.bpmn") // 添加流程图
                //.addClasspathResource("bpmn/gateway-exclusive.png") // 对应的流程图片 支持 png|jpg|gif|svg
                .name("排他网关流程部署测试")
                .deploy();
        System.out.println("流程部署id===》"+demo1.getId());
        System.out.println("流程部署name===》"+demo1.getName());
    }

    /**
     * 启动实例  全局系统参数 设置
     * 这里针对条件  分别启动两个流程实例
     */
    @Test
    public void startProcess(){
        // 获取流程引擎
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取 runtime 服务
        RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
        // 指定哪个模板
        String tempKey = "exclusive";

        // 流程变量  可以是对象 也可以是单个的类型变量 比如 字符串
        HashMap<String, Object> paramMap = new HashMap<>();

        Evection evection = new Evection();
        //evection.setNum(2); // 流程1
        evection.setNum(4); // 流程2
        paramMap.put("evection",evection);

        // 启动流程实例
        runtimeService.startProcessInstanceByKey(tempKey,paramMap);
    }

    /**
     * 查询流程实例信息
     */
    @Test
    public void queryTask(){
        // 执行已部署的流程模板名称
        String tempKey = "exclusive";
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = defaultProcessEngine.getTaskService();

        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(tempKey) // 指定哪个流程图模板
                .list();
        if(!CollectionUtil.isEmpty(list)){
            list.forEach(x->{
                System.out.println("流程实例 id "+x.getProcessInstanceId());
                System.out.println("任务 id "+x.getId());
                System.out.println("任务负责人 "+x.getAssignee());
                System.out.println("任务名称 "+x.getName());
                System.out.println("===========================================");
            });
        }
    }

    /**
     * 工作流的节点与状态的扭转
     * 这里有2个流程  分别对对应的任务 id 进行流程的推进
     *
     * 执行两次,将节点推送到 排他网关
     */
    @Test
    public void completTask(){
        String tempKey = "exclusive";
        // 获取数据库的连接信息
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = defaultProcessEngine.getTaskService();

        List<Task> list = taskService.createTaskQuery().processDefinitionKey(tempKey).list();
        if(!CollectionUtil.isEmpty(list)){
            list.forEach(task->{
                taskService.complete(task.getId());
            });
        }

    }
}

最终执行后,排他网关所在节点信息如下所示:
在这里插入图片描述

并行网关ParallelGateway

1、绘制流程图

在这里插入图片描述
流程图文件如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1715604997659" name="" targetNamespace="http://www.activiti.org/testm1715604997659" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="parallel" isClosed="false" isExecutable="true" name="并行网关流程测试" processType="None">
    <startEvent id="_2" name="StartEvent"/>
    <userTask activiti:assignee="worker1" activiti:exclusive="true" id="_3" name="出差申请"/>
    <userTask activiti:assignee="worker2" activiti:exclusive="true" id="_4" name="技术经理"/>
    <parallelGateway gatewayDirection="Unspecified" id="_5" name="ParallelGateway"/>
    <userTask activiti:assignee="worker3" activiti:exclusive="true" id="_6" name="总经理"/>
    <parallelGateway gatewayDirection="Unspecified" id="_7" name="ParallelGateway"/>
    <sequenceFlow id="_8" sourceRef="_2" targetRef="_3"/>
    <sequenceFlow id="_9" sourceRef="_3" targetRef="_5"/>
    <sequenceFlow id="_10" sourceRef="_5" targetRef="_4"/>
    <sequenceFlow id="_11" sourceRef="_5" targetRef="_6"/>
    <sequenceFlow id="_12" sourceRef="_4" targetRef="_7"/>
    <sequenceFlow id="_13" sourceRef="_6" targetRef="_7"/>
    <endEvent id="_14" name="EndEvent"/>
    <sequenceFlow id="_15" sourceRef="_7" targetRef="_14"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="parallel">
      <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
        <dc:Bounds height="32.0" width="32.0" x="40.0" y="275.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
        <dc:Bounds height="55.0" width="85.0" x="150.0" y="265.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
        <dc:Bounds height="55.0" width="85.0" x="430.0" y="200.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5">
        <dc:Bounds height="32.0" width="32.0" x="330.0" y="275.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6">
        <dc:Bounds height="55.0" width="85.0" x="430.0" y="355.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_7" id="Shape-_7">
        <dc:Bounds height="32.0" width="32.0" x="600.0" y="295.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_14" id="Shape-_14">
        <dc:Bounds height="32.0" width="32.0" x="710.0" y="295.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_13" id="BPMNEdge__13" sourceElement="_6" targetElement="_7">
        <di:waypoint x="515.0" y="382.5"/>
        <di:waypoint x="600.0" y="311.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_12" id="BPMNEdge__12" sourceElement="_4" targetElement="_7">
        <di:waypoint x="515.0" y="227.5"/>
        <di:waypoint x="600.0" y="311.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_15" id="BPMNEdge__15" sourceElement="_7" targetElement="_14">
        <di:waypoint x="632.0" y="311.0"/>
        <di:waypoint x="710.0" y="311.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_2" targetElement="_3">
        <di:waypoint x="72.0" y="291.0"/>
        <di:waypoint x="150.0" y="292.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_3" targetElement="_5">
        <di:waypoint x="235.0" y="292.5"/>
        <di:waypoint x="330.0" y="291.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_11" id="BPMNEdge__11" sourceElement="_5" targetElement="_6">
        <di:waypoint x="362.0" y="291.0"/>
        <di:waypoint x="430.0" y="382.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="_5" targetElement="_4">
        <di:waypoint x="362.0" y="291.0"/>
        <di:waypoint x="430.0" y="227.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

2、编写测试代码

编写测试代码,执行观察控制台日志信息。
addTable()–>startProcess()–>completTask()–>queryTask()

package com.bugs.activity;

import cn.bugs.vo.Evection;
import cn.hutool.core.collection.CollectionUtil;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

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

@SpringBootTest
public class GatewayParallel {

    /**
     * 部署
     */
    @Test
    public void addTable(){
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
        Deployment demo1 = repositoryService.createDeployment()
                .addClasspathResource("bpmn/gateway-parallel.bpmn") // 添加流程图
                //.addClasspathResource("bpmn/gateway-parallel.png") // 对应的流程图片 支持 png|jpg|gif|svg
                .name("排他网关流程部署测试")
                .deploy();
        System.out.println("流程部署id===》"+demo1.getId());
        System.out.println("流程部署name===》"+demo1.getName());
    }

    /**
     * 启动实例
     */
    @Test
    public void startProcess(){
        // 获取流程引擎
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取 runtime 服务
        RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
        // 指定哪个模板
        String tempKey = "parallel";

        // 启动流程实例
        runtimeService.startProcessInstanceByKey(tempKey);
    }

    /**
     * 工作流的节点与状态的扭转
     * 这里有2个流程  分别对对应的任务 id 进行流程的推进
     *
     * 执行两次,将节点推送到 排他网关
     */
    @Test
    public void completTask(){
        String tempKey = "parallel";
        // 获取数据库的连接信息
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = defaultProcessEngine.getTaskService();

        List<Task> list = taskService.createTaskQuery().processDefinitionKey(tempKey).list();
        if(!CollectionUtil.isEmpty(list)){
            list.forEach(task->{
                taskService.complete(task.getId());
            });
        }

    }

    /**
     * 查询流程实例信息
     */
    @Test
    public void queryTask(){
        // 执行已部署的流程模板名称
        String tempKey = "parallel";
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = defaultProcessEngine.getTaskService();

        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(tempKey) // 指定哪个流程图模板
                .list();
        if(!CollectionUtil.isEmpty(list)){
            list.forEach(x->{
                System.out.println("流程实例 id "+x.getProcessInstanceId());
                System.out.println("任务 id "+x.getId());
                System.out.println("任务负责人 "+x.getAssignee());
                System.out.println("任务名称 "+x.getName());
                System.out.println("===========================================");
            });
        }
    }
}

在这里插入图片描述
当进入并行网关后,此时的任务节点变成了2个,分别指向了 技术经理 和 总经理 审批节点。

再将其中某个节点进行审批操作,观察多个节点某个执行后整体流程的进度信息。

/**
 * 仅执行 worker2  技术经理 的审批任务
 */
@Test
public void completWork2Task(){
    String tempKey = "parallel";
    String assign = "worker2";
    // 获取数据库的连接信息
    ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = defaultProcessEngine.getTaskService();

    List<Task> list = taskService.createTaskQuery()
            .processDefinitionKey(tempKey)
            .taskAssignee(assign)
            .list();
    if(!CollectionUtil.isEmpty(list)){
        list.forEach(task->{
            taskService.complete(task.getId());
        });
    }
}

/**
 * 查询流程实例信息
 */
@Test
public void queryTask(){
    // 执行已部署的流程模板名称
    String tempKey = "parallel";
    ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = defaultProcessEngine.getTaskService();

    List<Task> list = taskService.createTaskQuery()
            .processDefinitionKey(tempKey) // 指定哪个流程图模板
            .list();
    if(!CollectionUtil.isEmpty(list)){
        list.forEach(x->{
            System.out.println("流程实例 id "+x.getProcessInstanceId());
            System.out.println("任务 id "+x.getId());
            System.out.println("任务负责人 "+x.getAssignee());
            System.out.println("任务名称 "+x.getName());
            System.out.println("===========================================");
        });
    }
}

在这里插入图片描述
还需要继续等待另一个节点的审批通过,才会彻底执行完成并行网关流程。

包含网关InclusiveGateway

包含网关就是 排他网关与并行网关的结合体。

1、绘制流程图

在这里插入图片描述
上图对应的bpmn文件xml代码如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1715674484799" name="" targetNamespace="http://www.activiti.org/testm1715674484799" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="inclusive" isClosed="false" isExecutable="true" processType="None">
    <startEvent id="_2" name="StartEvent"/>
    <userTask activiti:assignee="worker1" activiti:exclusive="true" id="_3" name="流程提交"/>
    <inclusiveGateway gatewayDirection="Unspecified" id="_4" name="InclusiveGateway"/>
    <userTask activiti:assignee="worker2" activiti:exclusive="true" id="_5" name="项目经理审批"/>
    <userTask activiti:assignee="worker3" activiti:exclusive="true" id="_6" name="人事审批"/>
    <userTask activiti:assignee="worker4" activiti:exclusive="true" id="_7" name="技术经理审批"/>
    <inclusiveGateway gatewayDirection="Unspecified" id="_8" name="InclusiveGateway"/>
    <endEvent id="_9" name="EndEvent"/>
    <sequenceFlow id="_10" sourceRef="_2" targetRef="_3"/>
    <sequenceFlow id="_11" sourceRef="_3" targetRef="_4"/>
    <sequenceFlow id="_12" name="请假天数超过或等于3天" sourceRef="_4" targetRef="_5">
      <documentation id="_12_D_1"/>
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[${evection.num>=3}]]>
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_13" sourceRef="_4" targetRef="_6"/>
    <sequenceFlow id="_14" name="请假天数小于3天" sourceRef="_4" targetRef="_7">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[${evection.num<3}]]>
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_15" sourceRef="_5" targetRef="_8"/>
    <sequenceFlow id="_16" sourceRef="_6" targetRef="_8"/>
    <sequenceFlow id="_17" sourceRef="_7" targetRef="_8"/>
    <sequenceFlow id="_18" sourceRef="_8" targetRef="_9"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="inclusive">
      <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
        <dc:Bounds height="32.0" width="32.0" x="65.0" y="265.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
        <dc:Bounds height="55.0" width="85.0" x="180.0" y="255.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
        <dc:Bounds height="32.0" width="32.0" x="365.0" y="265.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5">
        <dc:Bounds height="55.0" width="85.0" x="510.0" y="125.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6">
        <dc:Bounds height="55.0" width="85.0" x="510.0" y="255.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_7" id="Shape-_7">
        <dc:Bounds height="55.0" width="85.0" x="510.0" y="390.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_8" id="Shape-_8">
        <dc:Bounds height="32.0" width="32.0" x="725.0" y="270.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_9" id="Shape-_9">
        <dc:Bounds height="32.0" width="32.0" x="875.0" y="270.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_13" id="BPMNEdge__13" sourceElement="_4" targetElement="_6">
        <di:waypoint x="397.0" y="281.0"/>
        <di:waypoint x="510.0" y="282.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_12" id="BPMNEdge__12" sourceElement="_4" targetElement="_5">
        <di:waypoint x="397.0" y="281.0"/>
        <di:waypoint x="510.0" y="152.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_15" id="BPMNEdge__15" sourceElement="_5" targetElement="_8">
        <di:waypoint x="595.0" y="152.5"/>
        <di:waypoint x="725.0" y="286.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_14" id="BPMNEdge__14" sourceElement="_4" targetElement="_7">
        <di:waypoint x="397.0" y="281.0"/>
        <di:waypoint x="510.0" y="417.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_17" id="BPMNEdge__17" sourceElement="_7" targetElement="_8">
        <di:waypoint x="595.0" y="417.5"/>
        <di:waypoint x="725.0" y="286.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_16" id="BPMNEdge__16" sourceElement="_6" targetElement="_8">
        <di:waypoint x="595.0" y="282.5"/>
        <di:waypoint x="725.0" y="286.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_18" id="BPMNEdge__18" sourceElement="_8" targetElement="_9">
        <di:waypoint x="757.0" y="286.0"/>
        <di:waypoint x="875.0" y="286.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_11" id="BPMNEdge__11" sourceElement="_3" targetElement="_4">
        <di:waypoint x="265.0" y="282.5"/>
        <di:waypoint x="365.0" y="281.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="_2" targetElement="_3">
        <di:waypoint x="97.0" y="281.0"/>
        <di:waypoint x="180.0" y="282.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

2、编写测试代码

将上述的bpmn流程文件部署至activiti中,并将该流程进行启动。

addTable()–>startProcess()–>startProcess()–>completTask()–>queryTask()

package com.bugs.activity;

import cn.bugs.vo.Evection;
import cn.hutool.core.collection.CollectionUtil;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

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

@SpringBootTest
public class GatewayInclusive {

    /**
     * 单文件上传部署逻辑
     */
    @Test
    public void addTable(){
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
        Deployment demo1 = repositoryService.createDeployment()
                .addClasspathResource("bpmn/gateway-inclusive.bpmn") // 添加流程图
                .name("包含网关流程验证")
                .deploy();
        System.out.println("流程部署id===》"+demo1.getId());
        System.out.println("流程部署name===》"+demo1.getName());
    }


    /**
     * 启动实例
     * 这里启动2个,一个天数大于3天,一个小于3天
     */
    @Test
    public void startProcess(){
        // 获取流程引擎
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取 runtime 服务
        RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
        // 指定哪个模板
        String tempKey = "inclusive";

        Map<String, Object> paramMap = new HashMap<>();
        Evection evection = new Evection();
        //evection.setNum(5); // 流程1
        evection.setNum(2); // 流程2
        paramMap.put("evection",evection);

        // 启动流程实例
        runtimeService.startProcessInstanceByKey(tempKey,paramMap);
    }

    /**
     * 将指定流程进行流程提交操作
     */
    @Test
    public void completTask(){
        String tempKey = "inclusive";
        // 获取数据库的连接信息
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = defaultProcessEngine.getTaskService();

        List<Task> list = taskService.createTaskQuery().processDefinitionKey(tempKey).list();
        if(!CollectionUtil.isEmpty(list)){
            list.forEach(task->{
                taskService.complete(task.getId());
            });
        }

    }


    /**
     * 查询流程实例信息
     */
    @Test
    public void queryTask(){
        // 执行已部署的流程模板名称
        String tempKey = "inclusive";
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = defaultProcessEngine.getTaskService();

        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(tempKey) // 指定哪个流程图模板
                .list();
        if(!CollectionUtil.isEmpty(list)){
            list.forEach(x->{
                System.out.println("流程实例 id "+x.getProcessInstanceId());
                System.out.println("任务 id "+x.getId());
                System.out.println("任务负责人 "+x.getAssignee());
                System.out.println("任务名称 "+x.getName());
                System.out.println("===========================================");
            });
        }
    }
}

启动两个不同请假天数的流程实例后,将提交申请的流程全部进行审批操作。观察两个流程的情况信息。
在这里插入图片描述
因为天数的不同,根据流程的分支上的条件判断,由于人事审批并没有条件,则每个流程中都会进入人事审批环节。
配置了条件后,当条件满足,则会进行满足条件分支的审批任务上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/626172.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第五十三天

今天同事说他要离职啦&#xff0c;还挣挺多的&#xff0c;我也慢慢努力吧&#xff01;&#xff01; 儿子似乎有点斜颈&#xff0c;还好不是很大的病&#xff0c;儿子也开始面对人生的苦难啦。都好好加油生活&#xff01; 1143.最长公共子序列 二维可以理解一点。 class Solut…

Meilisearch使用过程趟过的坑

Elasticsearch 做为老牌搜索引擎&#xff0c;功能基本满足&#xff0c;但复杂&#xff0c;重量级&#xff0c;适合大数据量。 MeiliSearch 设计目标针对数据在 500GB 左右的搜索需求&#xff0c;极快&#xff0c;单文件&#xff0c;超轻量。 所以&#xff0c;对于中小型项目来说…

解决springboot+vue静态资源刷新后无法访问的问题

一、背景 原项目是有前后端分离设计&#xff0c;测试环境是centos系统&#xff0c;采用nginx代理和转发&#xff0c;项目正常运行。 项目近期上线到正式环境&#xff0c;结果更换了系统环境&#xff0c;需要放到一台windows系统中&#xff0c;前后端打成一个jar包&#xff0c;…

使用vue3+ts+vite从零开始搭建bolg(五):layout(持续更新中)

五、layout搭建 5.1静态搭建 在src下创建如图文件夹 这里用logo举例&#xff0c;在scripts里export <script lang"ts">export default {name: Logo,}</script> 然后在layout里引入 //引入左侧菜单顶部用户信息 import Logo from ./logo/index.vue 接…

跨境必看|TikTok账号运营的八大秘籍

国内的传统生意都是可以在抖音上做&#xff0c;那么也可以在TikTok 上重新做一遍。那该如何才能把握住这片巨大的蓝海&#xff0c;TikTok 账号的运营就成为了主要的关键了&#xff0c;对于TikTok账号运营的八大秘籍&#xff0c;大家一起看看是如何做的&#xff1f; 一、固定节…

算法_前缀和

DP34 【模板】前缀和 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别int n in.nextInt(),q in.ne…

NSSCTF Web方向的例题和相关知识点(二)

[SWPUCTF 2021 新生赛]Do_you_know_http 解题&#xff1a; 点击打开环境&#xff0c;是 提示说请使用wLLm浏览器访问 我们可以更改浏览器信息&#xff0c;在burp重放器中发包后发现是302重定向&#xff0c;但是提示说success成功&#xff0c;说明 我们修改是成功的&#xff…

如何写好设计文档

一、明确目的 在编写设计文档之前&#xff0c;首先要明确为什么需要写这份文档。设计文档是软件开发过程中的重要沟通工具&#xff0c;它有助于确保团队成员对项目有共同的理解&#xff0c;促进协作&#xff0c;便于变更管理&#xff0c;并提供历史记录。 二、编写方法 为目…

动手学深度学习17 使用和购买gpu

动手学深度学习16 Pytorch神经网络基础&#xff09; 5. GPUcolabNVIDIA GPUQA显存 5. GPU 课件&#xff1a; https://zh-v2.d2l.ai/chapter_deep-learning-computation/use-gpu.html 有GPU装cuda。 把模型参数放到指定设备上。 # 5.6. GPU # !nvidia-smi # 在命令行中&…

VictoriaMetrics

概念 介绍 VictoriaMetrics&#xff0c;是一个快速高效、经济并且可扩展的监控解决方案和时序数据库 本文均用VM简称VictoriaMetric 作用 用于作为prometheus的长期储存方案&#xff0c;代替prometheus存储监控采集的数据 优点 远程存储&#xff1a;可作为单一或多个Pro…

matlab使用1-基础

matlab使用1-基础 文章目录 matlab使用1-基础1. 界面介绍2. matlab变量3. matlab数据类型4. matlab矩阵操作5. matlab程序结构5.1 顺序结构5.2 循环结构5.3 分支结构 1. 界面介绍 命令行窗口输入&#xff1a;clc 可清除命令行窗口command window的内容 clc命令行窗口输入&…

C++ 多态性

一 多态性的分类 编译时的多态 函数重载 运算符重载 运行时的多态 虚函数 1 运算符重载的引入 使用C编写程序时&#xff0c;我们不仅要使用基本数据类型&#xff0c;还要设计新的数据类型-------类类型。 一般情况下&#xff0c;基本数据类型的运算都是运算符来表达&#x…

10G UDP协议栈 IP层设计-(6)IP TX模块

一、模块功能 1、上层数据封装IP报文头部 2、计算首部校验和 二、首部校验和计算方法 在发送方&#xff0c;先把IP数据报首部划分为许多16位字的序列&#xff0c;并把检验和字段置零。用反码算术运算把所有16位字相加后&#xff0c;将得到的和的反码写入检验和字段。接收方收…

Docker安装Redis,并在 Visual Studio Code 中使用它

Docker安装Redis 查找Redis docker search Redis完整结果 PS C:\Users\cheng> docker search Redis NAME DESCRIPTION STARS OFFICIAL redis Redis is an open …

【强化学习-Mode-Free DRL】深度强化学习如何选择合适的算法?DQN、DDPG、A3C等经典算法Mode-Free DRL算法的四个核心改进方向

【强化学习-DRL】深度强化学习如何选择合适的算法&#xff1f; 引言&#xff1a;本文第一节先对DRL的脉络进行简要介绍&#xff0c;引出Mode-Free DRL。第二节对Mode-Free DRL的两种分类进行简要介绍&#xff0c;并对三种经典的DQL算法给出其交叉分类情况&#xff1b;第三节对…

Excel如何设置密码保护【图文详情】

文章目录 前言一、Excel如何设置密码保护&#xff1f;二、Excel如何取消密码保护&#xff1f;总结 前言 在软件项目开发过程中&#xff0c;会输出很多技术文档&#xff0c;其中也包括保密级别很高的服务器账号Excel文档。为了确保服务器账号相关的Excel文档的安全性&#xff0…

超级简单的地图操作工具开发可疑应急,地图画点,画线,画区域,获取地图经纬度等

使用echars的地图画点,画线,画区域,获取地图经纬度等 解压密码:10086007 地图也是用临时的bmap.js和china.js纯离线二选一 一共就这么多文件 画点,画线,画区域 点击地图获取经纬度-打印到控制台,这样就能渲染航迹,多变形,结合其他算法算圆等等操作 下载资源:https://download…

C# OpenCvSharp DNN 黑白老照片上色

C# OpenCvSharp DNN 黑白老照片上色 目录 效果 项目 代码 下载 参考 效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Extensions; using System; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropS…

CVPR2022人脸识别Partial FC论文及代码学习笔记

论文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2022/papers/An_Killing_Two_Birds_With_One_Stone_Efficient_and_Robust_Training_CVPR_2022_paper.pdf 代码链接&#xff1a;insightface/recognition/arcface_torch at master deepinsight/insightface G…

leetcode——链表的中间节点

876. 链表的中间结点 - 力扣&#xff08;LeetCode&#xff09; 链表的中间节点是一个简单的链表OJ。我们要返回中间节点有两种情况&#xff1a;节点数为奇数和节点数是偶数。如果是奇数则直接返回中间节点&#xff0c;如果是偶数则返回第二个中间节点。 这道题的解题思路是&a…