<!--
 * @Author: 曹捷
 * @Date: 2021-05-28 16:34:45
 * @LastEditors: 曹捷
 * @LastEditTime: 2022-04-12 11:27:19
 * @Description: ajax 下拉 级联
  数据回显2.0
-->
<template>
  <obitCascaderVue :options="dataList" v-model:fullList="fullList" v-model:currValue="currValue" v-model:fullNameList="fullNameList" :children="children" :popupVisible="popupVisible" :label="label"
    :parentId="parentId" :valueName="valueName" :placeholder="placeholder" v-model:value="cData" :changeOnSelect="changeOnSelect" :sysnLoadData="cptLoadData">
  </obitCascaderVue>
</template>

<script>
import { watch, reactive, inject, toRefs, onMounted } from "vue";
import obitCascaderVue from "./obit-cascader.vue";
export default {
  components: { obitCascaderVue },
  emits: ["change", "update:value", "update:fullList", "update:fullNameList", 'update:currValue'],
  props: {
    value: {
      type: [Number, String, Array],
    },
    placeholder: {
      type: String,
      default: "请选择对应值",
    },
    // 子集字段名
    children: {
      type: String,
      default: "children",
    },
    // value 值字段名
    valueName: {
      type: String,
      default: "value",
    },
    // 展示字段名
    label: {
      type: String,
      default: "label",
    },
    // 上级id 字段名
    parentId: {
      type: String,
      default: "parentId",
    },
    url: {
      type: String,
      requierd: true,
    },
    changeOnSelect: {
      type: Boolean,
      default: false,
    },
    data: {
      type: Object,
      default () {
        return {};
      },
    },
    ajaxType: {
      type: String,
      default: "post",
    },
    customApi: {
      type: Boolean,
      default: false,
    },
    // 加载数据 可以是自定义Function 或者确定的枚举字段  例如  area  异步获取地区数据
    loadData: {
      type: [Function, String]
    },
    // 异步加载到第几层
    loadLevel: {
      type: Number,
      default: 3
    },
    // 初始化函数 用于数据回显  传入 _data
    mounted: {
      type: Function
    },
    popupVisible: {
      type: Boolean,
      default: undefined
    },
  },
  setup (props, context) {
    let http = inject("http");
    let _data = reactive({
      dataList: [],
      cData: undefined,
      fullList: [],
      fullNameList: [],
      mountedLoading: true,
      currValue: {}
    });
    let _methods = {
      initList () {
        if (!props.url) {
          return;
        }
        if (props.customApi) {
          http[props.url](props.data).then((res) => {
            _data.dataList = res;
          });
        } else {
          http.getDataByUrl(props.url, _methods.getUrlParams(), props.ajaxType).then((res) => {
            _data.dataList = _methods.changeResult(res);
          });
        }
      },
      /**
       * 自定义 数据回显，渲染 完整的树状内容
       */
      async customMounted () {
        _data.mountedLoading = false
        let dataList = await props.mounted(props)
        _data.dataList = dataList
        _data.mountedLoading = true
      },
      getUrlParams () {
        if (props.loadData === "area") {
          return { parentId: 0 };
        }
        return props.data;
      },
      changeResult (res) {
        res && res.forEach((element) => {
          if (props.loadData === "area") {
            element.isLeaf = element.level >= props.loadLevel;
            if (element[props.label] === '全国') {
              element.isLeaf = true
            }
          }
        });
        return res;
      },
      cptLoadData (selectedOptions) {
        let customLoadData = props.loadData;
        if (customLoadData) {
          if (customLoadData instanceof Function) {
            customLoadData(selectedOptions);
          } else if (customLoadData === "area") {
            // 地区异步加载
            const targetOption = selectedOptions[selectedOptions.length - 1];
            targetOption.loading = true; // load options lazily
            http.getDataByUrl(
              props.url,
              { parentId: targetOption[props.valueName] },
              props.ajaxType
            ).then((res) => {
              targetOption.children = _methods.changeResult(res);
              targetOption.loading = false;
            });
          }
        }
      },
    };
    watch(() => props.url, (value) => {
      _methods.initList();
    });

    watch(() => _data.cData, (value, oldvalue) => {
      if (oldvalue !== value) {
        context.emit("update:value", _data.cData);
        context.emit("change", { value: _data.cData, currValue: _data.currValue, fullList: _data.fullList, fullNameList: _data.fullNameList });
        context.emit("update:currValue", _data.currValue);
      }
    });
    watch(() => _data.fullNameList, (value) => {
      context.emit("update:fullList", _data.fullList);
      context.emit("update:fullNameList", value);
    })
    watch(() => props.value, (value) => {
      if (value !== _data.cData) {
        _data.cData = value ? value : "";
      }
    });
    if (props.value) {
      _data.cData = props.value;
    }
    _methods.initList();
    onMounted(() => {
      if (props.mounted) {
        _methods.customMounted()
      } else {
        _methods.initList();
      }
    })
    return {
      ...toRefs(_data),
      ..._methods,
    };
  },
};
</script>

<style>
</style>