<template>
  <el-table
    ref="table"
    class="bg-table bg-table-pro"
    :class="{ 'bg-table-tree': !!rowKey }"
    v-bind="$attrs"
    :data="data"
    :row-key="rowKey"
    :tree-props="treeProps"
    @selection-change="selectionChange"
    :default-expand-all="defaultExpandAll"
  >
    <el-table-column width="60" v-if="showIndex">
      <template v-slot:header>
        <p style="width: 100%; text-align: center">序号</p>
      </template>
      <template v-slot:default="{ $index }">
        <p style="width: 100%; text-align: center">{{ $index + 1 }}</p>
      </template>
    </el-table-column>
    <el-table-column
      type="selection"
      :selectable="selectable"
      width="60"
      align="center"
      v-if="showSelctColumn"
    />
    <el-table-column
      v-for="(header, index) in headers"
      :key="`col_${index}`"
      :width="header.width"
      :label="header.label"
      :align="header.align"
      :show-overflow-tooltip="!$slots[header.prop]"
      :fixed="header.fixed"
    >
      <template v-slot:header>
        <template v-if="$slots[`header-${header.prop}`]">
          <slot :name="`header-${header.prop}`" />
        </template>
        <template v-else>
          <p class="text-clip">
            <span v-if="header.required" style="color: #d75138">*</span>
            {{ header.label }}
          </p>
        </template>
      </template>

      <template v-slot:default="{ row, $index }">
        <template v-if="$slots[header.prop]">
          <slot :name="header.prop" :row="row" :index="$index" />
        </template>
        <template v-else-if="$slots[`text-${header.prop}`]">
          <p class="text-clip">
            <slot :name="`text-${header.prop}`" :row="row" :index="$index" />
          </p>
        </template>
        <template v-else>
          <p class="text-clip">{{ row[header.prop] }}</p>
        </template>
      </template>
    </el-table-column>
  </el-table>
</template>
  
  <script>
export default {
  name: "BgTablePro",
  props: {
    headers: {
      type: Array,
      require: true,
    },
    data: {
      type: Array,
    },
    rowKey: {
      type: String,
    },
    treeProps: {
      type: Object,
    },
    showIndex: {
      type: Boolean,
      default: false,
    },
    selectable: {
      type: Function,
    },
    defaultExpandAll: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      allSelection: [], // 所有页面上的选中的数据
    };
  },
  computed: {
    showSelctColumn() {
      return (
        this.$attrs &&
        (this.$attrs["selection-change"] || this.$attrs["select"])
      );
    }, // 是否显示选中列
    addSelectEvent() {
      return this.$attrs && this.$attrs["select"];
    }, // 是否监听select事件 select事件会记录所有页面上的选中的数据
  },
  watch: {
    data: {
      handler() {
        this.recoverSelection();
      },
      deep: true,
    },
  },
  methods: {
    recoverSelection() {
      let selectionIds = this.allSelection.map((v) => v[this.rowKey]);

      this.data.forEach((v) => {
        if (selectionIds.indexOf(v[this.rowKey]) > -1) {
          this.$nextTick(() => {
            console.log({ ...v });
            this.$refs.table.toggleRowSelection(v, true);
          });
        }
      });
    }, // 恢复选中
    selectionChange(selection) {
      if (!this.addSelectEvent) return; // 如果用户未监听select事件，则不执行

      if (!this.rowKey) throw Error("监听select事件时，row-key必须传入！");

      this.upAllSelection(selection);

      this.$emit("select", this.allSelection);
    }, // select事件
    upAllSelection(selection) {
      let rowIds = this.data.map((v) => v[this.rowKey]);
      let allSelection = [...this.allSelection];
      let selectionIds = allSelection.map((v) => v[this.rowKey]);

      // 首先把当前页的选中全部移除
      selectionIds = selectionIds.filter((v) => rowIds.indexOf(v) === -1);

      // allSelection仅保留selectionIds存在的
      allSelection = allSelection.filter(
        (v) => selectionIds.indexOf(v[this.rowKey]) > -1
      );

      // 然后再加入当前页的选中
      allSelection.push(...selection);

      this.allSelection = allSelection;
    }, // 更新当前全部被选中的数据
    clearSelection() {
      this.$refs.table.clearSelection();
      this.allSelectio = [];
    }, // 清空选中
    getRowInfo(row, key) {
      let currentIndex = -1;
      let parentRows = null;
      let propPath = "";
      let childrenKey = this.treeProps.children;
      let recursionItems = (items, prop) => {
        for (let i = 0; i < items.length; i++) {
          let item = items[i];

          propPath += `${i}.`;

          if (item[prop] === row[prop]) {
            currentIndex = i;
            parentRows = items;
            break;
          } else if (item[childrenKey] && item[childrenKey].length > 0) {
            propPath += `${childrenKey}.`;
            recursionItems(item[childrenKey], prop);
          }
        }
      };

      recursionItems(this.data, key, "");

      return {
        index: currentIndex,
        rows: parentRows,
        $_prop_path: propPath,
      };
    },
  },
};
</script>
  