| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- // video-media.dto.ts
- import {
- IsInt,
- IsOptional,
- IsString,
- IsIn,
- IsArray,
- IsMongoId,
- Min,
- Max,
- MaxLength,
- } from 'class-validator';
- import { Type } from 'class-transformer';
- import { PageListDto } from '@box/common/dto/page-list.dto';
- export class VideoMediaListQueryDto extends PageListDto {
- /**
- * 搜索关键词:匹配标题、文件名等(具体逻辑在 service 里实现)
- */
- @IsOptional()
- @IsString()
- @MaxLength(100)
- keyword?: string;
- /**
- * 分类过滤:可选
- */
- @IsOptional()
- @IsMongoId()
- categoryId?: string;
- /**
- * 标签过滤(通常前端只会传一个 tagId)
- */
- @IsOptional()
- @IsMongoId()
- tagId?: string;
- /**
- * 上/下架状态过滤
- * 0 = 下架, 1 = 上架
- */
- @IsOptional()
- @Type(() => Number)
- @IsInt()
- @IsIn([0, 1])
- listStatus?: number;
- }
- export class UpdateVideoMediaManageDto {
- @IsOptional()
- @IsString()
- @MaxLength(200)
- title?: string;
- /**
- * 分类 ID,可为空(取消分类)
- */
- @IsOptional()
- @IsMongoId()
- categoryId?: string | null;
- /**
- * 标签 ID 列表,最多 5 个
- */
- @IsOptional()
- @IsArray()
- @IsMongoId({ each: true })
- tagIds?: string[];
- /**
- * 上/下架状态,也可以在这里一起保存(可选)
- * 0 = 下架, 1 = 上架
- */
- @IsOptional()
- @Type(() => Number)
- @IsInt()
- @IsIn([0, 1])
- listStatus?: number;
- }
- export class UpdateVideoMediaStatusDto {
- @Type(() => Number)
- @IsInt()
- @IsIn([0, 1])
- listStatus!: number;
- }
- export class BatchUpdateVideoMediaStatusDto {
- @IsArray()
- @IsMongoId({ each: true })
- ids!: string[];
- @Type(() => Number)
- @IsInt()
- @IsIn([0, 1])
- listStatus!: number;
- }
- export class UpdateVideoMediaCoverResponseDto {
- @IsString()
- id!: string;
- @IsString()
- coverImg!: string;
- /**
- * 新 editedAt 值
- */
- @IsString()
- editedAt!: string;
- }
- export class VideoMediaListItemDto {
- @IsString()
- id!: string;
- @IsString()
- title!: string;
- @IsString()
- filename!: string;
- /**
- * 视频时长(秒)
- */
- @Type(() => Number)
- @IsInt()
- videoTime!: number;
- /**
- * 文件大小(业务上 BigInt 存储,DTO 建议用字符串避免精度问题)
- */
- @IsString()
- size!: string;
- /**
- * 封面 URL / key
- */
- @IsString()
- coverImg!: string;
- /**
- * 分类 ID,可空
- */
- @IsOptional()
- @IsMongoId()
- categoryId?: string | null;
- /**
- * 当前选中的标签 ID 列表(最多 5 个)
- */
- @IsArray()
- @IsMongoId({ each: true })
- tagIds!: string[];
- /**
- * 上/下架状态 0 = 下架, 1 = 上架
- */
- @Type(() => Number)
- @IsInt()
- @IsIn([0, 1])
- listStatus!: number;
- /**
- * 本地编辑时间(BigInt epoch)— 字符串返回
- */
- @IsString()
- editedAt!: string;
- }
- export class VideoMediaDetailDto {
- @IsString()
- id!: string;
- // --- Provider fields (read-only for mgnt) ---
- @IsString()
- title!: string;
- @IsString()
- filename!: string;
- @Type(() => Number)
- @IsInt()
- videoTime!: number;
- @IsString()
- size!: string; // from BigInt
- @IsString()
- coverImg!: string;
- @IsString()
- type!: string;
- @Type(() => Number)
- @IsInt()
- formatType!: number;
- @Type(() => Number)
- @IsInt()
- contentType!: number;
- @IsString()
- country!: string;
- @IsString()
- status!: string;
- @IsString()
- desc!: string;
- // --- Local business fields ---
- @IsOptional()
- @IsMongoId()
- categoryId?: string | null;
- @IsArray()
- @IsMongoId({ each: true })
- tagIds!: string[];
- @Type(() => Number)
- @IsInt()
- @IsIn([0, 1])
- listStatus!: number;
- @IsString()
- editedAt!: string;
- // --- Optional denormalized information for UI convenience ---
- @IsOptional()
- @IsString()
- categoryName?: string | null;
- @IsOptional()
- @IsArray()
- tags?: { id: string; name: string }[];
- }
|