package com.openisle.controller; import com.openisle.dto.PostDetailDto; import com.openisle.dto.PostRequest; import com.openisle.dto.PostSummaryDto; import com.openisle.mapper.PostMapper; import com.openisle.model.Post; import com.openisle.service.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.stream.Collectors; @RestController @RequestMapping("/api/posts") @RequiredArgsConstructor public class PostController { private final PostService postService; private final LevelService levelService; private final CaptchaService captchaService; private final DraftService draftService; private final UserVisitService userVisitService; private final PostMapper postMapper; private final PointService pointService; @Value("${app.captcha.enabled:false}") private boolean captchaEnabled; @Value("${app.captcha.post-enabled:false}") private boolean postCaptchaEnabled; @PostMapping public ResponseEntity createPost(@RequestBody PostRequest req, Authentication auth) { if (captchaEnabled && postCaptchaEnabled && !captchaService.verify(req.getCaptcha())) { return ResponseEntity.badRequest().build(); } Post post = postService.createPost(auth.getName(), req.getCategoryId(), req.getTitle(), req.getContent(), req.getTagIds(), req.getType(), req.getPrizeDescription(), req.getPrizeIcon(), req.getPrizeCount(), req.getStartTime(), req.getEndTime()); draftService.deleteDraft(auth.getName()); PostDetailDto dto = postMapper.toDetailDto(post, auth.getName()); dto.setReward(levelService.awardForPost(auth.getName())); dto.setPointReward(pointService.awardForPost(auth.getName(), post.getId())); return ResponseEntity.ok(dto); } @PutMapping("/{id}") public ResponseEntity updatePost(@PathVariable Long id, @RequestBody PostRequest req, Authentication auth) { Post post = postService.updatePost(id, auth.getName(), req.getCategoryId(), req.getTitle(), req.getContent(), req.getTagIds()); return ResponseEntity.ok(postMapper.toDetailDto(post, auth.getName())); } @DeleteMapping("/{id}") public void deletePost(@PathVariable Long id, Authentication auth) { postService.deletePost(id, auth.getName()); } @PostMapping("/{id}/close") public PostSummaryDto close(@PathVariable Long id, Authentication auth) { return postMapper.toSummaryDto(postService.closePost(id, auth.getName())); } @PostMapping("/{id}/reopen") public PostSummaryDto reopen(@PathVariable Long id, Authentication auth) { return postMapper.toSummaryDto(postService.reopenPost(id, auth.getName())); } @GetMapping("/{id}") public ResponseEntity getPost(@PathVariable Long id, Authentication auth) { String viewer = auth != null ? auth.getName() : null; Post post = postService.viewPost(id, viewer); return ResponseEntity.ok(postMapper.toDetailDto(post, viewer)); } @PostMapping("/{id}/lottery/join") public ResponseEntity joinLottery(@PathVariable Long id, Authentication auth) { postService.joinLottery(id, auth.getName()); return ResponseEntity.ok().build(); } @GetMapping public List listPosts(@RequestParam(value = "categoryId", required = false) Long categoryId, @RequestParam(value = "categoryIds", required = false) List categoryIds, @RequestParam(value = "tagId", required = false) Long tagId, @RequestParam(value = "tagIds", required = false) List tagIds, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "pageSize", required = false) Integer pageSize, Authentication auth) { List ids = categoryIds; if (categoryId != null) { ids = java.util.List.of(categoryId); } List tids = tagIds; if (tagId != null) { tids = java.util.List.of(tagId); } if (auth != null) { userVisitService.recordVisit(auth.getName()); } boolean hasCategories = ids != null && !ids.isEmpty(); boolean hasTags = tids != null && !tids.isEmpty(); if (hasCategories && hasTags) { return postService.listPostsByCategoriesAndTags(ids, tids, page, pageSize) .stream().map(postMapper::toSummaryDto).collect(Collectors.toList()); } if (hasTags) { return postService.listPostsByTags(tids, page, pageSize) .stream().map(postMapper::toSummaryDto).collect(Collectors.toList()); } return postService.listPostsByCategories(ids, page, pageSize) .stream().map(postMapper::toSummaryDto).collect(Collectors.toList()); } @GetMapping("/ranking") public List rankingPosts(@RequestParam(value = "categoryId", required = false) Long categoryId, @RequestParam(value = "categoryIds", required = false) List categoryIds, @RequestParam(value = "tagId", required = false) Long tagId, @RequestParam(value = "tagIds", required = false) List tagIds, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "pageSize", required = false) Integer pageSize, Authentication auth) { List ids = categoryIds; if (categoryId != null) { ids = java.util.List.of(categoryId); } List tids = tagIds; if (tagId != null) { tids = java.util.List.of(tagId); } if (auth != null) { userVisitService.recordVisit(auth.getName()); } return postService.listPostsByViews(ids, tids, page, pageSize) .stream().map(postMapper::toSummaryDto).collect(Collectors.toList()); } @GetMapping("/latest-reply") public List latestReplyPosts(@RequestParam(value = "categoryId", required = false) Long categoryId, @RequestParam(value = "categoryIds", required = false) List categoryIds, @RequestParam(value = "tagId", required = false) Long tagId, @RequestParam(value = "tagIds", required = false) List tagIds, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "pageSize", required = false) Integer pageSize, Authentication auth) { List ids = categoryIds; if (categoryId != null) { ids = java.util.List.of(categoryId); } List tids = tagIds; if (tagId != null) { tids = java.util.List.of(tagId); } if (auth != null) { userVisitService.recordVisit(auth.getName()); } return postService.listPostsByLatestReply(ids, tids, page, pageSize) .stream().map(postMapper::toSummaryDto).collect(Collectors.toList()); } @GetMapping("/featured") public List featuredPosts(@RequestParam(value = "categoryId", required = false) Long categoryId, @RequestParam(value = "categoryIds", required = false) List categoryIds, @RequestParam(value = "tagId", required = false) Long tagId, @RequestParam(value = "tagIds", required = false) List tagIds, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "pageSize", required = false) Integer pageSize, Authentication auth) { List ids = categoryIds; if (categoryId != null) { ids = java.util.List.of(categoryId); } List tids = tagIds; if (tagId != null) { tids = java.util.List.of(tagId); } if (auth != null) { userVisitService.recordVisit(auth.getName()); } return postService.listFeaturedPosts(ids, tids, page, pageSize) .stream().map(postMapper::toSummaryDto).collect(Collectors.toList()); } }