This commit is contained in:
fengchuanhn@gmail.com
2026-05-15 18:50:42 +08:00
parent 584d4c47a1
commit 28b2b4d686
9 changed files with 218 additions and 53 deletions

38
src/api/auth.js Normal file
View File

@@ -0,0 +1,38 @@
import { apiRequest } from "./client.js";
/**
* @param {{ username: string, password: string, confirmPassword: string }} payload
*/
export function registerApi(payload) {
return apiRequest("/auth/register", {
method: "POST",
body: JSON.stringify({
username: payload.username,
password: payload.password,
confirmPassword: payload.confirmPassword,
}),
});
}
/**
* @param {{ username: string, password: string }} payload
*/
export function loginApi(payload) {
return apiRequest("/auth/login", {
method: "POST",
body: JSON.stringify({
username: payload.username,
password: payload.password,
}),
});
}
/** @param {string} token */
export function logoutApi(token) {
return apiRequest("/auth/logout", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
},
});
}

62
src/api/client.js Normal file
View File

@@ -0,0 +1,62 @@
/** API 基址:开发走 Vite 代理 `/api`;生产可设 VITE_API_BASE_URL */
const API_BASE = import.meta.env.VITE_API_BASE_URL || "/api/v1";
function formatValidationDetail(detail) {
if (!Array.isArray(detail)) {
return "请求参数无效";
}
const first = detail[0];
if (first?.msg) {
return String(first.msg);
}
return "请求参数无效";
}
/**
* @param {string} path - 相对路径,如 `/auth/register`
* @param {RequestInit} options
* @returns {Promise<{ ok: boolean, message: string, data?: unknown }>}
*/
export async function apiRequest(path, options = {}) {
const url = `${API_BASE}${path}`;
const headers = {
"Content-Type": "application/json",
...options.headers,
};
let res;
try {
res = await fetch(url, { ...options, headers });
} catch {
return { ok: false, message: "无法连接服务器,请确认后端已启动" };
}
let body = null;
try {
body = await res.json();
} catch {
body = null;
}
if (res.status === 422) {
return {
ok: false,
message: formatValidationDetail(body?.detail),
};
}
if (body && typeof body.ok === "boolean") {
return body;
}
if (res.status === 401) {
return { ok: false, message: "未登录或登录已过期" };
}
return {
ok: false,
message: body?.message || `请求失败(${res.status}`,
};
}
export { API_BASE };