
<template>
  <el-select
    @clear="clear_select"
     :collapse-tags='collapse_tags'
     :multiple='multiple'
    style="width:100%"
    :disabled='disabled'
    :size="size"
    :clearable='clearable'
    ref="select_demo"
    @change="change"
    @focus="select_focus"
    v-model="value_inner"
    :filterable="filterable"
    :remote="remote"
    :remote-method="remoteMethod"
    :placeholder="placeholder">
    <el-option
      v-for="item in options"
      :key="item.value"
      :label="item.label"
      :value="item.value">
    </el-option>
  </el-select>
</template>

<script>
import axios from 'axios'
export default {
  name: 'base-select_plugn',
  props: {
    multiple: {},
    remote_condition: {},
    additional_conditions: {},
    data_base: {}, // 从外部传入的数据
    collapse_tags: {
      default: true,
      type: Boolean
    },
    disabled: {
      type: Boolean
    },
    size: {
      type: String,
      default: 'mini'
    },
    clearable: {
      type: Boolean
    },
    placeholder: {
      default: '请选择'
    },
    value: '',
    url: {
      type: String
    },
    id: {
      required: false
    },
    label: {
      required: false
    },
    // Global_data_select: {
    //   required: true
    // },
    parms: {

    },
    write_obj: {
    },
    write_prop: {},
    display_field: {},
    is_reset: {
      default: false
    },
    is_computed: {}
  },
  data() {
    return {
      options: [],
      value_inner: this.multiple ? [] : '',
      filterable: !!this.remote_condition,
      remote: !!this.remote_condition,
      url_static: 'mesAPI/ref/items/',
      url_dynamic: 'mesAPI/ref/table/',
      real_url: '',
      Global_data_select: [] // 设置为组件级别避免页面级别的太卡了
    }
  },
  watch: {
    value: {
      handler(newValue, oldValue) {
        if (this.multiple) {
          if (this.is_computed) { // 计算模式下
            this.value_inner = this.ten_twe_tans(newValue)
          } else {
            this.value_inner = newValue ? newValue.split(',') : []
          }
        } else {
          this.value_inner = newValue
        }
        if (this.Global_data_select.length) {
          const il = this.Global_data_select.length - 1
          if (!this.Global_data_select[il].status) {
            this.Global_data_select.pop()
          }
          this.Global_data_select.push({})
        }
        // setTimeout(() => {
        //   const il = this.Global_data_select.length - 1
        //   if (!this.Global_data_select[il].status) {
        //     this.Global_data_select.pop()
        //   }
        //   this.Global_data_select.push({})
        // }, 50)
      },
      deep: true
    },
    parms: {
      handler(newValue, oldValue) {

      },
      deep: true
    },
    Global_data_select: {
      handler(newValue, oldValue) {
        if (this.data_base) {
          return
        }
        const target = newValue.find(xs => {
          return xs.data && xs.url === this.real_url
        })
        if (target) {
          this.options = target.data
          const t = this.options.find(xs => {
            return xs[this.id] === this.value
          })
          if (!t && this.display_field) { // 不存在就设置默认值
            this.value_inner = this.multiple ? this.display_field.split(',') : this.display_field
          }
        }
        if (this.display_field) {
          this.value_inner = this.multiple ? this.display_field.split(',') : this.display_field
        }
      },
      deep: true
    }
  },
  beforeDestroy() { // 销毁掉这个对象
    this.Global_data_select = null
  },
  mounted() {
    const that = this
    this.$nextTick(() => {
      if (this.is_computed) { // 计算模式
        that.value_inner = this.ten_twe_tans(that.value)
      } else {
        if (this.multiple) {
          that.value_inner = that.value ? that.value.split(',') : []
        } else {
          that.value_inner = that.value
        }
      }
    })
    if (this.data_base) {
      this.options = this.translate_json(this.data_base)
    } else {
   // 如果是远程搜索且联动的时候
      if (this.parms && this.additional_conditions) return
      this.get_options()
    }
  },
  actived() {
  },
  methods: {
    // 复合值转换成2进制
    ten_twe_tans(val) {
      const list = parseInt(val).toString(2).split('').reverse()
      const result = []
      list.forEach((x, index) => {
        if (typeof this.value === 'number') {
          x.toString() === '1' ? result.push(2 ** index) : ''
        } else {
          x.toString() === '1' ? result.push((2 ** index).toString()) : ''
        }
      })
      return result
    },
    remoteMethod(query) {
      if (this.remote_condition) {
        this.remote_condition = this.remote_condition.trim()
        const query_trim = query.trim()
        let parm
        if (query_trim) {
          const q_str = encodeURIComponent('%' + query_trim + '%')
          if (this.real_url.endsWith('&')) { // 动态查询字段
            parm = this.remote_condition + '=' + q_str
          } else if (this.real_url.includes('/?')) {
            parm = '&' + this.remote_condition + '=' + q_str
          } else {
            parm = '?' + this.remote_condition + '=' + q_str
          }
        }
        if (this.additional_conditions) { // 附加动态条件
          if (this.additional_conditions.startsWith('&')) {
            parm = parm + this.additional_conditions
          } else {
            parm = parm + '&' + this.additional_conditions
          }
        }
        parm = parm || ''
        axios.get(this.real_url + parm).then((res) => {
          this.options = this.tansLate(res.data)
        })
      }
    },
    clear_select() {
      this.$emit('input', '')
      // 清除之后的回调
      this.$emit('clear_callback', '')
    },
    select_focus() {
      if (this.data_base) {
        return
      }
      if (!this.Global_data_select.length) {
        this.get_options()
        return
      }
      if (this.remote_condition) {
        if (!this.parms) return
        let i = 0
        for (const p in this.parms) {
          if (!this.parms[p]) {
            i = i + 1
          }
        }
        if (i === Object.keys(this.parms).length) {
          return
        } else {
          this.get_options()
        }
      } else {
        this.get_options()
      }
    },
    remoteMethod_(query) {
      // const parm = this.remote_condition + '=' + query
    },
    get_options(flage) {
      const args = this.tansLateParm(this.parms)
      if (!isNaN(this.url)) {
        // 常量id
        this.real_url = this.url_static + this.url + '/'
      } else if (this.url.startsWith('/mesAPI')) {
        // 说明它是自定义url
        this.real_url = this.url
      } else {
        // 字段查询
        if (this.url.includes('?')) {
          this.real_url = this.url_dynamic + this.url
        } else {
          this.real_url = this.url_dynamic + this.url + '/'
        }
      }
      if (this.real_url.includes('/?') && this.real_url.endsWith('/')) {
        this.real_url = this.real_url.substring(0, this.real_url.length - 1)
      }
      if (this.parms && Object.keys(this.parms).length) {
        this.real_url += args
      }
      const target = this.Global_data_select.find((xs, index) => {
        return xs.url === this.real_url
      })
      if (!target) {
        this.Global_data_select.push({ url: this.real_url })
      }
      if (target && target.status === 'padding') {
        return
      }
      if (target && target.data) {
        this.options = target.data
      } else {
        let target_index
        this.Global_data_select.forEach((xs, index) => {
          if (xs.url === this.real_url) {
            target_index = index
          }
        })
        this.$set(this.Global_data_select, target_index, { url: this.real_url, status: 'padding' })
        axios.get(this.real_url).then((res) => {
          this.$emit('axios_callback', res.data)
          // 返回结果是数组 则是按照字段来查询
          // 返回结果是json 则是按照常量id来查询
          this.options = Array.isArray(res.data) ? this.tansLate(res.data) : this.translate_json(res.data)
          this.$set(this.Global_data_select, target_index, { url: this.real_url, data: this.options, status: 'ok' })
        })
      }
    },
    change(val) {
      if (this.is_computed) { // 计算模式
        const s = val.reduce((prve, next) => {
          return Number(prve) + Number(next)
        }, 0)
        this.$emit('input', typeof this.value === 'number' ? s : s.toString())
      } else {
        if (this.multiple) { // 多选模式
          if (this.write_prop) {
            if (Array.isArray(this.write_prop)) {
              const f_list = this.options.filter(xs => val.includes(xs.value))
              for (const item of this.write_prop) {
                const [key, value] = item.split('=')
                const r = f_list.map(xs => {
                  return value ? xs[value] : xs[key]
                })
                this.$set(this.write_obj, key, r.join())
              }
            } else {
              const f_list = this.options.filter(xs => val.includes(xs.value))
              const f_label = f_list.map(xs => {
                return xs.label
              })
              this.$set(this.write_obj, this.write_prop, f_label.join())
            }
          }
          const return_obj = {
            val: val.join(),
            data: this.write_obj ? this.write_obj : {}
          }
          this.$emit('input', val.join())
          this.$emit('change_callback', return_obj)
        } else { // 单选模式
          const target = this.options.find(xs => val === xs.value)
          if (!target) return
          if (this.write_prop) {
            if (Array.isArray(this.write_prop)) {
              for (const item of this.write_prop) {
                const [key, value] = item.split('=')
                this.$set(this.write_obj, key, value ? target[value] : target[key])
              }
            } else {
              this.$set(this.write_obj, this.write_prop, target.label)
            }
          }
          const return_obj = {
            val,
            data: this.write_obj ? this.write_obj : {}
          }
          this.$emit('input', val)
          this.$emit('change_callback', return_obj)
        }
      }
    },
    tansLate(arr) {
      const list = []
      arr.forEach(element => {
        const parm = {}
        for (const pro in element) {
          if (pro === this.id && this.id === this.label) {
            parm.value = element[pro]
            parm.label = element[pro]
          } else if (pro === this.id) {
            parm.value = element[pro]
          } else if (pro === this.label) {
            parm.label = element[this.label]
          }
          parm[pro] = element[pro]
        }
        list.push(parm)
      })
      return list
    },
    tansLateParm(obj) {
      let str
      if (this.url.includes('/?')) {
        str = '&'
      } else {
        str = '?'
      }
      for (const prop in obj) {
        if (obj[prop]) {
          str += `${prop}=${obj[prop]}&`
        }
      }
      return str === '?' ? '' : str
    },
    translate_json(data = {}) {
      const list = []
      for (const prop in data) {
        const parm = {}
        parm.value = data[prop]
        parm.label = prop
        list.push(parm)
      }
      return list
    }
  }
}
</script>

