<template>
    <div class="app-container">
        <div class="containers">
            <div class="canvas" ref="canvas"></div>
            <ul class="buttons">
                <li>
                    <a href="javascript:" class="active" ref="saveXML" title="保存为bpmn"
                    >保存为bpmn</a
                    >
                </li>
                <li>
                    <a href="javascript:" class="active" ref="saveSvg" title="保存为svg"
                    >保存为svg</a
                    >
                </li>
                <li>
                    <a
                    href="javascript:"
                    class="active"
                    @click="handlerUndo"
                    title="撤销操作"
                    >撤销</a
                    >
                </li>
                <li>
                    <a
                    href="javascript:"
                    class="active"
                    @click="handlerRedo"
                    title="恢复操作"
                    >恢复</a
                    >
                </li>
                <li>
                    <a
                    href="javascript:"
                    class="active"
                    @click="handlerZoom(0.1)"
                    title="放大"
                    >放大</a
                    >
                </li>
                <li>
                    <a
                    href="javascript:"
                    class="active"
                    @click="handlerZoom(-0.1)"
                    title="缩小"
                    >缩小</a
                    >
                </li>
                <li>
                    <a
                    href="javascript:"
                    class="active"
                    @click="handlerZoom(0)"
                    title="还原"
                    >还原</a
                    >
                </li>
                <li>
                    <el-button type="primary" @click="submitBpmn" v-if="!loading" title="提交流程图">提 交</el-button>
                    <el-button :loading="loading" type="primary" @click="submitBpnm" v-else>提交中...</el-button>
                </li>
            </ul>
        
        </div>
         <!-- 添加或修改节点参数配置对话框 -->
        <el-dialog  title="修改" :visible.sync="serviceTask" width="600px" append-to-body :before-close="cancel" :close-on-click-modal="false">
            <el-form ref="form" :model="formData" :rules="rules" label-width="120px" >
                <el-row :gutter="20">
                    <el-col :span="24" >
                        <el-form-item label="节点名称" prop="name" >
                        <el-input v-model.trim="formData.name" placeholder="请输入节点名称"  @input="onInput" maxlength="30" show-word-limit  />
                        </el-form-item>
                    </el-col>
                    <!-- <el-col :span="24">
                        <el-form-item label="执行顺序" prop="order">
                        <el-input v-model.trim="formData.order" placeholder="请输入执行顺序"  @input="onInput" maxlength="30" show-word-limit  />
                        </el-form-item>
                    </el-col> -->
                    <el-col :span="24">
                        <el-form-item label="执行场景" prop="nodeId">
                        <treeselect v-model="formData.nodeId" :options="dataOptions" :show-count="true" placeholder="请选择执行场景" />
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" @click="submitForm" v-if="!loading">确 定</el-button>
                <el-button :loading="loading" type="primary" @click="submitForm" v-else>提交中...</el-button>
                <el-button @click="cancel">取 消</el-button>
            </div>
        </el-dialog>

        <!-- 添加或修改流程图参数配置对话框 -->
        <el-dialog  title="修改" :visible.sync="openBpmn" width="600px" append-to-body :before-close="cancel" :close-on-click-modal="false">
            <el-form ref="form2" :model="formData2" :rules="rules2" label-width="120px" >
                <el-row :gutter="20">
                    <el-col :span="24" >
                        <el-form-item label="流程图名称" prop="name" >
                        <el-input v-model.trim="formData2.name" placeholder="请输入流程图名称"  @input="onInput" maxlength="30" show-word-limit  />
                        </el-form-item>
                    </el-col>
                    <el-col :span="24" >
                        <el-form-item label="流程图描述" prop="procdefDescribe" >
                        <el-input type="textarea" v-model.trim="formData2.procdefDescribe" placeholder="请输入流程图描述"  @input="onInput" maxlength="60" show-word-limit  />
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" @click="submitBpnmForm" v-if="!loading">确 定</el-button>
                <el-button :loading="loading" type="primary" @click="submitBpnmForm" v-else>提交中...</el-button>
                <el-button @click="cancelBpnm">取 消</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
// 引入相关的依赖
import { xmlStr } from "@/mock/xmlStrPreview2";
import { CustomModeler } from "@/components/customBpmn";
import Treeselect from "@riophae/vue-treeselect";
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { getBpmnZkNodeList, getBpmnZkNodeTreeList, addBpmnZkNode, updataBpmnZkNode, 
getBpmnZkReNodeProcdefTreeList, getBpmnZkReNodeProcdefCheckedTreeList, 
getBpmnZkReProcdefList, addBpmnZkReProcdef, updataBpmnZkReProcdef, delBpmnZkReProcdef, getBpmnZkReNodeProcdefListByPorcedfId} from "@/api/business/Middleware/bpmn";
export default {
  name: "",
  components: { Treeselect },
  data() {
    return {
      bpmnModeler: null,
      container: null,
      canvas: null,
      scale: 1,
      userTask: false,
      serviceTask: false,
      scriptTask: false,
      sequenceFlow: "",
      formData: {
        name: "",
        type: "",
        nodeId:undefined,
        // order:undefined
    
      },
      //节点树选项
      dataOptions: [],

      data:undefined,
      openBpmn:false,
      // 节点表单校验
      rules: {
        name: [
          { required: true, message: "节点名称不能为空", trigger: "blur" }
        ],
        // order: [
        //   { required: true, message: "执行顺序不能为空", trigger: "blur" }
        // ],
        nodeId: [
          { required: true, message: "场景不能为空", trigger: ["blur",'change'] }
        ],
      },
      formData2: {
        name: undefined,
        procdefDescribe:undefined,
      },
      // 流程图表单校验
      rules2: {
        name: [
          { required: true, message: "流程描述名称不能为空", trigger: "blur" }
        ],
        procdefDescribe: [
          { required: true, message: "流程图描述不能为空", trigger: ["blur",'change'] }
        ],
      },
      loading:false,
      bpmnData:[], //待提交数据，
      bpmnTitle:undefined,//待提交流程图名称
      bpmnNodeId:undefined,// 弹框打开时节点Id
      xml:undefined,
      serviceTaskStatus:false,
      checkedKeys:[],//流程图返回节点
      bpmnDataFH:[],//流程图返回信息
    };
  },
  created(){

    
  },
  mounted() {
    this.getNodeTree()

    if(this.$route.query.name){
      getBpmnZkReProcdefList({name:this.$route.query.name,current: 1,size: 20}).then(res=>{
        this.bpmnDataFH = res.data.records[0]
        this.init()
      })
      getBpmnZkReNodeProcdefListByPorcedfId({procdefId:this.$route.query.id}).then(res=>{
        this.checkedKeys = res.data
      })
    }else{
      this.init()
    }
  },
  
  // 方法集合
  methods: {
      //强制el-input刷新
    onInput(){
        this.$forceUpdate();
    },
    init() {
      // 获取到属性ref为“canvas”的dom节点
      const canvas = this.$refs.canvas;
      // 建模
      this.bpmnModeler = new CustomModeler({
        container: canvas,
        additionalModules: [
          {
            // 禁止编辑label
            labelEditingProvider: ["value", ""]
          }
        ]
      });
      this.createNewDiagram();
      
    },
    async createNewDiagram() {
      let that = this
      try {
        //编辑或默认视图
        if(that.bpmnDataFH.resourceName){
          var result = await this.bpmnModeler.importXML(that.bpmnDataFH.resourceName);
        }else{
          var result = await this.bpmnModeler.importXML(xmlStr);
        }
        
        // 上传
        console.log(result)
        const { warnings } = result;
        this.data = result.warnings
        console.log(warnings);

        this.success();
      } catch (err) {
        console.log(err.message, err.warnings);
      }
    },
    success() {
      this.addBpmnListener();
      this.addModelerListener();
      this.addEventBusListener();
    },
    addModelerListener() {
      const bpmnjs = this.bpmnModeler;
      const that = this;
      // 这里我是用了一个forEach给modeler上添加要绑定的事件
      const events = [
        "shape.added",
        "shape.move.end",
        "shape.removed",
        "connect.end",
        "connect.move"
      ];
      events.forEach(function(event) {
        that.bpmnModeler.on(event, e => {
          console.log(1,event, e,that.data );
          var elementRegistry = bpmnjs.get("elementRegistry");
          var shape = e.element ? elementRegistry.get(e.element.id) : e.shape;
          console.log(2,shape);
        });
      });
    },
    // 下载
    async addBpmnListener() {
      console.log(11111)
      const that = this;
      const downloadLink = this.$refs.saveXML;
      console.log(downloadLink)
      const downloadSvgLink = this.$refs.saveSvg;

      async function opscoffee() {
        try {
          const result = await that.saveSVG();
          const { svg } = result;

          that.setEncoded(downloadSvgLink, "ops-coffee.svg", svg);
        } catch (err) {
          console.log(err);
        }

        try {
          const result = await that.saveXML();
          const { xml } = result;

          that.setEncoded(downloadLink, "ops-coffee.bpmn", xml);
        } catch (err) {
          console.log(err);
        }
      }

      opscoffee();
      this.bpmnModeler.on("commandStack.changed", opscoffee);
    },
    async saveSVG(done) {
      try {
        const result = await this.bpmnModeler.saveSVG(done);
        return result;
      } catch (err) {
        console.log(err);
      }
    },
    async saveXML(done) {
      try {
        const result = await this.bpmnModeler.saveXML({ format: true }, done);
        this.xml = result
        // console.log(this.xml)
        return result;
      } catch (err) {
        console.log(err);
      }
    },
    setEncoded(link, name, data) {
      const encodedData = encodeURIComponent(data);

      if (data) {
        link.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
        link.download = name;
      }
    },
    handlerRedo() {
      this.bpmnModeler.get("commandStack").redo();
    },
    handlerUndo() {
      this.bpmnModeler.get("commandStack").undo();
    },
    handlerZoom(radio) {
      const newScale = !radio ? 1.0 : this.scale + radio;
      this.bpmnModeler.get("canvas").zoom(newScale);

      this.scale = newScale;
    },
    addEventBusListener() {
      const that = this;
      const eventBus = this.bpmnModeler.get("eventBus");
      const modeling = this.bpmnModeler.get("modeling");
      const elementRegistry = this.bpmnModeler.get("elementRegistry");

      eventBus.on("element.click", function(e) {
        // console.log(
        //   "点击了element",
        //   e.element.businessObject.id,
        //   e.element.businessObject.$type,
        //   e.element.businessObject.name,that.data
        // );
        e.element.businessObject.nodeId = that.formData.nodeId 
        // e.element.businessObject.order = that.formData.order
        console.log(
          "点击了element",
          e,e.element.businessObject.name,
          e.element.businessObject.nodeId
        );

        if (e.element.businessObject.$type == "bpmn:SequenceFlow") {
          const sourceRef = e.element.businessObject.sourceRef;

          if (sourceRef.$type == "bpmn:ExclusiveGateway") {
            var targetElement = elementRegistry.get(sourceRef.id);

            modeling.updateProperties(targetElement, {
              default: e.element.businessObject
            });
          }
        }
      });
    },
    // 节点取消按钮
    cancel() {
        this.serviceTask = false
        // this.reset();
    },
    // 表单重置
    reset() {
      this.formData = {
        name: undefined,
        order: undefined,
        deptId: undefined,
        type: undefined
      };
      this.resetForm("form");
    },
    /** 节点提交按钮 */
    submitForm(row) {
      let that = this
      this.$refs["form"].validate(valid => {
        if (valid) {
            this.msgSuccess("节点属性保存成功");
            this.loading = false
            let data = this.dataOptions
            for(let a = 0; a<Object.keys(data).length; a++){
                if(data[a].id == this.formData.nodeId){
                    this.formData.param =  data[a].params
                }
                if(data[a].children){
                    if(Object.keys(data[a].children).length>0){
                        for(let b = 0; b<Object.keys(data[a].children).length; b++){
                            if(data[a].children[b].id == this.formData.nodeId){
                                this.formData.param = data[a].children[b].params
                            }
                            if(data[a].children[b].children){
                                if(Object.keys(data[a].children[b].children).length>0){
                                    for(let c = 0; c<Object.keys(data[a].children[b].children).length; c++){
                                        if(data[a].children[b].children[c].id == this.formData.nodeId){
                                            this.formData.param = data[a].children[b].children[c].params
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } 
            this.formData.procedefKey = this.$store.state.bpmn.nodeInfo.businessObject.id
            delete this.formData.type
            let arr = JSON.parse(JSON.stringify(this.bpmnData))
            if(arr.length>0){
              let num = 0
              for(let i =0;i<arr.length;i++){
                if(this.$store.state.bpmn.nodeInfo.businessObject.id == arr[i].procedefKey){
                  arr[i] = this.formData
                }else{
                  num +=1
                  if(num == arr.length){
                    this.bpmnData.push(this.formData)
                  }
                }
              }
            }else{
              this.bpmnData.push(this.formData)
            }
            //异步避免需要二次关闭
            setTimeout(()=>{
              that.serviceTask = false
            },1)
        }
      });
    },
    /** 流程图提交按钮 */
    submitBpmn(){
      if(this.bpmnDataFH.name){
        this.formData2.procdefDescribe = this.bpmnDataFH.procdefDescribe
        this.formData2.name = this.bpmnDataFH.name
      }
      this.openBpmn = true
    },
    /** 流程图提交数据 */
    submitBpnmForm(){
      this.$refs["form2"].validate(valid => {
        if (valid) {
            if(this.bpmnData.length<2 && this.checkedKeys.length<2){
              this.msgError("流程图节点数据个数小于2");
            }else{
             
              if(this.checkedKeys.length>1){
                let arr = {}
                arr.name = this.formData2.name
                arr.procdefDescribe = this.formData2.procdefDescribe
                arr.procedefKey = this.formData2.procedefKey
                arr.nodes = []
                for(let i = 0; i<this.checkedKeys.length;i++){
                  arr.nodes[i] = {}
                  arr.nodes[i].param = this.checkedKeys[i].param
                  arr.nodes[i].procedefKey = this.checkedKeys[i].procedefKey
                  arr.nodes[i].nodeId = this.checkedKeys[i].id
                  if(this.bpmnData.length>0){
                   for(let n=0;n<this.bpmnData.length;n++){
                      if(this.bpmnData[n].procedefKey){
                        if(this.bpmnData[n].procedefKey == arr.nodes[i].procedefKey){
                          arr.nodes[i].param = this.bpmnData[n].param
                          arr.nodes[i].nodeId = this.bpmnData[n].nodeId
                        }
                      }
                    }
                  }
                }
                arr.resourceName =  this.xml.xml;
                arr.id = this.bpmnDataFH.id
                console.log(arr)
                updataBpmnZkReProcdef(arr).then(res=>{
                  this.msgSuccess("流程图修改成功");
                  this.loading = false
                  this.openBpmn = false
                  this.$router.push('/business/Middleware/bpmn/index')
                })
              }else if(this.bpmnData.length>1){
                let arr = {}
                arr.name = this.formData2.name
                arr.procdefDescribe = this.formData2.procdefDescribe
                arr.procedefKey = this.formData2.procedefKey
                arr.nodes = this.bpmnData
                arr.resourceName =  this.xml.xml;
                console.log(arr)
                addBpmnZkReProcdef(arr).then(res=>{
                  this.msgSuccess("流程图保存成功");
                  this.loading = false
                  this.openBpmn = false
                  this.$router.push('/business/Middleware/bpmn/index')
                })
              }
              
              
            }
        }
      });
    },
    /** 流程图取消按钮 */
    cancelBpnm(){
      this.openBpmn = false
    },
    getNodeTree(){
        getBpmnZkNodeTreeList().then(res =>{
            if(res.data){
                for(let a = 0; a<Object.keys(res.data).length; a++){
                    this.dataOptions[a] = []
                    this.dataOptions[a].label = res.data[a].name
                    this.dataOptions[a].id = res.data[a].id
                    this.dataOptions[a].params = res.data[a].params
                    if(res.data[a].children){
                    if(Object.keys(res.data[a].children).length>0){
                        this.dataOptions[a].children = []
                        for(let b = 0; b<Object.keys(res.data[a].children).length; b++){
                        this.dataOptions[a].children[b] = {}
                        this.dataOptions[a].children[b].label = res.data[a].children[b].name
                        this.dataOptions[a].children[b].id = res.data[a].children[b].id
                        this.dataOptions[a].children[b].params = res.data[a].children[b].params
                        
                        if(res.data[a].children[b].children){
                            if(Object.keys(res.data[a].children[b].children).length>0){
                            this.dataOptions[a].children[b].children = []
                            for(let c = 0; c<Object.keys(res.data[a].children[b].children).length; c++){
                                this.dataOptions[a].children[b].children[c] = {}
                                this.dataOptions[a].children[b].children[c].label = res.data[a].children[b].children[c].name
                                this.dataOptions[a].children[b].children[c].id = res.data[a].children[b].children[c].id
                                this.dataOptions[a].children[b].children[c].params= res.data[a].children[b].children[c].params
                            }
                            }
                        }
                        }
                    }
                    }
                }
                // console.log(this.dataOptions)
            }
        })
    },
    currDeptChange(val) {
      console.log('currDeptChange', val)
    },
  },
  // 计算属性
  computed: {
    task: {
      get: function() {
        const that = this;
        const element = this.$store.state.bpmn.nodeInfo;
        if (element.businessObject) {
          // console.log(
          //   element.businessObject.id,
          //   element.businessObject.name,
          //   element.businessObject.$type
          // );

        //   if (element.businessObject.$type === "bpmn:UserTask") {
        //     that.formData.type = "用户任务1";
        //     that.formData.name = element.businessObject.name;
        //     that.userTask = this.$store.state.bpmn.nodeVisible;
        //   }

          if (element.businessObject.$type === "bpmn:ServiceTask") {
            that.formData = {
              name: "",
              type: "",
              nodeId:undefined,
              
            }
            that.formData.name = element.businessObject.name;
            let data = that.bpmnData
            
            if(that.checkedKeys.length>0){
              for(let i = 0; i<that.checkedKeys.length;i++){
                if(element.businessObject.id == that.checkedKeys[i].procedefKey){
                  this.formData.nodeId = that.checkedKeys[i].id
                }
              }
            }
            if(data.length>0){
              for(let i = 0; i<data.length;i++){
                if(element.businessObject.id == data[i].procedefKey){
                  this.formData.nodeId = data[i].nodeId
                }
              }
            }
            // if(that.serviceTaskStatus == false){
            //   that.serviceTask = true
            // }else{
            //   that.serviceTask = false
            // }
            that.serviceTask = this.$store.state.bpmn.nodeVisible;
            console.log(data,this.formData)
          }

        //   if (element.businessObject.$type === "bpmn:ScriptTask") {
        //     that.formData.type = "脚本任务1";
        //     that.formData.name = element.businessObject.name;
        //     that.serviceTask = this.$store.state.bpmn.nodeVisible;
        //   }

        //   if (element.businessObject.$type === "bpmn:SequenceFlow") {
        //     that.sequenceFlow = element.businessObject.name;
        //     that.scriptTask = this.$store.state.bpmn.nodeVisible;
        //   }
        }

        return false;
      },
      set: function(val) {
        this.$store.state.bpmn.nodeVisible = val;
      }
    }
  },
  watch: {
    'formData.nodeId': 'currDeptChange',
    task(val) {},
    userTask(val) {
      this.$store.state.bpmn.nodeVisible = val;
    },
    serviceTask(val) {
      this.$store.state.bpmn.nodeVisible = val;
    },
    scriptTask(val) {
      this.$store.state.bpmn.nodeVisible = val;
    },
    sequenceFlow(val) {
      const element = this.$store.state.bpmn.nodeInfo;
      const modeling = this.bpmnModeler.get("modeling");
      modeling.updateLabel(element, val);
    },
    "formData.name": {
      handler(val, old) {
        const element = this.$store.state.bpmn.nodeInfo;
        const modeling = this.bpmnModeler.get("modeling");
        modeling.updateLabel(element, val);
      },
      deep: true
    },
  }
};
</script>

<style scoped>
.containers {
  background: white;
  overflow: auto;
  background-image: linear-gradient(
      90deg,
      rgba(220, 220, 220, 0.5) 6%,
      transparent 0
    ),
    linear-gradient(rgba(192, 192, 192, 0.5) 6%, transparent 0);
  background-size: 12px 12px;
  width: 100%;
  height: 85vh;
  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
.canvas {
  width: 100%;
  height: 100%;
}
.panel {
  position: absolute;
  right: 0;
  top: 0;
  width: 300px;
}
.buttons {
  position: absolute;
  left: 80px;
  bottom: 20px;
}
.buttons li {
  display: inline-block;
  margin: 5px;
}
.buttons li a {
  color: #999;
  background: #eee;
  cursor: not-allowed;
  padding: 8px;
  border: 1px solid #ccc;
  text-decoration: none;
}
.buttons li a.active {
  color: #333;
  background: #fff;
  cursor: pointer;
}
.demo-drawer-footer {
  width: 100%;
  position: absolute;
  bottom: 0;
  left: 0;
  border-top: 1px solid #e8e8e8;
  padding: 10px 16px;
  text-align: right;
  background: #fff;
}
</style>
