import axios from 'axios'; import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; import { envConfig } from '../config/env'; // Token 存储键名(与 auth service 保持一致) const TOKEN_KEY = 'access_token'; // 创建 axios 实例 const apiClient: AxiosInstance = axios.create({ baseURL: envConfig.apiBaseUrl, timeout: 30000, // 30秒超时 headers: { 'Content-Type': 'application/json', }, }); // 请求拦截器 apiClient.interceptors.request.use( (config) => { // 自动添加 token 到请求头 const token = localStorage.getItem(TOKEN_KEY); if (token) { config.headers.Authorization = `Bearer ${token}`; } if (envConfig.debug) { console.log('请求:', config.method?.toUpperCase(), config.url); } return config; }, (error) => { if (envConfig.debug) { console.error('请求错误:', error); } return Promise.reject(error); } ); // 响应拦截器 apiClient.interceptors.response.use( (response: AxiosResponse) => { if (envConfig.debug) { console.log('响应:', response.config.url, response.data); } return response; }, (error) => { if (envConfig.debug) { console.error('响应错误:', error.response?.data || error.message); } // 处理常见错误 if (error.response) { switch (error.response.status) { case 401: // 未授权,清除 token 并跳转到登录页 localStorage.removeItem(TOKEN_KEY); localStorage.removeItem('user_info'); // 避免在登录页重复跳转 if (window.location.pathname !== '/login') { window.location.href = '/login'; } break; case 403: console.error('没有权限访问该资源'); break; case 404: console.error('请求的资源不存在'); break; case 500: console.error('服务器内部错误'); break; default: console.error('请求失败:', error.response.data?.message || error.message); } } else if (error.request) { console.error('网络错误,请检查网络连接'); } return Promise.reject(error); } ); // 导出常用的请求方法 export const api = { get: (url: string, config?: AxiosRequestConfig) => apiClient.get(url, config).then((res) => res.data), post: (url: string, data?: any, config?: AxiosRequestConfig) => apiClient.post(url, data, config).then((res) => res.data), put: (url: string, data?: any, config?: AxiosRequestConfig) => apiClient.put(url, data, config).then((res) => res.data), patch: (url: string, data?: any, config?: AxiosRequestConfig) => apiClient.patch(url, data, config).then((res) => res.data), delete: (url: string, config?: AxiosRequestConfig) => apiClient.delete(url, config).then((res) => res.data), }; // 导出 axios 实例(用于特殊需求) export default apiClient;