import { MotionFormat, PreprocessState, PublishStatus, SourceType } from '../common/enums'; import { Motion } from '../entities/motion.entity'; /** 契约 data-models.md §3 的对外表示 */ export interface MotionDto { id: number; songId: number | null; name: string; format: MotionFormat; fileUrl: string | null; fileSize: number | null; fps: number | null; frameCount: number | null; durationMs: number | null; keypointFormat: string | null; keypointUrl: string | null; /** 骨架缩略图(预处理时生成;T-WEB-014) */ thumbnailUrl: string | null; keypointFrames: number | null; preprocessState: PreprocessState; preprocessError: string | null; sourceType: SourceType; sourceName: string; sourceUrl: string; license: string; author: string; status: PublishStatus; createdAt: string; updatedAt: string; } export interface MotionUrlLookup { fileUrl: string | null; keypointUrl: string | null; fileSize?: number | null; thumbnailUrl: string | null; } export function toMotionDto(motion: Motion, urls: MotionUrlLookup): MotionDto { return { id: motion.id, songId: motion.songId, name: motion.name, format: motion.format, fileUrl: urls.fileUrl, fileSize: urls.fileSize ?? null, fps: motion.fps, frameCount: motion.frameCount, durationMs: motion.durationMs, keypointFormat: motion.keypointFormat, keypointUrl: urls.keypointUrl, thumbnailUrl: urls.thumbnailUrl, keypointFrames: motion.keypointFrames, preprocessState: motion.preprocessState, preprocessError: motion.preprocessError, sourceType: motion.sourceType, sourceName: motion.sourceName, sourceUrl: motion.sourceUrl, license: motion.license, author: motion.author, status: motion.status, createdAt: motion.createdAt.toISOString(), updatedAt: motion.updatedAt.toISOString(), }; }