<template>
  <!-- 关于表格的操作 -->
  <div class="main" style="height:100%">
    <!-- 行的合并 列的合并 表头添加斜线 -->
    <el-table :data="tableDataList" :span-method="objectSpanMethod" :header-cell-style="headMerge" border
      v-loading="loadingStatus" :element-loading-text="loadingText" :element-loading-spinner="loadingIcon"
      :element-loading-background="loadingBg" :height="height" :row-class-name="rowClassName"
      @cell-mouse-enter="handleMouseEnter" @cell-mouse-leave="handleMouseLeave" class="TableMergeTemplate">
      <el-table-column v-for="(item, index) in mergeTitleList" :prop="item.props" :label="item.label" :key="index + 1"
        header-align="center" align="center"></el-table-column>
      <el-table-column v-for="(item, index) in additionalTitle" :key="index + 200" :label="item.label"
        header-align="center" align="center" style="text-align: center;">
        <template v-slot="scope">
          <el-input ref="elInputRef" v-model="scope.row[item.props]" type="text"
            @input="textInput($event, scope.row, item.props)" @blur="theInput($event, item, scope.row, item.props)"
            size="mini" v-if="item.showInput && scope.row.id == inputId"></el-input>
          <span v-else @dblclick="dblclicks(item, scope.row, scope.row[item.props])" class="items">{{
              scope.row[item.props] ? scope.row[item.props] : 0
          }}</span>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  name: 'TableMergeTemplate',
  props: {
    additionalTitle: {
      type: Array,
      default: () => []
    },
    addDataList: {
      type: Array,
      default: () => []
    },
    addRightConfig: {
      type: Object
    },
    treeDataListConfig: {
      type: Object
    },
    summaryText: {
      type: String,
      default: () => '合计'
    },
    tableTreeDataList: {
      type: Array,
      default: () => []
    },
    loadingStatus: {
      type: Boolean,
      default: () => false
    },
    loadingText: {
      type: String,
      default: () => '拼命加载中'
    },
    loadingIcon: {
      type: String,
      default: () => 'el-icon-loading'
    },
    loadingBg: {
      type: String,
      default: () => 'rgba(0, 0, 0, 0.8)'
    },
    showSummary: {
      type: Boolean,
      default: () => false
    },
    height: {
      type: String
    }

  },
  data() {
    return {
      loading: false, // 加载中
      // 后追加的数据
      // additionalTitle: [],
      // 需要合并的单元格前面部分 表头
      mergeTitleList: [],
      // 表格数据
      tableDataList: [],
      inputId: undefined,
      keyList: [], // 存放的字段key
      labelList: [], // 存放的字段title
      datalist: [], // 列规则
      datalist1: [], // 行规则
      datalist2: [], // 头部合并规则
      oldValue: 0,
      newValue: 0,
      cellIndex: -1
    };
  },
  async created() {
    // Let obj1 = {
    //   name:11,
    //   age:222
    // }
    // let obj2 = {
    //   name:22221,
    //   ser:'22221'
    // }
    // obj1 = Object.assign(obj2,obj1)
    // console.log(obj1);
    this.additionalTitle.forEach(item => {
      this.$set(item, 'showInput', false);
    });
    // 处理树形数据
    await this.setTableDataList();
    // 计算合并的头部
    await this.setTableTitleList();
    // 添加合计
    await this.andCound();
    this.mergeTitleList.forEach(item => {
      this.keyList.push(item[this.treeDataListConfig.PropsMergeId]);
      this.labelList.push(item[this.treeDataListConfig.TitleMergeId]);
    });
    // Console.log(this.keyList,this.labelList,222);

    // // 调用计算需要合并的行
    this.getSpanArr(this.tableDataList);

    // 计算合并的titel
    this.labelList.forEach((item, index) => {
      this.getTitleList(item, index);
    });
  },
  methods: {
    // 双击函数input
    dblclicks(item, props, value) {
      // Console.log(item,props,value,22122);
      const Arr = Object.values(props);

      if (Arr.indexOf(this.summaryText) !== -1) {
        this.$message({
          type: 'error',
          message: `${this.summaryText}行不允许修改`
        });
        return;
      }

      this.inputId = props.id;
      this.oldValue = value || 0;
      item.showInput = true;
      setTimeout(() => {
        this.$refs.elInputRef[0].focus();
      }, 200);
    },
    // 输入函数
    textInput($e, val, props) {
      this.newValue = $e || 0;
      const list = JSON.parse(JSON.stringify(this.tableDataList));

      list.forEach(item => {
        if (item.id === val.id) {
          this.$set(item, props, $e);
        }
      });
      this.$nextTick(() => {
        this.tableDataList = [];
        this.tableDataList = list;
      });
    },
    // 失去焦点函数
    theInput($e, item, tableData, props) {
      item.showInput = false;
      this.tableDataList.forEach(item => {
        // Console.log(item[this.treeDataListConfig.PropsMergeId]);
        if (item[this.mergeTitleList[0].props] === this.summaryText) {
          const num = Number(this.newValue) + item[props] - this.oldValue;
          // Console.log($e,item[props],this.oldValue,num);

          this.$set(item, props, num);
        }
      });
      this.$emit('blurInput', tableData);
    },
    // 处理头部数据
    setTableTitleList() {
      this.tableTreeDataList.forEach((item, index) => {
        this.mergeTitleList.push({
          label: item[this.treeDataListConfig.title],
          props: this.treeDataListConfig.props + item[this.treeDataListConfig.level],
          mergeId: this.treeDataListConfig.TitleMergeId + item[this.treeDataListConfig.level],
          [this.treeDataListConfig.PropsMergeId]: this.treeDataListConfig.PropsMergeId + item[this.treeDataListConfig.level]
        });
        if (item.childrens) {
          item.childrens.forEach(items => {
            this.setTableTitleListDG(items);
          });
        }
      });
      this.mergeTitleList = (this.objTrim(this.mergeTitleList));
      console.log(this.mergeTitleList, '头部');
    },
    setTableTitleListDG(items) {
      this.mergeTitleList.push({
        label: items[this.treeDataListConfig.title],
        props: this.treeDataListConfig.props + items[this.treeDataListConfig.level],
        mergeId: this.treeDataListConfig.TitleMergeId + items[this.treeDataListConfig.level],
        [this.treeDataListConfig.PropsMergeId]: this.treeDataListConfig.PropsMergeId + items[this.treeDataListConfig.level]
      });
      if (items.childrens) {
        items.childrens.forEach(item => {
          this.setTableTitleListDG(item);
        });
      }
    },
    objTrim(mergeTitleList) {
      const obj = {};

      mergeTitleList = mergeTitleList.reduce((cur, next) => {
        obj[next.props] ? '' : obj[next.props] = true && cur.push(next);
        return cur;
      }, []);
      return mergeTitleList;
    },

    // 处理树形数据
    async setTableDataList() {
      this.tableDataList = [];
      this.tableTreeDataList.forEach((item, index) => {
        this.setData(item, index);
      });
    },
    // 合计数据展示
    andCound() {
      if (!this.showSummary) {
        return;
      }

      // Console.log(this.mergeTitleList[0]);
      const datas = {};

      this.$set(datas, this.mergeTitleList[0].props, this.summaryText);
      this.$set(datas, this.mergeTitleList[0][this.treeDataListConfig.PropsMergeId], this.mergeTitleList[0][this.treeDataListConfig.PropsMergeId]);
      console.log(this.tableDataList, '数据');
      this.tableDataList.forEach(item => {
        this.addDataList.forEach(items => {
          if (item[this.addRightConfig.treeDataId] == items[this.addRightConfig.rightId]) {
            item = Object.assign(item, items);
          }
        });
      });
      let order = 1;
      const data = this.tableDataList;

      for (let i = 0; i < data.length; i++) {
        if (i === 0) {
          data[i].order = order;
        } else {
          console.log(data[i][this.mergeTitleList[0].mergeId], data[i - 1][this.mergeTitleList[0].mergeId]);
          if (data[i][this.mergeTitleList[0].mergeId] == data[i - 1][this.mergeTitleList[0].mergeId]) {
            // 此处是给相同的数据加相同order，具体判断条件可根据自己数据进行判断
            data[i].order = data[i - 1].order = data[i].order
              ? data[i].order
              : order;
          } else {
            order++;
          }
        }
      }

      this.additionalTitle.forEach(items => {
        let num = 0;

        this.tableDataList.forEach(item => {
          if (item[items.props]) {
            num += (Number(item[items.props]));
          }
        });
        this.$set(datas, items.props, num);
      });
      this.tableDataList.push(datas);
    },
    // 处理中间递归函数
    setData(item, index, items) {
      // Item,  递归数据   items 第一次数据
      if (item.childrens) {
        // 证明还有下级结构
        item.childrens.forEach((Items, isIndex) => {
          this.setData(Items, isIndex, items);
        });
      } else {
        // 没有下级了 最后一级  然后在反推父类 拿到父类数据
        this.$set(item, `${this.treeDataListConfig.props}${item[this.treeDataListConfig.level]}`, item[this.treeDataListConfig.props]);
        this.$set(item, `${this.treeDataListConfig.TitleMergeId}${item[this.treeDataListConfig.level]}`, item[this.treeDataListConfig.TitleMergeId]);
        this.$set(item, `${this.treeDataListConfig.PropsMergeId}${item[this.treeDataListConfig.level]}`, item[this.treeDataListConfig.PropsMergeId]);

        // 查找父类
        this.tableTreeDataList.forEach(items => {
          this.setParentData(items, item, item.parentId, items);
        });
        this.tableDataList.push(item);
      }
    },
    // 查找父类递归
    setParentData(items, item, parentId, lunzhuanObj = {}) {
      // Items源数据 代表第一级   item要查找的数据   //要查找的parentId
      if (items.id === parentId) {
        // 证明找到了  为第一级
        this.$set(item, `${this.treeDataListConfig.props}${items[this.treeDataListConfig.level]}`, items[this.treeDataListConfig.props]);
        this.$set(item, `${this.treeDataListConfig.TitleMergeId}${items[this.treeDataListConfig.level]}`, items[this.treeDataListConfig.TitleMergeId]);
        this.$set(item, `${this.treeDataListConfig.PropsMergeId}${items[this.treeDataListConfig.level]}`, items[this.treeDataListConfig.PropsMergeId]);
      } else if (lunzhuanObj.id == parentId) {
        this.$set(item, `${this.treeDataListConfig.props}${lunzhuanObj[this.treeDataListConfig.level]}`, lunzhuanObj[this.treeDataListConfig.props]);
        this.$set(item, `${this.treeDataListConfig.TitleMergeId}${lunzhuanObj[this.treeDataListConfig.level]}`, lunzhuanObj[this.treeDataListConfig.TitleMergeId]);
        this.$set(item, `${this.treeDataListConfig.PropsMergeId}${lunzhuanObj[this.treeDataListConfig.level]}`, lunzhuanObj[this.treeDataListConfig.PropsMergeId]);
        if (lunzhuanObj.parentId != '') {
          this.setParentData(items, item, lunzhuanObj.parentId, items);
        }
      } else if (lunzhuanObj.childrens) {
        lunzhuanObj.childrens.forEach(LZItem => {
          this.setParentData(items, item, parentId, LZItem);
        });
      }
    },

    // 鼠标进入单元格
    handleMouseEnter(row, column, cell, event) {
      this.tableDataList.forEach(item => {
        if (row.order === item.order) {
          this.cellIndex = row.order;
        }
      });
    },
    // 给相应的rowIndex添加类名
    rowClassName({ row, rowIndex }) {
      // Console.log(row, rowIndex);
      let r = -1;

      this.tableDataList.forEach(item => {
        if (this.cellIndex === row.order) {
          r = rowIndex;
        }
      });
      if (rowIndex === r) {
        return 'hover-row';
      }
    },
    // 鼠标离开
    handleMouseLeave(row, column, cell, event) {
      this.cellIndex = -1;
    },

    getTitleList(item, index) {
      if (index === 0) {
        this.datalist2.push(1);
      } else if (item && (item === this.labelList[index - 1])) {
        if (this.labelList[index - 1] == this.labelList[index - 2]) {
          this.getTitleList(item, index - 1);
          this.datalist2[index] = 0;
        } else {
          this.datalist2[index - 1] += 1;
          this.datalist2[index] = 0;
        }
      } else {
        this.datalist2.push(1);
      }
    },
    getSpanArr(data) {
      this.datalist = []; // 列数组保存
      this.keyList.forEach((item, index1) => {
        let concatOne = 0;

        data.forEach((items, index) => {
          if (index == 0) {
            this.datalist[index1] = [];
            this.datalist[index1].push(1);
          } else if (items[item] && items[item] === data[index - 1][item]) {
            this.datalist[index1][concatOne] += 1;
            this.datalist[index1].push(0);
          } else {
            this.datalist[index1].push(1);
            concatOne = index;
          }
        });
      });
      this.datalist1 = []; // 行数组保存  赋值默认值
      data.forEach((items, index) => {
        this.keyList.forEach((item, index1) => {
          if (index1 == 0) {
            this.datalist1[index] = [];
            this.datalist1[index].push(1);
          } else {
            this.datalist1[index].push(1);
          }
        });
      });

      data.forEach((items, index) => {
        this.keyList.forEach((item, index1) => {
          this.getData(items, index, item, index1);
        });
      });
    },
    // 递归查询
    getData(items, index, item, index1) {
      if (!items[item]) {
        if (!items[this.keyList[index1 - 1]]) {
          this.getData(items, index, item, index1 - 1);
        } else {
          this.datalist1[index][index1 - 1] += 1;
        }
      } else {
        this.datalist1[index][index1] = 1;
      }
    },
    // 注意：横向合并列 纵向合并行
    objectSpanMethod(
      {
        row,
        column,
        rowIndex,
        columnIndex
      }) {
      const data = this.datalist[columnIndex];
      const data1 = this.datalist1[rowIndex];

      if (data1 && (data1[columnIndex] == 1 && data1[columnIndex - 1 > 0 ? columnIndex - 1 : 0] > 1 || data1[columnIndex] == 1 && data1[columnIndex - 2 > 0 ? columnIndex - 2 : 0] > 1 || data1[columnIndex] == 1 && data1[columnIndex - 3 > 0 ? columnIndex - 3 : 0] > 1 || data1[columnIndex] == 1 && data1[columnIndex - 4 > 0 ? columnIndex - 4 : 0] > 1 || data1[columnIndex] == 1 && data1[columnIndex - 5 > 0 ? columnIndex - 5 : 0] > 1 || data1[columnIndex] == 1 && data1[columnIndex - 6 > 0 ? columnIndex - 6 : 0] > 1 || data1[columnIndex] == 1 && data1[columnIndex - 7 > 0 ? columnIndex - 7 : 0] > 1)) {
        return {
          rowspan: 0,
          colspan: 0
        };
      }

      if (data && data1) {
        const _row = data[rowIndex];
        const _col = data1[columnIndex] > 1 ? data1[columnIndex] : 1; // 合并单元格格

        return {
          rowspan: _row,
          colspan: _col
        };
      }
    },

    // 第二列表头的隐藏
    headMerge({
      row,
      column,
      rowIndex,
      columnIndex
    }) {
      if (this.datalist2[columnIndex] > 1) {
        this.$nextTick(() => {
          if (document.getElementsByClassName(column.id).length !== 0) {
            document
              .getElementsByClassName(column.id)[0]
              .setAttribute('colSpan', this.datalist2[columnIndex]);
          }
        });
      }

      const Iindex = [];

      this.datalist2.forEach((item, index) => {
        if (item == 0) {
          Iindex.push(index);
        }
      });
      // || columnIndex == Iindex[1]
      if (Iindex.indexOf(columnIndex) != (-1)) {
        return {
          display: 'none'
        };
      }
    }
  }
};
</script>

<style lang="scss">
// 表头添加斜线部分的样式
// scss的混合
@mixin common() {
  text-align: right;
  border-bottom: none;
}

// 三个表格中部分需要更改的公共样式
@mixin common-part() {
  content: "";
  position: absolute;
  width: 1px;
  background-color: grey;
  opacity: 0.3;
  display: block;
}
.main {
  /*去掉下边框 */
  .el-table th.is-right,
  .el-table td.is-right {
    @include common();
  }

  /* 斜线上方 bjzh 部分 */
  .el-table thead.is-group tr:first-of-type th:first-of-type:before {
    @include common-part();
    height: 17.083rem;
    /*这里需要自己调整，根据td的宽度和高度*/
    top: 0;
    left: 0;
    transform: rotate(-78.3deg);
    /*这里需要自己调整，根据线的位置*/
    transform-origin: top;
  }

  /* 斜线下方 lg 部分 */
  .el-table thead.is-group tr:nth-of-type(2) th:first-of-type:before {
    @include common-part();
    height: 17.083rem;
    /*这里需要自己调整，根据td的宽度和高度*/
    bottom: 0;
    right: 0;
    transform: rotate(-79.3deg);
    /*这里需要自己调整，根据线的位置*/
    transform-origin: bottom;
    /*旋转的起点 */
  }
}

.items {
  display: inline-block;
  width: 100%;
  height: 100%;
}
</style>
