集成Activiti-Modeler流程设计器

集成Activiti-Modeler流程设计器

Activiti Modeler 是 Activiti 官方提供的一款在线流程设计的前端插件,可以方便流程设计与开发人员绘制流程图,保存流程模型,部署至流程定义等等。

1、材料准备
首先我们需要获取activiti-explorer.zip,这个是activiti-5.22.0才有的。

链接:https://pan.baidu.com/s/1zZ8vcjR63_hgzcLl6soiDw
提取码:1e8a

2、集成
2.1 集成静态资源

在这里插入图片描述
其中的editor-app就是编辑器,modeler.html是编辑器的入口页面。
diagram-viewer是流程跟踪插件,虽然这次用不着,但之后会用到。

还有一个界面组件文件,在resource下,名称叫stencilset.json。本身是英文的,可以通过替换它来达到汉化的效果。但现在还是先把它放到项目中去。
在这里插入图片描述
在editor-app/app-cfg.js中配置一下项目url。这个url是编辑器相关的后台服务的url。

ACTIVITI.CONFIG = {'contextRoot' : '/service',
};

我去掉了项目名。

3.后端部分
先引入两个activiti的模块,因为编辑器会用到这两个模块。

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

其中需要将modeler模块的源代码放到src中,因为需要在其中做部分修改,主要是url的映射。

源码:
https://github.com/Activiti/Activiti/tree/master/modules/activiti-modeler

其中有3个类,都是Controller:

StencilsetRestResource #获取编辑器组件及配置项信息。
ModelEditorJsonRestResource #根据modelId获取model的节点信息,编辑器根据返回的json进行绘图。
ModelSaveRestResource #编辑器制图之后,将节点信息以json的形式提交给这个Controller,然后由其进行持久化操作。

需要修改的地方就三个,在每个Controller类上加上@RequestMapping注解,并指定值为"service"(对应前台app-cfg.js中配置的url)。

···
@RequestMapping("service")
public class StencilsetRestResource {
···
···
@RequestMapping("service")
public class ModelEditorJsonRestResource implements ModelDataJsonConstants {
···
···
@RequestMapping("service")
public class ModelSaveRestResource implements ModelDataJsonConstants {
···

最后别忘了添加包扫描,扫描activiti提供的这些controller。

@SpringBootApplication
@ComponentScan({"org.activiti","com.jerryl"})
public class SpringBootWithActivitiApplication {
···

这样整合部分就基本结束了,此时编辑器已经可以使用了。

至于界面的汉化,界面上各个组件,各个标签上的文字都是在resource下的stencilset.json文件中设置的,可以在网上找一个汉化后的stencilset.json文件替换掉,就能看到中文界面了。

modeler相关方法的封装
主要需要封装4个方法:1.新建一个空的模型;2.所有模型列表;3.发布模型;4.删除模型;(activiti已提供了保存和获取模型节点信息的方法,就是上面的那3个类)
由于这里涉及前后端交互,实现方式随意,主要是activiti的api的调用。

参考代码:

/*** Created by liuruijie on 2017/2/21.* 模型管理*/
@RestController
@RequestMapping("models")
public class ModelerController {@AutowiredProcessEngine processEngine;@AutowiredObjectMapper objectMapper;/*** 新建一个空模型* @return* @throws UnsupportedEncodingException*/@PostMappingpublic Object newModel() throws UnsupportedEncodingException {RepositoryService repositoryService = processEngine.getRepositoryService();//初始化一个空模型Model model = repositoryService.newModel();//设置一些默认信息String name = "new-process";String description = "";int revision = 1;String key = "process";ObjectNode modelNode = objectMapper.createObjectNode();modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);model.setName(name);model.setKey(key);model.setMetaInfo(modelNode.toString());repositoryService.saveModel(model);String id = model.getId();//完善ModelEditorSourceObjectNode editorNode = objectMapper.createObjectNode();editorNode.put("id", "canvas");editorNode.put("resourceId", "canvas");ObjectNode stencilSetNode = objectMapper.createObjectNode();stencilSetNode.put("namespace","http://b3mn.org/stencilset/bpmn2.0#");editorNode.put("stencilset", stencilSetNode);repositoryService.addModelEditorSource(id,editorNode.toString().getBytes("utf-8"));return ToWeb.buildResult().redirectUrl("/modeler.html?modelId="+id);}/*** 获取所有模型* @return*/@GetMappingpublic Object modelList(){RepositoryService repositoryService = processEngine.getRepositoryService();List<Model> models = repositoryService.createModelQuery().list();return ToWeb.buildResult().putData("models", models);}/*** 删除模型* @param id* @return*/@DeleteMapping("{id}")public Object deleteModel(@PathVariable("id")String id){RepositoryService repositoryService = processEngine.getRepositoryService();repositoryService.deleteModel(id);return ToWeb.buildResult().refresh();}/*** 发布模型为流程定义* @param id* @return* @throws Exception*/@PostMapping("{id}/deployment")public Object deploy(@PathVariable("id")String id) throws Exception {//获取模型RepositoryService repositoryService = processEngine.getRepositoryService();Model modelData = repositoryService.getModel(id);byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());if (bytes == null) {return ToWeb.buildResult().status(Config.FAIL).msg("模型数据为空,请先设计流程并成功保存,再进行发布。");}JsonNode modelNode = new ObjectMapper().readTree(bytes);BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);if(model.getProcesses().size()==0){return ToWeb.buildResult().status(Config.FAIL).msg("数据模型不符要求,请至少设计一条主线流程。");}byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);//发布流程String processName = modelData.getName() + ".bpmn20.xml";Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes, "UTF-8")).deploy();modelData.setDeploymentId(deployment.getId());repositoryService.saveModel(modelData);return ToWeb.buildResult().refresh();}
}

springboot静态文件处理

@Configuration
public  class WebConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry){registry.addResourceHandler("/html/**").addResourceLocations("classpath:/html/");registry.addResourceHandler("/diagram-viewer/**").addResourceLocations("classpath:/html/");registry.addResourceHandler("/editor-app/**").addResourceLocations("classpath:/html/");registry.addResourceHandler("/js/**").addResourceLocations("classpath:/js/");registry.addResourceHandler("/css/**").addResourceLocations("classpath:/css/");}
}

获取json数据的请求

@RestController
public class Test01Controller {@RequestMapping("/editor/stencilset")public String test01(){InputStream stream=this.getClass().getClassLoader().getResourceAsStream("stencilset.json");try{return IOUtils.toString(stream,"utf-8");}catch (Exception e){}return null;}
}

在线设计流程新建model

@Controller
@RequestMapping("model")
public class ModelTest {@RequestMapping("create")public void createModel(HttpServletRequest request, HttpServletResponse response){try{String modelName = "modelName6";String modelKey = "modelKey66";String description = "modelKey666";ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();ObjectMapper objectMapper = new ObjectMapper();ObjectNode editorNode = objectMapper.createObjectNode();editorNode.put("id", "canvas");editorNode.put("resourceId", "canvas");ObjectNode stencilSetNode = objectMapper.createObjectNode();stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");editorNode.put("stencilset", stencilSetNode);Model modelData = repositoryService.newModel();ObjectNode modelObjectNode = objectMapper.createObjectNode();modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, modelName);modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);modelData.setMetaInfo(modelObjectNode.toString());modelData.setName(modelName);modelData.setKey(modelKey);//保存模型repositoryService.saveModel(modelData);repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));response.sendRedirect(request.getContextPath() + "/html/modeler.html?modelId=" + modelData.getId());}catch (Exception e){}}}

画流程图保存请求

@RequestMapping("/model/{modelId}/save")@ResponseStatus(HttpStatus.OK)public void saveModel(@PathVariable String modelId, HttpServletRequest req, HttpServletResponse resp) {try {Model model = this.repositoryService.getModel(modelId);ObjectNode modelJson = (ObjectNode)this.objectMapper.readTree(model.getMetaInfo());modelJson.put("name", req.getParameter("name"));modelJson.put("description",req.getParameter("description"));model.setMetaInfo(modelJson.toString());model.setName(req.getParameter("name"));this.repositoryService.saveModel(model);this.repositoryService.addModelEditorSource(model.getId(), (req.getParameter("json_xml")).getBytes("utf-8"));InputStream svgStream = new ByteArrayInputStream((req.getParameter("svg_xml")).getBytes("utf-8"));TranscoderInput input = new TranscoderInput(svgStream);PNGTranscoder transcoder = new PNGTranscoder();ByteArrayOutputStream outStream = new ByteArrayOutputStream();TranscoderOutput output = new TranscoderOutput(outStream);transcoder.transcode(input, output);byte[] result = outStream.toByteArray();System.out.println(new String(result,"utf-8"));this.repositoryService.addModelEditorSourceExtra(model.getId(), result);outStream.close();} catch (Exception var11) {LOGGER.error("Error saving model", var11);throw new ActivitiException("Error saving model", var11);}}

流程图查看的请求

@RequestMapping(value = {"/model/{modelId}/json"},method = {RequestMethod.GET},produces = {"application/json"})public ObjectNode getEditorJson(@PathVariable String modelId) {ObjectNode modelNode = null;Model model = this.repositoryService.getModel(modelId);if (model != null) {try {if (StringUtils.isNotEmpty(model.getMetaInfo())) {modelNode = (ObjectNode)this.objectMapper.readTree(model.getMetaInfo());} else {modelNode = this.objectMapper.createObjectNode();modelNode.put("name", model.getName());}modelNode.put("modelId", model.getId());ObjectNode editorJsonNode = (ObjectNode)this.objectMapper.readTree(new String(this.repositoryService.getModelEditorSource(model.getId()), "utf-8"));modelNode.put("model", editorJsonNode);} catch (Exception var5) {LOGGER.error("Error creating model JSON", var5);throw new ActivitiException("Error creating model JSON", var5);}}return modelNode;}

流程图保存成功以后ACT_RE_MODEL这张表会有数据

在这里插入图片描述

程图部署以后ACT_GE_BYTEARRAY会出现bomn结尾的文件
在这里插入图片描述

部署流程的请求,根据modelId

@RequestMapping("/model/test02")public void test02(Object obj) throws Exception {Model modelData = repositoryService.getModel("40001");ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));byte[] bpmnBytes = null;BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);bpmnBytes = new BpmnXMLConverter().convertToXML(model);String processName = modelData.getName() + ".bpmn";Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes,"UTF-8")).deploy();}

根据这个表的key进行流程启动,指定审批人
在这里插入图片描述

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

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

相关文章

浅析AI视频智能分析系统人脸检测算法的应用与特点

AI人脸检测算法可以提取人脸和服装的特征&#xff0c;并将其分类为有用的类别&#xff0c;例如性别、年龄和服装颜色。通过搜索这些丰富的属性信息&#xff0c;可以帮助我们轻松找到目标人物&#xff0c;比如通过人脸以图搜图、人脸布控等等。 如何搭建重点部位人脸识别动态布控…

私域流量的优势

私域流量是指由自身品牌或个人拥有并具备完全掌控权的流量资源。它相比于传统的广告推广&#xff0c;拥有独特的优势。 首先&#xff0c;私域流量能够更加精准地定位目标用户&#xff0c;实现精准传播。不再盲目投放广告&#xff0c;而是通过建立自身社群、粉丝群&#xff0c;获…

C语言经典100例题(56-60)--画圆;画方;画线

目录 【程序56】题目&#xff1a;画图&#xff0c;学用circle画圆形 【程序57】题目&#xff1a;画图&#xff0c;学用line画直线。 【程序58】题目&#xff1a;画图&#xff0c;学用rectangle画方形。 【程序59】题目&#xff1a;画图&#xff0c;综合例子。 【程序60】题…

【设计模式】三、概述分类+单例模式

文章目录 概述设计模式类型 单例模式饿汉式&#xff08;静态常量&#xff09;饿汉式&#xff08;静态代码块&#xff09;懒汉式(线程不安全)懒汉式(线程安全&#xff0c;同步方法)懒汉式(线程安全&#xff0c;同步代码块)双重检查静态内部类枚举单例模式在 JDK 应用的源码分析 …

IP协议详解

目录 一、IP协议头格式 二、IP地址、Mac地址 2.1 IPv4 2.2 IPv6 2.3 Mac地址 三、IP路由转发 四、IP分包及组包 一、IP协议头格式 IP协议是网络层的重点协议。这里主要列举一下16位标识与3位标志以及13位片偏移。 16位标识&#xff08;id&#xff09;&#xff1a;唯一的标识主…

查询IP地址可得到哪些信息

通过IP地址定位&#xff0c;可以获取一些基本的信息&#xff0c;包括以下内容&#xff1a; 1. 地理位置&#xff1a;你可以确定IP地址所在的地理位置&#xff0c;包括国家、州或省、城市和地理坐标。这通常是通过将IP地址与地理位置数据库进行匹配来实现的。 2. ISP&#xff…

spi协议精讲

spi 总线是一种 高速的、全双工&#xff0c;同步串行总线&#xff0c;有四根线MISO MOSI SCLK CS 2.通信过程 3.极性和相位 因为没有像iic一样规定上升沿还是下降沿发送数据&#xff0c;spi的通信取决于极性和相位&#xff0c;因此有四种工作模式 CPHA0 表示SCK 第一个边沿时&…

RocketMQ实践与原理分析(Docker安装RocketMQ)

前言 QBM之前使用的消息中间件是ActiveMQ&#xff0c;后续需要升级为RocketMQ。 MQ广泛应用于很多业务场景中&#xff0c;主要的作用 异步解耦削峰… 常用MQ中间件对比&#xff0c;参考官方文档&#xff1a;https://rocketmq.apache.org/zh/docs/4.x/introduction/03whatis…

mysql课堂笔记 mac

目录 启动mac上的mysql 进入mysql mac windows 创建数据库 创建表 修改字段数据类型 修改字段名 增加字段 删除字段 启动mac上的mysql sudo /usr/local/mysql/support-files/mysql.server start 直接输入你的开机密码即可。 编辑 进入mysql mac sudo /usr/local…

博客系统(升级(Spring))(四)(完)基本功能(阅读,修改,添加,删除文章)(附带项目)

博客系统 (三&#xff09; 博客系统博客主页前端后端个人博客前端后端显示个人文章删除文章 修改文章前端后端提取文章修改文章 显示正文内容前端后端文章阅读量功能 添加文章前端后端 如何使用Redis项目地点&#xff1a; 博客系统 博客系统是干什么的&#xff1f; CSDN就是一…

去耦电路设计应用指南(三)磁珠/电感的噪声抑制

&#xff08;三&#xff09;磁珠/电感的噪声抑制 1. 电感1.1 电感频率特性 2. 铁氧体磁珠3. LC 型和 PI 型滤波 当去耦电容器不足以抑制电源噪声时&#xff0c;电感器&磁珠/ LC 滤波器的结合使用是很有效的。扼流线圈与铁氧体磁珠 是用于电源去耦电路很常见的电感器。 1. …

MC-4/11/01/400 ELAU 软件允许用户完全访问相机设置

MC-4/11/01/400 ELAU 软件允许用户完全访问相机设置 一个完整的Sentinel模具保护解决方案包括一到四台冲击式摄像机、专用红外LED照明和镜头、Sentinel软件以及所有与模压机连接的必要互连组件。摄像机支架基于磁性&#xff0c;可快速、安全、灵活地部署。此外&#xff0c;一个…