Files
erp-frontend/src/common/http/request.ts
2026-03-21 15:56:53 +08:00

112 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useUserStore } from "@/pinia";
import axios from "axios";
import type { AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from "axios";
import { ElMessage } from "element-plus";
import { $t } from "@/common/languages";
// 创建 axios 实例
const service: AxiosInstance = axios.create({
baseURL: import.meta.env.VITE_API_URL || "/api", // 使用环境变量配置基础路径
timeout: 10000,
withCredentials: true, // 关键:允许携带 Cookie用于 Session 认证)
});
export interface ResponseStructure<T = any> {
code: number;
msg: string;
data: T;
}
// 请求拦截器
service.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 可在此添加 loading、token如果用 token、或其他 header
// 但 Session 模式下通常无需额外 token
return config;
},
error => {
ElMessage.error($t("_http.request_failed"));
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
(response: AxiosResponse<ResponseStructure<any>>) => {
const res = response.data;
// 假设后端返回格式为 { code: number, data: any, message: string }
// 通常 code === 0 表示成功
if (res.code === 0) {
return res as any; // 直接返回业务数据
} else if (res.code === 3) {
ElMessage.error(res.msg || $t("_http.invalid_credentials"));
return Promise.reject(new Error(res.msg || $t("_http.invalid_credentials")));
} else {
ElMessage.error(res.msg || $t("_http.request_error"));
return Promise.reject(new Error(res.msg || "Error"));
}
},
error => {
// 处理网络错误或 HTTP 状态码非 2xx 的情况
let message = $t("_http.network_error");
const { isLogined } = storeToRefs(useUserStore());
if (error.response) {
const status = error.response.status;
switch (status) {
case 401:
message = $t("_http.unauthorized");
isLogined.value = false;
useRouter().push("/login");
break;
case 403:
message = $t("_http.forbidden");
break;
case 500:
message = $t("_http.server_error");
break;
default:
message = $t("_http.request_failed_status", { status });
}
}
ElMessage.error(message);
return Promise.reject(error);
}
);
// ===== 快捷方法封装 =====
/**
* GET 请求
*/
export function get<T = any>(
url: string,
params?: Record<string, any>,
config?: InternalAxiosRequestConfig
): Promise<T> {
return service.get<ResponseStructure<T>, any>(url, { params, ...config });
}
/**
* POST 请求JSON
*/
export function post<T = any>(url: string, data?: any, config?: InternalAxiosRequestConfig): Promise<T> {
return service.post<ResponseStructure<T>, any>(url, data, config);
}
/**
* PUT 请求
*/
export function put<T = any>(url: string, data?: any, config?: InternalAxiosRequestConfig): Promise<T> {
return service.put<ResponseStructure<T>, any>(url, data, config);
}
/**
* DELETE 请求
*/
export function del<T = any>(url: string, config?: InternalAxiosRequestConfig): Promise<T> {
return service.delete<ResponseStructure<T>, any>(url, config);
}
export default service;