项目初始化

This commit is contained in:
leilei
2025-09-19 17:24:46 +08:00
commit 293951a610
107 changed files with 10222 additions and 0 deletions

194
src/utils/request.js Normal file
View File

@@ -0,0 +1,194 @@
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 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) => {
console.error('请求错误:', 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;