suke-mp/src/utils/request/interceptors.ts

116 lines
3.7 KiB
TypeScript
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 type { HttpError, HttpRequestConfig, HttpResponse } from 'uview-plus/libs/luch-request';
import { getToken } from '@/utils/auth';
import { showMessage } from '@/utils/request/status';
import { useUserStore } from '@/store';
// 是否正在刷新token的标记
let isRefreshing: boolean = false;
// 重试队列,每一项将是一个待执行的函数形式
let requestQueue: (() => void)[] = [];
function requestInterceptors() {
/**
* 请求拦截
* @param {Object} http
*/
uni.$u.http.interceptors.request.use(
(config: HttpRequestConfig) => {
// 可使用async await 做异步操作
// 初始化请求拦截器时会执行此方法此时data为undefined赋予默认{}
config.data = config.data || {};
// token设置
const token = getToken();
if(token && config.header) {
config.header.token = token;
config.header.companyid = getApp().globalData?.companyId;
// config.header.contentType = "x-www-form-urlencoded"
}
getApp().globalData?.logger.info('request: ', config);
return config;
},
(
config: any // 可使用async await 做异步操作
) => Promise.reject(config)
);
}
function responseInterceptors() {
/**
* 响应拦截
* @param {Object} http
*/
uni.$u.http.interceptors.response.use(
async (response: HttpResponse) => {
/* 对响应成功做点什么 可使用async await 做异步操作 */
const data = response.data;
// 配置参数
const config = response.config;
// 自定义参数
const custom = config?.custom;
if(config.responseType === 'arraybuffer') {
return data;
}
getApp().globalData?.logger.info('response: ', data);
// 请求成功则返回结果
if(data.code === 200 || data?.retcode == 0) {
return data || {};
}
// 登录状态失效,重新登录
if(data.code === 4011 || data?.retcode === 4011) {
// 是否在获取token中,防止重复获取
if(!isRefreshing) {
// 修改登录状态为true
isRefreshing = true;
await useUserStore().login();
// 登录完成之后,开始执行队列请求
requestQueue.forEach(cb => cb());
// 重试完了清空这个队列
requestQueue = [];
// isRefreshing = false;
// 重新执行本次请求
return uni.$u.http.request(config);
} else {
return new Promise(resolve => {
// 将resolve放进队列用一个函数形式来保存等登录后直接执行
requestQueue.push(() => {
resolve(uni.$u.http.request(config));
});
});
}
}
// 如果没有显式定义custom的toast参数为false的话默认对报错进行toast弹出提示
if(custom?.toast !== false) {
uni.$u.toast(data.message || data.retinfo);
}
// 如果需要catch返回则进行reject
if(custom?.catch) {
return Promise.reject(data);
} else {
// 否则返回一个pending中的promise
return new Promise(() => {
});
}
},
(response: HttpError) => {
console.error('http error: ', response);
/* 对响应错误做点什么 statusCode !== 200*/
getApp().globalData?.logger.error('request error : ', response);
if(response.statusCode) {
// 请求已发出但是不在2xx的范围
uni.$u.toast(showMessage(response.statusCode));
return Promise.reject(response.data);
}
uni.$u.toast('网络连接异常,请稍后再试!');
}
);
}
export { requestInterceptors, responseInterceptors };