161 lines
3.8 KiB
JavaScript
161 lines
3.8 KiB
JavaScript
import axios from 'axios'
|
||
import { ElMessage } from 'element-plus'
|
||
import { useUserStore } from '../stores/user'
|
||
import router from '../router'
|
||
|
||
// 创建axios实例
|
||
const service = axios.create({
|
||
// 从环境变量获取基础URL,如果没有则使用默认值
|
||
baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
|
||
timeout: 15000, // 请求超时时间
|
||
headers: {
|
||
'Content-Type': 'application/json;charset=utf-8'
|
||
}
|
||
})
|
||
|
||
// 请求拦截器
|
||
service.interceptors.request.use(
|
||
(config) => {
|
||
const userStore = useUserStore()
|
||
const token = userStore.token
|
||
|
||
// 如果有token,添加到请求头
|
||
if (token) {
|
||
config.headers = config.headers || {}
|
||
config.headers['Authorization'] = `Bearer ${token}`
|
||
}
|
||
|
||
return config
|
||
},
|
||
(error) => {
|
||
console.error('请求错误:', error)
|
||
return Promise.reject(error)
|
||
}
|
||
)
|
||
|
||
// 响应拦截器
|
||
service.interceptors.response.use(
|
||
(response) => {
|
||
// 如果是二进制数据,直接返回
|
||
if (response.config.responseType === 'arraybuffer' || response.config.responseType === 'blob') {
|
||
return response.data;
|
||
}
|
||
|
||
const res = response.data;
|
||
|
||
// 如果响应成功
|
||
if (res.success) {
|
||
return res;
|
||
}
|
||
|
||
// 处理特定错误码
|
||
switch (res.code) {
|
||
case 401:
|
||
handleUnauthorized();
|
||
break;
|
||
case 403:
|
||
ElMessage.error('没有权限访问该资源');
|
||
break;
|
||
case 500:
|
||
console.error('服务器错误详情:', res);
|
||
ElMessage.error(res.message || '服务器错误,请稍后重试');
|
||
break;
|
||
default:
|
||
ElMessage.error(res.message || '请求失败');
|
||
}
|
||
|
||
return Promise.reject(new Error(res.message || '请求失败'));
|
||
},
|
||
(error) => {
|
||
console.error('响应错误详情:', {
|
||
status: error.response?.status,
|
||
statusText: error.response?.statusText,
|
||
data: error.response?.data,
|
||
headers: error.response?.headers,
|
||
config: {
|
||
url: error.config?.url,
|
||
method: error.config?.method,
|
||
headers: error.config?.headers,
|
||
params: error.config?.params
|
||
}
|
||
});
|
||
|
||
// 处理网络错误
|
||
if (!error.response) {
|
||
ElMessage.error('网络错误,请检查您的网络连接');
|
||
return Promise.reject(error);
|
||
}
|
||
|
||
// 处理HTTP状态码错误
|
||
const status = error.response.status;
|
||
switch (status) {
|
||
case 401:
|
||
handleUnauthorized();
|
||
break;
|
||
case 403:
|
||
ElMessage.error('没有权限访问该资源');
|
||
break;
|
||
case 404:
|
||
ElMessage.error('请求的资源不存在');
|
||
break;
|
||
case 500:
|
||
ElMessage.error('服务器错误,请稍后重试');
|
||
break;
|
||
default:
|
||
ElMessage.error(`请求失败:${error.message}`);
|
||
}
|
||
|
||
return Promise.reject(error);
|
||
}
|
||
);
|
||
|
||
// 处理未授权情况
|
||
const handleUnauthorized = () => {
|
||
const userStore = useUserStore()
|
||
userStore.logout() // 清除用户信息
|
||
|
||
// 跳转到登录页,并携带当前页面路径
|
||
const currentPath = router.currentRoute.value.fullPath
|
||
router.push({
|
||
path: '/login',
|
||
query: {
|
||
redirect: currentPath
|
||
}
|
||
})
|
||
|
||
ElMessage.error('登录已过期,请重新登录')
|
||
}
|
||
|
||
// 封装请求方法
|
||
export const request = {
|
||
get(url, config) {
|
||
return service.get(url, config)
|
||
},
|
||
|
||
post(url, data, config) {
|
||
return service.post(url, data, config)
|
||
},
|
||
|
||
put(url, data, config) {
|
||
return service.put(url, data, config)
|
||
},
|
||
|
||
delete(url, config) {
|
||
return service.delete(url, config)
|
||
},
|
||
|
||
// 上传文件的专用方法
|
||
upload(url, file, config) {
|
||
const formData = new FormData()
|
||
formData.append('file', file)
|
||
|
||
return service.post(url, formData, {
|
||
headers: {
|
||
'Content-Type': 'multipart/form-data'
|
||
},
|
||
...config
|
||
})
|
||
}
|
||
}
|
||
|
||
export default request |