<!--
 * @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>