"use client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { useRef, useEffect } from "react"; import { useRouter, usePathname } from "next/navigation"; import { useAuthStore } from "@/stores/auth"; import { TooltipProvider } from "@/components/ui/tooltip"; // 公开路由(无需鉴权) const PUBLIC_PATHS = ["/login", "/register"]; function AuthLoader({ children }: { children: React.ReactNode }) { const fetchUser = useAuthStore((s) => s.fetchUser); const isLoading = useAuthStore((s) => s.isLoading); const isAuthenticated = useAuthStore((s) => s.isAuthenticated); const router = useRouter(); const pathname = usePathname(); const isPublic = PUBLIC_PATHS.some((p) => pathname === p || pathname.startsWith(p + "/")); useEffect(() => { if (!isPublic) { fetchUser(); } }, [fetchUser, isPublic]); // 鉴权路由:未登录则跳转(useEffect 中执行,避免渲染期间调用 router) useEffect(() => { if (!isLoading && !isAuthenticated && !isPublic) { router.push("/login"); } }, [isLoading, isAuthenticated, isPublic, router]); // 公开路由:直接渲染,不阻塞 if (isPublic) { return <>{children}; } // 加载中或未认证 if (isLoading || !isAuthenticated) { return (
); } return <>{children}; } export function Providers({ children }: { children: React.ReactNode }) { const queryClientRef = useRef(null); if (!queryClientRef.current) { queryClientRef.current = new QueryClient({ defaultOptions: { queries: { // 高频变更数据(审计、用户列表) staleTime: 30 * 1000, gcTime: 5 * 60 * 1000, refetchOnWindowFocus: false, retry: 1, refetchOnMount: "always", }, }, }); } return ( {children} ); }