Activiti7工作流引擎:节点动态跳转

news2025/1/11 19:48:15

Activiti7中并没有实现从一个UserTask跳转到另一个UserTask,要实现节点之间自由跳转,需要通过自定义命令来实现。

Activiti7实现主要使用了命令模式(Command)和责任链模式(Intercepter)。

  • 命令模式:主要是将每个操作封装成一个命令。如:
    • DeployCmd:部署操作。
    • CompleteTaskCmd:审批操作。
    • DeleteTaskCmd:删除操作。
    • AddCommentCmd:添加审批意见操作。
  • 责任链模式:每个拦截器AbstractCommandInterceptor有一个next属性指向下一个拦截器。
    • LogIntercepter:第一个拦截器 first
    • SpringTransactionIntercepter:Spring事务拦截器。
    • CommandContextIntercepter:命令上下文拦截器。
    • CommandInvoker:最后一个拦截器,用于执行前面的各种Cmd命令。

一:application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
    username: root
    password: root123
    driver-class-name: com.mysql.cj.jdbc.Driver
## Mybatis 配置
mybatis:
  typeAliasesPackage: com.example.demo.entity
  mapperLocations: classpath:mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true

# 打印mybatis中的sql语句
logging:
    level:
      org.activiti.engine.impl.persistence.entity: debug


activiti:
  #1.flase: 默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
  #2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
  #3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
  #4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
  database-schema-update: true
  #检测历史表是否存在 activiti7默认没有开启数据库历史记录 启动数据库历史记录
  db-history-used: true
  #记录历史等级 可配置的历史级别有none, activity, audit, full
  history-level: full
  #校验流程文件,默认校验resources下的processes文件夹里的流程文件
  check-process-definitions: false

二:bpmn

在这里插入图片描述

<?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:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" 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="m1692856575168" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="leave" isClosed="false" isExecutable="true" name="请假流程" processType="None">
    <startEvent id="start" name="StartEvent"/>
    <userTask activiti:exclusive="true" id="leads" name="组长审批"/>
    <userTask activiti:exclusive="true" id="manager" name="经理审批"/>
    <sequenceFlow id="_5" sourceRef="start" targetRef="leads"/>
    <sequenceFlow id="_6" sourceRef="leads" targetRef="manager"/>
    <exclusiveGateway gatewayDirection="Unspecified" id="_7" name="ExclusiveGateway"/>
    <sequenceFlow id="_8" sourceRef="manager" targetRef="_7"/>
    <userTask activiti:exclusive="true" id="gm" name="总经理审批"/>
    <userTask activiti:exclusive="true" id="dgm" name="副总经理审批"/>
    <sequenceFlow id="_11" sourceRef="_7" targetRef="gm">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[
        ]]>
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_12" sourceRef="_7" targetRef="dgm">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[
        ]]>
      </conditionExpression>
    </sequenceFlow>
    <userTask activiti:exclusive="true" id="hr" name="人事审批"/>
    <sequenceFlow id="_2" sourceRef="gm" targetRef="hr"/>
    <sequenceFlow id="_3" sourceRef="dgm" targetRef="hr"/>
    <endEvent id="end" name="EndEvent"/>
    <sequenceFlow id="_9" sourceRef="hr" targetRef="end"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#3C3F41;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="leave">
      <bpmndi:BPMNShape bpmnElement="start" id="Shape-start">
        <omgdc:Bounds height="32.0" width="32.0" x="60.0" y="160.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="leads" id="Shape-leads">
        <omgdc:Bounds height="55.0" width="85.0" x="170.0" y="150.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="manager" id="Shape-manager">
        <omgdc:Bounds height="55.0" width="85.0" x="315.0" y="150.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_7" id="Shape-_7" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="480.0" y="160.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="gm" id="Shape-gm">
        <omgdc:Bounds height="55.0" width="85.0" x="620.0" y="95.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="dgm" id="Shape-dgm">
        <omgdc:Bounds height="55.0" width="85.0" x="620.0" y="220.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="hr" id="Shape-hr">
        <omgdc:Bounds height="55.0" width="85.0" x="815.0" y="170.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="end" id="Shape-end">
        <omgdc:Bounds height="32.0" width="32.0" x="960.0" y="180.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_12" id="BPMNEdge__12" sourceElement="_7" targetElement="dgm">
        <omgdi:waypoint x="512.0" y="176.0"/>
        <omgdi:waypoint x="620.0" y="247.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_2" id="BPMNEdge__2" sourceElement="gm" targetElement="hr">
        <omgdi:waypoint x="705.0" y="122.5"/>
        <omgdi:waypoint x="815.0" y="197.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_3" id="BPMNEdge__3" sourceElement="dgm" targetElement="hr">
        <omgdi:waypoint x="705.0" y="247.5"/>
        <omgdi:waypoint x="815.0" y="197.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_5" id="BPMNEdge__5" sourceElement="start" targetElement="leads">
        <omgdi:waypoint x="92.0" y="176.0"/>
        <omgdi:waypoint x="170.0" y="177.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_6" id="BPMNEdge__6" sourceElement="leads" targetElement="manager">
        <omgdi:waypoint x="255.0" y="177.5"/>
        <omgdi:waypoint x="315.0" y="177.5"/>
        <bpmndi:BPMNLabel>
          <omgdc: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="manager" targetElement="_7">
        <omgdi:waypoint x="400.0" y="177.5"/>
        <omgdi:waypoint x="480.0" y="176.0"/>
        <bpmndi:BPMNLabel>
          <omgdc: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="hr" targetElement="end">
        <omgdi:waypoint x="900.0" y="197.5"/>
        <omgdi:waypoint x="960.0" y="196.0"/>
        <bpmndi:BPMNLabel>
          <omgdc: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="_7" targetElement="gm">
        <omgdi:waypoint x="512.0" y="176.0"/>
        <omgdi:waypoint x="620.0" y="122.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

三:自定义跳转命令

DynamicJumpCmd

/**
 * 节点动态跳转.
 */
@Slf4j
@AllArgsConstructor
public class DynamicJumpCmd implements Command<Void> {

    /** 流程实例id */
    private String processInstanceId;

    /** 从哪个节点 */
    private String fromActivityId;

    /** 跳转到那个节点 */
    private String toActivityId;


    @Override
    public Void execute(CommandContext commandContext) {
        log.info("node jump: processInstanceId={}, fromActivityId={}, toActivityId={}", processInstanceId, fromActivityId, toActivityId);
        // 0.参数合法性检查
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
        ExecutionEntity executionEntity = executionEntityManager.findById(processInstanceId);
        Assert.isTrue(executionEntity != null, "processInstanceId is not exist");
        BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(executionEntity.getProcessDefinitionId());
        FlowElement fromFlowElement = bpmnModel.getFlowElement(fromActivityId);
        Assert.isTrue(fromFlowElement != null, "fromActivityId is not exist");
        FlowElement toFlowElement = bpmnModel.getFlowElement(toActivityId);

        // 1.找出子执行实例fromActivityId,并删除该执行实例
        List<ExecutionEntity> childList = executionEntityManager.findChildExecutionsByProcessInstanceId(processInstanceId);
        ExecutionEntity currentChildExecutionEntity = null;
        for (ExecutionEntity child : childList) {
            if (child.getCurrentActivityId().equals(fromActivityId)) {
                currentChildExecutionEntity = child;
                break;
            }
        }
        executionEntityManager.deleteExecutionAndRelatedData(currentChildExecutionEntity, "任务动态跳转");

        // 2.创建新的执行实例,并绑定到toActivityId
        ExecutionEntity childExecution = executionEntityManager.createChildExecution(executionEntity);
        childExecution.setCurrentFlowElement(toFlowElement);

        // 执行流程操作
        Context.getAgenda().planContinueProcessOperation(childExecution);
        return null;
    }
}

DynamicJumpService

@Service
public class DynamicJumpService {

    @Autowired
    protected ManagementService managementService;

    public void jumpTask(String processInstanceId, String fromActivityId, String toActivityId) {
        DynamicJumpCmd dynamicJumpCmd = new DynamicJumpCmd(processInstanceId, fromActivityId, toActivityId);
        managementService.executeCommand(dynamicJumpCmd);
    }
}
@RequestMapping("/jump")
public void jump(String processInstanceId, String from, String to) {
    dynamicJumpService.jumpTask(processInstanceId, from, to);
}

@RequestMapping("/complete")
public void complete(String processInstanceId, String assignee) {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    Task task = taskService.createTaskQuery().processDefinitionKey("leave")
            .processInstanceId(processInstanceId)
            .singleResult();

    taskService.setAssignee(task.getId(), assignee);
    taskService.complete(task.getId());
}

四:Test

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • insert into ACT_RU_EXECUTION
  • insert into ACT_RU_TASK
  • update ACT_RU_EXECUTION:更新子执行实例
  • delete from ACT_RU_TASK
  • delete from ACT_RU_EXECUTION

在这里插入图片描述

insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_,IS_EVENT_SCOPE_, IS_MI_ROOT_, PARENT_ID_, SUPER_EXEC_, ROOT_PROC_INST_ID_, SUSPENSION_STATE_, TENANT_ID_, NAME_, START_TIME_, START_USER_ID_, IS_COUNT_ENABLED_, EVT_SUBSCR_COUNT_, TASK_COUNT_, JOB_COUNT_, TIMER_JOB_COUNT_, SUSP_JOB_COUNT_, DEADLETTER_JOB_COUNT_, VAR_COUNT_, ID_LINK_COUNT_, APP_VERSION_) values ( ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
2d360fca-4c7b-11ee-88f4-7221aa3b96b2(String), 0930c9a5-4c79-11ee-88f4-7221aa3b96b2(String), null, leave:1:37059261-4246-11ee-b072-8251588a22ea(String), hr(String), true(Boolean), false(Boolean), false(Boolean), false(Boolean), false(Boolean), 0930c9a5-4c79-11ee-88f4-7221aa3b96b2(String), null, 0930c9a5-4c79-11ee-88f4-7221aa3b96b2(String), 1(Integer), (String), null, 2023-09-06 14:04:01.751(Timestamp), null, false(Boolean), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), null



insert into ACT_RU_TASK (ID_, REV_, NAME_, BUSINESS_KEY_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_, DUE_DATE_, CATEGORY_, SUSPENSION_STATE_, TENANT_ID_, FORM_KEY_, CLAIM_TIME_, APP_VERSION_) values (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
53d7968b-4c7b-11ee-88f4-7221aa3b96b2(String), 人事审批(String), null, null, null, 50(Integer), 2023-09-06 14:05:06.638(Timestamp), null, null, null, 2d360fca-4c7b-11ee-88f4-7221aa3b96b2(String), 0930c9a5-4c79-11ee-88f4-7221aa3b96b2(String), leave:1:37059261-4246-11ee-b072-8251588a22ea(String), hr(String), null, null, 1(Integer), (String), null, null, null

update ACT_RU_EXECUTION set REV_ = 3, ACT_ID_ = ‘manager’  where ID_ = '0932ec86-4c79-11ee-88f4-7221aa3b96b2' and REV_ = 2;

delete from ACT_RU_TASK where ID_ = '0970dfe9-4c79-11ee-88f4-7221aa3b96b2' and REV_ = 1;

delete from ACT_RU_EXECUTION where ID_ = '0932ec86-4c79-11ee-88f4-7221aa3b96b2' and REV_ = 3

在这里插入图片描述

五:继续审批

节点跳转之后继续审批一下,验证节点跳转是否有问题。
在这里插入图片描述

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

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

相关文章

什么是回调函数?写出一个示例?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 回调函数⭐ 示例⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前…

Hadoop Hive入门

0目录 1.linux 安装hive 2.hive入门 3.hive高级语法1 1.linux 安装hive 先确保linux虚拟机中已经安装jdk&#xff1b;mysql和hadoop 并可以成功启动hadoop和mysql 下载hive对应版本到opt/install目录下并解压到opt/soft目录下 重命名 hive312 配置profile 文件&#xff…

结构体的简单介绍(3)——结构体的内存对齐

目录 结构体的内存对齐&#xff1a; 举例&提出疑问&#xff1f; 内存对齐&#xff1a; 对齐规则&#xff1a; 偏移数&#xff1a;类似于数组的下标&#xff0c;指的是结构体每个成员的首个地址距离结构体起始位置的距离。 用结构体内存对齐的图例示范&#xff1a;——…

【开发】安防监控/视频存储/视频汇聚平台EasyCVR优化播放体验的小tips

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、H.265自动转码H.264、平台级联等。为了便于用户二次开发、调用与集成&#xff0c;…

优化SOCKS5的方法

在今天的互联网世界中&#xff0c;保护个人隐私和提升网络速度至关重要。作为一种常用的代理协议&#xff0c;SOCKS5代理服务器不仅可以保护您的隐私&#xff0c;还可以实现更快速的网络访问。本文将为您介绍一些优化SOCKS5代理服务器的方法&#xff0c;以提高网络速度和安全性…

数据结构例题代码及其讲解-递归与树

树 ​ 树的很多题目中都包含递归的思想 递归 递归包括递归边界以及递归式 即&#xff1a;往下递&#xff0c;往上归 递归写法的特点&#xff1a;写起来代码较短&#xff0c;但是时间复杂度较高 01 利用递归求解 n 的阶乘。 int Func(int n) {if (n 0) {return 1;}else …

看涨期权计算例题(期权案例计算)

看涨期权又称认购期权&#xff0c;买进期权&#xff0c;买方期权&#xff0c;买权&#xff0c;延买期权&#xff0c;或“敲进”&#xff0c;是指期权的购买者拥有在期权合约有效期内按执行价格买进一定数量标的物的权利&#xff0c;下文为大家科普看涨期权计算例题&#xff08;…

【Redis】2、Redis持久化

Redis 高可用 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。 但是在Redis语境中&#xff0c;高可用的含义似乎要宽泛一些&#xff0c;除了保证提供…

【数论】容斥问题教程+符号含义+公式(c++)

容斥问题是什么 比如我们平常考试&#xff0c;我们会统计有几个语文及格&#xff0c;有几个数学及格&#xff0c;比如5个语文及格&#xff0c;2个数学及格&#xff0c;当然了&#xff0c;也会有大学霸两科都及格&#xff0c;比如1个人语文数学都及格&#xff0c;那我们班上一共…

React三属性之:state

作用: state是用于在组件中存储数据,称之为"状态机" 类似于vue2中的data属性,不过操作和vue中data差别很大. 使用: this.state的值不能直接进行赋值操作,如:this.state.value_str 修改的值,需要使用this.setState方法 this.setState({修改的key:修改的value},数…

vue Router从入门到精通

文章目录 介绍使用多级路由实例 路由的query参数传递参数接收参数实例 命名路由作用使用 params参数声明接收params参数传参接收参数实例 props配置实例 router-link的replace属性编程式路由导航作用使用实例 缓存路由组件两个新的生命周期钩子实例 路由守卫作用分类全局守卫独…

软件架构设计(四) 基于服务的架构(SOA)

前面我们了解到了层次架构中表示层的架构分层,分为了MVC,MVP,MVVM等架构风格,下面我们了解一下SOA架构与微服务架构。 什么是服务? 服务是一种为了满足某项业务需求的操作,规则等的逻辑组合,它包含了一系列有序活动的交互,为实现用户目标提供支持。 SOA的起源 前面…

车载网络扫盲

目录 车载以太网发展技术 车载网络通信架构与拓扑 车载网络的车载网关 车载网络通信协议 二层确定性以太网协议 二层车载网络扩展协议 三层安全加密协议 四层应用通信协议 车载网络通信架构的网络安全 车载以太网发展技术 车载网络技术包括车载影音娱乐和车载导航需要的MOST&am…

通用的方法在任何云VM上安装Mikrotik的Cloud Hosted Router

文章目录 1. 创建新的Instance&#xff08;Ubuntu或Debian&#xff0c;理论上任何 linux都可以&#xff09;2. 启动&#xff0c;然后将tempfs挂载到/tmp3. 下载镜像4. 写入镜像文件5.强制重启 通用的方法在任何云VM上安装Mikrotik的Cloud Hosted Router 许多云提供商不允许上传…

海康工业相机:MVC软件安装、官方sdk例子、sdk使用手册、

海康工业相机软件安装 首先下载海康的MVC&#xff0c;官方网址&#xff1a;https://www.hikrobotics.com/cn/machinevision/service/download 直接默认安装&#xff0c;一顿点击下一步&#xff0c;就不说了。 界面如下&#xff1a; sdk官方例子 如果你在windows系统是默认…

网络技术五:IP基本原理

IP基本原理 IP的作用 标识节点和链路 用唯一的IP地址标识每一个节点 用唯一的IP网络号标识每一个链路 寻址和转发 确定节点所在网络的位置&#xff0c;进而确定节点所在的位置 IP路由器选择适当的路径将IP包转发到目的节点 适应各种数据链路 根据链路的MTU对IP包进行分片…

【学习笔记】元学习如何解决计算机视觉少样本学习的问题?

目录 1 计算机视觉少样本学习 2 元学习 3 寻找最优初始参数值方法&#xff1a;MAML 3.1 算法步骤 3.2 代码&#xff1a;使用MAML 和 FO-MAML、任务增强完成Few-shot Classification 4 距离度量方法&#xff1a;Siamese Network,ProtoNet,RN 4.1 孪生网络&#xff08;Sia…

不安全的反序列化(phpjava)及漏洞复现

不安全的反序列化 1. 序列化与反序列化 A8:2017-不安全的反序列化 A08:2021-Software and Data Integrity Failures 为什么要序列化&#xff1f; 序列化&#xff0c;将对象的状态信息转换为可以存储或传输的形式的过程&#xff0c;这种形式大多为字节流、字符串、json 串。…

搭建PyTorch神经网络进行气温预测

import numpy as np import pandas as pd import matplotlib.pyplot as plt import torch import torch.optim as optim import warnings warnings.filterwarnings("ignore") %matplotlib inline features pd.read_csv(temps.csv)#看看数据长什么样子 features.he…

React三属性之:refs

作用 refs是为了获取节点,使用场景主要在需要操作dom的时候,比如echarts,就需要真实的dom节点 使用 import React from "react"; class RefsTest extends React.Component{state {value:输入框的值}refPlan React.createRef()logRef ()>{console.log(this.r…