Activiti——将绘制的流程图存入act数据库并进行流程推进与状态流转

embedded/2024/10/18 16:46:38/

文章目录

  • 前言
  • 流程图入库操作 RepositoryService
    • 项目结构
    • 数据库连接配置文件
    • 入库Java测试代码
    • zip 方式进行流程的批量部署
  • 流程启动 RuntimeService
  • 待处理任务查看 TaskService
  • 流程状态的扭转
  • 查询流程定义信息 RepositoryService
  • 查询正在执行的流程实例 RuntimeService
  • 已部署流程删除
  • 查询流程的历史记录信息 HistoryService

前言

之前的博客中,重点说明了activiti表的创建,以及第一张流程图的绘制。但是绘制的第一张流程图并非存在于对应的数据库中,今天需要做的就是将绘制的流程图,使用activiti的代码自动的填充进对应的数据表中。然后做一个简单的状态流转。

流程图入库操作 RepositoryService

项目结构

依旧是基于之前的项目依赖与结构。
在这里插入图片描述

数据库连接配置文件

其中数据库的连接配置文件activiti.cfg.xml,配置内容如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexhttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"><property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://xxxx:3306/activiti_02?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT%2B8&amp;nullCatalogMeansCurrent=true"/><property name="jdbcUsername" value="root"/><property name="jdbcPassword" value="root"/><property name="databaseSchemaUpdate" value="true"/></bean><!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://xxxx:3306/activiti?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT%2B8" /><property name="username" value="root" /><property name="password" value="root" /><property name="maxActive" value="3" /><property name="maxIdle" value="1" /></bean><bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"><property name="dataSource" ref="dataSource" /><property name="databaseSchemaUpdate" value="true"/></bean>--></beans>

配置文件中的一些注意事项在前面的博客中做了一些说明,此处不进行额外的讲解,有问题的参考之前的博客内容。

入库Java测试代码

编写一个测试类,其中的入库逻辑如下所示:

// 单个任务的部署
@Test
public void addTable(){ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();Deployment demo1 = repositoryService.createDeployment().addClasspathResource("bpmn/demo01.bpmn") // 添加流程图.addClasspathResource("bpmn/demo01.png") // 对应的流程图片 支持 png|jpg|gif|svg.name("第一个流程测试用例").deploy();System.out.println("流程部署id===》"+demo1.getId());System.out.println("流程部署name===》"+demo1.getName());
}

虽然都是使用addClasspathResource关联xml与png 图片,但是其中的底层原理则是根据文件后缀,自动去判断识别存入对应的数据表字段中。

查看控制台输出日志与数据库,可以发现能够将对应的流程图xml与流程图进行入库处理。

在这里插入图片描述
查看数据库是否存在对应的数据信息。

select * from ACT_RE_DEPLOYMENT;
select * from ACT_RE_PROCDEF;

在这里插入图片描述
在这里插入图片描述
上传后的文件内容存储表,可以通过查找act_ge_bytearray看见。
在这里插入图片描述
【注意点】

除了流程图的最初部署,会将流程图存入act_ge_bytearray表之外。
在流程审批的各个节点中,都能将对应的文件进行存储,方便后续进行文件的回显。

zip 方式进行流程的批量部署

将对应的 流程图 png 与 xml 汇总打包成一个zip文件,此时则需要注意 两个文件除了后缀不同之外,一定要保证前面的文件名称一致。
在这里插入图片描述
编写代码逻辑,将zip创建数据流,并使用activiti的DeploymentaddZipInputStream,将zip数据流解析并存入数据表中。

/*** zip 包方式批量上传流程图与流程xml文件*/
@Test
public void zipInsertTable(){// 获取zip文件流InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("bpmn/activitis.zip");ZipInputStream zipInputStream = new ZipInputStream(inputStream);ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();Deployment deploy = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();System.out.println("流程部署id===》"+deploy.getId());System.out.println("流程部署name===》"+deploy.getName());
}

代码执行后,观察控制台打印日志信息与数据表的查询。
在这里插入图片描述

select * from ACT_RE_PROCDEF;

在这里插入图片描述

流程启动 RuntimeService

当对应的流程图的结构信息已经进行了入库操作,此时就可以编写代码进行流程的启动测试了。
在这里插入图片描述

启动流程的逻辑如下所示:

/*** 流程启动  初次启动* 注意: 每次执行一次  就是以当前的流程图模板  创建了一个新的 activiti 的对象*/
@Test
public void startFlow(){ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();// 注意此处的 key  就是流程图的 id ProcessInstance demo01 = runtimeService.startProcessInstanceByKey("demo01");System.out.println("流程定义 id===》"+demo01.getProcessDefinitionId());System.out.println("流程实例 id===》"+demo01.getId());System.out.println("当前活动 id===》"+demo01.getActivityId());
}

代码执行后查看控制台的相关日志输出。
在这里插入图片描述
【注意点】startProcessInstanceByKey("demo01") 指定的 key 必须与 流程图中的 id 一致
在这里插入图片描述
如果不一致,则会出现org.activiti.engine.ActivitiObjectNotFoundException: no processes deployed with key 'demoxxxx'的报错问题!!

【注意点】每次执行创建流程的代码,都会以工作流流程图作为模板,构建一个新的实例
在这里插入图片描述

待处理任务查看 TaskService

流程启动,在有些项目中的首页,需要展示当前登录者的待处理任务列表信息。

进行了启动工作流操作,此时的工作流中的节点流转,如下:
在这里插入图片描述

此时可以通过TaskService查看,下面是一个简单的例子。

/*** 查询当前个人待执行的任务*/
@Test
public void viewReDoTask(){// 工作流从启动开始  就会流转至 第一个 UserTask 节点,// 此时可以通过配置的 Assignee 查询指定的人的  一些待处理 任务信息String assignee = "worker";// 数据库连接配置操作ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 根据对应的流程 查询当前指定人的待处理任务信息TaskService taskService = defaultProcessEngine.getTaskService();List<Task> list = taskService.createTaskQuery().processDefinitionKey("demo01") // 指定哪个流程图模板.taskAssignee(assignee) // 指定是谁负责待处理的任务.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("===========================================");});}
}

测试代码运行后,在控制台中可以看到以下的信息。
在这里插入图片描述

这里有两个流程实例,是因为为了验证启动流程是否同实例对象,执行了两次开启流程的代码逻辑。

流程状态的扭转

work节点中,上面进行了待处理任务的查看操作,如果用户进行了处理,需要将状态进行向下扭转,如何扭转任务的节点,接下来看下面的代码逻辑。

/*** 工作流的节点与状态的扭转*/
@Test
public void doTask(){// 获取数据库的连接信息ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();TaskService taskService = defaultProcessEngine.getTaskService();// 完成当前节点的任务  并向下推进String taskId = "7505";taskService.complete(taskId);
}

在这里插入图片描述

当任务进行推进操作后,再执行查询当前登录人员需要待处理的任务节点,那么任务id为 7505的相关任务不能查询到。查询一下。
在这里插入图片描述

任务编号为7505的已经成功推进!

查询流程定义信息 RepositoryService

再上面的startFlow()执行后,就会依据对应的工作流模板,创建一个工作流流程实例。查看指定的流程模板下已创建的相关流程实例信息,可以使用下面的代码逻辑实现。

/*** 查询流程定义 的一些内容*/
@Test
public void queryProcessDefinition(){// 获取数据库的连接信息ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();// 指定需要查询哪个流程模板信息String flowId = "demo01";List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(flowId) // 指定是哪个流程模板.orderByProcessDefinitionVersion() // 排序字段.desc().list();if(!CollectionUtil.isEmpty(list)){list.forEach(process->{System.out.println("流程定义 id "+process.getId());System.out.println("流程定义 name "+process.getName());System.out.println("流程定义 key "+process.getKey());System.out.println("流程定义 version "+process.getVersion());System.out.println("流程部署 id "+process.getDeploymentId());System.out.println("=============================");});}
}

查看控制台执行后的日志信息,如下所示:
在这里插入图片描述

查询正在执行的流程实例 RuntimeService

如果需要查询当前指定的流程模板,存在哪些流程实例处于流程中的状态,以及对应的流程实例的信息,以达到随时跟踪任务的执行情况。

可以使用如下方式进行查看:

/*** 查询指定工作流模板中,哪些实例正在执行流程中*/
@Test
public void queryDoProcessInstance(){// 指定工作流流程模板idString flowId= "demo01";// 获取数据库的连接信息ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processDefinitionKey(flowId).list();if(!CollectionUtil.isEmpty(list)){list.forEach(processInstance->{System.out.println("流程实例 id "+processInstance.getProcessInstanceId());System.out.println("所属流程定义 id "+processInstance.getProcessDefinitionId());System.out.println("是否执行完成 "+processInstance.isEnded());System.out.println("是否暂停 "+processInstance.isSuspended());System.out.println("当前活动标识 "+processInstance.getActivityId());System.out.println("业务关键字 "+processInstance.getBusinessKey());System.out.println("=============================");});}
}

在这里插入图片描述

已部署流程删除

有些已经部署后的流程,需要进行删除操作,则可以使用下列的逻辑实现。

这里说的已部署,是指已经执行了addTable()做了流程文件的上传操作。

/*** 删除 已部署 的流程实例。* 注意:如果当前流程实例并未执行完成,进行删除时会出现报错。*/
@Test
public void deleteDeployment(){// 流程部署idString deployMentId = "5001";// 获取数据库的连接信息ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();// 当该已部署的流程,存在流程中的实例时,执行当前流程会报错!repositoryService.deleteDeployment(deployMentId);// 如果需要进行强制删除  则可以采取下列的方式进行//repositoryService.deleteDeployment(deployMentId,true);
}

如果当前已部署的流程存在流程中的实例时,执行删除操作会出现下面的报错信息。
在这里插入图片描述

查询流程的历史记录信息 HistoryService

在一般的审批详情列表中,通常需要展示一些已审批处理节点的记录信息,此时则可以使用 HistoryService 查询指定流程实例下的各个已处理的审批节点数据记录。

当然了,测试操作需要指定指定工作流模板的流程id,先查询可以测试的流程编号。

/*** 查询指定工作流模板中,哪些实例正在执行流程中*/
@Test
public void queryDoProcessInstance(){// 指定工作流流程模板idString flowId= "demo01";// 获取数据库的连接信息ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processDefinitionKey(flowId).list();if(!CollectionUtil.isEmpty(list)){list.forEach(processInstance->{System.out.println("流程实例 id "+processInstance.getProcessInstanceId());System.out.println("所属流程定义 id "+processInstance.getProcessDefinitionId());System.out.println("是否执行完成 "+processInstance.isEnded());System.out.println("是否暂停 "+processInstance.isSuspended());System.out.println("当前活动标识 "+processInstance.getActivityId());System.out.println("业务关键字 "+processInstance.getBusinessKey());System.out.println("=============================");});}
}

在这里插入图片描述
使用对应的流程实例id,这里使用10001

使用下列代码进行历史数据的检索:

/*** 查询 历史信息*/
@Test
public void queryHistoryInfo(){String processInstanceId = "10001";ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();HistoryService historyService = defaultProcessEngine.getHistoryService();HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();historicActivityInstanceQuery.processInstanceId(processInstanceId);// 流程实例idhistoricActivityInstanceQuery.orderByHistoricActivityInstanceStartTime().asc();List<HistoricActivityInstance> list = historicActivityInstanceQuery.list();if(!CollectionUtil.isEmpty(list)){list.forEach(hi->{System.out.println(hi.getActivityId());System.out.println(hi.getActivityName());System.out.println(hi.getProcessDefinitionId());System.out.println(hi.getProcessInstanceId());System.out.println("=============================");});}
}

执行成功后在控制台的日志中可以看到下列信息:
在这里插入图片描述


http://www.ppmy.cn/embedded/8981.html

相关文章

单机单实例部署Kafka及测试

文章目录 部署Docker 测试启动测试创建Topic生产者消费者 集成Manager的部署dockerfile效果 参考资料 在我们做和kafka开发相关的工作时&#xff0c;往往希望独立部署一套kafka测试环境。而kafka部署时&#xff0c;不能只是简单安装kafka自身组件&#xff0c;还要安装zookeeper…

Flutter开发之--初识Flutter

文章目录 概述Flutter整体架构嵌入层引擎层框架层 跑通demo尝鲜Flutter项目的目录介绍Flutter demo项目的运行 总结 概述 Flutter 是由Google公司研发的一种跨端开发技术&#xff0c;在2018年正式推出。Flutter自带Skia图形绘制引擎&#xff0c;采用自绘制的方式&#xff0c;不…

Docker容器化部署(企业版)

大家好&#xff0c;webfunny前端监控埋点系统&#xff0c;已经正式发布了webfunny的官方镜像&#xff1a; Webfunny镜像目录&#xff1a;https://hub.docker.com/r/webfunny/webfunny_monitor_cluster/tags 部署前提是你的服务器已经安装了Docker环境&#xff0c;没有安装doc…

uniapp uni.navigateBack 连带返回问题记录

uniapp uni.navigateBack 连带返回问题记录 问题描述 去除原生导航栏&#xff0c;使用自定义导航&#xff0c;并使用自定义返回按钮&#xff0c;通过方法handleBack.navigateBack()返回到上一页。 共有3层页面&#xff0c;A -> B -> C。都是自定义导航栏。均使用navig…

vue详解(3)

1. Vue 生命周期总结 四个阶段&#xff0c;八个钩子 -> 三个常用 created&#xff0c;mounted&#xff0c;beforeDestroy 2. 工程化开发 & 脚手架 Vue CLI 基本介绍&#xff1a; Vue CLI 是 Vue 官方提供的一个全局命令工具。 可以帮助我们快速创建一个开发 Vue 项目…

Pytest精通指南(25)钩子函数-并发执行(pytest-xdist)

文章目录 前言应用场景插件安装注意事项参数分析使用方法拓展-分组并行 前言 pytest-xdist是一个pytest插件&#xff0c;它用于实现测试用例的并发执行&#xff0c;从而显著提高大型测试套件的运行速度。 在测试套件非常庞大或测试用例之间几乎没有依赖关系时&#xff0c;并发执…

文献速递:深度学习胶质瘤诊断---通过深度学习和弥散加权成像提高胶质瘤遗传亚型的无创分类

Title 题目 Improving the noninvasive classification of glioma genetic subtype with deep learning and diffusion weighted imaging 通过深度学习和弥散加权成像提高胶质瘤遗传亚型的无创分类 Background 背景 Diagnostic classification of diffuse gliomas now requ…

【创建型模式】抽象工厂模式

一、抽象工厂模式概述 抽象工厂模式定义&#xff1a;提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无须指定它们具体的类。 模式动机&#xff1a; 1.当系统提供的工厂生产的具体产品并不是一个简单的对象&#xff0c;而是多个位于不同产品等级结构、属于不同类型的…