|
|
@@ -0,0 +1,62 @@
|
|
|
+import axios, {type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios';
|
|
|
+
|
|
|
+// 自定义配置接口
|
|
|
+export interface CustomInstanceConfig extends AxiosRequestConfig {
|
|
|
+ // 可以添加自定义配置
|
|
|
+ skipAuth?: boolean; // 是否跳过鉴权
|
|
|
+}
|
|
|
+
|
|
|
+// 创建 Axios 实例
|
|
|
+const axiosInstance: AxiosInstance = axios.create({
|
|
|
+ baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
|
|
|
+ timeout: 30000,
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+// 请求拦截器
|
|
|
+axiosInstance.interceptors.request.use(
|
|
|
+ (config) => {
|
|
|
+ // 添加 token
|
|
|
+ const token = localStorage.getItem('token');
|
|
|
+ if (token) {
|
|
|
+ config.headers.Authorization = `Bearer ${token}`;
|
|
|
+ }
|
|
|
+ return config;
|
|
|
+ },
|
|
|
+ (error) => {
|
|
|
+ return Promise.reject(error);
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+// 响应拦截器
|
|
|
+axiosInstance.interceptors.response.use(
|
|
|
+ (response: AxiosResponse) => {
|
|
|
+ // 根据后端返回格式调整
|
|
|
+ if (response.data.code !== 0) {
|
|
|
+ return Promise.reject(new Error(response.data.message || '请求失败'));
|
|
|
+ }
|
|
|
+ return response.data;
|
|
|
+ },
|
|
|
+ (error) => {
|
|
|
+ // 统一错误处理
|
|
|
+ if (error.response?.status === 401) {
|
|
|
+ // 未授权,跳转登录
|
|
|
+ window.location.href = '/login';
|
|
|
+ }
|
|
|
+ return Promise.reject(error);
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+// 自定义实例函数(供 Orval 使用)
|
|
|
+export const customAxiosInstance = <T>(config: CustomInstanceConfig): Promise<T> => {
|
|
|
+ return axiosInstance(config);
|
|
|
+};
|
|
|
+
|
|
|
+// 也可以导出第二参数形式(如需处理完整响应)
|
|
|
+export const customAxiosInstanceWithFullResponse = <T>(
|
|
|
+ config: CustomInstanceConfig
|
|
|
+): Promise<AxiosResponse<T>> => {
|
|
|
+ return axiosInstance(config);
|
|
|
+};
|