环境

activiti:5.22.0
springboot:2.5.1

前言

默认已经Springboot2整合activiti5完毕;
可以参考:springboot2整合activiti5.22 maven版

这篇文章是接着上面文章写的。

activiti5.22官方编辑器

网上很多都是使用idea或者eclipse插件来画图,这种根据就没法用,代码部署上线后,肯定需要在线编辑器才能满足业务的使用;

期望如下效果:

思路

我们已经把activiti整合完毕;官方其实提供了编辑器,我们可以思考下,编辑器需要哪些东西:

  1. 前端代码:渲染画图、增删改查的组件显示;
  2. 后端代码:对应画图页面中的保存、查询等接口;

前端代码

根据网上的资料,我们需要在activiti官方源码中找到如下东西:

前端代码 描述
editor-app 编辑器
modeler.html 编辑器的入口页面
diagram-viewer 流程跟踪插件,虽然这次用不着,但之后会用到
stencilset.json 本身是英文的,可以通过替换它来达到汉化的效果。
favicon.ico 一个logo

先下载源码

https://github.com/Activiti/Activiti/tree/activiti-5.22.0

源码路径:activiti-webapp-explorer2模块中webappresource中。

放入自己的项目中:

说明:

  1. diagram-viewereditor-appfavicon.icomodeler.htmlstencilset.json移动到自己项目static文件夹中。
  2. model-list.html不是官方的,是新建流程的入口页面,自己编写的前端代码。

editor-app/app-cfg.js中配置一下项目url。这个url是编辑器相关的后台服务的url。

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

后端代码

先引入两个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>

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

其中有3个类,都是Controller:

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


个人项目存放的位置:

需要修改的地方就三个,在每个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

如果启动类和上面放的类都在一个包下,就不用添加。

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

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

但是入口页面得我们自己写,效果如下:

接下来,我们就要自己去设计这个页面,下面贴出后端代码,前端代码参考文章最后的源码链接;

modeler相关方法的封装

主要需要封装4个方法:

  1. 新建一个空的模型;
  2. 所有模型列表;
  3. 发布模型;
  4. 删除模型;

(activiti已提供了保存和获取模型节点信息的方法,就是上面的那3个类)
由于这里涉及前后端交互,实现方式随意,主要是activiti的api的调用。

下面只贴出 参考代码,demo,请参考文章最后的链接。

模型管理类

package com.sgy.flowactiviti.admin.controller;import org.springframework.web.bind.annotation.*;import java.io.Serializable;/*** restful的基本规范*/
public interface RestServiceController<T, ID extends Serializable> {/*** 根据id查询资源* @param id 资源的唯一标识* @return*/@GetMapping("{id}")Object getOne(@PathVariable("id") ID id);/*** 列表分页* @param rowSize 一页数据大小* @param page 当前页码* @return*/@GetMappingObject getList(@RequestParam(value = "rowSize", defaultValue = "1000", required = false) Integer rowSize, @RequestParam(value = "page", defaultValue = "1", required = false) Integer page);/*** 提交一个资源* @param entity 资源实体* @return*/@PostMappingObject postOne(@RequestBody T entity);/*** 提交一个资源,并给出标识* @param id 标识* @param entity 资源实体* @return*/@PutMapping("{id}")Object putOne(@PathVariable("id") ID id, @RequestBody T entity);/*** 提交一个资源的一部分,不处理null值* @param id 标识* @param entity 资源实体* @return*/@PatchMapping("{id}")Object patchOne(@PathVariable("id") ID id, @RequestBody T entity);/*** 根据id删除一个资源* @param id 标识* @return*/@DeleteMapping("{id}")Object deleteOne(@PathVariable("id") ID id);
}

具体实现:

package com.sgy.flowactiviti.admin.controller;import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.sgy.flowactiviti.admin.util.Status;
import com.sgy.flowactiviti.admin.util.ToWeb;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.io.UnsupportedEncodingException;
import java.util.List;/*** 模型管理*/
@RestController
@RequestMapping("models")
public class ModelerController implements RestServiceController<Model, String> {@AutowiredRepositoryService repositoryService;@AutowiredObjectMapper objectMapper;/*** 新建一个空模型* @return* @throws UnsupportedEncodingException*/@PostMapping("newModel")public Object newModel() throws UnsupportedEncodingException {//初始化一个空模型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("/editor?modelId="+id);}/*** 发布模型为流程定义* @param id* @return* @throws Exception*/@PostMapping("{id}/deployment")public Object deploy(@PathVariable("id")String id) throws Exception {//获取模型Model modelData = repositoryService.getModel(id);byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());if (bytes == null) {return ToWeb.buildResult().status(Status.FAIL).msg("模型数据为空,请先设计流程并成功保存,再进行发布。");}JsonNode modelNode = new ObjectMapper().readTree(bytes);BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);if(model.getProcesses().size()==0){return ToWeb.buildResult().status(Status.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();}@Overridepublic Object getOne(@PathVariable("id") String id) {Model model = repositoryService.createModelQuery().modelId(id).singleResult();return ToWeb.buildResult().setObjData(model);}@Overridepublic Object getList(@RequestParam(value = "rowSize", defaultValue = "1000", required = false) Integer rowSize, @RequestParam(value = "page", defaultValue = "1", required = false) Integer page) {List<Model> list = repositoryService.createModelQuery().listPage(rowSize * (page - 1), rowSize);long count = repositoryService.createModelQuery().count();return ToWeb.buildResult().setRows(ToWeb.Rows.buildRows().setCurrent(page).setTotalPages((int) (count/rowSize+1)).setTotalRows(count).setList(list).setRowSize(rowSize));}public Object deleteOne(@PathVariable("id")String id){repositoryService.deleteModel(id);return ToWeb.buildResult().refresh();}@Overridepublic Object postOne(@RequestBody Model entity) {throw new UnsupportedOperationException();}@Overridepublic Object putOne(@PathVariable("id") String s, @RequestBody Model entity) {throw new UnsupportedOperationException();}@Overridepublic Object patchOne(@PathVariable("id") String s, @RequestBody Model entity) {throw new UnsupportedOperationException();}
}

前端代码,你们就参考链接吧:

https://github.com/b3601993/spring-boot-with-activiti

总结

总体最麻烦的可能就是模型列表前端页面相关的代码,因为这块得我们自己去实现设计。
对于我后端人员来说,真的太难受了。

参考地址:

【activiti】整合官方编辑器插件

activiti5.22整合官方编辑器相关推荐

  1. Activiti-5.22.0——activiti-modeler界面设计组件介绍

    目录 1.启动事件(Start Events): (1)无启动事件(Start event): A.描述: B.图标: (2)计时器事件(Start timer event): A.描述: B.图标: ...

  2. 织梦DEDECMS 整合Kindeditor编辑器美化版nkeditor版可H5多图上传摒弃SWF上传

    织梦插件说明 织梦DEDECMS 整合Kindeditor编辑器美化版nkeditor版可H5多图上传摒弃SWF上传(UTF版) 本修改整合了Kindeditor编辑器美化版 功能: 1.可多图上传( ...

  3. ckeditor5 图片上传,tp5整合ckeditor5编辑器使用

    ** 更新:2019年1月29,"ckeditor5 图片上传,tp5整合ckeditor5编辑器使用"之前放的ckeditor.js文件过期,现已更新可用,同时提供可下载的cke ...

  4. springmvc整合百度编辑器

    前言 最近搭建个人博客站,少不了编辑器的整合,现在就分享下springMVC整合百度编辑器的一些心得. 简单步骤 1.百度编辑器官网下载开发版的完整源码.官网地址,点我进去 可以选择最新的jsp的ut ...

  5. vue整合文本编辑器

    场景说明: 后端输入一篇文章,在前端显示,这时就有个排版问题了.单纯的文本输入框无法满足要求. 所以需要采用后端整合文本编辑器,前端(vue)采用v-html标签直接渲染 小编的示例是整合vue 0. ...

  6. SpringBoot 整合activiti5.22 实现一个完整的请假流程

    最近在熟悉activiti的使用,翻阅了很多资料,自己也整理了一点出来方便以后自己使用 一.引入依赖 <dependencies><dependency><groupId ...

  7. 全网最新Spring Boot2.5.1整合Activiti5.22.0企业实战教程<监听器篇>

    文章目录 前言 一.执行监听器 1.1 处理任务 1.2 事件类型 1.3 实例代码 二.任务监听器 1.1 处理任务 1.2 事件类型 1.3 实例代码 三.实例结果 1.启动流程 2.执行任务 总 ...

  8. 全网最新Spring Boot2.5.1整合Activiti5.22.0企业实战教程<流程挂起与激活篇>

    文章目录 前言 一.单个流程实例挂起 1.1 部署流程 1.2 启动流程 1.3 挂起流程(suspendProcessInstanceById) 1.4 执行任务 1.5 激活流程(activate ...

  9. 全网最新Spring Boot2.5.1整合Activiti5.22.0企业实战教程<指定任务委派人篇>

    文章目录 前言 一.流程设计 二.部署流程 二.启动流程实例 二.我的待办任务 三.指定委派人 四.执行任务 总结 前言 任务委派人:任务负责人. 简单的来说就是,我们可以指定多个备胎,帮我去完成流程 ...

最新文章

  1. 数组的相关操作2——筛选数组
  2. Fiddler抓包工具之Filters(过滤器)进行会话过滤
  3. php 发帖代码,我的论坛源代码(四)_php
  4. python和java学哪个好-Python和Java两门编程语言,学习哪个更好?
  5. matlab时频工具箱简介,matlab时频分析工具箱下载_matlab时频分析工具箱官方下载-太平洋下载中心...
  6. mariadb mysql.sock_数据库缺少mysql.sock文件的解决办法
  7. 忘记保护密码情况下卸载瑞星杀毒软件
  8. C#开发微信订阅号、服务号视频教程-翟东平-专题视频课程
  9. CSS( Cascading Style Sheets )简书
  10. Cent OS安装中文字体
  11. visual studio进入时许可证已过期解决方案
  12. CUDA C/C++ 流和并发
  13. 放大招!百味勺子硬件设计篇
  14. python数据分析基础试题_Python数据分析基础知识
  15. vs qt中增加png图标
  16. 内存管理---内存释放
  17. 微图中的高程DEM数据说明
  18. windows下通过uiAutomation技术获取ui元素
  19. 润乾报表中API动态合并格,连续显示行号
  20. 二维码与QR code

热门文章

  1. 4个最好的在线漫画生成器,轻松创作漫画
  2. 二手车 电商+互联网金融的三种新玩法
  3. Oracle全文索引
  4. 使用lnmp安装zabbix3.4.4并设置163邮箱报警(超详细)
  5. 三点法求点三维坐标实验
  6. remount of the / superblock failed: Permission denied remount failed
  7. 计算机关闭后剪切板的内容会消失,清除win10剪贴板历史记录,保证隐私数据不泄露...
  8. Android 13新特性:自动清除剪贴板历史记录
  9. ES6 — Promise基础用法详解(resolve、reject、then、catch,all,)
  10. 举个栗子!Tableau 技巧(138):学做炫酷的温度计图表