<template>
  <ht-tree-dialog
    ref="htTreeDialog"
    :data="treeData"
    append-to-body
    :node-key="nodeKey"
    :show-checkbox="showCheckbox"
    :props="defaultProps"
    :leaf-only="false"
    :include-half-checked="false"
    :support-filter="false"
    :expand-on-click-node="false"
    :check-strictly="false"
    :load="loadTree"
    lazy
    :style="{
      width: `${customDialog.width}px`,
      height: `${customDialog.height}px`,
      margin: 'auto'
    }"
    class="tree-dialog"
    @onConfirm="treeDialogOnConfirm"
    :default-expanded-keys="defaultExpandedKeys"
  ></ht-tree-dialog>
</template>
<script>
import {Message} from 'element-ui'
import req from '@/request.js'
import hotentUtil from '@/hotent-ui-util.js'
export default {
  name: 'eip-tree-dialog',
  props: {
    //自定义对话框的别名
    alias: {
      type: String,
      required: true
    },
    //自定义对话框的配置
    customDialog: {
      type: Object,
      required: true
    },
    //动态传入的条件参数
    mapParam: {
      type: Object,
      default: () => {
        return {}
      }
    },
    ispreview: {
      type: Boolean,
      required: false,
      default: true
    }
  },
  data() {
    return {
      nodeKey: 'ID_', //树数据Id （每个树节点用来作为唯一标识的属性，整棵树应该是唯一的）
      showCheckbox: true, //对话框单选还是多选 true：多选，false：单选
      treeData: [], //树数据
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      displayField: {},
      treeList: []
    }
  },
  computed: {
    //默认展开的节点的 key 的数组
    defaultExpandedKeys: function(val) {
      if (
        this.treeData &&
        this.treeData.length > 0 &&
        this.treeData[0][this.nodeKey]
      ) {
        return [this.treeData[0][this.nodeKey]]
      }
      return []
    }
  },
  methods: {
    //显示对话框
    showDialog() {
      this.$refs.htTreeDialog.showDialog()
      //初始值值为空
      this.treeData = []
      //判断树是否支持多选
      if (this.customDialog.selectNum == 1) {
        // 单选
        this.showCheckbox = false
      } else {
        this.showCheckbox = true
      }
      //把对话框配置的显示字段ID赋值给树形的树数据Id
      this.nodeKey = this.customDialog.displayfield.id
      this.customDialogTreeShow() //加载树
    },
    //获取固定的参数
    getFixedCondition(mapParam) {
      for (let i = 0; i < this.customDialog.conditionfield.length; i++) {
        const item = this.customDialog.conditionfield[i]
        if (item.defaultType === '2') {
          mapParam[item.field] = item.defaultValue
        }
      }
    },
    //加载树
    customDialogTreeShow() {
      //得到对话框的配置
      let customDialog = this.customDialog
      let mapParam = '' //数据来源是数据源，且有动态参数传入时调用
      this.getFixedCondition(this.mapParam)
      //判断是否有动态传入的条件参数
      if (this.mapParam && JSON.stringify(this.mapParam) != '{}') {
        mapParam = JSON.stringify(this.mapParam)
        mapParam = mapParam.substring(1, mapParam.length - 1)
      }
      //判断数据来源是否是数据源，如果是数据源请求类型就为GET请求；如果数据来源是REST接口，请求类型就获取对话框配置的请求；
      let requestType =
        customDialog.dsType == 'dataSource'
          ? 'GET'
          : customDialog.requestType
          ? customDialog.requestType
          : 'POST'
      //数据来源是数据源的URL
      let url =
        '${form}/form/customDialog/v1/getTreeData?alias=' +
        this.alias +
        '&mapParam=' +
        mapParam
      let paramsObj = {}
      //数据来源是REST接口
      if (customDialog.dsType != 'dataSource') {
        url = customDialog.url
        if (customDialog.dsType == 'selectedApi') {
          url =
            '${portal}/portal/portalInterfaceManager/v1/doQuery?alias=' +
            customDialog.apiAlias
          requestType = 'GET'
        }
        var templatePa = customDialog.dataParam
        let ctx = {}
        //判断是否有条件字段
        if (customDialog.conditionfield.length > 0) {
          let conditions = customDialog.conditionfield //条件字段
          for (let i = 0; i < conditions.length; i++) {
            let con = conditions[i]
            //判断是否是POST请求
            if (requestType == 'POST') {
              if (templatePa) {
                ctx[con.field] = con.defaultValue
              } else {
                paramsObj[con.field] = con.defaultValue
              }
            } else {
              let ljChar = url.indexOf('?') == -1 ? '?' : '&'
              url = url + ljChar + con.field + '=' + con.defaultValue
            }
          }
        }
        if (templatePa) {
          templatePa = hotentUtil.parseExp(templatePa, ctx)
          paramsObj = JSON.parse(templatePa)
        }
      }
      let requestParams = {}
      requestParams.requestType = requestType
      requestParams.url = url
      requestParams.paramsObj = paramsObj
      this.searchTree(requestParams)
    },
    //树形查询
    searchTree(requestParams) {
      const this_ = this
      let query =
        requestParams.requestType == 'POST'
          ? req.post(requestParams.url, requestParams.paramsObj)
          : req.get(requestParams.url)
      query.then(function(response) {
        //显示字段配置
        let displayfield = this_.customDialog.displayfield
        this_.displayField = displayfield
        //把对话框配置的显示字段显示名称赋值给树形的显示值
        this_.defaultProps.label = displayfield.displayName.trim()

        if (this_.customDialog.dsType === 'restful') {
          this_.treeList = response.data[this_.customDialog.listKey]
        } else {
          this_.treeList = response.data
        }
        this_.treeData = this_.toTreeData(
          this_.treeList,
          displayfield.id,
          displayfield.pid
        )
      })
    },
    //加载树的信息
    toTreeData(data, id, pid) {
      //把平铺数据转树状结构，便于获取第一层数据
      let tile2nest = hotentUtil.tile2nest(data, id, pid)
      return tile2nest || []
    },
    //树节点 点击事件
    loadTree(node, resolve) {
      if (node) {
        resolve(
          this.treeList.filter(
            value =>
              value[this.displayField.pid] === node.data[this.displayField.id]
          )
        )
      } else {
        resolve([])
      }
    },
    //确认事件
    treeDialogOnConfirm(data) {
      //单选
      if (
        this.customDialog.selectNum === 1 &&
        data.constructor === Object &&
        JSON.stringify(data) == '{}'
      ) {
        Message.error('请至少选择一条数据')
        return
      } else if (
        this.customDialog.selectNum === 1 &&
        data.constructor === Array &&
        data.length > 0
      ) {
        //多选
        Message.error('请至少选择一条数据')
        return
      }
      //拿到配置的返回字段
      let returnStr = this.customDialog.resultfield
      //返回字段的字段名有多少个
      let field = new Array([returnStr.length])
      //返回字段的返回名称有多少个
      let comment = new Array([returnStr.length])
      let str = []
      for (let i = 0; i < returnStr.length; i++) {
        //得到返回字段的字段名
        field[i] =
          this.customDialog.dsType == 'dataSource'
            ? returnStr[i].field
            : returnStr[i].field
        //得到返回字段的返回名称
        comment[i] =
          this.customDialog.dsType == 'dataSource'
            ? returnStr[i].comment
            : returnStr[i].comment
      }
      let s = []
      //是否单选  1：单选；-1：多选
      if (this.customDialog.selectNum === 1) {
        s.push(data)
        this.deleteChildren(s) //循环把树数组里面的子节点数据删除
        let temp = ''
        for (let i = 0; i < comment.length; i++) {
          temp += '"' + comment[i] + '":"' + s[0][field[i]] + '",'
        }
        //去除字符串最后一个字符逗号
        if (temp != '') {
          temp = '{' + temp.substring(0, temp.length - 1) + '}'
        }
        str.push(JSON.parse(temp))
      } else {
        s = data
        this.deleteChildren(s) //循环把树数组里面的子节点数据删除
        for (let i = 0; i < s.length; i++) {
          var temp = ''
          for (let j = 0; j < comment.length; j++) {
            temp += '"' + comment[j] + '":"' + s[i][field[j]] + '",'
          }
          //去除字符串最后一个字符逗号
          if (temp != '') {
            temp = '{' + temp.substring(0, temp.length - 1) + '}'
          }
          str.push(JSON.parse(temp))
        }
      }
      if (this.ispreview) {
        Message.success('返回数据为：' + JSON.stringify(str))
      }
      this.$emit('return-all-data', s)
      this.$emit('onConfirm', str)
      this.$refs.htTreeDialog.handleClose() //关闭对话框
    },
    //循环把树数组里面的子节点数据删除
    deleteChildren(arrayVal) {
      for (let i = 0; i < arrayVal.length; i++) {
        delete arrayVal[i].children
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.el-main {
  padding-top: 0px;
}
.tree-dialog {
  /deep/.el-dialog {
    margin: auto;
  }
}
</style>
