Initial comitof pe project

This commit is contained in:
2025-08-13 01:55:49 +00:00
commit 05618f1cbb
40 changed files with 9432 additions and 0 deletions

238
src/utils/api/index.js Normal file
View File

@@ -0,0 +1,238 @@
import axios from "axios";
import crypto from "@/utils/crypto";
import Cookies from 'js-cookie';
import { ElMessage, ElLoading } from 'element-plus';
// 获取基础 API 地址
const API_BASE_URL = import.meta.env.VITE_APP_API_BASE_URL;
if (!API_BASE_URL) {
console.warn('API基础地址未配置请在环境变量中设置VITE_APP_API_BASE_URL');
}
// 创建axios实例
const api = axios.create({
baseURL: API_BASE_URL,
timeout: 15000, // 请求超时时间
headers: {
'Content-Type': 'application/json'
}
});
// 加载状态管理
let loadingInstance = null;
let requestCount = 0;
// 显示加载状态
const showLoading = () => {
if (requestCount === 0) {
loadingInstance = ElLoading.service({
lock: true,
text: '加载中...',
background: 'rgba(0, 0, 0, 0.1)'
});
}
requestCount++;
};
// 隐藏加载状态
const hideLoading = () => {
requestCount--;
if (requestCount <= 0 && loadingInstance) {
loadingInstance.close();
loadingInstance = null;
requestCount = 0;
}
};
// 请求拦截器
api.interceptors.request.use(
(config) => {
// 如果需要显示加载状态
if (config.showLoading !== false) {
showLoading();
}
// 添加认证token
const accessToken = Cookies.get('access_token');
if (accessToken) {
config.headers['Authorization'] = `Bearer ${accessToken}`;
}
// 处理POST请求加密
if (config.method?.toLowerCase() === 'post' && !config.isEncrypted) {
try {
// 添加用户信息
let requestData = { ...config.data };
const storedUserInfo = localStorage.getItem('info');
if (storedUserInfo) {
const info = JSON.parse(crypto.decrypt(storedUserInfo));
requestData['user_id'] = info.id;
}
// 加密数据
config.data = {
postdata: crypto.encrypt(JSON.stringify(requestData))
};
// 标记为已加密
config.isEncrypted = true;
} catch (error) {
console.error('请求数据加密失败:', error);
}
}
return config;
},
(error) => {
hideLoading();
ElMessage.error('请求配置错误');
return Promise.reject(error);
}
);
// 响应拦截器
api.interceptors.response.use(
(response) => {
hideLoading();
// 处理业务逻辑错误
const { data } = response;
// 根据实际后端规范调整
if (data.code && data.code !== 200) {
ElMessage.error(data.message || '操作失败');
return Promise.reject(new Error(data.message || '请求失败'));
}
return data;
},
async (error) => {
hideLoading();
// 处理网络错误
if (!error.response) {
ElMessage.error('网络连接异常,请检查网络');
return Promise.reject(error);
}
const { status, data } = error.response;
// 处理不同状态码
switch (status) {
case 401:
// 未授权处理token过期逻辑
ElMessage.error('登录已过期,请重新登录');
// 清除登录状态
Cookies.remove('access_token');
localStorage.removeItem('info');
// 跳转到登录页假设使用vue-router
if (window.router) {
window.router.push('/');
}
break;
case 403:
ElMessage.error('没有权限执行此操作');
break;
case 404:
ElMessage.error('请求的资源不存在');
break;
case 500:
ElMessage.error('服务器内部错误,请稍后再试');
break;
default:
ElMessage.error(data?.message || `请求错误 (${status})`);
}
return Promise.reject(error);
}
);
// 封装请求方法
const request = {
/**
* GET请求
* @param {string} url 请求地址
* @param {object} params 请求参数
* @param {object} config 额外配置
* @returns {Promise}
*/
get: (url, params = {}, config = {}) => {
return api({
url,
method: 'get',
params,
...config
});
},
/**
* POST请求
* @param {string} url 请求地址
* @param {object} data 请求数据
* @param {object} config 额外配置
* @returns {Promise}
*/
post: (url, data = {}, config = {}) => {
return api({
url,
method: 'post',
data,
...config
});
},
/**
* PUT请求
* @param {string} url 请求地址
* @param {object} data 请求数据
* @param {object} config 额外配置
* @returns {Promise}
*/
put: (url, data = {}, config = {}) => {
return api({
url,
method: 'put',
data,
...config
});
},
/**
* DELETE请求
* @param {string} url 请求地址
* @param {object} params 请求参数
* @param {object} config 额外配置
* @returns {Promise}
*/
delete: (url, params = {}, config = {}) => {
return api({
url,
method: 'delete',
params,
...config
});
},
/**
* 不加密的POST请求
* @param {string} url 请求地址
* @param {object} data 请求数据
* @param {object} config 额外配置
* @returns {Promise}
*/
postWithoutEncryption: (url, data = {}, config = {}) => {
return api({
url,
method: 'post',
data,
isEncrypted: true, // 标记为已加密,跳过加密处理
...config
});
}
};
// 暴露axios实例和请求方法
export { api, request };
export default request;