Activiti7

news2024/11/16 18:31:32

文章目录

  • Activiti官网
  • 一、BPM
  • 二、BPM软件
  • 三、BPMN
  • 四、Activiti使用步骤
    • 1、部署activiti
    • 2、流程定义
    • 3、流程定义部署
    • 4、启动一个流程实例
    • 5、用户查询待办任务(Task)
    • 6、用户办理任务
    • 7、流程结束
  • 五、Activiti环境准备
    • 1、下载扩展程序camunda-modeler
    • 2、配置idea扩展程序:
  • 六、Activiti数据库支持
    • 1、Activiti支持的数据库
    • 2、MySQL生成表
      • 1)创建数据库activiti
      • 2)pom依赖
      • 3)log4j.properties
      • 4)activiti.cfg.xml
      • 5)生成Activiti表
    • 3、表结构认识
  • 七、Activiti使用入门案例
    • 1、创建流程定义
    • 2、部署流程定义
      • 1)方式1——文件上传
      • 2)方 式2——压缩文件上传
    • 3、启动流程实例
    • 4、查询任务
    • 5、流程任务处理
    • 6、流程是心查询
    • 7、删除流程
    • 8、流程资源下载
    • 9、流程历史信息查看
  • 八、Activiti进阶
    • 1、 流程定义与流程实例定义
      • 1)启动流程实例时添加Businesskey
      • 2)挂起流程&激活流程
    • 2、流程变量
      • 1) 流程变量的作用域
      • 2)使用流程变量
      • 3)设置全局Global流程变量
        • ①启动流程时设置变量
        • ②任务办理时设置变量
        • ③通过当前流程实例设置变量
        • ④通过当前任务设置变量
      • 4)设置Local流程变量
    • 3、网关
      • 1) 排他网关ExclusiveGateway
      • 2) 并行网关ParallelGateway
      • 3) 包含网关InclusiveGateway
      • 4) 事件网关EventGatway
    • 4、个人任务管理
    • 5、组任务分配
      • 1)设置多个候选人
      • 2)组任务办理流程
  • 九、Activiti与Spring整合
  • 十、Activiti7与SpringBoot整合
    • 1、pom
    • 2、application.yml
    • 3、启动类
    • 4、SpringSecurityConfig
    • 5、工具类


Activiti官网

一、BPM

BPM(Business Process Management),即业务流程管理,是一种规范化的构造端到端的业务流程,以持续的提高组织业务效率。常见商业管理教育如EMBA、MBA等均将BPM包含在内。

二、BPM软件

BPM软件就是根据企业中业务环境的变化,推进人与人之间、人与系统之间以及系统与系统之间的整合及调整的经营方法与解决方案的IT工具。
通过BPM软件对企业内部及外部的业务流程的整个生命周期进行建模、自动化、管理监控和优化,使企业成本降低,利润得以大幅提升。
BPM软件在企业中应用领域广泛,凡是有业务流程的地方都可以BPM软件进行管理,比如企业人事办公管理、采购流程管理、公文审批流程管理、财务管理等。

三、BPMN

BPMN(BusinessProcessModelAndNotation)-业务流程模型和符号是由BPMI(BusinessProcess ManagementInitiative)开发的一套标准的业务流程建模符号,使用BPMN提供的符号可以创建业务流程。

2004年5日发布了BPMN1.0规范.BPMI于2005年9月并入OMG(The Obiect Management Groun对象管理组织
组织。OMG于2011年1月发布BPMN2.0的最终版本。

BPMN 是目前被各 BPM 厂商广泛接受的 BPM 标准。Activiti 就是使用 BPMN 2.0 进行流程建模、流程执行管理。它包括很多的建模符号,比如:
Event用一个圆圈表示,它是流程中运行过程中发生的事情。
流程开始,流程结束。。。
在这里插入图片描述
活动用圆角矩形表示,一个流程由一个活动或多个活动组成
在这里插入图片描述

四、Activiti使用步骤

1、部署activiti

Activiti是一个工作流引擎(其实就是一堆jar包API),业务系统访问(操作)activiti的接口,就可以方便的操作流程相关数据,这样就可以把工作流环境与业务系统的环境集成在一起。

2、流程定义

使用activiti流程建模工具(activity-designer)定义业务流程(.bpmn文件)。
.bpmn文件就是业务流程定义文件,通过xml定义业务流程。

3、流程定义部署

activiti部署业务流程定义(.bpmn文件)。
使用activiti提供的api把流程定义内容存储起来,在Activiti执行过程中可以查询定义的内容
Activiti执行把流程定义内容存储在数据库中。

4、启动一个流程实例

流程实例也叫:Processlnstance
启动一个流程实例表示开始一次业务流程的运行。
在员工请假流程定义部署完成后,如果张三要请假就可以启动一个流程实例,如果李四要请假也启动一个流程实例,两个流程执行相互不影响。

5、用户查询待办任务(Task)

因为现在系统的业务流程已经交给activiti管理,通过activiti就可以查询当前流程执行到哪了,当前用户需要办理什么任务了,这些activiti帮我们管理了,而不需要开发人员自己编写在sql语句查询。

6、用户办理任务

用户查询待办任务后,就可以办理某个任务,如果这个任务办理完成还需要其它用户办理,比如采购单创建后由部门经理审核,这个过程也是由activiti帮我们完成了。

7、流程结束

当任务办理完成没有下一个任务结点了,这个流程实例就完成了。

五、Activiti环境准备

1、下载扩展程序camunda-modeler

官网下载地址:camunda官网
github下载地址:github下载

2、配置idea扩展程序:

在这里插入图片描述

然后就可以右键bpmn文件, 选择扩展
在这里插入图片描述
在这里插入图片描述

六、Activiti数据库支持

Activiti在运行时需要数据库的支持,使用25张表,把流程定义节点内容读取到数据库表中,以供后续使用。

1、Activiti支持的数据库

在这里插入图片描述

2、MySQL生成表

1)创建数据库activiti

2)pom依赖

2)activiti 依赖的jar 包:mybatis、alf4j、log4j等
3) activiti 依赖的 spring 包
4) mysgl数据库驱动
5) 第三方数据连接池 dbcp
6) 单元测试 Junit-4.12.jar

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>7.1.0.M6</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring</artifactId>
            <version>7.1.0.M6</version>
        </dependency>
        <!-- bpmn-model -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-model</artifactId>
            <version>7.1.0.M6</version>
        </dependency>
        <!--bpmn-converter -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-converter</artifactId>
            <version>7.1.0.M6</version>
        </dependency>
        <!-- activiti-json-converter -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>7.1.0.M6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.activiti/activiti-bpmn-layout -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-layout</artifactId>
            <version>7.1.0.M6</version>
        </dependency>
        <dependency>
            <groupId>org.activiti.cloud</groupId>
            <artifactId>activiti-cloud-services-api</artifactId>
            <version>7-201802-EA</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version></version>
        </dependency>
        <dependency>
            <groupId>commons</groupId>
            <artifactId>commons-uo</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>4.12</version>
        </dependency>
         <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>org.slf4j-log4j12</artifactId>
            <version>4.12</version>
        </dependency>

3)log4j.properties

在这里插入图片描述

4)activiti.cfg.xml

在这里插入图片描述

5)生成Activiti表

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

3、表结构认识

七、Activiti使用入门案例

1、创建流程定义

2、部署流程定义

1)方式1——文件上传

在这里插入图片描述
查看部署成功后数据库表数据

2)方 式2——压缩文件上传

在这里插入图片描述

3、启动流程实例

在这里插入图片描述

4、查询任务

5、流程任务处理

在这里插入图片描述

6、流程是心查询

7、删除流程

8、流程资源下载

9、流程历史信息查看

八、Activiti进阶

1、 流程定义与流程实例定义

流程定义 ProcessDefinition 和流程实例 ProcessInstance是Activiti中非常重要的两个概念。他们的关系其实类似于JAVA中类和对象的概念。

流程定义ProcessDefinition是以BPMN文件定义的一个工作流程,是一组工作规范。例如我们之前定义的请假流程。流程实例ProcessInstance则是指一个具体的业务流程。例如某个员工发起一次请假,就会实例化一个请假的流程实例,并且每个不同的流程实例之间是互不影响的。

在后台的表结构中,有很多张表都包含了流程定义ProcessDefinetion和流程实例Processlnstance的字段。流程定义的字段通常是PROC DEF ID,而流程实例的字段通常是PROC INST ID。

1)启动流程实例时添加Businesskey

在之前的简单案例中,我们启动一个流程实例的关键代码其实就是这一行。

ProcessInstance processInstance = runtimeService.startProcessInstanceByKev("mvLeave");

当我们去查看下startProcessInstanceByKey这个方法时,会看到这个方法有好几个重载的实现方法,可以传一些不同的参数。其中几个重要的参数包括

· String processDefinitionKey:流程定义的唯一键 不能为空
·String businessKey:每个线程实例上下文中关联的唯一键。这个也是我们这一章节要介绍的重点。
·Map<String,Object> variables:在线程实例中传递的流程变量。这个流程变量可以在整个流程实例中使用,后面会介绍
到。
·String tenantld:租户ID,这是Activiti的多租户设计。相当于每个租户可以上来获取一个相对独立的运行环境

这一章节我们来介绍这个businessKey,业务关键字。这是Activiti提供的一个非常重要的便利,用来将activiti的工作流程与实际业务进行关联。

例如,当我们需要对一个业务订单进行审批时,订单的详细信息并不在activiti的数据当中,但是在审批时确实需要查看这些
订单的详细信息。这个时候,就可以用这个businessKey来关联订单ID,这样在业务系统中,就可以通过这个订单ID去关联订单详细信息,审批人员就可以快速拿来进行参考。

进行实际业务整合时,这个businessKey可以根据业务场景,设计成不同的数据格式,比如关键信息逗号拼接,甚至是json都
可以,唯一需要注意的是这个字段的数据库长度设计是255,不要超出了数据库的长度限制

接下来,我们看看如何在流程实例执行过程中获取这个业务关键字:

@Test
public void queryProcessInstance(){
// 流程定义key
String frocessDefinitionKey = "myLeave";
ProcessEngine processEngine =ProcessEnqines.qetDefaultProcessEnqine();
// 获取RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
List<ProcessInstance> list = runtimeService
.createProcessInstanceQuery()
.processDefinitionKey(processDefinitionKey)//
.list();

for (ProcessInstance processInstance :list){
System.out.println("------ ---------"); 
System.out.println("流程实例id:"
+ processInstance.qetProcessInstanceId());
System.out.println("所属流程定义id:"
+ processInstance.qetProcessDefinitionId());
System.out.println("是否执行完成:"+ processInstance.isEnded()):
System.out.println("是否暂停:"+ processInstance.isSuspended());
System.out.println("当前活动标识:"+ processInstance.getActivityId());
System.out.println("业务关键字:"+processInstance.getBusinessKey());

2)挂起流程&激活流程

挂起、激活流程实例
之前我们已经测试了如何删除一个流程,有很多时候,我们只是需要暂时停止一个流程,过一段时间就要恢复。例如月底
不接受报销审批流程,年底不接受借贷审批流程,或者非工作日不接受售后报销流程等,这个时候,就可以将流程进行挂起握
作。挂起后的流程就不会再继续执行。
在挂起流程时,有两种操作方式。

一种是将整个流程定义Process Definition挂起,这样,这个流程定义下的所有流程实例都将挂起,无法继续执行

2、流程变量

流程变量也是Activiti中非常重要的角色。我们之前定义的请假流程并没有用到流程变量,每个步骤都是非常固定的,但是,当我们需要实现一些复杂的业务流程,比如请假3天以内由部门经理审批,3天以上需要增加总经理审批这样的流程时,就需要用到流程变量了。

注:这个流程变量和之前介绍的业务关键字其实是有些相似的,都可以携带业务信息。并且也都可以通过activiti
的ani查询出来,但是通常在使用过程中,应该尽量减少流程变量中的业务信息,这样能够减少业务代码对activit
工作流的代码侵入。
在上一章节介绍到,流程变量的类型是Map<String,Object>。所以,流程变量比业务关键字要强大很多。变量值不仅仅是字
符串,也可以是POJO对象。但是当需要将一个POJO对象放入流程变量时,要注意这个对象必须要实现序列化接口
serializable。

1) 流程变量的作用域

变量的作用域可以设置为Global和Local两种。

·Global变量
这个是流程变量的默认作用域,表示是一个完整的流程实例。 Global变量中变量名不能重复。如果设置了相同的变量名,后面设置的值会直接覆盖前面设置的变量值。
· Local变量
Local变量的作用域只针对一个任务或一个执行实例的范围,没有流程实例大。Local变量由于作用在不同的任务或不同的执行实例中,所以不同变量的作用域是互不影响的,变量名可以相同。Local变量名也可以和Global变量名相同,不会有影响。

2)使用流程变量

定义好流程变量后,就可以在整个流程定义中使用这些流程变量了。例如可以在某些任务属性如assignee上使用 a s s i g n e e ,或者在某些连线上使用 {assignee},或者在某些连线上使用 assignee,或者在某些连线上使用{day<3}。

Activiti中可以使用UEL表达式来使用这些流程变量。UEL表达式可以直接获取一个变量的值,可以计算一个Boolean结果的表达式,还可以直接使用某些对象的属性。例如对干之前创建的请假流程,如果要实现3天以内部门经理审核,3天以上增加总经理审核,可以做如下调整:
在这里插入图片描述

3)设置全局Global流程变量

①启动流程时设置变量

②任务办理时设置变量

③通过当前流程实例设置变量

④通过当前任务设置变量

4)设置Local流程变量

3、网关

网关是用来控制流程流向的重要组件,通常都会要结合流程变量来使用。

1) 排他网关ExclusiveGateway

排他网关,用来在流程中实现决策。 当流程执行到这个网关,所有分支都会判断条件是否为true,如果为true则执行该分支,

注意:排他网关只会选择一个为true的分支执行。如果有两个分支条件都为true,排他网关会选择id值较小的一条
分支去执行。
为什么要用排他网关?

不用排他网关也可以实现分支,如:在连线的condition条件上设置分支条件。

在连线设置condition条件的缺点:如果条件都不满足,流程就结束了(是异常结束)。

如果 使用排他网关决定分支的走向,如下:

2) 并行网关ParallelGateway

3) 包含网关InclusiveGateway

4) 事件网关EventGatway

4、个人任务管理

在之前的简单示例中,我们已经可以通过配置Assignee属性来指定任务的负责人。但是我们之前的示例中,是简单的配置为 worker、manager、finacer等这样的固定的任务人。但是在实际工作中,往往不会是这样固定的人。可能是对应某个职位或者某个角色的系统用户。这时,这种固定分配的方式就非常不灵活了。这时,就可以使用UEL表达式配合流程变量来灵活指定。例如这样:

5、组任务分配

1)设置多个候选人

2)组任务办理流程

九、Activiti与Spring整合

十、Activiti7与SpringBoot整合

1、pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>Camunda1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Camunda1</name>
    <description>Camunda1</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.15</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter</artifactId>
            <version>7.1.0.M6</version>
        </dependency>
        <!--   springSecurity 依赖   -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2、application.yml

server:
  port: 7001
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/camunda?useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
      username: root
      password: 123456
  activiti:
    database-schema-update: true
    db-history-used: true
    history-level: full
    check-process-definitions: false
    async-executor-activate: true
#  mvc:
#    pathmatch:
#      matching-strategy: ant_path_matcher
#  main:
#    allow-bean-definition-overriding: true
mybatis:
  mapper-locations: classpath*:mappers/*.xml


logging:
  level:
    root: info
    com.example.emos.wx.db.dao : warn
  pattern:
    console: "%d{HH:mm:ss} %-5level %msg%n"

3、启动类

@SpringBootApplication(exclude = {org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class})
public class Camunda1Application {
    
    public static void main(String[] args) {
        SpringApplication.run(Camunda1Application.class, args);
    }
}

4、SpringSecurityConfig

@Configuration
public class SpringSecurityConfig
        extends WebSecurityConfigurerAdapter
{}

5、工具类

package com.example.camunda1;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

@Slf4j
@RestController
public class TestController {
    @Autowired
    RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;
    /**
     * 部署
     * @param file  ZIP压缩包文件
     * @param processName   流程名称
     * @return 流程部署ID
     */
    @PostMapping("/upload")
    public String upload(@RequestParam("zipFile") MultipartFile file,
                         @RequestParam("processName") String processName) {
        String originalFilename = file.getOriginalFilename();
        if (!originalFilename.endsWith("zip")) {
            return "文件格式错误";
        }
        ProcessDefinition processDefinition = null;
        try {
            ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream());
            Deployment deployment = repositoryService.createDeployment()
                    .addZipInputStream(zipInputStream).name(processName).deploy();

            processDefinition = repositoryService.createProcessDefinitionQuery()
                    .deploymentId(deployment.getId()).singleResult();

            log.info("流程部署ID:"+deployment.getId());
            log.info("流程部署Name:"+deployment.getName());
            log.error("=================================");
        } catch (IOException e) {
            log.error("流程部署失败!原因: {}", e.getMessage(), e);
        }
        return "id="+processDefinition.getDeploymentId();
    }

    /**
     * 查看流程图
     * @param deploymentId  部署ID
     * @param resourceName  图片名称
     * @param response
     * @return
     */
    @GetMapping("/getDiagram")
    public void getDiagram(@RequestParam("deploymentId") String deploymentId, @RequestParam("resourceName") String resourceName, HttpServletResponse response) {
        InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, resourceName);
//        response.setContentType(MediaType.IMAGE_PNG_VALUE);
        try {
            IOUtils.copy(inputStream, response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    /**
     * 查询流程部署列表
     */
    @GetMapping("/listDeployments")
    public List<Deployment> listDeployments() {
        List<Deployment> deployments = this.repositoryService.createDeploymentQuery().list();
        if (!deployments.isEmpty()) {
            deployments.forEach(deployment -> {
                System.out.println("流程部署Id:" + deployment.getId());
                System.out.println("流程部署Name:" + deployment.getName());
                System.out.println("流程部署DeploymentTime:" + deployment.getDeploymentTime());
                System.out.println("流程部署Key:" + deployment.getKey());
            });
        }
        return deployments;
    }


    /**
     * 查询流程定义列表
     */
    @GetMapping("/listProcessDefinitions")
    public List<ProcessDefinition> listProcessDefinitions() {
        List<ProcessDefinition> processDefinitions = this.repositoryService.createProcessDefinitionQuery()
                .list();
        if (!CollectionUtils.isEmpty(processDefinitions)) {
            processDefinitions.forEach(processDefinition -> {
                System.out.println("流程部署Id:" + processDefinition.getDeploymentId());
                System.out.println("流程定义Id:" + processDefinition.getId());
                System.out.println("流程定义Name:" + processDefinition.getName());
                System.out.println("流程定义Key:" + processDefinition.getKey());
                System.out.println("流程定义ResourceName:" + processDefinition.getResourceName());
                System.out.println("流程定义DeploymentId:" + processDefinition.getDeploymentId());
                System.out.println("流程定义Version:" + processDefinition.getVersion());
            });
        }
        return processDefinitions;
    }
    /**
     * 初始化流程实例 
     * processDefinitionKey流程定义KEY  "process_money"
     * businessKey业务表KEY(用于把业务数据与Activiti7流程数据相关联)
     */
    @GetMapping("/initProcessInstance")
    public void initProcessInstance(String processDefinitionKey, String businessKey,Map<String, Object> variables) {
        ProcessInstance processInstance = this.runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
    }
    /**
     * 通过UserId查找该用户发起的流程实例。
     */
    @GetMapping("/findTasksByUserId")
    public void findTasksByUserId(String userId) {
//        String userId ="zhangsan";
        List<Task> resultTask = taskService.createTaskQuery().taskCandidateOrAssigned(userId).list();
        System.out.println("任务列表:"+resultTask);
        // 任务列表里面。创建一个查询。通过流程id,获取指定类型的流程。
        Task task = resultTask.get(0);
        String processInstanceId = task.getProcessInstanceId();

        log.info("流程实例ID:"+task.getId());
        log.info("流程实例assignee:"+task.getAssignee());
        log.info("流程实例Name:"+task.getName());
        log.info("流程实例ExecutionId:"+task.getExecutionId());
        System.out.println("流程实例Id:"+processInstanceId);
    }

    /**
     * 根据流程实例ID查询流程实例
     * processInstanceId:流程实例ID
     */
    @GetMapping("getProcessInstance")
    public void getProcessInstance(String processInstanceId) {
//        String processInstanceId = "865523bc-bd85-11ed-b94e-005056c00008";
        ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        System.out.println("ProcessInstanceId:" + processInstance.getProcessInstanceId());
        System.out.println("ProcessDefinitionId:" + processInstance.getProcessDefinitionId());
        System.out.println("isEnded:" + processInstance.isEnded());
        System.out.println("isSuspended:" + processInstance.isSuspended());
        Map<String, Object> variables2 = processInstance.getProcessVariables();
        log.info(variables2.toString());
    }

    /**
     * 查询流程实例列表
     */
    @GetMapping("/listProcessInstances")
    public void listProcessInstances() {
        List<ProcessInstance> processInstanceList = this.runtimeService.createProcessInstanceQuery().list();
        if (!CollectionUtils.isEmpty(processInstanceList)) {
            processInstanceList.forEach(processInstance -> {
                System.out.println("ProcessInstanceId:" + processInstance.getProcessInstanceId());
                System.out.println("ProcessDefinitionId:" + processInstance.getProcessDefinitionId());
                System.out.println("isEnded:" + processInstance.isEnded());
                System.out.println("isSuspended:" + processInstance.isSuspended());
            });
        }
    }

    /**
     * 删除流程实例
     * reason:删除原因
     * processInstanceId:实例ID
     */
    public void deleteProcessInstance(String processInstanceId,String reason) {
        this.runtimeService.deleteProcessInstance(processInstanceId, reason);
    }
    /**
     * 查询所有任务列表
     */
    @GetMapping("/listTasks")
    public void listTasks() {
        List<Task> taskList = this.taskService.createTaskQuery().list();
        if (!CollectionUtils.isEmpty(taskList)) {
            taskList.forEach(task -> {
                System.out.println("Id:" + task.getId());
                System.out.println("Name:" + task.getName());
                System.out.println("Assignee:" + task.getAssignee());
                Object b = (Object) taskService.getVariable(task.getId(),"请假信息");
                log.info("a");
            });
        }
    }

    /**
     * 根据当前用户名查询代办任务
     */
    @GetMapping("/listTasksByAssignee")
    public void listTasksByAssignee(String assignee) {
        List<Task> taskList = this.taskService.createTaskQuery()
                .taskAssignee(assignee)
                .list();
        if (!CollectionUtils.isEmpty(taskList)) {
            taskList.forEach(task -> {
                System.out.println("Id:" + task.getId());
                System.out.println("Name:" + task.getName());
                System.out.println("Assignee:" + task.getAssignee());
                System.out.println("InstanceId:" + task.getProcessInstanceId());
                System.out.println("DefinitionId:" + task.getProcessDefinitionId());
            });
        }
    }

    /**
     * 完成任务
     */
    @GetMapping("/completeTask")
    public void completeTask(String taskId) {
//        String taskId = "354b9d90-477f-11ed-abfa-e4a8dfd43d4a";
        Map<String, Object> variables = new HashMap<>(16);
        this.taskService.complete(taskId, variables);
    }

}


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

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

相关文章

[2.2.2]进程调度的时机、方式、切换与过程

文章目录第二章 进程管理进程调度的时机、方式、切换与过程&#xff08;一&#xff09;进程调度的时机&#xff08;二&#xff09;进程调度的方式&#xff08;三&#xff09;进程的切换与过程小结第二章 进程管理 进程调度的时机、方式、切换与过程 时机 什么时候需要进程调度…

在 KubeSphere 中开启新一代云原生数仓 Databend

作者&#xff1a;尚卓燃&#xff08;https://github.com/PsiACE&#xff09;&#xff0c;Databend 研发工程师&#xff0c;Apache OpenDAL (Incubating) PPMC。 前言 Databend 是一款完全面向云对象存储的新一代云原生数据仓库&#xff0c;专为弹性和高效设计&#xff0c;为您…

导入你的 ST 项目到 Visual Studio

去年我们官宣了 Visual Studio Code 可以直接导入 ST 项目&#xff0c;今天再次宣布&#xff1a;它的好兄弟 Visual Studio 2022 17.6 也支持此功能&#xff0c;详细请看下文。 在 ARM 微控制器领域&#xff0c;有许多芯片供应商&#xff0c;其中最大的是意法半导体(ST)。ST 拥…

【冲刺蓝桥杯的最后30天】day6

大家好&#x1f603;&#xff0c;我是想要慢慢变得优秀的向阳&#x1f31e;同学&#x1f468;‍&#x1f4bb;&#xff0c;断更了整整一年&#xff0c;又开始恢复CSDN更新&#xff0c;从今天开始更新备战蓝桥30天系列&#xff0c;一共30天&#xff0c;如果对你有帮助或者正在备…

【魅力开源】第9集:管理者的大局观:企业数字化转型的能力逆向规划设计模型

文章目录前言一、背景&#xff1a;数字化转型机遇与挑战1.1 国家层面&#xff1a;数字化转型的背后代表的是“国家意志”1.2 企业层面&#xff1a;积极拥抱数字化转型&#xff0c;抢占的是“红利先机”1.3 个人层面&#xff1a;全民数字化时代到来&#xff0c;最为炙手可热的当…

CPDA|如何证明你的数据分析能力?

数据分析能力是一个很重要的能力&#xff0c;那么如何去证明这个能力呢&#xff1f; 一般来说&#xff0c;证明你的数据分析能力需要以实际的数据分析项目和成果为基础&#xff0c;可以从以下几个方面来证明&#xff1a; 项目经历&#xff1a;列举你参与的数据分析项目&#x…

Easy Deep Learning——PyTorch中的自动微分

目录 什么是深度学习&#xff1f;它的实现原理是怎么样的呢&#xff1f; 什么是梯度下降&#xff1f;梯度下降是怎么计算出最优解的&#xff1f; 什么是导数&#xff1f;求导对于深度学习来说有何意义&#xff1f; PyTorch 自动微分&#xff08;自动求导&#xff09; 为什么…

分享一个 hive on spark 模式下使用 HikariCP 数据库连接池造成的资源泄露问题

最近在针对某系统进行性能优化时&#xff0c;发现了一个hive on spark 模式下使用 HikariCP 数据库连接池造成的资源泄露问题&#xff0c;该问题具有普适性&#xff0c;故特地拿出来跟大家分享下。 1 问题描述 在微服务中&#xff0c;我们普遍会使用各种数据库连接池技术以加快…

二叉树,二叉搜索树相关模板

目录1.先序遍历2.中序遍历3.后序遍历4.层序遍历(可用于需按层进行计算的题目)5.判定二叉树的对称性6.二叉树最大深度&#xff08;结点深度&#xff1a;根节点到该结点。结点高度&#xff1a;该结点到叶子结点&#xff09;7.二叉树最小深度8.二叉树的平衡性9.求左叶子的和10.通过…

ArcGIS制图技巧:制图入门与点、线、面状符号制作

目的&#xff1a; 1、了解地图制作目的&#xff1b; 2、了解在ArcMap平台中制作地图大致过程。 3、掌握地形图生成的操作&#xff1b; 4、掌握地形图的正确输出方法。 5、理解点状符号、线状符号、面状符号的基本概念&#xff1b; 6、理解地形点状符号、线状符号、面状符…

从大专到测开,上海某字母站大厂的面试题,岗位是测开(25K*16)

简单介绍一句&#xff0c;大专出身&#xff0c;三年经验。跳了四次槽&#xff0c;面试了无数次&#xff0c;现在把自己的面试经验整理出来分享给大家&#xff0c;堪称必杀技&#xff01; 1&#xff0c;一切从实际出发&#xff0c;对实际工作进行适当修饰 2&#xff0c;不会的简…

【晓龙oba出品 - 黑科技解题系列】- 最小操作次数使数组元素相等

思路 算法归根到底就是找规律的游戏&#xff0c;我们首先来看一个现象&#xff1a; 以数组nums [1,2,3,4,5]为例 当我们将数组排序后&#xff0c;可以知道最小值为1,最大值为5&#xff0c;此时我们需要四次运算可以使最小值与最大值相等&#xff1a; 第一次&#xff1a;2,3,4,…

HNU-电子测试平台与工具2-数模转换

数模转换实验 计科XXXX wolf 工程文件我也一并上传了 D级任务 一.实验任务 对74194进行仿真验证&#xff0c;掌握Quartus仿真的基本原则和常规步骤&#xff0c;记录移位寄存器的数据读写&#xff0c;并描述仿真波形&#xff0c;分析结果。 二.实验过程 1.电路连接 2.功能…

Go 实现多态和 参数的动态个数及动态类型

引子 go语言作为静态(编译期类型检测)强类型(手写代码进行类型转换)语言, 要想实现 动态语言的鸭子类型的调用方法,做到 一个入参是不同类型,还是有些麻烦的; 需求 希望写代码时像python一样的鸭子类型,不用管参数类型,都可以调用同一个方法;希望 入参像python一样 能够在 个…

Kalman Filter in SLAM (1) ——Data Fusion and Kalman Filter(数据融合和卡尔曼滤波)

文章目录0. 参考资料1. Intro Example 例子引入1.1. 测量硬币直径1.2. 思考2. Data Fusion 数据融合2.1. 数据融合在做什么&#xff1f;2.2. 数据融合的前提——不确定度2.3. 数据融合的结果——统计意义下的最优估计3. State Space Representation 状态空间表达式3.1. 状态方程…

大数据 | (二)SSH连接报错Permission denied

大数据 | &#xff08;三&#xff09;centos7图形界面无法执行yum命令&#xff1a;centos7图形界面无法执行yum命令 哈喽&#xff01;各位CSDN的朋友们大家好&#xff01; 今天在执行Hadoop伪分布式安装时&#xff0c;遇到了一个问题&#xff0c;在此跟大家分享&#xff0c; …

ThreadLocal的内部结构和源码探究

目录一. ThreadLocal的内部结构1 常见的误解2 现在的设计3 这样设计的好处二. ThreadLocal的核心方法源码1 set方法2 get方法3 remove方法**4 initialValue方法**三. ThreadLocalMap源码分析1 基本结构2 弱引用和内存泄漏3 hash冲突的解决一. ThreadLocal的内部结构 ​ 通过之…

【C++知识点】STL 容器总结

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;C/C知识点 &#x1f4e3;专栏定位&#xff1a;整理一下 C 相关的知识点&#xff0c;供大家学习参考~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;…

2月榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩平台)发布!

飞瓜轻数发布2023年2月飞瓜数据UP主排行榜&#xff08;B站平台&#xff09;&#xff0c;通过充电数、涨粉数、成长指数三个维度来体现UP主账号成长的情况&#xff0c;为用户提供B站号综合价值的数据参考&#xff0c;根据UP主成长情况用户能够快速找到运营能力强的B站UP主。飞瓜…

(蓝桥真题)剪格子(搜索+剪枝)

样例1输入&#xff1a; 3 3 10 1 52 20 30 1 1 2 3 样例1输出&#xff1a; 3 样例2输入&#xff1a; 4 3 1 1 1 1 1 30 80 2 1 1 1 100 样例2输出&#xff1a; 10 分析&#xff1a;这道题目我们直接从(1,1)点开始进行dfs搜索即可&#xff0c;但是需要注意一点的是我们搜…