diff --git a/frontend/mining-admin-web/src/app/(dashboard)/layout.tsx b/frontend/mining-admin-web/src/app/(dashboard)/layout.tsx index 474ef53c..cefc97f2 100644 --- a/frontend/mining-admin-web/src/app/(dashboard)/layout.tsx +++ b/frontend/mining-admin-web/src/app/(dashboard)/layout.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { useAppDispatch, useAppSelector } from '@/store/hooks'; import { getProfile } from '@/store/slices/auth.slice'; @@ -15,17 +15,34 @@ export default function DashboardLayout({ children }: { children: React.ReactNod const dispatch = useAppDispatch(); const { token, isAuthenticated, user } = useAppSelector((state) => state.auth); const { isCollapsed } = useSidebar(); + const [isInitialized, setIsInitialized] = useState(false); + + // 等待客户端 hydration 完成后再检查 token + useEffect(() => { + // 在客户端检查 localStorage 中是否有 token + const storedToken = localStorage.getItem('admin_token'); + if (!storedToken) { + // 确实没有 token,跳转到登录页 + router.push('/login'); + } else { + setIsInitialized(true); + } + }, [router]); useEffect(() => { - if (!token) { - router.push('/login'); - return; - } - - if (!user) { + if (isInitialized && token && !user) { dispatch(getProfile()); } - }, [token, user, dispatch, router]); + }, [isInitialized, token, user, dispatch]); + + // 等待初始化完成 + if (!isInitialized) { + return ( +
+ +
+ ); + } if (!token) { return null;