Răsfoiți Sursa

♻️ refactor(clients): 重构客户管理页面数据请求逻辑

- 替换ahooks的useRequest为@tanstack/react-query的useQuery和useMutation
- 实现区域列表数据的自动获取和缓存
- 优化客户列表数据查询,支持自动刷新和缓存
- 将创建、更新、删除客户操作重构为mutation请求
- 移除手动调用run方法刷新数据的逻辑,改用queryClient.invalidateQueries实现自动刷新
- 增加请求错误处理和状态码验证
yourname 9 luni în urmă
părinte
comite
4cd21e6ae2
1 a modificat fișierele cu 90 adăugiri și 42 ștergeri
  1. 90 42
      src/client/admin/pages/Clients.tsx

+ 90 - 42
src/client/admin/pages/Clients.tsx

@@ -1,7 +1,7 @@
 import React, { useState, useEffect } from 'react';
 import { Table, Button, Space, Input, Modal, Form, message, Select } from 'antd';
 import { PlusOutlined, EditOutlined, DeleteOutlined, SearchOutlined } from '@ant-design/icons';
-import { useRequest } from 'ahooks';
+import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
 import { clientClient, areaClient } from '@/client/api';
 import type { InferResponseType } from 'hono/client';
 
@@ -16,39 +16,49 @@ const Clients: React.FC = () => {
   const [editingKey, setEditingKey] = useState<string | null>(null);
   const [searchText, setSearchText] = useState('');
   const [areas, setAreas] = useState<AreaItem[]>([]);
+  const queryClient = useQueryClient();
   
   // 获取区域列表
-  const { run: fetchAreas } = useRequest(
-    () => areaClient.$get({ query: { page: 1, pageSize: 1000 } }),
-    {
-      onSuccess: (result) => {
-        setAreas(result.data);
-      },
+  const { data: areasData } = useQuery({
+    queryKey: ['areas'],
+    queryFn: async (): Promise<InferResponseType<typeof areaClient.$get, 200>> => {
+      const res = await areaClient.$get({ query: { page: 1, pageSize: 1000 } });
+      if (res.status !== 200) {
+        throw new Error('获取区域列表失败');
+      }
+      return res.json();
+    },
+    onSuccess: (data) => {
+      setAreas(data.data);
     }
-  );
+  });
+  
   
   // 获取客户列表数据
-  const { data, loading, run } = useRequest<ClientListResponse>(
-    ({ page, pageSize }) => clientClient.$get({ 
-      query: { page, pageSize, keyword: searchText } 
-    }),
-    {
-      refreshDeps: [searchText],
-      defaultParams: [{ page: 1, pageSize: 10 }],
-      onSuccess: (result) => {
-        setDataSource(result.data);
-        setPagination({
-          ...pagination,
-          total: result.pagination.total,
-        });
-      },
+  const { data: clientsData, isLoading: clientsLoading } = useQuery({
+    queryKey: ['clients', pagination.current, pagination.pageSize, searchText],
+    queryFn: async () => {
+      const res = await clientClient.$get({
+        query: {
+          page: pagination.current,
+          pageSize: pagination.pageSize,
+          keyword: searchText
+        }
+      });
+      if (res.status !== 200) {
+        throw new Error('获取客户列表失败');
+      }
+      return res.json();
+    },
+    onSuccess: (result) => {
+      setDataSource(result.data);
+      setPagination({
+        ...pagination,
+        total: result.pagination.total,
+      });
     }
-  );
-  
-  // 初始化获取区域数据
-  useEffect(() => {
-    fetchAreas();
-  }, [fetchAreas]);
+  });
+  // 初始化获取区域数据 - 由useQuery自动处理
   
   const [dataSource, setDataSource] = useState<ClientItem[]>([]);
   const [pagination, setPagination] = useState({
@@ -59,13 +69,12 @@ const Clients: React.FC = () => {
   
   // 搜索
   const handleSearch = () => {
-    run({ page: 1, pageSize: pagination.pageSize });
+    setPagination({ ...pagination, current: 1 });
   };
   
   // 分页变化
   const handleTableChange = (pagination: any) => {
     setPagination(pagination);
-    run({ page: pagination.current, pageSize: pagination.pageSize });
   };
   
   // 显示添加/编辑弹窗
@@ -111,6 +120,39 @@ const Clients: React.FC = () => {
   };
   
   // 提交表单
+  // 创建客户
+  const createClient = useMutation({
+    mutationFn: async (data: any) => {
+      const res = await clientClient.$post({ json: data as any });
+      if (res.status !== 200) {
+        throw new Error('创建客户失败');
+      }
+      return res.json();
+    },
+    onSuccess: () => {
+      message.success('客户创建成功');
+      queryClient.invalidateQueries({ queryKey: ['clients'] });
+    }
+  });
+  
+  // 更新客户
+  const updateClient = useMutation({
+    mutationFn: async ({ id, data }: { id: string; data: any }) => {
+      const res = await clientClient[':id'].$put({
+        param: { id: Number(id) },
+        json: data,
+      });
+      if (res.status !== 200) {
+        throw new Error('更新客户失败');
+      }
+      return res.json();
+    },
+    onSuccess: () => {
+      message.success('客户更新成功');
+      queryClient.invalidateQueries({ queryKey: ['clients'] });
+    }
+  });
+  
   const handleSubmit = async () => {
     try {
       const values = await form.validateFields();
@@ -122,30 +164,36 @@ const Clients: React.FC = () => {
       
       if (editingKey) {
         // 更新操作
-        await clientClient[':id'].$put({
-          param: { id: editingKey },
-          json: values,
-        });
-        message.success('客户更新成功');
+        await updateClient.mutateAsync({ id: editingKey, data: values });
       } else {
         // 创建操作
-        await clientClient.$post({ json: values });
-        message.success('客户创建成功');
+        await createClient.mutateAsync(values);
       }
       
       setModalVisible(false);
-      run({ page: pagination.current, pageSize: pagination.pageSize });
     } catch (error) {
       message.error('操作失败,请重试');
     }
   };
   
-  // 删除操作
+  // 删除客户
+  const deleteClient = useMutation({
+    mutationFn: async (id: number) => {
+      const res = await clientClient[':id'].$delete({ param: { id: id.toString() } });
+      if (res.status !== 200) {
+        throw new Error('删除客户失败');
+      }
+      return res.json();
+    },
+    onSuccess: () => {
+      message.success('客户删除成功');
+      queryClient.invalidateQueries({ queryKey: ['clients'] });
+    }
+  });
+  
   const handleDelete = async (id: number) => {
     try {
-      await clientClient[':id'].$delete({ param: { id: id.toString() } });
-      message.success('客户删除成功');
-      run({ page: pagination.current, pageSize: pagination.pageSize });
+      await deleteClient.mutateAsync(id);
     } catch (error) {
       message.error('删除失败,请重试');
     }