DeeSelectSearch.vue 9.71 KB
<template>
  <div>
    <el-select
      v-if="itemObj.component && !readOnly"
      :key="key"
      v-model="selectValue"
      v-bind="attrs"
      :filterable="true"
      @blur="(params)=>{emit('blur',params)}"
      @focus="(params)=>{emit('focus',params)}"
      @visibleChange="(params)=>{emit('visible-change',params)}"
    >
      <el-option
        v-for="(option,index) in deeOptions"
        :key="index"
        :label="option[itemObj.component.labelWord || 'label']"
        :value="option[itemObj.component.valueWord || 'value']"
        v-bind="option"
      />
    </el-select>
    <span v-else-if="readOnly" style="line-height:40px">{{ showValue }}</span>
  </div>
</template>

<script>
// import { getTableList } from '../../api/searchCom.js'
import { get, post } from '@/utils/http'
export default {
  name: 'DeeSelectSearch',
  components: {},
  props: {
    value: {
      type: [Array, String, Boolean, Number],
      default: () => ''
    },
    itemObj: {
      type: Object,
      default: () => {}
    },
    formValue: {
      type: Object,
      default: () => {}
    },
    readOnly: {
      type: Boolean,
      default: () => false
    }

  },
  data() {
    return {
      key: 0,
      selectValue: '',
      parentValue: '',
      deeOptions: [],
      loading: false,
      origeOPtions: [],
      attrs: {}
    }
  },
  computed: {
    showValue() {
      if (!this.deeOptions || this.deeOptions.length === 0) {
        return ''
      }
      const params = this.deeOptions.find(r => r[this.itemObj.component.valueWord || 'value'] === this.value)
      if (!params) {
        return ''
      }
      return params[this.itemObj.component.labelWord || 'label']
    }
  },
  watch: {
    selectValue: {
      deep: true,
      handler: function(val) {
        this.$emit('input', val)
        this.$emit('change', val)
        // 下拉选择器 配置另外输出值
        // 此功能 只使用 自定义接口
        if (this.itemObj.component.optionsId) {
          if (val instanceof Array) { // 数组
            const list = []
            val.forEach(item => {
              const option = this.deeOptions.find(r => r.value === val)
              if (option) {
                list.push(option[this.itemObj.component.optionsIdName || 'id'])
              }
            })
            this.$set(this.formValue, this.itemObj.component.optionsId, list)
          } else {
            const option = this.deeOptions.find(r => r.value === val)
            if (option) {
              this.$set(this.formValue, this.itemObj.component.optionsId, option[this.itemObj.component.optionsIdName || 'id'])
            }
          }
        }
      }
    },
    value: {
      immediate: true,
      handler: function(val) {
        this.$nextTick(() => {
          this.selectValue = val
        })
      }
    },
    formValue: {
      deep: true,
      handler: function(newval, oldVal) {
        const val = this.itemObj
        if (val.component.dicType === '0' && val.component.optionsdic) {
          const parentValue = this.getParentValue(this.itemObj.component.optionsFilter)
          if (this.itemObj.component.optionsFilter && parentValue) {
            if (this.parentValue !== parentValue) {
              if (!this.readOnly && this.parentValue) {
                this.selectValue = ''
              }
              this.getDictList(val)
            }
          } else if (this.itemObj.component.optionsFilter && (!newval || parentValue === '')) {
            this.selectValue = ''
            this.deeOptions = []
          }
          if (this.itemObj.component.optionsFilter) {
            this.parentValue = parentValue
          }
        } else if (val.component.dicType === '3' && this.itemObj.component.optionsFilter && this.itemObj.component.optionsFilter) {
          const parentValue = this.getParentValue(this.itemObj.component.optionsFilter)
          if (this.parentValue !== parentValue) {
            if (!this.readOnly && this.parentValue) {
              this.selectValue = ''
            }
            this.getObjectAttr()
          }
          this.parentValue = parentValue
        }
      }
    },
    itemObj: {
      immediate: true,
      deep: true,
      handler: function(val) {
        this.attrs = JSON.parse(JSON.stringify(val.component))
        if (this.attrs.hasOwnProperty('multiple')) {
          this.attrs.multiple = Boolean(val.component.multiple)
          this.key++
        }
        this.getOptions(val)
      }
    }
  },
  mounted: function() {
    const val = this.itemObj
    if (val && val.component) {
      this.getOptions(val)
    }
  },
  methods: {
    emit(type, params) {
      this.$emit(type, params)
    },
    getOptions(val) {
      this.deeOptions = val.component && val.component.options ? JSON.parse(JSON.stringify(val.component.options)) : []
      if (val.component.dicType === '0' && val.component.optionsdic) {
        this.getDictList(val)
      } else if (val.component.dicType === '1' && val.component.optionsObj) {
        // this.deeOptions = []
      } else if (val.component.dicType === '3') {
        this.getObjectAttr()
      }
    },
    async getObjectAttr() {
      this.deeOptions = []
      if (!this.itemObj || !this.itemObj.component) {
        return
      }
      if (!this.itemObj.component.httpType || !this.itemObj.component.address) {
        return
      }
      let fun = null
      if (this.itemObj.component.httpType === 'get') {
        fun = get
      } else if (this.itemObj.component.httpType === 'post') {
        fun = post
      }
      if (!fun) {
        return
      }
      if (this.itemObj.component.paramsObj) {
        this.getDeeOptionsByParamsObj(fun)
        return
      }

      // 有父级 但父级没有选择 不读取本级下拉
      if (this.itemObj.component.optionsFilter && (!this.formValue || !this.getParentValue(this.itemObj.component.optionsFilter))) {
        return
      }
      const parentKey = this.itemObj.component.optionsFilter ? this.getParentValue(this.itemObj.component.optionsFilter) : null
      this.deeOptions = await this.$utils.getSelectCustomApi(this.itemObj.key, parentKey, this.itemObj.component, this.formValue, this.itemObj.component.isCache)
    },
    getDeeOptionsByParamsObj(fun) {
      const params = {}
      this.itemObj.component.paramsObj && this.itemObj.component.paramsObj.forEach(attr => {
        if (attr.paramsName === 'appId') {
          params[attr.paramsName] = attr.paramsVal
        } else {
          params[attr.paramsName] = this.formValue && this.formValue[attr.paramsVal]
        }
      })
      if (this.itemObj.component.paramsObj[0].paramsVal === 'optionsObj') {
        if (!this.formValue['optionsObj']) {
          return
        }
      }
      fun(this.itemObj.component.address, params).then((res) => {
        const items = res[this.itemObj.component.returnVal || 'items']
        this.deeOptions = items.map(row => {
          const item = {}
          const label = this.itemObj.component.labelWord || 'label'
          const value = this.itemObj.component.valueWord || 'value'
          item[label] = row[label]
          item[value] = row[value]
          return item
        })
      })
    },
    getParentValue(optionsFilter) {
      if (!this.formValue) {
        return ''
      }
      if (!optionsFilter) {
        return ''
      }
      if (optionsFilter.indexOf('.') < 0) {
        return this.formValue[optionsFilter]
      }
      return this.formValue[optionsFilter] || this.formValue[optionsFilter.replace(/\./g, '|')]
    },
    setParams(list, filter, filedName) {
      const items = []
      list && list.forEach(item => {
        if (item.fieldName && item.operator) {
          const param = {
            'fieldName': item.fieldName,
            'operator': item.operator
          }
          if (item.type === 'form') {
            param.value = this.formValue[item.formItem]
          } else {
            param.value = item.value
          }
          items.push(item)
        }
      })
      if (filter && filedName) { // 级联过滤
        items.push({
          'fieldName': filedName,
          'operator': 'EQ',
          'value': this.getParentValue(filter)
        })
      }
      return items
    },
    async getDictList(val) {
      this.deeOptions = []
      let code = ''
      if (!val.component.optionsdic) {
        return
      } else if (val.component.optionsdic instanceof Array) {
        code = val.component.optionsdic.slice(-1)[0]
      } else {
        code = val.component.optionsdic
      }
      let filter = ''
      if (!val.component.optionsFilter) {
        filter = ''
      } else {
        filter = this.getParentValue(val.component.optionsFilter)
      }
      // 有父级 但父级没有选择 不读取本级下拉
      if (val.component.optionsFilter && (!this.formValue || !this.getParentValue(val.component.optionsFilter))) {
        return
      }
      let list = await this.$utils.getDicListByCode(code, false, filter)
      if (val.component.dicFilter && val.component.dicFilter.length && !val.component.optionsFilter) {
        list = list.filter(r => val.component.dicFilter.includes(r.value))
      }
      this.$set(this, 'deeOptions', list)
    }
    // remoteMethod(query) {
    //   if (query !== '') {
    //     this.loading = true
    //     const formData = { name: query }
    //     get(this.itemObj.url || '/api/users', formData).then(res => {
    //       this.options = []
    //       if (res.items) {
    //         res.items.forEach(el => {
    //           this.options.push({
    //             value: el[this.itemObj.valueWord || 'id'],
    //             label: el[this.itemObj.labelWord || 'name']
    //           })
    //         })
    //       }
    //     })
    //   } else {
    //     this.options = []
    //   }
    // }
  },
  filter: {}
}
</script>

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