Activity整合springboot基本使用

工作流的实现需要使用工作流引擎,工作流引擎是一种软件系统,它可以自动化地处理和管理工作流中的各个环节,包括流程定义、流程执行、流程控制和流程监控等多个方面。

1. 基本介绍

Activiti是一个基于Java语言开发的业务流程管理(BPM)框架。

它具有轻量级、高度可伸缩的工作流引擎,可快速构建出复杂的流程系统。

Activiti支持BPMN2.0规范,可以与Spring和Spring Boot等主流框架集成。

2. 特点

  • 开源免费:Activiti是一款完全开源的工作流引擎,可以免费使用和修改。
  • 轻量级:Activiti采用轻量级的设计,具有快速启动和低资源消耗的优势。
  • 易于使用:Activiti提供了丰富的API和工具,可以帮助开发人员快速构建各种类型的工作流应用,同时也提供了友好的图形化界面,方便用户进行流程设计和管理。
  • 高度可扩展性:Activiti采用模块化的设计,支持各种类型的扩展和定制化开发。
  • 高度可靠性:Activiti采用基于Java的技术栈,具有高度可靠性和稳定性。

3. BPM

BPM(Business Process Management,业务流程管理)一种管理模式。

用于对流程进行建模、执行、监控和优化调整。

3.1 BPM的几个只要环节:

  • 流程设计:通过各种工具建模,将业务流程具体化并规范化。

  • 流程执行:将规范化后的流程应用到实际业务过程中,通过员工的协作实现任务的分配、执行和监控。

  • 流程控制:对流程执行过程的异常情况进行处理,并进行适时的调整。

  • 流程优化:通过对流程的数据分析和评估,对流程进行优化和改善。

3.2 优点

规范化流程

优化流程

加强协作

提升效率等

4.BPMN

4.1 基本介绍

BPMN(Business Process Model and Notation)一种业务流程建模和表示标准

BPMN采用图形化符号表示业务流程中的各个环节和元素,包括流程图、活动、事件、网关、连接对象等,来更加清晰、准确地描述和管理业务流程。

4.2 特点

标准化:BPMN是一种标准化的流程建模标准,可以帮助企业建立统一的流程建模和管理方法。

易于理解:BPMN采用图形化符号表示业务流程中的各个元素,易于理解和沟通。

可扩展性:BPMN提供了多种扩展机制,可以根据实际需求进行扩展和定制化开发。

可重用性:BPMN提供了多种建模元素和模板,可以帮助企业实现流程的重用和复用。

易于集成:BPMN可以集成到各种流程引擎和系统中,实现自动化流程管理和执行。


activiti数据库表

Activiti 的表都以 ACT_ 开头

ACT_RE :'RE’表示 repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。 ACT_RU:'RU’表示 runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti 只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。

ACT_HI:'HI’表示 history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。

ACT_GE : GE 表示 general。 通用数据, 用于不同场景下

Activiti数据表介绍
表分类表名解释
一般数据
[ACT_GE_BYTEARRAY]通用的流程定义和流程资源
[ACT_GE_PROPERTY]系统相关属性
流程历史记录
[ACT_HI_ACTINST]历史的流程实例
[ACT_HI_ATTACHMENT]历史的流程附件
[ACT_HI_COMMENT]历史的说明性信息
[ACT_HI_DETAIL]历史的流程运行中的细节信息
[ACT_HI_IDENTITYLINK]历史的流程运行过程中用户关系
[ACT_HI_PROCINST]历史的流程实例
[ACT_HI_TASKINST]历史的任务实例
[ACT_HI_VARINST]历史的流程运行中的变量信息
流程定义表
[ACT_RE_DEPLOYMENT]部署单元信息
[ACT_RE_MODEL]模型信息
[ACT_RE_PROCDEF]已部署的流程定义
运行实例表
[ACT_RU_EVENT_SUBSCR]运行时事件
[ACT_RU_EXECUTION]运行时流程执行实例
[ACT_RU_IDENTITYLINK]运行时用户关系信息,存储任务节点与参与者的相关信息
[ACT_RU_JOB]运行时作业
[ACT_RU_TASK]运行时任务
[ACT_RU_VARIABLE]运行时变量表

六大service服务介绍

Activiti工作流框架除了提供数据库的25张表外,还提供了Service服务层供我们使用。
在项目中直接使用Service服务层接口,就可以实现工作流相关的业务功能。

RepositoryService:仓储服务

仓储服务可以用来部署我们的流程图,还可以创建我们的流程部署查询对象,用于查询刚刚部署的流程列表,便于我们管理流程。

开发人员可以进行以下操作:

  • 部署流程定义:将流程定义部署到Activiti引擎中,使其可以被启动和执行。
  • 删除流程定义:从Activiti引擎中删除不再需要的流程定义。
  • 查询流程定义:查询流程定义的相关信息,如流程定义ID、名称、版本号、部署时间等。
  • 查询流程资源:查询流程定义所需的资源,如BPMN文件、图片、表单等。
  • 更新流程资源:更新流程定义所需的资源,如BPMN文件、图片、表单等。
  • 查询流程定义的BPMN模型:查询流程定义的BPMN模型,可以通过该模型来生成流程实例。
RuntimeService:运行时服务

主要用于管理Activiti流程引擎中的流程实例(process instance),包括启动、暂停、激活、删除等操作。

通过RuntimeService,开发人员可以进行以下操作:

  • 启动流程实例:根据流程定义ID或流程定义的key启动流程实例。
  • 查询流程实例:根据流程定义ID、流程实例ID、业务键等条件查询符合条件的流程实例。
  • 暂停流程实例:暂停正在运行的流程实例,暂停后可以恢复。
  • 激活流程实例:激活已经暂停的流程实例。
  • 删除流程实例:删除已经结束的流程实例,或者强制删除正在运行的流程实例。
  • 查询流程实例状态:查询正在运行的流程实例的状态,如当前节点、流程变量等。
TaskService: 任务服务

主要用于管理Activiti流程引擎中的任务(task),包括创建、查询、完成等操作。

通过TaskService,开发人员可以进行以下操作:

  • 创建任务:创建新的任务,指定任务的名称、描述、优先级等信息。
  • 查询任务:根据任务ID、任务名称、任务负责人等条件查询符合条件的任务。
  • 完成任务:完成指定的任务,可以设置任务的处理结果和流程变量等信息。
  • 拾取任务:将指定的任务分配给当前用户进行处理。
  • 释放任务:将当前用户正在处理的任务释放回任务池,可以由其他用户进行处理。
  • 委派任务:将任务委派给其他用户进行处理。
  • 查询任务历史记录:查询指定任务的历史记录,包括任务的创建、完成、指派等操作。
HistoryService :历史服务

主要用于管理Activiti流程引擎中的历史数据,包括流程实例、任务、流程变量等的历史数据。

通过HistoryService,开发人员可以进行以下操作:

  • 查询流程实例的历史数据:查询指定流程实例的历史数据,包括流程实例的启动时间、结束时间、持续时间等信息。
  • 查询任务的历史数据:查询指定任务的历史数据,包括任务的创建时间、完成时间、处理人等信息。
  • 查询流程变量的历史数据:查询指定流程变量的历史数据,包括变量的名称、类型、值、修改时间等信息。
  • 查询流程定义的历史数据:查询指定流程定义的历史数据,包括流程定义的ID、名称、版本号、部署时间等信息。

通过HistoryService,开发人员可以方便地查询流程引擎中的历史数据,从而了解流程实例的执行情况和流程变量的变化情况,以便进行问题排查和性能优化。

FormService: 表单服务

主要用于管理Activiti流程引擎中的表单(form),包括表单的初始化、提交、读取等操作。

通过FormService,开发人员可以进行以下操作:

  • 初始化表单:根据流程定义ID或流程实例ID初始化表单,将表单中的数据绑定到流程变量中。
  • 提交表单:将表单中的数据提交到流程引擎中,更新流程变量的值。
  • 读取表单:读取指定表单的数据,包括表单的名称、类型、数据绑定等信息。

通过FormService,开发人员可以方便地进行表单的管理和维护,从而提高流程引擎的可维护性和可扩展性。

IdentityService:实体服务

主要用于管理Activiti流程引擎中的用户(user)、组(group)、身份认证(authentication)等信息。

通过IdentityService,开发人员可以进行以下操作:

  • 创建用户:创建新的用户,指定用户的ID、名称、邮箱等信息。
  • 查询用户:根据用户ID、名称、邮箱等条件查询符合条件的用户。
  • 更新用户:更新指定用户的信息,如名称、邮箱等。
  • 删除用户:删除指定的用户。
  • 创建组:创建新的组,指定组的ID、名称、类型等信息。
  • 查询组:根据组ID、名称、类型等条件查询符合条件的组。
  • 更新组:更新指定组的信息,如名称、类型等。
  • 删除组:删除指定的组。
  • 身份认证:对用户进行身份认证,验证用户的用户名和密码是否正确。

通过IdentityService,开发人员可以方便地进行用户和组的管理和维护,从而实现流程引擎的权限控制和安全性。


基本使用

1. pom依赖

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.14</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>11.2.0.4</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <!--activity工作流依赖-->
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-spring-boot-starter</artifactId>
        <version>7.1.0.M6</version>
        <exclusions>
            <exclusion>
                <artifactId>mybatis</artifactId>
                <groupId>org.mybatis</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-image-generator</artifactId>
        <version>7.1.0.M6</version>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.18</version>
    </dependency>

    <!--mybatis-plus依赖-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.3</version>
    </dependency>

    <!--shiro整合boot依赖-->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring-boot-web-starter</artifactId>
        <version>1.12.0</version>
    </dependency>

    <!--shiro权限缓存到redis-->
    <dependency>
        <groupId>org.crazycake</groupId>
        <artifactId>shiro-redis-spring-boot-starter</artifactId>
        <version>3.3.1</version>
    </dependency>

    <!--实体转化依赖-->
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.5.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.5.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok-mapstruct-binding</artifactId>
        <version>0.2.0</version>
    </dependency>
</dependencies>

2. 启动类

// 启动时排除掉Activity需要依赖于SpringSecurity
@SpringBootApplication(exclude = {
        ActivitiSpringIdentityAutoConfiguration.class
})
public class ActivityApplication {
    public static void main(String[] args) {
        SpringApplication.run(ActivityApplication.class);
    }
}

3. config包下的配置类

@Configuration
public class ActivitySpringConfiguration {

    @Bean
    public UserGroupManager userGroupManager() {
        return new UserGroupManager() {

            @Override
            public List<String> getUserGroups(String s) {
                return new ArrayList<>();
            }

            @Override
            public List<String> getUserRoles(String s) {
                return null;
            }

            @Override
            public List<String> getGroups() {
                return null;
            }

            @Override
            public List<String> getUsers() {
                return null;
            }
        };
    }
}

4. resource中的有关Activiti的yml配置介绍

spring: 
  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
    #none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。
    #activity:级别高于none,保存流程实例与流程行为,其他数据不保存。
    #audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。
    #full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。
    history-level: full
    # =============================
    #自动检查、部署流程定义文件
    check-process-definitions: false
    # asyncExecutorActivate是指activiti在流程引擎启动就激活AsyncExecutor,异步:true-开启(默认)、false-关闭
    async-executor-activate: true
    #流程定义文件存放目录,要具体到某个目录
    #      process-definition-location-prefix: classpath:/processes/holliday/
    #process-definition-location-suffixes: #流程文件格式
    #  - **.bpmn20.xml
    #  - **.bpmn

5. 实际使用的yml示列:二择一即可,看你用什么数据库

如果你用mysql:首先你得在你的navicat(数据库)工具中新建好activity库

# mysql连接
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql:///activity
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
  activiti:
    db-history-used: true  #进行相关activiti操作时,要生成history相关的表
    history-level: full  #history相关表中的历史记录都要被记录
   
mybatis-plus:
  type-aliases-package: com.cy.entity   
    
    
    
    
# oracle连接
spring:
  datasource:
    driver-class-name: oracle.jdbc.driver.OracleDriver
    url: jdbc:oracle:thin:@localhost:1521:orcl
    username: oa
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
  activiti:
    db-history-used: true  #进行相关activiti操作时,要生成history相关的表
    history-level: full  #history相关表中的历史记录都要被记录
  
mybatis-plus:
  type-aliases-package: com.cy.entity  

如果你用oracle:在你的PL/SQL工具中新建好oa用户(用户自定义)

示例:

-- 创建用户 先切换sys管理员用户创建oa用户并设置root密码
create user oa identified by root
account unlock;

-- 执行此sql后,切换连接到oa用户
grant connect, resource to oa;

-- 在oa用户下执行查询 前提是您得运行6.3条目录得单元测试代码后在查询
select * from user_tables;

在这里插入图片描述

6. test包下的单元测试分步解析

6.1 idea中实际测试流程:

在这里插入图片描述

IDEA中下载插件:

在这里插入图片描述

新建bpmn文件作图:
在这里插入图片描述
在这里插入图片描述

在该文件下右键打开图形化界面:
在这里插入图片描述

打开后的效果图:这里我设计了流程图,初始应该是一篇空白
在这里插入图片描述

设计流程图:

点击黑色幕布(空白区域)设置一下id,方便后续测试:
在这里插入图片描述

新建start events元件
在这里插入图片描述
在这里插入图片描述

然后新建三个user task元件
在这里插入图片描述
在这里插入图片描述
修改元件属性:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后新建结束元件
在这里插入图片描述
在这里插入图片描述
连接一下箭头,最终效果图:
在这里插入图片描述
在这里插入图片描述

6.2 test包下的单元测试分步介绍,最终完整代码在 第7.2 条目录

gitee仓库地址{可以clone过来自行测试}:gitee地址:https://gitee.com/crqyue/activity-unit-testing.git

idea部署时直接open即可
在这里插入图片描述
新建此java类:
在这里插入图片描述

6.3 部署流程方法

可以说是固定的,文件名这里对应自己的bpmn20.xml文件即可

运行后,它会在您的数据库里完成25张表的生成

@SpringBootTest(classes = ActivityApplication.class)
@Slf4j
public class 学生请假测试 {
    
    	@Autowired
	RepositoryService ps;
	
	@Test
	public void 部署流程() {
		Deployment deploy = ps.createDeployment().addClasspathResource("学生请假.bpmn20.xml").deploy();
		System.out.println(deploy.getId());
	}
    
}

在这里插入图片描述

6.4 启动流程

我们之前不是在流程图那里给了一个${name}嘛,这里给一个map将参数传进去生成一个实例

通俗点就是要办理请假的人是谁,比如小白要请假是不是首先得备好请假条

@Autowired
RuntimeService runtimeService;

@Test
public void 启动流程() {
    Map<String,Object> map = new HashMap<>();
    map.put("name","小白");
    // 根据流程定义的ID启动流程
    ProcessInstance instance = runtimeService.startProcessInstanceByKey("qj","qj:10086",map);
    // 输出内容
    System.out.println("流程定义ID:" + instance.getProcessDefinitionId());
    System.out.println("流程实例的ID:" + instance.getId());
}

6.5 执行待审核的任务

作用:查询并输出指定业务键下(“qj:10086”)的待处理任务的信息,包括任务的基本属性和关联的流程实例信息。这对于在工作流中追踪和处理任务非常有用。

@Autowired
TaskService taskService;

@Test
public void 执行待审核的任务() {
    TaskQuery query = taskService.createTaskQuery();
    List<Task> taskList = query.
        processInstanceBusinessKey("qj:10086"). // 以业务id作为条件
        //                processDefinitionKey("qj"). // 以流程id作为条件
        //                taskAssignee("张三"). // 以任务办理人作为条件
        list();
    // 3.输出任务信息
    for (Task task : taskList) {
        System.out.println("任务ID:"+task.getId());
        System.out.println("任务名称:"+task.getName());
        System.out.println("任务的创建时间:"+task.getCreateTime());
        System.out.println("任务的办理人:"+task.getAssignee());
        System.out.println("流程实例ID:"+task.getProcessInstanceId());
        System.out.println("执行对象ID:"+task.getExecutionId());
        System.out.println("流程定义ID:"+task.getProcessDefinitionId());
    }
}

6.6 办理任务

作用:找到指定业务键下的待处理任务,为任务添加审批意见,并完成任务,推动流程实例进入下一步。在工作流程中,这类操作通常由具体的任务处理人执行,例如审批人完成审批任务。

@Test
public void 办理任务() {
    // processInstanceBusinessKey 业务id
    // taskAssignee 任务处理人
    Task task = taskService.createTaskQuery().
        processInstanceBusinessKey("qj:10086")
        //                .taskAssignee("刚哥")
        .singleResult();
    // 设置审批意见
    taskService.addComment(task.getId(),task.getProcessInstanceId(),"同意");
    // 任务id 完成任务进入下一步
    taskService.complete(task.getId());
}

6.7 查询历史活动实例

作用:查询指定业务键下的历史任务实例信息,包括任务的基本属性和与任务相关的审批意见。这对于追踪工作流程中任务的执行历史和审批记录非常有用。

@Autowired
HistoryService historyService;
/**
	 * 历史活动实例查询
	 */
@Test
public void queryHistoryTask() {
    List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery() // 创建历史活动实例查询
        //                .processInstanceId("b6d83887-ad4b-11ee-b76f-005056c00008") // 执行流程实例id
        .processInstanceBusinessKey("qj:10086")  //根据业务id,查询当前业务下创建的流程实例
        .orderByTaskCreateTime()
        .asc()
        .list();
    for (HistoricTaskInstance hai : list) {
        System.out.println("活动ID:" + hai.getId());
        System.out.println("流程实例ID:" + hai.getProcessInstanceId());
        System.out.println("活动名称:" + hai.getName());
        System.out.println("办理人:" + hai.getAssignee());
        System.out.println("开始时间:" + hai.getStartTime());
        System.out.println("结束时间:" + hai.getEndTime());


        List<Comment> taskComments = taskService.getTaskComments(hai.getId());
        for (Comment taskComment : taskComments) {
            System.out.println("---"+taskComment.toString());
            System.out.println("审批意见:" + taskComment.getFullMessage());
        }
    }
}

6.8 判断结束

作用:根据指定的业务ID查询对应的流程实例,然后判断该流程实例是否已经结束。这对于在业务流程中确定特定实例的执行状态非常有用。

通俗点:就是您想知道您的的请假申请情况怎么样,正在审批中还是已经结束

@Test
public void 根据业务id判断流程是否结束(){
    ProcessInstance pi = runtimeService.createProcessInstanceQuery().
        processInstanceBusinessKey("qj:10086").singleResult();
    System.out.println(pi==null?"结束":"未结束");
}

6.9 查询历史流程变量

作用:查询指定历史流程实例的所有历史流程变量,并输出它们的相关信息。这对于在业务流程中追踪和记录流程变量的历史值非常有用。

@Test
public void queryHisProVariable(){
    // 先根据流程id查询出历史任务
    HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().processInstanceBusinessKey("jz5")
        .list().get(0);

    // 查询出该任务执行中所有的变量
    List<HistoricVariableInstance> historicVariableInstanceList = historyService
        .createHistoricVariableInstanceQuery().
        processInstanceId(task.getProcessInstanceId()).list();

    boolean b = true;

    for(HistoricVariableInstance v: historicVariableInstanceList){
        if(v.getVariableName().endsWith("sp")){
            int sp = (int) v.getValue();
            if (sp == 0) {
                b = false;
                break;
            }
        }
    }

    System.out.println("(b?:\"\") = " + (b?"流程审批通过":"流程审批不通过"));
}

7.1 查看流程执行情况

就是你可以通过此单元测试去获得申请在整个流程图中的一个流转情况

注意

注意

注意

此位置得对应
在这里插入图片描述
在这里插入图片描述
然后得输出位置:
在这里插入图片描述
代码:

@Autowired
RepositoryService repositoryService;

@Test
public void 流程图(){
    try {
        // 获取历史流程实例
        HistoricProcessInstance historicProcessInstance = historyService
            .createHistoricProcessInstanceQuery()
            .processInstanceBusinessKey("qj").singleResult();
        // 获取流程中已经执行的节点,按照执行先后顺序排序
        List<HistoricActivityInstance> historicActivityInstances = historyService
            .createHistoricActivityInstanceQuery()
            .processInstanceId(historicProcessInstance.getId())
            .orderByHistoricActivityInstanceId()
            .asc().list();
        // 高亮已经执行流程节点ID集合
        List<String> highLightedActivitiIds = new ArrayList<>();
        int index = 1;
        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
            // 用默认颜色
            highLightedActivitiIds.add(historicActivityInstance.getActivityId());
            index++;
        }
        ProcessDiagramGenerator processDiagramGenerator = null;
        // 使用默认的程序图片生成器
        processDiagramGenerator = new DefaultProcessDiagramGenerator();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
        // 高亮流程已发生流转的线id集合
        List<String> highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstances);
        // 使用默认配置获得流程图表生成器,并生成追踪图片字符流
        InputStream imageStream = processDiagramGenerator.generateDiagram(bpmnModel,
                                                                          highLightedActivitiIds, highLightedFlowIds, "宋体","微软雅黑", "黑体");
        // 输出图片内容
        Integer byteSize = 1024;
        byte[] b = new byte[byteSize];
        OutputStream os = new FileOutputStream("E:\\ATTPD\\activity\\src\\main\\resources\\a.svg");
        int len;
        while ((len = imageStream.read(b, 0, byteSize)) != -1) {
            os.write(b, 0, len);
        }
        os.close();
    } catch (Exception e) {

    }

}

7.2 最终完整代码

@SpringBootTest(classes = ActivityApplication.class)
@Slf4j
public class MyTest {
    @Autowired
    RepositoryService ps;

    // 部署流程 
    @Test
    public void 部署流程() {
        Deployment deploy = ps.createDeployment().addClasspathResource("qj.bpmn20.xml").deploy();
        System.out.println(deploy.getId());
    }
    
    
    @Autowired
    RuntimeService runtimeService;
    @Test
    public void 启动流程() {
        Map<String,Object> map = new HashMap<>();
        map.put("uname","刚哥");
        // 根据流程定义的ID启动流程
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("qj","qj:10086",map);
        // 输出内容
        System.out.println("流程定义ID:" + instance.getProcessDefinitionId());
        System.out.println("流程实例的ID:" + instance.getId());
//        taskService.setOwner();
    }
    
    
    @Autowired
    TaskService taskService;

    @Test
    public void 执行待审核的任务() {
        TaskQuery query = taskService.createTaskQuery();
        List<Task> taskList = query.
                processInstanceBusinessKey("qj:10086"). // 以业务id作为条件
//                processDefinitionKey("qj"). // 以流程id作为条件
//                taskAssignee("刚哥"). // 以任务办理人作为条件
                list();
        // 3.输出任务信息
        for (Task task : taskList) {
            System.out.println("任务ID:"+task.getId());
            System.out.println("任务名称:"+task.getName());
            System.out.println("任务的创建时间:"+task.getCreateTime());
            System.out.println("任务的办理人:"+task.getAssignee());
            System.out.println("流程实例ID:"+task.getProcessInstanceId());
            System.out.println("执行对象ID:"+task.getExecutionId());
            System.out.println("流程定义ID:"+task.getProcessDefinitionId());
        }
    }

    //办理任务(主要操作ACT_RU_EXECUTION、ACT_RU_TASK表)
    @Test
    public void 办理任务() {
        // processInstanceBusinessKey 业务id
        // taskAssignee 任务处理人
        Task task = taskService.createTaskQuery().
                processInstanceBusinessKey("qj:10086")
//                .taskAssignee("刚哥")
                .singleResult();
        // 设置审批意见
        taskService.addComment(task.getId(),task.getProcessInstanceId(),"bzr不同意123");
        // 任务id 完成任务进入下一步
        Map<String, Object> map = new HashMap<>();
        map.put("a",0);
        taskService.complete(task.getId(),map);
    }

    @Autowired
    HistoryService historyService;
    /**
     * 历史活动实例查询
     */
    @Test
    public void queryHistoryTask() {
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery() // 创建历史活动实例查询
//                .processInstanceId("b6d83887-ad4b-11ee-b76f-005056c00008") // 执行流程实例id
                .processInstanceBusinessKey("qj:10086")  //根据业务id,查询当前业务下创建的流程实例
                .orderByTaskCreateTime()
                .asc()
                .list();
        for (HistoricTaskInstance hai : list) {
            System.out.println("活动ID:" + hai.getId());
            System.out.println("流程实例ID:" + hai.getProcessInstanceId());
            System.out.println("活动名称:" + hai.getName());
            System.out.println("办理人:" + hai.getAssignee());
            System.out.println("开始时间:" + hai.getStartTime());
            System.out.println("结束时间:" + hai.getEndTime());


            List<Comment> taskComments = taskService.getTaskComments(hai.getId());
            for (Comment taskComment : taskComments) {
                System.out.println("---"+taskComment.toString());
                System.out.println("审批意见:" + taskComment.getFullMessage());
            }
        }
    }

    @Test
    public void 根据业务id判断流程是否结束(){
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().
                processInstanceBusinessKey("qj:10086").singleResult();
        System.out.println(pi==null?"结束":"未结束");
    }


    /**
     * 查询历史流程变量
     */
    @Test
    public void queryHisProVariable(){
        List<HistoricVariableInstance> historicVariableInstanceList = historyService
                .createHistoricVariableInstanceQuery().
                processInstanceId("78042512-ad6a-11ee-bb19-005056c00008").list();
        for(HistoricVariableInstance historicVariableInstance: historicVariableInstanceList){
            System.out.println("历史流程变量id: "+historicVariableInstance.getId());
            System.out.println("历史流程变量名称: "+historicVariableInstance.getVariableName());
            System.out.println("历史流程变量值: "+historicVariableInstance.getValue());
            System.out.println("==================================================");
        }
    }

}

OK !!! 收尾!!!

若有误区或不能解决,私信我,远程协助你!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值