67 lines
2.0 KiB
JavaScript
67 lines
2.0 KiB
JavaScript
import axios from 'axios';
|
|
import { ElMessage } from 'element-plus';
|
|
import { useUserStore } from '../store/user';
|
|
import router from '../router';
|
|
|
|
const service = axios.create({
|
|
baseURL: import.meta.env.VITE_API_BASE_URL || '/api', // Use /api as default proxy prefix
|
|
timeout: 10000,
|
|
});
|
|
|
|
// Request Interceptor
|
|
service.interceptors.request.use(
|
|
(config) => {
|
|
const userStore = useUserStore();
|
|
if (userStore.token) {
|
|
config.headers['Authorization'] = `Bearer ${userStore.token}`;
|
|
}
|
|
return config;
|
|
},
|
|
(error) => {
|
|
return Promise.reject(error);
|
|
}
|
|
);
|
|
|
|
// Response Interceptor
|
|
service.interceptors.response.use(
|
|
(response) => {
|
|
const res = response.data;
|
|
// Backend standard format: { code: number, msg: string, data: any }
|
|
// Accept code 0 or 2xx as success
|
|
if (res.code === 0 || (res.code >= 200 && res.code < 300)) {
|
|
return res.data;
|
|
} else {
|
|
// If backend returns code !== 0/2xx but HTTP status is 200
|
|
ElMessage.error(res.msg || '请求失败');
|
|
return Promise.reject(new Error(res.msg || 'Error'));
|
|
}
|
|
},
|
|
(error) => {
|
|
const userStore = useUserStore();
|
|
let message = error.message;
|
|
|
|
if (error.response) {
|
|
const { status, data } = error.response;
|
|
// Backend error response format: { code: number, msg: string, data: null }
|
|
message = data?.msg || message;
|
|
|
|
if (status === 401) {
|
|
// Token expired or invalid
|
|
userStore.logout();
|
|
router.push(`/login?redirect=${encodeURIComponent(router.currentRoute.value.fullPath)}`);
|
|
ElMessage.error(message || '登录状态已过期,请重新登录');
|
|
return Promise.reject(new Error('Unauthorized'));
|
|
} else if (status === 403) {
|
|
ElMessage.error(message || '没有权限执行该操作');
|
|
} else {
|
|
ElMessage.error(message || '请求失败');
|
|
}
|
|
} else {
|
|
ElMessage.error(message || '网络连接异常');
|
|
}
|
|
return Promise.reject(error);
|
|
}
|
|
);
|
|
|
|
export default service;
|