hookehuyr

feat(AdPage): 添加手动刷新功能和加载超时处理

添加手动刷新UI组件和加载超时处理逻辑,当图片加载失败或超时时显示刷新选项
支持自动重试机制,超过最大重试次数后显示手动刷新按钮
......@@ -148,6 +148,86 @@
}
}
// 手动刷新样式
.manual-refresh-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #f8f9fa;
z-index: 2;
}
.refresh-content {
text-align: center;
padding: 60rpx 40rpx;
background: white;
border-radius: 16rpx;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1);
margin: 0 40rpx;
max-width: 600rpx;
}
.refresh-icon {
font-size: 80rpx;
margin-bottom: 24rpx;
}
.refresh-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.refresh-subtitle {
font-size: 28rpx;
color: #666;
margin-bottom: 40rpx;
line-height: 1.5;
}
.refresh-buttons {
display: flex;
gap: 20rpx;
justify-content: center;
}
.refresh-button {
flex: 1;
padding: 24rpx 32rpx;
background: linear-gradient(135deg, #007aff, #0056cc);
color: white;
border-radius: 12rpx;
font-size: 32rpx;
font-weight: 600;
text-align: center;
&:active {
background: linear-gradient(135deg, #0056cc, #003d99);
transform: scale(0.98);
}
}
.retry-button-small {
flex: 1;
padding: 24rpx 32rpx;
background: #f0f0f0;
color: #666;
border-radius: 12rpx;
font-size: 32rpx;
text-align: center;
&:active {
background: #e0e0e0;
transform: scale(0.98);
}
}
// 错误提示样式
.error-container {
position: absolute;
......
......@@ -12,12 +12,27 @@
<view class="skeleton-image">
<view class="skeleton-shimmer"></view>
<view class="skeleton-text">
<view class="loading-title">正在加载精彩内容</view>
<view class="loading-title">
{{ retryCount > 0 ? `正在重试加载 (${retryCount}/${maxRetries})` : '正在加载精彩内容' }}
</view>
<view class="loading-subtitle">请稍候...</view>
</view>
</view>
</view>
<!-- 手动刷新提示 -->
<view v-if="showManualRefresh" class="manual-refresh-container">
<view class="refresh-content">
<view class="refresh-icon">⚠️</view>
<view class="refresh-title">加载遇到问题</view>
<view class="refresh-subtitle">网络可能不稳定,请尝试刷新页面</view>
<view class="refresh-buttons">
<view class="refresh-button" @tap="manualRefresh">刷新页面</view>
<view class="retry-button-small" @tap="retryLoadImage">重试</view>
</view>
</view>
</view>
<!-- 背景图片 -->
<image
v-show="!imageLoading && !imageLoadError"
......@@ -66,6 +81,11 @@ const loading = ref(true);
const hasFamily = ref(false);
const imageLoading = ref(true); // 图片加载状态
const imageLoadError = ref(false); // 图片加载错误状态
const loadingTimeout = ref(null); // 加载超时定时器
const retryCount = ref(0); // 重试次数
const maxRetries = ref(3); // 最大重试次数
const isTimeout = ref(false); // 是否超时
const showManualRefresh = ref(false); // 是否显示手动刷新按钮
/**
* 获取广告配置
......@@ -126,16 +146,22 @@ const handleImageClick = () => {
* 图片加载完成处理
*/
const handleImageLoad = () => {
clearLoadingTimeout();
imageLoading.value = false;
imageLoadError.value = false;
isTimeout.value = false;
showManualRefresh.value = false;
retryCount.value = 0;
};
/**
* 图片加载失败处理
*/
const handleImageError = () => {
clearLoadingTimeout();
imageLoading.value = false;
imageLoadError.value = true;
handleLoadingTimeout();
};
/**
......@@ -144,15 +170,86 @@ const handleImageError = () => {
const retryLoadImage = () => {
imageLoading.value = true;
imageLoadError.value = false;
isTimeout.value = false;
showManualRefresh.value = false;
// 开始超时检测
startLoadingTimeout();
// 重新获取广告配置
fetchAdConfig();
};
/**
* 页面初始化
* 手动刷新页面
*/
const manualRefresh = () => {
// 重置所有状态
retryCount.value = 0;
imageLoading.value = true;
imageLoadError.value = false;
isTimeout.value = false;
showManualRefresh.value = false;
loading.value = true;
// 重新初始化页面
initializePage();
};
/**
* 开始加载超时检测
*/
const startLoadingTimeout = () => {
// 清除之前的定时器
if (loadingTimeout.value) {
clearTimeout(loadingTimeout.value);
}
// 设置10秒超时
loadingTimeout.value = setTimeout(() => {
if (imageLoading.value) {
console.warn('图片加载超时');
isTimeout.value = true;
handleLoadingTimeout();
}
}, 10000);
};
/**
* 处理加载超时
*/
const handleLoadingTimeout = () => {
if (retryCount.value < maxRetries.value) {
// 自动重试
retryCount.value++;
console.log(`第${retryCount.value}次自动重试加载`);
retryLoadImage();
} else {
// 超过最大重试次数,显示手动刷新选项
imageLoading.value = false;
showManualRefresh.value = true;
console.error('图片加载失败,已达到最大重试次数');
}
};
/**
* 清除加载超时定时器
*/
const clearLoadingTimeout = () => {
if (loadingTimeout.value) {
clearTimeout(loadingTimeout.value);
loadingTimeout.value = null;
}
};
/**
* 页面初始化逻辑
*/
onMounted(async () => {
const initializePage = async () => {
try {
// 开始超时检测
startLoadingTimeout();
// 执行静默授权
await performSilentAuth();
......@@ -163,9 +260,18 @@ onMounted(async () => {
]);
} catch (error) {
console.error('页面初始化失败:', error);
// 初始化失败时也要处理超时
handleLoadingTimeout();
} finally {
loading.value = false;
}
};
/**
* 页面初始化
*/
onMounted(() => {
initializePage();
});
/**
......