<template>
  <div ref="canvas" class="org-view-panel">
    <slot />
    <div class="org-view-body">
      <OrgTree
        ref="tree"
        :data="tree"
        :size="style"
        horizontal
        :disabled="command==='detail'"
        :label-class-name="labelClass"
        :render-content="renderContent"
        @on-expand-over="onAddChildren"
        @on-delete="onDelete"
      >
        <svg width="100%" height="100%">
          <template v-for="(item, index) in lines">
            <line
              :key="index"
              :x1="item.headLeft"
              :y1="item.headTop"
              :x2="item.tailLeft"
              :y2="item.tailTop"
              style="stroke: #67C23A; stroke-width: 2"
            />
          </template></svg></OrgTree>
    </div>
    <manager-dialog
      :title="editForm.title"
      :visible.sync="showEditDialog"
      append-to-body
      @close="closeEditDialog"
    >
      <manager-dialog
        width="50%"
        title="树形数据"
        class="scriptDesignViewTreeDialog"
        :visible.sync="treeFormVisible"
        append-to-body
        :show-footer="false"
        @open="getLabelWidth"
      >
        <el-form ref="treeForm" :model="treeForm" :label-width="labelWidth">
          <el-tree
            default-expand-all
            :data="treeFormList"
            :props="defaultProps"
          >
            <div slot-scope="{ data }">
              <el-form-item
                :label="data.label"
                :prop="data.prop"
                :rules="[
                  { required: !data.children && data.required, message: '请输入' + data.label },
                ]"
              >
                <el-select
                  v-if="data.dataType == 'array'"
                  v-model="treeForm[data.prop]"
                  placeholder="请输入"
                  :disabled="command === 'detail'"
                  size="mini"
                  multiple
                  filterable
                  allow-create
                  default-first-option
                >
                  <el-option v-for="(item, index) in treeForm[data.prop]" :key="index" :labe="item" :value="item"></el-option>
                </el-select>
                <el-input
                  v-else-if="!data.children && data.input"
                  v-model="treeForm[data.prop]"
                  placeholder="请输入"
                  size="mini"
                  :disabled="command === 'detail'"
                />
              </el-form-item>
            </div>
          </el-tree>
        </el-form>
      </manager-dialog>
      <el-form v-if="showEditDialog" ref="editForm" :model="editForm.form" label-width="auto">
        <el-form-item
          v-for="(item, index) in editList"
          :key="index"
          :label="item.label"
          :prop="item.prop"
          :rules="{ required: item.required, message: '请输入' + item.label }"
        >
          <el-button
            v-if="item.tree"
            type="primary"
            icon="el-icon-share"
            @click="openTreeForm(item)"
          />
          <el-input
            v-else
            v-model="editForm.form[item.prop]"
            :disabled="dialogDisabled"
            @input="$forceUpdate()"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button
          style="margin-left: 5px"
          @click="showEditDialog = false"
        >取消
        </el-button>
        <el-button
          v-if="command !== 'detail'"
          style="margin-left: 5px"
          type="primary"
          @click="saveEdit"
        ><span>确定</span>
        </el-button>
      </span>
    </manager-dialog>
    <manager-dialog title="前后事件属性关系" :visible.sync="dialogVisible" append-to-body>
      <el-form v-if="dialogVisible" :model="relationForm" label-width="auto">
        <el-form-item label="起始属性："><el-cascader
          v-if="relationForm.startIsTree"
          v-model="relationForm.startParamId"
          :show-all-levels="false"
          :options="startOptions"
          :props="{ checkStrictly: true }"
          clearable
          @change="val => relationChange(val, startOptions)"
        /><span v-else>{{
          relationForm.startParamName
        }}</span></el-form-item>
        <el-form-item label="终点属性："><el-cascader
          v-if="relationForm.endIsTree"
          v-model="relationForm.endParamId"
          :show-all-levels="false"
          :options="endOptions"
          :props="{ checkStrictly: true }"
          clearable
          @change="val => relationChange(val, endOptions)"
        /><span v-else>{{
          relationForm.endParamName
        }}</span></el-form-item>
        <el-form-item label="映射值:" prop="conditionValue">
          <el-input
            v-model="relationForm.conditionValue"
            placeholder="请输入映射值"
          />
        </el-form-item>
        <el-form-item label="映射关系:">
          <el-select
            v-model="relationForm.conditionType"
            placeholder="请选择前后事件关系"
          >
            <el-option
              v-for="item in staticParam.conditionType"
              :key="item.value"
              :disabled="
                (relationCurrentNode.dataType == 'string' && ['2','3','4','5'].includes(item.value))
                  || (relationCurrentNode.dataType == 'array' && !['6','7','8'].includes(item.value))
              "
              :label="item.label"
              :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submit">确定</el-button>
      </span>
    </manager-dialog>
    <manager-dialog title="映射关系" :visible.sync="relationFormVisible" append-to-body>
      <el-table :data="relationList" border stripe>
        <el-table-column
          prop="startParamName"
          label="起始属性"
          show-overflow-tooltip
        />
        <el-table-column
          prop="endParamName"
          label="终点属性"
          show-overflow-tooltip
        />
        <el-table-column label="映射值" show-overflow-tooltip>
          <template slot-scope="scope">
            <el-input
              v-if="scope.row.editVisible"
              v-model="scope.row.conditionValue"
            />
            <span v-else>{{ scope.row.conditionValue }}</span>
          </template>
        </el-table-column>
        <el-table-column label="映射关系" show-overflow-tooltip>
          <template slot-scope="scope">
            <el-select
              v-if="scope.row.editVisible"
              v-model="scope.row.conditionType"
              placeholder="请选择前后事件关系"
            >
            <el-option
              v-for="item in staticParam.conditionType"
              :key="item.value"
              :label="item.label"
              :value="item.value">
            </el-option>
            </el-select>
            <span v-else>{{
              scope.row.conditionType == "0"
                ? '等于'
                : scope.row.conditionType == "1"
                  ? '不等于'
                  : scope.row.conditionType == "2"
                    ? '大于'
                    : scope.row.conditionType == "3"
                      ? '大于等于'
                      : scope.row.conditionType == "4"
                        ? '小于'
                        : scope.row.conditionType == "5"
                          ? '小于等于'
                        : scope.row.conditionType == "6"
                          ? '包含'
                          : scope.row.conditionType == "7"
                            ? '不包含'
                            : '仅关联'
            }}</span></template></el-table-column>
        <el-table-column
          v-if="command !== 'detail'"
          label="操作"
          show-overflow-tooltip
        ><template slot-scope="scope">
          <el-button
            v-if="!scope.row.editVisible"
            type="text"
            @click="handleRelationModify(scope.row)"
          >修改</el-button>
          <el-button
            v-else
            type="text"
            @click="handleRelationComplete(scope.row)"
          >完成</el-button><el-button
            type="text"
            @click="handleRelationRemove(scope.row)"
          >移除</el-button></template></el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
      </span>
    </manager-dialog>
  </div>
</template>
<script>
import Card from './Card'
import BeginNode from './BeginNode'
import OrgTree from '@ability/components/OrgTree/org-tree'

export default {
  name: 'ScriptDesignView',
  components: { OrgTree },
  props: {
    command: String
  },
  data() {
    return {
      staticParam:{
        conditionType:[{
          value: '0',
          label: '等于'
        }, {
          value: '1',
          label: '不等于'
        }, {
          value: '2',
          label: '大于'
        }, {
          value: '3',
          label: '大于等于'
        }, {
          value: '4',
          label: '小于'
        }, {
          value: '5',
          label: '小于等于'
        }, {
          value: '6',
          label: '包含'
        }, {
          value: '7',
          label: '不包含'
        }, {
          value: '8',
          label: '仅关联'
        }]
      },
      id: null,
      labelWidth: '150px',
      activeNodeId: null,
      relationFormVisible: false,
      treeFormVisible: false,
      showEditDialog: false,
      dialogDisabled: false,
      dialogVisible: false,
      editList: [],
      relationList: [],
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      relationItem: {
        parentId: null,
        startParamId: null,
        startParamName: null,
        conditionValue: null,
        childrenId: null,
        endParamId: null,
        endParamName: null,
        conditionType: null,
        editVisible: false
      },
      lineForm: null,
      treeForm: {},
      treeFormList: [],
      editForm: {
        id: null,
        title: null,
        form: {},
        originalForm: {}
      },
      relationCurrentNode: {}, // 前后事件属性当前选中节点
      relationForm: {
        parentId: null,
        startParamId: null,
        startParamName: null,
        startIsTree: false,
        conditionValue: null,
        childrenId: null,
        endParamId: null,
        endParamName: null,
        endIsTree: false,
        conditionType: null
      },
      disabled: false,
      // 树型组织图-model,默认创建一个根节点
      tree: {
        parentId: null, // 父节点ID
        nodeId: '0', // 卡片组件ID，标识新增节点
        layoutId: null, // 业务组件ID
        nodeName: '起点', // 节点名称
        nodeType: 'root', // 节点类型
        renderType: 'begin', // 节点类型
        color: null, // 颜色
        icon: null, // 图标
        form: null, // 表单数据
        relation: [], // 属性关系
        children: [] // 子节点
      },
      lines: [],
      position: {
        top: 0,
        left: 0,
        scrollTop: 0,
        scrollLeft: 0
      },
      style: {
        width: '100%',
        height: '100%'
      },
      startOptions: [],
      endOptions: []
    }
  },
  watch: {
    dialogVisible(val) {
      if (!val) {
        this.relationCurrentNode = {}
        Object.keys(this.relationForm).forEach(key => this.relationForm[key] = null)
      }
    }
  },
  computed: {
    width() {
      return document.body.clientWidth
    },
    height() {
      return document.body.clientHeight
    }
  },
  mounted() {
    this.setPosition()
  },
  methods: {
    // 获取起始/终点属性当前选中节点
    relationChange(val, tree) {
      this.relationForm.conditionType = null
      if (!val || !val.length) {
        this.relationCurrentNode = {}
        return
      }
      val = val[val.length - 1]
      let getDataType = (id, nodes) => {
        let result = []
        nodes.forEach(el => {
          if (el.value == id) result.push(el)
          if (el.children && el.children.length) {
            let tmp = getDataType(id, el.children)
            if (tmp) tmp.forEach(item => result.push(item))
          }
        })
        return result
      }
      this.relationCurrentNode = getDataType(val, tree)[0]
    },
    saveDefault(tree) {
      if (Object.prototype.toString.call(tree) != '[object Array]') return
      tree.forEach(el => {
        this.treeForm = {}
        let ins = this.$refs.tree.$refs[el.nodeId]
        this.editForm.id = ins.id
        this.editForm.form = {}
        ins.dataList.forEach(obj => {
          this.$set(this.editForm.form, obj.prop, obj.value)
          if (obj.tree) {
            if (Object.keys(this.treeForm).length == 0) this.iterateValue(obj.value)
            // obj.value = this.iterateTree(obj.value, this.treeForm)
          }
          else obj.value = this.editForm.form[obj.prop]
          this.iterateNode(
            this.editForm.id,
            this.tree,
            this.editForm.form,
            'edit'
          )
        })
        if (el.children && el.children.length) this.saveDefault(el.children)
      })
    },
    getLabelWidth() {
      let width = 130
      const iterateTreeForm = (arr, callback) => {
        if (Object.prototype.toString.call(arr) != '[object Array]') return
        arr.forEach(obj => {
          callback(obj)
          if (obj.children && obj.children.length !== 0) {
            iterateTreeForm(obj.children, callback)
          }
        })
      }
      iterateTreeForm(this.treeFormList, (obj) => {
        const labelArr = obj.label.split('：')
        let labelWidth
        if (labelArr.length > 1) {
          labelWidth = (labelArr[0].length + 1) * 15 + labelArr[1].length * 6
        } else {
          labelWidth = (labelArr[0].length + 1) * 15
        }
        if (labelWidth > width) {
          width = labelWidth
        }
      })
      this.labelWidth = width + 'px'
    },
    closeEditDialog() {
      this.editForm.form = {}
      // this.treeForm = {}
      this.treeFormList = []
    },
    handleRelationComplete(row) {
      const index = this.relationList.findIndex(
        (obj) =>
          obj.startParamId === row.startParamId && obj.endParamId === row.endParamId
      )
      console.log(index)
      console.log(row)

      this.iterateNode(
        this.activeNodeId,
        this.tree,
        this.relationList.map((obj) => {
          return {
            parentId: null,
            startParamId: obj.startParamId,
            startParamName: obj.startParamName,
            conditionValue: obj.conditionValue,
            childrenId: null,
            endParamId: obj.endParamId,
            endParamName: obj.endParamName,
            conditionType: obj.conditionType
          }
        }),
        'modify'
      )
      this.relationList[index].editVisible = false
    },
    handleRelationModify(row) {
      const item = this.relationList.find(
        (obj) =>
          obj.startParamId === row.startParamId && obj.endParamId === row.endParamId
      )
      
      console.log("==修改==");
      console.log(row);
      console.log(item);
      item.editVisible = true
    },
    handleRelationRemove(row) {
      const indexRelationList = this.relationList.findIndex(
        (obj) =>
          obj.startParamId === row.startParamId &&
          obj.endParamId === row.endParamId
      )
      const delElement = this.relationList[indexRelationList]
      const indexLine = this.lines.findIndex(
        (obj) =>
          obj.tailId === delElement.parentId &&
          obj.headId === delElement.childrenId &&
          obj.tailProp === delElement.startParamId &&
          obj.headProp === delElement.endParamId
      )
      this.relationList.splice(indexRelationList, 1)
      this.lines.splice(indexLine, 1)
      this.iterateNode(
        this.activeNodeId,
        this.tree,
        this.relationList.map((obj) => {
          return {
            parentId: obj.parentId,
            startParamId: obj.startParamId,
            startParamName: obj.startParamName,
            childrenId: obj.childrenId,
            endParamId: obj.endParamId,
            endParamName: obj.endParamName
          }
        }),
        'modify'
      )
    },
    openRelationList(id) {
      this.iterateNode(id, this.tree.children[0], null, 'query')
    },
    computedPositon(line) {
      this.setPosition()
      return {
        headLeft:
          line.headX - this.position.left - 15 + this.position.scrollLeft,
        headTop: line.headY - this.position.top - 10 + this.position.scrollTop,
        tailLeft:
          line.tailX - this.position.left - 15 + 8 + this.position.scrollLeft,
        tailTop: line.tailY - this.position.top - 10 + this.position.scrollTop
      }
    },
    setStyle() {
      if (this.$refs.tree) {
        const domTree = this.$refs.tree.$refs
        this.style.width = domTree.tree.getBoundingClientRect().width + 'px'
        this.style.height = domTree.tree.getBoundingClientRect().height + 'px'
        this.position.scrollTop = domTree.container.scrollTop
        this.position.scrollLeft = domTree.container.scrollLeft
      }
    },
    setPosition() {
      if (this.$refs.canvas) {
        this.position.top = this.$refs.canvas.getBoundingClientRect().top
        this.position.left = this.$refs.canvas.getBoundingClientRect().left
      }
    },
    isLineRepeat(source, target) {
      const index = this.lines.findIndex(
        (obj) =>
          obj[source.position + 'Id'] === source.id &&
          obj[target.position + 'Id'] === target.id &&
          obj[source.position + 'Prop'] === source.prop &&
          obj[target.position + 'Prop'] === target.prop
      )
      return index
    },
    redrawLine(query) {
      this.setStyle()
      const del = []
      this.lines.forEach((obj) => {
        const newHead = document.getElementById(obj.headDom)
        const newTail = document.getElementById(obj.tailDom)
        if (newHead && newTail) {
          obj.headX = newHead.getBoundingClientRect().x
          obj.headY = newHead.getBoundingClientRect().y
          obj.tailX = newTail.getBoundingClientRect().x
          obj.tailY = newTail.getBoundingClientRect().y
          Object.assign(obj, this.computedPositon(obj))
        } else {
          del.push(obj.headId)
        }
      })
      if (del.length !== 0 && !query) { this.lines = this.lines.filter((obj) => !del.includes(obj.headId)) }
    },
    drawLine(source, target) {
      this.setStyle()
      const index = this.isLineRepeat(source, target)
      if (index === -1) {
        let line
        let headTree = false
        let tailTree = false
        const iterateTreeMap = (data) => {
          return data.map(obj => {
            const leaf = {
              value: obj.paramId,
              label: obj.paramName,
              children: null,
              disabled: obj.dataType == 'object',
              dataType: obj.dataType
            }
            if (obj.childTree) {
              leaf.children = iterateTreeMap(obj.childTree)
            }
            return leaf
          })
        }
        if (source.position === 'head') {
          line = {
            headId: source.id,
            headX: source.pageX + '',
            headY: source.pageY + '',
            headProp: source.propId,
            headLabel: source.label,
            headColor: source.color,
            headDom: source.dom,
            tailId: target.id,
            tailX: target.pageX + '',
            tailY: target.pageY + '',
            tailProp: target.propId,
            tailLabel: target.label,
            tailColor: target.color,
            tailDom: target.dom
          }
          if (source.tree) {
            headTree = true
            this.startOptions = iterateTreeMap(source.value)
          }
          if (target.tree) {
            tailTree = true
            this.endOptions = iterateTreeMap(target.value)
          }
        } else {
          line = {
            headId: target.id,
            headX: target.pageX + '',
            headY: target.pageY + '',
            headProp: target.propId,
            headLabel: target.label,
            headColor: target.color,
            headDom: target.dom,
            tailId: source.id,
            tailX: source.pageX + '',
            tailY: source.pageY + '',
            tailProp: source.propId,
            tailLabel: source.label,
            tailColor: source.color,
            tailDom: source.dom
          }
          if (source.tree) {
            tailTree = true
            this.startOptions = iterateTreeMap(source.value)
          }
          if (target.tree) {
            headTree = true
            this.endOptions = iterateTreeMap(target.value)
          }
        }
        this.lineForm = {
          ...line,
          ...this.computedPositon(line)
        }
        const relation = {
          parentId: line.tailId,
          startParamId: line.tailProp,
          startParamName: line.tailLabel,
          childrenId: line.headId,
          endParamId: line.headProp,
          endParamName: line.headLabel
        }
        this.relationForm.parentId = relation.parentId
        this.relationForm.startParamId = relation.startParamId
        this.relationForm.startParamName = relation.startParamName
        this.relationForm.startIsTree = tailTree
        this.relationForm.childrenId = relation.childrenId
        this.relationForm.endParamId = relation.endParamId
        this.relationForm.endParamName = relation.endParamName
        this.relationForm.endIsTree = headTree
        this.dialogVisible = true
      }
    },
    // 树形组织图-function
    labelClass(data) {
      return 'bg_node'
    },
    submit() {
      //前后事件属性的关联关系必选
      if (this.relationForm.endParamId!=null) {
        // if(this.relationForm.conditionType!="8"&&(this.relationForm.conditionType==null||this.relationForm.conditionValue)){
        //   this.$message.warning('请正确选择映射关系')
        // }
        const form = JSON.parse(JSON.stringify(this.relationForm))
        if (form.startParamId instanceof Array) {
          form.startParamId = form.startParamId[form.startParamId.length - 1]
        }
        if (form.endParamId instanceof Array) {
          form.endParamId = form.endParamId[form.endParamId.length - 1]
        }
        this.iterateNode(
          this.relationForm.childrenId,
          this.tree.children[0],
          form,
          'add'
        )
        this.relationForm.conditionValue = null
        this.lines.push(this.lineForm)
        this.dialogVisible = false
      } else {
        this.$message.warning('请正确选择映射关系')
      }
    },
    renderContent(h, data) {
      const renderType = data.renderType // 增加类型，指定要创建的是什么
      if (renderType == 'begin') {
        return h(BeginNode, {
          props: {
            title: '起点'
          }
        })
      } else {
        return h(Card, {
          ref: data.nodeId + '',
          props: {
            command: this.command,
            form: data.form,
            parent: data.parentId,
            type: data.nodeType,
            typeId: data.layoutId + '',
            title: data.nodeName,
            color: data.color,
            icon: data.icon,
            id: data.nodeId
          },
          on: {
            'on-edit': (value) => {
              this.openDialog(value, 'edit')
            },
            'on-detail': (value) => {
              this.openDialog(value, 'detail')
            },
            'on-relation': (source, target) => {
              this.$nextTick(() => {
                this.drawLine(source, target)
              })
            },
            'on-search': () => {
              this.$nextTick(() => {
                this.redrawLine(true)
              })
            },
            'open-relation': (id) => {
              this.relationFormVisible = true
              this.activeNodeId = id
              this.openRelationList(id)
            }
          }
        })
      }
    },
    onAddChildren(e, data) {
      const componentData = JSON.parse(e.dataTransfer.getData('componentData'))
      if (data.nodeType === 'root' && data.children.length !== 0) {
        this.$message.warning('根节点上只能添加一个节点')
      } else if (data.nodeType === 'root' && !componentData.item.resourceId) {
        this.$message.warning('必须以数据源为起始节点')
      } else if (this.tree.children[0] && componentData.item.resourceId) {
        this.$message.warning('只能有一个数据源节点')
      } else if (
        componentData.item.layoutId &&
        data.children.findIndex(
          (obj) => obj.layoutId === componentData.item.layoutId
        ) !== -1
      ) {
        this.$message.warning('同节点的添加类型不能重复')
      } else {
        data.children.push({
          parentId: data.nodeId,
          nodeId: componentData.id, // 卡片组件ID，标识新增节点
          layoutId:
            componentData.item.resourceId || componentData.item.layoutId, // 业务类型ID
          nodeName:
            componentData.item.resourceName || componentData.item.layoutName,
          nodeType: componentData.item.resourceId ? 'resource' : 'layout',
          renderType: 'card',
          color: componentData.item.color || null,
          icon: componentData.item.layoutIcon || null,
          form: null,
          relation: [],
          children: []
        })
        this.$nextTick(() => {
          if (this.lines.length !== 0) {
            this.redrawLine()
          }
        })
      }
    },
    onDelete(e, data) {
      if (this.command === 'detail') {
        this.$message.warning('查看时无法删除!')
        return
      }
      if (data.nodeType == 'root') {
        this.$message.warning('根节点不能删除!')
        return
      }
      this.$confirm('是否确认删除?', '提示', {
        confirmButtonText: '是',
        cancelButtonText: '否',
        type: 'warning'
      })
        .then(() => {
          this.iterateTreeDeleteNode(this.tree.children, data)
          this.$nextTick(() => {
            if (this.lines.length !== 0) {
              this.redrawLine()
            }
          })
        })
        .catch(() => {})
    },
    iterateChangeRelation(command, id, table) {},
    iterateTreeDeleteNode(array, childNode) {      
      for(let i = array.length - 1; i >= 0; i--) {
        if (array[i].nodeId == childNode.nodeId && array[i].parentId == childNode.parentId) {
          let ids = array.filter(el => el.nodeId != childNode.nodeId)
          let originalData = ids.map(item => {
            return this.$refs.tree.$refs[item.nodeId].$data
          })
          array.splice(i, 1)
          this.$nextTick(() => {
            ids.forEach((item, index) => {            
              Object.assign(this.$refs.tree.$refs[item.nodeId].$data, originalData[index])
              this.$refs.tree.$refs[item.nodeId].$forceUpdate()
            })
          })
          break
        } else {
          array[i].children && this.iterateTreeDeleteNode(array[i].children, childNode)
        }
      }
    },
    iterateValue(arr) {
      return arr.map((obj) => {
        const leaf = {
          prop: obj.paramCode,
          label: obj.paramName,
          required: obj.requiredFlag === '1',
          input: obj.paramType == 1,
          // value: obj.value ? obj.value : null
          value: this.editForm.originalForm[obj.paramCode] || obj.value || (obj.dataType == 'array' ? [] : null),
          dataType: obj.dataType
        }
        if (this.treeForm[leaf.prop] === undefined) {
          this.$set(this.treeForm, leaf.prop, leaf.value)
        }
        if (obj.childTree) {
          leaf.children = this.iterateValue(obj.childTree)
        }
        return leaf
      })
    },
    openTreeForm(data) {
      this.treeFormList = this.iterateValue(data.value)
      this.treeFormVisible = true
    },
    openDialog(data, type) {
      this.editForm.id = data.id
      this.editForm.title = data.title
      this.editForm.originalForm = data.form || {}
      this.editList = data.editList
      this.editList.forEach((obj) => {
        this.$set(this.editForm.form, obj.prop, obj.value)
      })      
      this.showEditDialog = true
      if (type == 'edit') {
        this.dialogDisabled = false
      }
      if (type == 'detail') {
        this.dialogDisabled = true
      }
      this.$nextTick(() => {
        this.$refs.editForm.clearValidate()
      })
    },
    hideEditDialog() {
      this.showEditDialog = false
    },
    iterateNode(id, nodes, data, command) {
      nodes.children.forEach((obj) => {
        if (id === obj.nodeId) {
          if (command === 'add') {
            obj.relation.push(data)
          } else if (command === 'query') {
            this.relationList = obj.relation.map((obj) => {
              return {
                ...obj,
                editVisible: false
              }
            })
          } else if (command === 'edit') {
            const source = { ...data, ...this.treeForm }
            const target = {}
            Object.keys(source).forEach((key) => {
              if (source[key] !== null) {
                target[key] = source[key]
              }
            })
            obj.form = target
          } else if (command === 'modify') {
            const form = data
            form.parentId = nodes.nodeId
            form.childrenId = obj.nodeId
            obj.relation = form
          } else {
            const index = obj.relation.findIndex(
              (obj) =>
                obj.parentId === data.parentId &&
                obj.childrenId === data.childrenId &&
                obj.startParamId === data.startParamId &&
                obj.endParamId === data.endParamId
            )
            obj.relation.splice(index, 1)
          }
        } else {
          this.iterateNode(id, obj, data, command)
        }
      })
    },
    iterateTree(tree, form) {
      if (Object.prototype.toString.call(tree) != '[object Array]') return null
      const props = Object.keys(form)
      return tree.map((obj) => {
        const leaf = obj
        if (props.includes(obj.paramCode)) {
          leaf.value = form[leaf.paramCode]
        } else if (obj.childTree && obj.childTree.length !== 0) {
          this.iterateTree(obj.tree, form)
        }
        return leaf
      })
    },
    saveEdit() {
      this.$refs.editForm.validate((valid) => {
        if (valid) {
          this.$refs.tree.$refs[this.editForm.id].dataList.forEach(
            (obj) => {
              if (obj.tree) {
                obj.value = this.iterateTree(obj.value, this.treeForm)
              } else {
                obj.value = this.editForm.form[obj.prop]
              }
            }
          )
          this.iterateNode(
            this.editForm.id,
            this.tree,
            this.editForm.form,
            'edit'
          )
          this.showEditDialog = false
        } else {
          this.$message.warning('请输入树中的必填项')
        }
      })
    }
  }
}
</script>
<style>
.relation {
  padding: 10px 0;
}
.relation-head {
  color: #909399;
}
.relation-text {
  padding: 9px 15px;
  text-align: center;
}
.el-tree-node__content {
  height: 36px !important;
}
.org-view-panel {
  height: 100%;
  min-height: 580px;
  overflow: auto;
}
.org-view-panel .org-view-body {
  width: 100%;
  min-height: calc(100%);
  display: flex;
  justify-content: flex-start;
  align-items: center;
}
.org-view-panel .org-tree-container {
  background-color: unset;
}
.org-view-panel .org-tree-node-label .org-tree-node-label-inner {
  box-shadow: unset;
  padding: 0;
}
.org-view-panel .ivu-card-head {
  padding: 10px;
  text-align: left;
}
.org-view-panel .ivu-card-extra {
  top: 8px;
  font-size: 18px;
}
.org-view-panel .ivu-card-body {
  padding: 10px 0 5px 10px;
}
.org-view-panel .sider-edit-mask {
  position: absolute;
  top: -3px;
  width: 100%;
  height: 100%;
  background: rgb(71, 59, 59);
  opacity: 0.2;
  z-index: 666;
}
.org-view-panel .sider-edit-tool {
  position: absolute;
  right: 0;
  top: -3px;
  width: 220px;
  height: 100%;
  background: #fbfbfb;
  z-index: 999;
  padding: 10px 0;
}
.org-view-panel .sider-edit-save {
  width: 200px;
  margin: 0px auto 10px;
  position: fixed;
  bottom: 5px;
}
.scriptDesignViewTreeDialog .el-form-item {
  margin-bottom: 0;
}

.scriptDesignViewTreeDialog .el-form-item .el-select__tags {
  flex-wrap: nowrap;
}
</style>
