<template>
  <Dialog :flag="flag" width="90%">
    <div ref="dialog" class="dialog-wrapper" :tabindex="0" @keyup.esc="dialogHide">
      <div class="title">
        <span class="title-text">{{ title }}</span>
        <span class="right">
          <img class="btn-square btn-shadow" style="position: relative;top:-8px;margin-right: 15px;" src="@/assets/baggage/ic_export.png" title="导出" @click="exportClickHandler" />
          <i class="icon el-icon-close" style="top: -12px;position: relative;" @click="dialogHide" />
        </span>
      </div>
      <div class="content">
        <div v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)" class="table-wrapper">
          <el-table ref="table" height="calc(100vh - 100px - 60px - 10px)" class="table" :data="dealedTableData" border stripe fit show-summary :summary-method="summaryRow" :header-cell-class-name="headerCellClass" :row-class-name="rowClass" :cell-class-name="cellClass" :span-method="spanMethod" @cell-click="cellClickHandler">
            <el-table-column v-for="column in tableColumns" :key="column.prop" :prop="column.prop" :label="column.label" :width="column.width" :fixed="column.fixed" :formatter="formatter">
              <template #header>
                <el-tooltip :content="column.desc || column.label" placement="top">
                  <TableHeaderCell :label="column.label" :filter-options="tableDataFilters[column.prop]" :filter-values.sync="filterValues[column.prop]" :sortable="column.sortable" :sort-rule.sync="tableDataSortRules[column.prop]" />
                </el-tooltip>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </div>
  </Dialog>
</template>

<script>
import Dialog from '@/layout/components/Dialog/index.vue'
import TableHeaderCell from '@/components/TableHeaderCell/index.vue'
import { setTableFilters, exportToExcel } from '@/utils/table'
import { TempQuery } from '@/api/temp'
export default {
  name: 'TableDialog',
  components: { Dialog, TableHeaderCell },
  props: {
    flag: {
      type: Boolean,
      require: true,
    },
    queryParams: {
      type: Array,
      default: () => [],
    },
    title: {
      type: String,
      default: '标题',
    },
    withExport: {
      type: Boolean,
      default: true
    },
  },
  data () {
    return {
      tableColumns: [
        {
          prop: 'flightNO',
          label: '航班号',
          desc: '指航班编号',
          fixed: 'left',
          filterable: true,
          sortable: true,
        },
        {
          prop: 'flightDate',
          label: '航班日期',
          desc: '指航班计划起飞日期（机票上的静态数据）',
          fixed: 'left',
          width: 110,
          filterable: true,
          sortable: true,
        },
        {
          prop: 'departureTime',
          label: '起飞时间',
          desc: '指航班预计起飞时间，动态数据，仅显示最新结果',
          width: 150,
        },
        {
          prop: 'sourceAirport',
          label: '起飞站',
          desc: '指航班执飞航段的起飞航站，以航站英文三字码显示',
          filterable: true,
          sortable: true,
        },
        {
          prop: 'targetAirport',
          label: '目的地',
          desc: '指航班执飞航段的目的航站，以航站英文三字码显示',
          filterable: true,
          sortable: true,
        },
        {
          prop: 'passengerNameUpcase',
          label: '旅客姓名',
          desc: '指旅客姓名的拼音大写',
          width: 150,
          filterable: true,
          sortable: true,
        },
        {
          prop: 'bagSN',
          label: '行李牌号',
          desc: '指行李的10位数字行李牌号码',
          width: 110,
          filterable: true,
          sortable: true,
        },
        {
          prop: 'specialType',
          label: '特殊行李类型',
          desc: '指有别于普通托运行李的特殊行李分类，包括（装笼动物、机组行李、易碎行李、VIP行李等），参考BSM报文.E项说明',
          width: 115,
          filterable: true,
          sortable: true,
        },
        {
          prop: 'deleted',
          label: '删除',
          desc: '指旅客是否取消值机托运，根据BSM报文状态是否有DEL判断，已删除的行李记录为斜体灰色字体',
          filterable: true,
          sortable: true,
        },
        {
          prop: 'activated',
          label: '激活',
          desc: '指托运行李是否被激活，参照BSM报文.S项说明',
          filterable: true,
          sortable: true,
        },
        {
          prop: 'bagWeight',
          label: '重量',
          desc: '指托运行李的重量，参照BSM报文.W项说明',
        },
        {
          prop: 'latestStatus',
          label: '最新状态',
          desc: '指托运行李的当前查询时间所在的节点状态',
          width: 110,
          filterable: true,
          sortable: true,
        },
        {
          prop: 'bagLocation',
          label: '最新位置',
          desc: '指托运行李的当前查询时间所在的节点状态的识读位置代号',
          width: 110,
          filterable: true,
          sortable: true,
        },
        {
          prop: 'U_Device_ID',
          label: '容器编号',
          desc: '指集装器ID信息',
          width: 110,
          filterable: true,
          sortable: true,
        },
        {
          prop: 'preFlightNO',
          label: '中转进航班',
          desc: '指有中转行李转出的进港航班号',
          width: 110,
          filterable: true,
          sortable: true,
        },
        {
          prop: 'transferFlightNO',
          label: '中转出航班',
          desc: '指有中转行李转入的离港航班号',
          width: 110,
          filterable: true,
          sortable: true,
        },
      ],
      tableData: [],
      tableDataFilters: {},
      filterValues: {},
      tableDataSortRules: {},
      spanArr: [],
      loading: false,
    }
  },
  computed: {
    dealedTableData () {
      const filtered = this.tableData.filter(item => {
        let flag = true
        Object.entries(this.filterValues).forEach(([key, arr]) => {
          if (arr.length && !arr.includes(String(item[key]))) {
            flag = false
          }
        })
        return flag
      })
      const sortRules = Object.entries(this.tableDataSortRules).reduce(
        (pre, [key, value]) => {
          if (value) {
            pre[0].push(key)
            value = value === 'ascending' ? 'asc' : 'desc'
            pre[1].push(value)
          }
          return pre
        },
        [[], []]
      )
      return this._.orderBy(filtered, sortRules[0], sortRules[1])
    },
  },
  watch: {
    flag (val) {
      if (val) {
        this.tableData = []
        this.getTableData()
        this.$nextTick(() => {
          this.$refs['dialog']?.focus()
        })
      }
    },
    dealedTableData: {
      handler (val) {
        this.spanArr = []
        let contactDot = 0
        val.forEach((item, index, arr) => {
          if (index === 0) {
            this.spanArr.push(1)
          } else {
            if (
              item['flightNO'] === arr[index - 1]['flightNO'] &&
              item['flightDate'] === arr[index - 1]['flightDate'] &&
              item['passengerNameUpcase'] ===
              arr[index - 1]['passengerNameUpcase'] &&
              item['checkInNO'] === arr[index - 1]['checkInNO'] &&
              item['bagWeight'] === arr[index - 1]['bagWeight']
            ) {
              this.spanArr[contactDot] += 1
              this.spanArr.push(0)
            } else {
              this.spanArr.push(1)
              contactDot = index
            }
          }
        })
      },
      deep: true,
    },
  },
  created () {
    Object.values(this.tableColumns).forEach(
      ({ prop, filterable, sortable }) => {
        if (filterable) {
          this.$set(this.tableDataFilters, prop, [])
          this.$set(this.filterValues, prop, [])
        }
        if (sortable) {
          this.$set(this.tableDataSortRules, prop, '')
        }
      }
    )
  },
  updated () {
    // table数据更新
    this.$nextTick(() => {
      this.$refs.table?.doLayout()
    })
  },
  methods: {
    dialogHide () {
      this.$emit('update:flag', false)
    },
    spanMethod ({ row, column, rowIndex, columnIndex }) {
      if (['passengerNameUpcase', 'bagWeight'].includes(column.property)) {
        const _row = this.spanArr[rowIndex]
        const _col = _row > 0 ? 1 : 0
        return {
          rowspan: _row,
          colspan: _col,
        }
      }
    },
    // 给表头单元格加上 ascending 或 descending 使用 element 自带的排序箭头变色
    headerCellClass ({ row, column, rowIndex, columnIndex }) {
      const classes = []
      const rule = this.tableDataSortRules[column.property]
      if (rule) {
        classes.push(rule)
      }
      return classes.join(' ')
    },
    rowClass ({ row, rowIndex }) {
      const classes = []
      if (row.deleted === 'DEL') {
        classes.push('bgl-deleted')
      }
      return classes.join(' ')
    },
    cellClass ({ row, column, rowIndex, columnIndex }) {
      const classes = []
      return classes.join(' ')
    },
    cellClickHandler (row, column, cell, event) { },
    formatter (row, column, cellValue) {
      switch (column.property) {
        case 'departureTime':
          return (cellValue ?? '').replace('T', ' ')
        case 'deleted':
          return cellValue == 'DEL' ? cellValue : ''
        case 'activated':
          return cellValue == 1 ? '激活' : '未激活'
        default:
          return cellValue ?? ''
      }
    },
    // 统计行数
    summaryRow () {
      const rowNum = this.dealedTableData.length
      return ['合计', `共${rowNum}件`]
    },
    async getTableData () {
      this.loading = true
      try {
        const {
          code,
          returnData: { listValues },
          message,
        } = await TempQuery({
          id: 1844,
          dataContent: this.queryParams,
        })
        if (String(code) !== '0') {
          throw new Error(message || '获取数据失败')
        }
        this.tableData = this._.cloneDeep(listValues)
        this.tableData = this.tableData.sort((a, b) => Date.parse(a.departureTime) - Date.parse(b.departureTime))
        setTableFilters(this.tableData, this.tableDataFilters)
      } catch (error) {
        this.$message.error(error.message || '失败')
      }
      this.loading = false
    },
    //导出
    exportClickHandler () {
      const table = this.$refs['table'].$el.cloneNode(true)
      const fileName = `${this.title}.xlsx`
      exportToExcel(table, `${this.title}`, fileName)
    }
  },
}
</script>

<style lang="scss" scoped>
.dialog-wrapper {
  width: 100%;
  height: calc(100vh - 100px);
  .title {
    display: flex;
    justify-content: space-between;
    .icon {
      margin-right: 10px;
      font-size: 20px;
      cursor: pointer;
      &:hover {
        background-color: #0003;
      }
    }
  }
  .content {
    margin: 0 20px;
  }
  ::v-deep .table {
    width: 100%;
    .cell {
      padding: 0;
      text-align: center;
      font-size: 14px;
      font-family: Helvetica, "Microsoft YaHei";
      letter-spacing: 0;
    }
    .cell-click {
      cursor: pointer;
      color: #2d7cff;
      &.cell-clicked {
        color: purple;
      }
    }
    .el-table__header-wrapper,
    .el-table__fixed-header-wrapper {
      .cell {
        font-weight: bold;
        color: #101116;
      }

      .has-gutter {
        tr {
          .bgl-huang {
            background: #fcf0b1;
          }
        }
      }
    }

    .el-table__body-wrapper,
    .el-table__fixed-body-wrapper {
      tr.bgl-deleted {
        background: #d2d6df;
        td {
          background: #d2d6df;
          font-style: italic;
        }
      }
    }

    .el-table__body tr.hover-row.current-row > td,
    .el-table__body tr.hover-row.el-table__row--striped.current-row > td,
    .el-table__body tr.hover-row.el-table__row--striped > td,
    .el-table__body tr.hover-row > td {
      background-color: red;
    }
  }
}
</style>
