feat: refine guide explain UX and QA docs
This commit is contained in:
@@ -1,26 +1,50 @@
|
||||
<template>
|
||||
<view class="exhibit-card" @tap="handleClick">
|
||||
<image v-if="exhibit.image" class="exhibit-image" :src="exhibit.image" mode="aspectFill" />
|
||||
<image
|
||||
v-if="coverImage"
|
||||
class="exhibit-image"
|
||||
:src="coverImage"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view v-else class="exhibit-image placeholder">
|
||||
<text class="placeholder-text">讲</text>
|
||||
</view>
|
||||
<view class="exhibit-content">
|
||||
<text class="exhibit-name">{{ exhibit.name }}</text>
|
||||
<text v-if="exhibit.artist" class="exhibit-artist">{{ exhibit.artist }}</text>
|
||||
<view v-if="exhibit.hall" class="exhibit-meta">
|
||||
<text class="meta-text">📍 {{ exhibit.hall }}</text>
|
||||
<text class="exhibit-name">{{ title }}</text>
|
||||
<text v-if="subtitle" class="exhibit-subtitle">{{ subtitle }}</text>
|
||||
<view class="exhibit-meta">
|
||||
<svg class="meta-icon" width="14" height="14" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M12 21C12 21 18 14.9 18 9.8C18 6.5 15.3 4 12 4C8.7 4 6 6.5 6 9.8C6 14.9 12 21 12 21Z" stroke="currentColor" stroke-width="1.8"/>
|
||||
<circle cx="12" cy="10" r="2.2" stroke="currentColor" stroke-width="1.8"/>
|
||||
</svg>
|
||||
<text class="meta-text">{{ metaText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="exhibit.hasAudio" class="audio-badge">
|
||||
<text class="audio-icon">🎧</text>
|
||||
<view class="audio-badge" :class="`status-${audioStatus}`">
|
||||
<text class="audio-text">{{ audioStatusText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import type {
|
||||
ExplainAudioStatus
|
||||
} from '@/view-models/explainViewModels'
|
||||
|
||||
interface Exhibit {
|
||||
id: string
|
||||
name: string
|
||||
artist?: string
|
||||
title?: string
|
||||
name?: string
|
||||
subtitle?: string
|
||||
hall?: string
|
||||
hallName?: string
|
||||
floor?: string
|
||||
floorLabel?: string
|
||||
coverImage?: string
|
||||
image?: string
|
||||
audioStatus?: ExplainAudioStatus
|
||||
audioStatusText?: string
|
||||
hasAudio?: boolean
|
||||
}
|
||||
|
||||
@@ -32,6 +56,18 @@ const emit = defineEmits<{
|
||||
click: [exhibit: Exhibit]
|
||||
}>()
|
||||
|
||||
const title = computed(() => props.exhibit.title || props.exhibit.name || '讲解内容')
|
||||
const subtitle = computed(() => props.exhibit.subtitle || props.exhibit.hall || props.exhibit.hallName)
|
||||
const coverImage = computed(() => props.exhibit.coverImage || props.exhibit.image)
|
||||
const audioStatus = computed<ExplainAudioStatus>(() => (
|
||||
props.exhibit.audioStatus || (props.exhibit.hasAudio ? 'playable' : 'unavailable')
|
||||
))
|
||||
const audioStatusText = computed(() => props.exhibit.audioStatusText || (audioStatus.value === 'playable' ? '音频' : '图文'))
|
||||
const metaText = computed(() => [
|
||||
props.exhibit.floorLabel || props.exhibit.floor,
|
||||
audioStatusText.value
|
||||
].filter(Boolean).join(' · '))
|
||||
|
||||
const handleClick = () => {
|
||||
emit('click', props.exhibit)
|
||||
}
|
||||
@@ -40,12 +76,16 @@ const handleClick = () => {
|
||||
<style scoped lang="scss">
|
||||
.exhibit-card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-height: 104px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--museum-bg-surface);
|
||||
border-radius: var(--radius-card);
|
||||
border: 1px solid #ebece5;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow-sm);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.exhibit-card:active {
|
||||
@@ -53,33 +93,59 @@ const handleClick = () => {
|
||||
}
|
||||
|
||||
.exhibit-image {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
flex-shrink: 0;
|
||||
width: 76px;
|
||||
height: 84px;
|
||||
border-radius: 8px;
|
||||
background-color: var(--museum-bg-light);
|
||||
}
|
||||
|
||||
.exhibit-image.placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #eef1e8;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #68725d;
|
||||
}
|
||||
|
||||
.exhibit-content {
|
||||
padding: var(--space-md);
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.exhibit-name {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 21px;
|
||||
font-weight: 700;
|
||||
color: var(--museum-text-primary);
|
||||
margin-bottom: var(--space-xs);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.exhibit-artist {
|
||||
font-size: 13px;
|
||||
.exhibit-subtitle {
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 17px;
|
||||
color: var(--museum-text-secondary);
|
||||
margin-bottom: var(--space-sm);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.exhibit-meta {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.meta-icon {
|
||||
flex-shrink: 0;
|
||||
color: #68725d;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.meta-text {
|
||||
@@ -89,19 +155,30 @@ const handleClick = () => {
|
||||
|
||||
.audio-badge {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background-color: var(--museum-accent);
|
||||
border-radius: 50%;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
min-width: 44px;
|
||||
height: 24px;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: var(--shadow-sm);
|
||||
box-sizing: border-box;
|
||||
background-color: #eef1e8;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.audio-icon {
|
||||
font-size: 16px;
|
||||
.audio-badge.status-playable {
|
||||
background-color: var(--museum-accent);
|
||||
}
|
||||
|
||||
.audio-text {
|
||||
font-size: 11px;
|
||||
color: #4f574b;
|
||||
}
|
||||
|
||||
.audio-badge.status-playable .audio-text {
|
||||
color: #151713;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -117,7 +117,7 @@ const emit = defineEmits<{
|
||||
// POI ID: 7043042949572197975
|
||||
const mapCenter = ref<MapCenter>({
|
||||
latitude: 22.692763, // 深圳自然博物馆纬度
|
||||
longitude: 114.363987 // 深圳自然博物馆经度(向右偏移,让建筑显示在左侧)
|
||||
longitude: 114.363572 // 深圳自然博物馆经度(调整到室外 2D 视觉中心)
|
||||
})
|
||||
|
||||
// 地图缩放级别(调整为适中比例,既能看到建筑全貌又能看清细节)
|
||||
|
||||
Reference in New Issue
Block a user