|
|
@@ -19,10 +19,7 @@ import {
|
|
|
import { Request } from 'express';
|
|
|
import { VideoService } from './video.service';
|
|
|
import {
|
|
|
- VideoPageDto,
|
|
|
VideoDetailDto,
|
|
|
- VideoCategoryDto,
|
|
|
- VideoTagDto,
|
|
|
VideoCategoryWithTagsResponseDto,
|
|
|
VideoListRequestDto,
|
|
|
VideoListResponseDto,
|
|
|
@@ -62,7 +59,17 @@ export class VideoController {
|
|
|
description: '推荐视频列表',
|
|
|
type: RecommendedVideosDto,
|
|
|
})
|
|
|
- async getRecommendedVideos(): Promise<RecommendedVideosDto> {
|
|
|
+ async getRecommendedVideos(
|
|
|
+ @Req() req: RequestWithUser,
|
|
|
+ ): Promise<RecommendedVideosDto> {
|
|
|
+ const uid = req.user?.uid;
|
|
|
+
|
|
|
+ if (!uid) {
|
|
|
+ throw new UnauthorizedException('Missing uid in JWT payload');
|
|
|
+ }
|
|
|
+
|
|
|
+ const ip = this.getClientIp(req);
|
|
|
+ const userAgent = this.getUserAgent(req);
|
|
|
return this.videoService.getRecommendedVideos();
|
|
|
}
|
|
|
|
|
|
@@ -86,174 +93,10 @@ export class VideoController {
|
|
|
@Param('channelId') channelId: string,
|
|
|
@Param('categoryId') categoryId: string,
|
|
|
): Promise<VideoDetailDto[]> {
|
|
|
- return this.videoService.getLatestVideosByCategory(channelId, categoryId);
|
|
|
+ return this.videoService.getLatestVideosByCategory(categoryId);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Get categories for a channel from Redis cache.
|
|
|
- */
|
|
|
- // @Get('categories/:channelId')
|
|
|
- // @ApiOperation({
|
|
|
- // summary: 'Get video categories for channel',
|
|
|
- // description: 'Returns list of video categories from prebuilt Redis cache.',
|
|
|
- // })
|
|
|
- // @ApiResponse({
|
|
|
- // status: 200,
|
|
|
- // description: 'List of categories',
|
|
|
- // type: VideoCategoryDto,
|
|
|
- // isArray: true,
|
|
|
- // })
|
|
|
- // async getCategories(
|
|
|
- // @Param('channelId') channelId: string,
|
|
|
- // ): Promise<VideoCategoryDto[]> {
|
|
|
- // return this.videoService.getCategoryListForChannel(channelId);
|
|
|
- // }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get tags for a category.
|
|
|
- * Note: channelId is kept in URL for backward compatibility but not used.
|
|
|
- */
|
|
|
- // @Get('tags/:channelId/:categoryId')
|
|
|
- // @ApiOperation({
|
|
|
- // summary: 'Get video tags for category',
|
|
|
- // description:
|
|
|
- // 'Returns list of tags in a specific category from Redis cache.',
|
|
|
- // })
|
|
|
- // @ApiResponse({
|
|
|
- // status: 200,
|
|
|
- // description: 'List of tags',
|
|
|
- // type: VideoTagDto,
|
|
|
- // isArray: true,
|
|
|
- // })
|
|
|
- // async getTags(
|
|
|
- // @Param('channelId') channelId: string,
|
|
|
- // @Param('categoryId') categoryId: string,
|
|
|
- // ): Promise<VideoTagDto[]> {
|
|
|
- // return this.videoService.getTagListForCategory(categoryId);
|
|
|
- // }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get videos in a category with pagination.
|
|
|
- */
|
|
|
- // @Get('category/:channelId/:categoryId')
|
|
|
- // @ApiOperation({
|
|
|
- // summary: 'Get videos by category',
|
|
|
- // description:
|
|
|
- // 'Returns paginated videos for a specific category from Redis cache.',
|
|
|
- // })
|
|
|
- // @ApiQuery({
|
|
|
- // name: 'page',
|
|
|
- // required: false,
|
|
|
- // description: 'Page number (default: 1)',
|
|
|
- // example: 1,
|
|
|
- // })
|
|
|
- // @ApiQuery({
|
|
|
- // name: 'pageSize',
|
|
|
- // required: false,
|
|
|
- // description: 'Items per page (default: 20)',
|
|
|
- // example: 20,
|
|
|
- // })
|
|
|
- // @ApiResponse({
|
|
|
- // status: 200,
|
|
|
- // description: 'Paginated video list',
|
|
|
- // type: VideoPageDto,
|
|
|
- // })
|
|
|
- // async getVideosByCategory(
|
|
|
- // @Param('channelId') channelId: string,
|
|
|
- // @Param('categoryId') categoryId: string,
|
|
|
- // @Query('page') page?: string,
|
|
|
- // @Query('pageSize') pageSize?: string,
|
|
|
- // ): Promise<VideoPageDto<VideoDetailDto>> {
|
|
|
- // const parsedPage = page ? Math.max(1, Number.parseInt(page, 10)) : 1;
|
|
|
- // const parsedPageSize = pageSize
|
|
|
- // ? Math.min(100, Number.parseInt(pageSize, 10))
|
|
|
- // : 20;
|
|
|
-
|
|
|
- // return this.videoService.getVideosByCategoryWithPaging({
|
|
|
- // channelId,
|
|
|
- // categoryId,
|
|
|
- // page: parsedPage,
|
|
|
- // pageSize: parsedPageSize,
|
|
|
- // });
|
|
|
- // }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get videos for a tag with pagination.
|
|
|
- * Note: Need categoryId to use new cache semantics for tag list fallback.
|
|
|
- */
|
|
|
- // @Get('tag/:channelId/:categoryId/:tagId')
|
|
|
- // @ApiOperation({
|
|
|
- // summary: 'Get videos by tag',
|
|
|
- // description:
|
|
|
- // 'Returns paginated videos for a specific tag from Redis cache.',
|
|
|
- // })
|
|
|
- // @ApiQuery({
|
|
|
- // name: 'page',
|
|
|
- // required: false,
|
|
|
- // description: 'Page number (default: 1)',
|
|
|
- // example: 1,
|
|
|
- // })
|
|
|
- // @ApiQuery({
|
|
|
- // name: 'pageSize',
|
|
|
- // required: false,
|
|
|
- // description: 'Items per page (default: 20)',
|
|
|
- // example: 20,
|
|
|
- // })
|
|
|
- // @ApiResponse({
|
|
|
- // status: 200,
|
|
|
- // description: 'Paginated video list',
|
|
|
- // type: VideoPageDto,
|
|
|
- // })
|
|
|
- // async getVideosByTag(
|
|
|
- // @Param('channelId') channelId: string,
|
|
|
- // @Param('categoryId') categoryId: string,
|
|
|
- // @Param('tagId') tagId: string,
|
|
|
- // @Query('page') page?: string,
|
|
|
- // @Query('pageSize') pageSize?: string,
|
|
|
- // ): Promise<VideoPageDto<VideoDetailDto>> {
|
|
|
- // const parsedPage = page ? Math.max(1, Number.parseInt(page, 10)) : 1;
|
|
|
- // const parsedPageSize = pageSize
|
|
|
- // ? Math.min(100, Number.parseInt(pageSize, 10))
|
|
|
- // : 20;
|
|
|
-
|
|
|
- // return this.videoService.getVideosByTagWithPaging({
|
|
|
- // channelId,
|
|
|
- // categoryId,
|
|
|
- // tagId,
|
|
|
- // page: parsedPage,
|
|
|
- // pageSize: parsedPageSize,
|
|
|
- // });
|
|
|
- // }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get home section videos (e.g., featured, latest, editorPick).
|
|
|
- */
|
|
|
- // @Get('home/:channelId/:section')
|
|
|
- // @ApiOperation({
|
|
|
- // summary: 'Get home section videos',
|
|
|
- // description:
|
|
|
- // 'Returns videos for home page sections (featured, latest, editorPick) from Redis cache.',
|
|
|
- // })
|
|
|
- // @ApiResponse({
|
|
|
- // status: 200,
|
|
|
- // description: 'List of videos in section',
|
|
|
- // type: VideoDetailDto,
|
|
|
- // isArray: true,
|
|
|
- // })
|
|
|
- // async getHomeSectionVideos(
|
|
|
- // @Param('channelId') channelId: string,
|
|
|
- // @Param('section') section: string,
|
|
|
- // ): Promise<VideoDetailDto[]> {
|
|
|
- // // Validate section is a known type
|
|
|
- // const validSections = ['featured', 'latest', 'editorPick'];
|
|
|
- // if (!validSections.includes(section)) {
|
|
|
- // return [];
|
|
|
- // }
|
|
|
-
|
|
|
- // return this.videoService.getHomeSectionVideos(channelId, section as any);
|
|
|
- // }
|
|
|
-
|
|
|
- /**
|
|
|
* GET /api/v1/video/categories-with-tags
|
|
|
*
|
|
|
* Get all video categories with their associated tags.
|