返回 AiToEarn
material.controller.ts
根目录 / project / aitoearn-backend / apps / aitoearn-server / src / core / content / material.controller.ts
1 /*
2 * @Author: nevin
3 * @Date: 2024-06-17 19:19:20
4 * @LastEditTime: 2024-12-23 12:45:22
5 * @LastEditors: nevin
6 * @Description: Material Controller
7 */
8 import {
9 Body,
10 Controller,
11 Delete,
12 Get,
13 Param,
14 Post,
15 Put,
16 Query,
17 } from '@nestjs/common'
18 import { ApiTags } from '@nestjs/swagger'
19 import { GetToken, Public, TokenInfo } from '@yikart/aitoearn-auth'
20 import { AccountType, ApiDoc, AppException, ParseObjectIdPipe, ResponseCode, TableDto, UserType } from '@yikart/common'
21 import { MaterialStatus, MaterialType, MediaType } from '@yikart/mongodb'
22 import { MaterialListVo, MaterialVo } from './content.vo'
23 import { MaterialGroupService } from './material-group.service'
24 import {
25 CreateMaterialDto,
26 DeleteByUseCountDto,
27 GetOptimalMaterialDto,
28 MaterialFilterDto,
29 MaterialFilterSchema,
30 MaterialIdsDto,
31 TransferMaterialDto,
32 UpdateMaterialDto,
33 } from './material.dto'
34 import { MaterialService } from './material.service'
35
36 export const MediaMaterialTypeMap = new Map<MediaType, MaterialType>([
37 [MediaType.VIDEO, MaterialType.VIDEO],
38 [MediaType.IMG, MaterialType.ARTICLE],
39 ])
40
41 const VIDEO_ONLY_PLATFORMS = new Set<AccountType>([
42 AccountType.YouTube,
43 AccountType.Bilibili,
44 AccountType.Kwai,
45 AccountType.TikTok,
46 AccountType.WeChatChannels,
47 ])
48
49 function getMaterialTypeByAccountType(accountType: AccountType): MaterialType | undefined {
50 if (VIDEO_ONLY_PLATFORMS.has(accountType)) {
51 return MaterialType.VIDEO
52 }
53 return undefined
54 }
55
56 @ApiTags('Me/Material')
57 @Controller('material')
58 export class MaterialController {
59 constructor(
60 private readonly materialService: MaterialService,
61 private readonly materialGroupService: MaterialGroupService,
62 ) { }
63
64 @ApiDoc({
65 summary: '创建草稿',
66 description: '使用提供的媒体和元数据创建草稿。',
67 body: CreateMaterialDto.schema,
68 })
69 @Post()
70 async create(
71 @GetToken() token: TokenInfo,
72 @Body() body: CreateMaterialDto,
73 ) {
74 const getInfo = await this.materialGroupService.getGroupInfo(body.groupId)
75 if (!getInfo || getInfo.userId !== token.id) {
76 throw new AppException(ResponseCode.MaterialGroupNotFound)
77 }
78
79 const res = await this.materialService.create({
80 ...body,
81 userId: token.id,
82 userType: UserType.User,
83 status: MaterialStatus.SUCCESS,
84 })
85 return MaterialVo.create(res)
86 }
87
88 @ApiDoc({
89 summary: '草稿转移到其他草稿箱',
90 description: '将草稿移动或复制到目标草稿箱。move 模式直接移动,copy 模式复制并重置使用次数。',
91 body: TransferMaterialDto.schema,
92 })
93 @Post('/transfer')
94 async transferToGroup(
95 @GetToken() token: TokenInfo,
96 @Body() body: TransferMaterialDto,
97 ) {
98 const targetGroup = await this.materialGroupService.getGroupInfo(body.targetGroupId)
99 if (!targetGroup || targetGroup.userId !== token.id) {
100 throw new AppException(ResponseCode.MaterialGroupNotFound)
101 }
102
103 const count = await this.materialService.transferToGroup(
104 token.id,
105 body.ids,
106 body.targetGroupId,
107 body.mode,
108 )
109 return { count }
110 }
111
112 @ApiDoc({
113 summary: '按条件删除草稿',
114 description: '删除符合筛选条件的草稿。',
115 body: MaterialFilterDto.schema,
116 })
117 @Delete('filter')
118 async delByFilter(
119 @GetToken() token: TokenInfo,
120 @Body() body: MaterialFilterDto,
121 ) {
122 const res = await this.materialService.delByFilter(token.id, body)
123 return res
124 }
125
126 @ApiDoc({
127 summary: '批量删除草稿',
128 description: '根据ID列表批量删除草稿。',
129 body: MaterialIdsDto.schema,
130 })
131 @Delete('list')
132 async delByIds(
133 @GetToken() token: TokenInfo,
134 @Body() body: MaterialIdsDto,
135 ) {
136 const res = await this.materialService.delByIds(token.id, body.ids)
137 return res
138 }
139
140 @ApiDoc({
141 summary: '根据使用次数删除草稿',
142 description: '删除指定草稿箱内使用次数大于等于指定值的草稿。',
143 body: DeleteByUseCountDto.schema,
144 })
145 @Delete('use-count')
146 async deleteByUseCount(
147 @GetToken() token: TokenInfo,
148 @Body() body: DeleteByUseCountDto,
149 ) {
150 await this.materialService.deleteByUseCount(token.id, body.groupId, body.minUseCount)
151 }
152
153 @ApiDoc({
154 summary: '删除草稿',
155 description: '根据ID删除草稿。',
156 })
157 @Delete(':id')
158 async del(
159 @GetToken() token: TokenInfo,
160 @Param('id', ParseObjectIdPipe) id: string,
161 ) {
162 const material = await this.materialService.getInfo(id)
163 if (!material || material.userId !== token.id) {
164 throw new AppException(ResponseCode.MaterialNotFound, 'Material not found')
165 }
166 const res = await this.materialService.del(id)
167 return res
168 }
169
170 @ApiDoc({
171 summary: '更新草稿信息',
172 description: '根据ID更新草稿详情。',
173 body: UpdateMaterialDto.schema,
174 })
175 @Put('info/:id')
176 async upMaterialInfo(
177 @GetToken() token: TokenInfo,
178 @Param('id', ParseObjectIdPipe) id: string,
179 @Body() body: UpdateMaterialDto,
180 ) {
181 const material = await this.materialService.getInfo(id)
182 if (!material || material.userId !== token.id) {
183 throw new AppException(ResponseCode.MaterialNotFound, 'Material not found')
184 }
185 const res = await this.materialService.updateInfo(id, body)
186 return res
187 }
188
189 @ApiDoc({
190 summary: '获取草稿详情',
191 description: '根据ID获取草稿详情。',
192 })
193 @Public()
194 @Get('info/:id')
195 async getInfo(@Param('id', ParseObjectIdPipe) id: string) {
196 const res = await this.materialService.getInfo(id)
197 return res ? MaterialVo.create(res) : res
198 }
199
200 @ApiDoc({
201 summary: '获取草稿箱最优草稿',
202 description: '根据草稿箱ID和平台类型获取最优草稿,视频类平台自动筛选视频草稿',
203 query: GetOptimalMaterialDto.schema,
204 })
205 @Public()
206 @Get('optimal')
207 async optimalInGroup(@Query() query: GetOptimalMaterialDto) {
208 const type = getMaterialTypeByAccountType(query.accountType)
209 const res = await this.materialService.optimalInGroup(query.groupId, type, query.accountType)
210 return res ? MaterialVo.create(res) : res
211 }
212
213 @ApiDoc({
214 summary: '获取草稿列表',
215 description: '分页获取草稿列表,支持筛选条件。',
216 query: MaterialFilterSchema,
217 })
218 @Get('list/:pageNo/:pageSize')
219 async getList(
220 @GetToken() token: TokenInfo,
221 @Param() param: TableDto,
222 @Query() query: MaterialFilterDto,
223 ) {
224 const res = await this.materialService.getList(
225 param,
226 {
227 ...query,
228 userId: token.id,
229 },
230 )
231 return MaterialListVo.create(res)
232 }
233 }
234
234 lines TYPESCRIPT