import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
|
import { message } from 'ant-design-vue';
|
import { getToken, setToken, clearAuth } from './auth';
|
import router from '../router';
|
|
// 创建 axios 实例
|
const service: AxiosInstance = axios.create({
|
baseURL: '/api',
|
timeout: 30000,
|
headers: {
|
'Content-Type': 'application/json;charset=UTF-8',
|
},
|
});
|
|
// 请求拦截器
|
service.interceptors.request.use(
|
(config: any) => {
|
// 添加 Token 到请求头
|
const token = getToken();
|
if (token) {
|
config.headers.Authorization = `Bearer ${token}`;
|
}
|
|
// 确保 POST 请求的数据被正确序列化为 JSON
|
if (config.method === 'post' && config.data) {
|
// 如果 data 不是 FormData,确保它是 JSON 字符串
|
if (!(config.data instanceof FormData)) {
|
config.headers['Content-Type'] = 'application/json;charset=UTF-8';
|
// axios 会自动将对象转换为 JSON,但我们确保 Content-Type 正确
|
}
|
}
|
|
// 开发环境下打印请求信息
|
if (import.meta.env.DEV) {
|
console.log('Request:', {
|
url: config.url,
|
method: config.method,
|
data: config.data,
|
headers: config.headers,
|
});
|
}
|
|
return config;
|
},
|
(error: AxiosError) => {
|
console.error('Request error:', error);
|
return Promise.reject(error);
|
}
|
);
|
|
// 响应拦截器
|
service.interceptors.response.use(
|
(response: AxiosResponse) => {
|
// 检查是否需要刷新 Token
|
const expHeader = response.headers['widesea_exp'];
|
if (expHeader === '1') {
|
// Token 即将过期,刷新 Token
|
refreshToken();
|
}
|
|
const res = response.data;
|
|
// 如果响应状态不是 true,显示错误消息
|
if (res.status === false) {
|
message.error(res.message || '请求失败');
|
return Promise.reject(new Error(res.message || '请求失败'));
|
}
|
|
return res;
|
},
|
(error: AxiosError) => {
|
console.error('Response error:', error);
|
|
if (error.response) {
|
const status = error.response.status;
|
|
switch (status) {
|
case 401:
|
// 未认证,清除 Token 并跳转到登录页
|
message.error('登录已过期,请重新登录');
|
clearAuth();
|
router.push('/login');
|
break;
|
case 403:
|
message.error('没有权限访问该资源');
|
break;
|
case 404:
|
message.error('请求的资源不存在');
|
break;
|
case 500:
|
message.error('服务器错误');
|
break;
|
default:
|
message.error(error.message || '请求失败');
|
}
|
} else {
|
message.error('网络错误,请检查网络连接');
|
}
|
|
return Promise.reject(error);
|
}
|
);
|
|
/**
|
* 刷新 Token
|
*/
|
async function refreshToken() {
|
try {
|
const token = getToken();
|
if (!token) return;
|
|
const response = await axios.post(
|
'/api/User/replaceToken',
|
{ token },
|
{
|
headers: {
|
Authorization: `Bearer ${token}`,
|
},
|
}
|
);
|
|
if (response.data.status && response.data.data) {
|
setToken(response.data.data);
|
}
|
} catch (error) {
|
console.error('Token refresh failed:', error);
|
}
|
}
|
|
export default service;
|