geo/frontend/lib/api/client.ts

62 lines
1.5 KiB
TypeScript

import { getSession } from "next-auth/react";
import type { Session } from "next-auth";
export const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
export function getApiUrl(path: string): string {
return `${API_BASE}${path}`;
}
export type ResponseType = "json" | "blob";
export async function fetchWithAuth(
url: string,
options: RequestInit = {},
token?: string,
responseType: ResponseType = "json"
) {
let authToken = token;
if (!authToken && typeof window !== "undefined") {
try {
const session = await getSession();
authToken = (session as Session)?.accessToken;
} catch {
// ignore session fetch error
}
}
const headers: Record<string, string> = {
"Content-Type": "application/json",
...((options.headers as Record<string, string>) || {}),
};
if (authToken) {
headers["Authorization"] = `Bearer ${authToken}`;
}
const res = await fetch(`${API_BASE}${url}`, { ...options, headers });
if (res.status === 401) {
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;
}
if (responseType === "blob") {
return res.blob();
}
return res.json();
}