<script>
import axios from "axios";
import { getToken } from "@/utils/auth";
export default {
  props: {
    //请求相关
    action: [String, Function], //String传入请求地址 Function传入返回promise的方法
    destroyAction: [Function], //删除promise方法
    delayReq: {
      type: Boolean,
      default: false
    },//created获取数据时，是否等select条件传入后再请求
    isFirstReq: {
      type: Boolean,
      default: true
    },//created时是否请求
    reqOpt: Object, //请求参数配置
    destroyReqOpt:Object,
    resProp: {
      type: String,
      default: "data",
    }, //请求后需要获取表格数据键名

    isHandlerKey: {
      type: Boolean,
      default: true
    },//是否每次有数据跟新时会刷新表格key从而刷新视图（取消sort优化，标题不会频闪）

    //操作权限
    auths: {
      type: Array,
      default: () => [],
    },

    //table props
    /**
     * @type {Array}
     * [
     *   {
     *     type: ("selection"|"index"|"expand"),
     *     index: [Number,Function(index)], //type=index,通过传递 index 属性来自定义索引
     *     columnKey: "", //column 的 key，如果需要使用 filter-change 事件，则需要此属性标识是哪个 column 的筛选条件
     *     label: "",
     *     prop: "",
     *     width: "",
     *     minWidth: "",
     *     fixed: ("true"| "left"| "right"),
     *     renderHeader:(h, { column, $index}) => {
     *     },
     *     sortable:[Boolean,String] (true|false|"custom"),//custom需监听 Table 的 sort-change 事件
     *     sortMethod: (a,b) => {}, //对数据进行排序的时候使用的方法，仅当 sortable 设置为 true 的时候有效，需返回一个数字，和 Array.sort 表现一致
     *     sortBy:[String,Array,Function(row, index)],//指定数据按照哪个属性进行排序，仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。如果 sort-by 为数组，则先按照第 1 个属性排序，如果第 1 个相等，再按照第 2 个排序，以此类推
     *     sortOrders:[Array] (['ascending', 'descending', null]),//数据在排序时所使用排序策略的轮转顺序，仅当 sortable 为 true 时有效
     *     resizable:[Boolean], //需要在 el-table 上设置 border 属性为真
     *     formatter:[Function(row, column, cellValue, index)],
     *     showOverflowTooltip:[Boolean],
     *     align: ("left","center","right"),
     *     headerAlign:	("left","center","right"),
     *     className:[String],
     *     labelClassName:[String],
     *     selectable:[Function(row, index)],//仅对 type=selection 的列有效，类型为 Function，Function 的返回值用来决定这一行的 CheckBox 是否可以勾选
     *     reserveSelection:[Boolean],//仅对 type=selection 的列有效，类型为 Boolean，为 true 则会在数据更新之后保留之前选中的数据（需指定 row-key）
     *     filters:[Array[{ text, value }]],
     *     filterPlacement:[String],
     *     filterMultiple:[Boolean],
     *     filterMethod:[Function(value, row, column)],
     *     filteredValue:[Array]
     *   }
     * ]
     */
    tableItem: {
      type: Array,
      default: () => [],
    },
    //数据
    list: {
      type: Array,
      default: () => [],
    },
    height: {
      type: [String, Number],
    },
    maxHeight: [String, Number],
    //斑马纹
    stripe: {
      type: Boolean,
      default: false,
    },
    //是否带有纵向边框
    border: {
      type: Boolean,
      default: true,
    },
    size: String, // medium / small / mini
    fit: {
      type: Boolean,
      default: true,
    },
    showHeader: {
      type: Boolean,
      default: true,
    },
    highlightCurrentRow: {
      type: Boolean,
      default: true,
    },
    currentRowKey: [String, Number],
    rowClassName: [Function, String],
    rowStyle: [Function, Object],
    cellClassName: [Function, String],
    cellStyle: [Function, Object],
    headerRowClassName: [Function, String],
    headerRowStyle: [Function, Object],
    headerCellClassName: [Function, String],
    headerCellStyle: [Function, Object],
    rowKey: {
      type: [String, Function],
      default: "id",
    },
    emptyText: String,
    defaultExpandAll: {
      type: Boolean,
      default: true,
    },
    expandRowKeys: Array, //可以通过该属性设置 Table 目前的展开行，需要设置 row-key 属性才能使用，该属性为展开行的 keys 数组。
    defaultSort: Object, //默认的排序列的 prop 和顺序。它的prop属性指定默认的排序的列，order指定默认排序的顺序（order: ascending, descending）
    tooltipEffect: String,
    showSummary: {
      type: Boolean,
      default: false,
    },
    sumText: {
      type: String,
      default: "合计",
    },
    summaryMethod: Function, //Function({ columns, data })
    spanMethod: Function,
    selectOnIndeterminate: Boolean,
    //展示树形数据时，树节点的缩进
    indent: {
      type: Number,
      default: 18,
    },
    lazy: Boolean,
    load: Function, //Function(row, treeNode, resolve)
    treeProps: {
      type: Object,
      default: () => {
        return { children: "children", hasChildren: "hasChildren" };
      },
    },

    tableStyle: {
      type: Object,
      default: () => {
        return { width: "100%", marginBottom: "20px" };
      },
    },
    btnToMore: {
      type: Boolean,
      default: false
    },
    moreAuths: {
      type: Array,
      default: () => ['edit','delete']
    },
    btnWidth: {
      type: Number,
      default: 220,
    },

    //  分页相关
    isPage: {
      type: Boolean,
      default: true,
    },
    total: {
      type: Number,
      default: 0,
    },
    pageSize: {
      type: Number,
    },
    pageSizeOpts: {
      type: Array,
      default: () => [10, 20, 30, 40],
    },
    showSizer: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      isBtns: false,
      tableHeight: null,
      //document.documentElement.clientHeight -50 -37 - 20- 25 - 76,
      isShowPage: true,
      checkTable: this.tableItem.map((item) => item?.prop),
      loading: false,
      visibleBtn: true, //操作按钮显示
      sortFlag:0,

      totalData: 0,
      listData: [],
      selectOpt: {
        page: 1,
        page_size: 10,
        sort_name: "",
        sort_type: "",
      },
    };
  },
  methods: {
    //方法
    initLoad() {
      if (this.height) return;
      let clientHeight = document.documentElement.clientHeight;
      let lxheader = document.querySelector(".v-header")?.getBoundingClientRect();
      let lxHeader_height = lxheader.height + 25; //查询 头部
      let paginationHeight = 37; //分页的高度
      let topHeight = 50; //页面 头部
      this.tableHeight =
        clientHeight - lxHeader_height - topHeight - paginationHeight - 20 - 25;
      //console.log(this.tableHeight)
    },
    async getTableData(isRefresh = false) {
      if (isRefresh) {
        this.selectOpt.page = 1;
      }
      setTimeout(() => {
        switch (typeof this.action) {
          case "string":
            this.loading = true;
            axios({
              baseURL: process.env.VUE_APP_BASE_API,
              url: this.action,
              headers: {
                Authorization: "Bearer " + getToken(),
              },
              params:
                this.reqOpt.method && this.reqOpt.method === "get"
                  ? this.selectOpt
                  : "",
              data:
                this.reqOpt.method && this.reqOpt.method === "post"
                  ? this.selectOpt
                  : "",
              ...this.reqOpt,
            })
              .then((res) => {
                this.listData = this.getByStrkey(res.data, this.resProp);
                this.totalData = res.data.total;
                this.$emit('loaded')
                setTimeout(() => {
                  this.loading = false;

                }, 300);
              })
              .catch((err) => {
                console.error(err);
                this.loading = false;
              });
            break;
          case "function":
            this.loading = true;
            this.action({
              ...this.selectOpt,
              ...this.reqOpt,
            },false)
              .then((res) => {
                this.listData = this.getByStrkey(res, this.resProp);
                this.totalData = res.total;
                this.$emit('loaded')
                setTimeout(() => {
                  this.loading = false;

                }, 300);
              })
              .catch((err) => {
                console.error(err);
                this.loading = false;
              });
            break;
          case "undefined":
            break
          default:
            console.error("ACTION TYPE ERROR")
            return;
        }
      })
    },
    getByStrkey(obj, str) {
      if (!str) return obj;
      let res = this.deepCopy(obj);
      let keys = str.split(".");
      keys.forEach((key) => {
        res = res[key];
      });
      return res;
    },
    deepCopy(data) {
      //string,number,bool,null,undefined,symbol
      //object,array,date
      if (data && typeof data === "object") {
        //针对函数的拷贝
        if (typeof data === "function") {
          let tempFunc = data.bind(null);
          tempFunc.prototype = this.deepCopy(data.prototype);
          return tempFunc;
        }

        switch (Object.prototype.toString.call(data)) {
          case "[object String]":
            return data.toString();
          case "[object Number]":
            return Number(data.toString());
          case "[object Boolean]":
            return new Boolean(data.toString());
          case "[object Date]":
            return new Date(data.getTime());
          case "[object Array]":
            let arr = [];
            for (let i = 0; i < data.length; i++) {
              arr[i] = this.deepCopy(data[i]);
            }
            return arr;

          //js自带对象或用户自定义类实例
          case "[object Object]":
            let obj = {};
            for (let key in data) {
              //会遍历原型链上的属性方法，可以用hasOwnProperty来控制 （obj.hasOwnProperty(prop)
              obj[key] = this.deepCopy(data[key]);
            }
            return obj;
        }
      } else {
        //string,number,bool,null,undefined,symbol
        return data;
      }
    },
    sortListener({ column, prop, order }) {
      if(prop === this.selectOpt.sort_name){
        this.sortFlag ++
      }else{
        this.sortFlag = 0
      }
      this.selectOpt.page = 1;
      this.selectOpt.sort_name = prop;
      this.selectOpt.sort_type = ['ASC','DESC',null][this.sortFlag % 3]
      // TODO: 优化
      // switch (order) {
      //   case "ascending":
      //     this.selectOpt.sort_type = "ASC";
      //     break;
      //   case "descending":
      //     this.selectOpt.sort_type = "DESC";
      //     break;
      //   default:
      //     this.selectOpt.sort_type = "";
      // }
      this.getTableData();
    },

    //element table方法
    clearSelection() {
      this.$refs.table.clearSelection();
    },
    toggleRowSelection(row) {
      this.$nextTick(() => {
        this.$refs.table.toggleRowSelection(row);
      });
    },
    toggleAllSelection() {
      this.$refs.table.toggleAllSelection();
    },
    toggleRowExpansion(row, expanded = true) {
      this.$refs.table.toggleRowExpansion(row, expanded);
    },
    setCurrentRow(row) {
      this.$refs.table.setCurrentRow(row);
    },
    clearSort() {
      this.$refs.table.clearSort();
    },
    clearFilter() {
      this.$refs.table.clearFilter();
    },
    doLayout() {
      this.$refs.table.doLayout();
    },
    sort() {
      this.$refs.table.sort();
    },
    getSelection(){
      return this.$refs.table?.store?.states?.selection ?? []
    },
    getListData () {
      return this.listData
    },

    //table通讯事件
    delete(row, type) {
      this.$emit(type, row);
    },
    editor(row, type) {
      this.$emit(type, row);
    },
    select(selection, row) {
      this.$emit("select", selection, row);
    },
    selectAll(selection) {
      this.$emit("select-all", selection);
    },
    selectionChange(selection) {
      this.$emit("selection-change", selection);
    },
    cellMouseEnter(row, column, cell, event) {
      this.$emit("cell-mouse-enter", { row, column, cell, event });
    },
    cellMouseLeave(row, column, cell, event) {
      this.$emit("cell-mouse-leave", { row, column, cell, event });
    },
    cellClick(row, column, cell, event) {
      this.$emit("cell-click", { row, column, cell, event });
    },
    cellDblclick(row, column, cell, event) {
      this.$emit("cell-dblclick", { row, column, cell, event });
    },
    rowClick(row, column, event) {
      this.$emit("row-click", { row, column, event });
    },
    rowContextmenu(row, column, event) {
      this.$emit("row-contextmenu", { row, column, event });
    },
    rowDblclick(row, column, event) {
      this.$emit("row-dblclick", { row, column, event });
    },
    headerClick(column, event) {
      this.$emit("header-click", column, event);
    },
    headerContextmenu(column, event) {
      this.$emit("header-contextmenu", column, event);
    },
    sortChange({ column, prop, order }) {
      this.$emit("sort-change", { column, prop, order });
    },
    filterChange(filters) {
      this.$emit("filter-change", filters);
    },
    currentChange(currentRow, oldCurrentRow) {
      this.$emit("current-change", currentRow, oldCurrentRow);
    },
    headerDragend(newWidth, oldWidth, column, event) {
      this.$emit("header-dragend", { newWidth, oldWidth, column, event });
    },
    expandChange(row, expanded) {
      this.$emit("expand-change", row, expanded);
    },

    deleteClick(row) {
      this.$emit("delete", row);
      if (this.destroyAction) {
        this.destroyAction({
          id: row.id,
          ...this.destroyReqOpt
        },false).then((res) => {
          this.$message({
            type: "success",
            message: "删除成功",
          });
          if(this.action)this.getTableData();
          this.$emit('destroyed',row)
        });
      }
    },
    editorClick(row) {
      this.$emit("editor", row);
    },

    createPage() {
      if (this.isPage)
        return (
          <div>
            <transition
              enter-active-class="slide-in-bottom"
              leave-to-class="slide-out-down"
            >
              <Page
                page-size-opts={this.pageSizeOpts}
                show-total={true}
                page-size={this.pageSize}
                v-show={this.isShowPage}
                total={
                  this.action
                    ? this.totalData || this.listData.length
                    : this.total
                }
                size="small"
                show-elevator={true}
                show-sizer={this.showSizer}
                class="xy-table__page"
                on={{
                  ["on-page-size-change"]: (e) => {
                    if (this.action) {
                      this.selectOpt.page_size = e;
                      this.selectOpt.page = 1;
                      this.getTableData();
                    }
                    this.$emit("pageSizeChange", e);
                  },
                  ["on-change"]: (e) => {
                    if (this.action) {
                      this.selectOpt.page = e;
                      this.getTableData();
                    }
                    this.$emit("pageIndexChange", e);
                  },
                }}
              ></Page>
            </transition>

            <el-popover
              placement="top-start"
              width="200"
              trigger="hover"
              scopedSlots={{
                default: () => {
                  return (
                    <el-checkbox-group v-model={this.checkTable}>
                      {this.$props?.tableItem?.map((item, index) => {
                        return item.type !== "expand" ? (
                          <el-checkbox label={item.prop} key={item.prop}>
                            {item.label}
                          </el-checkbox>
                        ) : (
                          ""
                        );
                      })}
                    </el-checkbox-group>
                  );
                },
              }}
            >
              <el-button
                slot="reference"
                size="mini"
                type="primary"
                class="xy-table__setting"
                icon="el-icon-s-tools"
                circle
                style={{
                  padding: "3px",
                }}
              ></el-button>
            </el-popover>
          </div>
        );
    },

    isCreateAuthBtns() {
      let _this = this;
      let res = (
        <el-table-column
          key={`xy-table-btn`}
          fixed="right"
          label="操作"
          minWidth={_this.btnWidth}
          header-align="center"
          scopedSlots={{
            default: (scope) => {
              if (_this.auths?.length <= 0) return;
              let { dom, flag } = _this.createAuthBtns(scope);
              _this.isBtns = flag;
              return dom;
            },
          }}
        ></el-table-column>
      );
      if (_this.isBtns !== 0) {
        return res;
      }
    },
    createAuthBtns(scope) {
      let _this = this;
      if (_this.auths?.length > 0) {
        let btns = new Map();
        btns.set(
          "more",
          <el-dropdown size="small" type="primary" placement="bottom" on={{
            ['command']:command => {
              if (command === 'edit') {
                this.editorClick(scope.row)
              }
              else if (command === 'delete') {
                let that = this
                this.$confirm("确认删除吗？",{
                  beforeClose(action,instance,done){
                    if (action === 'confirm') {
                      that.deleteClick(scope.row);
                      done();
                    } else {
                      done();
                    }
                  }
                }).then(res => {
                  this.$message({
                    type: 'success',
                    message: '删除成功'
                  })
                  this.load()
                })
              } else {
                this.$emit(command, scope.row)
              }
            }
          }}>
            <i-button
              type="default"
              size="small"
              style="margin-left: 6px;"
            >
              更多
            </i-button>

            <el-dropdown-menu slot="dropdown">
              {
                (() => {
                  let dom = [];

                  this.moreAuths.forEach(i => {
                    if (this.auths.indexOf(i) !== -1) {
                      this.$scopedSlots[i] ? dom.push((<el-dropdown-item command={i}>{ this.$scopedSlots[i](scope) }</el-dropdown-item>)) : ''
                    }
                  })

                  if (this.auths.indexOf('edit') !== -1) {
                    dom.push(<el-dropdown-item divided command="edit">编辑</el-dropdown-item>)
                  }
                  if (this.auths.indexOf('delete') !== -1) {
                    dom.push(<el-dropdown-item command="delete"><span style="color: red;">删除</span></el-dropdown-item>)
                  }
                  return dom;
                })()
              }
            </el-dropdown-menu>
          </el-dropdown>
        )
        btns.set(
          "detail",
          <i-button
            type="primary"
            size="small"
            ghost={true}
            onClick={() => _this.$emit('detail', scope.row, scope)}
          >
            查看
          </i-button>
        )
        btns.set(
          "edit",
          <i-button
            type="primary"
            size="small"
            onClick={() => _this.editorClick(scope.row, "edit")}
          >
            编辑
          </i-button>
        );
        btns.set(
          "delete",
          <el-popover width="180"
                      trigger="hover"
                      ref={`${scope.column.id}-${scope.$index}`}
                      scopedSlots={{
                        "default": () => {
                          return (
                            <div>
                              <p style={{'padding-bottom':'10px'}}>确定要删除吗？</p>
                              <div style={{"text-align":"right","margin":"0"}}>
                                <el-button size="mini"
                                           type="text"
                                           on={{
                                             ['click']:e => {
                                               this.$refs[`${scope.column.id}-${scope.$index}`].doClose()
                                             }
                                           }}>取消</el-button>
                                <el-button type="primary"
                                           size="mini"
                                           on={{
                                             ['click']:() => _this.deleteClick(scope.row, "delete")
                                           }}>确定</el-button>
                              </div>
                            </div>
                          )
                        },
                        "reference":() => {
                          return (
                            <div style={{ "margin-right": "6px","height":"100%","width":"100%"}}>
                              <i-button

                                type="error"
                                size="small"
                                on={{
                                  ['click']:e => {
                                    this.$refs[`${scope.column.id}-${scope.$index}`].doShow()
                                  }
                                }}
                              >
                                删除
                              </i-button>
                            </div>
                          )
                        }
                      }}>

          </el-popover>
          // <Poptip
          //   transfer={true}
          //   confirm
          //   title="确认要删除吗"
          //   on={{ ["on-ok"]: () => _this.deleteClick(scope.row, "delete") }}
          // >
          //   <i-button
          //     style={{
          //       "margin-right": "6px",
          //     }}
          //     type="error"
          //     size="small"
          //   >
          //     删除
          //   </i-button>
          // </Poptip>
        );
        let flag = 0;
        let dom = (
          <div
            style={{
              display: "flex",
              "justify-content": "flex-start",
              "align-items": "center",
              "flex-wrap": "wrap",
            }}
          >
            { (() => {
              let dom = [];
              _this.auths.forEach((item, index) => {
                if ((_this.btnToMore || _this.auths.length > 5) && _this.moreAuths.find(j => j === item)) return
                if (_this.$scopedSlots[item]) {
                  flag = index;
                  dom.push(_this.$scopedSlots[item](scope, item, index));
                } else {
                  if (btns.get(item)) {
                    flag = index;
                    dom.push(btns.get(item));
                  }
                }
              })

              if (_this.auths.length > 5 || _this.btnToMore) {
                dom.push(btns.get('more'))
              }

              return dom;
            })() }
          </div>
        );
        return { dom, flag };
      }
    },
  },
  computed: {
    tableFormat() {
      return this.tableItem.filter((item) => {
        return this.checkTable.indexOf(item.prop) !== -1;
      });
    },
  },
  watch:{
    tableItem(newVal){
      this.checkTable = newVal.map((item) => item?.prop)
    },
  },
  created() {
    if (this.isFirstReq) {
      if(this.delayReq) {
        let watch = this.$watch(()=>this.reqOpt,async (newVal,oldVal)=>{
          if(this.action) {
            await this.getTableData();
            watch();
          }
        },{
          deep: true,
          immediate: true
        })
      } else {
        if(this.action) this.getTableData();
      }
    }
  },
  mounted() {
    this.initLoad();
  },
  updated() {
    this.$nextTick(() => {
      this.doLayout();
    });
  },
  render(h) {
    let { $scopedSlots } = this;
    return (
      <div class="table-tree" style={{ position: "relative" }}>
        {this.tableItem && this.tableItem.length > 0 ? (
          <el-table
            class="v-table"
            v-loading={this.loading}
            ref="table"
            data={this.action ? this.listData : this.list}
            height={this.height ?? this.tableHeight}
            max-height={this.maxHeight}
            stripe={this.stripe}
            border={this.border}
            size={this.size}
            fit={this.fit}
            show-header={this.showHeader}
            highlight-current-row={this.highlightCurrentRow}
            current-row-key={this.currentRowKey}
            row-class-name={this.rowClassName}
            row-style={this.rowStyle}
            cell-class-name={this.cellClassName}
            cell-style={this.cellStyle}
            header-row-class-name={this.headerRowClassName}
            header-row-style={this.headerRowStyle}
            header-cell-class-name={this.headerCellClassName}
            header-cell-style={this.headerCellStyle}
            row-key={this.rowKey}
            empty-text={this.emptyText}
            default-expand-all={this.defaultExpandAll}
            expand-row-keys={this.expandRowKeys}
            default-sort={this.defaultSort}
            tooltip-effect={this.tooltipEffect}
            show-summary={this.showSummary}
            sum-text={this.sumText}
            summary-method={this.summaryMethod}
            span-method={this.spanMethod}
            select-on-indeterminate={this.selectOnIndeterminate}
            indent={this.indent}
            lazy={this.lazy}
            load={this.load}
            tree-props={this.treeProps}
            on={{
              ["select"]: this.select,
              ["select-all"]: this.selectAll,
              ["selection-change"]: this.selectionChange,
              ["cell-mouse-enter"]: this.cellMouseEnter,
              ["cell-mouse-leave"]: this.cellMouseLeave,
              ["cell-click"]: this.cellClick,
              ["cell-dblclick"]: this.cellDblclick,
              ["row-click"]: this.rowClick,
              ["row-contextmenu"]: this.rowContextmenu,
              ["row-dblclick"]: this.rowDblclick,
              ["header-click"]: this.headerClick,
              ["header-contextmenu"]: this.headerContextmenu,
              ["sort-change"]: this.action
                ? this.sortListener
                : this.sortChange,
              ["filter-change"]: this.filterChange,
              ["current-change"]: this.currentChange,
              ["header-dragend"]: this.headerDragend,
              ["expand-change"]: this.expandChange,
            }}
          >
            {this.tableFormat.map((item, index) => {
              if ($scopedSlots[item.prop]) {
                return $scopedSlots[item.prop](item, index);
              }
              return (
                <af-table-column
                  // TODO: 随机key值与sort优化问题
                  //key={`xy-table-col-${item.prop}`}
                  key={this.isHandlerKey ? String(Math.random()) + index : index}
                  type={item.type}
                  index={item.index}
                  //column-key={`xy-table-column-${item.prop}`}
                  column-key={String(Math.random())}
                  label={item.label}
                  prop={item.prop}
                  width={item.width}
                  min-width={item.minWidth}
                  fixed={item.fixed ?? false}
                  render-header={item.renderHeader}
                  sortable={item.sortable}
                  sort-method={item.sortMethod}
                  sort-by={item.sortBy}
                  sort-orders={item.sortOrders}
                  resizale={item.resizale}
                  formatter={item.formatter}
                  show-overflow-tooltip={item.showOverflowTooltip ?? true}
                  align={item.align ?? "center"}
                  header-align={item.headerAlign ?? "center"}
                  class-name={`xy-table__row-fade ${item.className} body-cell-${index}`}
                  label-class-name={`xy-table__title-fade ${item.labelClassName} header-cell-${index}`}
                  selectable={item.selectable}
                  reserve-selection={item.reserveSelection}
                  filters={item.filters}
                  filter-placement={item.filterPlacement}
                  filter-multiple={item.filterMultiple}
                  filter-method={item.filterMethod}
                  filtered-value={item.filteredValue}
                  scopedSlots={
                    item.customFn || item.type === "expand"
                      ? {
                        default(scope) {
                          if (item.type === "expand") {
                            return item.expandFn(scope);
                          }
                          if (item.customFn) {
                            return item.customFn(scope.row, scope);
                          }
                        },
                      }
                      : ""
                  }
                >
                  {item.multiHd
                    ? item.multiHd.map((item1, index1) => {
                      return (
                        <af-table-column
                          //key={`xy-table-col-multi-${item1.prop}`}
                          key={String(Math.random()) + index1}
                          prop={`${item.pProp ? item.pProp + "." : ""}${
                            item1.prop
                          }`}
                          type={item1.type}
                          index={item1.index}
                          column-key={String(Math.random() + index1)}
                          label={item1.label}
                          prop={item1.prop}
                          width={item1.width ?? "auto"}
                          min-width={item1.minWidth}
                          fixed={item1.fixed}
                          render-header={item1.renderHeader}
                          sortable={item1.sortable ?? false}
                          sort-method={item1.sortMethod}
                          sort-by={item1.sortBy}
                          sort-orders={item1.sortOrders}
                          resizale={item1.resizale ?? false}
                          formatter={item1.formatter}
                          show-overflow-tooltip={
                            item1.showOverflowTooltip ?? true
                          }
                          align={item1.align ?? "center"}
                          header-align={item1.headerAlign ?? "center"}
                          class-name={`xy-table__row-fade ${item1.className}`}
                          label-class-name={`xy-table__title-fade ${item1.labelClassName}`}
                          selectable={item1.selectable}
                          reserve-selection={item1.reserveSelection}
                          filters={item1.filters}
                          filter-placement={item1.filterPlacement}
                          filter-multiple={item1.filterMultiple}
                          filter-method={item1.filterMethod}
                          filtered-value={item1.filteredValue}
                          scopedSlots={
                            item1.customFn
                              ? {
                                default(scope1) {
                                  return item1.customFn(scope1);
                                },
                              }
                              : ""
                          }
                        ></af-table-column>
                      );
                    })
                    : ""}
                </af-table-column>
              );
            })}
            {
              $scopedSlots.btns ? $scopedSlots.btns() : (this.auths.length > 0 ? this.isCreateAuthBtns() : '')
            }
          </el-table>
        ) : (
          <el-table ref="table" v-loading={this.loading} height={this.height ?? this.tableHeight} />
        )}

        <el-backtop
          target=".el-table__body-wrapper"
          visibility-height={120}
          bottom={100}
          right={36}
        ></el-backtop>
        {this.createPage()}
      </div>
    );
  },
};
</script>

<style lang="scss" scoped>
@import "../../styles/variables.scss";

::v-deep .el-table {
  margin-bottom: 0 !important;

}
.xy-table__setting {
  font-size: 14px;

  position: absolute;
  z-index: 99;
  bottom: 7px;
  left: 10px;
}
.xy-table__page {
  display: flex;
  justify-content: right;
  align-items: center;
  border-bottom-right-radius: 4px;
  border-bottom-left-radius: 4px;
  background: rgba(140, 140, 140, 0.6);

  z-index: 10;
  padding: 6px 10px !important;
  position: relative;
  top: 0;
  left: 0;
  right: 0;

  ::v-deep .ivu-page-item,
  .ivu-page-options {
    background: transparent !important;
  }

  ::v-deep .ivu-page-item a {
    color: #fff;
  }

  ::v-deep .ivu-page-item-active a {
    color: $primaryColor;
  }

  ::v-deep .ivu-page-total {
    color: #fff !important;
  }

  ::v-deep .ivu-page-options-elevator {
    color: #fff !important;
  }

  @media (max-width: 600px) {
    ::v-deep .ivu-page-options {
      display: none !important;
    }
  }
}

.slide-in-bottom {
  transform-origin: 0 100%;
  animation: slide-in-bottom 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}

@keyframes slide-in-bottom {
  0% {
    transform: scaleY(0);
    opacity: 0;
  }
  100% {
    transform: scaleY(1);
    opacity: 1;
  }
}

.slide-out-down {
  transform-origin: 0 100%;
  animation: slide-out-down 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}

@keyframes slide-out-down {
  0% {
    transform: scaleY(1);
    opacity: 1;
  }
  100% {
    transform: scaleY(0);
    opacity: 0;
  }
}

.icon-scale-left {
  animation: icon-scale-left 0.5s forwards ease-out;
  @keyframes icon-scale-left {
    from {
    }
    to {
      clip-path: polygon(0 30%, 100% 30%, 100% 100%, 0 100%);
      background: rgba(140, 140, 140, 0.7);
      transform: scale(0.8, 0.8) translateX(-22px) translateY(-10px)
      rotate(-90deg);
    }
  }
}

.icon-recover {
  animation: icon-recover 0.5s forwards ease-out;
  @keyframes icon-recover {
    from {
      background: rgba(120, 120, 120, 0.8);
      transform: scale(0.8, 0.8) translateX(-30px) rotate(-90deg);
    }
    to {
    }
  }
}
</style>

<style>
.xy-table__row-fade {
  animation: fade-in-row 600ms;
}
@keyframes fade-in-row {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
  }
}
.xy-table__title-fade {
  animation: fade-in-title 600ms;
}
@keyframes fade-in-title {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

Button + Button {
  margin-left: 6px;
}
</style>
