<!--
* @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" -->
  <div class="app-container">
    <el-table
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      v-loading="tabLoading"
      ref="elTable"
      :header-cell-style="headerStyle"
      :data="tableInfo.tableData"
      :border="border"
      @current-change="handleCurrentChange"
      :summary-method="getSummaries"
      :row-class-name="tableRowClassName"
      :size="size"
      row-key="id"
      @cell-click="getCellClick"
      @row-click="getRowClick"
      :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"
      :max-height="tableMaxHeight"
      @sort-change="sortChange"
      :key="itemKey"
      @cell-dblclick="doubleClick"
      fit
    >
      <el-table-column
        align="center"
        :reserve-selection="true"
        v-if="showSelect"
        type="selection"
        width="55"
      >
      </el-table-column>
      <el-table-column
        fixed
        label="序号"
        align="center"
        type="index"
        v-if="showIndex"
        width="55"
      >
        <template slot-scope="scope">
          <div v-if="indexOperate && !lookflag">
            <p v-if="scope.$index + 1 != tableInfo.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="60">
        <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
        :key="item.id"
        :width="item.width ? item.width : 'auto'"
        :label="item.title"
        :prop="item.id"
        :show-overflow-tooltip="item.tooltip"
        :sortable="item.sortable"
        :align="item.align ? item.align : 'center'"
        header-align="center"
        :fixed="item.fixed"
        v-for="(item, ind) in tableInfo.detailFields"
        v-if="!item.hidden"
      >
        <!-- :isClick="item.other && item.other.isClick ? item.other.isClick : false" -->
        <template slot-scope="scope">
          <!-- 定义插槽：父组件可以使用 v-slot:prop="{row}" 搭配template标签，自定义每一列单元格的样式与操作              -->
          <slot
            :name="item.id"
            :row="
              slotrow
                ? scope
                : [scope.row, item, tableInfo.tableData[scope.row.index]]
            "
          >
            <template v-if="!lookflag">
              <!-- <button @click="test(scope)">按钮</button> -->
              <!-- v-model="tableInfo.tableData[scope.row.index][item.id]" -->

              <el-input
                :maxlength="item.maxlength ? item.maxlength : '50'"
                v-if="item.type === 'input'"
                v-model="scope.row[item.id]"
                placeholder=""
              ></el-input>
              <el-input
                :maxlength="item.maxlength ? item.maxlength : '50'"
                v-if="item.type === 'number'"
                type="number"
                onkeyup="value=value.replace(/[^\d]/g,'')"
                v-model="scope.row[item.id]"
                placeholder=""
                min="1"
              ></el-input>
              <el-checkbox
                v-if="item.type === 'checkbox'"
                v-model="scope.row[item.id]"
              ></el-checkbox>
              <BaseSelect
                v-if="item.type === 'select'"
                v-model="scope.row[item.id]"
                :selectInfo="item"
                :itemObj="item"
                :ruleForm="tableInfo.tableData[scope.row.index]"
              ></BaseSelect>
              <baseCascader
                v-if="item.type === 'treeselect'"
                v-model="scope.row[item.id]"
                :itemObj="item"
                :ruleForm="tableInfo.tableData[scope.row.index]"
              >
              </baseCascader>
              <el-link
                style="
                  overflow: hidden;
                  text-overflow: ellipsis;
                  white-space: nowrap;
                "
                v-if="item.type === 'click'"
                @click="clickBoxHandle(scope.row)"
                type="primary"
                >{{
                  tableInfo.tableData[scope.row.index][item.id]
                    ? tableInfo.tableData[scope.row.index][item.id]
                    : "点击这里..."
                }}</el-link
              >
              <div v-if="item.type === 'text'">
                <el-tooltip class="item" effect="dark" placement="top">
                  <div slot="content">
                    {{ tableInfo.tableData[scope.row.index][item.id] }}
                  </div>
                  <div
                    style="
                      overflow: hidden;
                      text-overflow: ellipsis;
                      white-space: nowrap;
                    "
                  >
                    {{ tableInfo.tableData[scope.row.index][item.id] }}
                  </div>
                </el-tooltip>
              </div>
              <BaseDatePicker
                v-if="item.type === 'datepick'"
                v-model="scope.row[item.id]"
              ></BaseDatePicker>
              <BaseDatePicker
                v-if="item.type === 'datetimepick'"
                datePickerType="datetime"
                v-model="scope.row[item.id]"
              ></BaseDatePicker>
              <div
                v-if="
                  item.type === 'compute' &&
                  !lookflag &&
                  scope.$index + 1 != tableInfo.tableData.length
                "
              >
                <el-tooltip class="item" effect="dark" placement="top">
                  <div slot="content">
                    {{ calculator(item, scope.row) }}
                  </div>
                  <div
                    style="
                      overflow: hidden;
                      text-overflow: ellipsis;
                      white-space: nowrap;
                    "
                  >
                    {{ calculator(item, scope.row) }}
                  </div>
                </el-tooltip>
              </div>
              <el-switch
                v-if="item.type === 'switch'"
                v-model="scope.row[item.id]"
              >
              </el-switch>
            </template>
            <template v-else>
              <div
                v-if="
                  item.type != 'checkbok' &&
                  item.type !== 'select' &&
                  item.type !== 'treeselect' &&
                  item.type !== 'datepick'
                "
              >
                <el-tooltip class="item" effect="dark" placement="top">
                  <div slot="content">
                    {{ tableInfo.tableData[scope.row.index][item.id] }}
                  </div>
                  <div
                    style="
                      overflow: hidden;
                      text-overflow: ellipsis;
                      white-space: nowrap;
                    "
                  >
                    {{ tableInfo.tableData[scope.row.index][item.id] }}
                  </div>
                </el-tooltip>
              </div>
              <baseCascader
                v-if="item.type === 'treeselect'"
                v-model="scope.row[item.id]"
                :lookflag="true"
                :itemObj="item"
                :ruleForm="tableInfo.tableData[scope.row.index]"
              >
              </baseCascader>
              <el-checkbox
                v-if="item.type === 'checkbox'"
                v-model="scope.row[item.id]"
              ></el-checkbox>
              <div v-if="item.type === 'datepick'">
                {{ 123 }}
                {{ scope.row[item.id].split("T")[0] }}
              </div>
            </template>
          </slot>
        </template>
      </el-table-column>
      <el-table-column
        label="操作"
        :width="funWidth"
        v-if="funData.length != 0 && !lookflag"
        align="center"
        header-align="center"
        :fixed="fixedTable"
      >
        <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="funcEmit(scope.row, funData[index], scope)"
              class="btnText"
              :style="{ background: item.color ? item.color : 'blue' }"
              style="padding: 3px 10px; border-radius: 20px"
            >
              <span
                style="color: #fff; font-weight: 700"
                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>
      <!-- 操作 、自定义插槽 -->
    </el-table>
  </div>
</template>
<script>
import baseCascader from "./baseCascader/index";
import { deepClone } from "@/utils/index.js";
import execMathExpress from "exec-mathexpress";
import BaseDatePicker from "./baseDatePicker.vue";
import BaseSelect from "./baseNewSelect.vue";
import Sortable from "sortablejs";
export default {
  props: {
    // 表格的索引值
    formIndex: {
      type: Number,
      default: 0,
    },
    lookflag: {
      type: Boolean,
      default: false,
    },
    tableInfo: {
      type: Object,
      default: () => {
        return {};
      },
    },
    // 最大高度
    tableMaxHeight: {
      type: [String, Number],
    },
    // loading
    tabLoading: {
      type: Boolean,
      default: false,
    },
    // 序号操作icon
    indexOperate: {
      type: Boolean,
      default: false,
    },
    // 固定列
    fixedTable: {
      type: [Boolean, String],
      default: false,
    },
    // 读取字段
    slotrow: {
      type: Boolean,
      default: false,
    },
    showsummary: {
      type: Boolean,
      default: false,
    },
    // 表格高度
    tableHeight: {
      type: [Number, String],
      default: "auto",
    },
    // 表格高度
    // windowHight: {
    // 	type: [ String],
    // 	default: 'auto'
    // },
    // 表格尺寸
    size: {
      type: String,
      default: "small",
    },
    // 表格数据
    tableData: {
      type: Array,
      default: () => {
        return [];
      },
    },
    // 表头数据
    detailFields: {
      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: 100,
    },
    // 是否带有纵向边框
    border: {
      type: Boolean,
      default: false,
    },

    // 单选是否高亮
    highlightCurrent: {
      type: Boolean,
      default: false,
    },
    // 默认拖动
    sortableSwitch: {
      type: Boolean,
      default: false,
    },
    // headerStyle:{
    // 	type: String,
    // 	default:{
    // 		'background-color': '#F5F5F5',
    // 		'color': '#333333',
    // 	},
    // }
  },
  data() {
    return {
      headerStyle: {
        "background-color": "#F5F5F5",
        color: "#333333",
      },
      itemKey: true,
      radioIndex: false,
    };
  },
  created() {},
  mounted() {
    this.$emit("getTableData", this.tableInfo.index);
    this.rowDrop();
  },
  computed: {},
  watch: {},
  methods: {
    test(row) {
    },

    calculator(item, row) {
      let obj = {};
      item.computeId.forEach((ele) => {
        obj[ele] = row[ele];
      });
      let result;
      try {
        let { num, den } = execMathExpress(item.total, obj);
        result = num / den;
      } catch (error) {
        return "数字不合法";
      }
      this.$emit("toalResult", this.tableInfo, row, item, result);
      return result.toFixed(2);
    },
    // 点击这里盒子触发
    clickBoxHandle(row) {
      this.$emit(
        "clickBox",
        this.tableInfo,
        row.index,
        this.tableInfo.tableData[row.index].id,
        this.formIndex
      );
    },
    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.detailFields.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);
    },
    // 每一行双击点击事件
    rowDblclick(row, column, event) {
      if (this.showSelect) {
        this.toggleSelection([row]);
      }
      this.$emit("rowDblclick", row);
    },
    // 保存选中的数据id,row-key就是要指定一个key标识这一行的数据
    getRowKey(row) {
      return row.id;
    },
    // 多选事件
    handleSelectionChange(selectTable) {
      this.$emit("onSelectionChange", selectTable);
    },
    /**
     * 触发操作事件
     * 参数1：当前按钮索引
     * 参数2：当前按钮所在行数据
     */
    funcEmit(row, item) {
      this.$emit("onFunc", row, item, this.tableInfo.tableData);
    },
    // 排序改变 	降序:descending;升序ascending
    sortChange(column) {
      this.$emit("sortChange", column);
    },
    //单选
    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() {
      this.$emit("newRow", this.tableInfo);
      this.$nextTick(() => {
        this.$refs.elTable.bodyWrapper.scrollTop =
          this.$refs.elTable.bodyWrapper.scrollHeight;
        this.setTableKey();
      });
    },
    //行拖拽,排序方法
    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) => {
          // console.log(evt,"evt")
          //   console.log(evt.oldIndex, "oldIndex");
          // console.log(this.tableData)
          // console.log(evt.oldIndex, this.tableData.splice(evt.oldIndex, 1))
          const targetRow = this.tableData.splice(evt.oldIndex, 1)[0];
          //   console.log(targetRow, "targetRow");
          //   console.log(evt.newIndex, "newIndex");
          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();
      }
    },
    // 合计
    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] = "";
            }
          }
        });
      });
      return sums;
    },
  },
  components: {
    BaseSelect,
    BaseDatePicker,
    baseCascader,
  },
};
</script>

<style>
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
}
.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">
>>> .el-radio__label {
  // display: none;
}

.btnText {
  cursor: pointer;
}

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

::v-deep .cell {
  font-weight: 400;
  display: flex;
  align-items: center;
}
::v-deep .el-table__row {
  height: 60px !important;
  background-color: #fcfcfc;
}
// ::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; } }
</style>
