集成 bpmn js
This commit is contained in:
parent
4504304d4c
commit
3b8b8475e8
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,9 @@
|
||||
"dependencies": {
|
||||
"amis": "^6.0.0",
|
||||
"axios": "^1.3.4",
|
||||
"bpmn-js": "^18.4.0",
|
||||
"bpmn-js-properties-panel": "^5.35.0",
|
||||
"camunda-bpmn-moddle": "^7.0.1",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"element-plus": "^2.6.3",
|
||||
"vue": "^3.4.21",
|
||||
|
||||
75
tansci-boot-ui/src/api/work/workflow.ts
Normal file
75
tansci-boot-ui/src/api/work/workflow.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 分页
|
||||
export function page(params:any){
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
url: '/tansci/system/workflow/page',
|
||||
method: 'get',
|
||||
params: params
|
||||
}).then((res:any) => {
|
||||
resolve(res.data)
|
||||
}).catch((e:any) => {
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 详情
|
||||
export function details(params:any){
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
url: '/tansci/system/workflow/details',
|
||||
method: 'get',
|
||||
params: params
|
||||
}).then((res:any) => {
|
||||
resolve(res.data)
|
||||
}).catch((e:any) => {
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 添加
|
||||
export function save(data:any){
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
url: '/tansci/system/workflow/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
}).then((res:any) => {
|
||||
resolve(res.data)
|
||||
}).catch((e:any) => {
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 删除
|
||||
export function del(id:String){
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
url: '/tansci/system/workflow/delete/' + id,
|
||||
method: 'get'
|
||||
}).then((res:any) => {
|
||||
resolve(res.data)
|
||||
}).catch((e:any) => {
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 修改
|
||||
export function update(data:any){
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
url: '/tansci/system/workflow/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
}).then((res:any) => {
|
||||
resolve(res.data)
|
||||
}).catch((e:any) => {
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
}
|
||||
148
tansci-boot-ui/src/assets/diagram.bpmn
Normal file
148
tansci-boot-ui/src/assets/diagram.bpmn
Normal file
@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd">
|
||||
<collaboration id="sid-c0e745ff-361e-4afb-8c8d-2a1fc32b1424">
|
||||
<participant id="sid-87F4C1D6-25E1-4A45-9DA7-AD945993D06F" name="Customer" processRef="sid-C3803939-0872-457F-8336-EAE484DC4A04" />
|
||||
</collaboration>
|
||||
<process id="sid-C3803939-0872-457F-8336-EAE484DC4A04" name="Customer" processType="None" isClosed="false" isExecutable="false">
|
||||
<extensionElements />
|
||||
<laneSet id="sid-b167d0d7-e761-4636-9200-76b7f0e8e83a">
|
||||
<lane id="sid-57E4FE0D-18E4-478D-BC5D-B15164E93254">
|
||||
<flowNodeRef>sid-52EB1772-F36E-433E-8F5B-D5DFD26E6F26</flowNodeRef>
|
||||
<flowNodeRef>sid-E49425CF-8287-4798-B622-D2A7D78EF00B</flowNodeRef>
|
||||
<flowNodeRef>sid-D7F237E8-56D0-4283-A3CE-4F0EFE446138</flowNodeRef>
|
||||
<flowNodeRef>sid-E433566C-2289-4BEB-A19C-1697048900D2</flowNodeRef>
|
||||
<flowNodeRef>sid-5134932A-1863-4FFA-BB3C-A4B4078B11A9</flowNodeRef>
|
||||
<flowNodeRef>SCAN_OK</flowNodeRef>
|
||||
</lane>
|
||||
</laneSet>
|
||||
<task id="sid-52EB1772-F36E-433E-8F5B-D5DFD26E6F26" name="Scan QR code">
|
||||
<incoming>sid-4DC479E5-5C20-4948-BCFC-9EC5E2F66D8D</incoming>
|
||||
<outgoing>sid-EE8A7BA0-5D66-4F8B-80E3-CC2751B3856A</outgoing>
|
||||
</task>
|
||||
<task id="sid-E49425CF-8287-4798-B622-D2A7D78EF00B" name="Open product information in mobile app">
|
||||
<incoming>sid-8B820AF5-DC5C-4618-B854-E08B71FB55CB</incoming>
|
||||
<outgoing>sid-57EB1F24-BD94-479A-BF1F-57F1EAA19C6C</outgoing>
|
||||
</task>
|
||||
<startEvent id="sid-D7F237E8-56D0-4283-A3CE-4F0EFE446138" name="Notices QR code">
|
||||
<outgoing>sid-7B791A11-2F2E-4D80-AFB3-91A02CF2B4FD</outgoing>
|
||||
</startEvent>
|
||||
<endEvent id="sid-E433566C-2289-4BEB-A19C-1697048900D2" name="Is informed">
|
||||
<incoming>sid-57EB1F24-BD94-479A-BF1F-57F1EAA19C6C</incoming>
|
||||
</endEvent>
|
||||
<exclusiveGateway id="sid-5134932A-1863-4FFA-BB3C-A4B4078B11A9">
|
||||
<incoming>sid-7B791A11-2F2E-4D80-AFB3-91A02CF2B4FD</incoming>
|
||||
<incoming>sid-337A23B9-A923-4CCE-B613-3E247B773CCE</incoming>
|
||||
<outgoing>sid-4DC479E5-5C20-4948-BCFC-9EC5E2F66D8D</outgoing>
|
||||
</exclusiveGateway>
|
||||
<exclusiveGateway id="SCAN_OK" name="Scan successful? ">
|
||||
<incoming>sid-EE8A7BA0-5D66-4F8B-80E3-CC2751B3856A</incoming>
|
||||
<outgoing>sid-8B820AF5-DC5C-4618-B854-E08B71FB55CB</outgoing>
|
||||
<outgoing>sid-337A23B9-A923-4CCE-B613-3E247B773CCE</outgoing>
|
||||
</exclusiveGateway>
|
||||
<sequenceFlow id="sid-337A23B9-A923-4CCE-B613-3E247B773CCE" name="Yes" sourceRef="SCAN_OK" targetRef="sid-5134932A-1863-4FFA-BB3C-A4B4078B11A9" />
|
||||
<sequenceFlow id="sid-4DC479E5-5C20-4948-BCFC-9EC5E2F66D8D" sourceRef="sid-5134932A-1863-4FFA-BB3C-A4B4078B11A9" targetRef="sid-52EB1772-F36E-433E-8F5B-D5DFD26E6F26" />
|
||||
<sequenceFlow id="sid-8B820AF5-DC5C-4618-B854-E08B71FB55CB" name="No" sourceRef="SCAN_OK" targetRef="sid-E49425CF-8287-4798-B622-D2A7D78EF00B" />
|
||||
<sequenceFlow id="sid-57EB1F24-BD94-479A-BF1F-57F1EAA19C6C" sourceRef="sid-E49425CF-8287-4798-B622-D2A7D78EF00B" targetRef="sid-E433566C-2289-4BEB-A19C-1697048900D2" />
|
||||
<sequenceFlow id="sid-EE8A7BA0-5D66-4F8B-80E3-CC2751B3856A" sourceRef="sid-52EB1772-F36E-433E-8F5B-D5DFD26E6F26" targetRef="SCAN_OK" />
|
||||
<sequenceFlow id="sid-7B791A11-2F2E-4D80-AFB3-91A02CF2B4FD" sourceRef="sid-D7F237E8-56D0-4283-A3CE-4F0EFE446138" targetRef="sid-5134932A-1863-4FFA-BB3C-A4B4078B11A9" />
|
||||
</process>
|
||||
<bpmndi:BPMNDiagram id="sid-74620812-92c4-44e5-949c-aa47393d3830">
|
||||
<bpmndi:BPMNPlane id="sid-cdcae759-2af7-4a6d-bd02-53f3352a731d" bpmnElement="sid-c0e745ff-361e-4afb-8c8d-2a1fc32b1424">
|
||||
<bpmndi:BPMNShape id="sid-87F4C1D6-25E1-4A45-9DA7-AD945993D06F_gui" bpmnElement="sid-87F4C1D6-25E1-4A45-9DA7-AD945993D06F" isHorizontal="true">
|
||||
<omgdc:Bounds x="83" y="105" width="933" height="250" />
|
||||
<bpmndi:BPMNLabel labelStyle="sid-84cb49fd-2f7c-44fb-8950-83c3fa153d3b">
|
||||
<omgdc:Bounds x="47.49999999999999" y="170.42857360839844" width="12.000000000000014" height="59.142852783203125" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="sid-57E4FE0D-18E4-478D-BC5D-B15164E93254_gui" bpmnElement="sid-57E4FE0D-18E4-478D-BC5D-B15164E93254" isHorizontal="true">
|
||||
<omgdc:Bounds x="113" y="105" width="903" height="250" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="sid-52EB1772-F36E-433E-8F5B-D5DFD26E6F26_gui" bpmnElement="sid-52EB1772-F36E-433E-8F5B-D5DFD26E6F26">
|
||||
<omgdc:Bounds x="393" y="170" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel labelStyle="sid-84cb49fd-2f7c-44fb-8950-83c3fa153d3b">
|
||||
<omgdc:Bounds x="360.5" y="172" width="84" height="12" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="sid-E49425CF-8287-4798-B622-D2A7D78EF00B_gui" bpmnElement="sid-E49425CF-8287-4798-B622-D2A7D78EF00B">
|
||||
<omgdc:Bounds x="728" y="170" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel labelStyle="sid-84cb49fd-2f7c-44fb-8950-83c3fa153d3b">
|
||||
<omgdc:Bounds x="695.9285736083984" y="162" width="83.14285278320312" height="36" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="sid-EE8A7BA0-5D66-4F8B-80E3-CC2751B3856A_gui" bpmnElement="sid-EE8A7BA0-5D66-4F8B-80E3-CC2751B3856A">
|
||||
<omgdi:waypoint x="493" y="210" />
|
||||
<omgdi:waypoint x="585" y="210" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds x="494" y="185" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="sid-8B820AF5-DC5C-4618-B854-E08B71FB55CB_gui" bpmnElement="sid-8B820AF5-DC5C-4618-B854-E08B71FB55CB">
|
||||
<omgdi:waypoint x="635" y="210" />
|
||||
<omgdi:waypoint x="728" y="210" />
|
||||
<bpmndi:BPMNLabel labelStyle="sid-e0502d32-f8d1-41cf-9c4a-cbb49fecf581">
|
||||
<omgdc:Bounds x="642" y="185" width="16" height="12" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="sid-7B791A11-2F2E-4D80-AFB3-91A02CF2B4FD_gui" bpmnElement="sid-7B791A11-2F2E-4D80-AFB3-91A02CF2B4FD">
|
||||
<omgdi:waypoint x="223" y="210" />
|
||||
<omgdi:waypoint x="275" y="210" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds x="204" y="185" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="sid-4DC479E5-5C20-4948-BCFC-9EC5E2F66D8D_gui" bpmnElement="sid-4DC479E5-5C20-4948-BCFC-9EC5E2F66D8D">
|
||||
<omgdi:waypoint x="325" y="210" />
|
||||
<omgdi:waypoint x="393" y="210" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds x="314" y="185" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="sid-57EB1F24-BD94-479A-BF1F-57F1EAA19C6C_gui" bpmnElement="sid-57EB1F24-BD94-479A-BF1F-57F1EAA19C6C">
|
||||
<omgdi:waypoint x="828" y="210" />
|
||||
<omgdi:waypoint x="901" y="210" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds x="820" y="185" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="sid-337A23B9-A923-4CCE-B613-3E247B773CCE_gui" bpmnElement="sid-337A23B9-A923-4CCE-B613-3E247B773CCE">
|
||||
<omgdi:waypoint x="611" y="234" />
|
||||
<omgdi:waypoint x="610.5" y="299" />
|
||||
<omgdi:waypoint x="300.5" y="299" />
|
||||
<omgdi:waypoint x="301" y="234" />
|
||||
<bpmndi:BPMNLabel labelStyle="sid-e0502d32-f8d1-41cf-9c4a-cbb49fecf581">
|
||||
<omgdc:Bounds x="585" y="236" width="21" height="12" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="StartEvent_0l6sgn0_di" bpmnElement="sid-D7F237E8-56D0-4283-A3CE-4F0EFE446138">
|
||||
<omgdc:Bounds x="187" y="192" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds x="182" y="229" width="46" height="24" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="EndEvent_0xwuvv5_di" bpmnElement="sid-E433566C-2289-4BEB-A19C-1697048900D2">
|
||||
<omgdc:Bounds x="901" y="192" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds x="892" y="231" width="56" height="12" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="ExclusiveGateway_1g0eih2_di" bpmnElement="sid-5134932A-1863-4FFA-BB3C-A4B4078B11A9" isMarkerVisible="true">
|
||||
<omgdc:Bounds x="275" y="185" width="50" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds x="210" y="160" width="90" height="12" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="ExclusiveGateway_0vci1x5_di" bpmnElement="SCAN_OK" isMarkerVisible="true">
|
||||
<omgdc:Bounds x="585" y="185" width="50" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds x="568" y="157" width="88" height="24" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
<bpmndi:BPMNLabelStyle id="sid-e0502d32-f8d1-41cf-9c4a-cbb49fecf581">
|
||||
<omgdc:Font name="Arial" size="11" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" />
|
||||
</bpmndi:BPMNLabelStyle>
|
||||
<bpmndi:BPMNLabelStyle id="sid-84cb49fd-2f7c-44fb-8950-83c3fa153d3b">
|
||||
<omgdc:Font name="Arial" size="12" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" />
|
||||
</bpmndi:BPMNLabelStyle>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</definitions>
|
||||
192
tansci-boot-ui/src/components/bpmn/BpmnModeler.vue
Normal file
192
tansci-boot-ui/src/components/bpmn/BpmnModeler.vue
Normal file
@ -0,0 +1,192 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import BpmnModeler from "bpmn-js/lib/Modeler.js"
|
||||
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-embedded.css"
|
||||
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css"
|
||||
import {
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
CamundaPlatformPropertiesProviderModule
|
||||
} from "bpmn-js-properties-panel"
|
||||
import camundaBpmnModdle from "camunda-bpmn-moddle/resources/camunda.json"
|
||||
import translate from './translate/translate.js'
|
||||
|
||||
const bpmnCanvas = ref();
|
||||
const bpmnProperties = ref();
|
||||
const bpmnModeler = ref();
|
||||
const props = defineProps({
|
||||
xmlStr: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
isPanel:{
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
const state = reactive({
|
||||
scale: 1.0
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
bpmnModeler
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
onModelerInit()
|
||||
})
|
||||
|
||||
function onModelerInit() {
|
||||
bpmnModeler.value = new BpmnModeler({
|
||||
// 基础画布
|
||||
container: bpmnCanvas.value,
|
||||
//属性面板
|
||||
propertiesPanel: {
|
||||
parent: bpmnProperties.value,
|
||||
},
|
||||
additionalModules: [
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
CamundaPlatformPropertiesProviderModule,
|
||||
{translate: ["value", translate]},
|
||||
],
|
||||
moddleExtensions: {
|
||||
camunda: camundaBpmnModdle,
|
||||
},
|
||||
})
|
||||
|
||||
let xmlStr:string = props.xmlStr;
|
||||
if(!props.xmlStr){
|
||||
xmlStr = `xml <?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="bpmn-js (https://demo.bpmn.io)" exporterVersion="5.1.2">
|
||||
<process id="Process" name="默认模板" isExecutable="true" camunda:versionTag="0.0.1">
|
||||
</process>
|
||||
<bpmndi:BPMNDiagram id="BpmnDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="Process">
|
||||
<bpmndi:BPMNShape id="StartEvent_1y45yut_di" bpmnElement="StartEvent">
|
||||
<omgdc:Bounds x="152" y="102" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds x="160" y="145" width="22" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</definitions>`
|
||||
}
|
||||
|
||||
bpmnModeler.value.importXML(xmlStr).then(() => {
|
||||
console.log("success");
|
||||
bpmnModeler.value.get("canvas").zoom("fit-viewport");
|
||||
}).catch((error:any) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
// 保存 XML
|
||||
async function onSaveXml() {
|
||||
const { xml } = await bpmnModeler.value.saveXML({ format: true });
|
||||
}
|
||||
|
||||
// 保存 SVG
|
||||
async function onSaveSvg() {
|
||||
const { svg } = await bpmnModeler.value.saveSVG();
|
||||
}
|
||||
|
||||
// 放大、缩小、还原
|
||||
function onHandlerZoom(radio:any) {
|
||||
bpmnModeler.value.get("commandStack").undo();
|
||||
const newScale = !radio ? 1.0 : state.scale + radio;
|
||||
bpmnModeler.value.get('canvas').zoom(newScale);
|
||||
state.scale = newScale;
|
||||
}
|
||||
|
||||
// 后退
|
||||
function onHandleUndo() {
|
||||
bpmnModeler.value.get("commandStack").undo();
|
||||
}
|
||||
|
||||
// 前进
|
||||
function onHandleRedo() {
|
||||
bpmnModeler.value.get("commandStack").redo();
|
||||
}
|
||||
|
||||
// 下载
|
||||
async function onHandleDownload() {
|
||||
const { xml } = await bpmnModeler.value.saveXML({ format: true });
|
||||
const dataTrack = "bpmn";
|
||||
const a = document.createElement("a");
|
||||
const name = `diagram.${dataTrack}`;
|
||||
a.setAttribute("href",`data:application/bpmn20-xml;charset=UTF-8,${encodeURIComponent(xml)}`);
|
||||
a.setAttribute("target", "_blank");
|
||||
a.setAttribute("dataTrack", `diagram:download-${dataTrack}`);
|
||||
a.setAttribute("download", name);
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
|
||||
// 导入
|
||||
function onHandleOnchangeFile(file:any) {
|
||||
const reader = new FileReader();
|
||||
reader.readAsText(file.raw, "utf-8");
|
||||
reader.onload = async (event) => {
|
||||
await bpmnModeler.value.importXML(event.target.result);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="bpmn-container">
|
||||
<div class="bpmn-header">
|
||||
<el-button-group size="small">
|
||||
<el-tooltip effect="light" content="还原"><el-button icon="Refresh" @click="onHandlerZoom(0)"></el-button></el-tooltip>
|
||||
<el-tooltip effect="light" content="放大"><el-button icon="CirclePlus" @click="onHandlerZoom(0.1)"></el-button></el-tooltip>
|
||||
<el-tooltip effect="light" content="缩小"><el-button icon="Remove" @click="onHandlerZoom(-0.1)"></el-button></el-tooltip>
|
||||
<el-tooltip effect="light" content="撤销"><el-button icon="RefreshLeft" @click="onHandleUndo"></el-button></el-tooltip>
|
||||
<el-tooltip effect="light" content="恢复"><el-button icon="RefreshRight" @click="onHandleRedo"></el-button></el-tooltip>
|
||||
<el-tooltip effect="light" content="下载"><el-button icon="Download" @click="onHandleDownload"></el-button></el-tooltip>
|
||||
<el-tooltip effect="light" content="导入">
|
||||
<el-upload style="display: inline-block" :file-list="fileList" action="" :auto-upload="false" :show-file-list="false" :on-change="onHandleOnchangeFile">
|
||||
<el-button icon="Upload"></el-button>
|
||||
</el-upload>
|
||||
</el-tooltip>
|
||||
</el-button-group>
|
||||
</div>
|
||||
<div class="bpmn-mall">
|
||||
<!-- 内容区 -->
|
||||
<div id="container" ref="bpmnCanvas"></div>
|
||||
<!-- 右侧控制区 -->
|
||||
<div id="properties" ref="bpmnProperties" v-if="props.isPanel" class="bpmn-panel"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
@import './properties-panel.css';
|
||||
.bpmn-container{
|
||||
background-color: white;
|
||||
position: relative;
|
||||
height: 85vh;
|
||||
.bpmn-header{
|
||||
padding-bottom: 0.4rem;
|
||||
}
|
||||
.bpmn-mall {
|
||||
// background-image: linear-gradient(90deg,hsla(0,0%,78.4%,.15) 10%,transparent 0),linear-gradient(hsla(0,0%,78.4%,.15) 10%,transparent 0);
|
||||
// background-size: 10px 10px;
|
||||
background: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdHRlcm4gaWQ9ImEiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZD0iTTAgMTBoNDBNMTAgMHY0ME0wIDIwaDQwTTIwIDB2NDBNMCAzMGg0ME0zMCAwdjQwIiBmaWxsPSJub25lIiBzdHJva2U9IiNlMGUwZTAiIG9wYWNpdHk9Ii4yIi8+PHBhdGggZD0iTTQwIDBIMHY0MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZTBlMGUwIi8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+') repeat !important;
|
||||
width:100%;
|
||||
height:100%;
|
||||
display: grid;
|
||||
}
|
||||
.bpmn-panel {
|
||||
width: 260px;
|
||||
position: absolute;
|
||||
right: 1px;
|
||||
border: 1px solid rgba(0,0,0,0.1);
|
||||
}
|
||||
/* 右下角logo */
|
||||
.bjs-powered-by {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
56
tansci-boot-ui/src/components/bpmn/BpmnViewer.vue
Normal file
56
tansci-boot-ui/src/components/bpmn/BpmnViewer.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import BpmnViewer from "bpmn-js/lib/Viewer.js"
|
||||
|
||||
const bpmnViewer = ref();
|
||||
const viewerCanvas = ref();
|
||||
const props = defineProps({
|
||||
xmlStr: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
onViewerInit()
|
||||
})
|
||||
|
||||
function onViewerInit() {
|
||||
console.log(1111111)
|
||||
// 初始时清除图层
|
||||
if(bpmnViewer && bpmnViewer.value){
|
||||
bpmnViewer && bpmnViewer.value.destroy();
|
||||
viewerCanvas.value.innerHTML = "";
|
||||
}
|
||||
|
||||
// 初始化
|
||||
bpmnViewer.value = new BpmnViewer({
|
||||
container: viewerCanvas.value,
|
||||
height: 520,
|
||||
})
|
||||
|
||||
let xmlStr:string = props.xmlStr;
|
||||
bpmnViewer.value.importXML(xmlStr).then(() => {
|
||||
console.log("success");
|
||||
bpmnViewer.value.get("canvas").zoom("fit-viewport");
|
||||
}).catch((error:any) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div class="bpmn-viewer-container">
|
||||
<div id="container" ref="viewerCanvas"></div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
.bpmn-viewer-container{
|
||||
background: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdHRlcm4gaWQ9ImEiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZD0iTTAgMTBoNDBNMTAgMHY0ME0wIDIwaDQwTTIwIDB2NDBNMCAzMGg0ME0zMCAwdjQwIiBmaWxsPSJub25lIiBzdHJva2U9IiNlMGUwZTAiIG9wYWNpdHk9Ii4yIi8+PHBhdGggZD0iTTQwIDBIMHY0MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZTBlMGUwIi8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+') repeat !important;
|
||||
width:100%;
|
||||
height:100%;
|
||||
.bjs-powered-by {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1523
tansci-boot-ui/src/components/bpmn/properties-panel.css
Normal file
1523
tansci-boot-ui/src/components/bpmn/properties-panel.css
Normal file
File diff suppressed because it is too large
Load Diff
16
tansci-boot-ui/src/components/bpmn/translate/translate.ts
Normal file
16
tansci-boot-ui/src/components/bpmn/translate/translate.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import translations from "./zh";
|
||||
|
||||
export default function customTranslate(template:any, replacements:any) {
|
||||
replacements = replacements || {};
|
||||
template = translations[template] || template;
|
||||
return template.replace(/{([^}]+)}/g, function(_, key) {
|
||||
let str = replacements[key];
|
||||
if (
|
||||
translations[replacements[key]] !== null &&
|
||||
translations[replacements[key]] !== "undefined"
|
||||
) {
|
||||
str = translations[replacements[key]];
|
||||
}
|
||||
return str || "{" + key + "}";
|
||||
});
|
||||
}
|
||||
251
tansci-boot-ui/src/components/bpmn/translate/zh.ts
Normal file
251
tansci-boot-ui/src/components/bpmn/translate/zh.ts
Normal file
@ -0,0 +1,251 @@
|
||||
export default {
|
||||
// Labels
|
||||
"Activate the global connect tool": "激活全局连接工具",
|
||||
"Append {type}": "追加 {type}",
|
||||
"Append EndEvent": "追加 结束事件 ",
|
||||
"Append Task": "追加 任务",
|
||||
"Append Gateway": "追加 网关",
|
||||
"Append Intermediate/Boundary Event": "追加 中间/边界 事件",
|
||||
"Add Lane above": "在上面添加道",
|
||||
"Divide into two Lanes": "分割成两个道",
|
||||
"Divide into three Lanes": "分割成三个道",
|
||||
"Add Lane below": "在下面添加道",
|
||||
"Append compensation activity": "追加补偿活动",
|
||||
"Change type": "修改类型",
|
||||
"Connect using Association": "使用关联连接",
|
||||
"Connect using Sequence/MessageFlow or Association": "使用顺序/消息流或者关联连接",
|
||||
"Connect using DataInputAssociation": "使用数据输入关联连接",
|
||||
"Remove": "移除",
|
||||
"Activate the hand tool": "激活抓手工具",
|
||||
"Activate the lasso tool": "激活套索工具",
|
||||
"Activate the create/remove space tool": "激活创建/删除空间工具",
|
||||
"Create expanded SubProcess": "创建扩展子过程",
|
||||
"Create IntermediateThrowEvent/BoundaryEvent": "创建中间抛出事件/边界事件",
|
||||
"Create Pool/Participant": "创建池/参与者",
|
||||
"Parallel Multi Instance": "并行多重事件",
|
||||
"Sequential Multi Instance": "时序多重事件",
|
||||
"DataObjectReference": "数据对象参考",
|
||||
"DataStoreReference": "数据存储参考",
|
||||
"Loop": "循环",
|
||||
"Ad-hoc": "即席",
|
||||
"Create {type}": "创建 {type}",
|
||||
"Create Task": "创建任务",
|
||||
"Create StartEvent": "创建开始事件",
|
||||
"Create EndEvent": "创建结束事件",
|
||||
"Create Group": "创建组",
|
||||
"Task": "任务",
|
||||
"Send Task": "发送任务",
|
||||
"Receive Task": "接收任务",
|
||||
"User Task": "用户任务",
|
||||
"Manual Task": "手工任务",
|
||||
"Business Rule Task": "业务规则任务",
|
||||
"Service Task": "服务任务",
|
||||
"Script Task": "脚本任务",
|
||||
"Call Activity": "调用活动",
|
||||
"Sub Process (collapsed)": "子流程(折叠的)",
|
||||
"Sub Process (expanded)": "子流程(展开的)",
|
||||
"Start Event": "开始事件",
|
||||
"StartEvent": "开始事件",
|
||||
"Intermediate Throw Event": "中间事件",
|
||||
"End Event": "结束事件",
|
||||
"EndEvent": "结束事件",
|
||||
"Create Gateway": "创建网关",
|
||||
"GateWay": "网关",
|
||||
"Create Intermediate/Boundary Event": "创建中间/边界事件",
|
||||
"Message Start Event": "消息开始事件",
|
||||
"Timer Start Event": "定时开始事件",
|
||||
"Conditional Start Event": "条件开始事件",
|
||||
"Signal Start Event": "信号开始事件",
|
||||
"Error Start Event": "错误开始事件",
|
||||
"Escalation Start Event": "升级开始事件",
|
||||
"Compensation Start Event": "补偿开始事件",
|
||||
"Message Start Event (non-interrupting)": "消息开始事件(非中断)",
|
||||
"Timer Start Event (non-interrupting)": "定时开始事件(非中断)",
|
||||
"Conditional Start Event (non-interrupting)": "条件开始事件(非中断)",
|
||||
"Signal Start Event (non-interrupting)": "信号开始事件(非中断)",
|
||||
"Escalation Start Event (non-interrupting)": "升级开始事件(非中断)",
|
||||
"Message Intermediate Catch Event": "消息中间捕获事件",
|
||||
"Message Intermediate Throw Event": "消息中间抛出事件",
|
||||
"Timer Intermediate Catch Event": "定时中间捕获事件",
|
||||
"Escalation Intermediate Throw Event": "升级中间抛出事件",
|
||||
"Conditional Intermediate Catch Event": "条件中间捕获事件",
|
||||
"Link Intermediate Catch Event": "链接中间捕获事件",
|
||||
"Link Intermediate Throw Event": "链接中间抛出事件",
|
||||
"Compensation Intermediate Throw Event": "补偿中间抛出事件",
|
||||
"Signal Intermediate Catch Event": "信号中间捕获事件",
|
||||
"Signal Intermediate Throw Event": "信号中间抛出事件",
|
||||
"Message End Event": "消息结束事件",
|
||||
"Escalation End Event": "定时结束事件",
|
||||
"Error End Event": "错误结束事件",
|
||||
"Cancel End Event": "取消结束事件",
|
||||
"Compensation End Event": "补偿结束事件",
|
||||
"Signal End Event": "信号结束事件",
|
||||
"Terminate End Event": "终止结束事件",
|
||||
"Message Boundary Event": "消息边界事件",
|
||||
"Message Boundary Event (non-interrupting)": "消息边界事件(非中断)",
|
||||
"Timer Boundary Event": "定时边界事件",
|
||||
"Timer Boundary Event (non-interrupting)": "定时边界事件(非中断)",
|
||||
"Escalation Boundary Event": "升级边界事件",
|
||||
"Escalation Boundary Event (non-interrupting)": "升级边界事件(非中断)",
|
||||
"Conditional Boundary Event": "条件边界事件",
|
||||
"Conditional Boundary Event (non-interrupting)": "条件边界事件(非中断)",
|
||||
"Error Boundary Event": "错误边界事件",
|
||||
"Cancel Boundary Event": "取消边界事件",
|
||||
"Signal Boundary Event": "信号边界事件",
|
||||
"Signal Boundary Event (non-interrupting)": "信号边界事件(非中断)",
|
||||
"Compensation Boundary Event": "补偿边界事件",
|
||||
"Exclusive Gateway": "互斥网关",
|
||||
"Parallel Gateway": "并行网关",
|
||||
"Inclusive Gateway": "相容网关",
|
||||
"Complex Gateway": "复杂网关",
|
||||
"Event based Gateway": "事件网关",
|
||||
"Transaction": "转运",
|
||||
"Sub Process": "子流程",
|
||||
"Event Sub Process": "事件子流程",
|
||||
"Collapsed Pool": "折叠池",
|
||||
"Expanded Pool": "展开池",
|
||||
// Errors
|
||||
"no parent for {element} in {parent}": "在{parent}里,{element}没有父类",
|
||||
"no shape type specified": "没有指定的形状类型",
|
||||
"flow elements must be children of pools/participants": "流元素必须是池/参与者的子类",
|
||||
"out of bounds release": "out of bounds release",
|
||||
"more than {count} child lanes": "子道大于{count} ",
|
||||
"element required": "元素不能为空",
|
||||
"diagram not part of bpmn:Definitions": "流程图不符合bpmn规范",
|
||||
"no diagram to display": "没有可展示的流程图",
|
||||
"no process or collaboration to display": "没有可展示的流程/协作",
|
||||
"element {element} referenced by {referenced}#{property} not yet drawn": "由{referenced}#{property}引用的{element}元素仍未绘制",
|
||||
"already rendered {element}": "{element} 已被渲染",
|
||||
"failed to import {element}": "导入{element}失败",
|
||||
//属性面板的参数
|
||||
"Id": "编号",
|
||||
"Name": "名称",
|
||||
"General": "常规",
|
||||
"Details": "详情",
|
||||
"Message Name": "消息名称",
|
||||
"Message": "消息",
|
||||
"Initiator": "创建者",
|
||||
"Asynchronous Continuations": "持续异步",
|
||||
"Asynchronous Before": "异步前",
|
||||
"Asynchronous After": "异步后",
|
||||
"Job Configuration": "工作配置",
|
||||
"Exclusive": "排除",
|
||||
"Job Priority": "工作优先级",
|
||||
"Retry Time Cycle": "重试时间周期",
|
||||
"Documentation": "文档",
|
||||
"Element Documentation": "元素文档",
|
||||
"History Configuration": "历史配置",
|
||||
"History Time To Live": "历史的生存时间",
|
||||
"Forms": "表单",
|
||||
"Form Key": "表单key",
|
||||
"Form Fields": "表单字段",
|
||||
"Business Key": "业务key",
|
||||
"Form Field": "表单字段",
|
||||
"ID": "编号",
|
||||
"Type": "类型",
|
||||
"Label": "名称",
|
||||
"Default Value": "默认值",
|
||||
"Validation": "校验",
|
||||
"Add Constraint": "添加约束",
|
||||
"Config": "配置",
|
||||
"Properties": "属性",
|
||||
"Add Property": "添加属性",
|
||||
"Value": "值",
|
||||
"Add": "添加",
|
||||
"Values": "值",
|
||||
"Add Value": "添加值",
|
||||
"Listeners": "监听器",
|
||||
"Execution Listener": "执行监听",
|
||||
"Event Type": "事件类型",
|
||||
"Listener Type": "监听器类型",
|
||||
"Java Class": "Java类",
|
||||
"Expression": "表达式",
|
||||
"Must provide a value": "必须提供一个值",
|
||||
"Delegate Expression": "代理表达式",
|
||||
"Script": "脚本",
|
||||
"Script Format": "脚本格式",
|
||||
"Script Type": "脚本类型",
|
||||
"Inline Script": "内联脚本",
|
||||
"External Script": "外部脚本",
|
||||
"Resource": "资源",
|
||||
"Field Injection": "字段注入",
|
||||
"Extensions": "扩展",
|
||||
"Input/Output": "输入/输出",
|
||||
"Input Parameters": "输入参数",
|
||||
"Output Parameters": "输出参数",
|
||||
"Parameters": "参数",
|
||||
"Output Parameter": "输出参数",
|
||||
"Timer Definition Type": "定时器定义类型",
|
||||
"Timer Definition": "定时器定义",
|
||||
"Date": "日期",
|
||||
"Duration": "持续",
|
||||
"Cycle": "循环",
|
||||
"Signal": "信号",
|
||||
"Signal Name": "信号名称",
|
||||
"Escalation": "升级",
|
||||
"Error": "错误",
|
||||
"Link Name": "链接名称",
|
||||
"Condition": "条件名称",
|
||||
"Variable Name": "变量名称",
|
||||
"Variable Event": "变量事件",
|
||||
"Specify more than one variable change event as a comma separated list.": "多个变量事件以逗号隔开",
|
||||
"Wait for Completion": "等待完成",
|
||||
"Activity Ref": "活动参考",
|
||||
"Version Tag": "版本标签",
|
||||
"Executable": "可执行文件",
|
||||
"External Task Configuration": "扩展任务配置",
|
||||
"Task Priority": "任务优先级",
|
||||
"External": "外部",
|
||||
"Connector": "连接器",
|
||||
"Must configure Connector": "必须配置连接器",
|
||||
"Connector Id": "连接器编号",
|
||||
"Implementation": "实现方式",
|
||||
"Field Injections": "字段注入",
|
||||
"Fields": "字段",
|
||||
"Result Variable": "结果变量",
|
||||
"Topic": "主题",
|
||||
"Configure Connector": "配置连接器",
|
||||
"Input Parameter": "输入参数",
|
||||
"Assignee": "代理人",
|
||||
"Candidate Users": "候选用户",
|
||||
"Candidate Groups": "候选组",
|
||||
"Due Date": "到期时间",
|
||||
"Follow Up Date": "跟踪日期",
|
||||
"Priority": "优先级",
|
||||
"The follow up date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)": "跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00",
|
||||
"The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)": "跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00",
|
||||
"Variables": "变量",
|
||||
"Candidate Starter Configuration": "候选开始配置",
|
||||
"Task Listener": "任务监听器",
|
||||
"Candidate Starter Groups": "候选开始组",
|
||||
"Candidate Starter Users": "候选开始用户",
|
||||
"Tasklist Configuration": "任务列表配置",
|
||||
"Startable": "启动",
|
||||
"Specify more than one group as a comma separated list.": "指定多个组,用逗号分隔",
|
||||
"Specify more than one user as a comma separated list.": "指定多个用户,用逗号分隔",
|
||||
"This maps to the process definition key.": "这会映射为流程定义的键",
|
||||
"CallActivity Type": "调用活动类型",
|
||||
"Condition Type": "条件类型",
|
||||
"Create UserTask": "创建用户任务",
|
||||
"Create CallActivity": "创建调用活动",
|
||||
"Called Element": "调用元素",
|
||||
"Create DataObjectReference": "创建数据对象引用",
|
||||
"Create DataStoreReference": "创建数据存储引用",
|
||||
"Multi Instance": "多实例",
|
||||
"Loop Cardinality": "实例数量",
|
||||
"Collection": "任务参与人列表",
|
||||
"Element Variable": "元素变量",
|
||||
"Completion Condition": "完成条件",
|
||||
"Open minimap": "打开小地图",
|
||||
"Close minimap": "关闭小地图",
|
||||
"History cleanup": "历史记录清理",
|
||||
"Tasklist": "任务列表",
|
||||
"Candidate starter": "候选人启动器",
|
||||
"External task": "外部任务",
|
||||
"Job execution": "任务执行",
|
||||
"Execution listeners": "执行侦听器",
|
||||
"Extension properties": "扩展属性",
|
||||
"Time to live":"存活时间",
|
||||
"Candidate starter groups":"候选人启动小组",
|
||||
"Candidate starter users":"候选初学者用户",
|
||||
}
|
||||
@ -32,7 +32,6 @@ export default[
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: 'index',
|
||||
icon: 'HomeFilled',
|
||||
meta: { title: "首页" },
|
||||
isShow: false,
|
||||
|
||||
157
tansci-boot-ui/src/views/work/Workflow.vue
Normal file
157
tansci-boot-ui/src/views/work/Workflow.vue
Normal file
@ -0,0 +1,157 @@
|
||||
<script setup lang="ts">
|
||||
import {onMounted, reactive, ref} from 'vue'
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
import type {FormInstance} from 'element-plus'
|
||||
import Table from '@/components/Table.vue'
|
||||
import BpmnViewer from "@/components/bpmn/BpmnViewer.vue"
|
||||
import {useRouter} from 'vue-router'
|
||||
import {page,update,del} from '@/api/work/workflow'
|
||||
|
||||
const router = useRouter()
|
||||
const searchForm = reactive({
|
||||
name: null
|
||||
})
|
||||
|
||||
const table = reactive({
|
||||
loading: false,
|
||||
page: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 1,
|
||||
},
|
||||
operation:{
|
||||
isShow: true,
|
||||
width: '240'
|
||||
},
|
||||
tableTitle: [
|
||||
{prop:'name',label:'流程名称'},
|
||||
{prop:'status',label:'是否禁用',type:'switch',
|
||||
option:{
|
||||
activeValue:0,activeColor:'#13ce66',activeText:'启用',
|
||||
inactiveValue:1,inactiveColor:'#ff4949',inactiveText:'禁用',
|
||||
inlinePrompt: false
|
||||
}
|
||||
},
|
||||
{prop:'updateTime',label:'更新时间'},
|
||||
{prop:'remarks',label:'描述'}
|
||||
],
|
||||
tableData:[],
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
onPage()
|
||||
})
|
||||
|
||||
function onPage(){
|
||||
table.loading = true;
|
||||
page(Object.assign(table.page, searchForm)).then((res:any)=>{
|
||||
if(res){
|
||||
table.loading = false;
|
||||
table.tableData = res.result.records;
|
||||
table.page.current = res.result.current;
|
||||
table.page.size = res.result.size;
|
||||
table.page.total = res.result.total;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onSizeChange(e){
|
||||
table.page.size = e;
|
||||
onPage();
|
||||
}
|
||||
function onCurrentChange(e){
|
||||
table.page.current = e;
|
||||
onPage();
|
||||
}
|
||||
function onRefresh(){
|
||||
searchForm.name = null
|
||||
onPage();
|
||||
}
|
||||
function onSearch(){
|
||||
onPage();
|
||||
}
|
||||
|
||||
function onSwitchChange(row:any){
|
||||
update({
|
||||
id: row.id,
|
||||
status: row.status
|
||||
}).then(res=>{
|
||||
if(res){
|
||||
ElMessage.success('操作成功!');
|
||||
onPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 添加
|
||||
function onAdd(){
|
||||
router.push({
|
||||
path: '/work/WorkflowAdd',
|
||||
query: { id: null }
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑
|
||||
function onEdit(val:any){
|
||||
router.push({
|
||||
path: '/work/WorkflowAdd',
|
||||
query: { id: val.column.row.id }
|
||||
});
|
||||
}
|
||||
|
||||
// 删除
|
||||
function onDelete(val:any){
|
||||
ElMessageBox.confirm('此操作将永久删除, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
del(val.column.row.id).then(res=>{
|
||||
if(res){
|
||||
ElMessage.success('删除成功!');
|
||||
onPage();
|
||||
}
|
||||
})
|
||||
}).catch(e=>{
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
// 预览
|
||||
const viewer = reactive({
|
||||
viewerVisible: false,
|
||||
xmlStr: ''
|
||||
})
|
||||
|
||||
function onViewer(val:any){
|
||||
viewer.xmlStr = val.column.row.content;
|
||||
viewer.viewerVisible = true;
|
||||
}
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div class="workflow-container">
|
||||
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="table.page" :loading="table.loading"
|
||||
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange" @onSwitchChange="onSwitchChange">
|
||||
<template #search>
|
||||
<div><el-button v-permission="'workflow:save'" type="primary" @click="onAdd()">添加</el-button></div>
|
||||
<div><el-input v-model="searchForm.name" placeholder="请输入名称"></el-input></div>
|
||||
<div><el-button @click="onRefresh" icon="RefreshRight" circle></el-button></div>
|
||||
<div><el-button @click="onSearch" type="primary" icon="Search">查询</el-button></div>
|
||||
</template>
|
||||
<template #column="scope">
|
||||
<el-button @click="onViewer(scope)" type='primary' link style="color:var(--query); padding:0;">预览</el-button>
|
||||
<el-button @click="onEdit(scope)" v-permission="'workflow:update'" type='primary' link style="color:var(--edit); padding:0;">编辑</el-button>
|
||||
<el-button @click="onDelete(scope)" v-permission="'workflow:delete'" type='primary' link style="color:var(--delete); padding:0;">删除</el-button>
|
||||
</template>
|
||||
</Table>
|
||||
<el-dialog v-model="viewer.viewerVisible" title="预览">
|
||||
<BpmnViewer :xmlStr="viewer.xmlStr" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.workflow-container{
|
||||
|
||||
}
|
||||
</style>
|
||||
113
tansci-boot-ui/src/views/work/WorkflowAdd.vue
Normal file
113
tansci-boot-ui/src/views/work/WorkflowAdd.vue
Normal file
@ -0,0 +1,113 @@
|
||||
<script setup lang="ts">
|
||||
import {onMounted, reactive, ref} from 'vue'
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
import type {FormInstance} from 'element-plus'
|
||||
import BpmnModeler from "@/components/bpmn/BpmnModeler.vue"
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { details, save, update } from '@/api/work/workflow'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const formRef = ref<FormInstance>();
|
||||
const saveXml = ref(null);
|
||||
const form = reactive({
|
||||
loading: false,
|
||||
workflowForm:{
|
||||
id: '',
|
||||
name: '',
|
||||
content: null,
|
||||
status: null,
|
||||
remarks: '',
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
onDetails()
|
||||
})
|
||||
|
||||
function onDetails(){
|
||||
if(!route.query.id){
|
||||
return false;
|
||||
}
|
||||
form.loading = true;
|
||||
details({id: route.query.id}).then((res:any) =>{
|
||||
form.workflowForm = {
|
||||
id: res.result.id,
|
||||
name: res.result.name,
|
||||
content: res.result.content,
|
||||
status: res.result.status,
|
||||
remarks: res.result.remarks,
|
||||
}
|
||||
form.loading = false;
|
||||
})
|
||||
}
|
||||
|
||||
function goBack(){
|
||||
router.push({path: '/work/Workflow'});
|
||||
}
|
||||
|
||||
async function onSubmit(formEl: FormInstance | undefined) {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid)=>{
|
||||
if(valid){
|
||||
const bpmnModeler = saveXml.value.bpmnModeler;
|
||||
if(!bpmnModeler){
|
||||
ElMessage.warning("流程图不能为空!")
|
||||
return false;
|
||||
}
|
||||
bpmnModeler.saveXML({ format: true }).then((res:any) =>{
|
||||
if(!res.xml){
|
||||
ElMessage.warning("流程图不能为空!")
|
||||
return false;
|
||||
}
|
||||
form.workflowForm.content = res.xml;
|
||||
if(!form.workflowForm.id){
|
||||
save(form.workflowForm).then(res=>{
|
||||
if(res){
|
||||
ElMessage.success("添加成功!");
|
||||
router.push({path: '/work/Workflow'});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
update(form.workflowForm).then(res=>{
|
||||
if(res){
|
||||
ElMessage.success("更新成功!");
|
||||
router.push({path: '/work/Workflow'});
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div class="workflow-add-container">
|
||||
<el-form :model="form.workflowForm" ref="formRef" :rules="rules" label-position="left" status-icon>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="1">
|
||||
<el-button @click="goBack()">返回</el-button>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item label="流程名称" prop="name" :rules="[{required: true,message:'请输入名称',trigger: 'blur'}]">
|
||||
<el-input v-model="form.workflowForm.name" placeholder="请输入名称" style="width: 100%"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-button type="primary" @click="onSubmit(formRef)">提交</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<BpmnModeler v-if="!form.loading" :xmlStr="form.workflowForm.content" ref="saveXml"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.workflow-add-container{
|
||||
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user