<template>
  <div class="page" v-loading="selectLoading">
    <el-card class="tree" shadow="always">
      <div slot="header" class="clearfix">

        <div style=" font-weight: 600;
        font-size: 17px;
        letter-spacing: 3px;">工作流程</div>
        <div>
          <el-button style="padding:4px 7px" icon="el-icon-plus" @click="flowClick(1)" size="mini" type="success">
          </el-button>
          <el-button style="padding:4px 7px" icon="el-icon-edit" @click="flowClick(2)" size="mini" type="primary">
          </el-button>
          <!-- <el-button style="padding:4px 7px" icon="el-icon-close" @click="flowClick(3)" size="mini" type="danger">
          </el-button> -->
        </div>
      </div>
      <el-scrollbar wrap-style="overflow-x:hidden;" style="height: calc(100vh - 180px)">
      <el-tree v-loading="treeLoading" highlight-current :data="treeData" :props="defaultProps" default-expand-all
        @node-click="handleNodeClick">
        <span slot-scope="{ node, data }" class="custom-tree-node">
          <!--可以根据情况，以数据类型来显示不同的图标或图片-->
          <svg-icon icon-class="wjj" style="margin-right: 5px; color: rgb(255, 207, 92)" v-if="data.child.length"
            class="iconfont icon-folder-open-fill" />
          <svg-icon icon-class="wj" style="margin-right: 5px; color: rgb(255, 207, 92)" v-else
            class="iconfont icon-wenjian" />
          <span>{{ node.label }}</span>
        </span>
      </el-tree>
      </el-scrollbar>
    </el-card>
    <div class="super-flow-base-demo" ref="flowContainer" @click="flowNodeClick">
      <!-- <div class="tips">流程图操作工具：鼠标右键</div> -->
      <super-flow ref="superFlow" :node-list="nodeList" :link-list="linkList" :origin="origin"
        :graph-menu="graphMenuList" :node-menu="nodeMenuList" :link-menu="linkMenuList"
        :enter-intercept="enterIntercept" :output-intercept="outputIntercept" :link-desc="linkDesc">
        <template v-slot:node="{meta}">
          <div :class=" meta.desc===form.name?'worldR':'' ">
            <div :class="`flow-node flow-node-${meta.prop}`" @click="nodeClick($event,meta)">
              <header class="ellipsis" v-if="meta.prop==='cc'">
                <svg-icon icon-class="yhgl" />
                <!-- {{ meta.name }} -->
              </header>
              <section>
                ' {{ meta.prop==='cc'?meta.desc:meta.name  }} '
              </section>
            </div>
          </div>
        </template>
      </super-flow>
    </div>
    <el-card class="treeForm" shadow="always">
      <el-form :model="form" label-width="32%">
        <el-form-item label="流程主题:">
          <el-input style="width:100%" v-model="title" disabled></el-input>
        </el-form-item>
        <el-divider> 节点设置</el-divider>
        <el-form-item label="节点名称:">
          <el-input size="small" style="width:100%" v-model="form.name"></el-input>
        </el-form-item>
        <el-form-item class="user_select" label="选择用户:" >
          <!-- :title="`${item.username}-${item.userChnName}-${item.fondName}`"  -->
          <el-select  style="width:100%" size="small" multiple filterable clearable v-model="form.users" :popper-append-to-body="false">
              <el-option 
              v-for="(item,index) in userList" :key="index" 
              :title="`${item.username}-${item.userChnName}`"
              :label="`${item.username}-${item.userChnName}`" :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="选择角色:">
          <el-select size="small" filterable clearable style="width:100%" v-model="form.roles" :popper-append-to-body="false">
            <el-option v-for="(item,index) in roleList" :key="index" :label="item.roleName" :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label=" " style="text-align:right">
          <el-button size="mini" type="primary" @click="submit()">保存</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-dialog :title="flowTitle" :visible.sync="flowStatus" :close-on-click-modal="false" width="40%">
      <el-form ref="flowForm" :model="flowForm" label-width="100px">
        <el-form-item label="流程名称：" prop="name" :rules="[{ required: true, message: '请输入流程名称', trigger: 'blur' }]">
          <el-input size="small" v-model="flowForm.name" style="width:80%"></el-input>
        </el-form-item>
        <el-form-item label=" ">
          <el-button size="mini" type="primary" @click="submitForm('flowForm')">保存</el-button>
          <el-button size="mini" type="info" @click="cancel('flowForm')">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
    <el-dialog :title="drawerConf.title" :visible.sync="drawerConf.visible" :close-on-click-modal="false" width="500px">
      <el-form @keyup.native.enter="settingSubmit" @submit.native.prevent v-show="drawerConf.type === drawerType.node"
        ref="nodeSetting" :model="nodeSetting">
        <el-form-item label="节点名称" prop="name">
          <el-input v-model="nodeSetting.name" placeholder="请输入节点名称" maxlength="30">
          </el-input>
        </el-form-item>
        <el-form-item label="节点描述" prop="desc">
          <el-input v-model="nodeSetting.desc" placeholder="请输入节点描述" maxlength="30">
          </el-input>
        </el-form-item>
      </el-form>
      <el-form @keyup.native.enter="settingSubmit" @submit.native.prevent v-show="drawerConf.type === drawerType.link"
        ref="linkSetting" :model="linkSetting">
        <el-form-item label="连线描述" prop="desc">
          <el-input v-model="linkSetting.desc" placeholder="请输入连线描述">
          </el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="drawerConf.cancel">
          取 消
        </el-button>
        <el-button type="primary" @click="settingSubmit">
          确 定
        </el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
  import {
    getUsers
  } from "@/api/jurisdiction/user"
  import {
    getRoles
  } from '@/api/jurisdiction/role'
  import {
    getList,
    selectApproveSettingNodeList,
    saveNodeData,
    getApproveSettingById,
    addSetting,
    updateSetting
  } from "@/api/system-management/processSettings"
  import {
    MessageBox,
    Message
  } from "element-ui"
  import {
    clearObjValue,
    message
  } from '@/utils/common'
  const drawerType = {
    node: 0,
    link: 1
  }
  export default {
    data() {
      return {
        selectLoading:false,
        content: "",
        flowTitle: "",
        flowStatus: false,
        flowForm: {
          name: ""
        },
        formMeta: {},
        treeRow: {},
        ids: [],
        startid: "",
        title: "",
        form: {
          name: "",
          users: [],
          roles: "",
          id: ""
        },
        userList: [],
        roleList: [],
        treeLoading: false,
        treeData: [{
          expressName: '工作流程',
          child: []
        }],
        defaultProps: {
          label: "expressName",
          children: "child",
        },

        drawerType,
        drawerConf: {
          title: '',
          visible: false,
          type: null,
          info: null,
          open: (type, info) => {
            const conf = this.drawerConf
            conf.visible = true
            conf.type = type
            conf.info = info
            if (conf.type === drawerType.node) {
              conf.title = '节点'
              if (this.$refs.nodeSetting) this.$refs.nodeSetting.resetFields()
              this.$set(this.nodeSetting, 'name', info.meta.name)
              this.$set(this.nodeSetting, 'desc', info.meta.desc)
            } else {
              conf.title = '连线'
              if (this.$refs.linkSetting) this.$refs.linkSetting.resetFields()
              this.$set(this.linkSetting, 'desc', info.meta ? info.meta.desc : '')
            }
          },
          cancel: () => {
            this.drawerConf.visible = false
            if (this.drawerConf.type === drawerType.node) {
              this.$refs.nodeSetting.clearValidate()
            } else {
              this.$refs.linkSetting.clearValidate()
            }
          }
        },
        linkSetting: {
          desc: ''
        },
        //默认节点新信息
        nodeSetting: {
          name: '节点名称',
          desc: '节点描述'
        },
        //二维坐标系原点
        origin: [656,
          501
        ],
        //节点列表
        nodeItemList: [{
            id: 1,
            coordinate: [400, 120],
            width: 120,
            height: 40,
            meta: {
              label: 'start',
              name: 'start',
              type: 'start'
            }
          },
          {
            id: 2,
            coordinate: [360, 235],
            width: 200,
            height: 40,
            meta: {
              label: 'process',
              name: 'process',
              type: 'process'
            }
          },
          {
            id: 3,
            coordinate: [400, 360],
            width: 120,
            height: 40,
            meta: {
              label: 'end',
              name: 'end',
              type: 'end'
            }
          }

        ],
        //连接线列表
        linkList: [],
        //鼠标右键功能列表
        graphMenuList: [
          [{
              label: '开始',
              disable(graph) {
                return !!graph.nodeList.find(node => node.meta.prop === 'start')
              },
              selected: (graph, coordinate) => {
                const start = graph.nodeList.find(node => node.meta.prop === 'start')
                if (!start) {
                  graph.addNode({
                    width: 100,
                    height: 35,
                    coordinate: coordinate,
                    meta: {
                      prop: 'start',
                      name: '开始'
                    }
                  })
                }
              }
            },
            {
              label: '中间节点',
              disable: false,
              selected: (graph, coordinate) => {
                graph.addNode({
                  width: 160,
                  height: 80,
                  coordinate: coordinate,
                  meta: {
                    prop: 'cc',
                    name: '中间节点',
                    desc: ""
                  }
                })
              }
            },
            {
              label: '结束',
              disable(graph) {
                return !!graph.nodeList.find(node => node.meta.prop === 'end')
              },
              selected: (graph, coordinate) => {
                graph.addNode({
                  width: 100,
                  height: 35,
                  coordinate: coordinate,
                  meta: {
                    prop: 'end',
                    name: '结束'
                  }
                })
              }
            }
          ],
          [
            // {
            //   label: '保存数据',
            //   selected: (graph, coordinate) => {
            //     console.log('保存数据:', JSON.parse(JSON.stringify(graph.toJSON(), null, 2)).linkList)
            //     console.log(this.$refs.superFlow.toJSON().linkList, "LIst")
            //     this.$message({
            //       message: '保存成功！请前往控制台查看',
            //       type: 'success'
            //     });
            //   }
            // },
            {
              label: '全选',
              selected: (graph, coordinate) => {
                graph.selectAll()
              }
            }
          ]
        ],
        that: this,
        //选中鼠标右键功能列表--节点
        nodeMenuList: [
          [{
            label: '删除',
            disable: false,
            selected(node, coordinate) {
              Message.success('删除成功!');
              node.remove()

            }
          }],
          // [{
          //   label: '编辑',
          //   hidden(node) {
          //     return node.meta.prop === 'start'
          //   },
          //   hidden(node) {
          //     return node.meta.prop === 'end'
          //   },

          //   selected: (node, coordinate) => {
          //     this.drawerConf.open(drawerType.node, node)
          //   }
          // }]
        ],
        //选中鼠标右键功能列表--连接线
        linkMenuList: [
          [{
            label: '删除',
            disable: false,
            selected: (link, coordinate) => {
              link.remove()
            }
          }],
          [{
            label: '编辑',
            disable: false,
            selected: (link, coordinate) => {
              this.drawerConf.open(drawerType.link, link)
            }
          }]
        ],
        nodeList: [],
        pagination:{
          pageSize:10,
          pageNum:1,
          total:0,
        },
        canmore:true,
      }
    },
    created() {
      this.getList()
      this.getUserRole()
    },
    watch: {
      "form.name": {
        handler(val, oldVal) {
          if (val) {
            this.updataData()
          }
        }
      },
      "form.users": {
        handler(val, oldVal) {
          if (val) {
            this.updataData()
          }
        }
      },
      "form.roles": {
        handler(val, oldVal) {
          if (val) {
            this.updataData()
          }
        }
      },

    },
    methods: {
      toJSON(data) {},
      cancel(formName) {
        this.flowStatus = false
        this.$refs[formName].resetFields();
      },
      submitForm(formName) {
        let data = {
          expressName: this.flowForm.name
        }
        this.$refs[formName].validate((valid) => {
          if (valid) {
            if (this.flowTitle === "新增流程") {
              addSetting(data).then(res => {
                this.getList()
                this.cancel(formName)
                this.nodeList = []
                this.linkList = []
                this.origin = []
                message('success', "新增成功", 3000)
              })
            } else {
              data.id = this.treeRow.id
              data.content = this.content
              updateSetting(data).then(res => {
                this.getList()
                this.cancel(formName)
                this.nodeList = []
                this.linkList = []
                this.origin = []
                message('success', "修改成功", 3000)
              })
            }

          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      flowClick(val) {
        this.flowForm.name = ""
        switch (val) {
          case 1:
            this.flowTitle = "新增流程"
            this.flowStatus = true
            break;
          case 2:
            if (JSON.stringify(this.treeRow) === "{}") {
              message("warning", "请先选择要修改的流程", 3000)
              return
            }
            this.flowTitle = "编辑流程"
            this.flowForm.name = this.treeRow.expressName
            this.flowStatus = true
            break;
        }

      },
      updataData() {
        this.nodeList.forEach(item => {
          if (item.id === this.form.id && item.meta.prop === "cc") {
            item.meta.desc = this.form.name
          }
        })
        this.formList.forEach(item => {
          if (item.nodeId === this.form.id) {
            item.nodeNames = this.form.name
            item.userId = this.form.users.length ? this.form.users.join(",") : []
            item.roleId = this.form.roles
          }
        })
      },
      getOrder() {
        this.$refs.superFlow.toJSON().linkList.forEach(item => {
          if (item.startId == this.startid) {
            if (this.ids.length != this.$refs.superFlow.toJSON().linkList.length - 1)
              this.ids.push(item.endId)
            this.startid = item.endId
            this.getOrder()
          }
        })
      },
      submit() {
        if (JSON.stringify(this.treeRow) === "{}") {
          message("warning", "请先选择要修改的流程", 3000)
          return
        }
        this.linkList = this.$refs.superFlow.toJSON().linkList
        this.origin = this.$refs.superFlow.toJSON().origin
        this.nodeList = this.$refs.superFlow.toJSON().nodeList
        this.ids = []
        this.nodeList.forEach(item => {
          if (item.meta.name === "开始") {
            this.startid = item.id
            this.getOrder()
          }
        })
        this.ids.forEach((ele, index) => {
          this.formList.forEach(item => {
            if (ele === item.nodeId) {
              item.node = index + 1
            }
          })
        })
        let data = {
          expressType: this.treeRow.id,
          content: JSON.stringify({
            linkList: this.linkList,
            origin: this.origin,
            nodeList: this.nodeList
          }),
          formList: this.formList
        }
        saveNodeData(data).then(res => {
          message('success', "保存成功", 3000)
        })
      },
      flowNodeClick(e) {
        const data = this.$refs.superFlow.toJSON().nodeList
        const nodeData = data.filter(item => item.meta.prop === "cc").map(ele => ele.id)
        if (this.formList.length > nodeData.length) {
          this.formList.forEach((item, index) => {
            if (nodeData.indexOf(item.nodeId) === -1) {
              this.formList.splice(index, 1)
            }
          })
        }
        if (this.formList.length < nodeData.length) {
          nodeData.forEach((item, index) => {

            if (!this.formList.filter(ele => ele.nodeId === item).length) {
              let obj = {
                expressType: this.treeRow.id,
                nodeId: item,
                nodeNames: "",
                roleId: "",
                roleName: "",
                userId: "",
                userName: "",
              }
              this.formList.push(obj)
              this.form.id = item
              // this.form.name = ""
              // this.form.users = []
              // this.form.roles = ""
            }


          })
        }
        if (this.formMeta.prop === "cc") {
          data.forEach(ele => {
            if (ele.meta.desc && ele.meta.desc === this.formMeta.desc) {
              this.form.id = ele.id
            }
          })
        }
        this.nodeList = this.$refs.superFlow.toJSON().nodeList
        this.linkList = this.$refs.superFlow.toJSON().linkList

      },
      nodeClick(val, meta) {
        clearObjValue(this.form)
        this.formMeta = meta
        this.form.name = meta.desc
        if (meta.prop === "cc") {
          this.formList.forEach(item => {
            if (item.nodeNames === meta.desc) {
              this.form.id = item.nodeId ? item.nodeId : ""
              this.form.users = item.userId ? (item.userId.split(',')).map(Number) : ""
              this.form.roles = item.roleId ? Number(item.roleId) : ""
            }
          })
        }
      },
      getUserRole() {
        this.selectLoading = true;
        getUsers({
          limit: 3000,
        }).then(res => {
          this.userList = res.body.list;
        }).then(()=>{
          getRoles({
            limit: 100
          }).then(res => {
            this.roleList = res.body.list
          })
        }).finally(()=>{
          this.selectLoading = false;
        })
        
      },
      getList() {
        this.treeLoading = true
        getList().then(res => {
          this.treeLoading = false
          res.body.approveSettings.forEach(item => {
            this.$set(item, 'child', [])
          })
          this.treeData[0].child = res.body.approveSettings
        }).catch(err => {
          this.treeLoading = false
        })
      },
      handleNodeClick(node) {

        this.treeRow = node
        if (!node.hasOwnProperty("id")) {
          // message("warning","请s")
          this.nodeList = []
          this.linkList = []
          this.title = ""
          return
        }
        this.title = node.expressName
        clearObjValue(this.form)
        getApproveSettingById({
          id: node.id
        }).then(res => {
          if (res.body.content) {
            this.content = res.body.content
            this.nodeList = JSON.parse(res.body.content).nodeList
            this.linkList = JSON.parse(res.body.content).linkList
            this.origin = JSON.parse(res.body.content).origin
          } else {
            this.nodeList = []
            this.linkList = []
            this.origin = [656, 501]
          }
        })
        selectApproveSettingNodeList({
          expressType: node.id
        }).then(res => {
          this.formList = res.body.approveSettingNodes;
        })
      },
      //连线进入节点限制函数
      enterIntercept(formNode, toNode, graph) {
        const formType = formNode.meta.prop
        switch (toNode.meta.prop) {
          //开始节点--只出不进
          case 'start':
            return false
          case 'approval':
            return [
              'start',
              'approval',
              'condition',
              'cc'
            ].includes(formType)
          case 'condition':
            return [
              'start',
              'approval',
              'condition',
              'cc'
            ].includes(formType)
          case 'end':
            return [
              'approval',
              'cc'
            ].includes(formType)
          default:
            return true
        }
      },
      //节点生成连线限制
      outputIntercept(node, graph) {
        return !(node.meta.prop === 'end')
      },
      //生成 link 定制描述文字（连接线描述）
      linkDesc(link) {
        return link.meta ? link.meta.desc : ''
      },
      //描述确定按钮
      settingSubmit(e) {
        const conf = this.drawerConf
        if (this.drawerConf.type === drawerType.node) {
          if (!conf.info.meta) conf.info.meta = {}
          Object.keys(this.nodeSetting).forEach(key => {
            this.$set(conf.info.meta, key, this.nodeSetting[key])
          })
          this.$refs.nodeSetting.resetFields()
        } else {
          if (!conf.info.meta) conf.info.meta = {}
          Object.keys(this.linkSetting).forEach(key => {
            this.$set(conf.info.meta, key, this.linkSetting[key])
          })
          this.$refs.linkSetting.resetFields()
        }
        conf.visible = false
      },
    }
  }

</script>
<style lang="scss" scoped>
  .page {
    padding: 5px;
    display: flex;
    justify-content: space-around;


    .tree {
      width: 20%;

      // overflow-x: scroll;
      /* 定义超出此盒子滚动 */
      .clearfix {
        display: flex;
        justify-content: space-between;
        justify-items: center;
      }
    }

    .treeForm {
      width: 27%;
      .user_select{
        ::v-deep{
          .el-form-item__content{
            .el-select{
              .el-select-dropdown{
                left:0px !important;
                right:0;
              }
            }
          }
        }
      }
    }
  }

  .tips {
    color: red;
  }

  .ellipsis {
    text-align: center;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    word-wrap: break-word;
  }

  .worldR {
    color: #4c81f3;
  }

  .super-flow-base-demo {
    width: 52%;
    // height: 800px;
    // height: 100vh;
    margin: 0 auto;
    background-color: #f5f5f5;
    display: flex;

    .super-flow__node {
      .flow-node {
        >header {
          font-size: 14px;
          height: 25px;
          line-height: 25px;
          padding: 0 12px;
          color: #ffffff;
        }

        >section {
          text-align: center;
          line-height: 20px;
          overflow: hidden;
          height: 52px;
          padding: 9px 12px;
          word-break: break-all;
        }

        &.flow-node-start {
          >header {
            background-color: #55abfc;

          }
        }


        &.flow-node-cc {
          >header {
            background-color: #30b95c;
          }
        }

        &.flow-node-end {
          >header {
            height: 32px;

            background-color: rgb(0, 0, 0);
          }
        }
      }
    }
  }

  .el-divider__text {
    font-weight: 600;
    letter-spacing: 4px;
  }

  .el-divider--horizontal {
    height: 2px;
    margin: 10px;
    // margin-bottom: ;
  }

</style>
