diff --git a/src/main/java/meltingpot/server/comment/controller/CommentController.java b/src/main/java/meltingpot/server/comment/controller/CommentController.java index 9c82896..b842ae8 100644 --- a/src/main/java/meltingpot/server/comment/controller/CommentController.java +++ b/src/main/java/meltingpot/server/comment/controller/CommentController.java @@ -56,11 +56,22 @@ public ResponseEntity> getCommentsList (@Curr @RequestParam(required = false) Long cursor, @RequestParam(defaultValue = "10") int pageSize){ try{ - return ResponseData.toResponseEntity(ResponseCode.READ_COMMENTS_LIST_SUCCESS, commentService.getCommentsList(account,postId,cursor,pageSize)); + return ResponseData.toResponseEntity(ResponseCode.READ_COMMENTS_LIST_SUCCESS, commentService.getCommentsList(account, postId, cursor,pageSize)); }catch (NoSuchElementException e) { return ResponseData.toResponseEntity(ResponseCode.READ_COMMENT_FAIL, null); } } + + @Operation (summary = "댓글 삭제하기") + @DeleteMapping("{commentId}") + public ResponseEntity createComment( @CurrentUser Account account, @PathVariable Long commentId) { + try { + return ResponseData.toResponseEntity(commentService.deleteComment(commentId,account)); + } catch (NoSuchElementException e) { + return ResponseData.toResponseEntity(ResponseCode.COMMENT_DELETE_FAIL); + } + } + } diff --git a/src/main/java/meltingpot/server/comment/dto/CommentsListResponse.java b/src/main/java/meltingpot/server/comment/dto/CommentsListResponse.java index 4b2e048..589a6f0 100644 --- a/src/main/java/meltingpot/server/comment/dto/CommentsListResponse.java +++ b/src/main/java/meltingpot/server/comment/dto/CommentsListResponse.java @@ -37,9 +37,9 @@ public static CommentDetail from(Comment comment) { return CommentDetail.builder() .commentId(comment.getId()) .parentId(comment.getParent() != null ? comment.getParent().getId() : null) - .userId(comment.getAccount().getId()) + .userId(comment.getAccount()!= null ? comment.getAccount().getId() : null) .content(comment.getContent()) - .name(comment.getAccount().getName()) + .name(comment.getAccount() != null? comment.getAccount().getName() : null) .isAnonymous(comment.getIsAnonymous()) .imageUrl(comment.getCommentImage() != null ? comment.getCommentImage().getImageUrl() : null) .updatedAt(comment.getUpdatedAt()) diff --git a/src/main/java/meltingpot/server/comment/service/CommentService.java b/src/main/java/meltingpot/server/comment/service/CommentService.java index 4b2b359..9cc4049 100644 --- a/src/main/java/meltingpot/server/comment/service/CommentService.java +++ b/src/main/java/meltingpot/server/comment/service/CommentService.java @@ -16,11 +16,11 @@ import org.springframework.data.domain.PageRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - +import org.springframework.web.server.ResponseStatusException; import java.util.*; -import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -131,8 +131,10 @@ public ResponseCode updateComment(CommentCreateRequest updateCommentDTO, Account // // return CommentsListResponse.from(commentDetailDTOs,nextCursor,isLast); // } - + /* 댓글 목록 불러오기 */ + @Transactional(readOnly = true) public CommentsListResponse getCommentsList(Account account, Long postId, Long cursor, int pageSize) { + Post post = findPostById(postId); List commentDetailDTOs = new ArrayList<>(); int count = 0; Long parentCursor = null; @@ -192,7 +194,40 @@ public CommentsListResponse getCommentsList(Account account, Long postId, Long c } + /* 댓글 삭제하기 */ + @Transactional + public ResponseCode deleteComment(Long commentId, Account account) { + Comment comment = findCommentById(commentId); + + if (!comment.getAccount().getId().equals(account.getId())) { + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "삭제 권한이 없습니다."); + } + if (comment.getParent() == null) { + comment.setContent("삭제된 댓글입니다."); + comment.setAccount(null); + comment.setIsAnonymous(true); + + if (comment.getCommentImage() != null) { + CommentImage commentImage = comment.getCommentImage(); + comment.setCommentImage(null); + commentImageRepository.delete(commentImage); + } + // 자식 댓글이 남아있지 않으면 부모 댓글도 삭제 + if (comment.getChildren().isEmpty()) { + commentRepository.delete(comment); + } + + } else { + Comment parentComment = comment.getParent(); + commentRepository.delete(comment); + parentComment.getChildren().remove(comment); + if (parentComment.getChildren().isEmpty()) { + commentRepository.delete(parentComment); + } + } + return ResponseCode.COMMENT_DELETE_SUCCESS; + } private Comment findCommentById(Long commentId) { return commentRepository.findById(commentId) diff --git a/src/main/java/meltingpot/server/domain/entity/comment/Comment.java b/src/main/java/meltingpot/server/domain/entity/comment/Comment.java index 8646bef..2c763db 100644 --- a/src/main/java/meltingpot/server/domain/entity/comment/Comment.java +++ b/src/main/java/meltingpot/server/domain/entity/comment/Comment.java @@ -80,6 +80,14 @@ public void setContent(String content) { this.content = content; } + public void setAccount(Account account) { + this.account = account; + } + + public void setIsAnonymous (Boolean isAnonymous) { + this.isAnonymous = isAnonymous; + } + public Comment getParent() { return parent;} diff --git a/src/main/java/meltingpot/server/post/controller/PostController.java b/src/main/java/meltingpot/server/post/controller/PostController.java index 389ad94..5d917f0 100644 --- a/src/main/java/meltingpot/server/post/controller/PostController.java +++ b/src/main/java/meltingpot/server/post/controller/PostController.java @@ -5,6 +5,9 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; +import meltingpot.server.domain.entity.comment.Comment; +import meltingpot.server.domain.entity.post.Post; +import meltingpot.server.domain.repository.CommentRepository; import meltingpot.server.post.dto.PostDetailResponse; import meltingpot.server.post.dto.PostsListResponse; import org.springframework.http.ResponseEntity; @@ -51,7 +54,7 @@ public ResponseEntity updatePost(@CurrentUser Account account,@Pat @ApiResponse(responseCode = "OK", description = "커뮤니티 글 목록 조회 성공"), @ApiResponse(responseCode = "NOT_FOUND", description = "커뮤니티 글을 찾을 수 없습니다") }) - public ResponseEntity> getPostList(@CurrentUser Account account, @PathVariable PostType postType , @RequestParam(name = "cursor") Long cursor, @RequestParam(name = "pageSize") Integer pageSize) { + public ResponseEntity> getPostList(@CurrentUser Account account, @PathVariable PostType postType , @RequestParam(required = false, name = "cursor") Long cursor, @RequestParam(name = "pageSize") Integer pageSize) { try { return ResponseData.toResponseEntity(ResponseCode.POST_LIST_FETCH_SUCCESS, postService.getPostsList(account,postType, cursor, pageSize)); } catch (NoSuchElementException e) { @@ -61,11 +64,23 @@ public ResponseEntity> getPostList(@CurrentUser @GetMapping("/{postId}") @Operation(summary = "커뮤니티 글 내용 조회", description = "postId로 커뮤니티 글 내용을 조회합니다.") - public ResponseEntity> getPostDetail(@CurrentUser Account account, @PathVariable Long postId, @RequestParam(name = "cursor") Long cursor, @RequestParam(name = "pageSize") Integer pageSize) { + public ResponseEntity> getPostDetail(@CurrentUser Account account, @PathVariable Long postId, @RequestParam(required = false, name = "cursor") Long cursor, @RequestParam(name = "pageSize") Integer pageSize) { try{ return ResponseData.toResponseEntity(ResponseCode.POST_DETAIL_FETCH_SUCCEESS,postService.getPostDetail(postId,cursor, pageSize)); }catch (NoSuchElementException e) { return ResponseData.toResponseEntity(ResponseCode.POST_NOT_FOUND, null); } } + + + @DeleteMapping("/{postId}") + @Operation(summary = "커뮤니티 글 삭제", description = "postId로 커뮤니티 글 삭제") + public ResponseEntity deletePost(@CurrentUser Account account,@PathVariable Long postId) { + try { + return ResponseData.toResponseEntity(postService.deletePost(postId, account)); + } catch (NoSuchElementException e) { + return ResponseData.toResponseEntity(ResponseCode.POST_DELETE_FAIL); + } + } + } diff --git a/src/main/java/meltingpot/server/post/service/PostService.java b/src/main/java/meltingpot/server/post/service/PostService.java index e2622b8..4391b32 100644 --- a/src/main/java/meltingpot/server/post/service/PostService.java +++ b/src/main/java/meltingpot/server/post/service/PostService.java @@ -92,6 +92,27 @@ public PostsListResponse getPostsList(Account account, PostType postType, Long return PostsListResponse.from(posts, nextCursor, isLast); } + /*post 삭제하기*/ + public ResponseCode deletePost(Long postId, Account account){ + Post post = findPostById(postId); + Account postAccount = findAccountById(post.getAccount().getId()); + + // 게시물에 연관된 이미지 삭제 + if (!post.getPostImages().isEmpty()) { + postImageRepository.deleteAll(post.getPostImages()); + } + + // 게시물에 연관된 댓글 삭제 + if (!post.getComments().isEmpty()) { + commentRepository.deleteAll(post.getComments()); + } + + // 게시물 삭제 + postRepository.delete(post); + + return ResponseCode.POST_DELETE_SUCCESS; + + } private Account findAccountById(Long accountId) { diff --git a/src/main/java/meltingpot/server/util/ResponseCode.java b/src/main/java/meltingpot/server/util/ResponseCode.java index 7ae42d1..9aa2556 100644 --- a/src/main/java/meltingpot/server/util/ResponseCode.java +++ b/src/main/java/meltingpot/server/util/ResponseCode.java @@ -29,6 +29,7 @@ public enum ResponseCode { SOCKET_TOKEN_GET_SUCCESS(OK, "소켓 토큰 조회 성공"), POST_LIST_FETCH_SUCCESS(OK, "게시글 목록 불러오기 성공"), POST_DETAIL_FETCH_SUCCEESS(OK, "게시글 내용 불러오기 성공"), + POST_DELETE_SUCCESS(OK, "게시글 삭제하기 성공"), CHAT_ROOM_USER_DELETE_SUCCESS(OK, "채팅방 나가기 성공"), CHAT_ALARM_UPDATE_SUCCESS(OK, "채팅 알림 설정 수정 성공"), @@ -51,6 +52,7 @@ public enum ResponseCode { UPDATE_POST_SUCCESS(OK,"게시물 수정 성공"), UPDATE_COMMENT_SUCCESS(OK, "댓글 수정 성공"), READ_COMMENTS_LIST_SUCCESS(OK,"댓글 목록 불러오기 성공"), + COMMENT_DELETE_SUCCESS(OK, "댓글 삭제하기 성공"), @@ -90,9 +92,11 @@ public enum ResponseCode { DESTINATION_NOT_VALID(BAD_REQUEST, "잘못된 목적지로 접근하였습니다"), COMMENT_CREATE_FAIL(BAD_REQUEST, "댓글 작성 실패 "), COMMENT_UPDATE_FAIL(BAD_REQUEST, "댓글 수정 실패 "), + COMMENT_DELETE_FAIL(BAD_REQUEST,"댓글 삭제 실패"), READ_COMMENT_FAIL(BAD_REQUEST, "댓글 불러오기 실패 "), POST_CREATE_FAIL(BAD_REQUEST, "게시글 작성 실패"), POST_UPDATE_FAIL(BAD_REQUEST,"게시글 수정 실패"), + POST_DELETE_FAIL(BAD_REQUEST,"게시글 삭제 실패"), REPORT_CREATE_FAIL(BAD_REQUEST, "신고 작성 실패"), AREA_FETCH_FAILED(BAD_REQUEST, "지역 조회 실패"), AREA_FETCH_FAILED_NOT_SERVICE_AREA(BAD_REQUEST, "현재 좌표 조회는 국내에서만 사용 가능합니다"),