<template>
  <div>
    <el-dropdown trigger="click" ref="dropdown" @click.native="handleClick" :style="'width:' + width + ';'">
      <el-input v-model="selectLabel" :clearable="clearable" :style="'width:' + width + ';'" :size="size"
        :placeholder="placeholder" @keyup.native="searchEvent" @change="isEmpty" @focus="focusEvent" @blur="blurEvent"
        @clear="clearValue" :disabled="disabled" suffix-icon="el-icon-arrow-down">
      </el-input>
      <el-dropdown-menu slot="dropdown">
        <el-table ref="dropDownTable" :data="tableData" @current-change="currentChange" size="mini" max-height="1000"
          highlight-current-row v-loading="loading">
          <el-table-column v-for="(column, index) in tableColumn" :key="index" show-overflow-tooltip :width="column.width"
            :label="column.title" :prop="column.field" :align="column.align">
          </el-table-column>
        </el-table>
        <!--分页-->
        <pagination v-show="tablePage.total > 0" :total="tablePage.total" :layout="layout"
          :page.sync="tablePage.currentPage" :limit.sync="tablePage.pageSize" @pagination="findList" />
      </el-dropdown-menu>
    </el-dropdown>
  </div>
</template>

<script>
import XEUtils from 'xe-utils'

export default {
  name: 'SelectTable',
  props: {
    value: {
      required: true
    },
    data: {
      type: Array,
      desc: '所有数据'
    },
    tableColumn: {
      type: Array,
      desc: '表格列'
    },
    label: {
      type: String,
      desc: '回显标签(当后端数据量过大时，可以先传递标签回显。)'
    },
    width: {
      type: String,
      default: 'auto',
      desc: '输入框宽度'
    },
    size: {
      type: String,
      desc: '输入框大小'
    },
    labelField: {
      type: String,
      default: 'name',
      desc: '回显标签,字段名。'
    },
    valueField: {
      type: String,
      default: 'code',
      desc: '回显值,字段名。'
    },
    placeholder: {
      type: String,
      default: '请输入关键字',
      desc: '占位符'
    },
    trigger: {
      type: Boolean,
      default: true,
      desc: '是否触发多次change事件。默认修改后触发一次回显不在触发，可按需求开启。'
    },
    disabled: Boolean,
    clearable: Boolean,
    //分页参数
    layout: String,
    pageSize: Number,
    currentPage: Number,
  },
  data() {
    return {
      //计数器 清空事件执行次数
      clearCounter: 0,
      //选中的值的（id主键）
      selectVal: null,
      //选中的值的标签
      selectLabel: null,
      //表格当前的数据
      tableData: [],
      //和关键字匹配的数据
      filterData: [],
      //分页参数
      tablePage: {
        total: 0,
        currentPage: 1,
        pageSize: 5
      },
      loading: true,//加载
      selected: false,
      paged: false
    }
  },
  computed: {},
  watch: {
    data: {
      deep: true,
      immediate: true,
      handler(val) {
        //该方法，只有在data发生改变时才触发。此处会被执行两次第一次没值,第二次才有值
        if (val && val.length > 0) {
          //data有值,搜索。
          this.loading = false
          if (this.tableData && this.tableData.length > 0) {
            //不是第一次
            this.searchEvent()
            this.setCurrentRowBySelectVal()
          } else {
            //第一次调用组件，并得到数据。
            // setTimeout(()=>{
            //     this.firstEntry()
            // },5000)
            this.firstEntry()
            this.findList()
          }
        } else {
          this.loading = false
        }
      }
    },
    value: {
      handler(val) {
        //如果值为空则把label也置空。
        if (!val) {
          this.selectLabel = ''
          this.selectVal = ''
        } else {
          this.selectVal = val;
          if (this.label) {
            this.selectLabel = this.label
          }
          this.firstEntry()
        }
      },
      immediate: true
    },
  },
  created() {
  },
  mounted() {
    this.initTablePage()

  },
  methods: {
    setCurrentRowBySelectVal() {
      if (this.selectVal) {
        //得到所有列。
        const searchProps = []
        searchProps.push(this.valueField)
        //查找值对应的下标
        if (this.tableData && this.tableData.length > 0) {
          let index = this.tableData.findIndex(value => searchProps.some(key => value[key] == this.selectVal))
          if (index > -1) {
            this.selectLabel = this.tableData[index][this.labelField]
            this.$nextTick(() => {
              if (this.$refs.dropDownTable) {
                this.$refs.dropDownTable.setCurrentRow(this.tableData[index])
              }
            })
          }
        }
      } else {
        this.selectLabel = '';
      }
    },
    //第一次进入
    firstEntry() {
      if (this.data.length > 0) {
        //初始化表格数据
        this.filterData = this.data
      }
      if (this.selectVal) {
        //得到所有列。
        const searchProps = []
        searchProps.push(this.valueField)
        //查找第一次传入的值对应的页
        let index = this.data.findIndex(value => searchProps.some(key => value[key] == this.selectVal))
        if (index > -1) {
          this.selectVal = this.data[index][this.valueField]
          this.selectLabel = this.data[index][this.labelField]
          /**可以根据需求开启触发。默认不触发**/
          if (this.trigger) {
            this.$emit('change', this.data[index][this.valueField])
            this.$emit('changeRow', this.data[index])
          }
          this.tablePage.currentPage = parseInt(index / this.tablePage.pageSize) + 1
        }
      } else {
        this.selectLabel = '';
      }
    },
    //聚焦输入框事件
    isEmpty(val) {
      this.selected = false
      this.paged = false
      if (val == '') {
        this.clearValue()
      }
    },
    //失焦事件
    blurEvent() {
      if (this.$isNotNull(this.selectLabel)) {
        //转小写，去空格
        const filterName = XEUtils.toValueString(this.selectLabel).trim().toLowerCase()
        // const filterRE = new RegExp(filterName, 'gi')
        //得到所有列。
        const searchProps = []
        this.tableColumn.forEach(value => {
          searchProps.push(value.field)
        })
        //模糊匹配到下标
        const index = this.data.findIndex(item => searchProps.some(key => XEUtils.toValueString(item[key]).toLowerCase().indexOf(filterName) > -1))
        if (index > -1) {
          setTimeout(() => {
            if (this.selected == false && this.paged == false) {
              this.clearValue()
              this.$message.warning('请选中一个选项!')
            } else {
              return
            }
          }, 300)
        } else {
          // this.$emit('changeRow', this.data[index])
          // this.$emit('change', " ")
          this.clearValue()
          this.$message.warning('请选中一个选项!')
        }
      }
    },
    //点击选项
    handleClick() {
      //如果是禁用输入框，隐藏下拉框
      if (this.disabled) {
        this.$refs.dropdown.hide()//隐藏下拉框
      }
    },
    ///聚焦事件
    focusEvent() {
      //如果是有值的话，高亮选着的值
      if (!this.selectVal) {
        this.$refs.dropDownTable.setCurrentRow()
      }
      this.filterData = this.data
      this.findList()
    },
    //搜索框，触发方法
    searchEvent() {
      if (!this.data) {
        return
      }
      if (this.$isNotNull(this.selectLabel)) {
        //转小写，去空格
        const filterName = XEUtils.toValueString(this.selectLabel).trim().toLowerCase()
        // const filterRE = new RegExp(filterName, 'gi')
        //得到所有列。
        const searchProps = []
        this.tableColumn.forEach(value => {
          searchProps.push(value.field)
        })
        //双重循环遍历所有数据得到匹配的行。
        const rest = this.data.filter(item => searchProps.some(key => XEUtils.toValueString(item[key]).toLowerCase().indexOf(filterName) > -1))

        //高亮标识匹配关键字。
        // this.tableData = rest.map(row => {
        //     const item = Object.assign({}, row)
        //     searchProps.forEach(key => {
        //         item[key] = XEUtils.toValueString(item[key]).replace(filterRE, match => `<span class="keyword-lighten">${match}</span>`)
        //     })
        //     return item
        // })
        this.filterData = rest
      } else {
        this.filterData = this.data
      }
      this.initTablePage()
      this.findList()
    },
    //清空传回undenfined
    clearValue(val) {
      if (val == undefined) {
        this.selectVal = ''
        this.selectLabel = ''
      }

      this.$refs.dropDownTable.setCurrentRow()
      this.$emit('change', this.selectVal)
    },

    suffixClick() {
      this.$refs.dropdown.togglePanel()
    },
    //选中行，触发事件。
    currentChange(row) {
      if (!row) {
        this.selected = false
        return
      } else {
        this.selected = true
      }
      if (this.labelField) {
        this.selectVal = row[this.valueField]
        this.selectLabel = row[this.labelField]
        this.$emit('change', this.selectVal)
        this.$emit('changeRow', row)
        this.$refs.dropdown.hide()//隐藏下拉框
      }
    },
    //分页查询列表
    findList() {
      setTimeout(() => { this.paged = true }, 100)
      if (this.filterData) {
        this.tablePage.total = this.filterData.length
        this.tableData = this.filterData.slice((this.tablePage.currentPage - 1) * this.tablePage.pageSize, this.tablePage.currentPage * this.tablePage.pageSize)
      }
    },
    //初始化分页参数
    initTablePage() {
      this.tablePage = {
        total: 0,
        currentPage: 1,
        pageSize: this.pageSize
      }
    }

  }
}
</script>

<style scoped>
.my-dropdown {
  z-index: 1000;
  background-color: #fff;
  box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);
}

.keyword-lighten {
  color: #000;
  background-color: #FFFF00;
}

.el-dropdown-menu {
  padding: 20px;
}

/deep/ .el-table tr {
  height: 5px !important;
}

/deep/ .pagination-container {
  height: 40px;
  box-shadow: none;
}

/deep/ .el-table {
  box-shadow: none;
  border-left: 1px solid #D4D4DE;
  border-right: 1px solid #D4D4DE;
}

/deep/ .el-table__header,
/deep/ .el-table__body,
/deep/ .el-table__footer {
  width: 550px !important;
}
</style>
