2025-11-03 17:23:03 +08:00
|
|
|
|
// src/utils/request.ts
|
|
|
|
|
|
import axios, {
|
|
|
|
|
|
type InternalAxiosRequestConfig, // 关键:导入内部配置类型
|
|
|
|
|
|
type AxiosError,
|
|
|
|
|
|
type AxiosResponse
|
|
|
|
|
|
} from 'axios';
|
|
|
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
|
|
|
import router from "../router";
|
|
|
|
|
|
import useUserStore from "../store/user.ts";
|
2025-10-27 17:21:49 +08:00
|
|
|
|
|
2025-11-03 17:23:03 +08:00
|
|
|
|
// 创建实例(配置不变)
|
2025-10-27 17:21:49 +08:00
|
|
|
|
const request = axios.create({
|
2025-11-03 17:23:03 +08:00
|
|
|
|
baseURL: import.meta.env.VITE_API_BASE_URL,
|
|
|
|
|
|
timeout: 10000,
|
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
2025-10-27 17:21:49 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
2025-11-03 17:23:03 +08:00
|
|
|
|
// 1. 请求拦截器:使用 InternalAxiosRequestConfig 类型
|
2025-10-27 17:21:49 +08:00
|
|
|
|
request.interceptors.request.use(
|
2025-11-03 17:23:03 +08:00
|
|
|
|
(config: InternalAxiosRequestConfig) => { // 类型改为 InternalAxiosRequestConfig
|
|
|
|
|
|
const userStore = useUserStore();
|
|
|
|
|
|
if (userStore.session) {
|
|
|
|
|
|
// 关键:用 set 方法添加自定义头,保持 headers 类型为 AxiosHeaders
|
|
|
|
|
|
console.log("发送session:", userStore.session);
|
|
|
|
|
|
config.headers.set('session_id', userStore.session);
|
|
|
|
|
|
}
|
|
|
|
|
|
return config; // 返回类型自动匹配
|
2025-10-27 17:21:49 +08:00
|
|
|
|
},
|
2025-11-03 17:23:03 +08:00
|
|
|
|
(error: AxiosError) => {
|
|
|
|
|
|
ElMessage.error('请求配置错误,请检查');
|
2025-10-27 17:21:49 +08:00
|
|
|
|
return Promise.reject(error);
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
request.interceptors.response.use(
|
2025-11-03 17:23:03 +08:00
|
|
|
|
(response: AxiosResponse) => { // 明确响应类型
|
|
|
|
|
|
const res = response.data;
|
|
|
|
|
|
if ('code' in res) {
|
|
|
|
|
|
// 有 code 字段:按原有规则校验(code=0 视为成功)
|
|
|
|
|
|
if (res.code == '400') {
|
|
|
|
|
|
ElMessage.error(res.msg || '操作失败');
|
|
|
|
|
|
return Promise.reject(res); // 业务错误抛错
|
|
|
|
|
|
}
|
|
|
|
|
|
// 有 code 时,返回 res.data(保持原有逻辑)
|
|
|
|
|
|
return res.data;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 2. 无 code 字段:默认接口成功,直接返回原始响应数据(或根据实际结构调整)
|
|
|
|
|
|
// 注意:根据无 code 接口的实际返回格式修改(可能是 res 本身,也可能是 res.data)
|
|
|
|
|
|
return res; // 假设无 code 的接口直接返回业务数据(如 { ok: true, list: [...] })
|
|
|
|
|
|
}
|
2025-10-27 17:21:49 +08:00
|
|
|
|
},
|
2025-11-03 17:23:03 +08:00
|
|
|
|
(error: AxiosError) => {
|
|
|
|
|
|
const status = error.response?.status;
|
|
|
|
|
|
switch (status) {
|
|
|
|
|
|
case 401:
|
|
|
|
|
|
const userStore = useUserStore();
|
|
|
|
|
|
userStore.logout();
|
|
|
|
|
|
router.push('/login');
|
|
|
|
|
|
ElMessage.error('登录已过期,请重新登录');
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 403:
|
|
|
|
|
|
ElMessage.error('没有权限访问');
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 500:
|
|
|
|
|
|
ElMessage.error('服务器内部错误');
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
ElMessage.error('网络异常,请稍后重试');
|
|
|
|
|
|
}
|
2025-10-27 17:21:49 +08:00
|
|
|
|
return Promise.reject(error);
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2025-11-03 17:23:03 +08:00
|
|
|
|
// 3. 封装请求方法(类型同步修改)
|
|
|
|
|
|
export const requestUtil = {
|
|
|
|
|
|
get: <T = any>(url: string, config?: InternalAxiosRequestConfig) => { // 用内部类型
|
|
|
|
|
|
return request.get<T>(url, config);
|
|
|
|
|
|
},
|
|
|
|
|
|
post: <T = any>(url: string, data?: any, config?: InternalAxiosRequestConfig) => {
|
|
|
|
|
|
return request.post<T>(url, data, config);
|
|
|
|
|
|
},
|
|
|
|
|
|
put: <T = any>(url: string, data?: any, config?: InternalAxiosRequestConfig) => {
|
|
|
|
|
|
return request.put<T>(url, data, config);
|
|
|
|
|
|
},
|
|
|
|
|
|
delete: <T = any>(url: string, config?: InternalAxiosRequestConfig) => {
|
|
|
|
|
|
return request.delete<T>(url, config);
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-10-27 17:21:49 +08:00
|
|
|
|
export default request;
|