Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -194,5 +194,19 @@ public ResponseEntity<ApiResponse<WeeklyRecommendationResponseDTO>> getWeeklyRec
WeeklyRecommendationResponseDTO weeklyRecommendationResponseDTO = postService.getWeeklyRecommendation(userDetails.getUsername());
return ApiResponse.success(SuccessStatus.GET_WEEKLY_RECOMMENDATION_SUCCESS, weeklyRecommendationResponseDTO);
}
}

@Operation(
summary = "가장 많이 기록된 책 조회 API",
description = "전체 공개 기록 기준으로 가장 많이 기록된 책을 조회합니다. 동률이면 최근에 작성된 책을 우선합니다."
)
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "가장 많이 기록된 책 조회 성공"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "가장 많이 기록된 책을 찾을 수 없습니다.")
})
@GetMapping("/most-recorded-book")
public ResponseEntity<ApiResponse<MostRecordedBookResponseDTO>> getMostRecordedBook() {

MostRecordedBookResponseDTO mostRecordedBookResponseDTO = postService.getMostRecordedBook();
return ApiResponse.success(SuccessStatus.GET_MOST_RECORDED_BOOK_SUCCESS, mostRecordedBookResponseDTO);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.moongeul.backend.api.post.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MostRecordedBookResponseDTO {

private Long postId; // 기록 ID
private String bookImage; // 책 사진
private String bookTitle; // 책 제목
private String isbn; // 책 ISBN
private String author; // 책 저자
private String publisher; // 출판사
private String pubdate; // 출판년도
private Double bookRating; // 책 별점
private Double rating; // 평점
private String content; // 기록글
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.moongeul.backend.api.book.entity.Book;
import com.moongeul.backend.api.member.entity.ReadingTasteType;
import com.moongeul.backend.api.post.entity.Post;
import com.moongeul.backend.api.post.entity.PostVisibility;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -11,6 +12,7 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

public interface PostRepository extends JpaRepository<Post, Long> {

Expand All @@ -37,6 +39,17 @@ public interface PostRepository extends JpaRepository<Post, Long> {
@Query("SELECT p FROM Post p WHERE p.book = :book ORDER BY p.createdAt DESC")
Page<Post> findByBookOrderByCreatedAtDesc(@Param("book") Book book, Pageable pageable);

// 전체 공개 기록 기준으로 가장 많이 기록된 책 ISBN 조회
@Query("SELECT p.book.isbn FROM Post p " +
"WHERE p.postVisibility = 'PUBLIC' " +
"GROUP BY p.book.isbn " +
"ORDER BY COUNT(p) DESC, MAX(p.createdAt) DESC")
List<String> findMostRecordedPublicBookIsbn(Pageable pageable);

// 특정 ISBN의 전체 공개 게시글 중 가장 최근 기록 조회
Optional<Post> findFirstByBookIsbnAndPostVisibilityOrderByCreatedAtDesc(
String isbn, PostVisibility postVisibility);

// 같은 취향 사용자들의 기록 중 이번 주 가장 공감을 많이 받은 기록 조회
// 모든 공감 유형의 합계(relatableCount + sameTasteCount + impressiveExpressionCount + wantToReadCount + helpfulCount) 기준으로 정렬
@Query("SELECT p FROM Post p " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,37 @@ private void decrementLikeCount(Post post, LikeType likeType) {
/*
* 추천
*/

// 가장 많이 기록된 책 조회
@Transactional(readOnly = true)
public MostRecordedBookResponseDTO getMostRecordedBook() {
List<String> mostRecordedBookIsbnList = postRepository.findMostRecordedPublicBookIsbn(PageRequest.of(0, 1));

if (mostRecordedBookIsbnList.isEmpty()) {
throw new NotFoundException(ErrorStatus.MOST_RECORDED_BOOK_NOT_FOUND_EXCEPTION.getMessage());
}

String mostRecordedBookIsbn = mostRecordedBookIsbnList.get(0);

Post post = postRepository.findFirstByBookIsbnAndPostVisibilityOrderByCreatedAtDesc(
mostRecordedBookIsbn,
PostVisibility.PUBLIC
)
.orElseThrow(() -> new NotFoundException(ErrorStatus.MOST_RECORDED_BOOK_NOT_FOUND_EXCEPTION.getMessage()));

return MostRecordedBookResponseDTO.builder()
.postId(post.getId())
.bookImage(post.getBook().getBookImage())
.bookTitle(post.getBook().getTitle())
.isbn(post.getBook().getIsbn())
.author(post.getBook().getAuthor())
.publisher(post.getBook().getPublisher())
.pubdate(post.getBook().getPubdate())
.bookRating(post.getBook().getRatingAverage())
.rating(post.getRating())
.content(post.getContent())
.build();
}

// 주간 추천 기록 조회
@Transactional(readOnly = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public enum ErrorStatus {
REVIEW_NOTFOUND_EXCEPTION(HttpStatus.NOT_FOUND, "해당 리뷰를 찾을 수 없습니다."),
USER_READING_TASTE_NOT_FOUND_EXCEPTION(HttpStatus.NOT_FOUND, "사용자의 독서 취향 정보를 찾을 수 없습니다."),
WEEKLY_RECOMMENDATION_NOT_FOUND_EXCEPTION(HttpStatus.NOT_FOUND, "주간 추천 기록을 찾을 수 없습니다."),
MOST_RECORDED_BOOK_NOT_FOUND_EXCEPTION(HttpStatus.NOT_FOUND, "가장 많이 기록된 책을 찾을 수 없습니다."),
QUESTION_NOTFOUND_EXCEPTION(HttpStatus.NOT_FOUND, "해당 질문을 찾을 수 없습니다."),
ANSWER_NOTFOUND_EXCEPTION(HttpStatus.NOT_FOUND, "해당 답변을 찾을 수 없습니다."),
TERMS_NOTFOUND_EXCEPTION(HttpStatus.NOT_FOUND, "약관 정보를 찾을 수 없습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public enum SuccessStatus {
DELETE_POST_SUCCESS(HttpStatus.OK, "기록(게시글) 삭제 성공"),
POST_LIKE_SUCCESS(HttpStatus.OK, "기록(게시글) 공감 버튼 등록 성공"),
GET_WEEKLY_RECOMMENDATION_SUCCESS(HttpStatus.OK, "주간 추천 기록 조회 성공"),
GET_MOST_RECORDED_BOOK_SUCCESS(HttpStatus.OK, "가장 많이 기록된 책 조회 성공"),
GET_WRITING_GUIDE(HttpStatus.OK, "글쓰기 도움 받기 조회 성공"),

/* CATEGORY */
Expand Down