diff --git a/src/main/java/com/codeit/todo/domain/Complete.java b/src/main/java/com/codeit/todo/domain/Complete.java index b73e683..52b8018 100644 --- a/src/main/java/com/codeit/todo/domain/Complete.java +++ b/src/main/java/com/codeit/todo/domain/Complete.java @@ -5,9 +5,12 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.data.relational.core.sql.Like; import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; @Entity @@ -36,6 +39,12 @@ public class Complete { @JoinColumn(name = "todo_id", nullable = false) private Todo todo; + @OneToMany(mappedBy = "complete", cascade = CascadeType.REMOVE, orphanRemoval = true) + private List comments = new ArrayList<>(); + + @OneToMany(mappedBy = "complete", cascade = CascadeType.REMOVE, orphanRemoval = true) + private List likes = new ArrayList<>(); + @Builder public Complete(LocalDate startDate, LocalDateTime createdAt, String note, String completeLink, String completeFile, String completePic, String completeStatus, Todo todo) { this.startDate = startDate; diff --git a/src/main/java/com/codeit/todo/repository/LikesRepository.java b/src/main/java/com/codeit/todo/repository/LikesRepository.java new file mode 100644 index 0000000..06c988c --- /dev/null +++ b/src/main/java/com/codeit/todo/repository/LikesRepository.java @@ -0,0 +1,8 @@ +package com.codeit.todo.repository; + +import com.codeit.todo.domain.Likes; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface LikesRepository extends JpaRepository { + Boolean existsByUser_UserIdAndComplete_CompleteId(int userId, int completeId); +} diff --git a/src/main/java/com/codeit/todo/service/complete/CompleteService.java b/src/main/java/com/codeit/todo/service/complete/CompleteService.java index 32874ec..6482ada 100644 --- a/src/main/java/com/codeit/todo/service/complete/CompleteService.java +++ b/src/main/java/com/codeit/todo/service/complete/CompleteService.java @@ -1,8 +1,11 @@ package com.codeit.todo.service.complete; import com.codeit.todo.web.dto.request.complete.UpdateCompleteRequest; +import com.codeit.todo.web.dto.response.complete.ReadCompleteDetailResponse; import com.codeit.todo.web.dto.response.complete.UpdateCompleteResponse; public interface CompleteService { UpdateCompleteResponse updateCompleteInfo(int userId, int completeId, UpdateCompleteRequest request); + + ReadCompleteDetailResponse readComplete(int userId, int completeId); } diff --git a/src/main/java/com/codeit/todo/service/complete/impl/CompleteServiceImpl.java b/src/main/java/com/codeit/todo/service/complete/impl/CompleteServiceImpl.java index 069a065..570d564 100644 --- a/src/main/java/com/codeit/todo/service/complete/impl/CompleteServiceImpl.java +++ b/src/main/java/com/codeit/todo/service/complete/impl/CompleteServiceImpl.java @@ -1,17 +1,20 @@ package com.codeit.todo.service.complete.impl; import com.codeit.todo.common.exception.complete.CompleteNotFoundException; -import com.codeit.todo.common.exception.payload.ErrorStatus; import com.codeit.todo.domain.Complete; import com.codeit.todo.repository.CompleteRepository; +import com.codeit.todo.repository.LikesRepository; import com.codeit.todo.service.complete.CompleteService; import com.codeit.todo.service.storage.StorageService; import com.codeit.todo.web.dto.request.complete.UpdateCompleteRequest; +import com.codeit.todo.web.dto.response.comment.ReadCommentResponse; +import com.codeit.todo.web.dto.response.complete.ReadCompleteDetailResponse; import com.codeit.todo.web.dto.response.complete.UpdateCompleteResponse; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.Objects; @Service @@ -22,12 +25,11 @@ public class CompleteServiceImpl implements CompleteService { private final StorageService storageService; private final CompleteRepository completeRepository; + private final LikesRepository likesRepository; @Override public UpdateCompleteResponse updateCompleteInfo(int userId, int completeId, UpdateCompleteRequest request) { - Complete complete = completeRepository.findById(completeId) - .filter(c -> c.getTodo().getGoal().getUser().getUserId() == userId) - .orElseThrow(() -> new CompleteNotFoundException(String.valueOf(completeId))); + Complete complete = getComplete(userId, completeId); String completePicUrl = ""; @@ -39,4 +41,23 @@ public UpdateCompleteResponse updateCompleteInfo(int userId, int completeId, Upd return new UpdateCompleteResponse(completeId); } + + @Transactional(readOnly = true) + @Override + public ReadCompleteDetailResponse readComplete(int userId, int completeId) { + Complete complete = getComplete(userId, completeId); + List commentResponses = complete.getComments().stream() + .map(ReadCommentResponse::fromEntity) + .toList(); + + Boolean likeStatus = likesRepository.existsByUser_UserIdAndComplete_CompleteId(userId, completeId); + + return ReadCompleteDetailResponse.from(complete, commentResponses, likeStatus); + } + + private Complete getComplete(int userId, int completeId) { + return completeRepository.findById(completeId) + .filter(c -> c.getTodo().getGoal().getUser().getUserId() == userId) + .orElseThrow(() -> new CompleteNotFoundException(String.valueOf(completeId))); + } } diff --git a/src/main/java/com/codeit/todo/web/controller/CompleteController.java b/src/main/java/com/codeit/todo/web/controller/CompleteController.java index 6b752b1..5b71b94 100644 --- a/src/main/java/com/codeit/todo/web/controller/CompleteController.java +++ b/src/main/java/com/codeit/todo/web/controller/CompleteController.java @@ -4,6 +4,8 @@ import com.codeit.todo.service.complete.CompleteService; import com.codeit.todo.web.dto.request.complete.UpdateCompleteRequest; import com.codeit.todo.web.dto.response.Response; +import com.codeit.todo.web.dto.response.complete.ReadCompleteDetailResponse; +import com.codeit.todo.web.dto.response.complete.ReadCompleteResponse; import com.codeit.todo.web.dto.response.complete.UpdateCompleteResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -35,4 +37,20 @@ public Response updateComplete( int userId = userDetails.getUserId(); return Response.ok(completeService.updateCompleteInfo(userId, completeId, request)); } + + @Operation( + summary = "인증 및 노트 상세 조회", + description = "인증 및 노트 상세조회하는 API 입니다." + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공") + }) + @GetMapping("{completeId}") + public Response readComplete( + @AuthenticationPrincipal CustomUserDetails userDetails, + @PathVariable int completeId + ) { + int userId = userDetails.getUserId(); + return Response.ok(completeService.readComplete(userId, completeId)); + } } diff --git a/src/main/java/com/codeit/todo/web/dto/response/comment/ReadCommentResponse.java b/src/main/java/com/codeit/todo/web/dto/response/comment/ReadCommentResponse.java new file mode 100644 index 0000000..7627db2 --- /dev/null +++ b/src/main/java/com/codeit/todo/web/dto/response/comment/ReadCommentResponse.java @@ -0,0 +1,25 @@ +package com.codeit.todo.web.dto.response.comment; + +import com.codeit.todo.domain.Comment; +import lombok.Builder; + +import java.time.LocalDateTime; + +@Builder +public record ReadCommentResponse( + int commentId, + String content, + String userName, + String profileImage, + LocalDateTime createdAt +) { + public static ReadCommentResponse fromEntity(Comment comment) { + return ReadCommentResponse.builder() + .commentId(comment.getCommentId()) + .content(comment.getContent()) + .userName(comment.getUser().getName()) + .profileImage(comment.getUser().getProfilePic()) + .createdAt(comment.getCreatedAt()) + .build(); + } +} diff --git a/src/main/java/com/codeit/todo/web/dto/response/complete/ReadCompleteDetailResponse.java b/src/main/java/com/codeit/todo/web/dto/response/complete/ReadCompleteDetailResponse.java new file mode 100644 index 0000000..985e432 --- /dev/null +++ b/src/main/java/com/codeit/todo/web/dto/response/complete/ReadCompleteDetailResponse.java @@ -0,0 +1,40 @@ +package com.codeit.todo.web.dto.response.complete; + +import com.codeit.todo.domain.Complete; +import com.codeit.todo.web.dto.response.comment.ReadCommentResponse; +import lombok.Builder; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +@Builder +public record ReadCompleteDetailResponse( + int completeId, + String completePic, + String note, + String completeLink, + String completeStatus, + LocalDateTime createdAt, + LocalDate startDate, + Boolean likeStatus, + int likeCount, + int commentCount, + List comments +) { + public static ReadCompleteDetailResponse from(Complete complete, List commentResponses, Boolean likeStatus) { + return ReadCompleteDetailResponse.builder() + .completeId(complete.getCompleteId()) + .completePic(complete.getCompletePic()) + .note(complete.getNote()) + .completeLink(complete.getCompleteLink()) + .completeStatus(complete.getCompleteStatus()) + .createdAt(complete.getCreatedAt()) + .startDate(complete.getStartDate()) + .likeCount(complete.getLikes().size()) + .likeStatus(likeStatus) + .commentCount(commentResponses.size()) + .comments(commentResponses) + .build(); + } +} diff --git a/src/main/java/com/codeit/todo/web/dto/response/complete/ReadCompleteResponse.java b/src/main/java/com/codeit/todo/web/dto/response/complete/ReadCompleteResponse.java index e03a54c..d4364da 100644 --- a/src/main/java/com/codeit/todo/web/dto/response/complete/ReadCompleteResponse.java +++ b/src/main/java/com/codeit/todo/web/dto/response/complete/ReadCompleteResponse.java @@ -1,5 +1,6 @@ package com.codeit.todo.web.dto.response.complete; +import com.codeit.todo.domain.Comment; import com.codeit.todo.domain.Complete; import lombok.Builder;