11
This commit is contained in:
38
src/api/auth.js
Normal file
38
src/api/auth.js
Normal 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
62
src/api/client.js
Normal 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 };
|
||||
Reference in New Issue
Block a user