import { create } from "zustand"; import { fetchUserProfile, updateUserProfile, UserInfoType, checkNicknameChangeStatus as checkNicknameChangeStatusApi, NicknameChangeStatus, updateNickname as updateNicknameApi, } from "@/services/userService"; export interface UserState { user: UserInfoType | {}; fetchUserInfo: () => Promise; updateUserInfo: (userInfo: Partial) => void; nicknameChangeStatus: Partial; checkNicknameChangeStatus: () => void; updateNickname: (nickname: string) => void; } // 请求锁,防止重复请求 let fetchingUserInfo = false; let fetchUserInfoPromise: Promise | null = null; const fetchUserInfoWithLock = async (set) => { // 如果正在请求,直接返回现有的 Promise if (fetchingUserInfo && fetchUserInfoPromise) { return fetchUserInfoPromise; } fetchingUserInfo = true; fetchUserInfoPromise = (async () => { try { const res = await fetchUserProfile(); set({ user: res.data }); return res.data; } catch (error) { console.error("获取用户信息失败:", error); return undefined; } finally { fetchingUserInfo = false; fetchUserInfoPromise = null; } })(); return fetchUserInfoPromise; }; export const useUser = create()((set) => ({ user: {}, fetchUserInfo: () => fetchUserInfoWithLock(set), updateUserInfo: async (userInfo: Partial) => { try { // 先更新后端 await updateUserProfile(userInfo); // 然后立即更新本地状态(乐观更新) set((state) => ({ user: { ...state.user, ...userInfo }, })); // 不再每次都重新获取完整用户信息,减少请求次数 // 只有在更新头像等需要服务器返回新URL的字段时才需要重新获取 // 如果需要确保数据一致性,可以在特定场景下手动调用 fetchUserInfo } catch (error) { console.error("更新用户信息失败:", error); throw error; } }, nicknameChangeStatus: {}, checkNicknameChangeStatus: async () => { try { const res = await checkNicknameChangeStatusApi(); set({ nicknameChangeStatus: res.data }); } catch (error) { console.error("检查昵称变更状态失败:", error); } }, updateNickname: async (nickname) => { try { await updateNicknameApi(nickname); await useUser.getState().checkNicknameChangeStatus(); set((state) => ({ user: { ...state.user, nickname }, })); } catch (error) { console.error("更新用户昵称失败:", error); } }, })); export const useUserInfo = () => useUser((state) => state.user); export const useNicknameChangeStatus = () => useUser((state) => state.nicknameChangeStatus); export const useUserActions = () => useUser((state) => ({ fetchUserInfo: state.fetchUserInfo, updateUserInfo: state.updateUserInfo, checkNicknameChangeStatus: state.checkNicknameChangeStatus, updateNickname: state.updateNickname, }));