Files
lpt-fe/src/utils/request.ts
T

116 lines
3.4 KiB
TypeScript

import axios from 'axios';
import { ElMessage } from "element-plus";
import router from "@/router";
/** 后端统一响应包装:code === 200 表示业务成功 */
export interface ApiResponse<T = any> {
code: number;
message?: string;
data: T;
}
const baseURL = import.meta.env.VITE_BASE_URL;
// 默认 30s:普通 CRUD 足够;AI 聚合等长耗时接口需在 api 层显式覆写 timeout
const DEFAULT_TIMEOUT = 30_000;
const axiosInstance = axios.create({
baseURL,
timeout: DEFAULT_TIMEOUT,
withCredentials: true
});
const handleError = (error: any) => {
// 401 未授权(HTTP 层):token 过期或未登录
if (error?.response?.status === 401) {
localStorage.removeItem("isLoggedIn");
router.push("/login");
return Promise.reject(error);
}
// 401 未授权(业务层):后端 GlobalExceptionHandler 返回 code=401
if (error && typeof error === "object" && error.code === 401) {
localStorage.removeItem("isLoggedIn");
router.push("/login");
return Promise.reject(error);
}
// 其他业务异常(如 code !== 200)透传,由调用方自行提示
if (error && typeof error === "object" && "code" in error && !error.response) {
return Promise.reject(error);
}
if (error.response) {
const backendMessage = error.response?.data?.message;
ElMessage.error(backendMessage || "请求失败了,请稍后再试");
} else if (error.request) {
ElMessage.error("请求失败了,请检查网络后重试");
} else {
ElMessage.error("请求失败了,请稍后再试");
}
throw new Error("请求失败了,请稍后再试");
};
const validateResponse = (res: any) => {
const result = res.data;
if (result.code !== 200) {
ElMessage.error(result.message || '请求失败');
return Promise.reject(result);
}
return result;
};
const get = <T = any>(
url: string,
params: Record<string, any> = {},
config: Record<string, any> = {},
): Promise<ApiResponse<T>> =>
axiosInstance.get(url, { params, ...config })
.then(validateResponse)
.catch(handleError);
const post = <T = any>(
url: string,
data: any = null,
config: Record<string, any> = {},
): Promise<ApiResponse<T>> =>
axiosInstance.post(url, data, config)
.then(validateResponse)
.catch(handleError);
const put = <T = any>(
url: string,
data: any,
config: Record<string, any> = {},
): Promise<ApiResponse<T>> =>
axiosInstance.put(url, data, config)
.then(validateResponse)
.catch(handleError);
const del = <T = any>(
url: string,
params: Record<string, any> = {},
config: Record<string, any> = {},
): Promise<ApiResponse<T>> =>
axiosInstance.delete(url, { params, ...config })
.then(validateResponse)
.catch(handleError);
const requestNotImplemented = () => {
ElMessage.error("该功能暂不可用,请刷新后重试");
throw new Error("该功能暂不可用,请刷新后重试");
};
const request = (method: string, url: string, paramsOrData: any) => {
switch (method.toLowerCase()) {
case 'get': return get(url, paramsOrData);
case 'post': return post(url, paramsOrData);
case 'put': return put(url, paramsOrData);
case 'delete': return del(url, paramsOrData);
default: return requestNotImplemented();
}
};
export default { get, post, put, del, request };