/** * 用户相关 React Hooks */ import { useCallback, useEffect, useState } from 'react'; import { useUserManagerStore } from './userStore'; import { userManager } from './UserManager'; import type { UserDTO } from '../../types/dto'; // ==================== useCurrentUser ==================== export interface UseCurrentUserResult { user: UserDTO | null; isLoading: boolean; refresh: () => Promise; } /** * 获取当前用户 hook * 自动加载,支持缓存和后台刷新 */ export function useCurrentUser(): UseCurrentUserResult { const user = useUserManagerStore(state => state.currentUser); const isLoading = useUserManagerStore(state => state.isLoadingCurrentUser); const [hasFetched, setHasFetched] = useState(false); useEffect(() => { if (!hasFetched) { setHasFetched(true); useUserManagerStore.getState().setLoadingCurrentUser(true); userManager.getCurrentUser().finally(() => { useUserManagerStore.getState().setLoadingCurrentUser(false); }); } }, [hasFetched]); const refresh = useCallback(async () => { useUserManagerStore.getState().setLoadingCurrentUser(true); try { return await userManager.getCurrentUser(true); } finally { useUserManagerStore.getState().setLoadingCurrentUser(false); } }, []); return { user, isLoading, refresh }; } // ==================== useUser ==================== export interface UseUserResult { user: UserDTO | null; isLoading: boolean; refresh: () => Promise; } /** * 根据 ID 获取用户 hook * 自动加载,支持缓存和后台刷新 */ export function useUser(userId: string | undefined | null): UseUserResult { const user = useUserManagerStore(state => userId ? (state.usersMap.get(userId)?.data ?? null) : null ); const isLoading = useUserManagerStore(state => userId ? state.loadingUserIds.has(userId) : false ); const [hasFetched, setHasFetched] = useState(false); useEffect(() => { if (!userId) return; if (!hasFetched) { setHasFetched(true); useUserManagerStore.getState().setLoadingUser(userId, true); userManager.getUserById(userId).finally(() => { useUserManagerStore.getState().setLoadingUser(userId, false); }); } }, [userId, hasFetched]); const refresh = useCallback(async () => { if (!userId) return null; useUserManagerStore.getState().setLoadingUser(userId, true); try { return await userManager.getUserById(userId, true); } finally { useUserManagerStore.getState().setLoadingUser(userId, false); } }, [userId]); return { user, isLoading, refresh }; } // ==================== useUsers ==================== export interface UseUsersResult { getUser: (id: string) => UserDTO | null; refreshUser: (id: string) => Promise; } /** * 多用户获?hook * 用于批量获取多个用户信息 */ export function useUsers(userIds: string[]): UseUsersResult { const usersMap = useUserManagerStore(state => state.usersMap); const loadingUserIds = useUserManagerStore(state => state.loadingUserIds); const [fetchedIds, setFetchedIds] = useState>(new Set()); useEffect(() => { userIds.forEach(id => { if (!fetchedIds.has(id) && !loadingUserIds.has(id)) { setFetchedIds(prev => new Set(prev).add(id)); useUserManagerStore.getState().setLoadingUser(id, true); userManager.getUserById(id).finally(() => { useUserManagerStore.getState().setLoadingUser(id, false); }); } }); }, [userIds, fetchedIds, loadingUserIds]); const getUser = useCallback((id: string) => { return usersMap.get(id)?.data ?? null; }, [usersMap]); const refreshUser = useCallback(async (id: string) => { useUserManagerStore.getState().setLoadingUser(id, true); try { return await userManager.getUserById(id, true); } finally { useUserManagerStore.getState().setLoadingUser(id, false); } }, []); return { getUser, refreshUser }; }