From 29d35fd4d2a12d0dbad77ac67815fd8a2caa2357 Mon Sep 17 00:00:00 2001 From: lehojun Date: Wed, 21 May 2025 14:23:48 +0900 Subject: [PATCH] =?UTF-8?q?[FEAT]=20#25=20=EB=8C=93=EA=B8=80=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apiPayload/code/status/ErrorStatus.java | 4 +- .../be/repository/CommentRepository.java | 9 +++ .../be/service/CommentServiceImpl.java | 66 +++++++++++++++++++ .../be/web/controller/CommentController.java | 30 +++++++++ .../com/example/be/web/dto/CommentDTO.java | 21 ++++++ .../java/com/example/be/web/dto/PostDTO.java | 2 + 6 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/be/repository/CommentRepository.java create mode 100644 src/main/java/com/example/be/service/CommentServiceImpl.java create mode 100644 src/main/java/com/example/be/web/controller/CommentController.java create mode 100644 src/main/java/com/example/be/web/dto/CommentDTO.java diff --git a/src/main/java/com/example/be/apiPayload/code/status/ErrorStatus.java b/src/main/java/com/example/be/apiPayload/code/status/ErrorStatus.java index b50f27c..bdca8d7 100644 --- a/src/main/java/com/example/be/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/com/example/be/apiPayload/code/status/ErrorStatus.java @@ -25,8 +25,10 @@ public enum ErrorStatus implements BaseErrorCode { _NOT_FOUND_COOKIE(HttpStatus.NOT_FOUND, "USER403", "쿠키가 없습니다."), //게시글 관련 에러 - _NOT_FOUND_POST(HttpStatus.NOT_FOUND, "POST401", "해당 게시글을 찾을 수 없습니다."); + _NOT_FOUND_POST(HttpStatus.NOT_FOUND, "POST401", "해당 게시글을 찾을 수 없습니다."), + //댓글 관련 에러 + _NOT_FOUND_COMMENT(HttpStatus.NOT_FOUND, "COMMENT404", "해당 댓글을 찾을 수 없습니다."); private final HttpStatus httpStatus; private final String code; diff --git a/src/main/java/com/example/be/repository/CommentRepository.java b/src/main/java/com/example/be/repository/CommentRepository.java new file mode 100644 index 0000000..20e1ad0 --- /dev/null +++ b/src/main/java/com/example/be/repository/CommentRepository.java @@ -0,0 +1,9 @@ +package com.example.be.repository; + +import com.example.be.domain.Comment; +import com.example.be.domain.Post; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CommentRepository extends JpaRepository { + +} diff --git a/src/main/java/com/example/be/service/CommentServiceImpl.java b/src/main/java/com/example/be/service/CommentServiceImpl.java new file mode 100644 index 0000000..d305d7d --- /dev/null +++ b/src/main/java/com/example/be/service/CommentServiceImpl.java @@ -0,0 +1,66 @@ +package com.example.be.service; + +import com.example.be.apiPayload.code.status.ErrorStatus; +import com.example.be.apiPayload.exception.handler.UserHandler; +import com.example.be.domain.Comment; +import com.example.be.domain.Post; +import com.example.be.domain.User; +import com.example.be.repository.CommentRepository; +import com.example.be.repository.PostRepository; +import com.example.be.repository.UserRepository; +import com.example.be.web.dto.CommentDTO; +import com.example.be.web.dto.CommonDTO; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class CommentServiceImpl { + + private final JwtUtilServiceImpl jwtUtilService; + private final UserRepository userRepository; + private final PostRepository postRepository; + private final CommentRepository commentRepository; + + @Transactional + public CommonDTO.IsSuccessDTO createComment(CommentDTO.CommentRequestDTO requestDTO, HttpServletRequest request) { + String accessToken = jwtUtilService.extractTokenFromCookie(request, "accessToken"); + if (accessToken == null) { + throw new UserHandler(ErrorStatus._NOT_FOUND_USER); + } + + String userId = jwtUtilService.getUserIdFromToken(accessToken); + User user = userRepository.findByUserId(UUID.fromString(userId)) + .orElseThrow(() -> new UserHandler(ErrorStatus._NOT_FOUND_USER)); + + Post post = postRepository.findById(requestDTO.getPostId()) + .orElseThrow(() -> new UserHandler(ErrorStatus._NOT_FOUND_POST)); + + Comment comment = Comment.builder() + .comment(requestDTO.getComment()) + .createDate(LocalDateTime.now()) + .user(user) + .post(post) + .build(); + + // 대댓글인 경우 상위 댓글 설정 + if (requestDTO.getParentCommentId() != null) { + Comment parentComment = commentRepository.findById(requestDTO.getParentCommentId()) + .orElseThrow(() -> new RuntimeException("상위 댓글을 찾을 수 없습니다.")); + + if (parentComment.getTopParent() != null) { + comment.setTopParent(parentComment.getTopParent()); + } else { + comment.setTopParent(parentComment); + } + } + + commentRepository.save(comment); + return CommonDTO.IsSuccessDTO.builder().isSuccess(true).build(); + } +} diff --git a/src/main/java/com/example/be/web/controller/CommentController.java b/src/main/java/com/example/be/web/controller/CommentController.java new file mode 100644 index 0000000..c4da8b1 --- /dev/null +++ b/src/main/java/com/example/be/web/controller/CommentController.java @@ -0,0 +1,30 @@ +package com.example.be.web.controller; + +import com.example.be.apiPayload.ApiResponse; +import com.example.be.service.CommentServiceImpl; +import com.example.be.service.PostServiceImpl; +import com.example.be.web.dto.CommentDTO; +import com.example.be.web.dto.CommonDTO; +import io.swagger.v3.oas.annotations.Operation; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/comment") +@RequiredArgsConstructor +public class CommentController { + private final PostServiceImpl postService; + private final CommentServiceImpl commentService; + + @PostMapping("") + @Operation(summary = "댓글 작성 API", description = "게시글에 댓글을 작성하거나 다른 댓글에 대한 답글을 작성합니다.") + public ApiResponse createComment( + @RequestBody CommentDTO.CommentRequestDTO requestDTO, + HttpServletRequest request) { + return ApiResponse.onSuccess(commentService.createComment(requestDTO, request)); + } +} diff --git a/src/main/java/com/example/be/web/dto/CommentDTO.java b/src/main/java/com/example/be/web/dto/CommentDTO.java new file mode 100644 index 0000000..338e237 --- /dev/null +++ b/src/main/java/com/example/be/web/dto/CommentDTO.java @@ -0,0 +1,21 @@ +package com.example.be.web.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public class CommentDTO { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + @Schema(description = "댓글 작성 요청 DTO") + public static class CommentRequestDTO { + private String comment; + private Long postId; + private Long parentCommentId; + } +} diff --git a/src/main/java/com/example/be/web/dto/PostDTO.java b/src/main/java/com/example/be/web/dto/PostDTO.java index 2e7c738..f346a87 100644 --- a/src/main/java/com/example/be/web/dto/PostDTO.java +++ b/src/main/java/com/example/be/web/dto/PostDTO.java @@ -86,4 +86,6 @@ public static class PostDetailResponseDTO { private int commentCount; private List comments; } + + }