import { StorageSerializers, useLocalStorage } from "@vueuse/core"; import { toast } from "vue-sonner"; import type { ICommonResponse, IUserLoginData, IUserLoginRequest, IUserLogoutData, IUserRegisterData, IUserRegisterRequest } from "#shared/types"; import { UserService } from "~/services"; const USER_INFO_STORAGE_KEY = "newapi_user_info"; export const useUserStore = defineStore("user", () => { /** 用户登录状态 */ const isOnline = ref(false); /** 用户信息 */ const userInfo = useLocalStorage( USER_INFO_STORAGE_KEY, null, { serializer: StorageSerializers.object } ); /** 登录加载状态 */ const loginLoading = ref(false); /** 注册加载状态 */ const registerLoading = ref(false); /** 登出加载状态 */ const logoutLoading = ref(false); /** 刷新当前用户信息加载状态 */ const getUserInfoLoading = ref(false); /** 用户登录 */ const login = async ( request: IUserLoginRequest ): Promise | null> => { if (loginLoading.value || isOnline.value || getUserInfoLoading.value) return null; loginLoading.value = true; try { const res = await UserService.UserLogin(request); if (res.code === 0 && res.data) { isOnline.value = true; userInfo.value = res.data; toast.success(res.msg || "登录成功"); await readyUserApiKey(); } else { isOnline.value = false; userInfo.value = null; toast.warning(res.msg || "登录失败"); } return res; } catch (err) { isOnline.value = false; userInfo.value = null; toast.error(getErrorMessage(err, "登录失败")); return null; } finally { loginLoading.value = false; } }; /** 通过 /api/auth/me 恢复刷新后的登录状态 */ const getUserInfo = async (): Promise | null> => { if (getUserInfoLoading.value) return null; getUserInfoLoading.value = true; try { const res = await UserService.UserMe(); if (res.code === 0 && res.data) { isOnline.value = true; userInfo.value = res.data; } else { isOnline.value = false; userInfo.value = null; } return res; } catch { isOnline.value = false; userInfo.value = null; return null; } finally { getUserInfoLoading.value = false; } }; /** 登录成功后准备后续 AI 调用需要的服务端 API Key,不影响登录状态本身 */ const readyUserApiKey = async () => { try { const res = await UserService.UserReady(); if (res.code !== 0) { toast.warning(res.msg || "环境准备失败"); } } catch (err) { toast.error(getErrorMessage(err, "环境准备失败")); } }; /** 用户注册 */ const register = async ( request: IUserRegisterRequest ): Promise | null> => { if (registerLoading.value || isOnline.value || getUserInfoLoading.value) return null; registerLoading.value = true; try { const res = await UserService.UserRegister(request); res.code === 0 ? toast.success(res.msg || "注册成功") : toast.warning(res.msg || "注册失败"); return res; } catch (err) { toast.error(getErrorMessage(err, "注册失败")); return null; } finally { registerLoading.value = false; } }; /** 用户登出 */ const logout = async (): Promise | null> => { if (logoutLoading.value || getUserInfoLoading.value) return null; logoutLoading.value = true; try { const res = await UserService.UserLogout(); if (res.code === 0) { toast.success(res.msg || "登出成功"); } else { toast.warning(res.msg || "登出失败"); } isOnline.value = false; userInfo.value = null; return res; } catch (err) { isOnline.value = false; userInfo.value = null; toast.error(getErrorMessage(err, "登出失败")); return null; } finally { logoutLoading.value = false; } }; return { isOnline, userInfo, loginLoading, registerLoading, logoutLoading, getUserInfoLoading, login, getUserInfo, register, logout }; });