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
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 };
|
|
}
|
|
|