提交室内导览交互与讲解优化

This commit is contained in:
lyf
2026-06-14 23:48:13 +08:00
parent a7c1879f60
commit feb7310a46
33 changed files with 3257 additions and 361 deletions

View File

@@ -72,8 +72,9 @@ export interface HallDetailViewModel {
}
const contentTypeFor = (exhibit: MuseumExhibit): ExplainContentType => {
if (exhibit.tags?.some((tag) => /体验|教育|商业|公共/.test(tag))) return 'zone'
if (exhibit.tags?.some((tag) => /主题/.test(tag))) return 'theme'
if (exhibit.hallName && exhibit.tags?.some((tag) => /展厅/.test(tag))) return 'hall'
if (exhibit.hallName && exhibit.tags?.some((tag) => /展厅|空间/.test(tag))) return 'hall'
return 'exhibit'
}
@@ -84,7 +85,7 @@ const buildSubtitle = (exhibit: MuseumExhibit) => [
const buildBadges = (exhibit: MuseumExhibit) => {
const badges = [
exhibit.hallName ? '展厅讲解' : '讲解',
exhibit.hallName ? '空间讲解' : '展品讲解',
exhibit.floorLabel || '',
...(exhibit.tags || [])
].filter(Boolean)
@@ -92,52 +93,77 @@ const buildBadges = (exhibit: MuseumExhibit) => {
return Array.from(new Set(badges)).slice(0, 3)
}
export const toExplainCardViewModel = (exhibit: MuseumExhibit): ExplainCardViewModel => ({
id: exhibit.id,
title: exhibit.name,
subtitle: buildSubtitle(exhibit),
summary: exhibit.description || '讲解内容待正式内容库补充。',
coverImage: exhibit.image,
contentType: contentTypeFor(exhibit),
hallName: exhibit.hallName,
floorLabel: exhibit.floorLabel,
durationLabel: undefined,
languageLabel: undefined,
audioStatus: 'unavailable',
audioStatusText: '图文讲解',
badges: buildBadges(exhibit),
progress: undefined,
poiId: exhibit.poiId,
locationActionText: '查看位置'
})
export const toExplainCardViewModel = (exhibit: MuseumExhibit): ExplainCardViewModel => {
const sourceHasAudio = exhibit.tags?.includes('源数据含音频地址') === true
return {
id: exhibit.id,
title: exhibit.name,
subtitle: buildSubtitle(exhibit),
summary: exhibit.description || '讲解内容来自 SGS 场景设置数据,正式 CMS 文案接入后可继续替换。',
coverImage: exhibit.image,
contentType: contentTypeFor(exhibit),
hallName: exhibit.hallName,
floorLabel: exhibit.floorLabel,
durationLabel: undefined,
languageLabel: '中文',
audioStatus: 'unavailable',
audioStatusText: sourceHasAudio ? '音频待同步' : '图文讲解',
badges: buildBadges(exhibit),
progress: undefined,
poiId: exhibit.poiId,
locationActionText: exhibit.poiId ? '查看位置' : undefined
}
}
export const toExplainExhibitViewModel = (exhibit: MuseumExhibit): ExplainExhibitViewModel => toExplainCardViewModel(exhibit)
export const toExplainDetailPageViewModel = (exhibit: MuseumExhibit): ExplainDetailPageViewModel => ({
id: exhibit.id,
title: exhibit.name,
subtitle: buildSubtitle(exhibit),
contentType: contentTypeFor(exhibit),
coverImages: [exhibit.image || '/static/exhibit-placeholder.jpg'].filter(Boolean),
hallName: exhibit.hallName,
floorLabel: exhibit.floorLabel,
summary: exhibit.description || '该讲解内容待正式内容库补充。',
body: exhibit.description || '该讲解内容待正式内容库补充。',
audio: {
status: 'unavailable',
unavailableReason: '正式讲解音频尚未接入媒体仓储'
},
chapters: [],
transcript: undefined,
location: exhibit.poiId
? {
poiId: exhibit.poiId,
actionText: '查看三维位置',
previewOnly: true
}
: undefined,
relatedItems: []
})
export const toExplainDetailPageViewModel = (exhibit: MuseumExhibit): ExplainDetailPageViewModel => {
const sourceHasAudio = exhibit.tags?.includes('源数据含音频地址') === true
const metadataLines = [
exhibit.size ? `展品编号:${exhibit.size}` : '',
exhibit.year ? `年代:${exhibit.year}` : '',
exhibit.material ? `来源:${exhibit.material}` : ''
].filter(Boolean)
const body = [
exhibit.description || '该讲解内容来自 SGS 场景设置数据,正式 CMS 文案接入后可继续替换。',
metadataLines.join('\n')
].filter(Boolean).join('\n\n')
return {
id: exhibit.id,
title: exhibit.name,
subtitle: buildSubtitle(exhibit),
contentType: contentTypeFor(exhibit),
coverImages: [exhibit.image || '/static/exhibit-placeholder.jpg'].filter(Boolean),
hallName: exhibit.hallName,
floorLabel: exhibit.floorLabel,
summary: exhibit.description || '该讲解内容来自 SGS 场景设置数据。',
body,
audio: {
status: 'unavailable',
language: 'zh-CN',
unavailableReason: sourceHasAudio
? 'SGS 场景设置源数据包含音频地址,但静态音频文件尚未同步到当前 H5 项目。'
: '该讲解在 SGS 场景设置源数据中暂无音频地址。'
},
chapters: metadataLines.length
? metadataLines.map((line, index) => ({
id: `${exhibit.id}-metadata-${index}`,
title: line
}))
: [],
transcript: exhibit.description,
location: exhibit.poiId
? {
poiId: exhibit.poiId,
actionText: '查看三维位置',
previewOnly: true
}
: undefined,
relatedItems: []
}
}
export const toExplainDetailViewModel = (exhibit: MuseumExhibit): ExplainDetailViewModel => toExplainDetailPageViewModel(exhibit)
@@ -145,7 +171,7 @@ export const toHallDetailViewModel = (hall: MuseumHall): HallDetailViewModel =>
id: hall.id,
name: hall.name,
floorLabel: hall.floorLabel || '楼层待补充',
description: hall.description || '该展厅介绍待正式内容补充。',
description: hall.description || '该空间介绍待 SGS 场景设置或 CMS 内容补充。',
image: hall.image || '/static/hall-placeholder.jpg',
exhibitCount: hall.exhibitCount || 0,
area: hall.area,