Files
xiaoxia-saas/apps/web/src/api/client.ts
T
xiaoxia 560856cf22
Deploy / Build Production Runtime Images (push) Has been skipped
Deploy / Deploy Production (push) Has been skipped
Deploy / Production Browser E2E (push) Has been skipped
Deploy / Deploy Staging (push) Failing after 210h26m26s
CI/CD Pipeline / Frontend Lint (push) Failing after 210h27m0s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 210h27m7s
fix: resolve all flake8 errors and apply Prettier formatting (#131)
2026-06-30 18:26:53 +08:00

86 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* API 客户端配置
* 封装 Axios 实例,配置拦截器和 Token 管理
*/
import axios, { AxiosError, InternalAxiosRequestConfig } from "axios";
import { message } from "antd";
import { useAuthStore } from "@/store/authStore";
// 创建 Axios 实例
const apiClient = axios.create({
baseURL: "/api/v1",
timeout: 10000,
headers: {
"Content-Type": "application/json",
},
});
// 请求拦截器:添加 Token
apiClient.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const token = localStorage.getItem("access_token");
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error: AxiosError) => {
return Promise.reject(error);
},
);
// 响应拦截器:统一错误提示 + 处理未授权状态
apiClient.interceptors.response.use(
(response) => response,
async (
error: AxiosError<{ detail?: string; message?: string; msg?: string }>,
) => {
// 401 → 清除登录态
if (error.response?.status === 401) {
useAuthStore.getState().clearAuth();
}
// 提取后端返回的错误信息(detail / message / msg
const data = error.response?.data;
const serverMsg = data?.detail || data?.message || data?.msg;
let handled = false;
if (error.code === "ECONNABORTED" || error.message?.includes("timeout")) {
message.error("请求超时,请检查网络后重试");
handled = true;
} else if (!error.response) {
message.error("网络连接异常,请检查网络设置");
handled = true;
} else if (serverMsg) {
message.error(serverMsg);
handled = true;
} else {
const status = error.response?.status;
if (status === 413) {
message.error("文件过大,请缩小后重试");
handled = true;
} else if (status === 415) {
message.error("不支持的文件格式");
handled = true;
} else if (status === 503) {
message.error("服务暂不可用,请稍后再试");
handled = true;
} else if (status && status >= 500) {
message.error("服务器繁忙,请稍后再试");
handled = true;
}
// 其他 4xx 且无具体信息时不弹通用提示,由各组件自行处理
}
// 标记已展示过提示,组件 onError 可据此跳过重复 toast
if (handled) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(error as any).__msgShown = true;
}
return Promise.reject(error);
},
);
export default apiClient;