import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { ColumnsType } from "antd/es/table"; import { forwardRef, useImperativeHandle, useState } from "react"; import { ErrorHandle } from "~/service/config/error"; import { XTable } from "./table"; interface TableQueryProps { queryKey: string; // 查询key fetchFn: (params: any) => Promise; // 查询函数 deleteFn?: (id: string) => Promise; // 删除函数 columns: ColumnsType; // 列配置 // 过滤条件/分页 defaultFilters?: { page: number; size: number; [property: string]: any; }; } export interface TableQueryRef { setFilters: (filters: any) => void; // 设置过滤条件 handleAddSuccess: () => void; // 添加成功处理 handleEditSuccess: (item: T) => void; // 编辑成功处理 delMutate: (id: string) => void; // 删除 delIsPending: boolean; // 删除状态 } export const TableQuery = forwardRef, TableQueryProps>( function TableQuery( { queryKey, fetchFn, deleteFn, columns, defaultFilters = { page: 1, size: 10 }, }, ref, ) { const [filters, setFilters] = useState(defaultFilters); const queryClient = useQueryClient(); // 查询数据 const { data, isLoading } = useQuery({ queryKey: [queryKey, filters], queryFn: () => fetchFn(filters), refetchInterval: 5000, throwOnError: (err) => { ErrorHandle(err); return true; }, }); // 删除功能 const { mutate: delMutate, isPending: delIsPending } = useMutation({ mutationFn: deleteFn, onError: ErrorHandle, onSuccess: (data) => { queryClient.setQueryData([queryKey, filters], (old: any) => { const newItems = old.data.items.filter( (item: any) => item.id !== data.data.id, ); // 如果当前页数据为空且不是第一页,回退一页 if (newItems.length === 0 && filters.page > 1) { setTimeout(() => { setFilters((prev) => ({ ...prev, page: prev.page - 1 })); }, 370); } // 如果是第一页且数据为空,刷新当前页 else if (newItems.length === 0 && filters.page === 1) { setTimeout(() => { queryClient.invalidateQueries({ queryKey: [queryKey, filters], }); }, 370); } return { ...old, data: { ...old.data, items: newItems, }, }; }); }, }); // 添加成功处理 const handleAddSuccess = () => { if (filters.page !== 1) { setFilters({ page: 1, size: filters.size }); return; } queryClient.invalidateQueries({ queryKey: [queryKey], }); }; // 编辑成功处理 const handleEditSuccess = (updatedItem: any) => { queryClient.setQueryData([queryKey, filters], (old: any) => { if (!old?.data) { console.log("🚀 ~ queryClient.setQueryData ~ old:", old); queryClient.invalidateQueries({ queryKey: [queryKey], }); return old; } return { ...old, data: { ...old.data, items: old.data.items.map((item: any) => item.id === updatedItem.id ? updatedItem : item, ), }, }; }); }; // 暴露内部方法 useImperativeHandle(ref, () => ({ setFilters, handleAddSuccess, handleEditSuccess, delMutate, delIsPending, })); return ( { setFilters({ ...filters, page, size }); }, }} /> ); }, );