100 lines
3.0 KiB
TypeScript
100 lines
3.0 KiB
TypeScript
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<UserInfoType | undefined>;
|
|
updateUserInfo: (userInfo: Partial<UserInfoType>) => void;
|
|
nicknameChangeStatus: Partial<NicknameChangeStatus>;
|
|
checkNicknameChangeStatus: () => void;
|
|
updateNickname: (nickname: string) => void;
|
|
}
|
|
|
|
// 请求锁,防止重复请求
|
|
let fetchingUserInfo = false;
|
|
let fetchUserInfoPromise: Promise<UserInfoType | undefined> | 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<UserState>()((set) => ({
|
|
user: {},
|
|
fetchUserInfo: () => fetchUserInfoWithLock(set),
|
|
updateUserInfo: async (userInfo: Partial<UserInfoType>) => {
|
|
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,
|
|
}));
|