<!--
  * @Author 蒋新平
  * @Date 2022-06-06
  * @Update 蒋新平(2022-06-06)
  * @describe 多级联动下拉框组件
-->
<template>
  <a-form-model
    ref="ruleFormMultilevel"
    :model="form"
    :rules="rules"
  >
    <a-row
      :gutter="listTable.Grid.gutter || 24"
      :type="listTable.Grid.type || 'flex'"
      :justify="listTable.Grid.justify || 'start'"
    >
      <a-col :span="listTable.Data.span || 8">
        <!-- 多级联动下拉框 -->
        <template :style="listTable.Data.modelStyle || ''">
          <a-row :gutter="listTable.Data.gutter">
            <a-col
              v-for="(child, c) in listTable.Data.children"
              :key="c"
              :span="child.span"
            >
              <a-form-model-item
                :label="child.label || ''"
                :label-col="child.labelCol || 9"
                :wrapper-col="child.wrapperCol || 15"
                :prop="child.prop"
                class="formItem"
              >
                <div class="space-between">
                  <a-select
                    v-model="child[child.prop]"
                    :placeholder="child.placeholder"
                    @change="handleSelectChange($event, child.option, c, child.prop)"
                    :disabled="child.disabled || false"
                  >
                    <a-select-option
                      v-for="(val, v) in child.option"
                      :key="v"
                      :value="`${val[child.optionId]}`"
                    >{{ val[child.optionName] }}</a-select-option>
                  </a-select>
                  <span style="padding-left: 10px;" v-if="child.subName">{{ child.subName }}</span>
                </div>
              </a-form-model-item>
            </a-col>
          </a-row>
        </template>
      </a-col>
    </a-row>
  </a-form-model>
</template>

<script>
  export default {
    name: 'MultilevelSelect',
    props: {
      // 表单列表数据
      value: {
        type: Object,
        default: () => null
      },
      // 匹配表单唯一标识并赋值 以数据形式进行
      matchedData: {
        type: Object,
        default: () => null
      }
    },
    data () {
      return {
        listTable: this.value
      }
    },
    watch: {},
    computed: {
      // 计算表单返回对象
      form () {
        const _this = this
        var objForm = {}
        _this.listTable.Data.children.forEach((child, c) => {
          objForm[`${child.prop}`] = child[child.prop]
        })
        return objForm
      },
      // 计算返回对应规则格式
      rules () {
        const _this = this
        var objRules = {}
        _this.listTable.Data.children.forEach((child, c) => {
          objRules[`${child.prop}`] = child.rules || []
        })
        return objRules
      }
    },
    mounted () {
      const _this = this
      _this.$nextTick(() => {
        _this.setMatchedData()
        setTimeout(()=>{
          // 获取多级联动下拉框数据
          _this.setRequest()
        },1000)
      })
    },
    methods: {
      // 获取多级联动下拉-发生改变时触发该事件
      handleSelectChange (value, item, chil, prop) {
        const _this = this
        // 处理失去焦点时没有校验
        setTimeout(() => {
          _this.$refs.ruleFormMultilevel.validateField(prop)
        }, 500)
        // 获取数据 选中的 name名称
        if (_this.listTable.Data.children[chil].getOptionName) {
          _this.listTable.Data.children[chil].getOptionName.name = item.filter(val => val.id == value)[0][_this.listTable.Data.children[chil].getOptionName.prop]
        }
        // 清空当前下拉框之后的所有数据和值
        _this.listTable.Data.children.forEach((newItem, c) => {
          if (c > chil) {
            newItem[newItem.prop] = undefined
            newItem.option = []
          }
        })
        // 如果子下标大于数组长度时，返回结束该方法
        chil++
        if (chil >= _this.listTable.Data.children.length) return
        let itemObj = item.filter(val => val.id == value)[0]
        let request = {}
        let params = {}
        request = Object.assign(request, _this.listTable.Data.children[chil].request)
        params[request.params.name] = itemObj[request.params.prop]
        request.params = params
        _this.getSelectParams(request, chil)
      },
      // 设置返回数据并赋值
      setMatchedData () {
        const _this = this
        for (let key in _this.matchedData) {
          _this.listTable.Data.children.forEach((child, c) => {
            if (child.prop == key) {
              child[`${child.prop}`] = _this.matchedData[key]
            }
          })
        }
      },
      // 获取多级联动下拉框接口方法
      // Obj => 接口参数，index => 列表数据，chil => 列表数据下的子数据
      getSelectParams (Obj, index) {
        const _this = this
        Obj.getFunction(Obj.params).then(res => {
          if (res.message) {
            _this.$message.error(res.message)
          } else {
            let Data
            // 判断是否需要自定义获取属性，否则就显示默认数据
            if (Obj.getPostfix) {
              Data = res.data.data || res.data
              // 判断该属性是否是对象，否则就是数组
              if (Data.constructor === Object) {
                Data = Data[Obj.getPostfix]
              } else {
                Data = Data[0][Obj.getPostfix]
              }
            } else {
              Data = res.data.data || res.data
            }
            _this.listTable.Data.children[index].option = Data
          }
        })
      },
      // 设置接口对象数据（初始值）并循环匹配名称请求不同接口
      setRequest () {
        const _this = this
        _this.getSelectParams(_this.listTable.Data.children[0].request, 0)
        let request = {}
        _this.listTable.Data.children.forEach((child, c) => {
          if (child[child.prop] && c > 0) {
            // 对象重新赋值，并且不影响原来对象
            request = Object.assign(request, child.request)
            c--
            let paramsName = {}
            paramsName[request.params.name] = _this.listTable.Data.children[c][_this.listTable.Data.children[c].prop]
            request.params = paramsName
            c++
            // console.log(request)
            _this.getSelectParams(request, c)
          }
        })
      },
      // 提交表单数据
      onSubmit () {
        const _this = this
        _this.$refs.ruleFormMultilevel.validate(valid => {
          if (valid) {
            let params = {}
            params = _this.form
            // 通过循环去除空字段
            for (let key in params) {
              if (!params[key]) {
                delete params[key]
              }
            }
            _this.$emit('formSubmit', params)
          } else {
            console.log('error submit!!')
            return false
          }
        })
      }
    }
  }
</script>

<style lang="scss" type="text/scss" scoped>
  .formItem {
    margin: 0;
  }
</style>
