45 lines
1.1 KiB
TypeScript
45 lines
1.1 KiB
TypeScript
export const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
|
|
|
|
export function getApiUrl(path: string): string {
|
|
return `${API_BASE}${path}`;
|
|
}
|
|
|
|
export async function fetchWithAuth(
|
|
url: string,
|
|
options: RequestInit = {},
|
|
token?: string
|
|
) {
|
|
const headers: Record<string, string> = {
|
|
"Content-Type": "application/json",
|
|
...((options.headers as Record<string, string>) || {}),
|
|
};
|
|
if (token) {
|
|
headers["Authorization"] = `Bearer ${token}`;
|
|
}
|
|
const res = await fetch(`${API_BASE}${url}`, { ...options, headers });
|
|
|
|
if (res.status === 401) {
|
|
if (typeof window !== "undefined") {
|
|
window.location.href = "/login";
|
|
}
|
|
throw new Error("登录已过期,请重新登录");
|
|
}
|
|
|
|
if (!res.ok) {
|
|
let errorDetail = `请求失败 (HTTP ${res.status})`;
|
|
try {
|
|
const error = await res.json();
|
|
errorDetail = error.detail || error.message || errorDetail;
|
|
} catch {
|
|
// 解析失败,使用默认错误信息
|
|
}
|
|
throw new Error(errorDetail);
|
|
}
|
|
|
|
if (res.status === 204) {
|
|
return null;
|
|
}
|
|
|
|
return res.json();
|
|
}
|