From 1384174f03c9a009cfbb3ae99aaeec21f177e4c2 Mon Sep 17 00:00:00 2001
From: yyg1378265336 <1378265336@qq.com>
Date: 星期四, 27 二月 2025 09:26:30 +0800
Subject: [PATCH] 生产工具信息

---
 src/components/Form/src/components/ApiTreeSelect.vue |  176 +++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 106 insertions(+), 70 deletions(-)

diff --git a/src/components/Form/src/components/ApiTreeSelect.vue b/src/components/Form/src/components/ApiTreeSelect.vue
index 1e8b04c..5a46128 100644
--- a/src/components/Form/src/components/ApiTreeSelect.vue
+++ b/src/components/Form/src/components/ApiTreeSelect.vue
@@ -1,88 +1,124 @@
 <template>
-  <a-tree-select v-bind="getAttrs" @change="handleChange">
+  <TreeSelect
+    v-bind="getAttrs"
+    @change="handleChange"
+    :field-names="fieldNames"
+    :load-data="async ? onLoadData : undefined"
+  >
     <template #[item]="data" v-for="item in Object.keys($slots)">
       <slot :name="item" v-bind="data || {}"></slot>
     </template>
     <template #suffixIcon v-if="loading">
       <LoadingOutlined spin />
     </template>
-  </a-tree-select>
+  </TreeSelect>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
   import { type Recordable } from '@vben/types';
-  import { type PropType, computed, defineComponent, watch, ref, onMounted, unref } from 'vue';
+  import { type PropType, computed, watch, ref, onMounted, unref, useAttrs } from 'vue';
   import { TreeSelect } from 'ant-design-vue';
-  import { isArray, isFunction } from '/@/utils/is';
+  import { isArray, isFunction } from '@/utils/is';
   import { get } from 'lodash-es';
-  import { propTypes } from '/@/utils/propTypes';
+  import { propTypes } from '@/utils/propTypes';
   import { LoadingOutlined } from '@ant-design/icons-vue';
 
-  export default defineComponent({
-    name: 'ApiTreeSelect',
-    components: { ATreeSelect: TreeSelect, LoadingOutlined },
-    props: {
-      api: { type: Function as PropType<(arg?: Recordable<any>) => Promise<Recordable<any>>> },
-      params: { type: Object },
-      immediate: { type: Boolean, default: true },
-      resultField: propTypes.string.def(''),
+  defineOptions({ name: 'ApiTreeSelect' });
+
+  const props = defineProps({
+    api: { type: Function as PropType<(arg?: any) => Promise<Recordable<any>>> },
+    params: { type: Object },
+    immediate: { type: Boolean, default: true },
+    async: { type: Boolean, default: false },
+    resultField: propTypes.string.def(''),
+    labelField: propTypes.string.def('title'),
+    valueField: propTypes.string.def('value'),
+    childrenField: propTypes.string.def('children'),
+    beforeFetch: {
+      type: Function as PropType<Fn>,
+      default: null,
     },
-    emits: ['options-change', 'change'],
-    setup(props, { attrs, emit }) {
-      const treeData = ref<Recordable<any>[]>([]);
-      const isFirstLoaded = ref<Boolean>(false);
-      const loading = ref(false);
-      const getAttrs = computed(() => {
-        return {
-          ...(props.api ? { treeData: unref(treeData) } : {}),
-          ...attrs,
-        };
-      });
-
-      function handleChange(...args) {
-        emit('change', ...args);
-      }
-
-      watch(
-        () => props.params,
-        () => {
-          !unref(isFirstLoaded) && fetch();
-        },
-        { deep: true },
-      );
-
-      watch(
-        () => props.immediate,
-        (v) => {
-          v && !isFirstLoaded.value && fetch();
-        },
-      );
-
-      onMounted(() => {
-        props.immediate && fetch();
-      });
-
-      async function fetch() {
-        const { api } = props;
-        if (!api || !isFunction(api)) return;
-        loading.value = true;
-        treeData.value = [];
-        let result;
-        try {
-          result = await api(props.params);
-        } catch (e) {
-          console.error(e);
-        }
-        loading.value = false;
-        if (!result) return;
-        if (!isArray(result)) {
-          result = get(result, props.resultField);
-        }
-        treeData.value = (result as Recordable<any>[]) || [];
-        isFirstLoaded.value = true;
-        emit('options-change', treeData.value);
-      }
-      return { getAttrs, loading, handleChange };
+    afterFetch: {
+      type: Function as PropType<Fn>,
+      default: null,
     },
   });
+
+  const emit = defineEmits(['options-change', 'change', 'load-data']);
+
+  const attrs = useAttrs();
+  const treeData = ref<Recordable<any>[]>([]);
+  const isFirstLoaded = ref<Boolean>(false);
+  const loading = ref(false);
+  const getAttrs = computed(() => {
+    return {
+      ...(props.api ? { treeData: unref(treeData) } : {}),
+      ...attrs,
+    };
+  });
+  const fieldNames = {
+    children: props.childrenField,
+    value: props.valueField,
+    label: props.labelField,
+  };
+
+  function handleChange(...args) {
+    emit('change', ...args);
+  }
+
+  watch(
+    () => props.params,
+    () => {
+      !unref(isFirstLoaded) && fetch();
+    },
+    { deep: true },
+  );
+
+  watch(
+    () => props.immediate,
+    (v) => {
+      v && !isFirstLoaded.value && fetch();
+    },
+  );
+
+  onMounted(() => {
+    props.immediate && fetch();
+  });
+
+  function onLoadData(treeNode) {
+    return new Promise((resolve: (value?: unknown) => void) => {
+      if (isArray(treeNode.children) && treeNode.children.length > 0) {
+        resolve();
+        return;
+      }
+      emit('load-data', { treeData, treeNode, resolve });
+    });
+  }
+
+  async function fetch() {
+    let { api, beforeFetch, afterFetch, params, resultField } = props;
+    if (!api || !isFunction(api) || loading.value) return;
+    loading.value = true;
+    treeData.value = [];
+    let res;
+    try {
+      if (beforeFetch && isFunction(beforeFetch)) {
+        params = (await beforeFetch(params)) || params;
+      }
+      res = await api(params);
+      if (afterFetch && isFunction(afterFetch)) {
+        res = (await afterFetch(res)) || res;
+      }
+    } catch (e) {
+      console.error(e);
+    }
+    loading.value = false;
+    if (!res) return;
+    if (resultField) {
+      res = get(res, resultField) || [];
+    }
+    treeData.value = (res as Recordable<any>[]) || [];
+    isFirstLoaded.value = true;
+    emit('options-change', treeData.value);
+  }
 </script>

--
Gitblit v1.9.3