(三)springboot2.7.6集成activit5.23.0之流程跟踪高亮显示

news2024/12/25 23:36:14

1.引入diagram-viewer。

上一篇集成流程设计器时已经把diagram-viewer文件夹拷贝过来了。所以这一步就省略了。

2.引入依赖activiti-diagram-rest。

<dependency>
  <groupId>org.activiti</groupId>
    <artifactId>activiti-diagram-rest</artifactId>
    <version>${activiti.version}</version>
</dependency>

3.查看审批跟踪流的url格式。

查看diagram-viewer/index.html文件,我们知道需要传入2个参数processDefinitionId和processInstanceId。

所以url基本格式是:

http://localhost:8080/diagram-viewer/index.html?processDefinitionId={processDefinitionId}&processInstanceId={processInstanceId}

4.初始化数据便于测试。 

首先,设计一个简单的流程two-task-process.bpmn20.xml。并部署。

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="twoTaskProcess" isExecutable="true">
    <startEvent id="sid-CB77D78D-657D-45C2-959C-53E120CD79DF"></startEvent>
    <userTask id="sid-35258D72-ABC4-42FB-B793-69243860DFE8" name="任务1" activiti:assignee="1"></userTask>
    <sequenceFlow id="sid-B8596EB9-169F-41C5-AA95-55EB32B8CA66" sourceRef="sid-CB77D78D-657D-45C2-959C-53E120CD79DF" targetRef="sid-35258D72-ABC4-42FB-B793-69243860DFE8"></sequenceFlow>
    <userTask id="sid-7CFC5FC2-134F-4E18-B3A1-D79672639388" name="任务2" activiti:assignee="2"></userTask>
    <sequenceFlow id="sid-4A25046F-34EE-4BDB-9A96-30B98A15BE93" sourceRef="sid-35258D72-ABC4-42FB-B793-69243860DFE8" targetRef="sid-7CFC5FC2-134F-4E18-B3A1-D79672639388"></sequenceFlow>
    <endEvent id="sid-1641410B-1B17-4A84-82C4-DA15EF102384"></endEvent>
    <sequenceFlow id="sid-F528180B-EFA4-436A-9BB9-1495898DB4A3" sourceRef="sid-7CFC5FC2-134F-4E18-B3A1-D79672639388" targetRef="sid-1641410B-1B17-4A84-82C4-DA15EF102384"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_process">
    <bpmndi:BPMNPlane bpmnElement="twoTaskProcess" id="BPMNPlane_process">
      <bpmndi:BPMNShape bpmnElement="sid-CB77D78D-657D-45C2-959C-53E120CD79DF" id="BPMNShape_sid-CB77D78D-657D-45C2-959C-53E120CD79DF">
        <omgdc:Bounds height="30.0" width="30.0" x="85.0" y="183.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-35258D72-ABC4-42FB-B793-69243860DFE8" id="BPMNShape_sid-35258D72-ABC4-42FB-B793-69243860DFE8">
        <omgdc:Bounds height="80.0" width="100.0" x="160.0" y="158.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-7CFC5FC2-134F-4E18-B3A1-D79672639388" id="BPMNShape_sid-7CFC5FC2-134F-4E18-B3A1-D79672639388">
        <omgdc:Bounds height="80.0" width="100.0" x="300.0" y="158.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-1641410B-1B17-4A84-82C4-DA15EF102384" id="BPMNShape_sid-1641410B-1B17-4A84-82C4-DA15EF102384">
        <omgdc:Bounds height="28.0" width="28.0" x="450.0" y="184.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-4A25046F-34EE-4BDB-9A96-30B98A15BE93" id="BPMNEdge_sid-4A25046F-34EE-4BDB-9A96-30B98A15BE93">
        <omgdi:waypoint x="260.0" y="198.0"></omgdi:waypoint>
        <omgdi:waypoint x="300.0" y="198.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-B8596EB9-169F-41C5-AA95-55EB32B8CA66" id="BPMNEdge_sid-B8596EB9-169F-41C5-AA95-55EB32B8CA66">
        <omgdi:waypoint x="115.0" y="198.0"></omgdi:waypoint>
        <omgdi:waypoint x="160.0" y="198.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-F528180B-EFA4-436A-9BB9-1495898DB4A3" id="BPMNEdge_sid-F528180B-EFA4-436A-9BB9-1495898DB4A3">
        <omgdi:waypoint x="400.0" y="198.0"></omgdi:waypoint>
        <omgdi:waypoint x="450.0" y="198.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

流程图如下:

然后运行项目时启动流程,并按上面url格式打印输出。

@ComponentScan({"xpl.study.activiti","org.activiti.rest"})
@SpringBootApplication(exclude = { org.activiti.spring.boot.SecurityAutoConfiguration.class,
		org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class })
public class StudyActivitiApplication {

	public static void main(String[] args) {
		SpringApplication.run(StudyActivitiApplication.class, args);
	}
	@Bean
	public CommandLineRunner init(final RepositoryService repositoryService, final RuntimeService runtimeService,
			final TaskService taskService) {
		return new CommandLineRunner() {
			@Override
			public void run(String... strings) throws Exception {
				System.out.println(
						"Number of process definitions : " + repositoryService.createProcessDefinitionQuery().count());
				System.out.println("Number of tasks : " + taskService.createTaskQuery().count());
//				runtimeService.startProcessInstanceByKey("oneTaskProcess");
//				System.out.println("Number of tasks after process start: " + taskService.createTaskQuery().count());
				ProcessInstance procInst = runtimeService.startProcessInstanceByKey("oneTaskProcess");
				System.out.println("pid:"+procInst.getActivityId() );
				System.out.println("procDefId:"+procInst.getProcessDefinitionId() );
				String url = "http://localhost:8080/diagram-viewer/index.html?processDefinitionId="
						+ procInst.getProcessDefinitionId() + "&processInstanceId="+procInst.getActivityId();
				System.out.println(url);
			}
		};
	}
}

运行结果:

5.复制上面输出的url,浏览器访问,查看效果。

看到上面404错误。

http://localhost:8080/diagram-viewer/service/process-definition/twoTaskProcess:1:5/diagram-layout?callback=jQuery171021142217172191757_1722612596099&_=1722612596116

 6.验证activiti-diagram-rest是否生效。

把上面的url去掉/diagram-viewer/service,即使用如下url访问。

http://localhost:8080/process-definition/twoTaskProcess:1:5/diagram-layout?callback=jQuery171021142217172191757_1722612596099&_=1722612596116

结果:

 说明该接口是可以访问的。上一章节配置包扫描时把org.activiti.rest加进去了,activiti-diagram-rest刚好相关的api都在这个包下面,所以不需要再启动类上面再添加新的扫描包。

7.修正URL,查看审批跟踪流程图。

修改diagram-viewer/index.html。

修改前:

修改后:

 并且把diagram-viewer/js/ActivitiRest.js文件中的jsonp都注释掉。查看activiti-diagram-rest源码,相关实现都没考虑jsonp,要是的api支持jsonp还需要对源码进行修改。本项目可以简单点直接注释jsonp,使用普通的ajax请求就可以了。只有有跨域需求才需要实现jsonp请求功能。

var ActivitiRest = {
	options: {},
	getProcessDefinitionByKey: function(processDefinitionKey, callback) {
		var url = Lang.sub(this.options.processDefinitionByKeyUrl, {processDefinitionKey: processDefinitionKey});
		
		$.ajax({
			url: url,
			//dataType: 'jsonp',
			cache: false,
			async: true,
			success: function(data, textStatus) {
				var processDefinition = data;
				if (!processDefinition) {
					console.error("Process definition '" + processDefinitionKey + "' not found");
				} else {
				  callback.apply({processDefinitionId: processDefinition.id});
				}
			}
		}).done(function(data, textStatus) {
			console.log("ajax done");
		}).fail(function(jqXHR, textStatus, error){
			console.error('Get diagram layout['+processDefinitionKey+'] failure: ', textStatus, 'error: ', error, jqXHR);
		});
	},
	
	getProcessDefinition: function(processDefinitionId, callback) {
		var url = Lang.sub(this.options.processDefinitionUrl, {processDefinitionId: processDefinitionId});
		
		$.ajax({
			url: url,
			//dataType: 'jsonp',
			cache: false,
			async: true,
			success: function(data, textStatus) {
				var processDefinitionDiagramLayout = data;
				if (!processDefinitionDiagramLayout) {
					console.error("Process definition diagram layout '" + processDefinitionId + "' not found");
					return;
				} else {
					callback.apply({processDefinitionDiagramLayout: processDefinitionDiagramLayout});
				}
			}
		}).done(function(data, textStatus) {
			console.log("ajax done");
		}).fail(function(jqXHR, textStatus, error){
			console.log('Get diagram layout['+processDefinitionId+'] failure: ', textStatus, jqXHR);
		});
	},
	
	getHighLights: function(processInstanceId, callback) {
		var url = Lang.sub(this.options.processInstanceHighLightsUrl, {processInstanceId: processInstanceId});
		
		$.ajax({
			url: url,
			//dataType: 'jsonp',
			cache: false,
			async: true,
			success: function(data, textStatus) {
				console.log("ajax returned data");
				var highLights = data;
				if (!highLights) {
					console.log("highLights not found");
					return;
				} else {
					callback.apply({highLights: highLights});
				}
			}
		}).done(function(data, textStatus) {
			console.log("ajax done");
		}).fail(function(jqXHR, textStatus, error){
		  console.log('Get HighLights['+processInstanceId+'] failure: ', textStatus, jqXHR);
		});
	}
};

再次访问,还是没有高亮。

调试了一晚上,快凌晨1点了,该是没找出高亮失败原因。睡一觉起来,再次检查了下代码,发现是url拼接过程中,获取流程id的方法写错了!太累了果然就该让大脑休息了。

procInst.getActivityId()

改为

procInst.Id() 

 StudyActivitiApplication修改后代码:




	@Bean
	public CommandLineRunner init(final RepositoryService repositoryService, final RuntimeService runtimeService,
			final TaskService taskService) {
		return new CommandLineRunner() {
			@Override
			public void run(String... strings) throws Exception {
				System.out.println(
						"Number of process definitions : " + repositoryService.createProcessDefinitionQuery().count());
				System.out.println("Number of tasks : " + taskService.createTaskQuery().count());
//				runtimeService.startProcessInstanceByKey("oneTaskProcess");
//				System.out.println("Number of tasks after process start: " + taskService.createTaskQuery().count());
//				ProcessInstance procInst = runtimeService.startProcessInstanceByKey("oneTaskProcess");
				ProcessInstance procInst = runtimeService.startProcessInstanceByKey("twoTaskProcess");
				String pId = procInst.getId();
				Task firstTask = taskService.createTaskQuery().processInstanceId(pId).singleResult();
				taskService.complete(firstTask.getId());
				System.out.println("pid:"+ pId );
				System.out.println("procDefId:"+procInst.getProcessDefinitionId() );
				String url = "http://localhost:8080/diagram-viewer/index.html?processDefinitionId="
						+ procInst.getProcessDefinitionId() + "&processInstanceId="+ pId;
				System.out.println(url);
			}
		};
	}

8.测试通过。

最后测试结果如下:

至此,官方的流程追踪功能集成完毕。

上面图中可以看到,历史执行的节点和线条没有高亮,不知道是故意不高亮的,还是有bug。正常我们希望的是历史路径都高亮,官方实现没按我们希望的逻辑实现,不清楚是有其他原因,还是就是还不够完善。

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

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

相关文章

设施农业智能化新引擎:AutoML让复杂农业算法唾手可得

&#xff08;于景鑫 北京市农林科学院智能装备技术研究中心&#xff09;近年来,人工智能技术蓬勃发展,大模型呈现出肆意生长之势,为各行各业带来新机遇。AutoML作为新一代自动化机器学习技术,承载着颠覆传统、引领变革的使命,正逐渐成为现代农业的"新宠"。本文将深入…

HCIP学习作业一 | HCIA复习

要求&#xff1a; R1-R2-R3-R4-R5 RIP 100 运行版本2 R6-R7 RIP 200 运行版本1 1.使用合理IP地址规划网络&#xff0c;各自创建环回接口 2.R1创建环回 172.16.1.1/24 172.16.2.1/24 172.16.3.1/24 3.要求R3使用R2访问R1环回 4.减少路由条目数量&#xff0c;R1-R2之间…

Suno声称在受版权保护的音乐上训练模型属于“合理使用“

继美国唱片业协会&#xff08;RIAA&#xff09; 最近对音乐生成初创公司 Udio 和 Suno 提起诉讼之后&#xff0c;Suno 在周四提交的一份法庭文件中承认&#xff0c;该公司确实使用了受版权保护的歌曲来训练其人工智能模型。但它声称&#xff0c;根据合理使用原则&#xff0c;这…

Uni-APP页面跳转问题(十六)

【背景】最近在做公司一个PAD端,谁被点检功能,主要时为了移动端点检设备和打印标签,需求比较简单就是扫描设备二维码,问题在于扫描后要能够重复进行多设备的扫描;早期开发的设备点检能够满足需求但是当连续扫描五六十个设备后,APP卡死,必须重启才能使用。 界面原图: 输…

智慧水务项目(四)django(drf)+angular 18 添加drf_yasg api接口文档

一、说明 文档api接口是必须的 本来准备用coreapi&#xff0c;据说drf_yasg更流弊 二、步骤 1、requirements.txt添加drf-yasg 2、settings.py中添加部分代码 drf_yasg需要与django.contrib.staticfiles配套使用&#xff0c;一般情况下&#xff0c;项目创建都会在INSTALLE…

PCG —— 基础使用

目录 一&#xff0c;基础知识 在关卡添加PCG资产 常见设置 调试 二&#xff0c;基础节点 Surface Sampler Static Mesh Spawner Transform Point Normal To Density Density Filter Bounds Modifier Self Prunning Difference Get Spline Data Spline Sampler …

LeetCode 热题 HOT 100 (015/100)【宇宙最简单版】

【栈】No. 0155 最小栈【中等】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#xff01; …

SAP EPPM-CPM(商业项目管理)模块简介

经过十几年的发展&#xff0c;SAP诞生了很多相关管理相关的模块&#xff0c;比如最经典的&#xff0c;无可替代的ERP核心组件之一的PS&#xff08;Project System&#xff09;模块&#xff0c;也有很多年历史的投资组合及项目管理PPM&#xff08;Portfolio Management and Proj…

GE电源维修 服务器 交换机电源维修CAR2512TE

GE电源维修 GV服务器电源维修 交换机电源维修 服务器电源模块维修的时候&#xff0c;我们先需要利用万用表检测一下各功率器件是否存在击穿短路&#xff0c;例如电源整流桥堆、开关管、高频大功率整流管、浪涌电流的大功率电阻是否烧断等&#xff0c;然后需要再检测各输出电压…

Kithara与Dlib (二) - 人脸实时检测

Kithara和Dlib进行人脸实时检测 目录 Kithara和Dlib进行人脸实时检测ResNet (残差网络)流程介绍核心代码性能测试开源源码 ResNet (残差网络) ResNet&#xff0c;全称为Residual Network&#xff08;残差网络&#xff09;&#xff0c;是由何凯明&#xff08;Kaiming He&#x…

飞瓜数据没有视频号爆款视频你就错过了涨粉的最新方法!

为了帮助用户更快的了解用户需求并切入视频号营销中&#xff0c;也为大家提供了更多的垂直类目。 飞瓜数据 飞瓜数据为很多视频平台提供了视频相关的数据服务&#xff0c;但我们发现并飞瓜并没有参与视频号相关的内容仅在视频号直播做了相关的扩展。视频号相关的数据并未提供。…

Java中等题-多数元素2(力扣)【摩尔投票升级版】

给定一个大小为 n 的整数数组&#xff0c;找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff1a;[3] 示例 2&#xff1a; 输入&#xff1a;nums [1] 输出&#xff1a;[1]示例 3&#xff1a; 输入&#xff1a;num…

队列的基本运算(顺序,环形,链式)

以下分别介绍了顺序队列&#xff0c;环形队列&#xff0c;链式队列的基本运算。主要有五种基本运算&#xff1a;1.初始化队列&#xff0c;2.销毁队列&#xff0c;3.判断队列是否为空&#xff0c;4.进队列&#xff0c;5.出队。 目录 顺序队列 环形队列 链式队列 顺序队列与环…

《LeetCode热题100》---<5.③普通数组篇五道>

本篇博客讲解LeetCode热题100道普通数组篇中的五道题 第五道&#xff1a;缺失的第一个正数&#xff08;困难&#xff09; 第五道&#xff1a;缺失的第一个正数&#xff08;困难&#xff09; 方法一&#xff1a;将数组视为哈希表 class Solution {public int firstMissingPosi…

频率的工程测量01 - Rif算法的构造

1.原始文档 《用于正弦波频率估计的修正I-Rife算法》&#xff0c;王哲文&#xff0c;2024 DOI&#xff1a; 10. 16337/j. 1004‑9037. 2024. 02. 019 1.1 这篇论文所属的自科基金U21A20500&#xff1a;近5年所承担的重要科研项目表-智能感知系统与安全教育部重点实验室&#…

位运算(更新中)

一、基础知识 1.基础位运算 << 左移操作符 &按位与 有0就是0 >>右移操作符 | 按位或 有1就是1 ~按位取反 ^异或 相同为1&#xff0c;相异为0 /…

大模型检索X一键成片,巴黎奥运的AI新演绎

媒体智能与巴黎奥运的一场邂逅。 随着巴黎奥运会开幕式为全世界掀起一场文艺浪潮&#xff0c;塞纳河畔也从浪漫艺术的盛宴&#xff0c;转向体育竞技的击攘。让全世界不可错过巴黎前方的每刻高光&#xff0c;更需要一场多媒体技术的迎赶革新。 于是&#xff0c;我们看到另一场媒…

现代前端架构介绍(第三部分):深入了解状态管理层及其对前端App的影响

远离JavaScript疲劳和框架大战&#xff0c;了解真正重要的东西 在第二部分中&#xff0c;我们讨论了功能架构的三个层次。其中一个就是状态管理层&#xff0c;今天我们将对其进行更深入的探讨。下面是现代前端架构系列的第三部分和最后一部分介绍。 状态管理&#xff0c;你可能…

抖音视频素材一般都从哪里找?抖音视频素材库分享

在浏览抖音时&#xff0c;你是否曾被那些内容丰富、制作精良的视频所吸引&#xff1f;这些视频背后的秘密其实非常简单——高质量的视频素材。优质素材能够让你的视频更加出彩。然而&#xff0c;许多抖音内容创作者在初期可能会困惑&#xff1a;这些视频素材究竟从哪里获取呢&a…

实现生成二维码,在table显示,图片预览可下载

utils/images/downLoadRemoteFile.js /*** 获取 blob 实现不跳转下载* param {String} url 目标文件地址* return {Promise}*/ const getBlob (url) > {return new Promise(resolve > {const xhr new XMLHttpRequest();xhr.open(GET, url, true);xhr.responseType b…