优化讲解展厅预览图弱网兜底
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-09 17:03:33 +08:00
parent 05c37db414
commit 5b4fe19ce3

View File

@@ -26,17 +26,32 @@
<template v-else>
<view v-if="stage === 'hall' && filteredHalls.length" class="hall-list">
<view
v-for="hall in filteredHalls"
v-for="(hall, index) in filteredHalls"
:key="hall.id"
class="hall-card"
@tap="handleHallClick(hall.id)"
>
<image
<view
v-if="hallPreviewUrl(hall)"
class="hall-thumb"
:src="hallPreviewUrl(hall)"
mode="aspectFill"
/>
class="hall-thumb hall-thumb-shell"
:class="{
'is-image-loaded': isHallPreviewLoaded(hall.id),
'is-image-error': isHallPreviewError(hall.id)
}"
>
<view class="hall-thumb-fallback">
<text class="hall-thumb-text">{{ hallIconText(hall.name) }}</text>
</view>
<image
v-if="!isHallPreviewError(hall.id)"
class="hall-thumb-image"
:src="hallPreviewUrl(hall)"
mode="aspectFill"
:lazy-load="isHallPreviewLazy(index)"
@load="handleHallPreviewLoad(hall.id)"
@error="handleHallPreviewError(hall.id)"
/>
</view>
<view v-else class="hall-thumb placeholder">
<text class="hall-thumb-text">{{ hallIconText(hall.name) }}</text>
</view>
@@ -202,6 +217,9 @@ const emit = defineEmits<{
}>()
const HALL_PREVIEW_BASE = '/static/explain/hall-previews'
const HALL_PREVIEW_EAGER_COUNT = 4
const loadedHallPreviewIds = ref(new Set<string>())
const failedHallPreviewIds = ref(new Set<string>())
const failedUnitPreviewIds = ref(new Set<string>())
const hallPreviewMap: Record<string, string> = {
@@ -249,6 +267,30 @@ const hallPreviewUrl = (hall: ExplainHallSelectItem) => {
const hallIconText = (name: string) => name.trim().slice(0, 1) || '讲'
const isHallPreviewLoaded = (hallId: string) => loadedHallPreviewIds.value.has(hallId)
const isHallPreviewError = (hallId: string) => failedHallPreviewIds.value.has(hallId)
const isHallPreviewLazy = (index: number) => index >= HALL_PREVIEW_EAGER_COUNT
const handleHallPreviewLoad = (hallId: string) => {
loadedHallPreviewIds.value = new Set([...loadedHallPreviewIds.value, hallId])
if (failedHallPreviewIds.value.has(hallId)) {
const nextFailedIds = new Set(failedHallPreviewIds.value)
nextFailedIds.delete(hallId)
failedHallPreviewIds.value = nextFailedIds
}
}
const handleHallPreviewError = (hallId: string) => {
failedHallPreviewIds.value = new Set([...failedHallPreviewIds.value, hallId])
if (loadedHallPreviewIds.value.has(hallId)) {
const nextLoadedIds = new Set(loadedHallPreviewIds.value)
nextLoadedIds.delete(hallId)
loadedHallPreviewIds.value = nextLoadedIds
}
}
const unitPreviewImageUrl = (unit: ExplainBusinessUnitSelectItem) => (
failedUnitPreviewIds.value.has(unit.id)
? EXPLAIN_UNIT_PREVIEW_FALLBACK
@@ -408,13 +450,52 @@ const handleBack = () => {
flex-shrink: 0;
width: 68px;
height: 68px;
position: relative;
overflow: hidden;
border-radius: 8px;
background: #ffffff;
background:
radial-gradient(circle at 70% 24%, rgba(224, 225, 0, 0.28), rgba(224, 225, 0, 0) 42%),
linear-gradient(135deg, #f4f6ed 0%, #e4eadc 100%);
border: 1px solid rgba(36, 49, 42, 0.06);
box-sizing: border-box;
object-fit: contain;
}
.hall-thumb-shell.is-image-loaded {
background: #eef0e4;
}
.hall-thumb-fallback {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
opacity: 1;
transition: opacity 0.2s ease;
}
.hall-thumb-shell.is-image-loaded .hall-thumb-fallback {
opacity: 0;
}
.hall-thumb-shell.is-image-error .hall-thumb-fallback {
opacity: 1;
}
.hall-thumb-image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 0.22s ease;
}
.hall-thumb-shell.is-image-loaded .hall-thumb-image {
opacity: 1;
}
.hall-thumb.placeholder {
display: flex;
align-items: center;