// src/api/client.ts import axios from 'axios' import type { AxiosError, InternalAxiosRequestConfig } from 'axios' import { useAuthStore } from '@/stores/auth' import router from '@/router' const baseURL = import.meta.env.VITE_API_BASE_URL || '/api' if (import.meta.env.DEV) { // Vite 的方式判断开发环境 console.log(`[Request] API Base URL: ${baseURL}`); } else if (process.env.NODE_ENV === 'development') { // Vue CLI 的方式判断开发环境 console.log(`[Request] API Base URL: ${baseURL}`); } const service = axios.create({ baseURL: baseURL, timeout: 6000, headers: { 'Content-Type': 'application/json', }, }); // 请求拦截器 service.interceptors.request.use( (config: InternalAxiosRequestConfig) => { const authStore = useAuthStore(); if (!authStore.token) { authStore.loadTokenFromStorage(); } if (authStore.token) { config.headers.Authorization = `Bearer ${authStore.token}`; } return config; }, (error: AxiosError) => { console.error('Request error:', error); return Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( (response) => { return response; // 只返回响应数据,便于后续使用 }, (error: AxiosError) => { // 可以在这里处理响应错误的情况,例如统一处理错误信息, 提示用户等 console.error('Response error:', error); // 这里可以做一些统一的错误处理,例如根据状态码判断是否 token 失效,并跳转到登录页面 if (error.response && error.response.status === 401) { const authStore = useAuthStore(); authStore.clear(); // 守卫校验期间(尚未进入受保护路由)由守卫负责跳登录; // 这里只处理已登录状态下 token 失效的情况,且不再用 location.href 硬刷新 const current = router.currentRoute.value; if (current.matched.some(record => record.meta.requiresAuth)) { router.push({ path: '/login', query: { redirect: current.fullPath } }); } } return Promise.reject(error); } ); export default service;