<!-- @desc:树形  @auth:周兴  @time:2023/3/2 16:51 -->
<template>
  <div class="tree-class" :style=" {width:100 + '%' ,'min-width':minWidth,height:height+'px'}">
    <div>
      <loading :loading="loadingData"></loading>
    </div>
    <vxe-table
      :ref="name"
      show-overflow
      resizable
      auto-resize
      row-key
      :border="border"
      :row-config="{isCurrent: true,isHover: true}"
      :show-header="showHeader"
      :data="treeData"
      :empty-text="emptyText"
      :height="height-((showChooseButton|| showExpandButton)?40:0)"
      @current-change="handleCurrentChange"
      @checkbox-change="handleSelectChange"
      @cell-click="cellClick"
      :checkbox-config="{labelField: 'name',showHeader:showCheckboxHeader, checkMethod:checkMethod}"
      :tree-config="{transform: true, rowField: 'id', parentField: 'parentId'}">
      <vxe-column fixed="left" :title="nodeTitle" type="checkbox" v-if="showCheckbox"
                  width="auto"
                  show-overflow="title" tree-node>
      </vxe-column>
      <vxe-column fixed="left" :title="nodeTitle" field="name" width="auto" show-overflow="title" v-else tree-node>
      </vxe-column>
      <div v-for="(colItem,colIndex) in columns" :key="colIndex">
        <vxe-column v-if="colItem.type === 'switch'" :params="{type:'switch'}" :field="colItem.field"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :title="colItem.title?colItem.title: $t(colItem.field)" class-name="switch-class">
          <template #default="{ row,rowIndex }" style="line-height: 0">
            <i-switch size="small" v-model="row[colItem.field]" v-if="!onlyChild ||  (onlyChild && !haveChild(row))"
                      @on-change="changeValue(colItem,rowIndex,row)" :disabled="colItem.disabled"></i-switch>
          </template>
        </vxe-column>
      </div>

    </vxe-table>
    <div class="choose-all-class">
      <Button v-if="showChooseButton" type="primary" size="small" @click="selectAll">{{ $t('allChoose') }}</Button>
      <Button v-if="showChooseButton" type="default" size="small" @click="unSelectAll" style="margin-left: 2px">
        {{ $t('allNoChoose') }}
      </Button>
      <Button v-if="showExpandButton" type="default" size="small" @click="expandAll" style="margin-left: 2px">
        {{ $t('expand') }}
      </Button>
      <Button v-if="showExpandButton" type="default" size="small" @click="unExpandAll" style="margin-left: 2px">
        {{ $t('collapse') }}
      </Button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'DkTree',
  props: {
    data: {
      type: Array,
      default: () => []
    },
    //数名称
    name: {
      type: String,
      default: 'tree'
    },
    border: {
      type: String,
      default: 'full'
    },
    multiple: {
      type: Boolean,
      default: false
    },
    showCheckbox: {
      type: Boolean,
      default: false
    },
    // 是否显示全选checkbox
    showCheckboxHeader: {
      type: Boolean,
      default: true
    },
    //选中的Id串
    checkRowKeys: {
      type: Array,
      default: () => []
    },
    //明细列
    treeNodeName: {
      type: String,
      default: ''
    },
    //id列
    id: {
      type: String,
      default: ''
    },
    //父级id列
    parentId: {
      type: String,
      default: ''
    },
    //对于同一级的节点，每次是否只能展开一个
    accordion: {
      type: Boolean,
      default: true
    },
    //属性节点的标题
    nodeTitle: {
      type: String,
      default: ''
    },
    //节点列的宽度
    nodeWidth: {
      type: [String, Number],
      default: 180
    },
    // 自定义列
    columns: {
      type: Array,
      default: () => []
    },
    //是否显示全选按钮
    showChooseButton: {
      type: Boolean,
      default: false
    },
    //是否显示展开按钮
    showExpandButton: {
      type: Boolean,
      default: false
    },
    // 高度
    height: {
      type: [String, Number],
      default: 260
    },
    // 最小宽度
    minWidth: {
      type: [String, Number],
      default: ''
    },
    // 展开的模式(one：第一个；all：所有，none:不展开）
    expandMode: {
      type: String,
      default: 'one'
    },
    //是否只有子级有节点，针对与column
    onlyChild: {
      type: Boolean,
      default: true
    },
    // 选择列是否可以点击
    checkDisable: {
      type: Boolean,
      default: true
    },
    // 是否铺满全table
    resizeFlag:{
      type: Boolean,
      default: true
    },
    // 是否把顶点作为当前行
    topCurrentFlag:{
      type:Boolean,
      default:false
    },
    // 加载数据
    loading:{
      type: Boolean,
      default: true
    },
  },
  watch: {
    checkDisable(n, o) {
      this.checkDisableData = n
    },
    loading(n,o){
      this.loadingData = n;
    },
    data(n, o) {
      if (n) {
        //赋值上所需要id ,parentId 和name
        let data = n.map(it => {
          let obj = it
          obj.name = it[this.treeNodeName]
          obj.id = it[this.id]
          obj.parentId = it[this.parentId]
          return obj
        })
        this.treeData = data
        if (data && data.length > 0) {
          if (data.length === 1) {
            this.setCurrentRow(this.treeData[0]) // 如果只有一行，设置为当前行就行
          } else {
            this.$nextTick(() => {
              //展开全部
              if (this.expandMode === vm.$config.expandMode.all) {
                this.$refs[this.name].setAllTreeExpand(true) //展开树形
                if(this.topCurrentFlag){
                  this.setCurrentRow(this.treeData[0]) //第一个节点为当前行
                }else{
                  this.setCurrentRow() //选中当前行
                }
                //展开一级
              } else if (this.expandMode === vm.$config.expandMode.one) {
                if (data.length > 1) {
                  this.$refs[this.name].setTreeExpand(this.treeData[0], true) //展开第一级
                  if(this.topCurrentFlag){
                    this.setCurrentRow(this.treeData[0]) //第一个节点为当前行
                  }else{
                    this.setCurrentRow(this.treeData[1]) //第一个节点为当前行
                  }
                }
                //展开一级到底
              } else if (this.expandMode === vm.$config.expandMode.oneDeep) {
                if (data.length > 1) {
                  this.setExpandOneDeep() // 设置展开
                }
              }
            })
          }
        }
      } else {
        this.treeData = n
      }
      this.loadingData = false;
    }
  },
  data() {
    const vm = window.vm
    return {
      vm: vm,
      treeData: [],
      //是否显示标题
      showHeader: false,
      checkDisableData: true,
      loadingData :true,
      emptyText:''
    }
  },
  methods: {
    /**
     * @desc   : 单元格点击事件
     * @author : 周兴
     * @date   : 2022/6/8 19:47
     */
    cellClick(e){
      this.$emit('cellClick',e)
    },
    /**
     * @desc   : 设置多行选中列
     * @author : 周兴
     * @date   : 2022/5/6 11:00
     */
    setCheckboxRowByKeys(val, field) {
      //如果没有传值就取id
      if (!field) {
        field = this.id
      }
      let disableFlag = this.checkDisableData
      if (!this.checkDisableData) {
        this.checkDisableData = true
      }
      //先清空
      this.$refs[this.name].clearCheckboxRow()
      if (val) {
        let rows = this.treeData.filter(it => val.includes(it[field]))
        //再赋值
        this.$refs[this.name].setCheckboxRow(rows, true)
      }
      this.checkDisableData = disableFlag
    },
    /**
     * @desc   : 清空checkbox数据源
     * @author : 周兴
     * @date   : 2022/5/6 13:01
     */
    clearCheckboxRow() {
      this.$refs[this.name].clearCheckboxRow()
    },
    /**
     * @desc   : checkbox是否可用
     * @author : 周兴
     * @date   : 2022/5/5 14:03
     */
    checkMethod({row}) {
      let flag = this.checkDisable
      //如果有不需要控制直接返回
      if (flag) {
        return flag
      } else {
        //有子级就不允许点
        if (this.haveChild(row)) {
          return false
        } else {
          return true
        }
      }
    },
    /**
     * @desc   : 获取当前行
     * @author : 周兴
     * @date   : 2022/5/3 13:16
     */
    getCurrentRow() {
      return this.$refs[this.name].getCurrentRecord()
    },
    /**
     * @desc   : 是否有子级
     * @author : 周兴
     * @date   : 2022/4/29 17:38
     */
    haveChild(row) {
      let data = this.treeData.filter(it => it.parentId == row[this.id])
      if (data && data.length > 0) {
        return true
      } else {
        return false
      }
    },
    /**
     * @desc   : 设置展开（一级到底）
     * @author : 周兴
     * @date   : 2022/5/2 17:28
     */
    setExpandOneDeep() {
      let parentId = ''
      for (let index in this.treeData) {
        this.$refs[this.name].setTreeExpand(this.treeData[index], true) //展开当前级
        parentId = this.treeData[index][this.id]
        //查看是否有该子级数据
        let rows = this.treeData.filter(it => it.parentId === parentId)
        if (!rows || rows.length === 0) {
          //不存在子级
          this.setCurrentRow(this.treeData[index])
          this.$emit('on-select-change', null, this.treeData[index])
          break
        }
      }
    },
    /**
     * @desc   : 设置选中的行
     * @author : 周兴
     * @date   : 2022/4/22 14:14
     */
    setCurrentRow(row) {
      if(row){
        this.$refs[this.name].setCurrentRow(row);
        this.currentChange(row);
      }else{
        let parentId = ''
        for (let index in this.treeData) {
          if (parentId === '' || parentId === this.treeData[index][this.parentId]) {
            parentId = this.treeData[index][this.id]
          } else {
            this.$refs[this.name].setCurrentRow(this.treeData[index - 1])
            this.currentChange(this.treeData[index - 1]);
            break
          }
        }
      }
    },
    /**
     * @desc   : 选中改变
     * @author : 周兴
     * @date   : 2022/4/28 16:24
     */
    handleSelectChange(e) {
      //不能点击checkbox
      if (!this.checkDisable) {
        this.$refs[this.name].setCheckboxRow(e.row, !e.checked)
        return
      }
      this.$refs[this.name].setCurrentRow(e.row) //切换当前行
      let records = e.$table.getCheckboxRecords()
      this.$emit('checkbox-change', {row:e.row,checked:e.checked,records:records})
      // this.$emit('on-checkbox-change-row', {row:e.row,checked:e.checked})

    },
    /**
     * @desc   : 当前行变化
     * @author : 周兴
     * @date   : 2022/4/28 16:05
     */
    handleCurrentChange(e) {
      this.currentChange(e.newValue)
    },
    /**
     * @desc   : 当前行变化
     * @author : 周兴
     * @date   : 2023/9/14 10:09
     */
    currentChange(row){
      this.$emit('current-change', row)
    },
    /**
     * @desc   : 获取选中的数据
     * @author : 周兴
     * @date   : 2022/4/21 15:36
     */
    getDataChecked() {
      let records = this.$refs[this.name].getCheckboxRecords()
      return records
    },
    /**
     * @desc   : 值改变事件
     * @author : 周兴
     * @date   : 2022/4/28 17:05
     */
    changeValue(colItem, rowIndex, row) {
      // console.log('tt', colItem, row)
      this.$emit('switch-change', colItem, row)
    },
    /**
     * @desc   : 树形全选
     * @author : 周兴
     * @date   : 2022/5/11 9:26
     */
    selectAll() {
      this.$refs[this.name].setAllCheckboxRow(true);
      let records = this.$refs[this.name].getCheckboxRecords()
      this.$emit('select-all', records)
    },
    /**
     * @desc   : 全不选
     * @author : 周兴
     * @date   : 2022/5/11 9:29
     */
    unSelectAll() {
      this.$refs[this.name].clearCheckboxRow();
      this.$emit('select-all', [])
    },
    /**
     * @desc   : 全部展开
     * @author : 洪旭东
     * @date   : 2022-05-31 13:18
     */
    expandAll(){
      this.$refs[this.name].setAllTreeExpand(true)
    },
    /**
     * @desc   : 全部合并
     * @author : 洪旭东
     * @date   : 2022-05-31 13:18
     */
    unExpandAll(){
      this.$refs[this.name].setAllTreeExpand(false)
    },
  },
  created() {
    this.checkDisableData = this.checkDisable
    //判断是否有标题
    if (this.nodeTitle) {
      this.showHeader = true
    } else {
      this.showHeader = false
    }
  }
}
</script>
<style scoped>
.right-l {
  position: relative;
}

.right-l:after {
  content: ' ';
  border-right: 1px solid #d0ccdc;
  height: 16px;
  border-radius: 10px;
  position: absolute;
  right: 0;
  top: 3px;
}

/deep/ .ivu-tree-title {
  font-size: 12px;
}

.tree-class {
  width: 100%;
  padding:0;
  border: 1px solid #DCDFE6;
  overflow-y: hidden;
  overflow-x: hidden;
  /*border: 0 !important;*/
}

.tree-node-icon {
  width: 24px;
  text-align: center;
}

.choose-all-class{
  width: 100%;
  height: 30px;
  position: fixed ;
  padding-top: 10px;
  z-index: 10;
}

/deep/.switch-class .vxe-cell{
  display: flex !important;
  justify-content: center;
  align-items: center !important;
}

</style>

