Procházet zdrojové kódy

feat(video): update VideoListRequestDto to make categoryId optional and adjust video list retrieval logic

Dave před 2 měsíci
rodič
revize
c4467237e9

+ 3 - 1
apps/box-app-api/src/feature/video/dto/video-list-request.dto.ts

@@ -26,9 +26,11 @@ export class VideoListRequestDto {
   @ApiProperty({
     description: '分类ID',
     example: '6507f1f77bcf86cd799439011',
+    required: false,
   })
+  @IsOptional()
   @IsString()
-  categoryId: string;
+  categoryId?: string;
 
   @ApiProperty({
     required: false,

+ 40 - 8
apps/box-app-api/src/feature/video/video.service.ts

@@ -822,10 +822,31 @@ export class VideoService {
    * and returns paginated results.
    */
   async getVideoList(dto: VideoListRequestDto): Promise<VideoListResponseDto> {
-    const { page, size, categoryId, tagName } = dto;
+    const { page, size, tagName } = dto;
+    let categoryId = dto.categoryId;
     let key: string;
     let tagId: string | undefined;
 
+    // If tagName is provided but categoryId is not, fallback to searchVideosByTagName
+    if (tagName && !categoryId) {
+      this.logger.debug(
+        `tagName provided without categoryId, falling back to searchVideosByTagName`,
+      );
+      return this.searchVideosByTagName({ page, size, tagName });
+    }
+
+    // Validate categoryId is provided when no tagName
+    if (!categoryId) {
+      this.logger.debug(`categoryId is required for getVideoList`);
+      return {
+        page,
+        size,
+        total: 0,
+        tagName,
+        items: [],
+      };
+    }
+
     // Step 1: Resolve the Redis key
     if (!tagName) {
       // No tag filter - use category list
@@ -834,12 +855,10 @@ export class VideoService {
       // Tag filter - need to find tag ID first
       try {
         const tagKey = tsCacheKeys.tag.metadataByCategory(categoryId);
-        const tags =
-          await this.redis.getJson<
-            Array<{ id: string; name: string; seq: number }>
-          >(tagKey);
+        // Tags are stored as a LIST where each element is a JSON string
+        const tagJsonStrings = await this.redis.lrange(tagKey, 0, -1);
 
-        if (!tags || tags.length === 0) {
+        if (!tagJsonStrings || tagJsonStrings.length === 0) {
           this.logger.debug(
             `No tags found for categoryId=${categoryId}, tagName=${tagName}`,
           );
@@ -852,6 +871,19 @@ export class VideoService {
           };
         }
 
+        // Parse each JSON string to get tag objects
+        const tags: Array<{ id: string; name: string; seq: number }> = [];
+        for (const jsonStr of tagJsonStrings) {
+          try {
+            const tag = JSON.parse(jsonStr);
+            tags.push(tag);
+          } catch (parseErr) {
+            this.logger.debug(
+              `Failed to parse tag JSON for category ${categoryId}: ${jsonStr}`,
+            );
+          }
+        }
+
         const tag = tags.find((t) => t.name === tagName);
         if (!tag) {
           this.logger.debug(
@@ -1158,7 +1190,7 @@ export class VideoService {
     for (const category of categories) {
       try {
         const tagKey = tsCacheKeys.tag.metadataByCategory(category.id);
-        // Tag metadata is stored as a LIST of JSON strings, not a single JSON string
+        // Tag metadata is stored as a LIST of JSON strings
         const tagJsonStrings = await this.redis.lrange(tagKey, 0, -1);
 
         if (tagJsonStrings && tagJsonStrings.length > 0) {
@@ -1169,7 +1201,7 @@ export class VideoService {
               tags.push(tag);
             } catch (parseErr) {
               this.logger.debug(
-                `Failed to parse tag JSON for category ${category.id}`,
+                `Failed to parse tag JSON for category ${category.id}: ${jsonStr}`,
               );
             }
           }