recommend-public.controller.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import { Controller, Get, Logger, Param, Query } from '@nestjs/common';
  2. import {
  3. ApiOperation,
  4. ApiResponse,
  5. ApiTags,
  6. ApiParam,
  7. ApiQuery,
  8. } from '@nestjs/swagger';
  9. import { RecommendationService } from './recommendation.service';
  10. import {
  11. YouMayAlsoLikeVideoResponseDto,
  12. YouMayAlsoLikeAdResponseDto,
  13. } from './dto/enriched-recommendation.dto';
  14. import { AdType as PrismaAdType } from '@prisma/mongo/client';
  15. @ApiTags('推荐')
  16. @Controller('recommend')
  17. export class RecommendPublicController {
  18. private readonly logger = new Logger(RecommendPublicController.name);
  19. constructor(private readonly recommendationService: RecommendationService) {}
  20. @Get('video/:videoId')
  21. @ApiOperation({
  22. summary: '获取视频推荐 - 猜你喜欢',
  23. description:
  24. '基于当前视频的标签和Redis分数,返回带有完整元数据的相似视频推荐列表。仅返回上架状态的视频。',
  25. })
  26. @ApiParam({
  27. name: 'videoId',
  28. description: '当前视频ID',
  29. example: '6756abc123def',
  30. })
  31. @ApiQuery({
  32. name: 'limit',
  33. required: false,
  34. description: '返回推荐数量(默认6)',
  35. example: 6,
  36. })
  37. @ApiResponse({
  38. status: 200,
  39. description: '成功返回推荐列表',
  40. type: YouMayAlsoLikeVideoResponseDto,
  41. })
  42. async getVideoRecommendations(
  43. @Param('videoId') videoId: string,
  44. @Query('limit') limit?: string,
  45. ): Promise<YouMayAlsoLikeVideoResponseDto> {
  46. const limitNum = limit ? parseInt(limit, 10) : 6;
  47. this.logger.debug(
  48. `GET /api/v1/recommend/video/${videoId}?limit=${limitNum}`,
  49. );
  50. const recommendations =
  51. await this.recommendationService.getEnrichedVideoRecommendations(
  52. videoId,
  53. limitNum,
  54. );
  55. return {
  56. currentVideoId: videoId,
  57. recommendations,
  58. count: recommendations.length,
  59. };
  60. }
  61. @Get('ad/:adId')
  62. @ApiOperation({
  63. summary: '获取广告推荐 - 猜你喜欢',
  64. description:
  65. '基于渠道和广告模块过滤,返回带有完整元数据的相似广告推荐列表。仅返回同渠道、同模块、状态启用且在有效期内的广告。',
  66. })
  67. @ApiParam({
  68. name: 'adId',
  69. description: '当前广告ID',
  70. example: '6756def456ghi',
  71. })
  72. // @ApiQuery({
  73. // name: 'channelId',
  74. // required: true,
  75. // description: '渠道ID(必须匹配)',
  76. // example: '6756channel123',
  77. // })
  78. @ApiQuery({
  79. name: 'adType',
  80. required: true,
  81. enum: PrismaAdType,
  82. description: '广告类型/模块 (AdType enum)',
  83. })
  84. @ApiQuery({
  85. name: 'limit',
  86. required: false,
  87. description: '返回推荐数量(默认3)',
  88. example: 3,
  89. })
  90. @ApiResponse({
  91. status: 200,
  92. description: '成功返回推荐列表',
  93. type: YouMayAlsoLikeAdResponseDto,
  94. })
  95. async getAdRecommendations(
  96. @Param('adId') adId: string,
  97. @Query('adType') adType: PrismaAdType,
  98. @Query('limit') limit?: string,
  99. ): Promise<YouMayAlsoLikeAdResponseDto> {
  100. const limitNum = limit ? parseInt(limit, 10) : 3;
  101. this.logger.debug(
  102. `GET /api/v1/recommend/ad/${adId}?adType=${adType}&limit=${limitNum}`,
  103. );
  104. const recommendations =
  105. await this.recommendationService.getEnrichedAdRecommendations(adId, {
  106. adType,
  107. limit: limitNum,
  108. });
  109. return {
  110. currentAdId: adId,
  111. recommendations,
  112. count: recommendations.length,
  113. };
  114. }
  115. }