vue 中使用bpmn基础
vue中使用bpmn.js 绘制流程图项目中需要前端绘制流程图保存为xml通过接口调用传给后台npm安装bpmnnpm install bpmn-js --savenpm install bpmn-js-properties-panel --savenpm install bpmn-moddle --savenpm install camunda-bpmn-moddle --save上面四个插件安
·
vue中使用bpmn.js 绘制流程图
项目中需要前端绘制流程图保存为xml通过接口调用传给后台
npm安装bpmn
npm install bpmn-js --save
npm install bpmn-js-properties-panel --save
npm install bpmn-moddle --save
npm install camunda-bpmn-moddle --save
上面四个插件安装好
1.在使用页面引入 插件
import BpmnViewer from 'bpmn-js'
import BpmnModeler from "bpmn-js/lib/Modeler"; // bpmn-js 设计器
import propertiesPanelModule from 'bpmn-js-properties-panel'
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
//左边属性面板,汉化包
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
import customTranslate from './customTranslate'
/* 右边工具栏样式*/
import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css'
import 'bpmn-js/dist/assets/diagram-js.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
import BpmData from "./BpmData";
其他相关文件
BpmnData.js文件
/**
* 存储流程设计相关参数
*/
export default class BpmData {
constructor () {
this.controls = [] // 设计器控件
this.init()
}
init () {
this.controls = [
{
action: 'create.start-event',
title: '开始'
},
{
action: 'create.intermediate-event',
title: '中间'
},
{
action: 'create.end-event',
title: '结束'
},
{
action: 'create.exclusive-gateway',
title: '网关'
},
{
action: 'create.task',
title: '任务'
},
{
action: 'create.user-task',
title: '用户任务'
},
{
action: 'create.user-sign-task',
title: '会签任务'
},
{
action: 'create.subprocess-expanded',
title: '子流程'
},
{
action: 'create.data-object',
title: '数据对象'
},
{
action: 'create.data-store',
title: '数据存储'
},{
action: 'create.participant-expanded',
title: '扩展流程'
},
{
action: 'create.group',
title: '分组'
}
]
}
// 获取控件配置信息
getControl (action) {
const result = this.controls.filter(item => item.action === action)
return result[0] || {}
}
}
customTranslate.js
import translations from './translationsGerman'
export default function customTranslate(template, replacements) {
replacements = replacements || {}
// Translate
template = translations[template] || template
// Replace
return template.replace(/{([^}]+)}/g, function(_, key) {
var str = replacements[key]
if (translations[replacements[key]] != null && translations[replacements[key]] !== 'undefined') {
str = translations[replacements[key]]
}
return str || '{' + key + '}'
})
}
2.html代码
<template>
<div class="containers">
<div class="canvas" ref="canvas" />
<div id="js-properties-panel" class="panel"></div>
<div class="toolbar">
<a title="download">下载</a>
<a ref="saveDiagram1" href="javascript:" title="download BPMN diagram">BPMN</a>
<a ref="saveSvg" href="javascript:" title="download as SVG image">SVG</a>
</div>
</div>
</template>
2.js初始化
mounted() {
const canvas = this.$refs.canvas;
// 生成实例
this.bpmnModeler = new BpmnModeler({
container: canvas,
propertiesPanel: {
parent: '#js-properties-panel'
},
additionalModules: [
// 左边工具栏以及节点
propertiesProviderModule,
// 右边的工具栏
propertiesPanelModule,
{
translate: ['value', customTranslate]
}
],
moddleExtensions: {
camunda: camundaModdleDescriptor
}
});
// 获取a标签dom节点
const downloadLink = this.$refs.saveDiagram1;
const downloadSvgLink = this.$refs.saveSvg;
// 监听流程图改变事件
const _this = this;
this.bpmnModeler.on("commandStack.changed", function() {
_this.saveSVG(function(err, svg) {
_this.setEncoded(downloadSvgLink, "diagram.svg", err ? null : svg);
});
_this.saveDiagram1(function(err, xml) {
_this.setEncoded(downloadLink, "diagram.bpmn", err ? null : xml);
});
});
// 新增流程定义
this.createNewDiagram();
}
3.定义函数
methods: {
createNewDiagram() {
const bpmnXmlStr = `
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0bka6us" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.0.0">
<bpmn:process id="PSVMKKK" name="测试流程发布" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_0kaxh13</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:endEvent id="Event_061g5sm">
<bpmn:incoming>Flow_0t6sg2a</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0kaxh13" sourceRef="StartEvent_1" targetRef="Activity_145aizd" />
<bpmn:userTask id="Activity_145aizd" name="审批节点">
<bpmn:incoming>Flow_0kaxh13</bpmn:incoming>
<bpmn:outgoing>Flow_0t6sg2a</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_0t6sg2a" sourceRef="Activity_145aizd" targetRef="Event_061g5sm" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="PSVMKKK">
<bpmndi:BPMNEdge id="Flow_0t6sg2a_di" bpmnElement="Flow_0t6sg2a">
<di:waypoint x="410" y="117" />
<di:waypoint x="532" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0kaxh13_di" bpmnElement="Flow_0kaxh13">
<di:waypoint x="215" y="117" />
<di:waypoint x="310" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_061g5sm_di" bpmnElement="Event_061g5sm">
<dc:Bounds x="532" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0wfa4qo_di" bpmnElement="Activity_145aizd">
<dc:Bounds x="310" y="77" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
`;
// 将字符串转换成图显示出来
this.bpmnModeler.importXML(bpmnXmlStr, err => {
if (err) {
console.error(err);
} else {
this.adjustPalette();
}
});
},
// 调整左侧工具栏排版
adjustPalette() {
try {
// 获取 bpmn 设计器实例
const canvas = this.$refs.canvas;
const djsPalette = canvas.children[0].children[1].children[4];
const djsPalStyle = {
width: "130px",
padding: "5px",
background: "white",
left: "20px",
borderRadius: 0
};
for (var key in djsPalStyle) {
djsPalette.style[key] = djsPalStyle[key];
}
const palette = djsPalette.children[0];
const allGroups = palette.children;
allGroups[0].style["display"] = "none";
// 修改控件样式
for (var gKey in allGroups) {
const group = allGroups[gKey];
for (var cKey in group.children) {
const control = group.children[cKey];
const controlStyle = {
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
width: "100%",
padding: "5px"
};
if (
control.className &&
control.dataset &&
control.className.indexOf("entry") !== -1
) {
const controlProps = this.bpmData.getControl(
control.dataset.action
);
control.innerHTML = `<div style='font-size: 14px;font-weight:500;margin-left:15px;'>${
controlProps["title"]
}</div>`;
for (var csKey in controlStyle) {
control.style[csKey] = controlStyle[csKey];
}
}
}
}
} catch (e) {
console.log(e);
}
},
// 下载为SVG格式,done是个函数,调用的时候传入的
saveSVG(done) {
// 把传入的done再传给bpmn原型的saveSVG函数调用
this.bpmnModeler.saveSVG(done);
},
// 下载为SVG格式,done是个函数,调用的时候传入的
saveDiagram(done) {
// 把传入的done再传给bpmn原型的saveXML函数调用
let that=this
this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
that.submitData(xml)
// done(err, xml);
});
},
saveDiagram1(done){
this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
done(err, xml);
});
},
// 当图发生改变的时候会调用这个函数,这个data就是图的xml
setEncoded(link, name, data) {
// 把xml转换为URI,下载要用到的
const encodedData = encodeURIComponent(data);
// 获取到图的xml,保存就是把这个xml提交给后台
this.xmlStr = data;
// 下载图的具体操作,改变a的属性,className令a标签可点击,href令能下载,download是下载的文件的名字
if (data) {
link.className = "active";
link.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
link.download = name;
}
},
}
更多推荐
已为社区贡献2条内容
所有评论(0)