first commit

This commit is contained in:
chenzhen
2025-07-22 11:21:01 +08:00
commit 09d0e316e1
164 changed files with 7907 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
const cancelerMap = new Map();
class RequestCancel {
// 获取实例
static getInstance() {
if (!this._instance) {
this._instance = new RequestCancel()
}
return this._instance
}
add(url, requestTask) {
this.remove(url);
if (cancelerMap.has(url)) {
cancelerMap.delete(url);
}
cancelerMap.set(url, requestTask);
}
remove(url) {
if (cancelerMap.has(url)) {
const requestTask = cancelerMap.get(url);
requestTask && requestTask.abort();
cancelerMap.delete(url);
}
}
}
const requestCancel = RequestCancel.getInstance();
export default requestCancel;

165
src/utils/request/http.js Normal file
View File

@@ -0,0 +1,165 @@
import { RequestMethodsEnum, RequestErrMsgEnum } from '@/enums/requestEnums';
import { merge } from 'lodash-es';
import { isFunction } from '@vue/shared'
import requestCancel from './cancel'
export default class HttpRequest {
constructor(options) {
this.options = options;
}
/**
* @description 重新请求
*/
retryRequest(options, config) {
const { retryCount, retryTimeout } = config;
if (!retryCount || options.method?.toUpperCase() == RequestMethodsEnum.POST) {
return Promise.reject();
}
uni.showLoading({ title: '加载中...' });
config.hasRetryCount = config.hasRetryCount ?? 0;
if (config.hasRetryCount >= retryCount) {
return Promise.reject();
}
config.hasRetryCount++;
config.requestHooks.requestInterceptorsHook = (options) => options;
return new Promise((resolve) => setTimeout(resolve, retryTimeout))
.then(() => this.request(options, config))
.finally(() => uni.hideLoading());
}
/**
* @description get请求
*/
get(options, config) {
return this.request({ ...options, method: RequestMethodsEnum.GET }, config);
}
/**
* @description post请求
*/
post(options, config) {
return this.request({ ...options, method: RequestMethodsEnum.POST }, config);
}
/**
* @description put请求
*/
put(options, config) {
return this.request({ ...options, method: RequestMethodsEnum.PUT }, config);
}
/**
* @description delete请求
*/
delete(options, config) {
return this.request({ ...options, method: RequestMethodsEnum.DELETE }, config);
}
/**
* @description 上传图片
*/
uploadFile(options, config) {
let mergeOptions = merge({}, this.options.requestOptions, options);
const mergeConfig = merge({}, this.options, config);
const {
requestInterceptorsHook,
responseInterceptorsHook,
responseInterceptorsCatchHook
} = mergeConfig.requestHooks || {};
if (requestInterceptorsHook && isFunction(requestInterceptorsHook)) {
mergeOptions = requestInterceptorsHook(mergeOptions, mergeConfig);
}
return new Promise((resolve, reject) => {
uni.uploadFile({
...mergeOptions,
success: async (response) => {
if (response.statusCode == 200) {
response.data = JSON.parse(response.data);
if (responseInterceptorsHook && isFunction(responseInterceptorsHook)) {
try {
response = await responseInterceptorsHook(response, mergeConfig);
if(response){
resolve(response);
}else{
reject('error')
}
}
catch (error) {
reject(error);
}
return;
}
resolve(response);
}
},
fail: async (err) => {
if (responseInterceptorsCatchHook &&
isFunction(responseInterceptorsCatchHook)) {
reject(await responseInterceptorsCatchHook(mergeOptions, err));
return;
}
reject(err);
},
complete: (response) => {
if (response.statusCode == 200) {
if (response.data instanceof String) {
response.data = JSON.parse(response.data);
}
resolve(response.data);
}
}
});
});
}
/**
* @description 请求函数
*/
async request(options, config) {
let mergeOptions = merge({}, this.options.requestOptions, options);
const mergeConfig = merge({}, this.options, config);
const { requestInterceptorsHook, responseInterceptorsHook, responseInterceptorsCatchHook } =
mergeConfig.requestHooks || {};
if (requestInterceptorsHook && isFunction(requestInterceptorsHook)) {
mergeOptions = requestInterceptorsHook(mergeOptions, mergeConfig);
}
return new Promise((resolve, reject) => {
const requestTask = uni.request({
...mergeOptions,
async success(response) {
// console.log("success111=>",response)
if (responseInterceptorsHook && isFunction(responseInterceptorsHook)) {
try {
response = await responseInterceptorsHook(response, mergeConfig);
resolve(response);
}
catch (error) {
reject(error);
}
return;
}
resolve(response);
},
fail: async (err) => {
// console.log("fail222=>",err)
if (err.errMsg == RequestErrMsgEnum.TIMEOUT) {
this.retryRequest(mergeOptions, mergeConfig)
.then((res) => resolve(res))
.catch((err) => reject(err));
return;
}
if (responseInterceptorsCatchHook &&
isFunction(responseInterceptorsCatchHook)) {
reject(await responseInterceptorsCatchHook(mergeOptions, err));
return;
}
reject(err);
},
complete(err) {
// console.log("complete333=>",err)
if (err.errMsg !== RequestErrMsgEnum.ABORT) {
requestCancel.remove(options.url);
}
}
});
const { ignoreCancel } = mergeConfig;
!ignoreCancel && requestCancel.add(options.url, requestTask);
});
}
}

View File

@@ -0,0 +1,96 @@
import HttpRequest from './http';
import { merge } from 'lodash-es';
import { getToken } from '../auth';
import { RequestCodeEnum, RequestMethodsEnum } from '@/enums/requestEnums';
import { useUserStore } from '@/stores/user'
import { useMessage } from '../message';
const message = useMessage();
const requestHooks = {
// 请求拦截器
requestInterceptorsHook(options, config) {
// console.log("request=>",options,config)
const { urlPrefix, baseUrl, withToken, isAuth } = config;
options.header = options.header ?? {};
if (urlPrefix) {
options.url = `${urlPrefix}${options.url}`;
}
if (baseUrl) {
options.url = `${baseUrl}${options.url}`;
}
const token = getToken();
if (withToken && !options.header.token) {
options.header.token = token;
}
return options;
},
// 响应拦截器
responseInterceptorsHook(response, config) {
// console.log("response=>",response,config)
const { isTransformResponse, isReturnDefaultResponse, isAuth } = config;
if (isReturnDefaultResponse) {
return response;
}
if (!isTransformResponse) {
return response.data;
}
const { logout, isLogin } = useUserStore();
const { code, data, msg, show } = response.data;
// console.log(code,data,msg,show)
switch (code) {
case RequestCodeEnum.SUCCESS:
msg && show && message.toast(msg);
return data;
case RequestCodeEnum.FAILED:
message.toast(msg);
return Promise.reject(msg);
case RequestCodeEnum.TOKEN_INVALID:
if (isAuth && isLogin) {
}
return Promise.reject();
default:
message.toast(msg)
// return data;
return Promise.reject(msg);
}
},
// 响应异常拦截器
responseInterceptorsCatchHook(options, err) {
if (options.method.toUpperCase() == RequestMethodsEnum.POST) {
console.log('请求失败:', err, options);
}
return Promise.reject();
}
};
// 默认配置
const defaultOptions = {
requestOptions: {// 请求配置
timeout: 10 * 1000,
header: { version: '1.0.0' }
},
baseUrl: `${import.meta.env.VITE_APP_BASE_URL || ''}`,// 基础 URL
isReturnDefaultResponse: false,// 是否返回默认响应
isTransformResponse: true, // 是否转换响应
urlPrefix: '',// url 前缀
ignoreCancel: true,// 忽略重复请求取消
withToken: true,// 携带 Token
isAuth: false,// 接口是否鉴权
retryCount: 2,// 重试次数
retryTimeout: 300, // 重试超时
requestHooks: requestHooks,// 请求 Hook
sslVerify: false // 设置为false不验证 ssl 证书
};
function createRequest(opt) {
return new HttpRequest(
merge(defaultOptions, opt || {})
);
}
const request = createRequest();
export default request;