Files
hcframe-doc/docs/.vuepress/components/Bpmn/bpmn.vue
2021-02-03 17:01:33 +08:00

307 lines
8.9 KiB
Vue

<template>
<div class="container">
<div class="bpmn-container">
<div ref="canvas" class="bpmn-canvas" />
<div id="js-properties-panel" class="bpmn-js-properties-panel" />
</div>
<div class="action">
<el-upload action class="upload-demo" :before-upload="openBpmn">
<el-button icon="el-icon-folder-opened" />
</el-upload>
<el-button class="new" icon="el-icon-circle-plus" @click="newDiagram" />
<el-button icon="el-icon-download" @click="downloadBpmn" />
<el-button icon="el-icon-picture" @click="downloadSvg" />
<el-button v-if="updateDate!=undefined" icon="el-icon-upload" @click="handleUpdateData" />
<a ref="downloadLink" hidden />
</div>
</div>
</template>
<script>
import BpmnModeler from "bpmn-js/lib/Modeler";
import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
import propertiesPanelModule from "bpmn-js-properties-panel";
import camundaModdleDescriptor from "camunda-bpmn-moddle/resources/camunda";
import customTranslate from "./customTranslate/customTranslate";
export default {
name: "Bpmn",
props: {
updateBpmnFlag: {
type: Boolean,
default: false,
},
updateDate: {
default: null,
},
},
data() {
return {
bpmnModeler: null,
canvas: null,
bpmnTemplate: `
<?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:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:activiti="http://activiti.org/bpmn"
id="m1577635100724"
name=""
targetNamespace="http://www.activiti.org/testm1577635100724"
>
<process id="process" name="" processType="None" isClosed="false" isExecutable="true">
<extensionElements>
<camunda:properties>
</camunda:properties>
</extensionElements>
<startEvent id="_2" name="start" />
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_leave">
<bpmndi:BPMNPlane id="BPMNPlane_leave" bpmnElement="leave">
<bpmndi:BPMNShape id="BPMNShape__2" bpmnElement="_2">
<omgdc:Bounds x="144" y="368" width="32" height="32" />
<bpmndi:BPMNLabel>
<omgdc:Bounds x="149" y="400" width="23" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
`,
bpmnNameFrom: null,
editBpmnFile: null,
};
},
mounted() {
this.$nextTick(() => {
if (this.updateDate != undefined) {
this.initUpdateDate();
}
this.initBpmn();
});
},
methods: {
initUpdateDate() {
if (this.updateBpmnFlag) {
const updateDate = this.updateDate.replace(new RegExp("activiti:", "gm"), "camunda:");
this.editBpmnFile = this.updateDate;
} else {
this.bpmnNameFrom = this.updateDate;
}
},
async initBpmn() {
this.canvas = this.$refs.canvas;
const customTranslateModule = {
translate: ["value", customTranslate],
};
this.bpmnModeler = new BpmnModeler({
container: this.canvas,
propertiesPanel: {
parent: "#js-properties-panel"
},
additionalModules: [
propertiesProviderModule,
propertiesPanelModule,
customTranslateModule,
],
moddleExtensions: {
camunda: camundaModdleDescriptor,
},
});
if (this.updateBpmnFlag) {
await this.createNewDiagram(this.editBpmnFile);
} else {
await this.createNewDiagram(this.bpmnTemplate);
}
},
replaceString(xml, nodeName, property, propertyLength, replaceChar) {
const node = xml.indexOf(nodeName);
let xmlName = xml.substr(node, xml.indexOf(property));
const begin = node + xmlName.indexOf(property) + propertyLength;
xmlName = xmlName.substr(xmlName.indexOf(property) + propertyLength);
const end = begin + xmlName.indexOf('"');
const fstStr = xml.substring(0, begin);
const lstStr = xml.substring(end, xml.length);
const newXml = fstStr + replaceChar + lstStr;
return newXml;
},
createNewDiagram(bpmn) {
if (!this.updateBpmnFlag && this.updateDate != undefined) {
bpmn = this.replaceString(
bpmn,
"process",
"name",
6,
this.bpmnNameFrom.name
);
bpmn = this.replaceString(
bpmn,
"process",
"id",
4,
this.bpmnNameFrom.key
);
}
this.bpmnModeler.importXML(bpmn, (err) => {
if (err) {
this.$message({
message: "打开模型出错,请确认该模型符合Bpmn2.0规范",
type: "error",
});
}
});
},
newDiagram() {
this.createNewDiagram(this.bpmnTemplate);
},
downloadBpmn() {
this.bpmnModeler.saveXML({ format: true }, (err, xml) => {
if (!err) {
const name = `${this.getFilename(xml)}.bpmn`;
this.download({ name: name, data: xml });
}
});
},
downloadSvg() {
this.bpmnModeler.saveXML({ format: true }, (err, xml) => {
if (!err) {
const name = `${this.getFilename(xml)}.svg`;
let context = "";
const djsGroupAll = this.$refs.canvas.querySelectorAll(".djs-group");
for (const item of djsGroupAll) {
context += item.innerHTML;
}
const viewport = this.$refs.canvas
.querySelector(".viewport")
.getBBox();
const svg = `
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="${viewport.width}"
height="${viewport.height}"
viewBox="${viewport.x} ${viewport.y} ${viewport.width} ${viewport.height}"
version="1.1"
>
${context}
</svg>
`;
this.download({ name: name, data: svg });
}
});
},
openBpmn(file) {
const reader = new FileReader();
reader.readAsText(file, "utf-8");
reader.onload = () => {
this.createNewDiagram(reader.result);
};
return false;
},
getFilename(xml) {
const start = xml.indexOf("process");
let filename = xml.substr(start, xml.indexOf(">"));
filename = filename.substr(filename.indexOf("id") + 4);
filename = filename.substr(0, filename.indexOf('"'));
return filename;
},
getFileInfo(xml, nodeName, property, propertyLength) {
const start = xml.indexOf(nodeName);
let fileInfo = xml.substr(start, xml.indexOf(">"));
fileInfo = fileInfo.substr(fileInfo.indexOf(property) + propertyLength);
fileInfo = fileInfo.substr(0, fileInfo.indexOf('"'));
return;
},
download({ name = "diagram.bpmn", data }) {
const downloadLink = this.$refs.downloadLink;
data = data.replace(new RegExp("camunda:", "gm"), "activiti:");
const encodedData = encodeURIComponent(data);
if (data) {
downloadLink.href =
"data:application/bpmn20-xml;charset=UTF-8," + encodedData;
downloadLink.download = name;
downloadLink.click();
}
},
handleUpdateData() {
if (!this.updateBpmnFlag) {
this.handleCreateData();
} else {
this.handleEditData();
}
},
handleCreateData() {
this.bpmnModeler.saveXML({ format: true }, async (err, xml) => {
if (!err) {
const fileName = `${this.getFileInfo(xml, "process", "name", 6)}`;
const filekey = `${this.getFileInfo(xml, "process", "id", 4)}.bpmn`;
xml = xml.replace(new RegExp("camunda:", "gm"), "activiti:");
this.$emit("createData", xml, filekey, fileName);
}
});
},
handleEditData() {
this.bpmnModeler.saveXML({ format: true }, async (err, xml) => {
if (!err) {
xml = xml.replace(new RegExp("camunda:", "gm"), "activiti:");
this.$emit("editData", xml);
}
});
},
},
};
</script>
<style>
.bpmn-container {
position: relative;
width: 100%;
height: 100vh;
display: flex;
}
.bpmn-canvas {
width: calc(100% - 300px);
height: 100vh;
}
.bpmn-js-properties-panel {
width: 320px;
height: inherit;
overflow-y: auto;
}
.action {
position: absolute;
right: 30rem;
display: flex;
margin-top: -40px;
}
.upload-demo {
margin-right: 10px;
}
.bjs-powered-by {
display: none;
}
</style>