Files
CNCEC_APP/utils/request.js
T
2026-08-17 11:01:21 +08:00

255 lines
5.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.
/**
* 网络请求封装 - 基于 uni.request 二次封装
*/
import config from '@/api/config.js';
import { getToken, clearAuthInfo, getUserInfo } from './auth';
// 请求队列(用于防重复请求)
const pendingRequests = new Map();
/**
* 生成请求唯一标识
*/
function generateRequestKey(options) {
return `${options.method}_${options.url}_${JSON.stringify(options.data || {})}`;
}
/**
* 核心请求方法
* @param {Object} options 请求配置
* @param {string} options.url 请求路径(不含 baseUrl
* @param {string} [options.method='GET'] 请求方法
* @param {Object} [options.data] 请求参数
* @param {Object} [options.header] 自定义请求头
* @param {boolean} [options.loading=false] 是否显示加载提示
* @param {string} [options.loadingText='加载中...'] 加载提示文字
* @param {boolean} [options.showError=true] 是否显示错误提示
* @param {boolean} [options.preventDuplicate=false] 是否防止重复请求
* @param {boolean} [options.isUnitId=true] 是否需要unitId参数
* @returns {Promise}
*/
function request(options) {
const { url, method = 'GET', data = {}, header = {}, loading = false, loadingText = '加载中...', showError = true, preventDuplicate = false, isUnitId = true } = options;
const fullUrl = url.startsWith('http') ? url : `${config.baseUrl}${url}`;
// 防重复请求
const requestKey = generateRequestKey({
method,
url: fullUrl,
data
});
if (preventDuplicate && pendingRequests.has(requestKey)) {
return pendingRequests.get(requestKey);
}
// 显示加载状态
if (loading) {
uni.showLoading({
title: loadingText,
mask: true
});
}
// 构建请求头
const token = getToken();
const requestHeader = {
'Content-Type': 'application/json',
...header
};
if (token) {
requestHeader['token'] = token;
}
//获取用户的unitld
const userInfo = getUserInfo();
if (userInfo?.UnitId && isUnitId) {
console.log('用户id的get', userInfo.UnitId);
data['unitId'] = userInfo.UnitId;
}
const requestPromise = new Promise((resolve, reject) => {
uni.request({
url: fullUrl,
method,
data,
header: requestHeader,
timeout: config.timeout,
success: (res) => {
const { statusCode, data: responseData } = res;
// HTTP 状态码判断
if (statusCode === 200) {
// 根据业务状态码处理(按实际后端接口约定调整)
if (responseData.code === 1 || responseData.code === 200) {
resolve(responseData.data);
} else if (responseData.code === 401) {
// Token 过期/无效
handleUnauthorized();
reject(responseData);
} else {
// 业务错误
if (showError) {
uni.showToast({
title: responseData.message || '请求失败',
icon: 'none',
duration: 2000
});
}
reject(responseData);
}
} else if (statusCode === 401) {
handleUnauthorized();
reject(res);
} else {
if (showError) {
uni.showToast({
title: `请求错误 (${statusCode})`,
icon: 'none'
});
}
reject(res);
}
},
fail: (err) => {
if (showError) {
uni.showToast({
title: '网络异常,请检查网络连接',
icon: 'none'
});
}
reject(err);
},
complete: () => {
if (loading) {
uni.hideLoading();
}
pendingRequests.delete(requestKey);
}
});
});
if (preventDuplicate) {
pendingRequests.set(requestKey, requestPromise);
}
return requestPromise;
}
/**
* 处理 401 未授权
*/
function handleUnauthorized() {
clearAuthInfo();
uni.showToast({
title: '登录已过期,请重新登录',
icon: 'none',
duration: 2000
});
setTimeout(() => {
uni.reLaunch({
url: '/pages/login/login'
});
}, 1500);
}
/**
* 文件上传
* @param {string} filePath 文件本地路径
* @param {Object} [formData] 额外表单数据
* @param {string} [name='file'] 文件字段名
* @returns {Promise}
*/
export function upload(filePath, formData = {}, name = 'file') {
const token = getToken();
return new Promise((resolve, reject) => {
uni.showLoading({
title: '上传中...',
mask: true
});
uni.uploadFile({
url: config.uploadUrl || `${config.baseUrl}/upload`,
filePath,
name,
formData,
header: token
? {
Authorization: `Bearer ${token}`
}
: {},
success: (res) => {
if (res.statusCode === 200) {
const data = JSON.parse(res.data);
if (data.code === 0 || data.code === 200) {
resolve(data.data);
} else {
uni.showToast({
title: data.message || '上传失败',
icon: 'none'
});
reject(data);
}
} else {
reject(res);
}
},
fail: (err) => {
uni.showToast({
title: '上传失败',
icon: 'none'
});
reject(err);
},
complete: () => {
uni.hideLoading();
}
});
});
}
// 快捷方法
/**
* 核心请求方法
* @param {Object} options 请求配置
* @param {string} options.url 请求路径(不含 baseUrl
* @param {string} [options.method='GET'] 请求方法
* @param {Object} [options.data] 请求参数
* @param {Object} [options.header] 自定义请求头
* @param {boolean} [options.loading=false] 是否显示加载提示
* @param {string} [options.loadingText='加载中...'] 加载提示文字
* @param {boolean} [options.showError=true] 是否显示错误提示
* @param {boolean} [options.preventDuplicate=false] 是否防止重复请求
* @param {boolean} [options.isUnitId=true] 是否需要unitId参数
* @returns {Promise}
*/
export const get = (url, data, options = {}) =>
request({
url,
method: 'GET',
data,
...options
});
export const post = (url, data, options = {}) =>
request({
url,
method: 'POST',
data,
...options
});
export const put = (url, data, options = {}) =>
request({
url,
method: 'PUT',
data,
...options
});
export const del = (url, data, options = {}) =>
request({
url,
method: 'DELETE',
data,
...options
});
export default request;