import axios from 'axios' import router from '../router' import { getToken, getCustomer, resetToken } from '../utils/auth' import { ElMessage } from 'element-plus' const service = axios.create( { baseURL: import.meta.env.VITE_APP_URL as string, timeout: 5000 } ) service.interceptors.request.use( config => { if (typeof getToken() === 'string') { // ⚠️ Bearer 后必须有空格,否则后端 JWT 解析器会识别失败 → 401 (config as any).headers['Authorization'] = 'Bearer ' + getToken() } // 当前域名 → 后端按域名解析 customer(local 自动归 dev,prod 必须 admin 预先注册) ;(config as any).headers['X-Customer-Domain'] = window.location.hostname const customer = getCustomer() if (typeof customer === 'string') { (config as any).headers['customerId'] = JSON.parse(customer).customerId } return config } ) service.interceptors.response.use( (response) => { const data = response.data // 后端 ApiResponse / ErrorResponse 结构:{ code, message, ... } // 业务 code 非 0 / AUTH_401 等都按错误处理 if (data && typeof data === 'object' && 'code' in data) { if (data.code === 0 || data.code === '0' || data.code === 200) { return response } // 401 业务码:跳登录 if (data.code === 'AUTH_401' || data.code === 'AUTH_CONTEXT_MISSING') { ElMessage.warning('登录已过期,请重新登录') resetToken() router.replace('/login').catch(() => {}) return Promise.reject(new Error(data.message || '未登录')) } // 其他业务错误:弹错 ElMessage.error(data.message || `请求失败 (${data.code})`) return Promise.reject(new Error(data.message || '请求失败')) } return response }, (error) => { if (error && error.response) { const status = error.response.status const body = error.response.data if (status === 401) { // HTTP 401:登录失效 const msg = (body && body.message) || '登录已过期,请重新登录' ElMessage.warning(msg) resetToken() router.replace('/login').catch(() => {}) } else if (status >= 500) { ElMessage.error((body && body.message) || '服务器内部错误') } else if (status >= 400) { ElMessage.error((body && body.message) || `请求错误 (${status})`) } else { ElMessage.error('网络异常') } } else { // 无 response:网络层 / CORS / 超时 ElMessage.error(error.message || '网络异常') } return Promise.reject(error) } ) export { service }