|
@@ -329,169 +329,169 @@ export class VideoMediaListItemDto {
|
|
|
editedAt!: number;
|
|
editedAt!: number;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export class VideoMediaDetailDto {
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: String,
|
|
|
|
|
- description: '视频 MongoDB ID',
|
|
|
|
|
- example: '507f1f77bcf86cd799439011',
|
|
|
|
|
- })
|
|
|
|
|
- @IsString()
|
|
|
|
|
- id!: string;
|
|
|
|
|
-
|
|
|
|
|
- // --- Provider fields (read-only for mgnt) ---
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: String,
|
|
|
|
|
- description: '视频标题',
|
|
|
|
|
- example: '产品演示视频',
|
|
|
|
|
- })
|
|
|
|
|
- @IsString()
|
|
|
|
|
- title!: string;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: String,
|
|
|
|
|
- description: '视频文件名',
|
|
|
|
|
- example: 'product-demo.mp4',
|
|
|
|
|
- })
|
|
|
|
|
- @IsString()
|
|
|
|
|
- filename!: string;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: Number,
|
|
|
|
|
- description: '视频时长(秒)',
|
|
|
|
|
- example: 120,
|
|
|
|
|
- })
|
|
|
|
|
- @Type(() => Number)
|
|
|
|
|
- @IsInt()
|
|
|
|
|
- videoTime!: number;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: String,
|
|
|
|
|
- description: '文件大小(字节),以字符串形式存储避免精度问题',
|
|
|
|
|
- example: '1048576000',
|
|
|
|
|
- })
|
|
|
|
|
- @IsString()
|
|
|
|
|
- size!: string;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: String,
|
|
|
|
|
- description: '视频封面 URL 或 S3 key',
|
|
|
|
|
- example: 'https://s3.example.com/covers/507f1f77bcf86cd799439011.jpg',
|
|
|
|
|
- })
|
|
|
|
|
- @IsString()
|
|
|
|
|
- coverImg!: string;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: String,
|
|
|
|
|
- description: '视频类型',
|
|
|
|
|
- example: 'video/mp4',
|
|
|
|
|
- })
|
|
|
|
|
- @IsString()
|
|
|
|
|
- type!: string;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: Number,
|
|
|
|
|
- description: '视频格式类型编码',
|
|
|
|
|
- example: 1,
|
|
|
|
|
- })
|
|
|
|
|
- @Type(() => Number)
|
|
|
|
|
- @IsInt()
|
|
|
|
|
- formatType!: number;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: Number,
|
|
|
|
|
- description: '内容类型编码',
|
|
|
|
|
- example: 1,
|
|
|
|
|
- })
|
|
|
|
|
- @Type(() => Number)
|
|
|
|
|
- @IsInt()
|
|
|
|
|
- contentType!: number;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: String,
|
|
|
|
|
- description: '国家/地区代码',
|
|
|
|
|
- example: 'CN',
|
|
|
|
|
- })
|
|
|
|
|
- @IsString()
|
|
|
|
|
- country!: string;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: String,
|
|
|
|
|
- description: '视频状态',
|
|
|
|
|
- example: 'active',
|
|
|
|
|
- })
|
|
|
|
|
- @IsString()
|
|
|
|
|
- status!: string;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: String,
|
|
|
|
|
- description: '视频描述',
|
|
|
|
|
- example: '这是一个产品演示视频',
|
|
|
|
|
- })
|
|
|
|
|
- @IsString()
|
|
|
|
|
- desc!: string;
|
|
|
|
|
-
|
|
|
|
|
- // --- Local business fields ---
|
|
|
|
|
-
|
|
|
|
|
- @ApiPropertyOptional({
|
|
|
|
|
- type: String,
|
|
|
|
|
- nullable: true,
|
|
|
|
|
- description: '视频分类 MongoDB ID',
|
|
|
|
|
- example: '507f1f77bcf86cd799439012',
|
|
|
|
|
- })
|
|
|
|
|
- @IsOptional()
|
|
|
|
|
- @IsMongoId()
|
|
|
|
|
- categoryId?: string | null;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: [String],
|
|
|
|
|
- description: '视频标签 MongoDB ID 列表',
|
|
|
|
|
- example: ['507f1f77bcf86cd799439013', '507f1f77bcf86cd799439014'],
|
|
|
|
|
- })
|
|
|
|
|
- @IsArray()
|
|
|
|
|
- @IsMongoId({ each: true })
|
|
|
|
|
- tagIds!: string[];
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: Number,
|
|
|
|
|
- enum: [0, 1],
|
|
|
|
|
- description: '上下架状态: 0=下架, 1=上架',
|
|
|
|
|
- example: 1,
|
|
|
|
|
- })
|
|
|
|
|
- @Type(() => Number)
|
|
|
|
|
- @IsInt()
|
|
|
|
|
- @IsIn([0, 1])
|
|
|
|
|
- listStatus!: number;
|
|
|
|
|
-
|
|
|
|
|
- @ApiProperty({
|
|
|
|
|
- type: Number,
|
|
|
|
|
- description: '编辑时间戳(EPOCH 毫秒)',
|
|
|
|
|
- example: 1733304600000,
|
|
|
|
|
- })
|
|
|
|
|
- @IsInt()
|
|
|
|
|
- editedAt!: number;
|
|
|
|
|
-
|
|
|
|
|
- // --- Optional denormalized information for UI convenience ---
|
|
|
|
|
-
|
|
|
|
|
- @ApiPropertyOptional({
|
|
|
|
|
- type: String,
|
|
|
|
|
- nullable: true,
|
|
|
|
|
- description: '分类名称(反范式化字段,用于 UI 便利性)',
|
|
|
|
|
- example: '产品介绍',
|
|
|
|
|
- })
|
|
|
|
|
- @IsOptional()
|
|
|
|
|
- @IsString()
|
|
|
|
|
- categoryName?: string | null;
|
|
|
|
|
-
|
|
|
|
|
- @ApiPropertyOptional({
|
|
|
|
|
- type: [Object],
|
|
|
|
|
- description: '标签对象数组(反范式化字段,包含 id 和 name)',
|
|
|
|
|
- example: [
|
|
|
|
|
- { id: '507f1f77bcf86cd799439013', name: '演示' },
|
|
|
|
|
- { id: '507f1f77bcf86cd799439014', name: '产品' },
|
|
|
|
|
- ],
|
|
|
|
|
- })
|
|
|
|
|
- @IsOptional()
|
|
|
|
|
- @IsArray()
|
|
|
|
|
- tags?: { id: string; name: string }[];
|
|
|
|
|
-}
|
|
|
|
|
|
|
+// export class VideoMediaDetailDto {
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// description: '视频 MongoDB ID',
|
|
|
|
|
+// example: '507f1f77bcf86cd799439011',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// id!: string;
|
|
|
|
|
+
|
|
|
|
|
+// // --- Provider fields (read-only for mgnt) ---
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// description: '视频标题',
|
|
|
|
|
+// example: '产品演示视频',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// title!: string;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// description: '视频文件名',
|
|
|
|
|
+// example: 'product-demo.mp4',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// filename!: string;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: Number,
|
|
|
|
|
+// description: '视频时长(秒)',
|
|
|
|
|
+// example: 120,
|
|
|
|
|
+// })
|
|
|
|
|
+// @Type(() => Number)
|
|
|
|
|
+// @IsInt()
|
|
|
|
|
+// videoTime!: number;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// description: '文件大小(字节),以字符串形式存储避免精度问题',
|
|
|
|
|
+// example: '1048576000',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// size!: string;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// description: '视频封面 URL 或 S3 key',
|
|
|
|
|
+// example: 'https://s3.example.com/covers/507f1f77bcf86cd799439011.jpg',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// coverImg!: string;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// description: '视频类型',
|
|
|
|
|
+// example: 'video/mp4',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// type!: string;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: Number,
|
|
|
|
|
+// description: '视频格式类型编码',
|
|
|
|
|
+// example: 1,
|
|
|
|
|
+// })
|
|
|
|
|
+// @Type(() => Number)
|
|
|
|
|
+// @IsInt()
|
|
|
|
|
+// formatType!: number;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: Number,
|
|
|
|
|
+// description: '内容类型编码',
|
|
|
|
|
+// example: 1,
|
|
|
|
|
+// })
|
|
|
|
|
+// @Type(() => Number)
|
|
|
|
|
+// @IsInt()
|
|
|
|
|
+// contentType!: number;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// description: '国家/地区代码',
|
|
|
|
|
+// example: 'CN',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// country!: string;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// description: '视频状态',
|
|
|
|
|
+// example: 'active',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// status!: string;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// description: '视频描述',
|
|
|
|
|
+// example: '这是一个产品演示视频',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// desc!: string;
|
|
|
|
|
+
|
|
|
|
|
+// // --- Local business fields ---
|
|
|
|
|
+
|
|
|
|
|
+// @ApiPropertyOptional({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// nullable: true,
|
|
|
|
|
+// description: '视频分类 MongoDB ID',
|
|
|
|
|
+// example: '507f1f77bcf86cd799439012',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsOptional()
|
|
|
|
|
+// @IsMongoId()
|
|
|
|
|
+// categoryId?: string | null;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: [String],
|
|
|
|
|
+// description: '视频标签 MongoDB ID 列表',
|
|
|
|
|
+// example: ['507f1f77bcf86cd799439013', '507f1f77bcf86cd799439014'],
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsArray()
|
|
|
|
|
+// @IsMongoId({ each: true })
|
|
|
|
|
+// tagIds!: string[];
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: Number,
|
|
|
|
|
+// enum: [0, 1],
|
|
|
|
|
+// description: '上下架状态: 0=下架, 1=上架',
|
|
|
|
|
+// example: 1,
|
|
|
|
|
+// })
|
|
|
|
|
+// @Type(() => Number)
|
|
|
|
|
+// @IsInt()
|
|
|
|
|
+// @IsIn([0, 1])
|
|
|
|
|
+// listStatus!: number;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiProperty({
|
|
|
|
|
+// type: Number,
|
|
|
|
|
+// description: '编辑时间戳(EPOCH 毫秒)',
|
|
|
|
|
+// example: 1733304600000,
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsInt()
|
|
|
|
|
+// editedAt!: number;
|
|
|
|
|
+
|
|
|
|
|
+// // --- Optional denormalized information for UI convenience ---
|
|
|
|
|
+
|
|
|
|
|
+// @ApiPropertyOptional({
|
|
|
|
|
+// type: String,
|
|
|
|
|
+// nullable: true,
|
|
|
|
|
+// description: '分类名称(反范式化字段,用于 UI 便利性)',
|
|
|
|
|
+// example: '产品介绍',
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsOptional()
|
|
|
|
|
+// @IsString()
|
|
|
|
|
+// categoryName?: string | null;
|
|
|
|
|
+
|
|
|
|
|
+// @ApiPropertyOptional({
|
|
|
|
|
+// type: [Object],
|
|
|
|
|
+// description: '标签对象数组(反范式化字段,包含 id 和 name)',
|
|
|
|
|
+// example: [
|
|
|
|
|
+// { id: '507f1f77bcf86cd799439013', name: '演示' },
|
|
|
|
|
+// { id: '507f1f77bcf86cd799439014', name: '产品' },
|
|
|
|
|
+// ],
|
|
|
|
|
+// })
|
|
|
|
|
+// @IsOptional()
|
|
|
|
|
+// @IsArray()
|
|
|
|
|
+// tags?: { id: string; name: string }[];
|
|
|
|
|
+// }
|