import { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm'; import { bigintNumber, decimalNumber } from '../common/transformers'; import { MotionFormat, PreprocessState, PublishStatus, SourceType } from '../common/enums'; import { Song } from './song.entity'; /** 动作数据 —— 契约 data-models.md §3 */ @Entity('motions') @Index('idx_motions_song_id', ['songId']) @Index('idx_motions_status', ['status']) @Index('idx_motions_format', ['format']) export class Motion { @PrimaryGeneratedColumn({ type: 'bigint' }) id!: number; @Column({ name: 'song_id', type: 'bigint', nullable: true, transformer: bigintNumber }) songId!: number | null; @ManyToOne(() => Song, { nullable: true, onDelete: 'SET NULL' }) @JoinColumn({ name: 'song_id' }) song?: Song | null; @Column({ type: 'varchar', length: 200 }) name!: string; @Column({ type: 'varchar', length: 24 }) format!: MotionFormat; @Column({ name: 'file_asset_id', type: 'bigint', nullable: true, transformer: bigintNumber }) fileAssetId!: number | null; @Column({ type: 'decimal', precision: 8, scale: 3, nullable: true, transformer: decimalNumber }) fps!: number | null; @Column({ name: 'frame_count', type: 'int', nullable: true }) frameCount!: number | null; @Column({ name: 'duration_ms', type: 'int', nullable: true }) durationMs!: number | null; // ---- 预处理产物(T-WEB-006)---- @Column({ name: 'keypoint_format', type: 'varchar', length: 32, nullable: true }) keypointFormat!: string | null; @Column({ name: 'keypoint_asset_id', type: 'bigint', nullable: true, transformer: bigintNumber }) keypointAssetId!: number | null; @Column({ name: 'keypoint_frames', type: 'int', nullable: true }) keypointFrames!: number | null; /** 骨架缩略图资产(预处理时生成;失败不影响预处理) */ @Column({ name: 'thumbnail_asset_id', type: 'bigint', nullable: true, transformer: bigintNumber }) thumbnailAssetId!: number | null; @Column({ name: 'preprocess_state', type: 'varchar', length: 16, default: PreprocessState.None }) preprocessState!: PreprocessState; @Column({ name: 'preprocess_error', type: 'text', nullable: true }) preprocessError!: string | null; // ---- 来源五元组(必填)---- @Column({ name: 'source_type', type: 'varchar', length: 32 }) sourceType!: SourceType; @Column({ name: 'source_name', type: 'varchar', length: 200 }) sourceName!: string; @Column({ name: 'source_url', type: 'varchar', length: 500 }) sourceUrl!: string; @Column({ type: 'varchar', length: 100 }) license!: string; @Column({ type: 'varchar', length: 200 }) author!: string; @Column({ type: 'varchar', length: 16, default: PublishStatus.Draft }) status!: PublishStatus; @CreateDateColumn({ name: 'created_at', type: 'datetime' }) createdAt!: Date; @UpdateDateColumn({ name: 'updated_at', type: 'datetime' }) updatedAt!: Date; @DeleteDateColumn({ name: 'deleted_at', type: 'datetime', nullable: true }) deletedAt!: Date | null; }