【操盘手】修复退出登录反复跳转问题

This commit is contained in:
wong
2025-05-23 16:47:37 +08:00
parent a3da60eace
commit c2497ec433
3 changed files with 26 additions and 15 deletions

View File

@@ -147,6 +147,7 @@ export function AuthProvider({ children }: AuthProviderProps) {
}, []) // 空依赖数组,仅在组件挂载时执行一次 }, []) // 空依赖数组,仅在组件挂载时执行一次
const handleLogout = () => { const handleLogout = () => {
// 先清除所有认证相关的状态
safeLocalStorage.removeItem("token") safeLocalStorage.removeItem("token")
safeLocalStorage.removeItem("token_expired") safeLocalStorage.removeItem("token_expired")
safeLocalStorage.removeItem("s2_accountId") safeLocalStorage.removeItem("s2_accountId")
@@ -155,11 +156,16 @@ export function AuthProvider({ children }: AuthProviderProps) {
setToken(null) setToken(null)
setUser(null) setUser(null)
setIsAuthenticated(false) setIsAuthenticated(false)
// 使用 window.location 而不是 router.push避免状态更新和路由跳转的竞态条件
if (typeof window !== 'undefined') {
window.location.href = '/login'
}
} }
const login = (newToken: string, userData: User) => { const login = (newToken: string, userData: User) => {
safeLocalStorage.setItem("token", newToken) safeLocalStorage.setItem("token", newToken)
safeLocalStorage.setItem("user", JSON.stringify(userData)) safeLocalStorage.setItem("userInfo", JSON.stringify(userData))
setToken(newToken) setToken(newToken)
setUser(userData) setUser(userData)
setIsAuthenticated(true) setIsAuthenticated(true)
@@ -167,8 +173,6 @@ export function AuthProvider({ children }: AuthProviderProps) {
const logout = () => { const logout = () => {
handleLogout() handleLogout()
// 登出后不强制跳转到登录页
// router.push("/login")
} }
// 用于刷新 token 的方法 // 用于刷新 token 的方法

View File

@@ -155,10 +155,19 @@ export default function LoginPage() {
useEffect(() => { useEffect(() => {
// 检查是否已登录,如果已登录且不在登录页面,则跳转到首页 // 检查是否已登录,如果已登录且不在登录页面,则跳转到首页
if (isAuthenticated && window.location.pathname === '/login') { if (isAuthenticated) {
router.push("/") // 获取重定向URL
const params = new URLSearchParams(window.location.search)
const returnUrl = params.get('returnUrl')
// 如果有重定向URL则跳转到该URL否则跳转到首页
if (returnUrl) {
window.location.href = decodeURIComponent(returnUrl)
} else {
window.location.href = "/"
}
} }
}, [isAuthenticated, router]) }, [isAuthenticated])
return ( return (
<div className="min-h-screen bg-white text-gray-900 flex flex-col px-4 py-8"> <div className="min-h-screen bg-white text-gray-900 flex flex-col px-4 py-8">

View File

@@ -93,12 +93,11 @@ export const request = async <T>(
// 使用响应拦截器处理响应 // 使用响应拦截器处理响应
if (result && result.code === 401) { if (result && result.code === 401) {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
// 只清除 token不进行重定向
localStorage.removeItem('token'); localStorage.removeItem('token');
localStorage.removeItem('user'); localStorage.removeItem('userInfo');
// 使用客户端导航而不是直接修改window.location // 使用 window.location 进行一次性重定向
setTimeout(() => { window.location.href = '/login';
window.location.href = '/login';
}, 0);
} }
throw new Error(result.msg || '登录已过期,请重新登录'); throw new Error(result.msg || '登录已过期,请重新登录');
} }
@@ -113,11 +112,10 @@ export const request = async <T>(
(error.message.toLowerCase().includes('unauthorized') && (error.message.toLowerCase().includes('unauthorized') &&
error.message.toLowerCase().includes('token')))) { error.message.toLowerCase().includes('token')))) {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
// 只清除 token不进行重定向
localStorage.removeItem('token'); localStorage.removeItem('token');
localStorage.removeItem('user'); localStorage.removeItem('userInfo');
setTimeout(() => { // 重定向逻辑由 AuthProvider 统一处理
window.location.href = '/login';
}, 0);
} }
} }