第一章 springboot+Activiti7整合实践 (一)
第二章 springboot+Activiti7整合实践 (二) 模型定义
此章节主要介绍流程定义的整体概念,此部分对于后端难度不大,前端需要对bpmnjs有一定的学习了解。
业务流程建模标记法“?Business Process Modeling Notation”,是定义业务流程通用标准语言。
bpmn-js是一个BPMN2.0渲染工具包和web建模器, 使得画流程图的功能在前端来完成。
?
最终生成xml代码,如下图
?
npm i bpmn-js --save-D 或使用yarn add 方式都可
// xxx.vue
<template>
<div class="containers">
<div class="canvas" ref="canvas"></div>
</div>
</template>
<script>
// 引入相关的依赖
import BpmnModeler from 'bpmn-js/lib/Modeler'
import {
xmlStr
} from '../mock/xmlStr' // 这里是直接引用了xml字符串
export default {
name: '',
components: {},
// 生命周期 - 创建完成(可以访问当前this实例)
created() { },
// 生命周期 - 载入后, Vue 实例挂载到实际的 DOM 操作完成,一般在该过程进行 Ajax 交互
mounted() {
this.init()
},
data() {
return {
// bpmn建模器
bpmnModeler: null,
container: null,
canvas: null
}
},
methods: {
init() {
// 获取到属性ref为“canvas”的dom节点
const canvas = this.$refs.canvas
// 建模
this.bpmnModeler = new BpmnModeler({
container: canvas
})
this.createNewDiagram()
},
createNewDiagram() {
// 将字符串转换成图显示出来
this.bpmnModeler.importXML(xmlStr, (err) => {
if (err) {
// console.error(err)
} else {
// 这里是成功之后的回调, 可以在这里做一系列事情
this.success()
}
})
},
success() {
// console.log('创建成功!')
}
}
}
</script>
以上为最基础的创建方式,涉及到左侧工具栏自定义,面板属性与xml对应关系等,这里不做介绍,可以参考一下文章来学习,以上基础使用内页也出自这里。
作者:LinDaiDai_霖呆呆
链接:https://juejin.cn/post/6844904017584193544
来源:稀土掘金
直接复制到我们的工程里,这个组件是与bpmn-js的前端设计功能界面,包含元素、面板、工具栏等功能,右侧图片介绍重要的功能文件。
(2)复制modelEditor.vue到合适的views下目录,此页面中引入上面的流程设计组件,整体是一个dialog。
此页面需要根据自己设计的前后端交互方式,修改关键的模型新增、更新、删除等接口即可,如有其他定制化修改,可修改相关组件中的内容(后面做会签的时候,修改了一下一下内容),主要功能其实就是当操作bpmn界面的时候,出发的一些事件,在事件中修改所生成的xml文件的关键属性,从而使改动生效,关键方法updateProperties(),功能即是修改某个bpmn元素的属性,即修改最终的xml。
接下来要做的就是点击列表页面的流程设计按钮,显示这个modelEditor.vue页面,效果如下。
对应设计图及xml文件,可大致了解一下bpmn元素的类名,如这里用到的采样、收样的用户任务,对应的元素类即为UserTask
修改modelEditor.vue 里的save方法,对应自己后台方法即可。
后台代码:
public String createModel(BpmModelCreateReqVO createReqVO, String bpmnXml) {
// 校验流程标识已经存在
Model keyModel = getModelByKey(createReqVO.getKey());
if (keyModel != null) {
throw new RuntimeException("流程标识已存在");
}
// 创建流程定义
Model model = repositoryService.newModel();
copy(model, createReqVO);
// 保存流程定义
repositoryService.saveModel(model);
// 保存 BPMN XML
saveModelBpmnXml(model, bpmnXml);
return model.getId();
}
@Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务
public void updateModel(BpmModelCreateReqVO updateReqVO) {
// 校验流程模型存在
Model model = repositoryService.getModel(updateReqVO.getId());
if (model == null) {
throw new RuntimeException("流程不存在");
}
// 修改流程定义
copy(model, updateReqVO);
// 更新模型
repositoryService.saveModel(model);
// 更新 BPMN XML
saveModelBpmnXml(model, updateReqVO.getBpmnXml());
// 更新 BPMN XML
//saveModelBpmnXml(model, updateReqVO.getBpmnXml());
}
@Transactional(rollbackFor = Exception.class)
public BpmnModel getBpmnModel(String id) {
byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
if (ArrayUtil.isEmpty(bpmnBytes)) {
return null;
}
BpmnXMLConverter converter = new BpmnXMLConverter();
return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true);
}
/**
* 根据key获得Model定义
* */
private Model getModelByKey(String key) {
return repositoryService.createModelQuery().modelKey(key).singleResult();
}
@Transactional(rollbackFor = Exception.class)
public void deleteModel(String id) {
// 校验流程模型存在
Model model = repositoryService.getModel(id);
if (model == null) {
throw new RuntimeException("流程模型不存在");
}
// 执行删除
repositoryService.deleteModel(id);
// 禁用流程定义
if(StringUtil.isNotEmpty(model.getDeploymentId())){
ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
processDefinitionService.suspendOrActiveApply(oldDefinition.getId(),1);
}
}
private void copy(Model model, BpmModelCreateReqVO bean) {
model.setName(bean.getName());
model.setKey(bean.getKey());
Map<String,Object> mapMetaInfo = new HashMap<>();
mapMetaInfo.put("description",bean.getDescription());
model.setMetaInfo(JSONUtil.toJsonStr(mapMetaInfo));
}
/**
* 保存bpmnXml字符串
* */
private void saveModelBpmnXml(Model model, String bpmnXml) {
if (StrUtil.isEmpty(bpmnXml)) {
return;
}
repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml));
}
我们前端流程设计使用的是芋道的设计,芋道讲用户任务的用户分配在设计流程时去除掉了,单独分离来,放到分配规则里,也是我们接下来要介绍给大家的功能,这样的设计使用户便于通过点选的方式来设计任务的代办人,使用芋道的根本原因也是如此。
可以看一下ruoyi和芋道的对比,ruoyi依据原生,使用html文件展示,对基本逻辑未作改动,保留了设计功能。
到此章节,其实是将基础的工作流前端设计与后端的初步结合,主要做的工作还是讲芋道的前端设计文件放到我们的项目中,这其中需要大家下功夫去了解bpmn-js更多的内容,最好先去了解怎么自定义属性面板,自定义工具栏,就能了解其中的关键点。