<!-- 
/* @name    表格组件
 * @authors pen (you@example.org)
 * @date    2022-02-28 
 * @version 2.0.1
 */
 -->
 <template>
  <el-table
    class="table_view"
    ref="table"
    v-bind="$attrs"
    v-on="$listeners"
    @row-click="rowClick"
    :data="filterData()"
    :border="border"
    :size="tableSize"
    :height="height"
    style="width: 100%"
  >
    <slot name="frontColumns"></slot>
    <template v-for="(column, index) in columns">
      <!-- 抛出点击跳转方法的点击列 -->
      <el-table-column
        v-if="
          column.showCellLink &&
          (column.visible || column.visible === undefined)
        "
        :type="column.type"
        :label="column.label"
        :class-name="column.className"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        :label-class-name="column.labelClassName"
        :prop="Array.isArray(columns) ? column.name : index"
        :width="column.width"
        :min-width="column.minWidth"
        :sortable="column.sortable"
        :sort-method="column.sortMethod"
        :sort-by="column.sortBy"
        :resizable="column.resizable"
        :column-key="column.columnKey"
        :align="column.align"
        :header-align="column.headerAlign"
        :show-tooltip-when-overflow="column.showTooltipWhenOverflow"
        :show-overflow-tooltip="
          column.showOverflowTooltip === undefined
            ? true
            : column.showOverflowTooltip
        "
        :fixed="column.fixed"
        :formatter="column.formatter"
        :selectable="column.selectable"
        :reserve-selection="column.reserveSelection"
        :filter-method="column.filterMethod"
        :filters="column.filters"
        :filter-placement="column.filterPlacement"
        :filter-multiple="column.filterMultiple"
        :index="column.index"
        :key="column.columnKey"
      >
        <template v-if="column.showFilterHead" #header>
          <table-head-filter-view
            ref="headFilter"
            :column="column"
            :headFilterArray="headFilterArray(column)"
            @on-filter-comfirm="onFilterComfirm"
          />
        </template>
        <template slot-scope="scope">
          <span>
            <el-link type="primary" @click="cellLinkEvent(scope.row)">
              {{ scope.row[Array.isArray(columns) ? column.name : index] }}
            </el-link>
          </span>
        </template>
      </el-table-column>
      <!-- 图片显示列 -->
      <el-table-column
        v-if="
          column.showImg && (column.visible || column.visible === undefined)
        "
        :type="column.type"
        :label="column.label"
        :class-name="column.className"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        :label-class-name="column.labelClassName"
        :prop="Array.isArray(columns) ? column.name : index"
        :width="column.width"
        :min-width="column.minWidth"
        :sortable="column.sortable"
        :sort-method="column.sortMethod"
        :sort-by="column.sortBy"
        :resizable="column.resizable"
        :column-key="column.columnKey"
        :align="column.align"
        :header-align="column.headerAlign"
        :show-tooltip-when-overflow="column.showTooltipWhenOverflow"
        :show-overflow-tooltip="
          column.showOverflowTooltip === undefined
            ? true
            : column.showOverflowTooltip
        "
        :fixed="column.fixed"
        :formatter="column.formatter"
        :selectable="column.selectable"
        :reserve-selection="column.reserveSelection"
        :filter-method="column.filterMethod"
        d:filters="column.filters"
        :filter-placement="column.filterPlacement"
        :filter-multiple="column.filterMultiple"
        :index="column.index"
        :key="column.columnKey"
      >
        <template slot-scope="scope">
          <!-- 表格显示图片组件 -->
          <table-img-view
            :popImgUrl="column.popImgUrl"
            :imgUrl="scope.row[Array.isArray(columns) ? column.name : index]"
            :defaultImg="column.defaultImg"
            :popoverImgStyle="column.popoverImgStyle"
            :tableImgStyle="column.tableImgStyle"
          ></table-img-view>
        </template>
      </el-table-column>

      <!-- 可显示状态tag的状态列 -->
      <el-table-column
        v-if="
          column.stateTagData &&
          (column.visible || column.visible === undefined)
        "
        :type="column.type"
        :label="column.label"
        :class-name="column.className"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        :label-class-name="column.labelClassName"
        :prop="Array.isArray(columns) ? column.name : index"
        :width="column.width"
        :min-width="column.minWidth"
        :sortable="column.sortable"
        :sort-method="column.sortMethod"
        :sort-by="column.sortBy"
        :resizable="column.resizable"
        :column-key="column.columnKey"
        :align="column.align"
        :header-align="column.headerAlign"
        :show-tooltip-when-overflow="column.showTooltipWhenOverflow"
        :show-overflow-tooltip="
          column.showOverflowTooltip === undefined
            ? true
            : column.showOverflowTooltip
        "
        :fixed="column.fixed"
        :formatter="column.formatter"
        :selectable="column.selectable"
        :reserve-selection="column.reserveSelection"
        :filter-method="column.filterMethod"
        :filters="column.filters"
        :filter-placement="column.filterPlacement"
        :filter-multiple="column.filterMultiple"
        :index="column.index"
        :key="column.columnKey"
      >
        <template v-if="column.showFilterHead" #header>
          <table-head-filter-view
            ref="headFilter"
            :column="column"
            :headFilterArray="headFilterArray(column)"
            @on-filter-comfirm="onFilterComfirm"
          />
        </template>
        <template slot-scope="scope">
          <span class="table_tag">
            <span
              class="custom_column_cricle"
              :style="{ background: columnBackground(column, scope) }"
            ></span>
            {{
              scope.row[column.stateTagData.showName] ||
              scope.row[column.stateTagData.judgeName] ||
              ''
            }}
          </span>
          <!-- 配置数据格式
                          stateTagData:{
                              showName:'auditStatusCn'
                              judgeName:'auditStatus',
                              judgeValue:{
                                  'pass':{
                                      type:'success',
                                      color:'#58bc58'
                                      },
                                  'wait':{
                                      type:'danger',
                                      color:'#ccc'
                                  }
                              }
                          }
                       -->
        </template>
      </el-table-column>
      <!-- 操作列 -->
      <el-table-column
        v-else-if="
          column.toolbarData &&
          column.toolbarData.length &&
          ((typeof column.visible === 'function' &&
            column.visible(scope.row)) ||
            column.visible ||
            column.visible === undefined)
        "
        :type="column.type"
        :label="column.label || '操作'"
        :class-name="column.className"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        :label-class-name="column.labelClassName"
        :prop="Array.isArray(columns) ? column.name : index"
        :width="column.width"
        :min-width="column.minWidth"
        :sortable="column.sortable"
        :sort-method="column.sortMethod"
        :sort-by="column.sortBy"
        :resizable="column.resizable"
        :column-key="column.columnKey"
        :align="column.align"
        :header-align="column.headerAlign"
        :show-tooltip-when-overflow="column.showTooltipWhenOverflow"
        :show-overflow-tooltip="
          column.showOverflowTooltip === undefined
            ? true
            : column.showOverflowTooltip
        "
        :fixed="column.fixed"
        :formatter="column.formatter"
        :selectable="column.selectable"
        :reserve-selection="column.reserveSelection"
        :filter-method="column.filterMethod"
        :filters="column.filters"
        :filter-placement="column.filterPlacement"
        :filter-multiple="column.filterMultiple"
        :index="column.index"
        :key="column.columnKey"
      >
        <template slot-scope="scope">
          <div class="tools_box">
            <el-link
              class="column_toolbar_link"
              v-for="(item, index) in column.toolbarData.filter(p =>
                judgePrem(p, scope.row)
              ).length > 3
                ? column.toolbarData
                    .filter(p => judgePrem(p, scope.row))
                    .slice(0, 2)
                : column.toolbarData.filter(p => judgePrem(p, scope.row))"
              v-if="judgePrem(item, scope.row)"
              :key="index"
              :underline="false"
              :href="item.href"
              :icon="item.icon"
              :type="item.type"
              @click="toolbarClick(scope.row, item, index)"
              :disabled="
                (typeof item.isDisabled === 'function' &&
                  item.isDisabled(scope.row)) ||
                item.disabled
              "
              :style="item.style"
              >{{ item.text }}</el-link
            >
          </div>
          <!-- 显示更多操作按钮 -->
          <table-more-operate-view
            v-if="
              column.toolbarData.filter(p => judgePrem(p, scope.row)).length > 3
            "
            :TableMoreOperateData="
              column.toolbarData.filter(p => judgePrem(p, scope.row))
            "
            :TableRowData="scope.row"
            :moreText="column.moreText"
            @toolbar-click="toolbarClick"
          />
        </template>
      </el-table-column>
      <!-- 单选显示列 -->
      <el-table-column
        v-else-if="
          column.singleChoice &&
          (column.visible || column.visible === undefined)
        "
        :type="column.type"
        :label="column.label"
        :class-name="column.className"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        :label-class-name="column.labelClassName"
        :prop="Array.isArray(columns) ? column.name : index"
        :width="column.width"
        :min-width="column.minWidth"
        :sortable="column.sortable"
        :sort-method="column.sortMethod"
        :sort-by="column.sortBy"
        :resizable="column.resizable"
        :column-key="column.columnKey"
        :align="column.align"
        :header-align="column.headerAlign"
        :show-tooltip-when-overflow="column.showTooltipWhenOverflow"
        :show-overflow-tooltip="
          column.showOverflowTooltip === undefined
            ? true
            : column.showOverflowTooltip
        "
        :fixed="column.fixed"
        :formatter="column.formatter"
        :selectable="column.selectable"
        :reserve-selection="column.reserveSelection"
        :filter-method="column.filterMethod"
        :filters="column.filters"
        :filter-placement="column.filterPlacement"
        :filter-multiple="column.filterMultiple"
        :index="column.index"
        :key="column.columnKey"
      >
        <template slot-scope="scope">
          <div class="single_radio">
            <el-radio v-model="currentSingleChoice" :label="scope.row.id"
              >&nbsp;</el-radio
            >
          </div>
        </template>
      </el-table-column>
      <!-- 自定义slot的自定义列 -->
      <el-table-column
        v-else-if="
          column.customSlot && (column.visible || column.visible === undefined)
        "
        :type="column.type"
        :label="column.label"
        :class-name="column.className"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        :label-class-name="column.labelClassName"
        :prop="Array.isArray(columns) ? column.name : index"
        :width="column.width"
        :min-width="column.minWidth"
        :sortable="column.sortable"
        :sort-method="column.sortMethod"
        :sort-by="column.sortBy"
        :resizable="column.resizable"
        :column-key="column.columnKey"
        :align="column.align"
        :header-align="column.headerAlign"
        :show-tooltip-when-overflow="column.showTooltipWhenOverflow"
        :show-overflow-tooltip="
          column.showOverflowTooltip === undefined
            ? true
            : column.showOverflowTooltip
        "
        :fixed="column.fixed"
        :formatter="column.formatter"
        :selectable="column.selectable"
        :reserve-selection="column.reserveSelection"
        :filter-method="column.filterMethod"
        :filters="column.filters"
        :filter-placement="column.filterPlacement"
        :filter-multiple="column.filterMultiple"
        :index="column.index"
        :key="column.columnKey"
      >
        <template v-if="column.showFilterHead" #header>
          <table-head-filter-view
            ref="headFilter"
            :column="column"
            :headFilterArray="headFilterArray(column)"
            @on-filter-comfirm="onFilterComfirm"
          />
        </template>
        <template v-slot:default="slotProps">
          <slot
            v-bind:customSlotData="slotProps.row"
            :name="column.customSlot"
          ></slot>
        </template>
      </el-table-column>
      <!-- 普通显示列 -->
      <el-table-column
        v-else-if="
          !column.showImg &&
          !column.showCellLink &&
          !column.singleChoice &&
          (column.visible || column.visible === undefined)
        "
        :type="column.type"
        :label="column.label"
        :class-name="column.className"
        ement-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        :label-class-name="column.labelClassName"
        :prop="Array.isArray(columns) ? column.name : index"
        :width="column.width"
        :min-width="column.minWidth"
        :sortable="column.sortable"
        :sort-method="column.sortMethod"
        :sort-by="column.sortBy"
        :resizable="column.resizable"
        :column-key="column.columnKey"
        :align="column.align"
        :header-align="column.headerAlign"
        :show-tooltip-when-overflow="column.showTooltipWhenOverflow"
        :show-overflow-tooltip="
          column.showOverflowTooltip === undefined
            ? true
            : column.showOverflowTooltip
        "
        :fixed="column.fixed"
        :formatter="column.formatter"
        :selectable="column.selectable"
        :reserve-selection="column.reserveSelection"
        :filter-method="column.filterMethod"
        :filters="column.filters"
        :filter-placement="column.filterPlacement"
        :filter-multiple="column.filterMultiple"
        :index="column.index"
        :key="column.columnKey"
      >
        <!-- 这里遇到一个坑 就是自定义表头如果使用slot="header" 表头的数据无法更新，只要改成#header就可以了 -->
        <template v-if="column.showFilterHead" #header>
          <table-head-filter-view
            ref="headFilter"
            :column="column"
            :headFilterArray="headFilterArray(column)"
            @on-filter-comfirm="onFilterComfirm"
          />
        </template>
        <template v-if="column.type == 'expand'" v-slot:default="slotProps">
          <slot name="expandSlot" v-bind:customSlotData="slotProps.row"></slot>
        </template>
      </el-table-column>
    </template>
    <slot name="columns"></slot>
    <!-- 数据为空时显示 -->
    <template #empty>
      <table-empty-view />
    </template>
  </el-table>
</template>
<script>
import tools from '../utils/tools.js'
import tableEmptyView from './baseView/tableEmpty'
import tableImgView from './baseView/tableImg'
import tableMoreOperateView from './baseView/tableMoreOperate'
import tableHeadFilterView from './baseView/tableHeadFilter'

export default {
  name: 'table-view',
  components: {
    tableEmptyView,
    tableImgView,
    tableMoreOperateView,
    tableHeadFilterView
  },
  props: {
    // 表格数据
    data: {
      type: Array
    },
    // 表格高度
    height: {
      type: [String, Number]
      // default: 'calc(100vh - 253px)'
    },
    tableSize: {
      type: String,
      default: 'small'
    },
    // 是否显示边框
    border: {
      type: Boolean,
      default: true
    },
    // columns列
    columns: {
      type: [Object, Array],
      default: () => {
        return {} || []
      }
    }
  },
  data() {
    return {
      // moneySymbol: '￥',
      currentSingleChoice: null,
      filterArr: []
    }
  },
  created() {
    if (Array.isArray(this.columns) && this.columns.length) {
      this.columns.forEach(p => {
        if (p.formatterName) {
          p = Object.assign(p, {
            formatter: (arg, columns) =>
              p.formatterParams
                ? this.columnsFormatter(
                    arg,
                    columns,
                    p.formatterName,
                    p.formatterParams
                  )
                : this.columnsFormatter(arg, columns, p.formatterName)
          })
        }
      })
    } else {
      if (Object.keys(this.columns).length) {
        Object.keys(this.columns).forEach(p => {
          if (this.columns[p]['formatterName'])
            this.columns[p] = Object.assign(this.columns[p], {
              formatter: (arg, columns) =>
                this.columns[p]['formatterParams']
                  ? this.columnsFormatter(
                      arg,
                      columns,
                      this.columns[p]['formatterName'],
                      ...this.columns[p]['formatterParams']
                    )
                  : this.columnsFormatter(
                      arg,
                      columns,
                      this.columns[p]['formatterName']
                    )
            })
        })
      }
    }
  },
  computed: {
    permissionsData() {
      return this.$store.state.permissions
    }
  },
  methods: {
    // 过滤数据
    filterData() {
      let arr = []
      if (this.filterArr.filter(p => p.arr.length).length) {
        let expression = []
        expression = this.filterArr
          .filter(p => p.arr.length)
          .map(p => {
            return {
              field: p.field,
              arr: p.arr.map(p => p.value)
            }
          })
        let str = ``
        expression.forEach((y, pIndex) => {
          y.arr.forEach((k, index) => {
            str +=
              `p.${y.field} === ` +
              (k === null ? null : `'${k}'`) +
              `${index == y.arr.length - 1 ? '' : '||'}`
          })
          if (pIndex !== expression.length - 1) str += '&&'
        })
        console.log('expression', expression, 'str', str)
        arr = this.data.filter(p => eval(str))
        console.log('计算属性arr', arr, 'this.filterArr', this.filterArr)
      } else {
        arr = this.data
      }
      return arr
    },
    // 点击过滤框的确定按钮执行的方法
    onFilterComfirm(arr, column) {
      console.log('过滤arr', arr, column)
      let isHas = this.filterArr.find(p => p.field === column.name)
      if (isHas) {
        isHas.arr = arr
      } else {
        this.filterArr.push({ field: column.name, arr: arr })
      }
      console.log('this.filterArr', this.filterArr)
      this.filterData()
    },
    // 去重
    uniqueFunc(arr, uniId) {
      const res = new Map()
      return arr.filter(
        item => !res.has(item[uniId]) && res.set(item[uniId], 1)
      )
    },
    // 组装好的所需的过滤数据
    headFilterArray(column) {
      console.log('组装好的所需的过滤数据', column, this.data)
      let arr = this.data.map(p => {
        let obj = {}
        obj[column.name] = p[column.name]
        if (column.filterLabel) obj[column.filterLabel] = p[column.filterLabel]
        if (column.filterValue) obj[column.filterValue] = p[column.filterValue]
        return obj
      })
      let newArr = this.uniqueFunc(arr, column.name)
        .map(item => {
          console.log(item, column.filterLabel)
          return {
            field: column.name,
            isSelect: false,
            label: item[column.filterLabel ? column.filterLabel : column.name],
            value: item[column.filterValue ? column.filterValue : column.name]
          }
        })
        .filter(y => y.value !== undefined)
      console.log('newArr', newArr)
      return newArr || []
    },
    // 权限判断操作栏按钮是否显示
    judgePrem(item, row) {
      if (item.hasOwnProperty('premissionKey')) {
        return this.permissionsData[item.premissionKey]
      } else {
        if (item.visible && typeof item.visible === 'function') {
          return item.visible(row)
        } else {
          return item.visible === undefined ? true : item.visible
        }
      }
    },
    rowClick(row, column, event) {
      this.currentSingleChoice = row.id
      this.$emit('row-click', row, column, event, this.currentSingleChoice)
    },
    columnBackground(column, scope) {
      let str =
        column.stateTagData.judgeValue[scope.row[column.stateTagData.judgeName]]
      if (str) {
        return str.type === 'danger'
          ? '#f5222d'
          : str.type === 'success'
          ? '#52c41a'
          : str.type === 'info'
          ? '#bfbfbf'
          : str.type === 'warning'
          ? '#ffaa00'
          : str.color
          ? str.color
          : '#888888'
      } else {
        return '#888888'
      }
    },
    columnsFormatter(arg, columns, funcName, formatterParams) {
      // if (funcName == 'toThousands') {
      //     return this.moneySymbol + tools[funcName](arg[columns.property])
      // }
      if (arg.hasOwnProperty(columns.property)) {
        return formatterParams
          ? tools[funcName](arg[columns.property], ...formatterParams)
          : tools[funcName](arg[columns.property])
      }
    },
    toolbarClick(row, item, index) {
      this.$emit('tool-bar-click', row, item, index)
    },
    cellLinkEvent(row) {
      this.$emit('cell-lick-event', row)
    }
    // clearSelection() {
    //   this.$refs.table.clearSelection()
    // },
    // clearCurrentRow() {
    //   this.$refs.table.setCurrentRow()
    // }
  }
}
</script>
<style lang="less">
.pop_box {
  padding: 6px;
  line-height: 0;
}
// /deep/ .el-table td.el-table__cell {
//   border: 1px solid #eee !important;
// }
// .el-tooltip__popper {
//   max-width: 320px;
// }
</style>
<style scoped lang="less">
.single_radio {
  width: 100%;
  display: flex;
  justify-content: center;
  /deep/.el-radio__label {
    display: none;
  }
}
.table_tag {
  display: inline-block;
  position: relative;
  padding: 0 0 0 10px;
  .custom_column_cricle {
    position: absolute;
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    left: -2px;
    top: 9px;
    z-index: 10px;
  }
}
.tools_box {
  display: inline-block;
}
.column_toolbar_link:not(:first-child) {
  margin-left: 10px;
}

.table_view {
  // //给固定列设置下边距
  // /deep/ .el-table__fixed,
  // /deep/ .el-table__fixed-right {
  //   height: auto !important;
  //   bottom: 10px !important; //具体值是多少根据你横向滚动条的高度进行设置
  // }
  // //去掉固定列下方的横线
  // /deep/ .el-table__fixed::before,
  // /deep/ .el-table__fixed-right::before {
  //   display: none;
  // }
  // 排序表头样式
  // /deep/ th.el-table__cell.is-sortable {
  //   padding: 3px 0 2px 0;
  // }
  // /deep/ th.el-table__cell {
  //   background: #fef2e9 !important;
  //   color: rgba(0, 0, 0, 0.85) !important;
  // }
  // /deep/ th > .cell {
  //   overflow: hidden !important;
  //   text-overflow: ellipsis !important;
  //   white-space: nowrap !important;
  // }
  // // :not(:last-child)
  // /deep/ th {
  //   border-right: 1px solid #ffd3b9 !important;
  //   border-bottom: 1px solid #ffb388 !important;
  // }

  // /deep/ .el-link.el-link--primary.is-disabled,
  // .el-link.el-link--danger.is-disabled {
  //   // color: rgba(0, 0, 0, 0.25);
  //   color: #bfbfbf;
  // }
  // .el-link.el-link--default {
  //   color: #18a1fb;
  // }
  // .el-link.el-link--default.is-disabled {
  //   // color: rgba(0, 0, 0, 0.25);
  //   color: #bfbfbf;
  // }
  // /deep/ .el-table__fixed-right-patch {
  //   background: #fef2e9;
  // }
  // /deep/ .el-table__fixed-right .el-table__fixed-header-wrapper th {
  //   border-right: 1px solid #ffd3b9;
  //   border-bottom: 1px solid #ffb388;
  // }
  // /deep/ .cell {
  //   user-select: text;
  //   font-size: 14px;
  //   width: 100% !important;
  // }
  // /deep/ .el-link--inner {
  //   user-select: text;
  // }
}
</style>
