blob: 79d9b8482bd3193b2b72f1f34347ff0f3d7f265c [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());
119 community.setType(postResourceDTO.getResource().getClassify());
120 community.setResourceId(postResourceDTO.getResource().getResourceId());
121 communityService.save(community);
122 return ResponseEntity.ok("");
123 }
124
125 /**
xiukiraac78f3d2025-06-08 23:38:10 +0800126 * 上传版本
127 *
128 * @param resourceVersion 上传版本信息
129 * @return 上传版本结果
130 */
131 @PostMapping("/version")
132 public ResponseEntity<String> uploadResourceVersion(@RequestBody ResourceVersion resourceVersion) {
133 resourceVersionService.save(resourceVersion);
134 return ResponseEntity.ok("");
135 }
136
137 /**
xiukiradbe96222025-06-06 21:25:09 +0800138 * 购买资源
139 *
140 * @param userResourceDTO 购买资源信息
141 * @return 购买资源结果
142 */
143 @PostMapping("purchase")
144 public ResponseEntity<String> purchaseResource(@RequestBody UserResourceDTO userResourceDTO) {
145
146 QueryWrapper<User> userQuery = new QueryWrapper<>();
147 userQuery.eq("user_id", userResourceDTO.getUserId());
148 User user = userService.getOne(userQuery);
149
150 QueryWrapper<Resource> ResourceQuery = new QueryWrapper<>();
151 ResourceQuery.eq("resource_id", userResourceDTO.getResourceId());
152 Resource resource = resourceService.getOne(ResourceQuery);
153
154 if (user.getCredits() < resource.getPrice()) {
155 // 积分余额不足
156 logger.info("The balance of points is insufficient to cover the price of this resource: {}", resource.getPrice());
157 return ResponseEntity.status(412).body("");
158 } else {
159 // 扣除用户积分
160 UpdateWrapper<User> userUpdate = new UpdateWrapper<>();
161 userUpdate.eq("user_id", user.getUserId()).set("credits", user.getCredits() - resource.getPrice());
162 userService.update(userUpdate);
163 // 添加购买资源记录
164 UserPurchase userPurchase = new UserPurchase();
165 userPurchase.setUserId(user.getUserId());
166 userPurchase.setResourceId(resource.getResourceId());
167 userPurchaseService.save(userPurchase);
168 // 给上传该资源的用户发送通知
169 Notification notification = new Notification();
170 QueryWrapper<UserUpload> userUploadQuery = new QueryWrapper<>();
171 userUploadQuery.eq("resource_id", userResourceDTO.getResourceId());
172 UserUpload userUpload = userUploadService.getOne(userUploadQuery);
173 notification.setUserId(userUpload.getUserId());
174 notification.setTitle("资源被购买");
175 notification.setContent("你的资源:" + resource.getResourceName() + " 被: " + user.getUsername() + " 购买了!");
176 notification.setCreateAt(new Date());
177 notification.setRead(false);
178 notification.setTriggeredBy(userResourceDTO.getUserId());
179 notification.setRelatedId(userResourceDTO.getResourceId());
180 notificationService.save(notification);
181 return ResponseEntity.ok("");
182 }
183 }
184
185 /**
186 * 点赞资源
187 *
188 * @param userResourceDTO 点赞资源信息
189 * @return 点赞资源结果
190 */
191 @PostMapping("like")
192 public ResponseEntity<String> likeResource(@RequestBody UserResourceDTO userResourceDTO) {
193
Seamher8ba71e02025-06-09 22:38:35 +0800194 logger.info("User id: "+userResourceDTO.getUserId() + "Resource ID: " + userResourceDTO.getResourceId());
195
xiukiradbe96222025-06-06 21:25:09 +0800196 QueryWrapper<User> userQuery = new QueryWrapper<>();
197 userQuery.eq("user_id", userResourceDTO.getUserId());
198 User user = userService.getOne(userQuery);
199
200 QueryWrapper<Resource> ResourceQuery = new QueryWrapper<>();
201 ResourceQuery.eq("resource_id", userResourceDTO.getResourceId());
202 Resource resource = resourceService.getOne(ResourceQuery);
203
204 UserLike userLike = new UserLike();
205 userLike.setUserId(userResourceDTO.getUserId());
206 userLike.setResourceId(userResourceDTO.getResourceId());
207 userLikeService.save(userLike);
208
209 // 给上传该资源的用户发送通知
210 Notification notification = new Notification();
211 QueryWrapper<UserUpload> userUploadQuery = new QueryWrapper<>();
212 userUploadQuery.eq("resource_id", userResourceDTO.getResourceId());
213 UserUpload userUpload = userUploadService.getOne(userUploadQuery);
214 notification.setUserId(userUpload.getUserId());
215 notification.setTitle("资源被点赞");
216 notification.setContent("你的资源:" + resource.getResourceName() + " 被: " + user.getUsername() + " 点赞了!");
217 notification.setCreateAt(new Date());
218 notification.setRead(false);
219 notification.setTriggeredBy(userResourceDTO.getUserId());
220 notification.setRelatedId(userResourceDTO.getResourceId());
221 notificationService.save(notification);
222
223 return ResponseEntity.ok("");
224 }
225
226 /**
227 * 收藏资源
228 *
229 * @param userResourceDTO 收藏资源信息
230 * @return 收藏资源结果
231 */
232 @PostMapping("collection")
233 public ResponseEntity<String> collectResource(@RequestBody UserResourceDTO userResourceDTO) {
234
235 QueryWrapper<User> userQuery = new QueryWrapper<>();
236 userQuery.eq("user_id", userResourceDTO.getUserId());
237 User user = userService.getOne(userQuery);
238
239 QueryWrapper<Resource> ResourceQuery = new QueryWrapper<>();
240 ResourceQuery.eq("resource_id", userResourceDTO.getResourceId());
241 Resource resource = resourceService.getOne(ResourceQuery);
242
243 UserCollection userCollection = new UserCollection();
244 userCollection.setUserId(userResourceDTO.getUserId());
245 userCollection.setResourceId(userResourceDTO.getResourceId());
246 userCollectionService.save(userCollection);
247
248
249 // 给上传该资源的用户发送通知
250 Notification notification = new Notification();
251 QueryWrapper<UserUpload> userUploadQuery = new QueryWrapper<>();
252 userUploadQuery.eq("resource_id", userResourceDTO.getResourceId());
253 UserUpload userUpload = userUploadService.getOne(userUploadQuery);
254 notification.setUserId(userUpload.getUserId());
255 notification.setTitle("资源被收藏");
256 notification.setContent("你的资源:" + resource.getResourceName() + " 被: " + user.getUsername() + " 收藏了!");
257 notification.setCreateAt(new Date());
258 notification.setRead(false);
259 notification.setTriggeredBy(userResourceDTO.getUserId());
260 notification.setRelatedId(userResourceDTO.getResourceId());
261 notificationService.save(notification);
262
263 return ResponseEntity.ok("");
264 }
xiukirab9490272025-06-06 21:53:52 +0800265
266 /**
267 * 删除资源
268 *
269 * @param resourceId 资源id
270 * @param userId 用户id
271 * @param password 密码
272 * @return 删除资源结果
273 */
274 @DeleteMapping
275 @ResponseStatus(HttpStatus.NO_CONTENT)
276 public ResponseEntity<String> userDelete(@RequestParam int resourceId, @RequestParam int userId, @RequestParam String password) {
277 logger.warn("Delete resource with id: {}", resourceId);
278 // 根据用户id查询该用户
279 QueryWrapper<User> userQuery = new QueryWrapper<>();
280 userQuery.eq("user_id", userId);
281 User userCheck = userService.getOne(userQuery);
282
283 // 只允许在用户上传资源页进行删除操作,所以不需要验证该资源是由该用户上传的
284 if (userCheck.getPassword().equals(password)) {
285 // 删除资源
286 resourceService.removeById(resourceId);
287 return ResponseEntity.noContent().build();
288 } else {
289 logger.warn("Delete failed. Incorrect password for account: {}", password);
290 return ResponseEntity.status(408).body("");
291 }
292 }
293
294 /**
295 * 取消点赞
296 *
297 * @param userId 用户id
298 * @param resourceId 资源id
299 * @return 取消点赞结果
300 */
301 @DeleteMapping("like")
302 @ResponseStatus(HttpStatus.NO_CONTENT)
303 public ResponseEntity<String> likeDelete(@RequestParam int userId, @RequestParam int resourceId) {
304 QueryWrapper<UserLike> userLikeQuery = new QueryWrapper<>();
305 userLikeQuery.eq("user_id", userId).eq("resource_id", resourceId);
306 userLikeService.remove(userLikeQuery);
307 return ResponseEntity.noContent().build();
308 }
309
310 /**
311 * 取消收藏
312 *
313 * @param userId 用户id
314 * @param resourceId 资源id
315 * @return 取消收藏结果
316 */
317 @DeleteMapping("collection")
318 @ResponseStatus(HttpStatus.NO_CONTENT)
319 public ResponseEntity<String> collectionDelete(@RequestParam int userId, @RequestParam int resourceId) {
320 QueryWrapper<UserCollection> userCollectionQuery = new QueryWrapper<>();
321 userCollectionQuery.eq("user_id", userId).eq("resource_id", resourceId);
322 userCollectionService.remove(userCollectionQuery);
323 return ResponseEntity.noContent().build();
324 }
xiukiraac78f3d2025-06-08 23:38:10 +0800325
326 /**
327 * 搜索资源
328 *
329 * @param userId 用户id
330 * @param searchValue 输入(模糊搜索)
331 * @param classify 类型名称
332 * @param gameplayList 主要玩法列表
333 * @param gameVersionList 版本列表
334 * @param pageNumber 第几页
335 * @param rows 行数
336 * @return 搜索资源结果
337 */
338 @GetMapping("/search")
339 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) {
340 IPage<Resource> page = new Page<>(pageNumber, rows);
341 QueryWrapper<Resource> resourceWrapper = new QueryWrapper<>();
342 // 搜索名称字段不为空时,根据搜索名称进行模糊匹配,并将该次搜索存到搜索历史表
343 if (!Objects.equals(searchValue, "")) {
Seamher8ba71e02025-06-09 22:38:35 +0800344 logger.info("Filter by name: " + searchValue);
xiukiraac78f3d2025-06-08 23:38:10 +0800345 resourceWrapper.like("resource_name", searchValue);
346 SearchHistory searchHistory = new SearchHistory();
347 searchHistory.setSearchContent(searchValue);
348 searchHistory.setUserId(userId);
349 searchHistoryService.save(searchHistory);
350 }
351 // 分类字段不为空时,根据类别筛选
Seamher8ba71e02025-06-09 22:38:35 +0800352 logger.info("Classify: " + classify + " Mapped: " + GAME_CLASSIFY.get(classify));
353 if (!Objects.equals(GAME_CLASSIFY.get(classify), "")) {
354 logger.info("Filter by classify: " + classify);
355 resourceWrapper.eq("classify", GAME_CLASSIFY.get(classify));
xiukiraac78f3d2025-06-08 23:38:10 +0800356 }
357
358 // 主要玩法列表不为空时,根据主要玩法列表筛选(用户传入一个玩法列表,需要去 gameplay 表中查询该资源的所有玩法列表,只有当用户传入的玩法列表的每个值都在资源实际有的玩法列表中时,该资源才符合条件)
359 if (gameplayList.length > 0) {
360 // 该子查询统计了用户传入的玩法列表中有多少玩法是在资源的实际玩法列表中有的
Seamher8ba71e02025-06-09 22:38:35 +0800361 logger.info("Filter by gameplay: " + Arrays.toString(gameplayList));
xiukiraac78f3d2025-06-08 23:38:10 +0800362 String subQuery = "SELECT COUNT(*) " +
363 "FROM gameplay gp " +
364 "WHERE gp.resource_id = resource.resource_id " +
365 "AND gp.gameplay_name IN (" +
366 String.join(",", Arrays.stream(gameplayList).map(name -> "'" + name + "'").toArray(String[]::new)) + ")";
367 // 只有当子查询返回的数量等于用户传入的玩法列表长度时,说明用户传入的玩法列表完全被包含在资源的玩法列表中
368 resourceWrapper.apply("(" + subQuery + ") = " + gameplayList.length);
369 }
370
371 // 游戏版本列表不为空时,根据游戏版本列表筛选
372 if (gameVersionList.length > 0) {
373 // 拼接游戏版本列表的 IN 子句
Seamher8ba71e02025-06-09 22:38:35 +0800374 logger.info("Filter by game version: " + Arrays.toString(gameplayList));
xiukiraac78f3d2025-06-08 23:38:10 +0800375 String gameVersionInClause = String.join(",", Arrays.stream(gameVersionList)
376 .map(v -> "'" + v + "'")
377 .toArray(String[]::new));
378
379 // 修改 HAVING 条件逻辑,只检查输入版本列表是否是实际版本列表的子集
380 String resourceCondition = "EXISTS ("
381 + "SELECT 1 "
382 + "FROM resource_version rv "
383 + "JOIN game_version gv ON gv.resource_version_id = rv.resource_version_id "
384 + "WHERE rv.resource_id = resource.resource_id "
385 + "GROUP BY rv.resource_id "
386 + "HAVING COUNT(DISTINCT CASE WHEN gv.game_version_name IN (" + gameVersionInClause + ") THEN gv.game_version_name END) = " + gameVersionList.length
387 + ")";
388
389 // 应用条件
390 resourceWrapper.apply(resourceCondition);
391 }
392
393 IPage<Resource> resourcePage = resourceService.page(page, resourceWrapper);
394 List<Resource> resourceList = resourcePage.getRecords();
Seamher8ba71e02025-06-09 22:38:35 +0800395 logger.info("Resource list" + resourceList);
xiukiraac78f3d2025-06-08 23:38:10 +0800396 long total = resourcePage.getTotal();
397 long pages = resourcePage.getPages();
398 long current = resourcePage.getCurrent();
399 long size = resourcePage.getSize();
400
401 List<List<Gameplay>> gameplayLists = new ArrayList<>();
402 for (Resource resource : resourceList) {
403 // 对于每个资源,获取游戏玩法列表
404 QueryWrapper<Gameplay> gameplayQuery = new QueryWrapper<>();
405 gameplayQuery.eq("resource_id", resource.getResourceId());
406 List<Gameplay> allGameplayList = gameplayService.list(gameplayQuery);
407 gameplayLists.add(allGameplayList);
408 }
409
410 GetResourcePageDTO getResourceSearchDTO = new GetResourcePageDTO(resourceList, gameplayLists, total, pages, current, size);
411 return ResponseEntity.ok(getResourceSearchDTO);
412 }
413
414 /**
415 * 获取资源信息
416 *
417 * @param resourceId 资源id
418 * @param userId 用户id
419 * @return 获取资源信息结果
420 */
421 @GetMapping("/info")
422 public ResponseEntity<GetResourceInfoDTO> getResourceInfo(@RequestParam int resourceId, @RequestParam int userId) {
423 // 获取Resource表信息
424 Resource resource = resourceService.getById(resourceId);
425
426 // 获取Gameplay列表
427 List<Gameplay> gameplayList = gameplayService.list(new QueryWrapper<Gameplay>().eq("resource_id", resourceId));
428
429 // 获取ResourceVersion列表
430 List<ResourceVersion> resourceVersionList = resourceVersionService.list(new QueryWrapper<ResourceVersion>().eq("resource_id", resourceId));
431
432 // 获取GameVersion二维列表
433 List<List<GameVersion>> gameVersionLists = new ArrayList<>();
434 for (ResourceVersion resourceVersion : resourceVersionList) {
435 List<GameVersion> gameVersionList = gameVersionService.list(new QueryWrapper<GameVersion>().eq("resource_version_id", resourceVersion.getResourceVersionId()));
436 gameVersionLists.add(gameVersionList);
437 }
438
439 // 获取TorrentRecord二维列表
440 List<List<TorrentRecord>> torrentRecordLists = new ArrayList<>();
441 for (ResourceVersion resourceVersion : resourceVersionList) {
442 List<TorrentRecord> torrentRecordList = torrentRecordService.list(new QueryWrapper<TorrentRecord>().eq("resource_version_id", resourceVersion.getResourceVersionId()));
443 torrentRecordLists.add(torrentRecordList);
444 }
445
446 // 获取用户是否收藏
447 QueryWrapper<UserCollection> userCollectionQuery = new QueryWrapper<>();
448 userCollectionQuery.eq("user_id", userId).eq("resource_id", resourceId);
449 boolean isCollect = userCollectionService.getOne(userCollectionQuery) != null;
450
451 // 获取用户是否点赞
452 QueryWrapper<UserLike> userLikeQuery = new QueryWrapper<>();
453 userLikeQuery.eq("user_id", userId).eq("resource_id", resourceId);
454 boolean isLike = userLikeService.getOne(userLikeQuery) != null;
455
456 // 获取用户是否购买
457 QueryWrapper<UserPurchase> userPurchaseQuery = new QueryWrapper<>();
458 userPurchaseQuery.eq("user_id", userId).eq("resource_id", resourceId);
459 boolean isPurchase = userPurchaseService.getOne(userPurchaseQuery) != null;
460
461 // 获取用户是否上传
462 QueryWrapper<UserUpload> userUploadQuery = new QueryWrapper<>();
463 userUploadQuery.eq("user_id", userId).eq("resource_id", resourceId);
464 boolean isUpload = userUploadService.getOne(userUploadQuery) != null;
465
466 // 获取上传者ID
467 QueryWrapper<UserUpload> findUploaderQuery = new QueryWrapper<>();
468 findUploaderQuery.eq("resource_id", resourceId);
469 int uploaderId = userUploadService.getOne(findUploaderQuery).getUserId();
470
471 GetResourceInfoDTO getResourceInfoDTO = new GetResourceInfoDTO(resource, gameplayList, resourceVersionList, gameVersionLists, torrentRecordLists, isCollect, isLike, isPurchase, isUpload, uploaderId);
472 return ResponseEntity.ok(getResourceInfoDTO);
473 }
474
475 /**
476 * 获取热门资源
477 *
478 * @param classify 资源分类
479 * @param pageNumber 页数
480 * @param rows 行数
481 * @return 获取热门资源结果
482 */
483 @GetMapping("/hot")
484 public ResponseEntity<GetResourcePageDTO> getHotResource(@RequestParam String classify, @RequestParam int pageNumber, @RequestParam int rows) {
485 IPage<Resource> page = new Page<>(pageNumber, rows);
486 QueryWrapper<Resource> resourceQuery = new QueryWrapper<>();
Seamher8ba71e02025-06-09 22:38:35 +0800487 resourceQuery.eq("classify", GAME_CLASSIFY.get(classify));
xiukiraac78f3d2025-06-08 23:38:10 +0800488 // 动态计算热度并按降序排序
489 resourceQuery.orderByDesc("(downloads * 0.25 + likes * 0.25 + collections * 0.25 + comments * 0.25)");
490 IPage<Resource> resourcePage = resourceService.page(page, resourceQuery);
491 List<Resource> resourceList = resourcePage.getRecords();
492 long total = resourcePage.getTotal();
493 long pages = resourcePage.getPages();
494 long current = resourcePage.getCurrent();
495 long size = resourcePage.getSize();
496
497 List<List<Gameplay>> gameplayLists = new ArrayList<>();
498 for (Resource resource : resourceList) {
499 // 对于每个资源,获取游戏玩法列表
500 QueryWrapper<Gameplay> gameplayQuery = new QueryWrapper<>();
501 gameplayQuery.eq("resource_id", resource.getResourceId());
502 List<Gameplay> allGameplayList = gameplayService.list(gameplayQuery);
503 gameplayLists.add(allGameplayList);
504 }
505
506 GetResourcePageDTO getResourcePageDTO = new GetResourcePageDTO(resourceList, gameplayLists, total, pages, current, size);
507 return ResponseEntity.ok(getResourcePageDTO);
508 }
509
510 /**
511 * 获取热门资源幻灯片数据
512 *
513 * @return 获取用户收藏结果
514 */
515 @GetMapping("/hot/slide")
516 public ResponseEntity<GetResourceHotSlideDTO> getResourceHotSlide() {
517 QueryWrapper<Resource> resourceQuery = new QueryWrapper<>();
518 // 动态计算热度并按降序排序
519 resourceQuery.orderByDesc("(downloads * 0.25 + likes * 0.25 + collections * 0.25 + comments * 0.25)");
520 // 限制返回3条记录
521 resourceQuery.last("LIMIT 3");
522 List<Resource> resourceList = resourceService.list(resourceQuery);
523
524 GetResourceHotSlideDTO getResourceHotSlideDTO = new GetResourceHotSlideDTO(resourceList);
525 return ResponseEntity.ok(getResourceHotSlideDTO);
526 }
527
528 /**
529 * 获取热门资源趋势图
530 *
531 * @return 获取热门资源趋势图结果
532 */
533 @GetMapping("/hot-trend")
534 public ResponseEntity<GetResourceHotTrendDTO> getResourceHotTrend() {
535 List<HotTrend> hotTrendList = hotTrendService.list();
536 GetResourceHotTrendDTO getResourceHotTrendDTO = new GetResourceHotTrendDTO(hotTrendList);
537 return ResponseEntity.ok(getResourceHotTrendDTO);
538 }
539
540 /**
541 * 修改资源信息
542 *
543 * @param putResourceInfoDTO 要修改的资源信息
544 * @return 修改资源信息结果
545 */
546 @PutMapping("/info")
547 public ResponseEntity<String> putResourceInfo(@RequestBody PutResourceInfoDTO putResourceInfoDTO) {
548 // 检查资源名是否重复
549 QueryWrapper<Resource> resourceQuery = new QueryWrapper<>();
550 resourceQuery.ne("resource_id", putResourceInfoDTO.getResourceId()).eq("resource_name", putResourceInfoDTO.getResourceName());
551 Resource resource = resourceService.getOne(resourceQuery);
552
553 if (resource != null) {
554 // 资源名重复
555 logger.warn("Modification attempt failed. Resource name already exists: {}", putResourceInfoDTO.getResourceName());
556 return ResponseEntity.status(411).body("");
557 }
558
559 UpdateWrapper<Resource> resourceUpdate = new UpdateWrapper<>();
560 resourceUpdate.eq("resource_id", putResourceInfoDTO.getResourceId())
561 .set("resource_name", putResourceInfoDTO.getResourceName())
562 .set("resource_picture", putResourceInfoDTO.getResourcePicture())
563 .set("resource_summary", putResourceInfoDTO.getResourceSummary())
564 .set("resource_detail", putResourceInfoDTO.getResourceDetail())
565 .set("price", putResourceInfoDTO.getPrice());
566 resourceService.update(resourceUpdate);
567
568 QueryWrapper<Gameplay> gameplayQuery = new QueryWrapper<>();
569 gameplayQuery.eq("resource_id", putResourceInfoDTO.getResourceId());
570 gameplayService.remove(gameplayQuery);
571
572 for (int i = 0; i < putResourceInfoDTO.getGameplayList().length; i++) {
573 Gameplay gameplay = new Gameplay();
574 gameplay.setGameplayName(putResourceInfoDTO.getGameplayList()[i]);
575 gameplay.setResourceId(putResourceInfoDTO.getResourceId());
576 gameplayService.save(gameplay);
577 }
578
579 return ResponseEntity.ok("");
580 }
xiukiradbe96222025-06-06 21:25:09 +0800581}