blob: 61f56fe8085f2998ddbf358a2c1177485335d941 [file] [log] [blame]
xiukira687b9cb2025-05-29 15:15:02 +08001package com.g9.g9backend.controller;
2
xiukiradbe96222025-06-06 21:25:09 +08003import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
4import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
xiukiraac78f3d2025-06-08 23:38:10 +08005import com.baomidou.mybatisplus.core.metadata.IPage;
6import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
xiukiradbe96222025-06-06 21:25:09 +08007import com.g9.g9backend.pojo.*;
8import com.g9.g9backend.pojo.DTO.*;
9import com.g9.g9backend.service.*;
xiukira687b9cb2025-05-29 15:15:02 +080010import org.slf4j.Logger;
11import org.slf4j.LoggerFactory;
xiukirab9490272025-06-06 21:53:52 +080012import org.springframework.http.HttpStatus;
xiukiradbe96222025-06-06 21:25:09 +080013import org.springframework.http.ResponseEntity;
xiukirad0a7a082025-06-05 16:28:08 +080014import org.springframework.web.bind.annotation.*;
15
xiukiraac78f3d2025-06-08 23:38:10 +080016import java.util.*;
xiukiradbe96222025-06-06 21:25:09 +080017
xiukira687b9cb2025-05-29 15:15:02 +080018
19/**
20 * ResourceController 资源控制器类,处理与资源相关的请求
21 *
22 * @author hcy
23 */
24@RestController
25@RequestMapping("/resource")
26public class ResourceController {
27
xiukiradbe96222025-06-06 21:25:09 +080028 private final ResourceService resourceService;
29
30 private final GameplayService gameplayService;
31
32 private final RewardService rewardService;
33
34 private final UserUploadService userUploadService;
35
36 private final CommunityService communityService;
37
38 private final UserService userService;
39
40 private final UserPurchaseService userPurchaseService;
41
42 private final UserLikeService userLikeService;
43
44 private final UserCollectionService userCollectionService;
45
46 private final NotificationService notificationService;
47
xiukiraac78f3d2025-06-08 23:38:10 +080048 private final ResourceVersionService resourceVersionService;
49
50 private final SearchHistoryService searchHistoryService;
51
52 private final GameVersionService gameVersionService;
53
54 private final TorrentRecordService torrentRecordService;
55
56 private final HotTrendService hotTrendService;
57
Seamher8ba71e02025-06-09 22:38:35 +080058 static Map<String, String> GAME_CLASSIFY = new HashMap() {{
59 put("模组", "mod");
60 put("地图", "map");
61 put("整合包", "modPack");
62 put("材质包", "resourcePack");
63 }};
64
65
xiukiraac78f3d2025-06-08 23:38:10 +080066 public ResourceController(ResourceService resourceService, GameplayService gameplayService, RewardService rewardService, UserUploadService userUploadService, CommunityService communityService, UserService userService, UserPurchaseService userPurchaseService, UserLikeService userLikeService, UserCollectionService userCollectionService, NotificationService notificationService, ResourceVersionService resourceVersionService, SearchHistoryService searchHistoryService, GameVersionService gameVersionService, TorrentRecordService torrentRecordService, HotTrendService hotTrendService) {
xiukiradbe96222025-06-06 21:25:09 +080067 this.resourceService = resourceService;
68 this.gameplayService = gameplayService;
69 this.rewardService = rewardService;
70 this.userUploadService = userUploadService;
71 this.communityService = communityService;
72 this.userService = userService;
73 this.userPurchaseService = userPurchaseService;
74 this.userLikeService = userLikeService;
75 this.userCollectionService = userCollectionService;
76 this.notificationService = notificationService;
xiukiraac78f3d2025-06-08 23:38:10 +080077 this.resourceVersionService = resourceVersionService;
78 this.searchHistoryService = searchHistoryService;
79 this.gameVersionService = gameVersionService;
80 this.torrentRecordService = torrentRecordService;
81 this.hotTrendService = hotTrendService;
xiukiradbe96222025-06-06 21:25:09 +080082 }
83
xiukira687b9cb2025-05-29 15:15:02 +080084 private final Logger logger = LoggerFactory.getLogger(ResourceController.class);
xiukiradbe96222025-06-06 21:25:09 +080085
86 /**
87 * 上传资源
88 *
89 * @param postResourceDTO 上传资源信息
90 * @return 上传资源结果
91 */
92 @PostMapping
93 public ResponseEntity<String> uploadResource(@RequestBody PostResourceDTO postResourceDTO) {
94 // 存资源
95 Resource resource = postResourceDTO.getResource();
96 resourceService.save(resource);
97 // 存玩法列表
98 String[] gameplayList = postResourceDTO.getGameplayList();
99 for (String gameplayName : gameplayList) {
100 Gameplay gameplay = new Gameplay();
101 gameplay.setGameplayName(gameplayName);
102 gameplay.setResourceId(postResourceDTO.getResource().getResourceId());
103 gameplayService.save(gameplay);
104 }
105 // 完成对应悬赏
106 if (postResourceDTO.getCompleteRewardId() != 0) {
107 UpdateWrapper<Reward> rewardUpdate = new UpdateWrapper<>();
108 rewardUpdate.eq("reward_id", postResourceDTO.getCompleteRewardId()).set("completed_by", postResourceDTO.getUserId()).set("completed_at", postResourceDTO.getResource().getUploadTime()).set("resource_id", postResourceDTO.getResource().getResourceId());
109 rewardService.update(rewardUpdate);
110 }
111 // 存用户上传表
112 UserUpload userUpload = new UserUpload();
113 userUpload.setUserId(postResourceDTO.getUserId());
114 userUpload.setResourceId(postResourceDTO.getResource().getResourceId());
115 userUploadService.save(userUpload);
116 // 创建资源社区
117 Community community = new Community();
118 community.setCommunityName(postResourceDTO.getResource().getResourceName());
xiukira197532d2025-06-09 21:15:50 +0800119 community.setCommunityPicture(postResourceDTO.getResource().getResourcePicture());
120 community.setDescription(postResourceDTO.getResource().getResourceDetail());
xiukiradbe96222025-06-06 21:25:09 +0800121 community.setType(postResourceDTO.getResource().getClassify());
122 community.setResourceId(postResourceDTO.getResource().getResourceId());
123 communityService.save(community);
Seamher3eb882d2025-06-09 23:56:09 +0800124 return ResponseEntity.ok(String.valueOf(resource.getResourceId()));
xiukiradbe96222025-06-06 21:25:09 +0800125 }
126
127 /**
xiukiraac78f3d2025-06-08 23:38:10 +0800128 * 上传版本
129 *
130 * @param resourceVersion 上传版本信息
131 * @return 上传版本结果
132 */
133 @PostMapping("/version")
134 public ResponseEntity<String> uploadResourceVersion(@RequestBody ResourceVersion resourceVersion) {
135 resourceVersionService.save(resourceVersion);
Seamher3eb882d2025-06-09 23:56:09 +0800136 return ResponseEntity.ok(String.valueOf(resourceVersion.getResourceVersionId()));
xiukiraac78f3d2025-06-08 23:38:10 +0800137 }
138
139 /**
xiukiradbe96222025-06-06 21:25:09 +0800140 * 购买资源
141 *
142 * @param userResourceDTO 购买资源信息
143 * @return 购买资源结果
144 */
145 @PostMapping("purchase")
146 public ResponseEntity<String> purchaseResource(@RequestBody UserResourceDTO userResourceDTO) {
147
148 QueryWrapper<User> userQuery = new QueryWrapper<>();
149 userQuery.eq("user_id", userResourceDTO.getUserId());
150 User user = userService.getOne(userQuery);
151
152 QueryWrapper<Resource> ResourceQuery = new QueryWrapper<>();
153 ResourceQuery.eq("resource_id", userResourceDTO.getResourceId());
154 Resource resource = resourceService.getOne(ResourceQuery);
155
156 if (user.getCredits() < resource.getPrice()) {
157 // 积分余额不足
158 logger.info("The balance of points is insufficient to cover the price of this resource: {}", resource.getPrice());
159 return ResponseEntity.status(412).body("");
160 } else {
161 // 扣除用户积分
162 UpdateWrapper<User> userUpdate = new UpdateWrapper<>();
163 userUpdate.eq("user_id", user.getUserId()).set("credits", user.getCredits() - resource.getPrice());
164 userService.update(userUpdate);
165 // 添加购买资源记录
166 UserPurchase userPurchase = new UserPurchase();
167 userPurchase.setUserId(user.getUserId());
168 userPurchase.setResourceId(resource.getResourceId());
169 userPurchaseService.save(userPurchase);
170 // 给上传该资源的用户发送通知
171 Notification notification = new Notification();
172 QueryWrapper<UserUpload> userUploadQuery = new QueryWrapper<>();
173 userUploadQuery.eq("resource_id", userResourceDTO.getResourceId());
174 UserUpload userUpload = userUploadService.getOne(userUploadQuery);
175 notification.setUserId(userUpload.getUserId());
176 notification.setTitle("资源被购买");
177 notification.setContent("你的资源:" + resource.getResourceName() + " 被: " + user.getUsername() + " 购买了!");
178 notification.setCreateAt(new Date());
179 notification.setRead(false);
180 notification.setTriggeredBy(userResourceDTO.getUserId());
181 notification.setRelatedId(userResourceDTO.getResourceId());
182 notificationService.save(notification);
183 return ResponseEntity.ok("");
184 }
185 }
186
187 /**
188 * 点赞资源
189 *
190 * @param userResourceDTO 点赞资源信息
191 * @return 点赞资源结果
192 */
193 @PostMapping("like")
194 public ResponseEntity<String> likeResource(@RequestBody UserResourceDTO userResourceDTO) {
195
Seamher8ba71e02025-06-09 22:38:35 +0800196 logger.info("User id: "+userResourceDTO.getUserId() + "Resource ID: " + userResourceDTO.getResourceId());
197
xiukiradbe96222025-06-06 21:25:09 +0800198 QueryWrapper<User> userQuery = new QueryWrapper<>();
199 userQuery.eq("user_id", userResourceDTO.getUserId());
200 User user = userService.getOne(userQuery);
201
202 QueryWrapper<Resource> ResourceQuery = new QueryWrapper<>();
203 ResourceQuery.eq("resource_id", userResourceDTO.getResourceId());
204 Resource resource = resourceService.getOne(ResourceQuery);
205
206 UserLike userLike = new UserLike();
207 userLike.setUserId(userResourceDTO.getUserId());
208 userLike.setResourceId(userResourceDTO.getResourceId());
209 userLikeService.save(userLike);
210
211 // 给上传该资源的用户发送通知
212 Notification notification = new Notification();
213 QueryWrapper<UserUpload> userUploadQuery = new QueryWrapper<>();
214 userUploadQuery.eq("resource_id", userResourceDTO.getResourceId());
215 UserUpload userUpload = userUploadService.getOne(userUploadQuery);
216 notification.setUserId(userUpload.getUserId());
217 notification.setTitle("资源被点赞");
218 notification.setContent("你的资源:" + resource.getResourceName() + " 被: " + user.getUsername() + " 点赞了!");
219 notification.setCreateAt(new Date());
220 notification.setRead(false);
221 notification.setTriggeredBy(userResourceDTO.getUserId());
222 notification.setRelatedId(userResourceDTO.getResourceId());
223 notificationService.save(notification);
224
225 return ResponseEntity.ok("");
226 }
227
228 /**
229 * 收藏资源
230 *
231 * @param userResourceDTO 收藏资源信息
232 * @return 收藏资源结果
233 */
234 @PostMapping("collection")
235 public ResponseEntity<String> collectResource(@RequestBody UserResourceDTO userResourceDTO) {
236
237 QueryWrapper<User> userQuery = new QueryWrapper<>();
238 userQuery.eq("user_id", userResourceDTO.getUserId());
239 User user = userService.getOne(userQuery);
240
241 QueryWrapper<Resource> ResourceQuery = new QueryWrapper<>();
242 ResourceQuery.eq("resource_id", userResourceDTO.getResourceId());
243 Resource resource = resourceService.getOne(ResourceQuery);
244
245 UserCollection userCollection = new UserCollection();
246 userCollection.setUserId(userResourceDTO.getUserId());
247 userCollection.setResourceId(userResourceDTO.getResourceId());
248 userCollectionService.save(userCollection);
249
250
251 // 给上传该资源的用户发送通知
252 Notification notification = new Notification();
253 QueryWrapper<UserUpload> userUploadQuery = new QueryWrapper<>();
254 userUploadQuery.eq("resource_id", userResourceDTO.getResourceId());
255 UserUpload userUpload = userUploadService.getOne(userUploadQuery);
256 notification.setUserId(userUpload.getUserId());
257 notification.setTitle("资源被收藏");
258 notification.setContent("你的资源:" + resource.getResourceName() + " 被: " + user.getUsername() + " 收藏了!");
259 notification.setCreateAt(new Date());
260 notification.setRead(false);
261 notification.setTriggeredBy(userResourceDTO.getUserId());
262 notification.setRelatedId(userResourceDTO.getResourceId());
263 notificationService.save(notification);
264
265 return ResponseEntity.ok("");
266 }
xiukirab9490272025-06-06 21:53:52 +0800267
268 /**
269 * 删除资源
270 *
271 * @param resourceId 资源id
272 * @param userId 用户id
273 * @param password 密码
274 * @return 删除资源结果
275 */
276 @DeleteMapping
277 @ResponseStatus(HttpStatus.NO_CONTENT)
278 public ResponseEntity<String> userDelete(@RequestParam int resourceId, @RequestParam int userId, @RequestParam String password) {
279 logger.warn("Delete resource with id: {}", resourceId);
280 // 根据用户id查询该用户
281 QueryWrapper<User> userQuery = new QueryWrapper<>();
282 userQuery.eq("user_id", userId);
283 User userCheck = userService.getOne(userQuery);
284
285 // 只允许在用户上传资源页进行删除操作,所以不需要验证该资源是由该用户上传的
286 if (userCheck.getPassword().equals(password)) {
287 // 删除资源
288 resourceService.removeById(resourceId);
289 return ResponseEntity.noContent().build();
290 } else {
291 logger.warn("Delete failed. Incorrect password for account: {}", password);
292 return ResponseEntity.status(408).body("");
293 }
294 }
295
296 /**
297 * 取消点赞
298 *
299 * @param userId 用户id
300 * @param resourceId 资源id
301 * @return 取消点赞结果
302 */
303 @DeleteMapping("like")
304 @ResponseStatus(HttpStatus.NO_CONTENT)
305 public ResponseEntity<String> likeDelete(@RequestParam int userId, @RequestParam int resourceId) {
306 QueryWrapper<UserLike> userLikeQuery = new QueryWrapper<>();
307 userLikeQuery.eq("user_id", userId).eq("resource_id", resourceId);
308 userLikeService.remove(userLikeQuery);
309 return ResponseEntity.noContent().build();
310 }
311
312 /**
313 * 取消收藏
314 *
315 * @param userId 用户id
316 * @param resourceId 资源id
317 * @return 取消收藏结果
318 */
319 @DeleteMapping("collection")
320 @ResponseStatus(HttpStatus.NO_CONTENT)
321 public ResponseEntity<String> collectionDelete(@RequestParam int userId, @RequestParam int resourceId) {
322 QueryWrapper<UserCollection> userCollectionQuery = new QueryWrapper<>();
323 userCollectionQuery.eq("user_id", userId).eq("resource_id", resourceId);
324 userCollectionService.remove(userCollectionQuery);
325 return ResponseEntity.noContent().build();
326 }
xiukiraac78f3d2025-06-08 23:38:10 +0800327
328 /**
329 * 搜索资源
330 *
331 * @param userId 用户id
332 * @param searchValue 输入(模糊搜索)
333 * @param classify 类型名称
334 * @param gameplayList 主要玩法列表
335 * @param gameVersionList 版本列表
336 * @param pageNumber 第几页
337 * @param rows 行数
338 * @return 搜索资源结果
339 */
340 @GetMapping("/search")
341 public ResponseEntity<GetResourcePageDTO> getResourceSearch(@RequestParam int userId, @RequestParam String searchValue, @RequestParam String classify, @RequestParam String[] gameplayList, @RequestParam String[] gameVersionList, @RequestParam int pageNumber, @RequestParam int rows) {
342 IPage<Resource> page = new Page<>(pageNumber, rows);
343 QueryWrapper<Resource> resourceWrapper = new QueryWrapper<>();
344 // 搜索名称字段不为空时,根据搜索名称进行模糊匹配,并将该次搜索存到搜索历史表
345 if (!Objects.equals(searchValue, "")) {
Seamher8ba71e02025-06-09 22:38:35 +0800346 logger.info("Filter by name: " + searchValue);
xiukiraac78f3d2025-06-08 23:38:10 +0800347 resourceWrapper.like("resource_name", searchValue);
348 SearchHistory searchHistory = new SearchHistory();
349 searchHistory.setSearchContent(searchValue);
350 searchHistory.setUserId(userId);
351 searchHistoryService.save(searchHistory);
352 }
353 // 分类字段不为空时,根据类别筛选
Seamher8ba71e02025-06-09 22:38:35 +0800354 logger.info("Classify: " + classify + " Mapped: " + GAME_CLASSIFY.get(classify));
355 if (!Objects.equals(GAME_CLASSIFY.get(classify), "")) {
356 logger.info("Filter by classify: " + classify);
357 resourceWrapper.eq("classify", GAME_CLASSIFY.get(classify));
xiukiraac78f3d2025-06-08 23:38:10 +0800358 }
359
360 // 主要玩法列表不为空时,根据主要玩法列表筛选(用户传入一个玩法列表,需要去 gameplay 表中查询该资源的所有玩法列表,只有当用户传入的玩法列表的每个值都在资源实际有的玩法列表中时,该资源才符合条件)
361 if (gameplayList.length > 0) {
362 // 该子查询统计了用户传入的玩法列表中有多少玩法是在资源的实际玩法列表中有的
Seamher8ba71e02025-06-09 22:38:35 +0800363 logger.info("Filter by gameplay: " + Arrays.toString(gameplayList));
xiukiraac78f3d2025-06-08 23:38:10 +0800364 String subQuery = "SELECT COUNT(*) " +
365 "FROM gameplay gp " +
366 "WHERE gp.resource_id = resource.resource_id " +
367 "AND gp.gameplay_name IN (" +
368 String.join(",", Arrays.stream(gameplayList).map(name -> "'" + name + "'").toArray(String[]::new)) + ")";
369 // 只有当子查询返回的数量等于用户传入的玩法列表长度时,说明用户传入的玩法列表完全被包含在资源的玩法列表中
370 resourceWrapper.apply("(" + subQuery + ") = " + gameplayList.length);
371 }
372
373 // 游戏版本列表不为空时,根据游戏版本列表筛选
374 if (gameVersionList.length > 0) {
375 // 拼接游戏版本列表的 IN 子句
Seamher8ba71e02025-06-09 22:38:35 +0800376 logger.info("Filter by game version: " + Arrays.toString(gameplayList));
xiukiraac78f3d2025-06-08 23:38:10 +0800377 String gameVersionInClause = String.join(",", Arrays.stream(gameVersionList)
378 .map(v -> "'" + v + "'")
379 .toArray(String[]::new));
380
381 // 修改 HAVING 条件逻辑,只检查输入版本列表是否是实际版本列表的子集
382 String resourceCondition = "EXISTS ("
383 + "SELECT 1 "
384 + "FROM resource_version rv "
385 + "JOIN game_version gv ON gv.resource_version_id = rv.resource_version_id "
386 + "WHERE rv.resource_id = resource.resource_id "
387 + "GROUP BY rv.resource_id "
388 + "HAVING COUNT(DISTINCT CASE WHEN gv.game_version_name IN (" + gameVersionInClause + ") THEN gv.game_version_name END) = " + gameVersionList.length
389 + ")";
390
391 // 应用条件
392 resourceWrapper.apply(resourceCondition);
393 }
394
395 IPage<Resource> resourcePage = resourceService.page(page, resourceWrapper);
396 List<Resource> resourceList = resourcePage.getRecords();
Seamher8ba71e02025-06-09 22:38:35 +0800397 logger.info("Resource list" + resourceList);
xiukiraac78f3d2025-06-08 23:38:10 +0800398 long total = resourcePage.getTotal();
399 long pages = resourcePage.getPages();
400 long current = resourcePage.getCurrent();
401 long size = resourcePage.getSize();
402
403 List<List<Gameplay>> gameplayLists = new ArrayList<>();
404 for (Resource resource : resourceList) {
405 // 对于每个资源,获取游戏玩法列表
406 QueryWrapper<Gameplay> gameplayQuery = new QueryWrapper<>();
407 gameplayQuery.eq("resource_id", resource.getResourceId());
408 List<Gameplay> allGameplayList = gameplayService.list(gameplayQuery);
409 gameplayLists.add(allGameplayList);
410 }
411
412 GetResourcePageDTO getResourceSearchDTO = new GetResourcePageDTO(resourceList, gameplayLists, total, pages, current, size);
413 return ResponseEntity.ok(getResourceSearchDTO);
414 }
415
416 /**
417 * 获取资源信息
418 *
419 * @param resourceId 资源id
420 * @param userId 用户id
421 * @return 获取资源信息结果
422 */
423 @GetMapping("/info")
424 public ResponseEntity<GetResourceInfoDTO> getResourceInfo(@RequestParam int resourceId, @RequestParam int userId) {
425 // 获取Resource表信息
426 Resource resource = resourceService.getById(resourceId);
427
428 // 获取Gameplay列表
429 List<Gameplay> gameplayList = gameplayService.list(new QueryWrapper<Gameplay>().eq("resource_id", resourceId));
430
431 // 获取ResourceVersion列表
432 List<ResourceVersion> resourceVersionList = resourceVersionService.list(new QueryWrapper<ResourceVersion>().eq("resource_id", resourceId));
433
434 // 获取GameVersion二维列表
435 List<List<GameVersion>> gameVersionLists = new ArrayList<>();
436 for (ResourceVersion resourceVersion : resourceVersionList) {
437 List<GameVersion> gameVersionList = gameVersionService.list(new QueryWrapper<GameVersion>().eq("resource_version_id", resourceVersion.getResourceVersionId()));
438 gameVersionLists.add(gameVersionList);
439 }
440
441 // 获取TorrentRecord二维列表
442 List<List<TorrentRecord>> torrentRecordLists = new ArrayList<>();
443 for (ResourceVersion resourceVersion : resourceVersionList) {
444 List<TorrentRecord> torrentRecordList = torrentRecordService.list(new QueryWrapper<TorrentRecord>().eq("resource_version_id", resourceVersion.getResourceVersionId()));
445 torrentRecordLists.add(torrentRecordList);
446 }
447
448 // 获取用户是否收藏
449 QueryWrapper<UserCollection> userCollectionQuery = new QueryWrapper<>();
450 userCollectionQuery.eq("user_id", userId).eq("resource_id", resourceId);
451 boolean isCollect = userCollectionService.getOne(userCollectionQuery) != null;
452
453 // 获取用户是否点赞
454 QueryWrapper<UserLike> userLikeQuery = new QueryWrapper<>();
455 userLikeQuery.eq("user_id", userId).eq("resource_id", resourceId);
456 boolean isLike = userLikeService.getOne(userLikeQuery) != null;
457
458 // 获取用户是否购买
459 QueryWrapper<UserPurchase> userPurchaseQuery = new QueryWrapper<>();
460 userPurchaseQuery.eq("user_id", userId).eq("resource_id", resourceId);
461 boolean isPurchase = userPurchaseService.getOne(userPurchaseQuery) != null;
462
463 // 获取用户是否上传
464 QueryWrapper<UserUpload> userUploadQuery = new QueryWrapper<>();
465 userUploadQuery.eq("user_id", userId).eq("resource_id", resourceId);
466 boolean isUpload = userUploadService.getOne(userUploadQuery) != null;
467
468 // 获取上传者ID
469 QueryWrapper<UserUpload> findUploaderQuery = new QueryWrapper<>();
470 findUploaderQuery.eq("resource_id", resourceId);
471 int uploaderId = userUploadService.getOne(findUploaderQuery).getUserId();
472
473 GetResourceInfoDTO getResourceInfoDTO = new GetResourceInfoDTO(resource, gameplayList, resourceVersionList, gameVersionLists, torrentRecordLists, isCollect, isLike, isPurchase, isUpload, uploaderId);
474 return ResponseEntity.ok(getResourceInfoDTO);
475 }
476
477 /**
478 * 获取热门资源
479 *
480 * @param classify 资源分类
481 * @param pageNumber 页数
482 * @param rows 行数
483 * @return 获取热门资源结果
484 */
485 @GetMapping("/hot")
486 public ResponseEntity<GetResourcePageDTO> getHotResource(@RequestParam String classify, @RequestParam int pageNumber, @RequestParam int rows) {
487 IPage<Resource> page = new Page<>(pageNumber, rows);
488 QueryWrapper<Resource> resourceQuery = new QueryWrapper<>();
Seamher8ba71e02025-06-09 22:38:35 +0800489 resourceQuery.eq("classify", GAME_CLASSIFY.get(classify));
xiukiraac78f3d2025-06-08 23:38:10 +0800490 // 动态计算热度并按降序排序
491 resourceQuery.orderByDesc("(downloads * 0.25 + likes * 0.25 + collections * 0.25 + comments * 0.25)");
492 IPage<Resource> resourcePage = resourceService.page(page, resourceQuery);
493 List<Resource> resourceList = resourcePage.getRecords();
494 long total = resourcePage.getTotal();
495 long pages = resourcePage.getPages();
496 long current = resourcePage.getCurrent();
497 long size = resourcePage.getSize();
498
499 List<List<Gameplay>> gameplayLists = new ArrayList<>();
500 for (Resource resource : resourceList) {
501 // 对于每个资源,获取游戏玩法列表
502 QueryWrapper<Gameplay> gameplayQuery = new QueryWrapper<>();
503 gameplayQuery.eq("resource_id", resource.getResourceId());
504 List<Gameplay> allGameplayList = gameplayService.list(gameplayQuery);
505 gameplayLists.add(allGameplayList);
506 }
507
508 GetResourcePageDTO getResourcePageDTO = new GetResourcePageDTO(resourceList, gameplayLists, total, pages, current, size);
509 return ResponseEntity.ok(getResourcePageDTO);
510 }
511
512 /**
513 * 获取热门资源幻灯片数据
514 *
515 * @return 获取用户收藏结果
516 */
517 @GetMapping("/hot/slide")
518 public ResponseEntity<GetResourceHotSlideDTO> getResourceHotSlide() {
519 QueryWrapper<Resource> resourceQuery = new QueryWrapper<>();
520 // 动态计算热度并按降序排序
521 resourceQuery.orderByDesc("(downloads * 0.25 + likes * 0.25 + collections * 0.25 + comments * 0.25)");
522 // 限制返回3条记录
523 resourceQuery.last("LIMIT 3");
524 List<Resource> resourceList = resourceService.list(resourceQuery);
525
526 GetResourceHotSlideDTO getResourceHotSlideDTO = new GetResourceHotSlideDTO(resourceList);
527 return ResponseEntity.ok(getResourceHotSlideDTO);
528 }
529
530 /**
531 * 获取热门资源趋势图
532 *
533 * @return 获取热门资源趋势图结果
534 */
535 @GetMapping("/hot-trend")
536 public ResponseEntity<GetResourceHotTrendDTO> getResourceHotTrend() {
537 List<HotTrend> hotTrendList = hotTrendService.list();
538 GetResourceHotTrendDTO getResourceHotTrendDTO = new GetResourceHotTrendDTO(hotTrendList);
539 return ResponseEntity.ok(getResourceHotTrendDTO);
540 }
541
542 /**
543 * 修改资源信息
544 *
545 * @param putResourceInfoDTO 要修改的资源信息
546 * @return 修改资源信息结果
547 */
548 @PutMapping("/info")
549 public ResponseEntity<String> putResourceInfo(@RequestBody PutResourceInfoDTO putResourceInfoDTO) {
550 // 检查资源名是否重复
551 QueryWrapper<Resource> resourceQuery = new QueryWrapper<>();
552 resourceQuery.ne("resource_id", putResourceInfoDTO.getResourceId()).eq("resource_name", putResourceInfoDTO.getResourceName());
553 Resource resource = resourceService.getOne(resourceQuery);
554
555 if (resource != null) {
556 // 资源名重复
557 logger.warn("Modification attempt failed. Resource name already exists: {}", putResourceInfoDTO.getResourceName());
558 return ResponseEntity.status(411).body("");
559 }
560
561 UpdateWrapper<Resource> resourceUpdate = new UpdateWrapper<>();
562 resourceUpdate.eq("resource_id", putResourceInfoDTO.getResourceId())
563 .set("resource_name", putResourceInfoDTO.getResourceName())
564 .set("resource_picture", putResourceInfoDTO.getResourcePicture())
565 .set("resource_summary", putResourceInfoDTO.getResourceSummary())
566 .set("resource_detail", putResourceInfoDTO.getResourceDetail())
567 .set("price", putResourceInfoDTO.getPrice());
568 resourceService.update(resourceUpdate);
569
570 QueryWrapper<Gameplay> gameplayQuery = new QueryWrapper<>();
571 gameplayQuery.eq("resource_id", putResourceInfoDTO.getResourceId());
572 gameplayService.remove(gameplayQuery);
573
574 for (int i = 0; i < putResourceInfoDTO.getGameplayList().length; i++) {
575 Gameplay gameplay = new Gameplay();
576 gameplay.setGameplayName(putResourceInfoDTO.getGameplayList()[i]);
577 gameplay.setResourceId(putResourceInfoDTO.getResourceId());
578 gameplayService.save(gameplay);
579 }
580
581 return ResponseEntity.ok("");
582 }
xiukiradbe96222025-06-06 21:25:09 +0800583}