-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
445109c
commit be598ff
Showing
9 changed files
with
233 additions
and
20 deletions.
There are no files selected for viewing
47 changes: 33 additions & 14 deletions
47
src/main/java/com/codiary/backend/domain/comment/controller/CommentController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,68 @@ | ||
package com.codiary.backend.domain.comment.controller; | ||
|
||
import com.codiary.backend.domain.comment.converter.CommentConverter; | ||
import com.codiary.backend.domain.comment.dto.request.CommentRequestDTO; | ||
import com.codiary.backend.domain.comment.dto.response.CommentResponseDTO; | ||
import com.codiary.backend.domain.comment.entity.Comment; | ||
import com.codiary.backend.domain.comment.service.CommentService; | ||
import com.codiary.backend.domain.member.security.CustomMemberDetails; | ||
import com.codiary.backend.global.apiPayload.ApiResponse; | ||
import com.codiary.backend.global.apiPayload.code.status.SuccessStatus; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.web.PageableDefault; | ||
import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
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; | ||
|
||
@RequiredArgsConstructor | ||
@RestController | ||
@RequestMapping("/api/v2/posts/{post_id}/comments") | ||
@RequestMapping("/api/v2/posts") | ||
@Tag(name = "댓글 API", description = "댓글 관련 API 입니다.") | ||
public class CommentController { | ||
|
||
private final CommentService commentService; | ||
|
||
@Operation(summary = "댓글 달기") | ||
@PostMapping() | ||
public ApiResponse<?> commentPost(@PathVariable("post_id") Long postId) { | ||
return null; | ||
@PostMapping("/posts/{post_id}/comments") | ||
public ApiResponse<CommentResponseDTO.CommentDTO> commentOnPost( | ||
@PathVariable("post_id") Long postId, | ||
@RequestBody CommentRequestDTO.CreateCommentDTO request, | ||
@AuthenticationPrincipal CustomMemberDetails memberDetails | ||
) { | ||
Long commenterId = memberDetails.getId(); | ||
Comment newComment = commentService.commentOnPost(postId, commenterId, request); | ||
return ApiResponse.onSuccess(SuccessStatus.COMMENT_OK, CommentConverter.toCommentResponseDto(newComment)); | ||
} | ||
|
||
@Operation(summary = "댓글 삭제") | ||
@DeleteMapping("/{comment_id}") | ||
public ApiResponse<?> deleteComment( | ||
@PathVariable("post_id") Long postId, | ||
@PathVariable("comment_id") Long commentId | ||
@DeleteMapping("comments/{comment_id}") | ||
public ApiResponse<String> deleteComment( | ||
@PathVariable("comment_id") Long commentId, | ||
@AuthenticationPrincipal CustomMemberDetails memberDetails | ||
) { | ||
return null; | ||
Long memberId = memberDetails.getId(); | ||
String response = commentService.deleteComment(commentId, memberId); | ||
return ApiResponse.onSuccess(SuccessStatus.COMMENT_OK, response); | ||
} | ||
|
||
@Operation(summary = "댓글 조회", description = "기본적으로 10개씩 페이지네이션 하여 제공됩니다.") | ||
@GetMapping("/{comment_id}") | ||
public ApiResponse<?> getComments( | ||
@Operation(summary = "댓글 조회", description = "기본적으로 10개씩 페이지네이션하여 제공됩니다.") | ||
@GetMapping("/posts/{post_id}/comments") | ||
public ApiResponse<List<CommentResponseDTO.CommentDTO>> getComments( | ||
@PathVariable("post_id") Long postId, | ||
@PathVariable("comment_id") Long commentId, | ||
@AuthenticationPrincipal CustomMemberDetails memberDetails, | ||
@PageableDefault(size = 10) Pageable pageable | ||
) { | ||
return null; | ||
Long memberId = memberDetails.getId(); | ||
List<Comment> comments = commentService.getComments(postId, memberId, pageable); | ||
return ApiResponse.onSuccess(SuccessStatus.COMMENT_OK, CommentConverter.toCommentResponseListDto(comments)); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/com/codiary/backend/domain/comment/converter/CommentConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.codiary.backend.domain.comment.converter; | ||
|
||
import com.codiary.backend.domain.comment.dto.response.CommentResponseDTO; | ||
import com.codiary.backend.domain.comment.entity.Comment; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class CommentConverter { | ||
|
||
public static CommentResponseDTO.CommentDTO toCommentResponseDto(Comment comment) { | ||
return CommentResponseDTO.CommentDTO.builder() | ||
.commentId(comment.getCommentId()) | ||
.commentBody(comment.getCommentBody()) | ||
.postId(comment.getPost().getPostId()) | ||
.commenterId(comment.getMember().getMemberId()) | ||
.commenterProfileImageUrl( | ||
(comment.getMember().getImage() != null) ? (comment.getMember().getImage().getImageUrl()) : "") | ||
.commenterNickname(comment.getMember().getNickname()) | ||
.createdAt(comment.getCreatedAt()) | ||
.updatedAt(comment.getUpdatedAt()) | ||
.build(); | ||
} | ||
|
||
public static List<CommentResponseDTO.CommentDTO> toCommentResponseListDto(List<Comment> comments) { | ||
return comments.stream() | ||
.map(CommentConverter::toCommentResponseDto) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/codiary/backend/domain/comment/dto/request/CommentRequestDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.codiary.backend.domain.comment.dto.request; | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.fasterxml.jackson.databind.PropertyNamingStrategies; | ||
import com.fasterxml.jackson.databind.annotation.JsonNaming; | ||
import lombok.Builder; | ||
|
||
public class CommentRequestDTO { | ||
|
||
// Comment 생성 DTO | ||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) | ||
@Builder | ||
public record CreateCommentDTO( | ||
String commentBody | ||
) { | ||
} | ||
|
||
} |
25 changes: 25 additions & 0 deletions
25
src/main/java/com/codiary/backend/domain/comment/dto/response/CommentResponseDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.codiary.backend.domain.comment.dto.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.fasterxml.jackson.databind.PropertyNamingStrategies; | ||
import com.fasterxml.jackson.databind.annotation.JsonNaming; | ||
import java.time.LocalDateTime; | ||
import lombok.Builder; | ||
|
||
public class CommentResponseDTO { | ||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) | ||
@Builder | ||
public record CommentDTO( | ||
Long commentId, | ||
String commentBody, | ||
Long postId, | ||
Long commenterId, | ||
String commenterProfileImageUrl, | ||
String commenterNickname, | ||
LocalDateTime createdAt, | ||
LocalDateTime updatedAt | ||
) { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/main/java/com/codiary/backend/domain/comment/repository/CommentRepositoryCustom.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.codiary.backend.domain.comment.repository; | ||
|
||
import com.codiary.backend.domain.comment.entity.Comment; | ||
import java.util.List; | ||
import org.springframework.data.domain.Pageable; | ||
|
||
public interface CommentRepositoryCustom { | ||
|
||
List<Comment> findByPostWithMemberInfoOrderByCreatedAtDesc(Long postId, Pageable pageable); | ||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/com/codiary/backend/domain/comment/repository/CommentRepositoryImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.codiary.backend.domain.comment.repository; | ||
|
||
import static com.codiary.backend.domain.comment.entity.QComment.comment; | ||
import static com.codiary.backend.domain.member.entity.QMember.member; | ||
import static com.codiary.backend.domain.post.entity.QPost.post; | ||
|
||
import com.codiary.backend.domain.comment.entity.Comment; | ||
import com.querydsl.jpa.impl.JPAQueryFactory; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.data.domain.Pageable; | ||
|
||
@RequiredArgsConstructor | ||
public class CommentRepositoryImpl implements CommentRepositoryCustom { | ||
|
||
private final JPAQueryFactory queryFactory; | ||
|
||
@Override | ||
public List<Comment> findByPostWithMemberInfoOrderByCreatedAtDesc(Long postId, Pageable pageable) { | ||
List<Comment> comments = queryFactory | ||
.selectFrom(comment) | ||
.leftJoin(comment.member, member) | ||
.leftJoin(comment.post, post) | ||
.where(comment.post.postId.eq(postId)) | ||
.offset(pageable.getOffset()) | ||
.limit(pageable.getPageSize()) | ||
.fetch(); | ||
|
||
return comments; | ||
} | ||
} |
64 changes: 63 additions & 1 deletion
64
src/main/java/com/codiary/backend/domain/comment/service/CommentService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,76 @@ | ||
package com.codiary.backend.domain.comment.service; | ||
|
||
import com.codiary.backend.domain.comment.dto.request.CommentRequestDTO; | ||
import com.codiary.backend.domain.comment.entity.Comment; | ||
import com.codiary.backend.domain.comment.repository.CommentRepository; | ||
import com.codiary.backend.domain.member.entity.Member; | ||
import com.codiary.backend.domain.member.repository.MemberRepository; | ||
import com.codiary.backend.domain.post.entity.Post; | ||
import com.codiary.backend.domain.post.repository.PostRepository; | ||
import com.codiary.backend.global.apiPayload.code.status.ErrorStatus; | ||
import com.codiary.backend.global.apiPayload.exception.GeneralException; | ||
import com.codiary.backend.global.apiPayload.exception.handler.MemberHandler; | ||
import com.codiary.backend.global.apiPayload.exception.handler.PostHandler; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
@Transactional | ||
public class CommentService { | ||
|
||
private final CommentRepository commentRepository; | ||
private final MemberRepository memberRepository; | ||
private final PostRepository postRepository; | ||
|
||
public Comment commentOnPost(Long postId, Long commenterId, CommentRequestDTO.CreateCommentDTO request) { | ||
// validation: 사용자, post 유무 확인 | ||
// + 사용자가 해당 게시물에 대한 댓글 권한 있는지( 이후 구현 ) | ||
Member commenter = memberRepository.findById(commenterId) | ||
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); | ||
Post post = postRepository.findById(postId).orElseThrow(() -> new PostHandler(ErrorStatus.POST_NOT_FOUND)); | ||
|
||
// business logic: 댓글 생성 | ||
Comment comment = Comment.builder() | ||
.commentBody(request.commentBody()) | ||
.member(commenter) | ||
.post(post) | ||
.build(); | ||
|
||
// response: 댓글 반환 | ||
return commentRepository.save(comment); | ||
} | ||
|
||
public String deleteComment(Long commentId, Long memberId) { | ||
// validation: 사용자, comment 유무 확인 | ||
// + 사용자가 해당 댓글에 대한 댓글 권한 있는지( 이후 구현 ) | ||
Member commenter = memberRepository.findById(memberId) | ||
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); | ||
Comment comment = commentRepository.findById(commentId) | ||
.orElseThrow(() -> new GeneralException(ErrorStatus.COMMENT_NOT_FOUND)); | ||
|
||
// business logic: 댓글 삭제 | ||
commentRepository.delete(comment); | ||
|
||
// response: 삭제 성공 반환 | ||
return "성공적으로 삭제되었습니다!"; | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public List<Comment> getComments(Long postId, Long memberId, Pageable pageable) { | ||
// validation: 사용자, post 유무 확인 | ||
// + 사용자가 해당 게시물에 대한 읽기 권한 있는지( 이후 구현 ) | ||
Member commenter = memberRepository.findById(memberId) | ||
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); | ||
Post post = postRepository.findById(postId).orElseThrow(() -> new PostHandler(ErrorStatus.POST_NOT_FOUND)); | ||
|
||
// business logic: 댓글 조회 | ||
List<Comment> comments = commentRepository.findByPostWithMemberInfoOrderByCreatedAtDesc(postId, pageable); | ||
|
||
// response: comment list 반환 | ||
return comments; | ||
} | ||
} |