|
@@ -0,0 +1,946 @@
|
|
|
+<!--
|
|
|
+ * @Author: zwy
|
|
|
+ * @Date: 2021-02-21 10:11:08
|
|
|
+ * @LastEditors: zwy
|
|
|
+ * @LastEditTime: 2021-03-11 15:39:12
|
|
|
+ * @Descripttion: 巡检任务流程
|
|
|
+-->
|
|
|
+<template>
|
|
|
+ <div class="bpmn">
|
|
|
+ <div class="bpmn-left" ref="bpmn">
|
|
|
+ <div class="bpmn-title">流程图设计</div>
|
|
|
+ </div>
|
|
|
+ <div class="bpmn-right">
|
|
|
+ <div class="bpmn-title">节点配置</div>
|
|
|
+ <div class="no-scrollbar">
|
|
|
+ <div class="bpmn-node">节点ID: {{ nodeId }}</div>
|
|
|
+ <user
|
|
|
+ :values="userValues"
|
|
|
+ v-if="showUserSelect"
|
|
|
+ :channelId="channelId"
|
|
|
+ :prevTask="prevUserTaskObj"
|
|
|
+ :isReject="isReject"
|
|
|
+ :rejectUser="rejectUserValue"
|
|
|
+ @change="userChange"
|
|
|
+ @rejectUserChange="rejectUserChange"
|
|
|
+ ></user>
|
|
|
+ <condition
|
|
|
+ :values="conditionValues"
|
|
|
+ :channelId="channelId"
|
|
|
+ :formId="prevFormId"
|
|
|
+ @change="conditionChange"
|
|
|
+ v-if="showConditionSelect"
|
|
|
+ ></condition>
|
|
|
+ <bpmn-form v-if="showFormSelect" :values="formValues" @change="formChange" :channelId="channelId" :getFormList='getFormList'></bpmn-form>
|
|
|
+ <service
|
|
|
+ v-if="showSerivceSelect"
|
|
|
+ :values="serviceValues"
|
|
|
+ @change="serviceChange"
|
|
|
+ :channelId="channelId"
|
|
|
+ :prevTask="prevUserTaskObj"
|
|
|
+ ></service>
|
|
|
+ <!-- <user v-if='showAssign' :values='assignValues' @change='assignChange' :isAssign='true' :channelId='channelId'></user> -->
|
|
|
+ <sequence
|
|
|
+ v-if="showSequence"
|
|
|
+ :formKey="sequenceFormKey"
|
|
|
+ :channelId="channelId"
|
|
|
+ @change="sequenceChange"
|
|
|
+ :values="sequenceValue"
|
|
|
+ ></sequence>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+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'; //这四个为bpmn工作流绘图工具的样式
|
|
|
+import BpmnModeler from 'bpmn-js/lib/Modeler'; //建模器
|
|
|
+import translateModer from '@utils/translate.js';
|
|
|
+import Provider from './bpmn/Provider';
|
|
|
+import BpmnModdle from 'bpmn-moddle';
|
|
|
+
|
|
|
+import condition from './bpmn/condition.vue';
|
|
|
+import user from './bpmn/user.vue';
|
|
|
+import bpmnForm from './bpmn/form.vue';
|
|
|
+import service from './bpmn/service.vue';
|
|
|
+import sequence from './bpmn/sequence.vue';
|
|
|
+
|
|
|
+// 初始化的xml
|
|
|
+let initXml = '';
|
|
|
+export default {
|
|
|
+ props: ['params'],
|
|
|
+ components: {
|
|
|
+ condition,
|
|
|
+ user,
|
|
|
+ bpmnForm,
|
|
|
+ service,
|
|
|
+ sequence
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ bmpn: '',
|
|
|
+ model: '',
|
|
|
+ // 节点ID
|
|
|
+ nodeId: '',
|
|
|
+ // 是否显示条件选择
|
|
|
+ showConditionSelect: false,
|
|
|
+ // 是否显示用户选择
|
|
|
+ showUserSelect: false,
|
|
|
+ // 是否显示表单
|
|
|
+ showFormSelect: false,
|
|
|
+ // 是否显示服务设置
|
|
|
+ showSerivceSelect: false,
|
|
|
+ // 是否显示指派设置
|
|
|
+ showAssign: false,
|
|
|
+ // 显示节点之间连接的节点动作配置
|
|
|
+ showSequence: false,
|
|
|
+ prevUserTaskObj: {},
|
|
|
+ // 是否为驳回表单
|
|
|
+ isReject: '',
|
|
|
+ // 驳回节点处理的值
|
|
|
+ rejectUserValue: '',
|
|
|
+ // 连线起始节点的表单Key
|
|
|
+ sequenceFormKey: '',
|
|
|
+ sequenceValue: '',
|
|
|
+ // 节点ID的顺序集合
|
|
|
+ nodeIdOrderList: [],
|
|
|
+
|
|
|
+ getFormList:[],
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ fromXML() {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ this.model.fromXML(xml, { format: true }, (err, res) => {
|
|
|
+ resolve(res);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ toXML(result) {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ this.model.toXML(result, { format: true }, (err, xml) => {
|
|
|
+ resolve(xml);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getBpmn() {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ this.$http
|
|
|
+ .get('/sc-community/workflow/process/getBpmnContent', {
|
|
|
+ id: this.params.data.id
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ initXml = res.data || '';
|
|
|
+ resolve(res.data || '');
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getXML() {
|
|
|
+ //下载为bpmn格式
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ this.bpmn.saveXML({ format: true }, (err, xml) => {
|
|
|
+ this.model.fromXML(xml, { format: true }, (err, definitions, context) => {
|
|
|
+ resolve({ definitions, context });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getIdOrder(root) {
|
|
|
+ let i = root.length,
|
|
|
+ dataArr = [],
|
|
|
+ loop = function (node, arr) {
|
|
|
+ if (!node) return;
|
|
|
+ if (node instanceof Array) {
|
|
|
+ let j = node.length;
|
|
|
+ while (j--) {
|
|
|
+ let arrs = [...arr];
|
|
|
+ if (node[j].$type == 'bpmn:EndEvent' || (!node[j].outgoing && !node[j].targetRef)) {
|
|
|
+ dataArr.push(arr);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ loop(node[j].targetRef, arrs);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let set = new Set(arr);
|
|
|
+ if (set.has(node.id)) return;
|
|
|
+ if (node.$type == 'bpmn:UserTask' || node.$type == 'bpmn:ServiceTask') {
|
|
|
+ arr.push(node.id);
|
|
|
+ }
|
|
|
+ if (node.$type == 'bpmn:EndEvent' || (!node.outgoing && !node.targetRef)) {
|
|
|
+ dataArr.push(arr);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ loop(node.outgoing, arr);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ start;
|
|
|
+ while (i--) {
|
|
|
+ if ('bpmn:StartEvent' == root[i].$type) {
|
|
|
+ start = root[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ loop(start.outgoing, []);
|
|
|
+ this.nodeIdOrderList = dataArr;
|
|
|
+ },
|
|
|
+ // 获取选择的用户
|
|
|
+ userChange(arr) {
|
|
|
+ if (!this.nodeId) return;
|
|
|
+ this.getXML().then(({ definitions, context }) => {
|
|
|
+ let eles = definitions.rootElements[0].flowElements,
|
|
|
+ selectModel,
|
|
|
+ i = eles.length;
|
|
|
+ while (i--) {
|
|
|
+ if (this.nodeId == eles[i].id) {
|
|
|
+ selectModel = eles[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (selectModel.documentation == undefined) {
|
|
|
+ selectModel.extensionElements = this.model.create('bpmn:Documentation', { text: JSON.stringify(arr) });
|
|
|
+ } else {
|
|
|
+ selectModel.documentation[0].text = JSON.stringify(arr);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 渲染xml
|
|
|
+ definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
|
|
|
+ this.bpmn.importXML(xml, (_) => {
|
|
|
+ // 改变元素颜色
|
|
|
+ // let modeling = this.bpmn.get('modeling');
|
|
|
+ // let elementRegistry = this.bpmn.get('elementRegistry');//使用elementRegistry来获取Shape信息
|
|
|
+ // let elementToColor = elementRegistry.get(this.nodeId);//传递id进去
|
|
|
+ // modeling.setColor(elementToColor, {
|
|
|
+ // stroke: 'green',
|
|
|
+ // fill: 'yellow'
|
|
|
+ // })
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 用户节点驳回处理人员改变
|
|
|
+ rejectUserChange(val) {
|
|
|
+ if (!this.nodeId) return;
|
|
|
+ this.getXML().then(({ definitions, context }) => {
|
|
|
+ let root = definitions.rootElements[0],
|
|
|
+ obj = {},
|
|
|
+ documentation = root.get('documentation');
|
|
|
+ // 根节点添加documentation,用来存储各个节点的驳回处理人
|
|
|
+ if (documentation.length) {
|
|
|
+ obj = documentation[0].text ? JSON.parse(documentation[0].text) : {};
|
|
|
+ obj[this.nodeId] = val;
|
|
|
+ documentation[0].text = JSON.stringify(obj);
|
|
|
+ } else {
|
|
|
+ obj[this.nodeId] = val;
|
|
|
+ documentation = this.model.create('bpmn:Documentation', { text: JSON.stringify(obj) });
|
|
|
+ root.get('documentation').push(documentation);
|
|
|
+ }
|
|
|
+ // 2,驳回后的节点加监听器
|
|
|
+ // <extensionElements>
|
|
|
+ // <activiti:taskListener event="create" class="com.bz.smart_city.activiti.listener.ReturnTaskListener"></activiti:taskListener>
|
|
|
+ // </extensionElements>
|
|
|
+ // 3,驳回后的节点加内容
|
|
|
+ // from上级节点
|
|
|
+ // assignee:first受理人,last处理人
|
|
|
+ // <documentation>{"rejectConfig":[{"from":"usertask2","assignee":"first"},{"from":"usertask3","assignee":"last"}]}</documentation>
|
|
|
+ let selectEl = context.elementsById[this.nodeId],
|
|
|
+ out = selectEl.outgoing || [],
|
|
|
+ i = out.length,
|
|
|
+ targetRef;
|
|
|
+ // 获取驳回连线的目标节点
|
|
|
+ while (i--) {
|
|
|
+ if (out[i].conditionExpression && out[i].conditionExpression.body == '${action=="reject"}') {
|
|
|
+ targetRef = out[i].targetRef;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (targetRef) {
|
|
|
+ let targetRefDoc = targetRef.get('documentation');
|
|
|
+ if (targetRefDoc.length) {
|
|
|
+ let temp = targetRefDoc[0].text;
|
|
|
+ temp = temp ? JSON.parse(temp) : {};
|
|
|
+ let config = temp.rejectConfig,
|
|
|
+ tag = false;
|
|
|
+ // 如果已有,则替换assignee的值
|
|
|
+ for (let i in config) {
|
|
|
+ if (config[i].from == this.nodeId) {
|
|
|
+ tag = true;
|
|
|
+ config[i].assignee = val;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 没有则添加一条记录
|
|
|
+ if (!tag) {
|
|
|
+ config.push({
|
|
|
+ from: this.nodeId,
|
|
|
+ assignee: val
|
|
|
+ });
|
|
|
+ }
|
|
|
+ targetRefDoc[0].text = JSON.stringify({ rejectConfig: config });
|
|
|
+ } else {
|
|
|
+ let doc = this.model.create('bpmn:Documentation', {
|
|
|
+ text: '{"rejectConfig":[{"from":"' + this.nodeId + '","assignee":"' + assignee + '"}]}'
|
|
|
+ });
|
|
|
+ targetRefDoc.push(doc);
|
|
|
+ }
|
|
|
+ // let extensionElements = this.model.create('bpmn:ExtensionElements'),
|
|
|
+ // foo = this.model.createAny('activiti:taskListener', 'http://activiti.org/bpmn', {
|
|
|
+ // event: 'create',
|
|
|
+ // class: 'com.bz.smart_city.activiti.listener.ReturnTaskListener'
|
|
|
+ // });
|
|
|
+
|
|
|
+ // extensionElements.get('values').push(foo);
|
|
|
+ // targetRef.extensionElements = extensionElements
|
|
|
+ }
|
|
|
+
|
|
|
+ // 渲染xml
|
|
|
+ definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
|
|
|
+ this.bpmn.importXML(xml);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 获取分支条件
|
|
|
+ // conditionChange(obj) {
|
|
|
+ // let temp = {}
|
|
|
+ // for(let item in obj) {
|
|
|
+ // if(obj[item] instanceof Array && obj[item].length) {
|
|
|
+ // temp[item] = obj[item]
|
|
|
+ // }
|
|
|
+ // if('alarmTimeRange' == item && '-' != obj[item]) {
|
|
|
+ // temp[item] = obj[item]
|
|
|
+ // }
|
|
|
+ // if('preHandleResult' == item && obj[item]) {
|
|
|
+ // temp[item] = obj[item]
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // if(!this.nodeId) return
|
|
|
+ // this.getXML().then(({definitions, context}) => {
|
|
|
+ // let eles = definitions.rootElements[0].flowElements,
|
|
|
+ // selectModel,
|
|
|
+ // i = eles.length;
|
|
|
+ // while(i--) {
|
|
|
+ // if(this.nodeId == eles[i].id) {
|
|
|
+ // selectModel = eles[i]
|
|
|
+ // break;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // if('{}' != JSON.stringify(temp)) {
|
|
|
+ // selectModel.conditionExpression = this.model.create('bpmn:FormalExpression', {
|
|
|
+ // body: "${workFlowConditionService.checkCondition(execution,\""+JSON.stringify(temp).replace(/\"/g,"\\\"")+"\")}"
|
|
|
+ // })
|
|
|
+ // } else {
|
|
|
+ // selectModel.conditionExpression = null;
|
|
|
+ // }
|
|
|
+ // // 渲染xml
|
|
|
+ // definitions.$model.toXML(definitions, {format: true}, (err,xml) => {
|
|
|
+ // this.bpmn.importXML(xml)
|
|
|
+ // })
|
|
|
+ // })
|
|
|
+ // },
|
|
|
+ // 表单选择
|
|
|
+ formChange(val) {
|
|
|
+ if (!this.nodeId) return;
|
|
|
+ this.getFormDetail(val);
|
|
|
+ this.getXML().then(({ definitions, context }) => {
|
|
|
+ let eles = definitions.rootElements[0].flowElements,
|
|
|
+ selectModel,
|
|
|
+ i = eles.length;
|
|
|
+ while (i--) {
|
|
|
+ if (this.nodeId == eles[i].id) {
|
|
|
+ selectModel = eles[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 置空下游连接线上的节点动作值
|
|
|
+ let outgoing = selectModel.outgoing || [],
|
|
|
+ j = outgoing.length,
|
|
|
+ temp;
|
|
|
+ while (j--) {
|
|
|
+ outgoing[j].conditionExpression = null;
|
|
|
+ }
|
|
|
+ selectModel.$attrs['activiti:formKey'] = val;
|
|
|
+ // 渲染xml
|
|
|
+ definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
|
|
|
+ this.bpmn.importXML(xml);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 根据表单key获取表单详情
|
|
|
+ getFormDetail(key, resolve) {
|
|
|
+ this.showAssign = false;
|
|
|
+ this.isReject = false;
|
|
|
+ if ('water-form' == key) {
|
|
|
+ this.showAssign = true;
|
|
|
+ resolve && resolve();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$http
|
|
|
+ .get('/sc-community/workflow/form/' + key, {
|
|
|
+ channelId: this.channelId
|
|
|
+ })
|
|
|
+ .then(({ data = {} }) => {
|
|
|
+ let actionList = data.userActionList || [],
|
|
|
+ i = actionList.length;
|
|
|
+ while (i--) {
|
|
|
+ if ('指派' == actionList[i].actionName) {
|
|
|
+ this.showAssign = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if ('reject' == actionList[i].actionValue) {
|
|
|
+ this.isReject = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ resolve && resolve();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 服务任务改变
|
|
|
+ serviceChange(arr) {
|
|
|
+ if (!this.nodeId) return;
|
|
|
+ this.getXML().then(({ definitions, context }) => {
|
|
|
+ let eles = definitions.rootElements[0].flowElements,
|
|
|
+ selectModel,
|
|
|
+ i = eles.length;
|
|
|
+ while (i--) {
|
|
|
+ if (this.nodeId == eles[i].id) {
|
|
|
+ selectModel = eles[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // selectModel.$arrts['activiti:delegateExpression']="";
|
|
|
+ // activiti:delegateExpression="${progressSevice.runWithParticipants(execution,'')}
|
|
|
+ selectModel.$attrs['activiti:expression'] =
|
|
|
+ "#{progressSevice.runWithParticipants(execution,'" + JSON.stringify(arr) + "')}";
|
|
|
+
|
|
|
+ // console.log('服务任务的节点',selectModel)
|
|
|
+ // console.log("arr的值",arr)
|
|
|
+ if (selectModel.documentation == undefined) {
|
|
|
+ selectModel.extensionElements = this.model.create('bpmn:Documentation', { text: JSON.stringify(arr) });
|
|
|
+ } else {
|
|
|
+ selectModel.documentation[0].text = JSON.stringify(arr);
|
|
|
+ }
|
|
|
+ // selectModel.$attrs['activiti:field'] = JSON.stringify(arr);
|
|
|
+ // let extensionElements = this.model.create('bpmn:ExtensionElements'),
|
|
|
+ // field = this.model.createAny('activiti:field', 'http://activiti.org/bpmn', {
|
|
|
+ // event: 'create',
|
|
|
+ // name:'expression',
|
|
|
+ // }),
|
|
|
+ // string = this.model.createAny('activiti:string', 'http://activiti.org/bpmn', {
|
|
|
+ // event: 'create',
|
|
|
+
|
|
|
+ // });
|
|
|
+ // console.log("field",field)
|
|
|
+ // field.extensionElements = string
|
|
|
+ // extensionElements.get('values').push(field);
|
|
|
+ // selectModel.extensionElements = extensionElements
|
|
|
+ // selectModel.value.push(field)
|
|
|
+ // 渲染xml
|
|
|
+ definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
|
|
|
+ this.bpmn.importXML(xml);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 指派用户改变事件
|
|
|
+ // assignChange(arr) {
|
|
|
+ // if(!this.nodeId) return
|
|
|
+ // this.getXML().then(({definitions, context}) => {
|
|
|
+ // let eles = definitions.rootElements[0].extensionElements;
|
|
|
+ // if(eles) {
|
|
|
+ // let values = eles.get('values'),
|
|
|
+ // i = values.length,
|
|
|
+ // index;
|
|
|
+ // while(i--) {
|
|
|
+ // if('sc:transfer' == values[i].$type && this.nodeId == values[i].taskRef) {
|
|
|
+ // index = i;
|
|
|
+ // break
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // if(index) {
|
|
|
+ // if(arr.length) {
|
|
|
+ // values[index].usersRange = "${workOrderUserService.findUsers('"+arr+"')}"
|
|
|
+ // } else {
|
|
|
+ // values.splice(index, 1)
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // if(arr.length) {
|
|
|
+ // let scTransfer = this.model.createAny('sc:transfer', 'http://sc', {
|
|
|
+ // id: 'sc_transfer_'+(+new Date()),
|
|
|
+ // taskRef: this.nodeId,
|
|
|
+ // usersRange: "${workOrderUserService.findUsers('"+arr+"')}"
|
|
|
+ // })
|
|
|
+ // eles.get('values').push(scTransfer);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // // if(arr.length) {
|
|
|
+ // // eles = this.model.create('bpmn:ExtensionElements');
|
|
|
+ // // let scTransfer = this.model.createAny('sc:transfer', 'http://sc', {
|
|
|
+ // // id: 'sc_transfer_'+(+new Date()),
|
|
|
+ // // taskRef: this.nodeId,
|
|
|
+ // // usersRange: "${workOrderUserService.findUsers('"+arr+"')}"
|
|
|
+ // // })
|
|
|
+ // // eles.get('values').push(scTransfer);
|
|
|
+ // // } else {
|
|
|
+ // // return;
|
|
|
+ // // }
|
|
|
+ // }
|
|
|
+ // // 渲染xml
|
|
|
+ // definitions.$model.toXML(definitions, {format: true}, (err,xml) => {
|
|
|
+ // this.bpmn.importXML(xml)
|
|
|
+ // })
|
|
|
+ // })
|
|
|
+ // },
|
|
|
+ // 节点连线的节点动作值改变
|
|
|
+ sequenceChange(val) {
|
|
|
+ if (!this.nodeId) return;
|
|
|
+ this.getXML().then(({ definitions, context }) => {
|
|
|
+ let eles = definitions.rootElements[0].flowElements,
|
|
|
+ selectModel,
|
|
|
+ i = eles.length;
|
|
|
+ while (i--) {
|
|
|
+ if (this.nodeId == eles[i].id) {
|
|
|
+ selectModel = eles[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log('节点动作的值', val);
|
|
|
+ let scTransfer = this.model.create('bpmn:FormalExpression', {
|
|
|
+ body: '${action=="' + val + '"}'
|
|
|
+ });
|
|
|
+ if (!val) {
|
|
|
+ scTransfer = null;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ 2,驳回后的节点加监听器
|
|
|
+ <extensionElements>
|
|
|
+ <activiti:taskListener event="create" class="com.bz.smart_city.activiti.listener.ReturnTaskListener"></activiti:taskListener>
|
|
|
+ </extensionElements>
|
|
|
+ 3,驳回后的节点加内容
|
|
|
+ from上级节点
|
|
|
+ assignee:first受理人,last处理人
|
|
|
+
|
|
|
+ <documentation>{"rejectConfig":[{"from":"usertask2","assignee":"first"},{"from":"usertask3","assignee":"last"}]}</documentation>
|
|
|
+ */
|
|
|
+ if (val === 'reject') {
|
|
|
+ // 获取节点的驳回处理人
|
|
|
+ let root = definitions.rootElements[0],
|
|
|
+ obj = {},
|
|
|
+ documentation = root.get('documentation');
|
|
|
+ if (documentation.length) {
|
|
|
+ obj = documentation[0].text ? JSON.parse(documentation[0].text) : {};
|
|
|
+ }
|
|
|
+ let sourceRef = selectModel.sourceRef,
|
|
|
+ targetRef = selectModel.targetRef,
|
|
|
+ targetRefDoc = targetRef.get('documentation'),
|
|
|
+ doc = this.model.create('bpmn:Documentation', {
|
|
|
+ text: '{"rejectConfig":[{"from":"' + sourceRef.id + '","assignee":"' + obj[sourceRef.id] + '"}]}'
|
|
|
+ });
|
|
|
+ if (obj[sourceRef.id]) {
|
|
|
+ if (targetRefDoc.length) {
|
|
|
+ let temp = targetRefDoc[0].text;
|
|
|
+ temp = temp ? JSON.parse(temp) : {};
|
|
|
+ let config = temp.rejectConfig,
|
|
|
+ tag = false;
|
|
|
+ // 如果已有,则替换assignee的值
|
|
|
+ for (let i in config) {
|
|
|
+ if (config[i].from == sourceRef.id) {
|
|
|
+ tag = true;
|
|
|
+ config[i].assignee = obj[sourceRef.id];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 没有则添加一条记录
|
|
|
+ if (!tag) {
|
|
|
+ config.push({
|
|
|
+ from: sourceRef.id,
|
|
|
+ assignee: obj[sourceRef.id]
|
|
|
+ });
|
|
|
+ }
|
|
|
+ targetRefDoc[0].text = JSON.stringify({ rejectConfig: config });
|
|
|
+ } else {
|
|
|
+ targetRefDoc.push(doc);
|
|
|
+ }
|
|
|
+
|
|
|
+ // let extensionElements = this.model.create('bpmn:ExtensionElements'),
|
|
|
+ // foo = this.model.createAny('activiti:taskListener', 'http://activiti.org/bpmn', {
|
|
|
+ // event: 'create',
|
|
|
+ // class: 'com.bz.smart_city.activiti.listener.ReturnTaskListener'
|
|
|
+ // });
|
|
|
+
|
|
|
+ // extensionElements.get('values').push(foo);
|
|
|
+ // targetRef.extensionElements = extensionElements
|
|
|
+ } else {
|
|
|
+ // this.$message.error('该驳回操作没有设置驳回处理人员')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ selectModel.conditionExpression = scTransfer;
|
|
|
+ // // 渲染xml
|
|
|
+ definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
|
|
|
+ this.bpmn.importXML(xml);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 获取所有的上游用户节点ID及名字
|
|
|
+ getPrevUserTaskObj(id, context) {
|
|
|
+ let list = this.nodeIdOrderList,
|
|
|
+ i = list.length,
|
|
|
+ index,
|
|
|
+ temp;
|
|
|
+ while (i--) {
|
|
|
+ index = list[i].indexOf(id);
|
|
|
+ while (index > 0 && index--) {
|
|
|
+ temp = context.elementsById[list[i][index]];
|
|
|
+ if (temp.$type == 'bpmn:UserTask') {
|
|
|
+ this.prevUserTaskObj[list[i][index]] = temp.name || temp.id;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 保存BPMN内容
|
|
|
+ submit(callback) {
|
|
|
+ //
|
|
|
+ this.getXML().then(({ definitions, context }) => {
|
|
|
+ let rootElements = definitions.rootElements[0];
|
|
|
+ rootElements.id = this.params.data.processKey;
|
|
|
+ definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
|
|
|
+ this.bpmn.importXML(xml); //将字符串转换成图表显示出来, this.bpmnModeler.importXML(xmlStr, (err) => {if(err){}else{成功之后的回调}}
|
|
|
+ let $loading = this.$loading();
|
|
|
+ initXml = xml;
|
|
|
+ this.$http
|
|
|
+ .postForm('/sc-community/workflow/process/saveBpmnContent', {
|
|
|
+ id: this.params.data.id,
|
|
|
+ content: xml,
|
|
|
+ svg: ''
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ $loading.close();
|
|
|
+ if (0 == res.status) {
|
|
|
+ this.$message.success(res.msg);
|
|
|
+ this.params.callback && this.params.callback();
|
|
|
+ this.$emit('close');
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg);
|
|
|
+ }
|
|
|
+ callback && callback();
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ $loading.close();
|
|
|
+ callback && callback();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getForm() {
|
|
|
+ this.$http
|
|
|
+ .get('/sc-community/workflow/form/list')
|
|
|
+ .then((data) => {
|
|
|
+ this.getFormList = data.data;
|
|
|
+ })
|
|
|
+
|
|
|
+ .catch(function () {});
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.bpmn = new BpmnModeler({
|
|
|
+ container: this.$refs.bpmn,
|
|
|
+ additionalModules: [
|
|
|
+ {
|
|
|
+ __init__: ['Provider'], //定义完provider这个类后,必须导出
|
|
|
+ translate: ['value', translateModer],
|
|
|
+ Provider: ['type', Provider]
|
|
|
+ // Context: ['type', Context]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ });
|
|
|
+ //向后台请求xml数据,如果没有的话,给一段默认的xml字符串
|
|
|
+ this.getBpmn().then((xml) => {
|
|
|
+ if (xml) {
|
|
|
+ this.bpmn.importXML(xml, (err) => {
|
|
|
+ // 连接两个节点
|
|
|
+ // let elementRegistry = this.bpmn.get('elementRegistry'),
|
|
|
+ // ele1 = elementRegistry.get('startevent1'),
|
|
|
+ // ele2 = elementRegistry.get('Task_1iyqgyp'),
|
|
|
+ // ele3 = elementRegistry.get('EndEvent_0botuxl'),
|
|
|
+ // modeling = this.bpmn.get('modeling')
|
|
|
+ // modeling.connect(ele1, ele2, {
|
|
|
+ // type: 'bpmn:SequenceFlow'//线
|
|
|
+ // })
|
|
|
+ // modeling.connect(ele2, ele3, {
|
|
|
+ // type: 'bpmn:SequenceFlow'
|
|
|
+ // })
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.bpmn.importXML(
|
|
|
+ `
|
|
|
+ <?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:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" 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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
|
|
|
+ <process id="myProcess" name="My process" isExecutable="true">
|
|
|
+ <startEvent id="startevent1" name="开始"></startEvent>
|
|
|
+ </process>
|
|
|
+ <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
|
|
|
+ <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
|
|
|
+ <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
|
|
|
+ <omgdc:Bounds height="35.0" width="35.0" x="84.0" y="150.0"></omgdc:Bounds>
|
|
|
+ </bpmndi:BPMNShape>
|
|
|
+ </bpmndi:BPMNPlane>
|
|
|
+ </bpmndi:BPMNDiagram>
|
|
|
+ </definitions>
|
|
|
+ `,
|
|
|
+ (err) => {
|
|
|
+ // 手动创建节点
|
|
|
+ // this.getXML().then(({definitions, context}) => {
|
|
|
+ // let model = new BpmnModdle();
|
|
|
+ // var bpmnProcess = model.create('bpmn:UserTask', {
|
|
|
+ // id: 'UserTask_1_1',
|
|
|
+ // });
|
|
|
+ // var bpmdi = model.create('bpmndi:BPMNShape', {
|
|
|
+ // // 填充颜色
|
|
|
+ // fill: '#fff',
|
|
|
+ // // 边框颜色
|
|
|
+ // stroke: '#000',
|
|
|
+ // bpmnElement: bpmnProcess,
|
|
|
+ // bounds: model.create('dc:Bounds', { x: 100.0, y: 200.0, width: 100.0, height: 50.0 })
|
|
|
+ // })
|
|
|
+ // definitions.get('rootElements')[0].flowElements.push(bpmnProcess);
|
|
|
+ // definitions.diagrams[0].plane.planeElement.push(bpmdi)
|
|
|
+ // model.toXML(definitions, (err, xmlStrUpdated) => {
|
|
|
+ // // console.log(xmlStrUpdated)
|
|
|
+ // this.bpmn.importXML(xmlStrUpdated)
|
|
|
+ // });
|
|
|
+ // })
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 给图绑定事件,当图有发生改变就会触发这个事件
|
|
|
+ // this.bpmn.on('commandStack.changed', (e) => {
|
|
|
+ // console.log(e)
|
|
|
+ // // this.bpmn.on('canvas.viewbox.changed', () => {
|
|
|
+ // // this.bpmn.saveXML({format: true}, (err, xml) => {
|
|
|
+ // // console.log(xml)
|
|
|
+ // // })
|
|
|
+ // // })
|
|
|
+ // })
|
|
|
+ // this.bpmn.injector._instances.eventBus所有事件// 监听 element
|
|
|
+ // console.log(this.bpmn.injector._instances.eventBus._listeners)
|
|
|
+ // 删除元素
|
|
|
+ this.bpmn.on('commandStack.elements.delete.postExecuted', (e) => {
|
|
|
+ this.getXML().then(({ definitions, context }) => {
|
|
|
+ definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
|
|
|
+ this.bpmn.importXML(xml);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ // 自动给添加的节点赋名
|
|
|
+ // this.bpmn.on('element.changed', e => {
|
|
|
+ // this.getXML().then(({definitions, context}) => {
|
|
|
+ // let el = context.elementsById[e.element.id];
|
|
|
+ // if(!el || el.name) return
|
|
|
+ // let type = el.$type,
|
|
|
+ // set = new Set(['bpmn:UserTask', 'bpmn:ServiceTask', 'bpmn:EndEvent', 'bpmn:StartEvent', 'bpmn:ExclusiveGateway'])//ExclusiveGateway:网关
|
|
|
+ // if(!set.has(type)) return
|
|
|
+ // if(type === 'bpmn:UserTask') {
|
|
|
+ // el.name = '用户节点' + el.id.replace('UserTask_', '')
|
|
|
+ // }
|
|
|
+ // if(type === 'bpmn:ServiceTask') {
|
|
|
+ // el.name = '服务节点' + el.id.replace('ServiceTask_', '')
|
|
|
+ // }
|
|
|
+ // if(type === 'bpmn:EndEvent') {
|
|
|
+ // el.name = '结束'
|
|
|
+ // }
|
|
|
+ // if(type === 'bpmn:StartEvent') {
|
|
|
+ // el.name = '开始'
|
|
|
+ // }
|
|
|
+ // if(type === 'bpmn:ExclusiveGateway') {
|
|
|
+ // el.name = '网关' + el.id.replace('ExclusiveGateway_', '')
|
|
|
+ // }
|
|
|
+ // definitions.$model.toXML(definitions, {format: true}, (err,xml) => {
|
|
|
+ // this.bpmn.importXML(xml)
|
|
|
+ // })
|
|
|
+ // })
|
|
|
+ // })
|
|
|
+
|
|
|
+ this.model = new BpmnModdle();
|
|
|
+ // 控制用户选择模块、网关条件显示
|
|
|
+ this.bpmn.on('element.click', (e) => {
|
|
|
+ this.nodeId = e.element.id;
|
|
|
+ this.showConditionSelect = false;
|
|
|
+ this.showUserSelect = false;
|
|
|
+ this.showFormSelect = false;
|
|
|
+ this.showSerivceSelect = false;
|
|
|
+ this.showAssign = false;
|
|
|
+ this.showSequence = false;
|
|
|
+ this.prevUserTaskObj = {};
|
|
|
+ this.isReject = false;
|
|
|
+ this.rejectUserValue = '';
|
|
|
+ this.sequenceFormKey = null;
|
|
|
+ this.sequenceValue = null;
|
|
|
+ this.getXML().then(({ definitions, context }) => {
|
|
|
+ this.getIdOrder(definitions.rootElements[0].flowElements);
|
|
|
+ let el = context.elementsById[this.nodeId];
|
|
|
+ if (!el) return;
|
|
|
+
|
|
|
+ // 用户设置显示控制
|
|
|
+ if ('bpmn:UserTask' == el.$type) {
|
|
|
+ // 获取节点的驳回处理人
|
|
|
+ let root = definitions.rootElements[0],
|
|
|
+ obj = {},
|
|
|
+ documentation = root.get('documentation');
|
|
|
+ if (documentation.length) {
|
|
|
+ obj = documentation[0].text ? JSON.parse(documentation[0].text) : {};
|
|
|
+ this.rejectUserValue = obj[this.nodeId];
|
|
|
+ }
|
|
|
+ this.showUserSelect = true;
|
|
|
+ this.showFormSelect = true;
|
|
|
+ let arrts = el.$attrs;
|
|
|
+ this.userValues = el.documentation[0].text;
|
|
|
+ this.formValues = arrts['activiti:formKey'];
|
|
|
+ // 驳回表单
|
|
|
+ this.userFormKey = this.formValues;
|
|
|
+ this.assignValues = '';
|
|
|
+ new Promise((resolve) => {
|
|
|
+ this.getFormDetail(this.formValues, resolve);
|
|
|
+ }).then((_) => {
|
|
|
+ // 获取指派信息
|
|
|
+ // let values = definitions.rootElements[0].extensionElements.values,
|
|
|
+ // i = values.length;
|
|
|
+ // while(i--) {
|
|
|
+ // if('sc:transfer' == values[i].$type && this.nodeId == values[i].taskRef) {
|
|
|
+ // this.assignValues = values[i].usersRange
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ });
|
|
|
+ // 获取所有上游用户节点对象
|
|
|
+ this.getPrevUserTaskObj(el.id, context);
|
|
|
+ } else {
|
|
|
+ this.showUserSelect = false;
|
|
|
+ this.showFormSelect = false;
|
|
|
+ this.userValues = '';
|
|
|
+ this.formValues = '';
|
|
|
+ this.prevUserTaskObj = {};
|
|
|
+ }
|
|
|
+ // 服务设置显示控制
|
|
|
+ if ('bpmn:ServiceTask' == el.$type) {
|
|
|
+ console.log('ServiceTask', el);
|
|
|
+ this.showSerivceSelect = true;
|
|
|
+ let arrts = el.$attrs;
|
|
|
+ this.serviceValues = JSON.parse(el.documentation[0].text);
|
|
|
+ // this.serviceValues = arrts['activiti:expression']
|
|
|
+
|
|
|
+ // 获取所有上游用户节点对象
|
|
|
+ this.getPrevUserTaskObj(el.id, context);
|
|
|
+ } else {
|
|
|
+ this.showSerivceSelect = false;
|
|
|
+ this.serviceValues = '';
|
|
|
+ }
|
|
|
+ // 连接线显示控制
|
|
|
+ if ('bpmn:SequenceFlow' == el.$type) {
|
|
|
+ // 网关条件设置显示控制
|
|
|
+ if (el.sourceRef && 'bpmn:ExclusiveGateway' == el.sourceRef.$type) {
|
|
|
+ this.showConditionSelect = true;
|
|
|
+ this.conditionValues = el.conditionExpression && el.conditionExpression.body;
|
|
|
+ // 获取当前网关条件上游最近一个用户节点
|
|
|
+ let id = this.getPrevNode(context, el);
|
|
|
+ // 获取节点的表单key集合
|
|
|
+ let formArr = [],
|
|
|
+ node,
|
|
|
+ i = id.length;
|
|
|
+ while (i--) {
|
|
|
+ node = context.elementsById[id[i]];
|
|
|
+ if (node.$attrs) {
|
|
|
+ formArr.push(node.$attrs['activiti:formKey']);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.prevFormId = formArr;
|
|
|
+ // 获取网关节点的上游连接线的actionValue
|
|
|
+ let incoming = el.sourceRef.incoming,
|
|
|
+ actionValueArr = [],
|
|
|
+ temp;
|
|
|
+ i = incoming.length;
|
|
|
+ while (i--) {
|
|
|
+ temp = incoming[i].conditionExpression;
|
|
|
+ if (temp && temp.body) {
|
|
|
+ actionValueArr.push(temp.body.substr(20, 4));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.showConditionSelect = false;
|
|
|
+ this.conditionValues = '';
|
|
|
+
|
|
|
+ let sourceRef = el.sourceRef, // 起始节点
|
|
|
+ targetRef = el.targetRef; // 目标节点
|
|
|
+ this.showSequence = true;
|
|
|
+ // 获取起始节点的formKey
|
|
|
+ this.sequenceFormKey = sourceRef.$attrs['activiti:formKey'];
|
|
|
+ this.sequenceValue = el.conditionExpression && el.conditionExpression.body;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.showSequence = false;
|
|
|
+ this.sequenceFormKey = null;
|
|
|
+ this.sequenceValue = null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getForm();
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang='scss'>
|
|
|
+.bpmn {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ .bpmn-title {
|
|
|
+ line-height: 30px;
|
|
|
+ // padding: 0 20px;
|
|
|
+ border-bottom: 1px solid #d8d8d8;
|
|
|
+ }
|
|
|
+ .bpmn-left {
|
|
|
+ width: 80%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ .bpmn-right {
|
|
|
+ width: 20%;
|
|
|
+ .bpmn-node {
|
|
|
+ padding: 20px;
|
|
|
+ border: 1px solid #d8d8d8;
|
|
|
+ margin: 5px 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .djs-palette.two-column.open {
|
|
|
+ width: auto;
|
|
|
+ .entry {
|
|
|
+ float: inherit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .djs-context-pad .entry {
|
|
|
+ .bpmn-icon-end-event-none {
|
|
|
+ display: none;
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .bjs-powered-by,
|
|
|
+ .group[data-group='tools'],
|
|
|
+ .group[data-group='gateway'],
|
|
|
+ .group[data-group='activity'],
|
|
|
+ .group[data-group='data-object'],
|
|
|
+ .group[data-group='data-store'],
|
|
|
+ .group[data-group='collaboration'],
|
|
|
+ .bpmn-icon-intermediate-event-none,
|
|
|
+ .bpmn-icon-subprocess-expanded,
|
|
|
+ .bpmn-icon-gateway-xor,
|
|
|
+ .djs-context-pad .group[data-group='model'],
|
|
|
+ .djs-context-pad .bpmn-icon-screw-wrench {
|
|
|
+ display: none;
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|