-
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.
Merge branch 'develop' into 10th-Kampus-BE-41
- Loading branch information
Showing
42 changed files
with
1,009 additions
and
53 deletions.
There are no files selected for viewing
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
5 changes: 0 additions & 5 deletions
5
src/main/java/com/cotato/kampus/domain/comment/CommentStatus.java
This file was deleted.
Oops, something went wrong.
114 changes: 114 additions & 0 deletions
114
src/main/java/com/cotato/kampus/domain/comment/api/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 |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package com.cotato.kampus.domain.comment.api; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
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.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import com.cotato.kampus.domain.comment.application.CommentService; | ||
import com.cotato.kampus.domain.comment.dto.request.CommentCreateRequest; | ||
import com.cotato.kampus.domain.comment.dto.response.CommentCreateResponse; | ||
import com.cotato.kampus.domain.comment.dto.response.CommentDeleteResponse; | ||
import com.cotato.kampus.domain.comment.dto.response.CommentLikeResponse; | ||
import com.cotato.kampus.domain.comment.dto.response.CommentListResponse; | ||
import com.cotato.kampus.domain.comment.dto.response.MyCommentResponse; | ||
import com.cotato.kampus.global.common.dto.DataResponse; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import lombok.AccessLevel; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Tag(name = "댓글(Comment) API", description = "댓글 관련 API") | ||
@RestController | ||
@RequiredArgsConstructor(access = AccessLevel.PROTECTED) | ||
@RequestMapping("/v1/api") | ||
public class CommentController { | ||
|
||
private final CommentService commentService; | ||
|
||
@PostMapping("/posts/{postId}/comments") | ||
@Operation(summary = "댓글 작성", description = "특정 게시글에 댓글을 추가합니다. 대댓글일 경우 parentId에 원래 댓글의 id를 넣어주세요. (기본값 = null)") | ||
public ResponseEntity<DataResponse<CommentCreateResponse>> createComment( | ||
@PathVariable Long postId, | ||
@RequestBody CommentCreateRequest request){ | ||
|
||
return ResponseEntity.ok(DataResponse.from( | ||
CommentCreateResponse.of( | ||
commentService.createComment( | ||
postId, | ||
request.content(), | ||
request.anonymity(), | ||
request.parentId() | ||
) | ||
) | ||
) | ||
); | ||
} | ||
|
||
@DeleteMapping("/comments/{commentId}") | ||
@Operation(summary = "댓글 삭제", description = "특정 댓글을 삭제합니다.") | ||
public ResponseEntity<DataResponse<CommentDeleteResponse>> deleteComment( | ||
@PathVariable Long commentId | ||
){ | ||
|
||
return ResponseEntity.ok(DataResponse.from( | ||
CommentDeleteResponse.of( | ||
commentService.deleteComment( | ||
commentId | ||
) | ||
) | ||
) | ||
); | ||
} | ||
|
||
@PostMapping("/comments/{commentId}/like") | ||
@Operation(summary = "댓글 좋아요 추가", description = "특정 댓글에 좋아요를 추가합니다.") | ||
public ResponseEntity<DataResponse<CommentLikeResponse>> toggleLikeForComment( | ||
@PathVariable Long commentId | ||
){ | ||
|
||
return ResponseEntity.ok(DataResponse.from( | ||
CommentLikeResponse.of( | ||
commentService.likeComment( | ||
commentId | ||
) | ||
) | ||
) | ||
); | ||
} | ||
|
||
@GetMapping("/posts/{postId}/comments") | ||
@Operation(summary ="댓글 조회", description = "특정 게시글의 모든 댓글과 대댓글을 조회합니다.") | ||
public ResponseEntity<DataResponse<CommentListResponse>> getPostComments( | ||
@PathVariable Long postId | ||
){ | ||
|
||
return ResponseEntity.ok(DataResponse.from( | ||
CommentListResponse.from( | ||
commentService.findAllCommentsForPost( | ||
postId | ||
) | ||
) | ||
) | ||
); | ||
} | ||
|
||
@GetMapping("/comments/my") | ||
@Operation(summary = "내가 쓴 댓글 조회", description = "현재 사용자가 작성한 댓글을 최신순으로 조회합니다.") | ||
public ResponseEntity<DataResponse<MyCommentResponse>> getMyComments( | ||
@RequestParam(required = false, defaultValue = "0") int page | ||
){ | ||
return ResponseEntity.ok(DataResponse.from( | ||
MyCommentResponse.from( | ||
commentService.findUserComments(page) | ||
) | ||
) | ||
); | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
src/main/java/com/cotato/kampus/domain/comment/application/AuthorResolver.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,55 @@ | ||
package com.cotato.kampus.domain.comment.application; | ||
|
||
import java.util.Optional; | ||
|
||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import com.cotato.kampus.domain.comment.dao.CommentRepository; | ||
import com.cotato.kampus.domain.comment.domain.Comment; | ||
import com.cotato.kampus.domain.comment.dto.CommentDto; | ||
import com.cotato.kampus.domain.common.application.ApiUserResolver; | ||
import com.cotato.kampus.domain.common.enums.Anonymity; | ||
import com.cotato.kampus.domain.post.application.PostUpdater; | ||
import com.cotato.kampus.domain.user.application.UserFinder; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Component | ||
@Transactional(readOnly = true) | ||
@RequiredArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class AuthorResolver { | ||
|
||
private final CommentRepository commentRepository; | ||
private final ApiUserResolver apiUserResolver; | ||
private final PostUpdater postUpdater; | ||
private final UserFinder userFinder; | ||
|
||
public Optional<Long> allocateAnonymousNumber(Long postId, Anonymity anonymity){ | ||
|
||
// 익명인 경우 | ||
if(anonymity == Anonymity.ANONYMOUS){ | ||
// 해당 Post에 현재 User의 댓글 작성 여부 확인 | ||
Optional<Comment> comment = commentRepository.findFirstByPostIdAndUserIdAndAnonymity( | ||
postId, apiUserResolver.getUserId(), anonymity | ||
); | ||
|
||
return comment.map(Comment::getAnonymousNumber) | ||
.or(() -> Optional.ofNullable(postUpdater.increaseNextAnonymousNumber(postId))); | ||
} else { | ||
return Optional.empty(); | ||
} | ||
} | ||
|
||
public String resolveAuthorName(CommentDto commentDto){ | ||
|
||
if(commentDto.anonymity() == Anonymity.ANONYMOUS){ | ||
return "Anonymous" + commentDto.anonymousNumber(); | ||
} | ||
|
||
String nickname = userFinder.findById(commentDto.userId()).getNickname(); | ||
|
||
return nickname; | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
src/main/java/com/cotato/kampus/domain/comment/application/CommentAppender.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,48 @@ | ||
package com.cotato.kampus.domain.comment.application; | ||
|
||
import java.util.Optional; | ||
|
||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import com.cotato.kampus.domain.comment.dao.CommentRepository; | ||
import com.cotato.kampus.domain.comment.domain.Comment; | ||
import com.cotato.kampus.domain.comment.enums.CommentStatus; | ||
import com.cotato.kampus.domain.comment.enums.ReportStatus; | ||
import com.cotato.kampus.domain.common.application.ApiUserResolver; | ||
import com.cotato.kampus.domain.common.enums.Anonymity; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Component | ||
@Transactional(readOnly = true) | ||
@RequiredArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class CommentAppender { | ||
|
||
private final CommentRepository commentRepository; | ||
private final ApiUserResolver apiUserResolver; | ||
|
||
@Transactional | ||
public Long append(Long postId, String content, Anonymity anonymity, Optional<Long> anonymousNumber, Long parentId){ | ||
|
||
Long userId = apiUserResolver.getUserId(); | ||
|
||
Long anonymousNumberValue = anonymousNumber.orElse(null); | ||
|
||
Comment comment = Comment.builder() | ||
.userId(userId) | ||
.postId(postId) | ||
.content(content) | ||
.likes(0L) | ||
.reportStatus(ReportStatus.NORMAL) | ||
.commentStatus(CommentStatus.NORMAL) | ||
.anonymity(anonymity) | ||
.reports(0L) | ||
.anonymousNumber(anonymousNumberValue) | ||
.parentId(parentId) | ||
.build(); | ||
|
||
return commentRepository.save(comment).getId(); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/main/java/com/cotato/kampus/domain/comment/application/CommentDeleter.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,46 @@ | ||
package com.cotato.kampus.domain.comment.application; | ||
|
||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import com.cotato.kampus.domain.comment.dao.CommentRepository; | ||
import com.cotato.kampus.domain.comment.domain.Comment; | ||
import com.cotato.kampus.domain.comment.enums.CommentStatus; | ||
import com.cotato.kampus.domain.common.application.ApiUserResolver; | ||
import com.cotato.kampus.domain.user.domain.User; | ||
import com.cotato.kampus.global.error.ErrorCode; | ||
import com.cotato.kampus.global.error.exception.AppException; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Component | ||
@Transactional(readOnly = true) | ||
@RequiredArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class CommentDeleter { | ||
|
||
private final CommentRepository commentRepository; | ||
private final ApiUserResolver apiUserResolver; | ||
private final CommentFinder commentFinder; | ||
|
||
public Long delete(Long commentId) { | ||
|
||
User user = apiUserResolver.getUser(); | ||
Comment comment = commentFinder.findComment(commentId); | ||
|
||
// 작성자 검증 | ||
if(comment.getUserId() != user.getId()){ | ||
throw new AppException(ErrorCode.COMMENT_NOT_AUTHOR); | ||
} | ||
|
||
// 대댓글이 있으면 삭제된 상태로 업데이트 | ||
if(commentRepository.existsByParentId(commentId)){ | ||
comment.setCommentStatus(CommentStatus.DELETED_BY_USER); | ||
return commentRepository.save(comment).getId(); | ||
} | ||
|
||
// 댓글 삭제 | ||
commentRepository.delete(comment); | ||
return commentId; | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
src/main/java/com/cotato/kampus/domain/comment/application/CommentFinder.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,53 @@ | ||
package com.cotato.kampus.domain.comment.application; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.data.domain.PageRequest; | ||
import org.springframework.data.domain.Slice; | ||
import org.springframework.data.domain.Sort; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import com.cotato.kampus.domain.comment.dao.CommentRepository; | ||
import com.cotato.kampus.domain.comment.domain.Comment; | ||
import com.cotato.kampus.domain.comment.dto.CommentDto; | ||
import com.cotato.kampus.domain.comment.dto.CommentSummary; | ||
import com.cotato.kampus.domain.common.application.ApiUserResolver; | ||
import com.cotato.kampus.global.error.ErrorCode; | ||
import com.cotato.kampus.global.error.exception.AppException; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Component | ||
@Transactional(readOnly = true) | ||
@RequiredArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class CommentFinder { | ||
|
||
private final CommentRepository commentRepository; | ||
private final ApiUserResolver apiUserResolver; | ||
|
||
public Comment findComment(Long commentId){ | ||
return commentRepository.findById(commentId) | ||
.orElseThrow(() -> new AppException(ErrorCode.COMMENT_NOT_FOUND)); | ||
} | ||
|
||
public List<CommentDto> findComments(Long postId){ | ||
List<Comment> comments = commentRepository.findAllByPostIdOrderByCreatedTimeAsc(postId); | ||
List<CommentDto> commentDtos = comments.stream() | ||
.map(CommentDto::from) | ||
.toList(); | ||
|
||
return commentDtos; | ||
} | ||
|
||
public Slice<CommentSummary> findUserComments(int page){ | ||
|
||
Long userId = apiUserResolver.getUserId(); | ||
|
||
PageRequest pageRequest = PageRequest.of(page, 10, Sort.by(Sort.Direction.DESC, "createdTime")); | ||
Slice<Comment> comments = commentRepository.findAllByUserId(userId, pageRequest); | ||
|
||
return comments.map(CommentSummary::from); | ||
} | ||
} |
Oops, something went wrong.