This commit is contained in:
@@ -160,6 +160,9 @@ export interface ExplainGuideStopSelectItem {
|
|||||||
hallId?: string
|
hallId?: string
|
||||||
hallName?: string
|
hallName?: string
|
||||||
floorId?: string
|
floorId?: string
|
||||||
|
poiId?: string
|
||||||
|
mapX?: number
|
||||||
|
mapY?: number
|
||||||
coverImageUrl?: string
|
coverImageUrl?: string
|
||||||
description?: string
|
description?: string
|
||||||
hasAudio?: boolean
|
hasAudio?: boolean
|
||||||
@@ -239,7 +242,7 @@ const emptyDescription = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const hallIconUrl = (hall: ExplainHallSelectItem) => {
|
const hallIconUrl = (hall: ExplainHallSelectItem) => {
|
||||||
return hallIconMap[hall.name.trim()] || hall.image || ''
|
return hall.image || hallIconMap[hall.name.trim()] || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const hallIconText = (name: string) => name.trim().slice(0, 1) || '讲'
|
const hallIconText = (name: string) => name.trim().slice(0, 1) || '讲'
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ export interface BackendGuideStop {
|
|||||||
id?: string | number | null
|
id?: string | number | null
|
||||||
name?: string | null
|
name?: string | null
|
||||||
floorId?: string | number | null
|
floorId?: string | number | null
|
||||||
|
mapX?: number | string | null
|
||||||
|
mapY?: number | string | null
|
||||||
targetType?: string | null
|
targetType?: string | null
|
||||||
targetId?: string | number | null
|
targetId?: string | number | null
|
||||||
coverImageUrl?: string | null
|
coverImageUrl?: string | null
|
||||||
@@ -128,6 +130,7 @@ export interface BackendCatalogLinkedExhibitItem {
|
|||||||
code?: string | null
|
code?: string | null
|
||||||
exhibitCode?: string | null
|
exhibitCode?: string | null
|
||||||
coverImageUrl?: string | null
|
coverImageUrl?: string | null
|
||||||
|
galleryUrls?: string | string[] | null
|
||||||
sortOrder?: number | null
|
sortOrder?: number | null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +138,10 @@ export interface BackendCatalogStopItem {
|
|||||||
stopId?: string | number | null
|
stopId?: string | number | null
|
||||||
id?: string | number | null
|
id?: string | number | null
|
||||||
outlineId?: string | number | null
|
outlineId?: string | number | null
|
||||||
|
poiId?: string | number | null
|
||||||
|
floorId?: string | number | null
|
||||||
|
mapX?: number | string | null
|
||||||
|
mapY?: number | string | null
|
||||||
name?: string | null
|
name?: string | null
|
||||||
guideLevel?: string | null
|
guideLevel?: string | null
|
||||||
description?: string | null
|
description?: string | null
|
||||||
@@ -168,7 +175,7 @@ const firstText = (...values: Array<string | number | null | undefined>) => (
|
|||||||
.find(Boolean) || ''
|
.find(Boolean) || ''
|
||||||
)
|
)
|
||||||
|
|
||||||
const parseGalleryUrls = (value: BackendExhibit['galleryUrls']) => {
|
const parseGalleryUrls = (value: BackendExhibit['galleryUrls'] | string[]) => {
|
||||||
if (!value) return []
|
if (!value) return []
|
||||||
if (Array.isArray(value)) return value.map(String).filter(Boolean)
|
if (Array.isArray(value)) return value.map(String).filter(Boolean)
|
||||||
|
|
||||||
@@ -308,8 +315,11 @@ const toCatalogLinkedExhibitSummary = (source: BackendCatalogLinkedExhibitItem)
|
|||||||
id,
|
id,
|
||||||
name: firstText(source.name, source.exhibitCode, source.code, `展品 ${id}`),
|
name: firstText(source.name, source.exhibitCode, source.code, `展品 ${id}`),
|
||||||
nameEn: firstText(source.nameEn) || undefined,
|
nameEn: firstText(source.nameEn) || undefined,
|
||||||
|
code: firstText(source.code, source.exhibitCode) || undefined,
|
||||||
exhibitCode: firstText(source.exhibitCode, source.code) || undefined,
|
exhibitCode: firstText(source.exhibitCode, source.code) || undefined,
|
||||||
coverImageUrl: normalizeSameOriginPublicUrl(firstText(source.coverImageUrl)) || undefined
|
coverImageUrl: normalizeSameOriginPublicUrl(firstText(source.coverImageUrl)) || undefined,
|
||||||
|
galleryUrls: parseGalleryUrls(source.galleryUrls),
|
||||||
|
sortOrder: normalizeNumber(source.sortOrder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +341,7 @@ export const toCatalogGuideStop = (
|
|||||||
name: firstText(source.name, `讲解点${id}`),
|
name: firstText(source.name, `讲解点${id}`),
|
||||||
hallId: hall?.id,
|
hallId: hall?.id,
|
||||||
hallName: hall?.name,
|
hallName: hall?.name,
|
||||||
floorId: hall?.floorId,
|
floorId: stringifyId(source.floorId) || hall?.floorId,
|
||||||
targetType: playTargetType,
|
targetType: playTargetType,
|
||||||
targetId: playTargetId,
|
targetId: playTargetId,
|
||||||
coverImageUrl: canUseStopImage
|
coverImageUrl: canUseStopImage
|
||||||
@@ -342,6 +352,9 @@ export const toCatalogGuideStop = (
|
|||||||
audioStatus: normalizeCatalogAudioStatus(source.audioStatus),
|
audioStatus: normalizeCatalogAudioStatus(source.audioStatus),
|
||||||
supportedLanguages: normalizeSupportedLanguages(source.supportedLanguages),
|
supportedLanguages: normalizeSupportedLanguages(source.supportedLanguages),
|
||||||
hasTextRecord: source.hasTextRecord === true,
|
hasTextRecord: source.hasTextRecord === true,
|
||||||
|
poiId: stringifyId(source.poiId) || undefined,
|
||||||
|
mapX: normalizeNumber(source.mapX),
|
||||||
|
mapY: normalizeNumber(source.mapY),
|
||||||
outlineId: stringifyId(source.outlineId) || outline?.id,
|
outlineId: stringifyId(source.outlineId) || outline?.id,
|
||||||
outlineName: outline?.name,
|
outlineName: outline?.name,
|
||||||
sort: typeof source.sort === 'number' ? source.sort : undefined,
|
sort: typeof source.sort === 'number' ? source.sort : undefined,
|
||||||
@@ -374,6 +387,10 @@ export const toCatalogMuseumExhibitFromStop = (
|
|||||||
image: stop.coverImageUrl || undefined,
|
image: stop.coverImageUrl || undefined,
|
||||||
description: stop.description || linkedPrimary?.name || '该讲解点暂无简介。',
|
description: stop.description || linkedPrimary?.name || '该讲解点暂无简介。',
|
||||||
tags: [stop.outlineName, linkedPrimary?.exhibitCode].filter(Boolean) as string[],
|
tags: [stop.outlineName, linkedPrimary?.exhibitCode].filter(Boolean) as string[],
|
||||||
|
poiId: stop.poiId,
|
||||||
|
sourcePoiId: stop.poiId,
|
||||||
|
mapX: stop.mapX,
|
||||||
|
mapY: stop.mapY,
|
||||||
guideTitle: stop.name,
|
guideTitle: stop.name,
|
||||||
guideText: stop.description,
|
guideText: stop.description,
|
||||||
audioAvailable: audioReady,
|
audioAvailable: audioReady,
|
||||||
@@ -611,6 +628,8 @@ export const toBackendGuideStop = (source: BackendGuideStop): ExplainGuideStop |
|
|||||||
description: firstText(source.description) || undefined,
|
description: firstText(source.description) || undefined,
|
||||||
hasAudio: source.hasAudio === true,
|
hasAudio: source.hasAudio === true,
|
||||||
poiId: stringifyId(source.poiId) || undefined,
|
poiId: stringifyId(source.poiId) || undefined,
|
||||||
|
mapX: normalizeNumber(source.mapX),
|
||||||
|
mapY: normalizeNumber(source.mapY),
|
||||||
outlineId: stringifyId(source.outlineId) || undefined,
|
outlineId: stringifyId(source.outlineId) || undefined,
|
||||||
outlineName: firstText(source.outlineName) || undefined,
|
outlineName: firstText(source.outlineName) || undefined,
|
||||||
sort: typeof source.sort === 'number' ? source.sort : undefined
|
sort: typeof source.sort === 'number' ? source.sort : undefined
|
||||||
|
|||||||
@@ -9,8 +9,11 @@ export interface BackendGuideStopLinkedExhibit {
|
|||||||
id?: string | number | null
|
id?: string | number | null
|
||||||
name?: string | null
|
name?: string | null
|
||||||
nameEn?: string | null
|
nameEn?: string | null
|
||||||
|
code?: string | null
|
||||||
exhibitCode?: string | null
|
exhibitCode?: string | null
|
||||||
coverImageUrl?: string | null
|
coverImageUrl?: string | null
|
||||||
|
galleryUrls?: string | string[] | null
|
||||||
|
sortOrder?: number | string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BackendGuideStopInfo {
|
export interface BackendGuideStopInfo {
|
||||||
@@ -19,6 +22,10 @@ export interface BackendGuideStopInfo {
|
|||||||
targetId?: string | number | null
|
targetId?: string | number | null
|
||||||
resolvedStopId?: string | number | null
|
resolvedStopId?: string | number | null
|
||||||
stopId?: string | number | null
|
stopId?: string | number | null
|
||||||
|
poiId?: string | number | null
|
||||||
|
floorId?: string | number | null
|
||||||
|
mapX?: number | string | null
|
||||||
|
mapY?: number | string | null
|
||||||
lang?: string | null
|
lang?: string | null
|
||||||
title?: string | null
|
title?: string | null
|
||||||
description?: string | null
|
description?: string | null
|
||||||
@@ -74,8 +81,11 @@ export interface GuideStopLinkedExhibit {
|
|||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
nameEn?: string
|
nameEn?: string
|
||||||
|
code?: string
|
||||||
exhibitCode?: string
|
exhibitCode?: string
|
||||||
coverImageUrl?: string
|
coverImageUrl?: string
|
||||||
|
galleryUrls?: string[]
|
||||||
|
sortOrder?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GuideStopInfo {
|
export interface GuideStopInfo {
|
||||||
@@ -83,6 +93,10 @@ export interface GuideStopInfo {
|
|||||||
targetType: AudioPlayTargetType
|
targetType: AudioPlayTargetType
|
||||||
targetId: string
|
targetId: string
|
||||||
resolvedStopId?: string
|
resolvedStopId?: string
|
||||||
|
poiId?: string
|
||||||
|
floorId?: string
|
||||||
|
mapX?: number
|
||||||
|
mapY?: number
|
||||||
lang: 'zh-CN' | 'en-US'
|
lang: 'zh-CN' | 'en-US'
|
||||||
title: string
|
title: string
|
||||||
description?: string
|
description?: string
|
||||||
@@ -156,7 +170,7 @@ const normalizeLanguage = (value: string | null | undefined): 'zh-CN' | 'en-US'
|
|||||||
value === 'en-US' ? 'en-US' : 'zh-CN'
|
value === 'en-US' ? 'en-US' : 'zh-CN'
|
||||||
)
|
)
|
||||||
|
|
||||||
const parseGalleryUrls = (value: BackendGuideStopInfo['galleryUrls']) => {
|
const parseGalleryUrls = (value: BackendGuideStopInfo['galleryUrls'] | BackendGuideStopLinkedExhibit['galleryUrls']) => {
|
||||||
if (!value) return []
|
if (!value) return []
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
return value.map((entry) => normalizeSameOriginPublicUrl(String(entry))).filter(Boolean)
|
return value.map((entry) => normalizeSameOriginPublicUrl(String(entry))).filter(Boolean)
|
||||||
@@ -192,10 +206,13 @@ const normalizeLinkedExhibits = (items: BackendGuideStopLinkedExhibit[] | null |
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
name: item.name?.trim() || item.exhibitCode?.trim() || `展品 ${id}`,
|
name: item.name?.trim() || item.exhibitCode?.trim() || item.code?.trim() || `展品 ${id}`,
|
||||||
nameEn: item.nameEn?.trim() || undefined,
|
nameEn: item.nameEn?.trim() || undefined,
|
||||||
exhibitCode: item.exhibitCode?.trim() || undefined,
|
code: item.code?.trim() || item.exhibitCode?.trim() || undefined,
|
||||||
coverImageUrl: normalizeSameOriginPublicUrl(item.coverImageUrl) || undefined
|
exhibitCode: item.exhibitCode?.trim() || item.code?.trim() || undefined,
|
||||||
|
coverImageUrl: normalizeSameOriginPublicUrl(item.coverImageUrl) || undefined,
|
||||||
|
galleryUrls: parseGalleryUrls(item.galleryUrls),
|
||||||
|
sortOrder: normalizeNumber(item.sortOrder)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(Boolean) as GuideStopLinkedExhibit[]
|
.filter(Boolean) as GuideStopLinkedExhibit[]
|
||||||
@@ -225,6 +242,10 @@ export const toGuideStopInfo = (
|
|||||||
targetType,
|
targetType,
|
||||||
targetId,
|
targetId,
|
||||||
resolvedStopId: stringifyId(source.resolvedStopId) || stringifyId(source.stopId) || undefined,
|
resolvedStopId: stringifyId(source.resolvedStopId) || stringifyId(source.stopId) || undefined,
|
||||||
|
poiId: stringifyId(source.poiId) || undefined,
|
||||||
|
floorId: stringifyId(source.floorId) || undefined,
|
||||||
|
mapX: normalizeNumber(source.mapX),
|
||||||
|
mapY: normalizeNumber(source.mapY),
|
||||||
lang: normalizeLanguage(source.lang || fallback.lang),
|
lang: normalizeLanguage(source.lang || fallback.lang),
|
||||||
title: source.title?.trim() || '讲解内容',
|
title: source.title?.trim() || '讲解内容',
|
||||||
description: source.description?.trim() || undefined,
|
description: source.description?.trim() || undefined,
|
||||||
|
|||||||
@@ -152,6 +152,8 @@ export interface MuseumExhibit {
|
|||||||
description?: string
|
description?: string
|
||||||
poiId?: string
|
poiId?: string
|
||||||
sourcePoiId?: string
|
sourcePoiId?: string
|
||||||
|
mapX?: number
|
||||||
|
mapY?: number
|
||||||
location?: GuideLocationResolution
|
location?: GuideLocationResolution
|
||||||
artist?: string
|
artist?: string
|
||||||
year?: string
|
year?: string
|
||||||
@@ -183,8 +185,11 @@ export interface MuseumExhibit {
|
|||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
nameEn?: string
|
nameEn?: string
|
||||||
|
code?: string
|
||||||
exhibitCode?: string
|
exhibitCode?: string
|
||||||
coverImageUrl?: string
|
coverImageUrl?: string
|
||||||
|
galleryUrls?: string[]
|
||||||
|
sortOrder?: number
|
||||||
}>
|
}>
|
||||||
stopInfoAvailable?: boolean
|
stopInfoAvailable?: boolean
|
||||||
stopInfoReason?: string
|
stopInfoReason?: string
|
||||||
@@ -208,6 +213,8 @@ export interface ExplainGuideStop {
|
|||||||
supportedLanguages?: string[]
|
supportedLanguages?: string[]
|
||||||
hasTextRecord?: boolean
|
hasTextRecord?: boolean
|
||||||
poiId?: string
|
poiId?: string
|
||||||
|
mapX?: number
|
||||||
|
mapY?: number
|
||||||
outlineId?: string
|
outlineId?: string
|
||||||
outlineName?: string
|
outlineName?: string
|
||||||
sort?: number
|
sort?: number
|
||||||
@@ -219,8 +226,11 @@ export interface ExplainGuideStop {
|
|||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
nameEn?: string
|
nameEn?: string
|
||||||
|
code?: string
|
||||||
exhibitCode?: string
|
exhibitCode?: string
|
||||||
coverImageUrl?: string
|
coverImageUrl?: string
|
||||||
|
galleryUrls?: string[]
|
||||||
|
sortOrder?: number
|
||||||
}>
|
}>
|
||||||
playTargetType?: AudioPlayTargetType
|
playTargetType?: AudioPlayTargetType
|
||||||
playTargetId?: string
|
playTargetId?: string
|
||||||
|
|||||||
@@ -27,10 +27,13 @@
|
|||||||
<view class="detail-body">
|
<view class="detail-body">
|
||||||
<text class="detail-title">{{ exhibit.title }}</text>
|
<text class="detail-title">{{ exhibit.title }}</text>
|
||||||
<text v-if="detailMeta" class="detail-meta">{{ detailMeta }}</text>
|
<text v-if="detailMeta" class="detail-meta">{{ detailMeta }}</text>
|
||||||
<view v-if="exhibit.linkedExhibitStatusText" class="detail-chip-row">
|
<view v-if="exhibit.linkedExhibitStatusText || exhibit.galleryStatusText" class="detail-chip-row">
|
||||||
<view class="detail-chip" :class="{ shared: exhibit.isSharedStop }">
|
<view v-if="exhibit.linkedExhibitStatusText" class="detail-chip" :class="{ shared: exhibit.isSharedStop }">
|
||||||
<text class="detail-chip-text">{{ exhibit.linkedExhibitStatusText }}</text>
|
<text class="detail-chip-text">{{ exhibit.linkedExhibitStatusText }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view v-if="exhibit.galleryStatusText" class="detail-chip">
|
||||||
|
<text class="detail-chip-text">{{ exhibit.galleryStatusText }}</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view
|
<view
|
||||||
@@ -67,6 +70,36 @@
|
|||||||
</view>
|
</view>
|
||||||
<text v-if="textError" class="text-error">{{ textError }}</text>
|
<text v-if="textError" class="text-error">{{ textError }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view v-if="visibleLinkedExhibits.length" class="content-section">
|
||||||
|
<text class="section-title">关联展品</text>
|
||||||
|
<view class="linked-exhibit-list">
|
||||||
|
<view
|
||||||
|
v-for="linked in visibleLinkedExhibits"
|
||||||
|
:key="linked.id"
|
||||||
|
class="linked-exhibit-item"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
v-if="linked.coverImageUrl"
|
||||||
|
class="linked-exhibit-image"
|
||||||
|
:src="linked.coverImageUrl"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
<view v-else class="linked-exhibit-image placeholder">
|
||||||
|
<text class="linked-exhibit-placeholder">展品</text>
|
||||||
|
</view>
|
||||||
|
<view class="linked-exhibit-main">
|
||||||
|
<text class="linked-exhibit-name">{{ linked.name }}</text>
|
||||||
|
<text v-if="linked.exhibitCode || linked.code" class="linked-exhibit-code">
|
||||||
|
{{ linked.exhibitCode || linked.code }}
|
||||||
|
</text>
|
||||||
|
<text v-if="linked.galleryUrls?.length" class="linked-exhibit-gallery">
|
||||||
|
图集 {{ linked.galleryUrls.length }} 张
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
@@ -168,6 +201,10 @@ const canExpandText = computed(() => (
|
|||||||
&& !textExpanded.value
|
&& !textExpanded.value
|
||||||
&& !textLoading.value
|
&& !textLoading.value
|
||||||
))
|
))
|
||||||
|
const visibleLinkedExhibits = computed(() => (
|
||||||
|
[...(exhibit.value.linkedExhibits || [])]
|
||||||
|
.sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0))
|
||||||
|
))
|
||||||
|
|
||||||
// 讲解详情页只定位到所属展厅,不再追踪具体展品点位。
|
// 讲解详情页只定位到所属展厅,不再追踪具体展品点位。
|
||||||
const resolveHallGuidePoi = async () => {
|
const resolveHallGuidePoi = async () => {
|
||||||
@@ -641,6 +678,76 @@ const handleBack = () => {
|
|||||||
color: #8a4a31;
|
color: #8a4a31;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.linked-exhibit-list {
|
||||||
|
margin-top: 14px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linked-exhibit-item {
|
||||||
|
min-height: 72px;
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e1e5dc;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linked-exhibit-image {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 52px;
|
||||||
|
height: 52px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #eef1e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linked-exhibit-image.placeholder {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linked-exhibit-placeholder,
|
||||||
|
.linked-exhibit-name,
|
||||||
|
.linked-exhibit-code,
|
||||||
|
.linked-exhibit-gallery {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linked-exhibit-placeholder {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #68725d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linked-exhibit-main {
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linked-exhibit-name {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 21px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #151713;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linked-exhibit-code,
|
||||||
|
.linked-exhibit-gallery {
|
||||||
|
margin-top: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 17px;
|
||||||
|
color: #666d61;
|
||||||
|
}
|
||||||
|
|
||||||
.action-bar {
|
.action-bar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ const explainGuideStopItems = computed<ExplainGuideStopSelectItem[]>(() => (
|
|||||||
hallId: stop.hallId,
|
hallId: stop.hallId,
|
||||||
hallName: stop.hallName,
|
hallName: stop.hallName,
|
||||||
floorId: stop.floorId,
|
floorId: stop.floorId,
|
||||||
|
poiId: stop.poiId,
|
||||||
|
mapX: stop.mapX,
|
||||||
|
mapY: stop.mapY,
|
||||||
coverImageUrl: stop.coverImageUrl,
|
coverImageUrl: stop.coverImageUrl,
|
||||||
description: stop.description,
|
description: stop.description,
|
||||||
hasAudio: stop.hasAudio,
|
hasAudio: stop.hasAudio,
|
||||||
|
|||||||
@@ -723,6 +723,9 @@ const explainGuideStopItems = computed<ExplainGuideStopSelectItem[]>(() => (
|
|||||||
hallId: stop.hallId,
|
hallId: stop.hallId,
|
||||||
hallName: stop.hallName,
|
hallName: stop.hallName,
|
||||||
floorId: stop.floorId,
|
floorId: stop.floorId,
|
||||||
|
poiId: stop.poiId,
|
||||||
|
mapX: stop.mapX,
|
||||||
|
mapY: stop.mapY,
|
||||||
coverImageUrl: stop.coverImageUrl,
|
coverImageUrl: stop.coverImageUrl,
|
||||||
description: stop.description,
|
description: stop.description,
|
||||||
hasAudio: stop.hasAudio,
|
hasAudio: stop.hasAudio,
|
||||||
|
|||||||
@@ -135,12 +135,14 @@ export class ExplainUseCase {
|
|||||||
name: stopInfo.title || fallback?.name || linkedPrimary?.name || '讲解内容',
|
name: stopInfo.title || fallback?.name || linkedPrimary?.name || '讲解内容',
|
||||||
hallId: fallback?.hallId,
|
hallId: fallback?.hallId,
|
||||||
hallName: fallback?.hallName,
|
hallName: fallback?.hallName,
|
||||||
floorId: fallback?.floorId,
|
floorId: stopInfo.floorId || fallback?.floorId,
|
||||||
floorLabel: fallback?.floorLabel,
|
floorLabel: fallback?.floorLabel,
|
||||||
image: coverImage,
|
image: coverImage,
|
||||||
description,
|
description,
|
||||||
poiId: fallback?.poiId,
|
poiId: stopInfo.poiId || fallback?.poiId,
|
||||||
sourcePoiId: fallback?.sourcePoiId,
|
sourcePoiId: stopInfo.poiId || fallback?.sourcePoiId,
|
||||||
|
mapX: stopInfo.mapX ?? fallback?.mapX,
|
||||||
|
mapY: stopInfo.mapY ?? fallback?.mapY,
|
||||||
location: fallback?.location,
|
location: fallback?.location,
|
||||||
year: fallback?.year,
|
year: fallback?.year,
|
||||||
material: fallback?.material,
|
material: fallback?.material,
|
||||||
|
|||||||
@@ -46,7 +46,11 @@ export interface ExplainDetailPageViewModel {
|
|||||||
coverImages: string[]
|
coverImages: string[]
|
||||||
hallId?: string
|
hallId?: string
|
||||||
hallName?: string
|
hallName?: string
|
||||||
|
floorId?: string
|
||||||
floorLabel?: string
|
floorLabel?: string
|
||||||
|
poiId?: string
|
||||||
|
mapX?: number
|
||||||
|
mapY?: number
|
||||||
summary: string
|
summary: string
|
||||||
body: string
|
body: string
|
||||||
audio: {
|
audio: {
|
||||||
@@ -61,6 +65,7 @@ export interface ExplainDetailPageViewModel {
|
|||||||
statusText?: string
|
statusText?: string
|
||||||
}
|
}
|
||||||
imageStatus?: string
|
imageStatus?: string
|
||||||
|
galleryStatusText?: string
|
||||||
linkedExhibitCount?: number
|
linkedExhibitCount?: number
|
||||||
isSharedStop?: boolean
|
isSharedStop?: boolean
|
||||||
linkedExhibitStatusText?: string
|
linkedExhibitStatusText?: string
|
||||||
@@ -68,8 +73,11 @@ export interface ExplainDetailPageViewModel {
|
|||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
nameEn?: string
|
nameEn?: string
|
||||||
|
code?: string
|
||||||
exhibitCode?: string
|
exhibitCode?: string
|
||||||
coverImageUrl?: string
|
coverImageUrl?: string
|
||||||
|
galleryUrls?: string[]
|
||||||
|
sortOrder?: number
|
||||||
}>
|
}>
|
||||||
chapters: Array<{
|
chapters: Array<{
|
||||||
id: string
|
id: string
|
||||||
@@ -171,6 +179,10 @@ export const toExplainExhibitViewModel = (exhibit: MuseumExhibit): ExplainExhibi
|
|||||||
|
|
||||||
export const toExplainDetailPageViewModel = (exhibit: MuseumExhibit): ExplainDetailPageViewModel => {
|
export const toExplainDetailPageViewModel = (exhibit: MuseumExhibit): ExplainDetailPageViewModel => {
|
||||||
const hasPlayableAudio = isAudioReady(exhibit)
|
const hasPlayableAudio = isAudioReady(exhibit)
|
||||||
|
const coverImages = [
|
||||||
|
exhibit.image || EXPLAIN_DETAIL_PLACEHOLDER_IMAGE,
|
||||||
|
...(exhibit.galleryUrls || [])
|
||||||
|
].filter(Boolean)
|
||||||
const linkedExhibitCount = typeof exhibit.linkedExhibitCount === 'number'
|
const linkedExhibitCount = typeof exhibit.linkedExhibitCount === 'number'
|
||||||
? exhibit.linkedExhibitCount
|
? exhibit.linkedExhibitCount
|
||||||
: exhibit.linkedExhibits?.length
|
: exhibit.linkedExhibits?.length
|
||||||
@@ -195,13 +207,14 @@ export const toExplainDetailPageViewModel = (exhibit: MuseumExhibit): ExplainDet
|
|||||||
title: exhibit.name,
|
title: exhibit.name,
|
||||||
subtitle: buildSubtitle(exhibit),
|
subtitle: buildSubtitle(exhibit),
|
||||||
contentType: contentTypeFor(exhibit),
|
contentType: contentTypeFor(exhibit),
|
||||||
coverImages: [
|
coverImages,
|
||||||
exhibit.image || EXPLAIN_DETAIL_PLACEHOLDER_IMAGE,
|
|
||||||
...(exhibit.galleryUrls || [])
|
|
||||||
].filter(Boolean),
|
|
||||||
hallId: exhibit.hallId,
|
hallId: exhibit.hallId,
|
||||||
hallName: exhibit.hallName,
|
hallName: exhibit.hallName,
|
||||||
|
floorId: exhibit.floorId,
|
||||||
floorLabel: exhibit.floorLabel,
|
floorLabel: exhibit.floorLabel,
|
||||||
|
poiId: exhibit.poiId,
|
||||||
|
mapX: exhibit.mapX,
|
||||||
|
mapY: exhibit.mapY,
|
||||||
summary: transcript || '该展项暂无讲解文稿。',
|
summary: transcript || '该展项暂无讲解文稿。',
|
||||||
body,
|
body,
|
||||||
audio: {
|
audio: {
|
||||||
@@ -218,6 +231,7 @@ export const toExplainDetailPageViewModel = (exhibit: MuseumExhibit): ExplainDet
|
|||||||
statusText: hasPlayableAudio ? '可播放' : '当前语言暂无语音讲解'
|
statusText: hasPlayableAudio ? '可播放' : '当前语言暂无语音讲解'
|
||||||
},
|
},
|
||||||
imageStatus: exhibit.imageStatus,
|
imageStatus: exhibit.imageStatus,
|
||||||
|
galleryStatusText: coverImages.length > 1 ? `共 ${coverImages.length} 张讲解图片` : undefined,
|
||||||
linkedExhibitCount,
|
linkedExhibitCount,
|
||||||
isSharedStop: exhibit.isSharedStop,
|
isSharedStop: exhibit.isSharedStop,
|
||||||
linkedExhibitStatusText,
|
linkedExhibitStatusText,
|
||||||
|
|||||||
Reference in New Issue
Block a user