import axios from 'axios' import { clearTokens, getToken } from './auth' type UnifiedResult = { code?: number type?: string message?: string result?: T errors?: unknown } let redirectingToLogin = false function handleUnauthorized(requestAuthorization?: unknown) { // A response from the previous session must not clear a newly signed-in session. const currentToken = getToken() if (currentToken && requestAuthorization !== `Bearer ${currentToken}`) return clearTokens() if (typeof window !== 'undefined' && window.location.pathname !== '/auth' && !redirectingToLogin) { redirectingToLogin = true window.location.replace('/auth') } } const http = axios.create({ baseURL: '/', timeout: 15000 }) http.interceptors.request.use((config) => { const token = getToken() if (token) config.headers.Authorization = `Bearer ${token}` return config }) http.interceptors.response.use( ((response: any) => { const body = response.data as UnifiedResult if (body && typeof body === 'object') { if (body.code === 401) { handleUnauthorized(response.config?.headers?.Authorization) return Promise.reject(new Error(body.message || '登录已过期,请重新登录')) } } if (body && typeof body === 'object' && 'result' in body) { if (body.type && body.type !== 'success') { return Promise.reject(new Error(body.message || '请求失败')) } return body.result } return body }) as any, (error) => { if (error.response?.status === 401) { handleUnauthorized(error.config?.headers?.Authorization ?? error.response?.config?.headers?.Authorization) } const body = error.response?.data as UnifiedResult | undefined const message = body?.message || error.message || '网络请求失败' return Promise.reject(new Error(message)) } ) export default http