<!--
* @name: 自定义 el-table
* @author: Zhangpengcheng
* @date: 2022-08-30
* tabLoading 加载  headerStyle表头格式  tableData数据 border纵向边框    @current-change单选触发   summary-method合计  @cell-click某个单元格点击触发事件  @sort-change触发后台排序
* @row-click 当某一行被点击时会触发该事件 highlight-current-row是否高亮  show-summary是否合计  SummariesIndex合计需要的index @selection-change多选 tableHeight高度
* :style="'height:'+ tableHeight + '!important'"
-->
<template>
  <!-- :row-class-name="tableRowClassName" -->
  <span style="position: relative">
    <el-table
      v-loading="tabLoading"
      ref="elTable"
      :header-cell-style="headerStyle"
      :data="tableData"
      :border="border"
      :min-width="minWidth"
      :summary-method="getSummaries"
      :row-class-name="tableRowClassName"
      :size="size"
      :row-key="getRowKey"
      :max-height="tableMaxHeight"
      :height="tableHeight"
      @cell-click="getCellClick"
      @row-click="getRowClick"
      @current-change="handleCurrentChange"
      :highlight-current-row="highlightCurrent"
      :show-summary="showsummary"
      :SummariesIndex="SummariesIndex"
      @row-dblclick="rowDblclick"
      @selection-change="handleSelectionChange"
      @select="select"
      @select-all="selectAll"
      style="width: 100%"
      :cell-class-name="tableCellName"
      :style="'min-height:' + minHeight + ';max-height:' + maxHeight"
      @sort-change="sortChange"
      :key="itemKey"
      @cell-dblclick="doubleClick"
      fit
      :span-method="objectSpanMethod"
    >
      <el-table-column
        align="center"
        :reserve-selection="true"
        v-if="showSelect"
        type="selection"
        width="55"
      >
      </el-table-column>

      <el-table-column
        label="序号"
        align="center"
        type="index"
        v-if="showIndex"
        width="50"
      >
        <template slot-scope="scope">
          <div v-if="indexOperate" style="text-align: center">
            <p v-if="scope.$index + 1 != tableData.length">
              {{ scope.$index + 1 }}
            </p>
            <el-button
              type="primary"
              plain
              icon="el-icon-plus"
              circle
              v-else
              size="mini"
              @click="newRow"
            >
            </el-button>
          </div>
          <p v-else>{{ scope.$index + 1 }}</p>
        </template>
      </el-table-column>

      <el-table-column label="单选" align="center" v-if="slotrow" width="50">
        <template slot-scope="scope">
          <!-- 定义插槽：父组件可以使用 v-slot:prop="{row}" 搭配template标签，自定义每一列单元格的样式与操作              -->
          <el-radio v-model="radioIndex" :label="scope.$index"
            ><span></span
          ></el-radio>
        </template>
      </el-table-column>

      <el-table-column
        v-for="(item, ind) in tableColumn"
        :key="ind"
        :width="item.width ? item.width : 'auto'"
        :label="item.label"
        :prop="item.prop"
        :show-overflow-tooltip="item.tooltip"
        :sortable="item.sortable"
        :align="item.align ? item.align : 'center'"
        :min-width="item.minWidth ? item.minWidth : '100px'"
        header-align="center"
        :fixed="item.fixed"
      >
        <!-- :isClick="item.other && item.other.isClick ? item.other.isClick : false" -->
        <template slot-scope="scope">
          <!-- 定义插槽：父组件可以使用 v-slot:prop="{row}" 搭配template标签，自定义每一列单元格的样式与操作              -->
          <slot :name="item.prop" :row="slotrow ? scope : scope.row">
            <!--  插槽后备内容：如父组件不使用插槽则使用后备内容                  -->
            <span
              :style="{
                color: item.color ? item.color : '#333',
                cursor: item.isClick ? 'pointer' : 'default',
              }"
            >
              {{
                !item.stateOption
                  ? scope.row[item.prop]
                  : item.stateOption[scope.row[item.prop]] | timeFiter
              }}
            </span>
          </slot>
        </template>
      </el-table-column>
      <el-table-column
        label="操作"
        :width="funWidth"
        v-if="funData.length != 0"
        align="center"
        header-align="center"
        :fixed="fixedTable"
        style="border-radius: 0 10px 10px 0"
      >
        <template slot-scope="scope">
          <div flex="cross:center main:center">
            <div
              v-for="(item, index) in funData"
              :key="index"
              :class="{ 'mr-12': index + 1 != funData.length }"
              @click.stop="funcEmit(index, scope.row, item)"
              class="btnText"
            >
              <span
                :style="'color:' + item.color"
                v-if="!item.ifField && !item.hiddenField"
                >{{ item.text }}</span
              >
              <span
                :style="{
                  color:
                    scope.row[item.ifField] == item.fieldVal
                      ? item.fieldColor
                      : item.color,
                }"
                v-if="item.ifField"
              >
                {{
                  scope.row[item.ifField] == item.fieldVal
                    ? item.fieldTxt
                    : item.text
                }}
              </span>
            </div>
          </div>
        </template>
      </el-table-column>
      <!-- 操作 、自定义插槽 -->
      <slot v-else></slot>
    </el-table>
    <div class="buttom">
      <el-button
        type="primary"
        plain
        icon="el-icon-plus"
        circle
        size="mini"
        @click="newRow"
        class="bottom"
        v-if="tableData.length == 0 && bottomPlus == true"
      ></el-button>
    </div>
  </span>
</template>
<script>
import Sortable from "sortablejs";
import { v4 as uuidv4 } from "uuid";
export default {
  props: {
    // 最大高度
    tableMaxHeight: {
      type: [String, Number],
    },
    // loading
    tabLoading: {
      type: Boolean,
      default: false,
    },
    // 序号操作icon
    indexOperate: {
      type: Boolean,
      default: false,
    },
    // 固定列
    fixedTable: {
      type: [Boolean, String],
      default: "right",
    },
    // 读取字段
    slotrow: {
      type: Boolean,
      default: false,
    },
    showsummary: {
      type: Boolean,
      default: false,
    },
    // 表格高度
    tableHeight: {
      type: [Number, String],
      default: "",
    },
    minHeight: {
      type: [Number, String],
      default: "auto",
    },
    maxHeight: {
      type: [Number, String],
      default: "auto",
    },
    // 表格高度
    // windowHight: {
    // 	type: [ String],
    // 	default: 'auto'
    // },
    // 表格尺寸
    size: {
      type: String,
      default: "small",
    },
    // 表格数据
    tableData: {
      type: Array,
      default: () => {
        return [];
      },
    },
    // 表头数据
    tableColumn: {
      type: Array,
      default: () => {
        return [];
      },
    },
    // 合计的index
    SummariesIndex: {
      type: Array,
      default: () => {
        return [];
      },
    },
    // 是否显示选择框
    showSelect: {
      type: Boolean,
      default: false,
    },
    // 是否显示序号
    showIndex: {
      type: Boolean,
      default: false,
    },
    // 操作选项
    funData: {
      type: Array,
      default: () => {
        return [];
      },
    },
    // 操作按钮宽度
    funWidth: {
      type: Number,
      default: 80,
    },
    // 是否带有纵向边框
    border: {
      type: Boolean,
      default: true,
    },
    minWidth: {
      type: String,
      default: "100px",
    },

    // 单选是否高亮
    highlightCurrent: {
      type: Boolean,
      default: false,
    },
    // 默认拖动
    sortableSwitch: {
      type: Boolean,
      default: false,
    },
    // 表格为空时的添加按钮
    bottomPlus: {
      type: Boolean,
      default: false,
    },
    // headerStyle:{
    // 	type: String,
    // 	default:{
    // 		'background-color': '#F5F5F5',
    // 		'color': '#333333',
    // 	},
    // }
    tableDataMergeList: {
      type: Array,
      default: () => {
        return [];
      },
    },
  },
  data() {
    return {
      headerStyle: {
        "background-color": "#F5F5F5",
        color: "#333333",
      },
      itemKey: true,
      radioIndex: false,
    };
  },
  created() {},
  mounted() {
    this.rowDrop();
    // 解决滚动条问题
    // var tableBody = this.$refs.elTable.$refs.footerWrapper
    // tableBody.addEventListener('scroll', () => {
    //   // 滚动距离
    //   const scrollLeft = tableBody.scrollLeft
    //   this.$refs.elTable.$refs.bodyWrapper.scrollLeft = scrollLeft
    // })
  },
  filters: {
    timeFiter(val) {
      if (!val && val != 0) {
        return;
      } else {
        let returnData = val;
        // if (typeof val != "number" && typeof val != "boolean") {
        //   // console.log(val,"asdasdad")
        //   returnData = val.split("T").join(" ");
        // }
        return returnData;
        // return val
      }
    },
  },
  computed: {},
  watch: {
    tableData: {
      deep: true,
      handler(newV, oldV) {
        newV.forEach((el, index) => {
          el.sort = index;
        });
        // this.setTableKey()
      },
    },
  },
  methods: {
    objectSpanMethod({ row, column }) {
      if (this.tableDataMergeList.includes(column.property)) {
        if (row[`${column.property}Length`]) {
          return {
            rowspan: row[`${column.property}Length`],
            colspan: 1,
          };
        } else {
          return {
            rowspan: 0,
            colspan: 0,
          };
        }
      }
    },
    uuidKey() {
      return uuidv4();
    },
    setCurrent(row) {
      this.$refs.elTable.setCurrentRow(row);
    },
    select(selection, row) {
      this.$emit("select", selection, row);
    },
    selectAll(selection) {
      this.$emit("selectAll", selection);
    },
    setTableKey() {
      this.itemKey = !this.itemKey;
    },
    // 单元格双击事件
    doubleClick(row, column, cell, event) {
      this.$emit("doubleClick", row, column, cell, event);
    },
    // 取消多选
    clearSelect() {
      this.$refs.elTable.clearSelection();
    },
    /**
     * @description 单元格点击事件
     * @author duanyipeng
     * @createDate 2020/7/6 21:36
     * @param { Object } row 每一行数据
     * @param { Object } column 选中单元格表头数据
     * @use {
     *          other:{
     *              isClick:true
     *          }
     *      }
     */
    getCellClick(row, column) {
      let label = column.label;
      // let itemColumn = this.tableColumn.filter(item => {
      // 	return item.label === label
      // })
      // if (itemColumn[0] && itemColumn[0].other && itemColumn[0].other.isClick) {
      // 	this.$emit('onCellClick', row, label)
      // }
      this.$emit("onCellClick", row, label);
    },
    // 每一行点击事件
    getRowClick(row, column, event) {
      this.handleCurrentChange(row);
      this.$emit("onRowClick", row, event);
    },
    // 每一行双击点击事件
    rowDblclick(row, column, event) {
      this.$emit("rowDblclick", row);
    },
    // 保存选中的数据id,row-key就是要指定一个key标识这一行的数据
    getRowKey(row) {
      return uuidv4();
    },
    // 多选事件
    handleSelectionChange(selectTable) {
      this.$emit("onSelectionChange", selectTable);
    },
    /**
     * 触发操作事件
     * 参数1：当前按钮索引
     * 参数2：当前按钮所在行数据
     */
    funcEmit(index, row, item) {
      this.$emit("onFunc", index, row, item);
    },
    // 排序改变 	降序:descending;升序ascending
    sortChange(column) {
      this.$emit("sortChange", column.prop, column.order);
    },
    //单选
    handleCurrentChange(val) {
      this.radioIndex = val.index;
      this.$emit("radioChange", val);
    },
    clearRadioIndex() {
      this.radioIndex = false;
    },
    setRadioIndex(index) {
      this.radioIndex = index;
    },
    // 添加index
    tableCellName({ row, column, rowIndex, columnINdex }) {
      row.index = rowIndex;
      column.index = columnINdex;
    },
    // tableRowClassName({	row,rowIndex}) {
    // 	if (rowIndex === 1) {
    // 	  return 'warning-row';
    // 	} else if (rowIndex === 3) {
    // 	  return 'success-row';
    // 	}
    // 	return '';
    // },
    tableRowClassName: function ({ row, rowIndex }) {
      let data = "";
      this.$emit(
        "row-class-name",
        {
          row: row,
          rowIndex: rowIndex,
        },
        (val) => {
          data = val;
        }
      );
      return data; //属性名必须返回一个string
    },
    newRow() {
      let arr = this.getAddRowData();
      this.$emit("newRow", arr);
      this.$nextTick(() => {
        this.$refs.elTable.bodyWrapper.scrollTop =
          this.$refs.elTable.bodyWrapper.scrollHeight;
        this.$refs.elTable.doLayout();
      });
    },
    getAddRowData() {
      let arr = {};
      this.tableColumn.forEach((el) => {
        arr[el.prop] = "";
      });
      return arr;
    },
    //行拖拽,排序方法
    rowDrop() {
      if (!this.sortableSwitch) {
        return;
      }
      const el = this.$refs.elTable.$el.querySelectorAll(
        ".el-table__body-wrapper > table > tbody"
      )[0];
      this.sortable = Sortable.create(el, {
        ghostClass: "sortable-ghost",
        setData: function (dataTransfer) {
          dataTransfer.setData("Text", "");
        },
        onEnd: (evt) => {
          const targetRow = this.tableData.splice(evt.oldIndex, 1)[0];
          this.tableData.splice(evt.newIndex, 0, targetRow);
        },
      });
    },
    // 默认选择
    toggleSelection(rowData, selected) {
      if (rowData) {
        rowData.forEach((row) => {
          this.$refs.elTable.toggleRowSelection(row, selected);
        });
      } else {
        this.$refs.elTable.clearSelection();
      }
    },
    handlerSpanMethod(row, column, rowIndex, columnIndex) {
      this.$emit("spanMethod", row, column, rowIndex, columnIndex);
    },
    // 合计
    getSummaries(params) {
      const { columns, data } = params;
      const sums = [];
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = "合计";
          return;
        }
        this.SummariesIndex.forEach((el) => {
          if (index == el) {
            const values = data.map((item) => Number(item[column.property]));
            if (!values.every((value) => isNaN(value))) {
              sums[index] = values.reduce((prev, curr) => {
                const value = Number(curr);
                if (!isNaN(value)) {
                  return prev + curr;
                } else {
                  return prev;
                }
              }, 0);
              sums[index] = sums[index].toFixed(2);
            } else {
              sums[index] = "";
            }
          }
        });
      });
      this.$emit("sums", sums);

      return sums;
    },
  },
};
</script>

<style>
.el-table .warning-row {
  background: #ffe562;
}

.el-table .success-row {
  background: #acf389;
}

.el-table .denger-row {
  background: #e13501;
}

.fiexTableBottm {
  position: sticky;
  bottom: 0;
}
</style>
<style scoped lang="scss">
.btnText {
  cursor: pointer;
}

.mr-12 {
  margin-right: 12px;
}

::v-deep .cell {
  font-weight: 400;
}

.buttom {
  ::v-deep .el-button--mini.is-circle {
    position: absolute;
    top: 50px;
    left: 10px;
  }
}

::v-deep .el-table__cell:last-child {
  border-radius: 0 10px 10px 0;
}

// ::v-deep .el-table .sort-caret.ascending {
// 	top: 1px
// }

// ::v-deep .el-table .sort-caret.descending {
// 	bottom: 2px
// }

// ::v-deep .el-table .caret-wrapper {
// 	height: 23px;
// }

// 解决滚动条问题
// div ::v-deep .el-table--scrollable-x .el-table__body-wrapper{overflow-x: hidden!important;z-index: 2!important;}
// div ::v-deep .el-table__footer-wrapper {overflow-x: auto;border-top: 1px solid #f4f4f4;}
// ::v-deep .el-table {
//   overflow-x: auto;
// }
// ::v-deep .el-table__header-wrapper,
// ::v-deep .el-table__body-wrapper,
// ::v-deep .el-table__footer-wrapper {
//   overflow: visible;
// }
// ::v-deep .el-table::after {
//   position: relative;
// }
// ::v-deep .el-table--scrollable-x ::v-deep .el-table__body-wrapper {
//   overflow: visible;
// }
// ::v-deep .el-table { .el-table__body-wrapper { z-index: 2; } }
::v-deep.el-table {
  width: 100%;
  margin-bottom: 0vh !important;

  &::before {
    display: none;
  }

  .el-table__body {
    -webkit-border-vertical-spacing: 0px !important; // 垂直间距 设置的是行间距
  }

  //以下代码是实现边框效果
  thead th {
    font-size: 14px;
    color: #575757 !important;

    &:nth-last-child(2) {
      border-right: 1px solid rgba(0, 0, 0, 0.1) !important;
      border-radius: 0 5px 5px 0;
      right: 1px;
    }
  }

  thead th,
  .el-table__row td {
    font-size: 18px;
    font-family: PingFangSC-Semibold, PingFang SC;
    font-weight: 600;
    border-top: 1px solid rgba(0, 0, 0, 0.1) !important;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1) !important;

    &:first-child {
      border-left: 0px solid rgba(0, 0, 0, 0.1) !important;
      border-radius: 0px 0 0 0px !important;
    }
  }

  .el-table__row > td {
    font-size: 12px;
    color: #333333;

    &:last-child {
      border-left: 0px solid rgba(0, 0, 0, 0.1) !important;
      border-radius: 0px 0 0 0px !important;
    }
  }

  .el-table__body tr:hover > td.el-table__cell {
    background-color: #eef5fe !important;
  }

  .el-table__fixed::before {
    display: none;
  }
}
</style>
