feat: 修改接口报错登出问题,优化切换数据刷新问题

This commit is contained in:
chenli
2026-01-30 17:06:39 +08:00
parent 527747259c
commit 43a645ec87
4 changed files with 147 additions and 106 deletions

View File

@@ -511,7 +511,13 @@
modelId, modelId,
isPreview = '0', isPreview = '0',
id = '', id = '',
current,
tabCurrent
} = config } = config
console.log(tabCurrent !== undefined,'判断11111111')
if(tabCurrent !== undefined){
uni.setStorageSync('fromNonTabBar', tabCurrent);
}
const formPermissionList =[] const formPermissionList =[]
Object.assign(this, { Object.assign(this, {
userInfo: uni.getStorageSync('userInfo') || {}, userInfo: uni.getStorageSync('userInfo') || {},

View File

@@ -66,6 +66,10 @@
type: [String, Number], type: [String, Number],
default: '0' default: '0'
}, },
current: {
type: [String, Number],
default: '0'
},
}, },
data() { data() {
return { return {
@@ -100,7 +104,8 @@
id: businessId, id: businessId,
name: name, name: name,
btnType: 'btn_process', btnType: 'btn_process',
current: this.category current: this.category,
tabCurrent: this.current
} }
uni.navigateTo({ uni.navigateTo({
url: '/pages/apply/dynamicModelList/form?config=' + url: '/pages/apply/dynamicModelList/form?config=' +

View File

@@ -18,7 +18,7 @@
</view> </view>
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption"
:up="upOption" :top="mescrollTop"> :up="upOption" :top="mescrollTop">
<flowlist :list='list' :swipeAction='current != 3' :category='category' /> <flowlist :list='list' :swipeAction='current != 3' :category='category' :current='current' />
</mescroll-body> </mescroll-body>
</view> </view>
</template> </template>
@@ -76,12 +76,18 @@
onShow() { onShow() {
const fromNonTabBar = uni.getStorageSync('fromNonTabBar'); const fromNonTabBar = uni.getStorageSync('fromNonTabBar');
console.log(fromNonTabBar,'fromNonTabBar---') console.log(fromNonTabBar,'fromNonTabBar---')
this.current = fromNonTabBar && Number(fromNonTabBar) if(fromNonTabBar == ''){
// if(!fromNonTabBar){ this.current = 1
// this.current = 1 this.category = '2'
// }else { }else {
// this.current = 0 this.current = Number(fromNonTabBar)
// } this.category = Number(fromNonTabBar) + 1+''
}
const page = {
num : 1,
size: 20
}
this.upCallback(page)
uni.removeStorageSync('fromNonTabBar'); uni.removeStorageSync('fromNonTabBar');
uni.$off('operate') uni.$off('operate')
uni.$on('refresh', () => { uni.$on('refresh', () => {
@@ -91,6 +97,10 @@
}, },
onUnload() { onUnload() {
uni.$off('refresh') uni.$off('refresh')
uni.removeStorageSync('fromNonTabBar');
},
onHide() {
uni.removeStorageSync('fromNonTabBar');
}, },
methods: { methods: {
getFlowStatus(status) { getFlowStatus(status) {

View File

@@ -11,6 +11,45 @@ let requestQueue = []
let isRefreshingToken = false let isRefreshingToken = false
const isRelogin = { show: false } const isRelogin = { show: false }
// 全局网络状态标记(防止多请求覆盖)
let GLOBAL_IS_NETWORK_ERROR = false;
// ========== 核心:全局拦截登录跳转 ==========
// 拦截所有跳登录页的操作,仅允许非断网场景跳转
function interceptLoginJump() {
// 拦截 reLaunch最常用的跳登录方式
const originalReLaunch = uni.reLaunch;
uni.reLaunch = function(options) {
// 如果是跳登录页 + 当前是网络错误 → 阻止跳转
if (options.url && options.url.includes('/pages/login/index') && GLOBAL_IS_NETWORK_ERROR) {
console.log('【拦截】断网时禁止跳登录页');
uni.showToast({
title: '网络已断开,请先连接网络',
icon: 'none',
duration: 3000
});
return; // 终止跳转
}
// 非登录页/非断网场景 → 正常跳转
originalReLaunch.call(uni, options);
};
// 拦截其他跳转方式(兜底)
const interceptors = ['navigateTo', 'redirectTo', 'switchTab'];
interceptors.forEach(method => {
const originalMethod = uni[method];
uni[method] = function(options) {
if (options.url && options.url.includes('/pages/login/index') && GLOBAL_IS_NETWORK_ERROR) {
return;
}
originalMethod.call(uni, options);
};
});
}
// 初始化拦截器(页面加载时执行一次)
interceptLoginJump();
// ------------- 核心request方法 ------------- // ------------- 核心request方法 -------------
function request(config) { function request(config) {
config.options = Object.assign(defaultOpt, config.options) config.options = Object.assign(defaultOpt, config.options)
@@ -42,7 +81,7 @@ function request(config) {
uni.showLoading({ title: config.options.loadText || '正在加载' }) uni.showLoading({ title: config.options.loadText || '正在加载' })
} }
// 返回Promise,核心改造逻辑 // 返回Promise
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// 封装核心请求逻辑 // 封装核心请求逻辑
const coreRequest = () => { const coreRequest = () => {
@@ -54,6 +93,8 @@ function request(config) {
timeout: define.timeout, timeout: define.timeout,
success: async (res) => { success: async (res) => {
uni.hideLoading(); uni.hideLoading();
GLOBAL_IS_NETWORK_ERROR = false; // 有响应 → 网络正常
if (res.statusCode === 200) { if (res.statusCode === 200) {
if (res.data.code == 200 || res.data.code == 0) { if (res.data.code == 200 || res.data.code == 0) {
resolve(res.data) resolve(res.data)
@@ -61,30 +102,37 @@ function request(config) {
// 白名单接口不处理 // 白名单接口不处理
const isWhiteList = whiteList.some(v => config.url.includes(v)) const isWhiteList = whiteList.some(v => config.url.includes(v))
if (isWhiteList) { if (isWhiteList) {
// 仅提示错误,不触发登出 uni.showToast({ title: res.data.msg || '认证失败', icon: 'none' });
ajaxError(res.data, false) reject(res.data.msg);
reject(res.data.msg) return;
return
} }
// ------------- 刷新token逻辑 ------------- // 无刷新token → 提示手动登录(不自动跳转)
if (!refreshToken) { if (!refreshToken) {
// 无刷新token触发登出 uni.showModal({
await handleAuthorized() title: '登录过期',
reject(res.data.msg) content: '您的登录已过期,请重新登录',
return showCancelButton: false,
confirmText: '去登录'
}).then(res => {
if (res.confirm) {
clearAuthStorage();
uni.reLaunch({ url: '/pages/login/index' }); // 这里会走拦截器,仅网络正常时跳转
}
});
reject('登录过期无刷新Token');
return;
} }
if (isRefreshingToken) { if (isRefreshingToken) {
requestQueue.push(() => coreRequest()) requestQueue.push(() => coreRequest());
return return;
} }
isRefreshingToken = true isRefreshingToken = true;
try { try {
// 拼接URL参数 // 刷新token接口
const refreshUrl = `${host}/admin-api/system/auth/refresh-token?refreshToken=${encodeURIComponent(refreshToken)}` const refreshUrl = `${host}/admin-api/system/auth/refresh-token?refreshToken=${encodeURIComponent(refreshToken)}`;
// 调用刷新token接口
const refreshRes = await uni.request({ const refreshRes = await uni.request({
url: refreshUrl, url: refreshUrl,
method: 'POST', method: 'POST',
@@ -93,50 +141,63 @@ function request(config) {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
data: {} data: {}
}) });
// 刷新成功处理
if (refreshRes.data && (refreshRes.data.code == 0 || refreshRes.data.code == 200)) { if (refreshRes.data && (refreshRes.data.code == 0 || refreshRes.data.code == 200)) {
const newTokenData = refreshRes.data.data // 刷新成功
// 存储新token const newTokenData = refreshRes.data.data;
uni.setStorageSync('token', newTokenData.accessToken) uni.setStorageSync('token', newTokenData.accessToken);
uni.setStorageSync('refreshToken', newTokenData.refreshToken) uni.setStorageSync('refreshToken', newTokenData.refreshToken);
// 更新请求头 header['Authorization'] = newTokenData.accessToken;
header['Authorization'] = newTokenData.accessToken coreRequest();
// 重试当前请求 requestQueue.forEach(cb => cb());
coreRequest() requestQueue = [];
// 执行队列请求
requestQueue.forEach(cb => cb())
requestQueue = []
} else { } else {
// 刷新token失败触发登出 // 刷新失败 → 提示手动登录
await handleAuthorized() uni.showModal({
reject('刷新token失败' + (refreshRes.data?.msg || '接口返回异常')) title: '登录过期',
content: '刷新登录状态失败,请重新登录',
showCancelButton: false,
confirmText: '去登录'
}).then(res => {
if (res.confirm) {
clearAuthStorage();
uni.reLaunch({ url: '/pages/login/index' });
}
});
reject('刷新Token失败' + (refreshRes.data?.msg || '接口返回异常'));
} }
} catch (err) { } catch (err) {
// 刷新token异常,触发登出 // 刷新token异常 → 判定为网络错误
await handleAuthorized() GLOBAL_IS_NETWORK_ERROR = true;
reject('刷新token异常' + err.errMsg) uni.showToast({ title: '网络异常,无法刷新登录状态', icon: 'none', duration: 3000 });
reject('网络异常:' + (err.errMsg || err.message));
} finally { } finally {
isRefreshingToken = false isRefreshingToken = false;
requestQueue = [] requestQueue = [];
} }
} else { } else {
// 普通业务错误,仅提示,不登出 // 普通业务错误
ajaxError(res.data, false) uni.showToast({ title: res.data.msg || '请求出错,请重试', icon: 'none' });
reject(res.data.msg) reject(res.data.msg);
} }
} else { } else {
// HTTP状态码错误,仅提示,不登出 // HTTP状态码错误
ajaxError(res.data, false) uni.showToast({ title: `请求失败[${res.statusCode}]`, icon: 'none' });
reject(res.errMsg) reject(res.errMsg);
} }
}, },
fail: (err) => { fail: (err) => {
uni.hideLoading(); uni.hideLoading();
// 网络错误,仅提示,不登出 GLOBAL_IS_NETWORK_ERROR = true;
uni.showToast({ title: '连接服务器失败', icon: 'none' })
reject(err) // 重置刷新状态,防止死锁
isRefreshingToken = false;
requestQueue = [];
// 仅提示网络错误,不跳转
uni.showToast({ title: '网络连接失败,请检查网络', icon: 'none', duration: 3000 });
reject({ isNetworkError: true, errMsg: err.errMsg });
} }
}) })
} }
@@ -147,57 +208,16 @@ function request(config) {
// ------------- 辅助函数 ------------- // ------------- 辅助函数 -------------
/** /**
* 错误提示函数 * 清除登录缓存
* @param {Object} data 错误数据
* @param {Boolean} isAuthError 是否是认证错误(是否需要触发登出)
*/ */
function ajaxError(data, isAuthError = false) { function clearAuthStorage() {
uni.showToast({ uni.removeStorageSync('token');
title: data.msg || '请求出错,请重试', uni.removeStorageSync('refreshToken');
icon: 'none', uni.removeStorageSync('cid');
duration: 2000, // 延长提示时间,提升体验 uni.removeStorageSync('userInfo');
complete() { uni.removeStorageSync('permissionList');
// 只有明确的认证错误且不在刷新token过程中才触发登出 uni.removeStorageSync('sysVersion');
if (isAuthError && [600, 601, 602, 401].includes(data.code) && !isRefreshingToken) { uni.removeStorageSync('dynamicModelExtra');
setTimeout(() => handleAuthorized(), 1500)
}
}
})
} }
/** export default request;
* 处理登录过期逻辑仅token失效时调用
*/
async function handleAuthorized() {
// 防止重复弹出登录弹窗
if (!isRelogin.show) {
isRelogin.show = true
try {
const res = await uni.showModal({
title: '登录过期',
content: '您的登录已过期,请重新登录',
showCancelButton: false,
confirmText: '重新登录'
})
if (res.confirm) {
// 清除登录相关缓存
uni.removeStorageSync('token')
uni.removeStorageSync('refreshToken')
uni.removeStorageSync('cid')
uni.removeStorageSync('userInfo')
uni.removeStorageSync('permissionList')
uni.removeStorageSync('sysVersion')
uni.removeStorageSync('dynamicModelExtra')
// 跳转到登录页
uni.reLaunch({ url: '/pages/login/index' })
}
} catch (err) {
console.error('处理登录过期异常:', err)
} finally {
isRefreshingToken = false
isRelogin.show = false
}
}
}
export default request