Files
anxinyan/admin-web/src/api/request.ts
2026-05-15 14:01:36 +08:00

83 lines
2.2 KiB
TypeScript

import axios from "axios";
import { clearAdminSession, getAdminToken } from "../utils/auth";
import { resolveApiBaseUrl } from "../utils/env";
import { goToAdminLogin } from "../utils/navigation";
interface ApiPayload {
code?: number;
message?: string;
data?: unknown;
}
function redirectToLoginOnUnauthorized() {
clearAdminSession();
goToAdminLogin();
}
const request = axios.create({
baseURL: resolveApiBaseUrl(),
timeout: 20000,
});
request.interceptors.request.use((config) => {
const token = getAdminToken();
if (token) {
config.headers = config.headers || {};
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
request.interceptors.response.use(
(response) => {
if (response.config.responseType === "blob" || response.config.responseType === "arraybuffer") {
const contentType = String(response.headers?.["content-type"] || "");
if (response.data instanceof Blob && contentType.includes("application/json")) {
return response.data.text().then((text) => {
let payload: ApiPayload | null = null;
try {
payload = JSON.parse(text) as ApiPayload;
} catch {
payload = null;
}
const error = new Error(payload?.message || "请求失败") as Error & {
payload?: ApiPayload | null;
status?: number;
};
error.payload = payload;
error.status = response.status;
return Promise.reject(error);
}) as any;
}
return response.data as any;
}
const payload = response.data as ApiPayload;
if (payload?.code === 0) {
return payload as any;
}
if (payload?.code === 401) {
redirectToLoginOnUnauthorized();
}
const error = new Error(payload?.message || "请求失败") as Error & {
payload?: ApiPayload;
status?: number;
};
error.payload = payload;
error.status = response.status;
return Promise.reject(error);
},
(error) => {
const status = error?.response?.status;
if (status === 401) {
redirectToLoginOnUnauthorized();
}
return Promise.reject(error);
},
);
export default request;