import axios, { type AxiosError, type AxiosRequestConfig, type InternalAxiosRequestConfig } from 'axios' const API_BASE_URL = '/api' const AUTH_WHITELIST = ['/auth/captcha', '/auth/login'] const request = axios.create({ baseURL: API_BASE_URL, timeout: 30000, // Let Axios automatically set Content-Type based on payload type }) request.interceptors.request.use( (config: InternalAxiosRequestConfig) => { config.headers['X-Client-Id'] = 'sundynix-admin' const isWhitelisted = AUTH_WHITELIST.some(path => config.url?.startsWith(path)) if (!isWhitelisted) { const token = localStorage.getItem('token') if (token) config.headers.Authorization = `Bearer ${token}` } // Remove any custom handling, Axios natively handles FormData correctly without global Content-Type return config }, (error: AxiosError) => Promise.reject(error) ) request.interceptors.response.use( response => { const newToken = response.headers['x-refresh-token'] if (newToken) { localStorage.setItem('token', newToken) // 静默替换 } const res = response.data if (res.code !== undefined && res.code !== 200) { if (res.code === 401) { localStorage.removeItem('token') localStorage.removeItem('user') window.location.href = '/login' } return Promise.reject(new Error(res.msg || '请求失败')) } // 统一返回 data 字段,调用方直接拿到业务数据 return res.data }, (error: AxiosError) => { if (error.response?.status === 401) { localStorage.removeItem('token') localStorage.removeItem('user') window.location.href = '/login' } return Promise.reject(error) } ) export function get(url: string, params?: Record, config?: AxiosRequestConfig): Promise { return request.get(url, { params, ...config }) } export function post(url: string, data?: unknown, config?: AxiosRequestConfig): Promise { return request.post(url, data, config) } export function put(url: string, data?: unknown, config?: AxiosRequestConfig): Promise { return request.put(url, data, config) } export function del(url: string, config?: AxiosRequestConfig): Promise { return request.delete(url, config) } export default request export interface ApiResponse { code: number; data: T; msg: string } export interface PageResult { list: T[]; total: number; current?: number; size?: number } export interface PageParams { current: number; pageSize: number; keyword?: string }