Files
xSynergy-manage/src/utils/request.js
2025-10-11 17:28:20 +08:00

193 lines
6.9 KiB
JavaScript
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 axios from "axios";
import {
ElNotification,
ElMessageBox,
ElMessage,
} from "element-plus";
import { tansParams } from "@/utils/ruoyi";
import cache from "@/plugins/cache";
import { getToken, removeToken } from "@/utils/auth";
import router from '@/router';
import { useMeterStore } from '@/stores/modules/meter'
axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
const meterStore = useMeterStore()
meterStore.initUdid()
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: import.meta.env.VITE_APP_BASE_API,
// 超时
timeout: 10000,
});
// request拦截器
service.interceptors.request.use(
(config) => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false;
if (getToken() && !isToken) {
config.headers["Authorization"] = "Bearer " + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
}
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
if (meterStore.getSudid()) {
config.headers["X-User-Agent"] = `gxtech/web 1.0.0: c=GxTech, udid=${meterStore.getSudid()}, sv=15.4.1, app=stt`;
}
// get请求映射params参数
if (config.method === "get" && config.params) {
let url = config.url + "?" + tansParams(config.params);
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
if (
!isRepeatSubmit &&
(config.method === "post" || config.method === "put")
) {
const requestObj = {
url: config.url,
data:
typeof config.data === "object"
? JSON.stringify(config.data)
: config.data,
time: new Date().getTime(),
};
const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
if (requestSize >= limitSize) {
console.warn(
`[${config.url}]: ` +
"请求数据大小超出允许的5M限制无法进行防重复提交验证。"
);
return config;
}
const sessionObj = cache.session.getJSON("sessionObj");
if (
sessionObj === undefined ||
sessionObj === null ||
sessionObj === ""
) {
cache.session.setJSON("sessionObj", requestObj);
} else {
const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (
s_data === requestObj.data &&
requestObj.time - s_time < interval &&
s_url === requestObj.url
) {
const message = "数据正在处理,请勿重复提交";
console.warn(`[${s_url}]: ` + message);
return Promise.reject(new Error(message));
} else {
cache.session.setJSON("sessionObj", requestObj);
}
}
}
return config;
},
(error) => {
Promise.reject(error);
}
);
service.interceptors.response.use(
(response) => {
// 1. 检查响应是否存在
if (!response) {
ElMessage.error('无响应数据');
return Promise.reject(new Error('无响应数据'));
}
// 2. 安全获取响应数据和状态码
const responseData = response.data || {};
const statusCode = response.status;
const businessCode = responseData.meta?.code || statusCode;
// 3. 二进制数据直接返回
if (
response.request.responseType === 'blob' ||
response.request.responseType === 'arraybuffer'
) {
return responseData;
}
// 4. 根据业务码处理不同情况
switch (businessCode) {
case 200:
case 201:
return Promise.resolve(responseData);
case 401:
return Promise.resolve(responseData);
// return handleUnauthorized().then(() => {
// return Promise.reject({ code: 401, message: '未授权' });
// });
case 500:
const serverErrorMsg = responseData.meta?.message || '服务器内部错误';
ElMessage({ message: serverErrorMsg, type: 'error' });
return Promise.reject({ code: 500, message: serverErrorMsg });
default:
const errorMsg = responseData.meta?.message || `业务错误 (${businessCode})`;
ElNotification.error({ title: errorMsg });
return Promise.reject({ code: businessCode, message: errorMsg });
}
},
(error) => {
let { message } = error;
let code = error?.response?.status || -1;
if (message == 'Network Error') {
message = '后端接口连接异常';
ElMessage({ message, type: 'error', duration: 5 * 1000 });
} else if (message.includes('timeout')) {
message = '系统接口请求超时';
ElMessage({ message, type: 'error', duration: 5 * 1000 });
} else if (message.includes('Request failed with status code')) {
// message = '系统接口' + message.substr(message.length - 3) + '异常';
}
// 返回结构化错误
return Promise.reject({
code,
message,
raw: error // 保留原始 error
});
}
);
// 单独处理401未授权
function handleUnauthorized() {
return ElMessageBox.confirm(
'认证信息已失效,您可以继续留在该页面,或者重新登录',
'系统提示',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
removeToken()
if (router.currentRoute.path !== '/login') {
router.push({
path: '/login',
query: { redirect: router.currentRoute.fullPath }
});
} else {
// 如果在登录页,强制刷新以清除残留状态
window.location.reload();
}
})
.catch(() => {
return Promise.reject('用户取消操作');
});
}
export default service;