import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; import type { ApiError, ApiResponse } from './types'; // 创建 Axios 实例 const createApiClient = (): AxiosInstance => { const baseURL = process.env.NEXT_PUBLIC_API_URL || ''; const instance = axios.create({ baseURL, timeout: 30000, headers: { 'Content-Type': 'application/json', }, }); // 请求拦截器 instance.interceptors.request.use( (config) => { // 自动添加 JWT Token if (typeof window !== 'undefined') { const token = localStorage.getItem('auth_token'); if (token && config.headers) { config.headers.Authorization = `Bearer ${token}`; } // 添加企业 ID const companyId = localStorage.getItem('company_id'); if (companyId && config.headers) { config.headers['X-Company-ID'] = companyId; } } return config; }, (error) => { return Promise.reject(error); } ); // 响应拦截器 instance.interceptors.response.use( (response: AxiosResponse) => { return response; }, (error: AxiosError) => { // 统一错误处理 const apiError: ApiError = { code: 'UNKNOWN_ERROR', message: '未知错误', }; if (error.response) { // 服务器返回错误 const { data, status } = error.response; if (data && typeof data === 'object' && 'error' in data) { const errorData = data as { error: { code: string; message: string; details?: unknown } }; apiError.code = errorData.error.code; apiError.message = errorData.error.message; apiError.details = errorData.error.details; } else { apiError.code = `HTTP_${status}`; apiError.message = error.message; } // 401 未授权 - 跳转登录 if (status === 401) { if (typeof window !== 'undefined') { localStorage.removeItem('auth_token'); localStorage.removeItem('company_id'); window.location.href = '/login'; } } } else if (error.request) { // 请求发送但无响应 apiError.code = 'NETWORK_ERROR'; apiError.message = '网络错误,请检查连接'; } else { // 其他错误 apiError.message = error.message; } return Promise.reject(apiError); } ); return instance; }; // API 客户端单例 export const apiClient = createApiClient(); // 通用请求方法封装 export const api = { get: async (url: string, config?: AxiosRequestConfig): Promise> => { const response = await apiClient.get(url, config); return { data: response.data, status: response.status }; }, post: async (url: string, data?: unknown, config?: AxiosRequestConfig): Promise> => { const response = await apiClient.post(url, data, config); return { data: response.data, status: response.status }; }, put: async (url: string, data?: unknown, config?: AxiosRequestConfig): Promise> => { const response = await apiClient.put(url, data, config); return { data: response.data, status: response.status }; }, patch: async (url: string, data?: unknown, config?: AxiosRequestConfig): Promise> => { const response = await apiClient.patch(url, data, config); return { data: response.data, status: response.status }; }, delete: async (url: string, config?: AxiosRequestConfig): Promise> => { const response = await apiClient.delete(url, config); return { data: response.data, status: response.status }; }, }; export default apiClient;