feat(网络状态): 添加网络从可用变为弱网/无网时的弹窗提示功能
在网络状态从可用变为弱网或无网时,新增弹窗提示用户并可一键进入离线模式 优化网络状态变化处理逻辑,避免重复提示并增加页面路由判断
Showing
2 changed files
with
88 additions
and
31 deletions
| ... | @@ -26,6 +26,7 @@ | ... | @@ -26,6 +26,7 @@ |
| 26 | * 离线预约记录详情/离线二维码 (`pages/offlineBookingDetail/index`) | 26 | * 离线预约记录详情/离线二维码 (`pages/offlineBookingDetail/index`) |
| 27 | * 离线预约码入口页 (`pages/offlineBookingCode/index`) | 27 | * 离线预约码入口页 (`pages/offlineBookingCode/index`) |
| 28 | * 离线预约缓存刷新与轮询 (`src/composables/useOfflineBookingCache.js`, `src/composables/useOfflineBookingCachePolling.js`) | 28 | * 离线预约缓存刷新与轮询 (`src/composables/useOfflineBookingCache.js`, `src/composables/useOfflineBookingCachePolling.js`) |
| 29 | + * 网络从可用变为弱网/无网时,弹窗提示并可一键进入离线模式(`src/app.js`) | ||
| 29 | 30 | ||
| 30 | 5. **义工核销** | 31 | 5. **义工核销** |
| 31 | * 义工登录与权限预检 (`pages/volunteerLogin/index`) | 32 | * 义工登录与权限预检 (`pages/volunteerLogin/index`) | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-06-28 10:33:00 | 2 | * @Date: 2025-06-28 10:33:00 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2026-01-13 23:30:40 | 4 | + * @LastEditTime: 2026-01-16 00:17:50 |
| 5 | * @FilePath: /xyxBooking-weapp/src/app.js | 5 | * @FilePath: /xyxBooking-weapp/src/app.js |
| 6 | * @Description: 应用入口文件 | 6 | * @Description: 应用入口文件 |
| 7 | */ | 7 | */ |
| ... | @@ -16,7 +16,10 @@ import { is_usable_network, get_network_type } from '@/utils/network' | ... | @@ -16,7 +16,10 @@ import { is_usable_network, get_network_type } from '@/utils/network' |
| 16 | import { enable_offline_booking_cache_polling } from '@/composables/useOfflineBookingCachePolling' | 16 | import { enable_offline_booking_cache_polling } from '@/composables/useOfflineBookingCachePolling' |
| 17 | import { weak_network_text, get_weak_network_modal_use_cache_options } from '@/utils/uiText' | 17 | import { weak_network_text, get_weak_network_modal_use_cache_options } from '@/utils/uiText' |
| 18 | 18 | ||
| 19 | +// 记录是否已展示过网络异常提示弹窗 | ||
| 19 | let has_shown_network_modal = false | 20 | let has_shown_network_modal = false |
| 21 | +// 记录上一次网络是否可用,用于识别“从可用变为不可用”的场景 | ||
| 22 | +let last_network_usable = null | ||
| 20 | 23 | ||
| 21 | const App = createApp({ | 24 | const App = createApp({ |
| 22 | // 对应 onLaunch | 25 | // 对应 onLaunch |
| ... | @@ -48,32 +51,34 @@ const App = createApp({ | ... | @@ -48,32 +51,34 @@ const App = createApp({ |
| 48 | } | 51 | } |
| 49 | 52 | ||
| 50 | /** | 53 | /** |
| 51 | - * 监听网络状态变化 | 54 | + * 判断是否应该跳过网络异常提示弹窗 |
| 52 | - * - 当网络连接且有授权时,预加载离线预约记录数据 | 55 | + * - 仅在当前页面为离线预约列表/详情/核销码页时返回 true |
| 53 | */ | 56 | */ |
| 54 | - Taro.onNetworkStatusChange((res) => { | 57 | + |
| 55 | - if (res.isConnected && hasAuth()) { | 58 | + const should_skip_network_prompt = () => { |
| 56 | - preloadBookingData() | 59 | + const pages = Taro.getCurrentPages ? Taro.getCurrentPages() : [] |
| 60 | + const current_page = pages && pages.length ? pages[pages.length - 1] : null | ||
| 61 | + const current_route = String(current_page?.route || '') | ||
| 62 | + if (!current_route) return false | ||
| 63 | + if (current_route.includes('pages/offlineBookingList/index')) return true | ||
| 64 | + if (current_route.includes('pages/offlineBookingDetail/index')) return true | ||
| 65 | + if (current_route.includes('pages/offlineBookingCode/index')) return true | ||
| 66 | + return false | ||
| 57 | } | 67 | } |
| 58 | - }) | ||
| 59 | 68 | ||
| 60 | /** | 69 | /** |
| 61 | - * 处理在启动时出现的不良网络情况 | 70 | + * 处理不良网络情况 |
| 62 | - * - 当网络连接不良且有离线预约记录缓存时,提示用户是否使用缓存进入离线模式 | 71 | + * - 仅在当前页面未跳过提示弹窗时调用 |
| 63 | - * - 当网络连接不良且无缓存时,提示用户网络连接不畅 | 72 | + * - 若有离线预约缓存,则展示弹窗询问是否使用缓存数据 |
| 64 | - * @returns {Promise<boolean>} 如果用户选择进入离线模式,则返回 true;否则返回 false | 73 | + * - 否则展示简单提示弹窗 |
| 65 | - */ | ||
| 66 | - const handle_bad_network_on_launch = async () => { | ||
| 67 | - /** | ||
| 68 | - * 避免重复提示用户 | ||
| 69 | - * - 仅在首次启动时检查网络情况 | ||
| 70 | */ | 74 | */ |
| 75 | + | ||
| 76 | + const handle_bad_network = async (network_type) => { | ||
| 71 | if (has_shown_network_modal) return false | 77 | if (has_shown_network_modal) return false |
| 78 | + if (should_skip_network_prompt()) return false | ||
| 72 | 79 | ||
| 73 | - const network_type = await get_network_type() | ||
| 74 | const is_none_network = network_type === 'none' | 80 | const is_none_network = network_type === 'none' |
| 75 | const is_weak_network = !is_usable_network(network_type) | 81 | const is_weak_network = !is_usable_network(network_type) |
| 76 | - | ||
| 77 | if (!is_weak_network) return false | 82 | if (!is_weak_network) return false |
| 78 | 83 | ||
| 79 | has_shown_network_modal = true | 84 | has_shown_network_modal = true |
| ... | @@ -99,8 +104,48 @@ const App = createApp({ | ... | @@ -99,8 +104,48 @@ const App = createApp({ |
| 99 | return is_none_network | 104 | return is_none_network |
| 100 | } | 105 | } |
| 101 | 106 | ||
| 102 | - const should_stop = await handle_bad_network_on_launch() | 107 | + /** |
| 103 | - if (should_stop) return | 108 | + * 监听网络状态变化 |
| 109 | + * - 当网络连接且有授权时,预加载离线预约记录数据 | ||
| 110 | + */ | ||
| 111 | + Taro.onNetworkStatusChange((res) => { | ||
| 112 | + const is_connected = res?.isConnected !== false | ||
| 113 | + const network_type = res?.networkType || 'none' | ||
| 114 | + const network_usable = is_connected && is_usable_network(network_type) | ||
| 115 | + | ||
| 116 | + if (network_usable) { | ||
| 117 | + has_shown_network_modal = false | ||
| 118 | + last_network_usable = true | ||
| 119 | + if (hasAuth()) preloadBookingData() | ||
| 120 | + return | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + const should_prompt = last_network_usable === true || last_network_usable === null | ||
| 124 | + last_network_usable = false | ||
| 125 | + if (should_prompt) { | ||
| 126 | + handle_bad_network(network_type) | ||
| 127 | + } | ||
| 128 | + return | ||
| 129 | + }) | ||
| 130 | + | ||
| 131 | + /** | ||
| 132 | + * 处理在启动时出现的不良网络情况 | ||
| 133 | + * - 当网络连接不良且有离线预约记录缓存时,提示用户是否使用缓存进入离线模式 | ||
| 134 | + * - 当网络连接不良且无缓存时,提示用户网络连接不畅 | ||
| 135 | + * @returns {Promise<boolean>} 如果用户选择进入离线模式,则返回 true;否则返回 false | ||
| 136 | + */ | ||
| 137 | + const handle_bad_network_on_launch = async () => { | ||
| 138 | + /** | ||
| 139 | + * 避免重复提示用户 | ||
| 140 | + * - 仅在首次启动时检查网络情况 | ||
| 141 | + * - 如果用户已展示过提示弹窗,则直接返回 false | ||
| 142 | + */ | ||
| 143 | + if (has_shown_network_modal) return false | ||
| 144 | + | ||
| 145 | + const network_type = await get_network_type() | ||
| 146 | + last_network_usable = is_usable_network(network_type) | ||
| 147 | + return handle_bad_network(network_type) | ||
| 148 | + } | ||
| 104 | 149 | ||
| 105 | /** | 150 | /** |
| 106 | * 尝试在网络可用时预加载离线预约记录数据 | 151 | * 尝试在网络可用时预加载离线预约记录数据 |
| ... | @@ -119,16 +164,28 @@ const App = createApp({ | ... | @@ -119,16 +164,28 @@ const App = createApp({ |
| 119 | } | 164 | } |
| 120 | 165 | ||
| 121 | /** | 166 | /** |
| 122 | - * 尝试在有授权时预加载二维码数据 | 167 | + * @description: 授权成功后的共用启动逻辑 |
| 168 | + * - 尝试在网络可用时预加载离线预约数据 | ||
| 169 | + * - 启动离线预约缓存轮询(会自行处理网络可用性与引用计数) | ||
| 170 | + */ | ||
| 171 | + const bootstrap_after_auth = () => { | ||
| 172 | + try_preload_when_online() | ||
| 173 | + enable_offline_booking_cache_polling() | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + // 处理在启动时出现的不良网络情况 | ||
| 177 | + const should_stop = await handle_bad_network_on_launch() | ||
| 178 | + // 如果用户选择进入离线模式,则直接返回 | ||
| 179 | + if (should_stop) return | ||
| 180 | + | ||
| 181 | + /** | ||
| 182 | + * 尝试在有授权时预加载离线预约记录数据 | ||
| 123 | * - 若无授权,则尝试静默授权 | 183 | * - 若无授权,则尝试静默授权 |
| 124 | - * - 授权成功后调用 try_preload_when_online 预加载数据 | 184 | + * - 授权成功后调用 bootstrap_after_auth 启动共用逻辑 |
| 125 | * - 授权失败则跳转至授权页面 | 185 | * - 授权失败则跳转至授权页面 |
| 126 | */ | 186 | */ |
| 127 | if (hasAuth()) { | 187 | if (hasAuth()) { |
| 128 | - // 有授权时预加载数据 | 188 | + bootstrap_after_auth() |
| 129 | - try_preload_when_online() | ||
| 130 | - // 启动离线预约缓存轮询 | ||
| 131 | - enable_offline_booking_cache_polling() | ||
| 132 | return | 189 | return |
| 133 | } | 190 | } |
| 134 | 191 | ||
| ... | @@ -137,19 +194,18 @@ const App = createApp({ | ... | @@ -137,19 +194,18 @@ const App = createApp({ |
| 137 | try { | 194 | try { |
| 138 | // 尝试静默授权 | 195 | // 尝试静默授权 |
| 139 | await silentAuth() | 196 | await silentAuth() |
| 140 | - // 授权成功后预加载数据 | 197 | + // 授权成功后调用 bootstrap_after_auth 启动共用逻辑 |
| 141 | - try_preload_when_online() | 198 | + bootstrap_after_auth() |
| 142 | - // 启动离线预约缓存轮询 | ||
| 143 | - enable_offline_booking_cache_polling() | ||
| 144 | } catch (error) { | 199 | } catch (error) { |
| 145 | console.error('静默授权失败:', error) | 200 | console.error('静默授权失败:', error) |
| 146 | // 授权失败则跳转至授权页面 | 201 | // 授权失败则跳转至授权页面 |
| 147 | navigateToAuth(full_path || undefined) | 202 | navigateToAuth(full_path || undefined) |
| 148 | } | 203 | } |
| 204 | + | ||
| 205 | + return | ||
| 149 | }, | 206 | }, |
| 150 | onShow() { | 207 | onShow() { |
| 151 | }, | 208 | }, |
| 152 | - // 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖 | ||
| 153 | }); | 209 | }); |
| 154 | 210 | ||
| 155 | App.use(createPinia()) | 211 | App.use(createPinia()) | ... | ... |
-
Please register or login to post a comment