流程建模艺术:使用Activiti设计流程

流程建模艺术:使用Activiti设计流程

  • 前言
  • 流程相关
    • 定义一个流程
    • 启动一个流程
    • 删除一个流程
  • 方法相关
    • 创建流程
    • 校验流程模型是否合法
    • 获取当前人的待办
    • 查询候选任务
    • 删除历史流程
    • 获取未完成的历史流程实例列表
    • 获取已完成的历史任务实例列表
    • 根据业务id查询历史活动实例

前言

“当今的企业和组织越来越依赖流程自动化来提高效率、降低成本并确保一致性。在这个数字化时代,Activiti和Flowable等流程引擎成为了不可或缺的工具。但是,要充分发挥它们的潜力,您需要深入了解它们的工作原理和最佳实践。本博客将带您初步了解activiti流程引擎,从基础概念到实际应用,让您在流程自动化的世界中游刃有余。”

流程相关

定义一个流程

repositoryService.createDeployment().addBpmnModel(name, bpmnModel).tenantId("ceshibo").deploy()

【说明】执行上述方法会向3张表中插入数据

  1. ACT_RE_DEPLOYMENT: 存储流程部署信息,包括部署 ID、名称、时间等。
  2. ACT_GE_BYTEARRAY: 存储流程定义文件,包括 BPMN、PNG、XML 等格式的文件。
  3. ACT_RE_PROCDEF: 存储流程定义信息,包括流程定义 ID、KEY、版本号、名称、部署 ID、XML 文件名称等。

【警告】上面的addBpmnModel(name,bpmnModel)向部署对象中添加BPMN模型,其中一定要注意,name必须是以.bpmn结尾,否则会出现ACT_RE_PROCDEF没有数据

启动一个流程

前提是获取到ProcessDefinition,根据ACT_RE_DEPLOYMENT的id获取

业务表中应该含有的字段

ID:唯一标识一条流程定义的ID。
KEY:流程定义的标识,相当于流程定义的名称。
NAME:流程定义的名称,用于在流程设计器中展示。
VERSION:流程定义的版本号,用于区分不同版本的流程定义。
DEPLOYMENT_ID:流程定义所属的部署ID。
RESOURCE_NAME:流程定义的资源名称,即对应的BPMN文件名称。
DIAGRAM_RESOURCE_NAME:流程定义的图形资源名称,即对应的流程图名称。
TENANT_ID:流程定义所属的租户ID,如果没有多租户需求,可以为空。

获取流程定义实体

// 根据部署ID获取流程定义ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
  • 根据流程id启动流程,ACT_RE_PROCDEF的id

    // 其中variables为流程变量,这里要加上businessKey,也就是业务id,因为每一个流程定义对应的是多个流程实例
    ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();ProcessInstance processInstance = processInstanceBuilder.processDefinitionId(startProcessInstanceDTO.getProcessDefinitionId()).variables(processVariables).businessKey("test01").businessStatus(BUSINESS_STATUS_1).start();
    
  • 根据流程定义key启动流程实例

    // 因为流程实例会存在多个版本,所以会存在相同的key,这里会取最新的一条流程实例
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("process_key", variables);
    

启动流程后会影响的表

  1. ACT_HI_ACTINST:是一个历史记录表,记录了所有活动实例的信息,包括已经完成和正在运行中的活动实例。
  2. ACT_HI_PROCINST:历史流程实例表,里面包含流程启动时间,结束时间,持续时间等。
  3. ACT_HI_TASKINST:历史任务实例信息,流程执行过程中,任务实例没有完成,但是开始了,也会被插入到该表中
  4. ACT_HI_VARINST:流程实例的变量信息,流程变量和任务变量。对于每个发生变化的变量,都会在表中生成一条记录。一条记录对应一个变量的变化历史,包括变量名称、变量值、修改时间等信息。
  5. ACT_RU_EXECUTION:是运行时流程执行实例表,每一个正在执行中的流程实例都对应着该表中的一条数据。该表中的数据会随着流程的执行而不断发生变化,包括流程开始、流程节点完成等。一般来说,如果一个流程已经结束,对应的记录会从 ACT_RU_EXECUTION 表中删除,如果一个流程还未结束,则对应的记录会保留在表中,直到流程结束。一个流程实例在 ACT_RU_EXECUTION 表中会对应一条数据,但是如果该流程实例下有多个执行流程(例如存在子流程或并行网关等情况),则会对应多条数据
  6. ACT_RU_VARIABLE:正在执行中的流程实例中的变量信息
  7. ACT_RU_TASK:当前待办任务的运行时信息,包括任务的 ID、名称、描述、优先级、创建时间、到期时间、处理人、任务状态等信息。该表中的数据会在任务完成后被删除。

删除一个流程

删除流程实例分为删除运行时数据和历史数据两个方面。删除运行时数据会将该流程实例的所有运行时数据,包括任务、执行流程、事件等全部删除,同时该流程实例的历史数据也会被删除。而删除历史数据则是针对已经结束的流程实例的历史数据进行删除,包括历史任务、历史变量等。

另外,在使用流程引擎删除流程实例时,需要注意以下几点:

  1. 如果该流程实例存在待办任务,需要先将这些任务删除或完成。
  2. 如果该流程实例已经关联了附件、评论、历史记录等信息,需要先将这些关联信息进行清理。
  3. 如果需要删除的流程实例已经产生了历史记录,需要同时删除历史记录。
Map<String, Object> map = new HashMap<>();
// 这一步查历史流程实例ACT_HI_PROCINST是否有符合条件的一条,这里是业务的key,返回的是单个历史流程实例
HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(bizId).orderByProcessInstanceStartTime().desc().singleResult();
if (processInstance == null) {map.put("code", 1001);map.put("msg", "流程未启动!");return map;
}
String processInstId = processInstance.getId();
// 这里可以不去查运行时的流程实例,直接从上面的历史流程实例数据中查询endtime是否为null,如果不为null说明流程已经结束了,可以使用processInstance.getEndTime()来获取
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstId).singleResult();
if (pi == null) {//该流程实例已经完成了historyService.deleteHistoricProcessInstance(processInstId);
} else {// TODO 待办刷新,因为删除完了,不能查到,故先查询,删除后推送// 下面的是删除流程实例,顺序别调换runtimeService.deleteProcessInstance(processInstId, "");historyService.deleteHistoricProcessInstance(processInstId);
}
map.put("code", 1000);
map.put("msg", "流程删除成功!");
return map;

删除流程会将上面启动流程影响的表中的数据全部删除(当前流程实例)

方法相关

创建流程

Deployment deploy = repositoryService.createDeployment().addBpmnModel(bpmnName, bpmnModel).tenantId(tenantId.toString()).deploy();

【说明】返回的Deployment对应的是ACT_RE_DEPLOYMENT表

校验流程模型是否合法

ProcessValidatorFactory processValidatorFactory = new ProcessValidatorFactory();
ProcessValidator processValidator = processValidatorFactory.createDefaultProcessValidator();
List<ValidationError> validate = processValidator.validate(bpmnModel);

【说明】

ProcessValidatorFactory 是 Activiti 中用于创建流程验证器的工厂类,createDefaultProcessValidator() 方法创建一个默认的流程验证器实例。然后使用流程验证器对给定的 bpmnModel 进行验证,返回一个 List<ValidationError>,其中包含验证过程中发现的错误信息。

验证过程可以帮助检查流程定义是否符合 BPMN 2.0 规范,例如检查是否存在未连接的节点、无效的表达式、重复的元素等。如果验证结果中存在错误信息,可以根据错误信息进行修复或调整流程定义,以确保其正确性。

获取当前人的待办

Task approveTask = taskService.createTaskQuery().processInstanceId(processInstanceId).taskAssignee(userId).singleResult();

【说明】

该代码片段是使用 Activiti 的任务服务(taskService)根据给定的流程实例 ID 和用户 ID 查询待办任务(approveTask)的过程。

具体来说,该代码执行以下操作:

  1. 使用 taskService.createTaskQuery() 创建一个任务查询对象。
  2. 使用 .processInstanceId(processInstanceId) 条件筛选,指定要查询的任务所属的流程实例 ID。
  3. 使用 .taskAssignee(userId) 条件筛选,指定要查询的任务的负责人(即指定用户 ID)。
  4. 使用 .singleResult() 方法执行查询并返回单个任务结果。

查询候选任务

Task candTask = taskService.createTaskQuery().processInstanceId(processInstanceId).executionId(executionIds).taskCandidateUser(userId).singleResult();

具体来说,该代码执行以下操作:

  1. 使用 taskService.createTaskQuery() 创建一个任务查询对象。
  2. 使用 .processInstanceId(processInstanceId) 条件筛选,指定要查询的任务所属的流程实例 ID。
  3. 使用 .executionId(executionIds) 条件筛选,指定要查询的任务所属的执行 ID(一般情况下可以为空,除非你要查询特定的执行任务)。
  4. 使用 .taskCandidateUser(userId) 条件筛选,指定要查询的任务的候选用户(即指定用户 ID)。
  5. 使用 .singleResult() 方法执行查询并返回单个任务结果。

根据查询条件,该代码片段的目的是获取某个流程实例中特定候选用户可领取的任务(如果存在的话)。

删除历史流程

List<ProcessInstance> processInstanceList = this.runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(bizKey).list();
if (CollUtil.isNotEmpty(processInstanceList)) {for (ProcessInstance pi : processInstanceList) {// 这里先删除运行中的再删除历史的this.runtimeService.deleteProcessInstance(pi.getId(), "因重复发起!");this.historyService.deleteHistoricProcessInstance(pi.getId());}
}

具体来说,该代码执行以下操作:

  1. 使用 runtimeService.createProcessInstanceQuery() 创建一个流程实例查询对象。
  2. 使用 .processInstanceBusinessKey(bizKey) 条件筛选,指定要查询的流程实例的业务键。
  3. 使用 .list() 方法执行查询并返回流程实例列表(processInstanceList)。
  4. 如果流程实例列表不为空,则遍历每个流程实例。
  5. 对于每个流程实例,首先使用 runtimeService.deleteProcessInstance() 方法删除运行时的流程实例,参数为流程实例 ID 和删除原因。
  6. 接着使用 historyService.deleteHistoricProcessInstance() 方法删除对应的历史流程实例,参数为流程实例 ID。

注意,上述代码片段中的 bizKey 是示例变量,你需要根据实际情况将其替换为有效的业务键。

获取未完成的历史流程实例列表

List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().unfinished().list();

具体来说,该代码执行以下操作:

  1. 使用 historyService.createHistoricProcessInstanceQuery() 创建一个历史流程实例查询对象。
  2. 使用 .unfinished() 条件筛选,指定要查询的历史流程实例必须是未完成的。
  3. 使用 .list() 方法执行查询并返回符合条件的历史流程实例列表(list)。

获取已完成的历史任务实例列表

List<HistoricTaskInstance> hisTaskInstList = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstId).finished().orderByTaskCreateTime().asc().list();

具体来说,该代码执行以下操作:

  1. 使用 historyService.createHistoricTaskInstanceQuery() 创建一个历史任务实例查询对象。
  2. 使用 .processInstanceId(processInstId) 条件筛选,指定要查询的历史任务实例所属的流程实例ID。
  3. 使用 .finished() 条件筛选,指定要查询的历史任务实例必须是已完成的。
  4. 使用 .orderByTaskCreateTime().asc() 指定按任务创建时间升序排序。
  5. 使用 .list() 方法执行查询并返回符合条件的历史任务实例列表(hisTaskInstList)。

根据业务id查询历史活动实例

// 根据业务id获取历史流程实例
HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(bizKey).orderByProcessInstanceStartTime().desc().singleResult();
// 查询已完成的历史活动实例
List<HistoricActivityInstance> hisActivityInstanceList = ((HistoricActivityInstanceQuery) this.historyService.createHistoricActivityInstanceQuery().processInstanceId(hpi.getId()).finished().orderByHistoricActivityInstanceEndTime().asc()).list();
  • historyService.createHistoricProcessInstanceQuery():创建历史流程实例查询对象。
  • processInstanceQuery.processInstanceBusinessKey(bizKey):设置查询条件,通过业务ID进行查询。
  • orderByProcessInstanceStartTime().desc():按照流程实例的开始时间进行降序排序。
  • singleResult():获取单个结果,即最新的历史流程实例对象。
  • historyService.createHistoricActivityInstanceQuery():创建历史活动实例查询对象。
  • activityInstanceQuery.processInstanceId(hpi.getId()):设置查询条件,通过历史流程实例ID进行查询。
  • finished():过滤只返回已完成的历史活动实例。
  • orderByHistoricActivityInstanceEndTime().asc():按照历史活动实例的结束时间进行升序排序。
  • list():获取符合条件的历史活动实例列表。

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

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

相关文章

CISSP学习笔记:PKI和密码学应用

第七章 PKI和密码学应用 7.1 非对称密码学 对称密码系统具有共享的秘钥系统&#xff0c;从而产生了安全秘钥分发的问题非对称密码学使用公钥和私钥对&#xff0c;无需支出复杂密码分发系统 7.1.1 公钥与私钥 7.1.2 RSA&#xff08;兼具加密和数字签名&#xff09; RSA算法…

[论文笔记]UNILM

引言 今天带来论文Unified Language Model Pre-training for Natural Language Understanding and Generation的笔记,论文标题是 统一预训练语言模型用于自然语言理解和生成。 本篇工作提出了一个新的统一预训练语言模型(Unifield pre-trained Language Model,UniLM),可以同…

debian 安装matlab2022b报错解决方法与问题解决思路

报错 terminate called after throwing an instance of ‘std::runtime_error’ 在安装目录执行 ./bin/glnxa64/MATLABWindow通过执行以上命令发现是和libharfbuzz库有关。 该库在调用freetype库时&#xff0c;有方法找不到。 偿试remove freetype库&#xff0c;发现该库有大…

Linux基本操作符(2)

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 关于Linux的操作符&#xff0c;在上篇博客中我们已经讲述了一些&#xff0c;都是Linux最基本的操作符。今天我们继续了解一些关于对文件及目录增删查改的操作符&#xff0c;话不多说我们直接上内容。 目录 rm指令的回…

Git/GitHub/Idea的搭配使用

目录 1. Git 下载安装1.1. 下载安装1.2. 配置 GitHub 秘钥 2. Idea 配置 Git3. Idea 配置 GitHub3.1. 获取 GitHub Token3.2. Idea 根据 Token 登录 GitHub3.3. Idea 提交代码到远程仓库3.3.1. 配置本地仓库3.3.2. GitHub 创建远程仓库1. 创建单层目录2. 创建多层目录3. 删除目…

大数据-玩转数据-Flink Sql 窗口

一、说明 时间语义&#xff0c;要配合窗口操作才能发挥作用。最主要的用途&#xff0c;当然就是开窗口然后根据时间段做计算了。Table API和SQL中&#xff0c;主要有两种窗口&#xff1a;分组窗口&#xff08;Group Windows&#xff09;和 含Over字句窗口&#xff08;Over Win…

卤制品配送经营商城小程序的用处是什么

卤制品也是食品领域重要的分支&#xff0c;尤其对年轻人来说&#xff0c;只要干净卫生好吃价格合理&#xff0c;那复购率宣传性自是不用说&#xff0c;而随着互联网发展&#xff0c;传统线下门店也须要通过线上破解难题或进一步扩大生意。 而商城小程序无疑是商家通过线上私域…

字符串函数与内存函数讲解

文章目录 前言一、字符串函数1.求字符串长度strlen 2.长度不受限制的字符串函数(1)strcpy(2)strcat(3)strcmp 3.长度受限制的字符串函数(1)strncpy(2)strncat(3)strncmp 4.字符串查找(1)strstr(2)strtok 5.错误信息报告(1)strerror(2)perror 二、内存函数1.memcpy2.memmove3.me…

Neural Networks for Fingerprint Recognition

Neural Computation ( IF 3.278 ) 摘要&#xff1a; 在采集指纹图像数据库后&#xff0c;设计了一种用于指纹识别的神经网络算法。当给出一对指纹图像时&#xff0c;算法输出两个图像来自同一手指的概率估计值。在一个实验中&#xff0c;神经网络使用几百对图像进行训练&…

第 365 场 LeetCode 周赛题解

A 有序三元组中的最大值 I 参考 B B B 题做法… class Solution { public:using ll long long;long long maximumTripletValue(vector<int> &nums) {int n nums.size();vector<int> suf(n);partial_sum(nums.rbegin(), nums.rend(), suf.rbegin(), [](int x…

golang工程——protobuf使用及原理

相关文档 源码&#xff1a;https://github.com/grpc/grpc-go 官方文档&#xff1a;https://www.grpc.io/docs/what-is-grpc/introduction/ protobuf编译器源码&#xff1a;https://github.com/protocolbuffers/protobuf proto3文档&#xff1a;https://protobuf.dev/programmin…

加入PreAuthorize注解鉴权之后NullPointerException报错

记录一次很坑的bug&#xff0c;加入PreAuthorize注解鉴权之后NullPointerException报错&#xff0c;按理来说没有权限应该403报错&#xff0c;但是这个是500报错&#xff0c;原因是因为controller层的service注入失败&#xff0c;然而我去掉注解后service注入成功&#xff0c;并…

使用VSCODE 调试ros2具体设置

vscode 调试 ROS2 张得帅&#xff01; 于 2023-09-09 15:39:39 发布 456 收藏 1 文章标签&#xff1a; vscode ros2 版权 1、在下列目录同层级找到.vscode文件夹 . ├── build ├── install ├── log └── src 2、 安装ros插件 3、创建tasks.json文件&#xff0c;添…

二十七、[进阶]MySQL默认存储引擎InnoDB的简单介绍

1、MySQL体系结构 MySQL大致可以分为连接层、服务层、引擎层、存储层四个层&#xff0c;这里需要注意&#xff0c;索引的结构操作是在存储引擎层完成的&#xff0c;所以不同的存储引擎&#xff0c;索引的结构是不一样的。 &#xff08;1&#xff09;体系结构示意图 &#xff0…

国庆10.01

TCPselect 代码 服务器 #include<myhead.h> #include<sqlite3.h> #define PORT 6666 //端口号 #define IP "192.168.0.104" //IP地址//键盘事件 int jp(fd_set tempfds,int maxfd) {char buf[128] ""; //用来接收数据char buf1[128] …

【算法|贪心算法系列No.2】leetcode2208. 将数组和减半的最少操作次数

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

Spring注册Bean系列--方法1:@Component

原文网址&#xff1a;Spring注册Bean系列--方法1&#xff1a;Component_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Spring注册Bean的方法&#xff1a;Component。 注册Bean的方法我写了一个系列&#xff0c;见&#xff1a;Spring注册Bean(提供Bean)系列--方法大全_IT利刃出鞘…

开绕组电机零序Bakc EMF-based无感控制以及正交锁相环inverse Park-based

前言 最近看论文遇到了基于反Park变换的锁相环&#xff0c;用于从开绕组永磁同步电机零序电压信号中提取转子速度与位置信息&#xff0c;实现无感控制。在此记录 基于零序Back EMF的转子估算 开绕组电机的零序反电动势 e 0 − 3 ω e ψ 0 s i n 3 θ e e_0-3\omega_e\psi_…

​68条萝卜刀《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书

​68条萝卜刀《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书 ​68条萝卜刀《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书

springboot和vue:十一、Axios网络请求的安装引入与使用、跨域问题解决(CORS)

Axios简介与安装 Axios是一个基于promise的网络请求库&#xff0c;作用于node.js和浏览器中Axios在浏览器端使用XMLHttpRequests发送网络请求&#xff0c;并自动完成json数据的转换安装&#xff1a;npm install axios官方文档&#xff1a;https://www.axios-http.cn/ Axios基…