activiti——网关配置

news2024/11/17 19:35:35

文章目录

  • 前言
  • 网关介绍
  • 代码案例测试各项网关
    • 排他网关 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("===========================================");
            });
        }
    }
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

短视频拍摄+直播间搭建视觉艺术实战课:手把手场景演绎 从0-1短视频-8节课

抖音短视频和直播间你是否遇到这些问题? 短视频是用手机拍还是相机拍?画面怎么拍都没有质感 短视频产量低&#xff0c;拍的素材可用率低 看到别人用手机就能把短视频拍好自己却无从下手 明明已经打了好几盏灯了,但是画面还是比较暗 直播软件参数不会设置&#xff0c;电脑…

Git使用(1):介绍、克隆、推送

一、介绍与安装 1、Git是什么&#xff1f; Git是目前世界上最先进的分布式版本控制系统。工作原理 / 流程&#xff1a; workspace&#xff1a;工作区Index / Stage&#xff1a;暂存区Repository&#xff1a;仓库区&#xff08;或本地仓库&#xff09;Remote&#xff1a;远程仓…

3dmax材质库导入方法?3dmax云渲染速度体验

3ds Max 材质库包含多种素材&#xff0c;如金属、木材、布料和石材等&#xff0c;但用户在导入材质时常遇到问题。本文将介绍如何在3ds Max中成功导入材质&#xff0c;并探讨使用云渲染服务来加速渲染过程&#xff0c;提高项目效率。 一、3dmax材质库导入教程 自建材质导入方法…

LLM Agent智能体综述(万字长文)

前言 &#x1f3c6;&#x1f3c6;&#x1f3c6;在上一篇文章中&#xff0c;我们介绍了如何部署MetaGPT到本地&#xff0c;获取OpenAI API Key并配置其开发环境&#xff0c;并通过一个开发小组的多Agent案例感受了智能体的强大&#xff0c;在本文中&#xff0c;我们将对AI Agent…

卷积神经网络CNN的运行过程、常见术语与问题

目录 一、CNN运行过程 1、卷积&#xff08;Convolution&#xff09; 2、激活函数&#xff08;activation function&#xff09; 3、池化&#xff08;pooling&#xff09; 3.1 池化操作 3.2 池化过程 3.3 池化后结果 4、Flatten 5、全连接层 Flatten层的操作 全连接层…

Oracle 流stream将删除的数据保存

Oracle 流stream将删除的数据保存 --实验的目的是捕获hr.employees表的删除行&#xff0c;将删除行插入到emp_del表中。 --设置初始化参数 AQ_TM_PROCESSES1 COMPATIBLE9.2.0 LOG_PARALLELISM1 --查看数据库的名称&#xff0c;我的为ora9,将以下的ora9全部替换为你的数据库名称…

部分树上问题及图的联通性(图论学习总结部分内容)

文章目录 前言三、部分树上问题及图的联通性最小生成树知识点例题 e g 1 : eg1: eg1: 走廊泼水节&#xff08;克鲁斯卡尔思想的灵活运用&#xff09; e g 2 &#xff1a; eg2&#xff1a; eg2&#xff1a; B-Picnic Planning e g 3 eg3 eg3&#xff1a;L - Classic Problem&…

Mybatis入门之在基于Springboot的框架下拿到MySQL中数据

介绍 Java技术操作数据库 MyBatis是一款优秀的持久层框架 用于简化JDBC的开发 优秀的持久层框架 我们要基于Springboot整合Mybatis 实操 学习 基于Mybatis是如何操作数据库的 通过MyBatis书写SQL语句 SQL语句执行完毕后 会将查询结果返回给Java程序 表中数据会自动封装…

灵卡科技HDMI音视频采集及H.264编码一体化采集卡—LCC260

推荐一款由灵卡科技倾力打造的高品质HDMI音视频采集卡——LCC260。以创新的技术&#xff0c;精湛的工艺和卓越的性能&#xff0c;为您提供全方位的音视频解决方案。 LCC260是一款集HDMI音视频采集与H.264编码于一身的全功能采集卡。它的输入端配备了最先进的HDMI 1.4a标准接口&…

Vue实战技巧 —— 企业开发实战中的常见疑难问题

Vue企业开发实战中的常见疑难问题 1. 解决Vue动态路由参数变化&#xff0c;页面数据不更新2. vue组件里定时器销毁问题3. vue实现按需加载组件的两种方式4. 组件之间&#xff0c;父子组件之间的通信方案5. Vue中获取当前父元素&#xff0c;子元素&#xff0c;兄弟元素6. 开发环…

HIVE大数据平台SQL优化分享

相信很多小伙伴在面试的时候&#xff0c;必然跳不过去的一个问题就是SQL脚本的优化&#xff0c;这是很多面试官爱问的问题&#xff0c;也是可以证明你实力进阶的一个重要的能力。 下面给大家分享一个重量级的大数据行业sql技能---hive大数据平台SQL优化。 此文章是大数据平台…

Python中tkinter编程入门4

在Python中tkinter编程入门3-CSDN博客中创建了Button控件&#xff0c;点击该控件就会产生一个点击事件&#xff0c;在创建Button控件时指定该点击事件的处理程序后&#xff0c;按键控件就会对用户的点击事件产生响应。 1 定义事件处理器 定义事件处理器就是一个自定义的函数。…

【UnityRPG游戏制作】Unity_RPG项目_BOSS系统

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;就业…

使用Nginx对网站资源进行加密访问并限制访问IP

你好呀&#xff0c;我是赵兴晨&#xff0c;文科程序员。 大家在工作中有没有遇到过这样的需求&#xff0c;新上的网站部署到生产服务器上&#xff0c;但是还没公开&#xff0c;只允许个别高层领导看。 思来想去&#xff0c;我想到了一个简单的方法&#xff0c;通过Nginx对网站…

【Javaer学习Python】 1、Django安装

安装 Python 和 PyCharm 的方法就略过了&#xff0c;附一个有效激活PyCharm的链接&#xff1a;https://www.quanxiaoha.com/pycharm-pojie/pycharm-pojie-20241.html 1、安装Django # 安装Django pip install Django# 查看当前版本 python -m django --version 5.0.62、创建项…

SpringBoot项目的项目部署全过程

一、前端 安装nginx 1.将提前准备好的nginx的安装包上传到Linux中/opt目录下(我用的是Xftp) 2.解压 2.1:在xshell中解压该文件: tar -zxvf nginx-1.20.1.tar.gz 2.2:进入解压后的目录 cd nginx-1.20.1/ 2.3:安装需要的依赖 yum -y install zlib zlib-devel openssl openssl-de…

如何去掉试卷答案,并打印出来

实际上&#xff0c;针对试卷答案的问题&#xff0c;一个简单而高效的方法是使用图片编辑软件中的“消除笔”功能。只需将试卷拍摄成照片&#xff0c;然后通过这一功能&#xff0c;就可以轻松擦除答案。虽然这种方法可能需要一些时间和耐心&#xff0c;但它确实为我们提供了一个…

Kubernetes 群集部署

一、Kubernetes 概述 1.1、什么是 Kubernetes Kubernetes 是一个可移植、可扩展的开源容器编排系统&#xff0c;主要用于自动化部署、扩展和管理容器应用&#xff0c;提供资源调度、部署管理、服务发现、扩容缩容、监控等功能。对于负载均衡、服务发现、高可用、滚动升级、自…

【智能算法】河马优化算法(HO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;MH Amiri受到自然界河马社会行为启发&#xff0c;提出了河马优化算法&#xff08;Hippopotamus Optimization Algorithm, HO&#xff09;。 2.算法原理 2.1算法思想 …

《无畏契约》游戏画面出现“撕裂感“,你清楚背后的原理吗?

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …