Files
cyh-tk-backend/src/modules/dramas/dramas.controller.ts
zhxiao1124 fca247c3f2 feat(dramas): 新增剧集搜索、推荐接口与管理筛选功能
1.  为后台剧集列表添加标题和推荐状态筛选参数
2.  新增前台推荐剧集列表接口和前置搜索接口
3.  添加可选布尔值解析工具方法
4.  新增对应接口的端到端测试用例
2026-07-02 17:26:08 +08:00

163 lines
6.2 KiB
TypeScript

import { Body, Controller, Get, Param, Patch, Post, Query, UseGuards } from "@nestjs/common";
import { ApiBearerAuth, ApiTags } from "@nestjs/swagger";
import { RequirePermissions } from "../admin/decorators/require-permissions.decorator";
import { AdminJwtAuthGuard } from "../admin/guards/admin-jwt-auth.guard";
import { PermissionsGuard } from "../admin/guards/permissions.guard";
import { ConfigureEpisodesDto } from "./dto/configure-episodes.dto";
import { CreateDramaDto } from "./dto/create-drama.dto";
import { CreateEpisodeDto } from "./dto/create-episode.dto";
import { UpdateDramaDto } from "./dto/update-drama.dto";
import { UpdateEpisodeDto } from "./dto/update-episode.dto";
import { DramasService } from "./dramas.service";
import { PublishStatus } from "./drama-status.enum";
@ApiTags("Dramas")
@Controller()
export class DramasController {
constructor(private readonly dramasService: DramasService) {}
@Post("/api/admin/v1/dramas")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("drama:create")
createDrama(@Body() dto: CreateDramaDto) {
return this.dramasService.createDrama(dto);
}
@Get("/api/admin/v1/dramas")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("drama:read")
listAdminDramas(@Query("page") page?: string, @Query("pageSize") pageSize?: string, @Query("title") title?: string, @Query("isRecommended") isRecommended?: string) {
return this.dramasService.listAdminDramas({
page: Number(page) || 1,
pageSize: Number(pageSize) || 20,
title,
isRecommended: this.parseOptionalBoolean(isRecommended),
});
}
@Get("/api/admin/v1/dramas/:id")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("drama:read")
getDrama(@Param("id") id: string) {
return this.dramasService.getDramaOrThrow(Number(id));
}
@Patch("/api/admin/v1/dramas/:id")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("drama:update")
updateDrama(@Param("id") id: string, @Body() dto: UpdateDramaDto) {
return this.dramasService.updateDrama(Number(id), dto);
}
@Post("/api/admin/v1/dramas/:id/episodes/batch")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("episode:create")
configureEpisodes(@Param("id") id: string, @Body() dto: ConfigureEpisodesDto) {
return this.dramasService.configureEpisodes(Number(id), dto);
}
@Get("/api/admin/v1/dramas/:id/episodes")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("episode:update")
listAdminEpisodes(@Param("id") id: string, @Query("page") page?: string, @Query("pageSize") pageSize?: string) {
return this.dramasService.listAdminEpisodes(Number(id), {
page: Number(page) || 1,
pageSize: Number(pageSize) || 20,
});
}
@Post("/api/admin/v1/episodes")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("episode:create")
createEpisode(@Body() dto: CreateEpisodeDto) {
return this.dramasService.createEpisode(dto);
}
@Patch("/api/admin/v1/episodes/:id")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("episode:update")
updateEpisode(@Param("id") id: string, @Body() dto: UpdateEpisodeDto) {
return this.dramasService.updateEpisode(Number(id), dto);
}
@Patch("/api/admin/v1/dramas/:dramaId/episodes/:episodeId")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("episode:update")
updateDramaEpisode(@Param("dramaId") dramaId: string, @Param("episodeId") episodeId: string, @Body() dto: UpdateEpisodeDto) {
return this.dramasService.updateDramaEpisode(Number(dramaId), Number(episodeId), dto);
}
@Post("/api/admin/v1/dramas/:id/submit-review")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("drama:update")
submitReview(@Param("id") id: string) {
return this.dramasService.submitReview(Number(id));
}
@Patch("/api/admin/v1/episodes/:id/publish-status")
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, PermissionsGuard)
@RequirePermissions("episode:update")
updatePublishStatus(@Param("id") id: string, @Body() dto: { publishStatus: PublishStatus }) {
return this.dramasService.updateEpisodePublishStatus(Number(id), dto.publishStatus);
}
@Get("/api/app/v1/dramas")
listPublishedDramas(@Query("page") page?: string, @Query("pageSize") pageSize?: string) {
return this.dramasService.listPublishedDramas({
page: Number(page) || 1,
pageSize: Number(pageSize) || 10,
});
}
@Get("/api/app/v1/dramas/recommended")
listRecommendedDramas(@Query("page") page?: string, @Query("pageSize") pageSize?: string) {
return this.dramasService.listRecommendedDramas({
page: Number(page) || 1,
pageSize: Number(pageSize) || 10,
});
}
@Get("/api/app/v1/dramas/presearch")
presearchVideos(@Query("keyword") keyword?: string, @Query("page") page?: string, @Query("pageSize") pageSize?: string) {
return this.dramasService.presearchVideos({
page: Number(page) || 1,
pageSize: Number(pageSize) || 10,
keyword,
});
}
@Get("/api/app/v1/dramas/:id/episodes")
listPublishedEpisodes(@Param("id") id: string, @Query("page") page?: string, @Query("pageSize") pageSize?: string) {
return this.dramasService.listPublishedEpisodes(Number(id), {
page: Number(page) || 1,
pageSize: Number(pageSize) || 20,
});
}
@Get("/api/app/v1/dramas/:id")
getPublishedDrama(@Param("id") id: string) {
return this.dramasService.getPublishedDramaOrThrow(Number(id));
}
private parseOptionalBoolean(value?: string) {
if (value === "true") {
return true;
}
if (value === "false") {
return false;
}
return undefined;
}
}