<!--element下拉列表封装
  使用：
   <hyb-select ref="hybSelect"
   url="/v1/orgs"
   v-model="search.orgId" option="orgId" label="orgName"
   placeholder multiple localOptions></hyb-select>

    1.url:要显示的下拉列表数据来源
    规范：返回的数据要符合(JSON中对应的字段必须：label和value,不能其他)
      [
        {label:'显示1',value:'值1'},
        {label:'显示2',value:'值2'},
        {label:'显示3',value:'值3'},
        ...
      ]
    2.v-model数据的双向绑定,绑定父组件中的字段
    3.option自定义select的value对应的字段
    4.label自定义select的label对应的字段
    5.placeholder下拉列表提示
    6.multiple是否是多选
    7.localOptions使用本地的数据,不用请求远程数据,注意：使用该属性时Url属性不能要,不然无效
-->
<template>
  <div>
    <el-select v-model="selectValue"
               :clearable="clearable"
               :collapse-tags="collapseTags"
               filterable
               class="filter-item"
               :placeholder="placeholder"
               :disabled="disabled"
               :multiple="multiple == null ? false : true"
               :remote="remoteFilter"
               :remote-method="remoteQuery"
               @change="change">
      <el-option v-for="(item, index) in options"
                 :key="index"
                 :label="getItemLabel(item, label)"
                 :value="item[option]"
                 :disabled="isDisabledOption(item)">
        <template v-if="mergeLabel">
          <span style="float: left">{{ getItemLabel(item, label) }}</span>
          <span style="float: right; color: #8492a6; font-size: 13px">{{ item[option] }}</span>
        </template>
      </el-option>
      <el-option v-if="totalPage > 1"
                 label="搜索更多"
                 value=""
                 disabled />
    </el-select>
  </div>
</template>

<script>
import request from '@/utils/request'
export default {
  props: {
    dictCode: null, // 当传入dictCode时，可以不用传递url
    url: null,
    method: null,
    queryParam: {
      type: Object,
      default: () => {
        return {}
      },
    },
    value: null,
    placeholder: null,
    label: {
      type: String,
      default: 'text',
    },
    option: {
      type: String,
      default: 'id',
    },
    multiple: null,
    localOptions: null,
    disabled: null,
    clearable: {
      type: Boolean,
      default: true,
    },
    collapseTags: {
      type: Boolean,
      default: false,
    },
    mergeLabel: {
      type: Boolean,
      default: false,
    },
    // 禁用的下拉选项
    disabledOptions: {
      type: String,
      default: () => {
        return ''
      },
    },
    // 使用远程搜索
    remoteFilter: {
      type: Boolean,
      default: false,
    },
  },
  data () {
    return {
      options: null,
      selectValue: null,
      // 如果是分页的，
      totalPage: 0,
    }
  },
  computed: {
    // 根据dictCode和url拼出最终的请求url
    requestUrl () {
      if (this.url != null && this.url.trim() != '') {
        if (this.url.indexOf('?') > 0) {
          if (this.option == null) {
            console.log('url-' + this.url.substring(this.url.indexOf('?')))
          }
          if (this.label == null) {
          }
        }
        return this.url
      }
      if (this.dictCode != null && this.dictCode.trim() != '') {
        return `/meta/gaeaDict/select/${this.dictCode}`
      }
      return null
    },
  },
  watch: {
    value: function (val, oldVal) {
      if (this.multiple != null) {
        if (!this.value) {
          this.selectValue = []
        } else {
          this.selectValue = this.value
        }
      } else {
        if (this.value != null && this.value != undefined) {
          this.selectValue = this.value
        } else {
          this.selectValue = ''
        }
      }
    },
    url () {
      setTimeout(() => {
        this.queryData()
      }, 500)
    },
  },
  created () {
    if (this.multiple != null) {
      this.selectValue = this.value
    } else {
      if (this.value != null) {
        this.selectValue = this.value
      }
    }
  },
  mounted () {
    if (this.requestUrl == null) {
      this.options = this.localOptions
      return
    }
    this.queryData()
  },
  methods: {
    // 判断选择是否已经禁用
    isDisabledOption (option) {
      if (option == null || this.disabledOptions == null || this.disabledOptions.length == 0) {
        return false
      }
      var currentOptionVal = option[this.option]
      return this.disabledOptions.indexOf(currentOptionVal) >= 0
    },
    change (value) {
      if (value === '') {
        value = null
      }
      this.$emit('input', value)

      // 根据当前值，找出对应的选项
      var optionItem = this.options.find((item) => item[this.option] == value)
      this.$emit('change', value, optionItem)
    },
    // 根据用户配置的label，生成对应的标签
    getItemLabel (item, label) {
      if (label.indexOf('${') < 0 && label.indexOf('}' < 0)) {
        return item[label]
      }
      var reg = /\$\{[a-zA-Z0-9]*\}/g
      var list = label.match(reg)
      // ["${id}", "${text}"]
      var result = label
      for (var i = 0; i < list.length; i++) {
        var sub = list[i]
        var key = sub.replace('${', '').replace('}', '')
        result = result.replace(sub, item[key])
      }
      return result
    },
    // 从本地localStorage取 gaeaDict
    getOptionsFromLocalStorage () {
      var dicts = JSON.parse(localStorage.getItem('gaeaDict'))
      var options = []
      if (!dicts.hasOwnProperty(this.dictCode)) {
        return []
      }
      var dictItems = dicts[this.dictCode]
      for (var i = 0; i < dictItems.length; i++) {
        var dictItem = dictItems[i]
        options.push({ id: dictItem.id, text: dictItem.text })
      }
      return options
    },
    queryData () {
      // 所有从本地localStorage取，因为在App.vue中已经请求远程保存到本地了
      var options = this.getOptionsFromLocalStorage()
      if (this.isNotBlank(options)) {
        this.options = options
        return
      }
      // 本地localStorage取不到，再从远程接口取
      if (this.requestUrl == null) {
        return
      }
      if (this.method != null && this.method.toLocaleLowerCase().trim() == 'post') {
        this.queryDataByPost()
      } else {
        this.queryDataByGet()
      }
    },
    queryDataByGet (keyword) {
      var param = this.deepClone(this.queryParam)
      if (this.isNotBlank(keyword)) {
        param['keyword'] = keyword
      }
      param['multiple'] = this.multiple == null ? null : 1
      request({
        url: this.requestUrl,
        headers: { noPrompt: true },
        params: param,
      }).then((response) => {
        this.setOptions(response.data)
      })
    },
    queryDataByPost (keyword) {
      var param = this.deepClone(this.queryParam)
      if (this.isNotBlank(keyword)) {
        param['keyword'] = keyword
      }
      request({
        url: this.requestUrl,
        method: 'post',
        headers: { noPrompt: true },
        data: param,
      }).then((response) => {
        this.setOptions(response.data)
      })
    },
    setOptions (resData) {
      if (resData == null || resData.length == 0) {
        this.options = []
        this.totalPage = 0
        return
      }
      if (this.isArray(resData)) {
        this.options = resData
        this.totalPage = 1
        return
      }
      if (resData.records == null || resData.total == null || resData.pages == null) {
        this.options = []
        return
      }
      this.totalPage = resData.pages
      // resData.records
      // resData.total
      // resData.size
      // resData.current
      this.options = resData.records
    },
    remoteQuery (keyword) {
      if (this.isBlank(keyword)) {
        return
      }
      setTimeout(() => {
        if (this.method != null && this.method.toLocaleLowerCase().trim() == 'post') {
          this.queryDataByPost(keyword)
        } else {
          this.queryDataByGet(keyword)
        }
      }, 200)
    },
  },
}
</script>
