From 077b7006de46ad644aa321843303430513126ad0 Mon Sep 17 00:00:00 2001
From: Ben Lin <maobin001@msn.com>
Date: 星期二, 18 六月 2024 18:54:17 +0800
Subject: [PATCH] 更新

---
 src/components/Form/src/components/ApiTree.vue |  175 +++++++++++++++++++++++++++++++--------------------------
 1 files changed, 95 insertions(+), 80 deletions(-)

diff --git a/src/components/Form/src/components/ApiTree.vue b/src/components/Form/src/components/ApiTree.vue
index 41a7413..56f9358 100644
--- a/src/components/Form/src/components/ApiTree.vue
+++ b/src/components/Form/src/components/ApiTree.vue
@@ -1,92 +1,107 @@
 <template>
-  <a-tree v-bind="getAttrs" @change="handleChange">
+  <Tree v-bind="getAttrs" v-model:selectedKeys="state">
     <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>
+  </Tree>
 </template>
 
-<script lang="ts">
-  import { type Recordable, type AnyFunction } from '@vben/types';
-  import { type PropType, computed, defineComponent, watch, ref, onMounted, unref } from 'vue';
-  import { Tree } from 'ant-design-vue';
-  import { isArray, isFunction } from '/@/utils/is';
+<script lang="ts" setup>
+  import { type Recordable } from '@vben/types';
+  import { type PropType, computed, watch, ref, onMounted, unref, useAttrs } from 'vue';
+  import { Tree, TreeProps } from 'ant-design-vue';
+  import { isFunction } from '@/utils/is';
   import { get } from 'lodash-es';
-  import { propTypes } from '/@/utils/propTypes';
-  import { LoadingOutlined } from '@ant-design/icons-vue';
+  import { DataNode } from 'ant-design-vue/es/tree';
+  import { useRuleFormItem } from '@/hooks/component/useFormItem';
 
-  export default defineComponent({
-    name: 'ApiTree',
-    components: { ATree: Tree, 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(''),
-      afterFetch: { type: Function as PropType<AnyFunction> },
+  defineOptions({ name: 'ApiTree' });
+
+  const props = defineProps({
+    api: { type: Function as PropType<(arg?: any) => Promise<Recordable<any>>> },
+    params: { type: Object },
+    immediate: { type: Boolean, default: true },
+    resultField: { type: String, default: '' },
+    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, afterFetch } = props;
-        if (!api || !isFunction(api)) return;
-        loading.value = true;
-        treeData.value = [];
-        let result;
-        try {
-          result = await api(props.params);
-        } catch (e) {
-          console.error(e);
-        }
-        if (afterFetch && isFunction(afterFetch)) {
-          result = afterFetch(result);
-        }
-        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,
+    },
+    value: {
+      type: Array as PropType<TreeProps['selectedKeys']>,
     },
   });
+
+  const emit = defineEmits(['options-change', 'change', 'update:value']);
+
+  const attrs = useAttrs();
+
+  const treeData = ref<DataNode[]>([]);
+  const isFirstLoaded = ref<Boolean>(false);
+  const loading = ref(false);
+  const emitData = ref<any[]>([]);
+
+  const [state] = useRuleFormItem(props, 'value', 'change', emitData);
+  const getAttrs = computed(() => {
+    return {
+      ...(props.api ? { treeData: unref(treeData) } : {}),
+      ...attrs,
+    };
+  });
+
+  watch(
+    () => state.value,
+    (v) => {
+      emit('update:value', v);
+    },
+  );
+
+  watch(
+    () => props.params,
+    () => {
+      !unref(isFirstLoaded) && fetch();
+    },
+    { deep: true },
+  );
+
+  watch(
+    () => props.immediate,
+    (v) => {
+      v && !isFirstLoaded.value && fetch();
+    },
+  );
+
+  onMounted(() => {
+    props.immediate && fetch();
+  });
+
+  async function fetch() {
+    let { api, beforeFetch, afterFetch, params, resultField } = props;
+    if (!api || !isFunction(api)) 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 & { key: string | number })[]) || [];
+    isFirstLoaded.value = true;
+    emit('options-change', treeData.value);
+  }
 </script>

--
Gitblit v1.9.3