Files
aiartstudio/app/stores/user.ts
T

176 lines
4.4 KiB
TypeScript

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<IUserLoginData | null>(
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<ICommonResponse<IUserLoginData> | 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<ICommonResponse<IUserLoginData> | 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<ICommonResponse<IUserRegisterData> | 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<ICommonResponse<IUserLogoutData> | 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
};
});