/** * 用户状态管理 * 使用Zustand进行状态管理 * 对接真实后端API */ import { create } from 'zustand'; import { User, Post, Notification, NotificationBadge } from '../types'; import { PaginatedData } from '../services/api'; import { authService, postService, notificationService, } from '../services'; import { userManager } from './userManager'; import { messageManager } from './messageManager'; interface UserState { // 状态 users: User[]; userCache: Record; // 用户缓存 posts: Post[]; notifications: Notification[]; notificationBadge: NotificationBadge; messageUnreadCount: number; // 加载状态 isLoadingPosts: boolean; isLoadingNotifications: boolean; // 搜索历史 searchHistory: string[]; // 操作 fetchUser: (userId: string) => Promise; fetchUserPosts: (userId: string, page?: number) => Promise; fetchPosts: (type: 'follow' | 'hot' | 'latest', page?: number) => Promise>; fetchNotifications: (type?: string, page?: number) => Promise; markNotificationAsRead: (notificationId: string) => Promise; markAllNotificationsAsRead: () => Promise; fetchNotificationBadge: () => Promise; setMessageUnreadCount: (count: number) => void; addSearchHistory: (keyword: string) => void; clearSearchHistory: () => void; // 关注用户操作(authService 不管理状态,所以保留在 store) followUser: (userId: string) => Promise; unfollowUser: (userId: string) => Promise; // 刷新数据 refreshAll: () => Promise; } export const useUserStore = create((set, get) => { return { // 初始状态 users: [], userCache: {}, posts: [], notifications: [], notificationBadge: { total: 0, likes: 0, comments: 0, follows: 0, system: 0, }, messageUnreadCount: 0, searchHistory: [], isLoadingPosts: false, isLoadingNotifications: false, // 获取用户信息 fetchUser: async (userId: string) => { // 先检查缓存 const cached = get().userCache[userId]; if (cached) return cached; try { const user = await userManager.getUserById(userId); if (user) { set(state => ({ userCache: { ...state.userCache, [userId]: user } })); return user; } } catch (error) { console.error('获取用户信息失败:', error); } return undefined; }, // 获取用户帖子 fetchUserPosts: async (userId: string, page = 1) => { try { const response = await postService.getUserPosts(userId, page); const newPosts = response.list; set(state => ({ posts: page === 1 ? newPosts : [...state.posts, ...newPosts] })); return newPosts; } catch (error) { console.error('获取用户帖子失败:', error); return []; } }, // 获取帖子列表(首页) fetchPosts: async (type: 'follow' | 'hot' | 'latest', page = 1) => { set({ isLoadingPosts: true }); try { let response; switch (type) { case 'follow': response = await postService.getFollowingPosts(page); break; case 'hot': response = await postService.getHotPosts(page); break; case 'latest': default: response = await postService.getLatestPosts(page); break; } const newPosts = response.list; set(state => ({ posts: page === 1 ? newPosts : [...state.posts, ...newPosts], isLoadingPosts: false })); return response; } catch (error) { console.error('获取帖子列表失败:', error); set({ isLoadingPosts: false }); return { list: [], total: 0, page, page_size: 20, total_pages: 0, }; } }, // 获取通知列表 fetchNotifications: async (type?: string, page = 1) => { set({ isLoadingNotifications: true }); try { const response = await notificationService.getNotifications( page, 20, type as any ); const newNotifications = response.list; set(state => ({ notifications: page === 1 ? newNotifications : [...state.notifications, ...newNotifications], isLoadingNotifications: false })); return newNotifications; } catch (error) { console.error('获取通知列表失败:', error); set({ isLoadingNotifications: false }); return []; } }, // 标记通知为已读 markNotificationAsRead: async (notificationId: string) => { try { await notificationService.markAsRead(notificationId); set(state => { const notifications = state.notifications.map(n => n.id === notificationId ? { ...n, isRead: true } : n ); return { notifications, notificationBadge: { total: notifications.filter(n => !n.isRead).length, likes: notifications.filter(n => n.type === 'like_post' && !n.isRead).length, comments: notifications.filter(n => n.type === 'comment' && !n.isRead).length, follows: notifications.filter(n => n.type === 'follow' && !n.isRead).length, system: notifications.filter(n => n.type === 'system' && !n.isRead).length, } }; }); } catch (error) { console.error('标记通知为已读失败:', error); } }, // 标记所有通知为已读 markAllNotificationsAsRead: async () => { try { await notificationService.markAllAsRead(); set(state => ({ notifications: state.notifications.map(n => ({ ...n, isRead: true })), notificationBadge: { total: 0, likes: 0, comments: 0, follows: 0, system: 0, } })); } catch (error) { console.error('标记所有通知为已读失败:', error); } }, // 获取通知角标 fetchNotificationBadge: async () => { try { const badge = await notificationService.getNotificationBadge(); set({ notificationBadge: badge }); } catch (error) { console.error('获取通知角标失败:', error); } }, // 设置消息未读数 // 注意:未读数现在由 MessageManager 统一管理 // 此方法保留用于 TabBar 角标显示,从 MessageManager 同步 setMessageUnreadCount: (count: number) => { set({ messageUnreadCount: count }); }, // 添加搜索历史 addSearchHistory: (keyword: string) => { set(state => { const history = [keyword, ...state.searchHistory.filter(k => k !== keyword)].slice(0, 20); return { searchHistory: history }; }); }, // 清除搜索历史 clearSearchHistory: () => { set({ searchHistory: [] }); }, // 关注用户 - authService 不管理状态,所以由 store 管理 followUser: async (userId: string) => { const originalUsers = get().users; const originalUserCache = get().userCache; set(state => ({ users: state.users.map(u => u.id === userId ? { ...u, isFollowing: true, followersCount: u.followers_count + 1 } : u ), userCache: Object.fromEntries( Object.entries(state.userCache).map(([id, user]) => [ id, id === userId ? { ...user, isFollowing: true, followersCount: user.followers_count + 1 } : user ]) ) })); try { await authService.followUser(userId); } catch (error) { console.error('关注用户失败:', error); set({ users: originalUsers, userCache: originalUserCache }); } }, unfollowUser: async (userId: string) => { const originalUsers = get().users; const originalUserCache = get().userCache; set(state => ({ users: state.users.map(u => u.id === userId ? { ...u, isFollowing: false, followersCount: Math.max(0, u.followers_count - 1) } : u ), userCache: Object.fromEntries( Object.entries(state.userCache).map(([id, user]) => [ id, id === userId ? { ...user, isFollowing: false, followersCount: Math.max(0, user.followers_count - 1) } : user ]) ) })); try { await authService.unfollowUser(userId); } catch (error) { console.error('取消关注用户失败:', error); set({ users: originalUsers, userCache: originalUserCache }); } }, // 刷新所有数据 refreshAll: async () => { await Promise.all([ get().fetchPosts('latest', 1), get().fetchNotificationBadge(), ]); }, }; }); // 导出selector hooks以优化性能 export const usePosts = () => useUserStore((state) => state.posts); export const useNotifications = () => useUserStore((state) => state.notifications); export const useNotificationBadge = () => useUserStore((state) => state.notificationBadge); export const useMessageUnreadCount = () => useUserStore((state) => state.messageUnreadCount); export const useSearchHistory = () => useUserStore((state) => state.searchHistory); export const useIsLoadingPosts = () => useUserStore((state) => state.isLoadingPosts);