hookehuyr

feat(AdPage): 添加网络错误弹窗及降级图片处理逻辑

当广告图片加载失败时显示网络错误弹窗,并提供操作指引
初始化时使用默认图片作为降级方案,优化错误处理流程
...@@ -43,6 +43,106 @@ ...@@ -43,6 +43,106 @@
43 } 43 }
44 } 44 }
45 45
46 +/* 网络错误弹窗样式 */
47 +.network-error-popup {
48 + position: fixed;
49 + top: 0;
50 + left: 0;
51 + width: 100vw;
52 + height: 100vh;
53 + z-index: 1000;
54 + display: flex;
55 + align-items: center;
56 + justify-content: center;
57 +
58 + .popup-overlay {
59 + position: absolute;
60 + top: 0;
61 + left: 0;
62 + width: 100%;
63 + height: 100%;
64 + background: rgba(0, 0, 0, 0.5);
65 + backdrop-filter: blur(4rpx);
66 + -webkit-backdrop-filter: blur(4rpx);
67 + }
68 +
69 + .popup-content {
70 + position: relative;
71 + width: 600rpx;
72 + background: white;
73 + border-radius: 24rpx;
74 + padding: 60rpx 40rpx 40rpx;
75 + text-align: center;
76 + box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
77 +
78 + .popup-icon {
79 + font-size: 80rpx;
80 + margin-bottom: 20rpx;
81 + }
82 +
83 + .popup-title {
84 + font-size: 36rpx;
85 + font-weight: 600;
86 + color: #333;
87 + margin-bottom: 20rpx;
88 + }
89 +
90 + .popup-message {
91 + font-size: 28rpx;
92 + color: #666;
93 + line-height: 1.5;
94 + margin-bottom: 30rpx;
95 + }
96 +
97 + .popup-steps {
98 + text-align: left;
99 + margin-bottom: 40rpx;
100 +
101 + .step-item {
102 + font-size: 26rpx;
103 + color: #888;
104 + line-height: 1.6;
105 + margin-bottom: 10rpx;
106 + padding-left: 20rpx;
107 + }
108 + }
109 +
110 + .popup-buttons {
111 + display: flex;
112 + gap: 20rpx;
113 +
114 + .popup-button {
115 + flex: 1;
116 + height: 80rpx;
117 + line-height: 80rpx;
118 + text-align: center;
119 + border-radius: 12rpx;
120 + font-size: 28rpx;
121 + font-weight: 500;
122 + transition: all 0.3s ease;
123 +
124 + &.cancel {
125 + background: #f5f5f5;
126 + color: #666;
127 +
128 + &:active {
129 + background: #e8e8e8;
130 + }
131 + }
132 +
133 + &.confirm {
134 + background: #ff6b35;
135 + color: white;
136 +
137 + &:active {
138 + background: #e55a2b;
139 + }
140 + }
141 + }
142 + }
143 + }
144 +}
145 +
46 .loading-container { 146 .loading-container {
47 position: absolute; 147 position: absolute;
48 top: 0; 148 top: 0;
......
1 <!-- 1 <!--
2 * @Date: 2022-09-19 14:11:06 2 * @Date: 2022-09-19 14:11:06
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-09-28 14:03:53 4 + * @LastEditTime: 2025-09-28 14:08:23
5 * @FilePath: /lls_program/src/pages/AdPage/index.vue 5 * @FilePath: /lls_program/src/pages/AdPage/index.vue
6 * @Description: 广告页面 6 * @Description: 广告页面
7 --> 7 -->
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
36 <!-- 背景图片 --> 36 <!-- 背景图片 -->
37 <image 37 <image
38 v-show="!imageLoading && !imageLoadError" 38 v-show="!imageLoading && !imageLoadError"
39 - :src="adImageUrl || defaultAdImage" 39 + :src="adImageUrl"
40 class="ad-background" 40 class="ad-background"
41 mode="scaleToFill" 41 mode="scaleToFill"
42 @tap="handleImageClick" 42 @tap="handleImageClick"
...@@ -64,6 +64,30 @@ ...@@ -64,6 +64,30 @@
64 <view v-if="loading" class="loading-container"> 64 <view v-if="loading" class="loading-container">
65 <view class="loading-text">加载中...</view> 65 <view class="loading-text">加载中...</view>
66 </view> 66 </view>
67 +
68 + <!-- 网络错误提示弹窗 -->
69 + <view v-if="showNetworkErrorPopup" class="network-error-popup">
70 + <view class="popup-overlay" @tap="closeNetworkErrorPopup"></view>
71 + <view class="popup-content">
72 + <view class="popup-icon">⚠️</view>
73 + <view class="popup-title">网络不稳定</view>
74 + <view class="popup-message">
75 + 当前网络连接不稳定,建议您:
76 + </view>
77 + <view class="popup-steps">
78 + <view class="step-item">1. 检查网络连接</view>
79 + <view class="step-item">2. 删除小程序后重新进入</view>
80 + </view>
81 + <view class="popup-buttons">
82 + <view class="popup-button cancel" @tap="closeNetworkErrorPopup">
83 + 我知道了
84 + </view>
85 + <view class="popup-button confirm" @tap="deleteAndReenter">
86 + 删除重进
87 + </view>
88 + </view>
89 + </view>
90 + </view>
67 </view> 91 </view>
68 </template> 92 </template>
69 93
...@@ -79,7 +103,7 @@ import "./index.less"; ...@@ -79,7 +103,7 @@ import "./index.less";
79 const defaultAdImage = 'https://cdn.ipadbiz.cn/space_34093/%E5%BC%95%E5%AF%BC%E9%A1%B51_Fu2ZY_Tm6TL1OzbyrqQkeVRAdVfU.jpg?imageMogr2/strip/quality/60'; 103 const defaultAdImage = 'https://cdn.ipadbiz.cn/space_34093/%E5%BC%95%E5%AF%BC%E9%A1%B51_Fu2ZY_Tm6TL1OzbyrqQkeVRAdVfU.jpg?imageMogr2/strip/quality/60';
80 104
81 // 定义响应式数据 105 // 定义响应式数据
82 -const adImageUrl = ref(''); 106 +const adImageUrl = ref(defaultAdImage); // 初始化为默认图片
83 const loading = ref(true); 107 const loading = ref(true);
84 const hasFamily = ref(false); 108 const hasFamily = ref(false);
85 const imageLoading = ref(true); // 图片加载状态 109 const imageLoading = ref(true); // 图片加载状态
...@@ -89,6 +113,8 @@ const retryCount = ref(0); // 重试次数 ...@@ -89,6 +113,8 @@ const retryCount = ref(0); // 重试次数
89 const maxRetries = ref(3); // 最大重试次数 113 const maxRetries = ref(3); // 最大重试次数
90 const isTimeout = ref(false); // 是否超时 114 const isTimeout = ref(false); // 是否超时
91 const showManualRefresh = ref(false); // 是否显示手动刷新按钮 115 const showManualRefresh = ref(false); // 是否显示手动刷新按钮
116 +const showNetworkErrorPopup = ref(false); // 是否显示网络错误弹窗
117 +const useFallbackImage = ref(false); // 是否使用降级图片
92 118
93 /** 119 /**
94 * 获取广告配置 120 * 获取广告配置
...@@ -96,12 +122,42 @@ const showManualRefresh = ref(false); // 是否显示手动刷新按钮 ...@@ -96,12 +122,42 @@ const showManualRefresh = ref(false); // 是否显示手动刷新按钮
96 const fetchAdConfig = async () => { 122 const fetchAdConfig = async () => {
97 try { 123 try {
98 const { code, data } = await getBootPageAPI(); 124 const { code, data } = await getBootPageAPI();
99 - if (code && data) { 125 + if (code && data && data.adImageUrl) {
100 adImageUrl.value = data.adImageUrl; 126 adImageUrl.value = data.adImageUrl;
127 + useFallbackImage.value = false;
128 + return true;
129 + } else {
130 + throw new Error('广告配置数据无效');
101 } 131 }
102 } catch (error) { 132 } catch (error) {
103 console.error('获取广告配置失败:', error); 133 console.error('获取广告配置失败:', error);
134 + // 使用降级图片
135 + adImageUrl.value = defaultAdImage;
136 + useFallbackImage.value = true;
137 + throw error;
138 + }
139 +};
140 +
141 +/**
142 + * 关闭网络错误弹窗
143 + */
144 +const closeNetworkErrorPopup = () => {
145 + showNetworkErrorPopup.value = false;
146 +};
147 +
148 +/**
149 + * 删除小程序并重新进入的提示
150 + */
151 +const deleteAndReenter = () => {
152 + Taro.showModal({
153 + title: '操作提示',
154 + content: '请按以下步骤操作:\n1. 点击右上角"..."菜单\n2. 选择"删除"小程序\n3. 重新搜索进入小程序',
155 + showCancel: false,
156 + confirmText: '我知道了',
157 + success: () => {
158 + closeNetworkErrorPopup();
104 } 159 }
160 + });
105 }; 161 };
106 162
107 /** 163 /**
...@@ -238,12 +294,20 @@ const handleLoadingTimeout = () => { ...@@ -238,12 +294,20 @@ const handleLoadingTimeout = () => {
238 retryLoadImage(); 294 retryLoadImage();
239 }, 1000); 295 }, 1000);
240 } else { 296 } else {
241 - // 超过最大重试次数,显示手动刷新选项 297 + // 超过最大重试次数
242 imageLoading.value = false; 298 imageLoading.value = false;
243 loading.value = false; 299 loading.value = false;
300 +
301 + // 如果使用的是降级图片,显示网络错误弹窗
302 + if (useFallbackImage.value) {
303 + showNetworkErrorPopup.value = true;
304 + console.log('使用降级图片,显示网络错误提示');
305 + } else {
306 + // 否则显示手动刷新选项
244 showManualRefresh.value = true; 307 showManualRefresh.value = true;
245 console.error('图片加载失败,已达到最大重试次数'); 308 console.error('图片加载失败,已达到最大重试次数');
246 } 309 }
310 + }
247 }; 311 };
248 312
249 /** 313 /**
...@@ -276,43 +340,48 @@ const initializePage = async () => { ...@@ -276,43 +340,48 @@ const initializePage = async () => {
276 await fetchAdConfig(); 340 await fetchAdConfig();
277 adConfigSuccess = true; 341 adConfigSuccess = true;
278 } catch (adError) { 342 } catch (adError) {
279 - console.error('获取广告配置失败,但继续执行后续逻辑:', adError); 343 + console.error('获取广告配置失败,使用降级图片:', adError);
344 + adConfigSuccess = false; // 使用降级图片也算是一种"成功"
280 } 345 }
281 346
282 // 无论广告配置是否成功,都要检查家庭状态 347 // 无论广告配置是否成功,都要检查家庭状态
283 try { 348 try {
284 await checkUserFamily(); 349 await checkUserFamily();
285 350
286 - // 如果家庭状态检查成功,但广告配置失败了,再次尝试获取广告配置 351 + // 如果广告配置失败了(使用降级图片),再次尝试获取广告配置
287 if (!adConfigSuccess) { 352 if (!adConfigSuccess) {
288 try { 353 try {
289 await fetchAdConfig(); 354 await fetchAdConfig();
290 adConfigSuccess = true; 355 adConfigSuccess = true;
291 console.log('重试获取广告配置成功'); 356 console.log('重试获取广告配置成功');
292 } catch (retryError) { 357 } catch (retryError) {
293 - console.error('重试获取广告配置仍然失败:', retryError); 358 + console.error('重试获取广告配置仍然失败,继续使用降级图片:', retryError);
294 } 359 }
295 } 360 }
296 361
297 - // 如果广告配置成功,清除超时定时器并设置成功状态 362 + // 清除超时定时器并设置成功状态
298 - if (adConfigSuccess) {
299 clearLoadingTimeout(); 363 clearLoadingTimeout();
300 imageLoading.value = false; 364 imageLoading.value = false;
301 imageLoadError.value = false; 365 imageLoadError.value = false;
302 - } else { 366 +
303 - // 广告配置失败,触发重试逻辑 367 + // 如果最终还是使用降级图片,显示网络错误提示
304 - imageLoadError.value = true; 368 + if (useFallbackImage.value) {
305 - handleLoadingTimeout(); 369 + setTimeout(() => {
370 + showNetworkErrorPopup.value = true;
371 + }, 1000); // 延迟1秒显示,让用户先看到页面
306 } 372 }
307 373
308 } catch (familyError) { 374 } catch (familyError) {
309 console.error('检查家庭状态失败:', familyError); 375 console.error('检查家庭状态失败:', familyError);
310 // 家庭状态检查失败,但仍然尝试显示广告 376 // 家庭状态检查失败,但仍然尝试显示广告
311 - if (adConfigSuccess) {
312 clearLoadingTimeout(); 377 clearLoadingTimeout();
313 imageLoading.value = false; 378 imageLoading.value = false;
314 - } else { 379 +
315 - handleLoadingTimeout(); 380 + // 如果使用降级图片,显示网络错误提示
381 + if (useFallbackImage.value) {
382 + setTimeout(() => {
383 + showNetworkErrorPopup.value = true;
384 + }, 1000);
316 } 385 }
317 } 386 }
318 } catch (error) { 387 } catch (error) {
......