<!-- 通用选择 -->
<template>
  <el-select style="width: 100%" v-bind="$attrs" v-model="selValue" :placeholder="placeholder" :clearable="clearable"
    :filterable="filterable" :value-key="valueKey" :remote="filterable && pageAble && pageParam.pageSize < total"
    :remote-method="remoteMethod" :loading="loading" @change="change">
    <slot name="header"></slot>
    <el-option v-for="(v, index) in options" :key="index" :label="v[labelKey]" :value="v[valueKey] + ''">
      <slot :index="index" :row="v"></slot>
    </el-option>
    <el-pagination
      v-if="pageAble"
      :pager-count="5"
      hide-on-single-page
      layout="prev, pager, next"
      :total="total"
      :current-page.sync="pageParam.pageNum"
      @current-change="getList"
      >
    </el-pagination>
  </el-select>
</template>

<script>

export default {
  name: 'NomalSelect',
  props: {
    apiMethod: {
      type: Function,
      default: null,
    },
    // 参数是否同步
    syncQuery: {
      type: Boolean,
      default: true
    },
    labelKey: {
      type: String,
      default: 'label'
    },
    valueKey: {
      type: String,
      default: 'id'
    },
    value: {
      type: [String, Number, Array],
      default: ''
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    clearable: {
      type: Boolean,
      default: true
    },
    filterable: {
      type: Boolean,
      default: true
    },
    query: {
      type: [Object, Number, String],
      default: () => ({})
    },
    isPathQuery: {
      type: Boolean,
      default: false,
    },
    // 是否分页
    pageAble: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      selValue: typeof this.value === 'string' || typeof this.value === 'number' ? this.value + '' : this.value,
      options: [],
      total: 0,
      pageParam: this.pageAble ? { pageNum: 1, pageSize: 10 } : {},
      loading: false,
      timer: null,
    }
  },
  watch: {
    value() {
      if (typeof this.value === 'string' || typeof this.value === 'number') {
        this.selValue = this.value + '';
      } else {
        this.selValue = this.value;
      }
      
    },
    apiMethod() {
      this.getList();
    },
    query: {
      handler() {
        this.getList();
      },
      deep: true
    }
  },
  model: {
    prop: 'value',
    event: 'change'
  },
  mounted() {
    this.getList();
  },
  methods: {
    refresh() {
      this.pageParam = this.pageAble ? { pageNum: 1, pageSize: 10 } : {};
      this.getList();
    },
    getList() {
      if (!this.apiMethod) {
        return;
      }
      if (this.isPathQuery) {
        if (!this.query || typeof this.query === 'object') {
          this.options = [];
          return;
        }
        this.loading = true;
        this.apiMethod(this.query).then(res => {
          this.options = res?.rows || res.data || [];
          this.total = res?.total || this.options.length || 0;
          this.loading = false;
          
        }).catch(err => {
          this.loading = false;
        });
        return;
      }
      this.loading = true;
      this.apiMethod(this.syncQuery ? {
        ...this.pageParam,
        ...this.query,
      }: this.pageParam, this.query).then(res => {
        this.options = res?.rows || res.data || [];
        this.total = res?.total || this.options.length || 0;
        this.loading = false;
      }).catch(err => {
        this.loading = false;
      });
    },
    // 远程搜索
    remoteMethod(query) {
      if (this.timer) {
        clearTimeout(this.timer);
      }
      this.timer = setTimeout(() => {
        this.timer = null;
        this.pageParam = {
          ...this.pageParam,
          pageNum: 1,
          [this.labelKey]: query
        };

        this.getList();
      }, 300);
      
    },
    change(val) {
      this.$emit('change', val);
      // 返回选中的原始数据
      if (this.$attrs.multiple) {
        const selvs = val.map(element => {
          const findex = this.options.findIndex(v => v[this.valueKey] == element);
          return this.options[findex] || {};
        });
        this.$emit('rowChange', selvs);
        return;
      }
      const findex = this.options.findIndex(v => v[this.valueKey] == val);
      if (findex > -1) {
        this.$emit('rowChange', this.options[findex]);
      }
    }
  }
}
</script>

<style lang="scss" scoped></style>