You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

95 lines
2.6 KiB

interface User {
id: number;
username: string;
email: string | null;
nickname: string | null;
avatar: string | null;
role: string;
createdAt?: number;
}
interface CaptchaData {
token: string;
image: string;
}
interface ApiResponse<T> {
code: number;
message: string;
data: T | null;
}
export function useAuth() {
const user = useState<User | null>("auth-user", () => null);
const loading = ref(false);
async function loadUser() {
try {
const res = await $fetch<ApiResponse<{ user: User }>>("/api/auth/me", {
headers: process.server ? useRequestHeaders(["cookie"]) : {},
});
if (res.code === 0 && res.data?.user) {
user.value = res.data.user;
}
} catch {
// 未登录时静默处理
}
}
async function register(username: string, password: string, captchaToken: string, captchaCode: string) {
loading.value = true;
try {
const res = await $fetch<ApiResponse<{ user: User }>>("/api/auth/register", {
method: "POST",
body: { username, password, captchaToken, captchaCode },
});
if (res.code !== 0) {
return { success: false as const, message: res.message || "注册失败" };
}
await loadUser();
return { success: true as const };
} catch {
return { success: false as const, message: "网络错误,请重试" };
} finally {
loading.value = false;
}
}
async function login(username: string, password: string, captchaToken: string, captchaCode: string) {
loading.value = true;
try {
const res = await $fetch<ApiResponse<{ user: User }>>("/api/auth/login", {
method: "POST",
body: { username, password, captchaToken, captchaCode },
});
if (res.code !== 0) {
return { success: false as const, message: res.message || "登录失败" };
}
await loadUser();
return { success: true as const };
} catch {
return { success: false as const, message: "网络错误,请重试" };
} finally {
loading.value = false;
}
}
async function logout() {
await $fetch("/api/auth/logout", { method: "POST" });
user.value = null;
}
async function fetchCaptcha(): Promise<CaptchaData | null> {
const res = await $fetch<ApiResponse<CaptchaData>>("/api/auth/captcha", {
method: "POST",
});
if (res.code === 0 && res.data) {
return res.data;
}
return null;
}
const isLoggedIn = computed(() => !!user.value);
return { user, loading, isLoggedIn, loadUser, register, login, logout, fetchCaptcha };
}