feat: wire guide data source and POI focus UI
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
75
src/usecases/explainUseCase.ts
Normal file
75
src/usecases/explainUseCase.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import type {
|
||||
ExplainTrack,
|
||||
MediaAsset,
|
||||
MuseumExhibit,
|
||||
MuseumHall,
|
||||
SearchIndexItem
|
||||
} from '@/domain/museum'
|
||||
import {
|
||||
explainRepository,
|
||||
type ExplainRepository
|
||||
} from '@/repositories/ExplainRepository'
|
||||
import {
|
||||
mediaRepository,
|
||||
type MediaRepository
|
||||
} from '@/repositories/MediaRepository'
|
||||
|
||||
export interface ExplainAudioSelection {
|
||||
exhibit: MuseumExhibit
|
||||
track: ExplainTrack | null
|
||||
media: MediaAsset | null
|
||||
playable: boolean
|
||||
unavailableMessage?: string
|
||||
}
|
||||
|
||||
export class ExplainUseCase {
|
||||
constructor(
|
||||
private readonly explain: ExplainRepository = explainRepository,
|
||||
private readonly media: MediaRepository = mediaRepository
|
||||
) {}
|
||||
|
||||
listExhibits() {
|
||||
return this.explain.listExhibits()
|
||||
}
|
||||
|
||||
getExhibitById(id: string) {
|
||||
return this.explain.getExhibitById(id)
|
||||
}
|
||||
|
||||
listHalls(): Promise<MuseumHall[]> {
|
||||
return this.explain.listHalls()
|
||||
}
|
||||
|
||||
getHallById(id: string) {
|
||||
return this.explain.getHallById(id)
|
||||
}
|
||||
|
||||
async listExhibitsByHallId(hallId: string) {
|
||||
const exhibits = await this.explain.listExhibits()
|
||||
return exhibits.filter((exhibit) => exhibit.hallId === hallId)
|
||||
}
|
||||
|
||||
searchExplain(keyword?: string): Promise<SearchIndexItem[]> {
|
||||
return this.explain.searchExplain(keyword)
|
||||
}
|
||||
|
||||
async selectAudioForExhibit(exhibitId: string): Promise<ExplainAudioSelection | null> {
|
||||
const exhibit = await this.explain.getExhibitById(exhibitId)
|
||||
if (!exhibit) return null
|
||||
|
||||
const track = await this.explain.getTrackByExhibitId(exhibitId)
|
||||
const media = track?.mediaId
|
||||
? await this.media.getMediaById(track.mediaId)
|
||||
: null
|
||||
|
||||
return {
|
||||
exhibit,
|
||||
track,
|
||||
media,
|
||||
playable: media?.available === true && Boolean(media.url),
|
||||
unavailableMessage: media?.unavailableReason || '该展项暂无讲解音频'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const explainUseCase = new ExplainUseCase()
|
||||
Reference in New Issue
Block a user