import type { CustomWorldGalleryCard, CustomWorldLibraryEntry, } from '../../../packages/shared/src/contracts/runtime'; import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary'; import { buildCustomWorldPlayableCharacters } from '../../data/characterPresets'; import { resolveCustomWorldCampSceneImage } from '../../data/customWorldVisuals'; import { buildPuzzlePublicWorkCode } from '../../services/publicWorkCode'; import type { CustomWorldProfile } from '../../types'; export type PlatformWorldCardLike = | CustomWorldGalleryCard | CustomWorldLibraryEntry | PlatformPuzzleGalleryCard; export type PlatformPuzzleGalleryCard = { sourceType: 'puzzle'; workId: string; profileId: string; publicWorkCode: string; ownerUserId: string; authorDisplayName: string; worldName: string; subtitle: string; summaryText: string; coverImageSrc: string | null; themeTags: string[]; visibility: 'published'; publishedAt: string | null; updatedAt: string; }; export type PlatformPublicGalleryCard = | CustomWorldGalleryCard | PlatformPuzzleGalleryCard; export function isLibraryWorldEntry( entry: PlatformWorldCardLike, ): entry is CustomWorldLibraryEntry { return 'profile' in entry; } export function isPuzzleGalleryEntry( entry: PlatformWorldCardLike, ): entry is PlatformPuzzleGalleryCard { return 'sourceType' in entry && entry.sourceType === 'puzzle'; } export function mapPuzzleWorkToPlatformGalleryCard( work: PuzzleWorkSummary, ): PlatformPuzzleGalleryCard { return { sourceType: 'puzzle', workId: work.workId, profileId: work.profileId, publicWorkCode: buildPuzzlePublicWorkCode(work.profileId), ownerUserId: work.ownerUserId, authorDisplayName: work.authorDisplayName, worldName: work.levelName, subtitle: '拼图关卡', summaryText: work.summary, coverImageSrc: work.coverImageSrc, themeTags: work.themeTags, visibility: 'published', publishedAt: work.publishedAt, updatedAt: work.updatedAt, }; } export function resolvePlatformWorldCoverImage(entry: PlatformWorldCardLike) { if (entry.coverImageSrc) { return entry.coverImageSrc; } if (isLibraryWorldEntry(entry)) { return resolveCustomWorldCampSceneImage(entry.profile) ?? ''; } return ''; } export function resolvePlatformWorldLeadPortrait(entry: PlatformWorldCardLike) { if (!isLibraryWorldEntry(entry)) { return ''; } return buildCustomWorldPlayableCharacters(entry.profile)[0]?.portrait ?? ''; } export function buildPlatformWorldTags(entry: PlatformWorldCardLike) { if (isPuzzleGalleryEntry(entry)) { return entry.themeTags.length > 0 ? entry.themeTags.slice(0, 3) : ['拼图']; } if (!isLibraryWorldEntry(entry)) { return [ describePlatformThemeLabel(entry.themeMode), `${entry.playableNpcCount} 角色`, `${entry.landmarkCount} 地标`, ]; } return [ ...entry.profile.majorFactions.slice(0, 2), ...entry.profile.coreConflicts.slice(0, 1), ] .map((value) => value.trim()) .filter(Boolean) .slice(0, 3); } export function formatPlatformWorldTime(value: string | null) { if (!value) { return '未发布'; } const date = new Date(value); if (Number.isNaN(date.getTime())) { return value; } return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit', }); } export function resolvePlatformPublicWorkCode( entry: PlatformWorldCardLike, ): string | null { if (isPuzzleGalleryEntry(entry)) { return entry.publicWorkCode; } return entry.publicWorkCode; } export function describePlatformThemeLabel( themeMode: CustomWorldGalleryCard['themeMode'], ) { switch (themeMode) { case 'martial': return '江湖'; case 'arcane': return '灵脉'; case 'machina': return '机巧'; case 'tide': return '潮痕'; case 'rift': return '裂界'; default: return '回响'; } }