Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat/#105] 인기 있는 책 조회 API, pr 코멘트 수정 #108

Merged
merged 5 commits into from
Oct 25, 2023
Merged
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
@@ -1,6 +1,7 @@
package com.techeer.checkIt.domain.book.controller;

import com.techeer.checkIt.domain.book.dto.Response.BookRes;
import com.techeer.checkIt.domain.book.dto.Response.BookSearchLikeRes;
import com.techeer.checkIt.domain.book.dto.Response.BookSearchRes;
import com.techeer.checkIt.domain.book.service.BookService;
import com.techeer.checkIt.domain.user.entity.User;
Expand Down Expand Up @@ -56,7 +57,7 @@ public ResponseEntity<ResultResponse> getNewBooksList() {
}

@ApiOperation(value = "책 좋아요 API")
@GetMapping("/like/{bookId}")
@PostMapping("/like/{bookId}")
public ResponseEntity<ResultResponse> updateLikeById(
@AuthenticationPrincipal UserDetail userDetail,
@PathVariable Long bookId
Expand All @@ -67,4 +68,10 @@ public ResponseEntity<ResultResponse> updateLikeById(
return ResponseEntity.ok(ResultResponse.of(UPDATE_BOOK_LIKE_SUCCESS ,bookResponse));
}

@ApiOperation(value = "인기 있는 책 조회 API")
@GetMapping("/like")
public ResponseEntity<ResultResponse> getLikeBooksList() {
Page<BookSearchLikeRes> books = bookService.sortedBooksByLike();
return ResponseEntity.ok(ResultResponse.of(GET_NEW_BOOK_SUCCESS, books));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.techeer.checkIt.domain.book.dto.Response;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class BookSearchLikeRes {
private String title;
private String author;
private String publisher;
private String coverImageUrl;
private int pages;
private String category;
private int like;
}
14 changes: 14 additions & 0 deletions src/main/java/com/techeer/checkIt/domain/book/entity/Book.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class Book extends BaseEntity {
private String category;
@OneToMany(mappedBy = "book")
private List<Reading> readingList = new ArrayList<>();
@Column(name = "like_count")
private Integer likeCount = 0;
@Builder
public Book(String title, String author, String publisher, String coverImageUrl, int pages, int height, int width, int thickness, String category) {
this.title = title;
Expand All @@ -49,4 +51,16 @@ public Book(String title, String author, String publisher, String coverImageUrl,
this.thickness = thickness;
this.category = category;
}

@PostLoad
@PrePersist
private void initializeDefaults() {
if (likeCount == null) {
likeCount = 0; // 기본값을 0으로 설정
}
}
public void updateLike(int like) {
this.likeCount = like;
}
public void setLikeCount(Integer likeCount) { this.likeCount = likeCount; }
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toPageDtoList랑 toPageDtoList2를 기존 방식대로 표현하면
toBookSearchResDtoPage와 BookSearchLikeResDtoPage 가 맞는거 같은데 너무 긴 것 같습니다
이거 어떻게 줄일 수 있을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저두 너무 긴것 같아서 일단 짧게 표현을 했는데 지금은 코드위에 주석으로 설명 넣어놓겠습니다!

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.techeer.checkIt.domain.book.mapper;

import com.techeer.checkIt.domain.book.dto.Response.BookRes;
import com.techeer.checkIt.domain.book.dto.Response.BookSearchLikeRes;
import com.techeer.checkIt.domain.book.dto.Response.BookSearchRes;
import com.techeer.checkIt.domain.book.entity.Book;
import com.techeer.checkIt.domain.book.entity.BookDocument;
Expand Down Expand Up @@ -37,14 +38,32 @@ public BookSearchRes toBookSearchDto(BookDocument book) {
.category(book.getCategory())
.build();
}
public BookSearchLikeRes toBookSearchLikeDto(Book book) {
return BookSearchLikeRes.builder()
.title(book.getTitle())
.author(book.getAuthor())
.publisher(book.getPublisher())
.coverImageUrl(book.getCoverImageUrl())
.pages(book.getPages())
.category(book.getCategory())
.like(book.getLikeCount())
.build();
}
public List<BookSearchRes> toSearchDtoList(List<BookDocument> books){
return books.stream()
.map(this::toBookSearchDto)
.collect(Collectors.toList());
}
// toPageDtoList = toBookSearchResDtoPage
public Page<BookSearchRes> toPageDtoList(Page<BookDocument> books) {
return new PageImpl<>(books.stream()
.map(this::toBookSearchDto)
.collect(Collectors.toList()));
}
// toPageDtoList2 = BookSearchLikeResDtoPage
public Page<BookSearchLikeRes> toPageDtoList2(Page<Book> books) {
return new PageImpl<>(books.stream()
.map(this::toBookSearchLikeDto)
.collect(Collectors.toList()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import com.techeer.checkIt.domain.book.dao.RedisDao;
import com.techeer.checkIt.domain.book.dto.Response.BookRes;
import com.techeer.checkIt.domain.book.dto.Response.BookSearchLikeRes;
import com.techeer.checkIt.domain.book.dto.Response.BookSearchRes;
import com.techeer.checkIt.domain.book.entity.Book;
import com.techeer.checkIt.domain.book.entity.BookDocument;
import com.techeer.checkIt.domain.book.exception.BookNotFoundException;
import com.techeer.checkIt.domain.book.mapper.BookMapper;
import com.techeer.checkIt.domain.book.repository.BookJpaRepository;
import com.techeer.checkIt.domain.book.repository.BookSearchRepository;
import javax.transaction.Transactional;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -39,6 +41,12 @@ public Page<BookSearchRes> sortedBooksByTime() {
return bookMapper.toPageDtoList(newBooks);
}

public Page<BookSearchLikeRes> sortedBooksByLike() {
PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("likeCount")));
Page<Book> newBooks = bookJpaRepository.findAll(pageRequest);
return bookMapper.toPageDtoList2(newBooks);
}

// id별 조회할 때
public BookRes findBookById(Long userId, Long bookId) {
Book book = bookJpaRepository.findByBookId(bookId).orElseThrow(BookNotFoundException::new);
Expand All @@ -53,22 +61,31 @@ public BookRes findBookById(Long userId, Long bookId) {
public Book findById(Long id) {
return bookJpaRepository.findById(id).orElseThrow(BookNotFoundException::new);
}
@Transactional
public void updateLike(Long userId, Long bookId) {
Book book = bookJpaRepository.findByBookId(bookId).orElseThrow(BookNotFoundException::new);
String redisKey = "B" + bookId.toString(); // 게시글 key
String redisUserKey = "U" + userId.toString(); // 유저 key
// redis에 없는 게시글 id가 들어올 경우 : 새롭게 데이터를 만들어주고 좋아요수를 0으로 초기화, 있는 경우 : 현제 좋아요수 반환
String values = (redisDao.getValues(redisKey) == null) ? redisDao.setValues(redisKey,"0") : redisDao.getValues(redisKey);
int likes = Integer.parseInt(values);
int likes = Integer.parseInt(values), bookLikes = 0;


// 유저를 key로 조회한 게시글 ID List안에 해당 게시글 ID가 포함되어있지 않는다면,
if (!redisDao.getValuesList(redisUserKey).contains(redisKey.substring(1))) {
redisDao.setValuesList(redisUserKey, redisKey.substring(1)); // 유저 key로 해당 글 ID를 List 형태로 저장
likes = Integer.parseInt(values) + 1; // 좋아요 증가
redisDao.setValues(redisKey, String.valueOf(likes)); // 글ID key로 좋아요 저장
bookLikes = book.getLikeCount();
book.updateLike(bookLikes+1);
} else {
redisDao.deleteValueList(redisUserKey, redisKey.substring(1)); // 유저 key로 해당 글 ID를 List 형태에서 제거
likes = Integer.parseInt(values) - 1; // 좋아요 감소
redisDao.setValues(redisKey, String.valueOf(likes)); // 글ID key로 좋아요 저장
bookLikes = book.getLikeCount();
book.updateLike(bookLikes-1);
}

bookJpaRepository.save(book);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.techeer.checkIt.global.result.ResultResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.validation.Valid;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand All @@ -35,15 +36,15 @@ public class ReviewController {
private final BookService bookService;

@ApiOperation(value = "리뷰 생성 API")
@PostMapping()
@PostMapping
public ResponseEntity<ResultResponse> createReview(
@AuthenticationPrincipal UserDetail userDetail,
@RequestBody CreateReviewReq createReviewReq
@RequestBody @Valid CreateReviewReq createReviewReq
){
User user = userService.findUserByUsername(userDetail.getUsername());
Book book = bookService.findById(createReviewReq.getBookId());
reviewService.createReview(user, book, createReviewReq);
ReviewRes reviewRes = reviewService.findReviewByNameIdBookId(user, createReviewReq.getBookId());
ReviewRes reviewRes = reviewService.findReviewByUserNameIdBookId(user, createReviewReq.getBookId());
return ResponseEntity.ok(ResultResponse.of(ResultCode.REVIEW_CREATE_SUCCESS, reviewRes));
}

Expand All @@ -54,13 +55,13 @@ public ResponseEntity<ResultResponse> getReviewByUserNameBookId(
@PathVariable Long bookId
){
User user = userService.findUserByUsername(userDetail.getUsername());
ReviewRes reviewRes = reviewService.findReviewByNameIdBookId(user, bookId);
ReviewRes reviewRes = reviewService.findReviewByUserNameIdBookId(user, bookId);
return ResponseEntity.ok(ResultResponse.of(ResultCode.REVIEW_CREATE_SUCCESS, reviewRes));
}

@ApiOperation(value = "리뷰 삭제 API")
@DeleteMapping ("{bookId}")
public ResponseEntity<ResultResponse> deleteReviewUserNameBookId(
public ResponseEntity<ResultResponse> deleteReviewByUserNameBookId(
@AuthenticationPrincipal UserDetail userDetail,
@PathVariable Long bookId
){
Expand All @@ -70,14 +71,14 @@ public ResponseEntity<ResultResponse> deleteReviewUserNameBookId(
}

@ApiOperation(value = "리뷰 내용 변경 API")
@PutMapping()
@PutMapping
public ResponseEntity<ResultResponse> updateReview(
@AuthenticationPrincipal UserDetail userDetail,
@RequestBody CreateReviewReq createReviewReq
@RequestBody @Valid CreateReviewReq createReviewReq
) {
User user = userService.findUserByUsername(userDetail.getUsername());
reviewService.updateReview(user, createReviewReq);
ReviewRes reviewRes = reviewService.findReviewByNameIdBookId(user, createReviewReq.getBookId());
ReviewRes reviewRes = reviewService.findReviewByUserNameIdBookId(user, createReviewReq.getBookId());
return ResponseEntity.ok(ResultResponse.of(ResultCode.REVIEW_DELETE_SUCCESS, reviewRes));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void createReview (User user, Book book, CreateReviewReq createReviewReq)
reviewRepository.save(review);
}

public ReviewRes findReviewByNameIdBookId (User user, Long bookId) {
public ReviewRes findReviewByUserNameIdBookId (User user, Long bookId) {
Review review = reviewRepository.findByUserNameBookId(user.getNickname(), bookId).orElseThrow(ReviewNotFoundException::new);
return reviewMapper.toDto(review);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public enum ResultCode {

// Review
REVIEW_CREATE_SUCCESS("RE001", "리뷰 등록 성공"),
GET_REVIEW_SUCCESS("RE0012", "리뷰 조회 성공"),
GET_REVIEW_SUCCESS("RE002", "리뷰 조회 성공"),
REVIEW_DELETE_SUCCESS("RE003", "리뷰 삭제 성공"),
REVIEW_UPDATE_SUCCESS("RE004", "리뷰 갱신 성공"),
;
Expand Down
Loading