This commit is contained in:
ryan
2026-07-13 15:17:45 +08:00
parent 08e61ce833
commit e0eb4e5975
334 changed files with 17212 additions and 12321 deletions
+56 -53
View File
@@ -1,29 +1,34 @@
"use client"
'use client';
import {createContext, ReactNode, useCallback, useContext, useEffect, useRef, useState} from 'react'
import {AuthService} from '@/lib/services/auth'
import {User} from '@/lib/services/auth/types'
import {
createContext,
ReactNode,
useCallback,
useContext,
useEffect,
useRef,
useState,
} from 'react';
import { AuthService } from '@/lib/services/auth';
import { User } from '@/lib/services/auth/types';
/** 用户状态接口 */
interface UserState {
user: User | null
loading: boolean
error: string | null
user: User | null;
loading: boolean;
error: string | null;
}
/** 用户上下文接口 */
interface UserContextValue extends UserState {
setUser: (user: User) => void
refetch: () => Promise<void>
logout: () => Promise<void>
setUser: (user: User) => void;
refetch: () => Promise<void>;
logout: () => Promise<void>;
}
/** 用户上下文 */
const UserContext = createContext<UserContextValue | undefined>(undefined)
const UserContext = createContext<UserContextValue | undefined>(undefined);
/**
* 用户Provider组件
@@ -44,83 +49,81 @@ export function UserProvider({ children }: { children: ReactNode }) {
user: null,
loading: true,
error: null,
})
const isMountedRef = useRef(true)
});
const isMountedRef = useRef(true);
/** 获取用户信息 */
const fetchUser = useCallback(async () => {
try {
setState(prev => ({ ...prev, loading: true, error: null }))
const user = await AuthService.getUserInfo()
setState((prev) => ({ ...prev, loading: true, error: null }));
const user = await AuthService.getUserInfo();
if (!isMountedRef.current) return
if (!isMountedRef.current) return;
setState({ user, loading: false, error: null })
setState({ user, loading: false, error: null });
} catch (error) {
if (!isMountedRef.current) return
if (!isMountedRef.current) return;
setState({
user: null,
loading: false,
error: error instanceof Error ? error.message : '获取用户信息失败',
})
});
}
}, [])
}, []);
/** 重新获取用户信息 */
const refetch = useCallback(async () => {
await fetchUser()
}, [fetchUser])
await fetchUser();
}, [fetchUser]);
/** 直接设置用户信息(登录/注册后免二次请求) */
const setUser = useCallback((user: User) => {
setState({ user, loading: false, error: null })
}, [])
setState({ user, loading: false, error: null });
}, []);
/** 用户登出 */
const logout = useCallback(async () => {
try {
await AuthService.logout()
await AuthService.logout();
if (!isMountedRef.current) return
if (!isMountedRef.current) return;
setState({ user: null, loading: false, error: null })
window.location.href = '/login'
setState({ user: null, loading: false, error: null });
window.location.href = '/login';
} catch (error) {
if (!isMountedRef.current) {
throw error
throw error;
}
const errorMessage = error instanceof Error ? error.message : '登出失败'
setState(prev => ({
const errorMessage = error instanceof Error ? error.message : '登出失败';
setState((prev) => ({
...prev,
error: errorMessage,
}))
throw new Error(errorMessage)
}));
throw new Error(errorMessage);
}
}, [])
}, []);
/** 组件挂载时获取用户信息(登录/注册页跳过,避免无意义请求) */
useEffect(() => {
isMountedRef.current = true
isMountedRef.current = true;
const path = window.location.pathname
if (path === "/login" || path === "/register") {
setState({user: null, loading: false, error: null})
const path = window.location.pathname;
if (path === '/login' || path === '/register') {
setState({ user: null, loading: false, error: null });
return () => {
isMountedRef.current = false
}
isMountedRef.current = false;
};
}
fetchUser()
fetchUser();
return () => {
isMountedRef.current = false
}
}, [fetchUser])
isMountedRef.current = false;
};
}, [fetchUser]);
return (
<UserContext.Provider
@@ -133,7 +136,7 @@ export function UserProvider({ children }: { children: ReactNode }) {
>
{children}
</UserContext.Provider>
)
);
}
/**
@@ -146,9 +149,9 @@ export function UserProvider({ children }: { children: ReactNode }) {
* ```
*/
export function useUser(): UserContextValue {
const context = useContext(UserContext)
const context = useContext(UserContext);
if (context === undefined) {
throw new Error('useUser must be used within a UserProvider')
throw new Error('useUser must be used within a UserProvider');
}
return context
return context;
}