hookehuyr

refactor(网络请求): 重构弱网处理逻辑并移除组件中的超时代码

将弱网和超时处理逻辑集中到请求拦截器中
移除组件中冗余的超时处理代码
添加离线预约缓存检查功能
<!--
* @Date: 2024-01-16 10:06:47
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-13 15:18:07
* @LastEditTime: 2026-01-13 16:00:44
* @FilePath: /xyxBooking-weapp/src/components/qrCode.vue
* @Description: 预约码卡组件
-->
......@@ -169,12 +169,7 @@ const formatGroup = (data) => {
const init = async () => {
if (!props.type) {
try {
// TAG: 设置 5s 超时判定为弱网
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('TIMEOUT')), 5000);
});
const { code, data } = await Promise.race([qrcodeListAPI(), timeoutPromise]);
const { code, data } = await qrcodeListAPI();
if (code) {
data.forEach(item => {
......@@ -194,10 +189,6 @@ const init = async () => {
}
} catch (err) {
console.error('Fetch QR List Failed:', err);
// 如果是超时,跳转弱网页面
if (err.message === 'TIMEOUT') {
go('/pages/weakNetwork/index');
}
}
} else {
if (props.payId) {
......
/*
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-08 19:25:17
* @LastEditTime: 2026-01-13 16:15:35
* @FilePath: /xyxBooking-weapp/src/utils/request.js
* @Description: 简单axios封装,后续按实际处理
*/
......@@ -11,6 +11,7 @@ import Taro from '@tarojs/taro'
// import qs from 'qs'
// import { strExist } from './tools'
import { refreshSession, saveCurrentPagePath, navigateToAuth } from './authRedirect'
import { has_offline_booking_cache } from '@/composables/useOfflineBookingCache'
// import { ProgressStart, ProgressEnd } from '@/components/axios-progress/progress';
// import store from '@/store'
......@@ -46,6 +47,95 @@ service.defaults.params = {
...REQUEST_DEFAULT_PARAMS,
};
let has_shown_timeout_modal = false
/**
* 判断是否为超时错误
* @param {Error} error - 请求错误对象
* @returns {boolean} 是否为超时错误
*/
const is_timeout_error = (error) => {
const msg = String(error?.message || error?.errMsg || '')
if (error?.code === 'ECONNABORTED') return true
return msg.toLowerCase().includes('timeout')
}
/**
* 判断是否为网络错误(断网/弱网/请求失败等)
* @param {Error} error - 请求错误对象
* @returns {boolean} 是否为网络错误
*/
const is_network_error = (error) => {
const msg = String(error?.message || error?.errMsg || '')
const raw = (() => {
try {
return JSON.stringify(error) || ''
} catch (e) {
return ''
}
})()
const lower = (msg + ' ' + raw).toLowerCase()
if (lower.includes('request:fail')) return true
if (lower.includes('request fail')) return true
if (lower.includes('network error')) return true
if (lower.includes('failed to fetch')) return true
if (lower.includes('the internet connection appears to be offline')) return true
if (lower.includes('err_blocked_by_client')) return true
if (lower.includes('blocked_by_client')) return true
return false
}
/**
* 是否需要触发弱网/断网降级逻辑
* - 超时:直接触发
* - 网络错误:直接触发(避免 wifi 但无网场景漏判)
* @param {Error} error - 请求错误对象
* @returns {Promise<boolean>} 是否需要触发降级
*/
const should_handle_bad_network = async (error) => {
if (is_timeout_error(error)) return true
return is_network_error(error)
}
/**
* 处理请求超时错误
* - 显示超时提示 modal
* - 若有离线预约记录缓存,则跳转至离线预约列表页
* - 否则提示用户检查网络连接
*/
const handle_request_timeout = async () => {
if (has_shown_timeout_modal) return
has_shown_timeout_modal = true
const pages = Taro.getCurrentPages ? Taro.getCurrentPages() : []
const current_page = pages && pages.length ? pages[pages.length - 1] : null
const current_route = current_page?.route || ''
if (String(current_route).includes('pages/offlineBookingList/index')) return
// 若有离线预约记录缓存,则跳转至离线预约列表页
if (has_offline_booking_cache()) {
try {
await Taro.reLaunch({ url: '/pages/offlineBookingList/index' })
} catch (e) {
console.error('reLaunch offlineBookingList failed:', e)
}
return
}
// 否则提示用户检查网络连接
try {
await Taro.showModal({
title: '网络连接不畅',
content: '当前网络信号较弱,暂无法使用小程序,请到网络更好的地方重试。',
confirmText: '知道了',
showCancel: false,
})
} catch (e) {
console.error('show weak network modal failed:', e)
}
}
// request interceptor
service.interceptors.request.use(
config => {
......@@ -144,12 +234,15 @@ service.interceptors.response.use(
return response
},
error => {
async error => {
// Taro.showToast({
// title: error.message,
// icon: 'none',
// duration: 2000
// })
if (await should_handle_bad_network(error)) {
handle_request_timeout()
}
return Promise.reject(error)
}
)
......