From 48aaf2aa2211b2ed3f6bc6a1326cdbe250af81f1 Mon Sep 17 00:00:00 2001 From: eeddiinn Date: Sun, 10 Mar 2024 22:12:24 +0900 Subject: [PATCH 1/7] =?UTF-8?q?=E2=9C=A8=20[FEAT]=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=A6=90=EA=B2=A8=EC=B0=BE=EA=B8=B0=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20api=201=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/FavoriteCreateRequestDto.java | 9 +++++ .../domain/book/facade/BookFacade.java | 27 +++++++++++--- .../lequuServer/domain/book/model/Book.java | 7 ++++ .../domain/book/model/Favorite.java | 35 +++++++++++++++++++ .../book/repository/FavoriteRepository.java | 8 +++++ .../common/controller/CommonController.java | 17 ++++++--- .../domain/member/model/Member.java | 8 +++++ .../global/exception/enums/SuccessType.java | 3 +- 8 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/sopt/lequuServer/domain/book/dto/request/FavoriteCreateRequestDto.java create mode 100644 src/main/java/org/sopt/lequuServer/domain/book/model/Favorite.java create mode 100644 src/main/java/org/sopt/lequuServer/domain/book/repository/FavoriteRepository.java diff --git a/src/main/java/org/sopt/lequuServer/domain/book/dto/request/FavoriteCreateRequestDto.java b/src/main/java/org/sopt/lequuServer/domain/book/dto/request/FavoriteCreateRequestDto.java new file mode 100644 index 0000000..a55a094 --- /dev/null +++ b/src/main/java/org/sopt/lequuServer/domain/book/dto/request/FavoriteCreateRequestDto.java @@ -0,0 +1,9 @@ +package org.sopt.lequuServer.domain.book.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; + +public record FavoriteCreateRequestDto( + @Schema(example = "1") + Long bookId +) { +} \ No newline at end of file diff --git a/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java b/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java index eb2c6ce..d1ab554 100644 --- a/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java +++ b/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java @@ -1,15 +1,14 @@ package org.sopt.lequuServer.domain.book.facade; -import static org.sopt.lequuServer.global.s3.enums.ImageFolderName.BOOK_FAVORITE_IMAGE_FOLDER_NAME; - -import java.util.List; -import java.util.UUID; import lombok.RequiredArgsConstructor; import org.sopt.lequuServer.domain.book.dto.request.BookCreateRequestDto; +import org.sopt.lequuServer.domain.book.dto.request.FavoriteCreateRequestDto; import org.sopt.lequuServer.domain.book.dto.response.BookCreateResponseDto; import org.sopt.lequuServer.domain.book.dto.response.BookDetailResponseDto; import org.sopt.lequuServer.domain.book.model.Book; +import org.sopt.lequuServer.domain.book.model.Favorite; import org.sopt.lequuServer.domain.book.repository.BookRepository; +import org.sopt.lequuServer.domain.book.repository.FavoriteRepository; import org.sopt.lequuServer.domain.book.service.BookService; import org.sopt.lequuServer.domain.member.model.Member; import org.sopt.lequuServer.domain.member.repository.MemberRepository; @@ -23,6 +22,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.UUID; + +import static org.sopt.lequuServer.global.s3.enums.ImageFolderName.BOOK_FAVORITE_IMAGE_FOLDER_NAME; + @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -36,6 +40,7 @@ public class BookFacade { private final PostedStickerRepository postedStickerRepository; private final BadWordFilterService badWordFilterService; private final S3Service s3Service; + private final FavoriteRepository favoriteRepository; @Transactional public BookCreateResponseDto createBook(BookCreateRequestDto request, Long memberId) { @@ -100,4 +105,16 @@ public BookDetailResponseDto getBookDetail(String bookUuid) { return BookDetailResponseDto.of(book); } -} + + @Transactional + public void createFavorite(Long memberId, FavoriteCreateRequestDto request) { + Member member = memberRepository.findByIdOrThrow(memberId); + Book book = bookRepository.findByIdOrThrow(request.bookId()); + + Favorite favorite = Favorite.of(member, book); + favoriteRepository.save(favorite); + + book.addFavorite(favorite); + member.addFavorite(favorite); + } // memberId와 bookId를 favorite에 저장하는 로직 +} \ No newline at end of file diff --git a/src/main/java/org/sopt/lequuServer/domain/book/model/Book.java b/src/main/java/org/sopt/lequuServer/domain/book/model/Book.java index 0cdb580..d123de9 100644 --- a/src/main/java/org/sopt/lequuServer/domain/book/model/Book.java +++ b/src/main/java/org/sopt/lequuServer/domain/book/model/Book.java @@ -58,6 +58,13 @@ public void addPostedSticker(PostedSticker postedSticker) { postedStickers.add(postedSticker); } + @OneToMany(mappedBy = "book") + private final List favorites = new ArrayList<>(); + + public void addFavorite(Favorite favorite) { + favorites.add(favorite); + } + @Builder public Book(String uuid, String favoriteName, String favoriteImage, String title, String description, String backgroundColor, Member member, int popularRate) { this.uuid = uuid; diff --git a/src/main/java/org/sopt/lequuServer/domain/book/model/Favorite.java b/src/main/java/org/sopt/lequuServer/domain/book/model/Favorite.java new file mode 100644 index 0000000..bed9c52 --- /dev/null +++ b/src/main/java/org/sopt/lequuServer/domain/book/model/Favorite.java @@ -0,0 +1,35 @@ +package org.sopt.lequuServer.domain.book.model; + +import jakarta.persistence.*; +import lombok.*; +import org.sopt.lequuServer.domain.member.model.Member; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "favorite") +public class Favorite { + + @Id + @Column(name = "favorite_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne + @JoinColumn(name = "book_id") + private Book book; + + @Builder + public Favorite(Member member, Book book) { + this.member = member; + this.book = book; + } + + public static Favorite of(Member member, Book book) { + return new Favorite(member, book); + } +} diff --git a/src/main/java/org/sopt/lequuServer/domain/book/repository/FavoriteRepository.java b/src/main/java/org/sopt/lequuServer/domain/book/repository/FavoriteRepository.java new file mode 100644 index 0000000..8a586c2 --- /dev/null +++ b/src/main/java/org/sopt/lequuServer/domain/book/repository/FavoriteRepository.java @@ -0,0 +1,8 @@ +package org.sopt.lequuServer.domain.book.repository; + +import org.sopt.lequuServer.domain.book.model.Favorite; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FavoriteRepository extends JpaRepository { +} + diff --git a/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java b/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java index c88ab8a..c96c9d1 100644 --- a/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java +++ b/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java @@ -1,16 +1,19 @@ package org.sopt.lequuServer.domain.common.controller; import lombok.RequiredArgsConstructor; +import org.sopt.lequuServer.domain.book.dto.request.FavoriteCreateRequestDto; +import org.sopt.lequuServer.domain.book.facade.BookFacade; import org.sopt.lequuServer.domain.common.dto.response.PopularBookResponseDto; import org.sopt.lequuServer.domain.common.dto.response.SplashDto; import org.sopt.lequuServer.domain.common.facade.CommonFacade; +import org.sopt.lequuServer.global.auth.jwt.JwtProvider; import org.sopt.lequuServer.global.common.dto.ApiResponse; import org.sopt.lequuServer.global.exception.enums.SuccessType; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import java.security.Principal; import java.util.List; @RestController @@ -19,6 +22,7 @@ public class CommonController implements CommonApi { private final CommonFacade commonFacade; + private final BookFacade bookFacade; @GetMapping("/splash") public ResponseEntity> getSplash() { @@ -34,5 +38,10 @@ public ResponseEntity>> getHome() { public ResponseEntity> test() { throw new RuntimeException("테스트용 에러 발생"); } -} + @PostMapping("/home") + public ResponseEntity> createFavorite(Principal principal, @RequestBody FavoriteCreateRequestDto request) { + bookFacade.createFavorite(JwtProvider.getUserFromPrincial(principal), request); + return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(SuccessType.CREATE_FAVORITE_SUCCESS)); + } +} \ No newline at end of file diff --git a/src/main/java/org/sopt/lequuServer/domain/member/model/Member.java b/src/main/java/org/sopt/lequuServer/domain/member/model/Member.java index 3d97c97..c43fe9e 100644 --- a/src/main/java/org/sopt/lequuServer/domain/member/model/Member.java +++ b/src/main/java/org/sopt/lequuServer/domain/member/model/Member.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; import lombok.*; +import org.sopt.lequuServer.domain.book.model.Favorite; import org.sopt.lequuServer.domain.note.model.Note; import org.sopt.lequuServer.domain.book.model.Book; import org.sopt.lequuServer.domain.sticker.model.PostedSticker; @@ -73,6 +74,13 @@ public void addPostedSticker(PostedSticker postedSticker) { postedStickers.add(postedSticker); } + @OneToMany(mappedBy = "member") + private final List favorites = new ArrayList<>(); + + public void addFavorite(Favorite favorite) { + favorites.add(favorite); + } + /** * 유저가 최초로 생성될 때 필요한 최소 정보 */ diff --git a/src/main/java/org/sopt/lequuServer/global/exception/enums/SuccessType.java b/src/main/java/org/sopt/lequuServer/global/exception/enums/SuccessType.java index c77249b..572ffa4 100644 --- a/src/main/java/org/sopt/lequuServer/global/exception/enums/SuccessType.java +++ b/src/main/java/org/sopt/lequuServer/global/exception/enums/SuccessType.java @@ -33,7 +33,8 @@ public enum SuccessType { */ CREATE_BOOK_SUCCESS(HttpStatus.CREATED, "레큐북이 성공적으로 생성됐습니다."), POST_STICKER_SUCCESS(HttpStatus.CREATED, "스티커 부착에 성공했습니다."), - CREATE_NOTE_SUCCESS(HttpStatus.CREATED, "레큐노트를 성공적으로 생성했습니다.") + CREATE_NOTE_SUCCESS(HttpStatus.CREATED, "레큐노트를 성공적으로 생성했습니다."), + CREATE_FAVORITE_SUCCESS(HttpStatus.CREATED, "즐겨찾기 레큐북 등록을 성공했습니다."), /** * 204 NO CONTENT From 0e04dd67b6195ed921f5a6ae59792701222936bd Mon Sep 17 00:00:00 2001 From: eeddiinn Date: Mon, 11 Mar 2024 00:02:55 +0900 Subject: [PATCH 2/7] =?UTF-8?q?=E2=9C=A8=20[FEAT]=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=A6=90=EA=B2=A8=EC=B0=BE=EA=B8=B0=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20api=20=EA=B5=AC=ED=98=84=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/book/facade/BookFacade.java | 15 -------- .../lequuServer/domain/book/model/Book.java | 1 + .../common/controller/CommonController.java | 15 ++------ .../controller/FavoriteController.java | 30 ++++++++++++++++ .../dto/request/FavoriteCreateRequestDto.java | 2 +- .../favorite/facade/FavoriteFacade.java | 34 +++++++++++++++++++ .../{book => favorite}/model/Favorite.java | 3 +- .../repository/FavoriteRepository.java | 4 +-- .../domain/member/model/Member.java | 2 +- 9 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java rename src/main/java/org/sopt/lequuServer/domain/{book => favorite}/dto/request/FavoriteCreateRequestDto.java (70%) create mode 100644 src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java rename src/main/java/org/sopt/lequuServer/domain/{book => favorite}/model/Favorite.java (87%) rename src/main/java/org/sopt/lequuServer/domain/{book => favorite}/repository/FavoriteRepository.java (55%) diff --git a/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java b/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java index d1ab554..7ce0072 100644 --- a/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java +++ b/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java @@ -2,13 +2,10 @@ import lombok.RequiredArgsConstructor; import org.sopt.lequuServer.domain.book.dto.request.BookCreateRequestDto; -import org.sopt.lequuServer.domain.book.dto.request.FavoriteCreateRequestDto; import org.sopt.lequuServer.domain.book.dto.response.BookCreateResponseDto; import org.sopt.lequuServer.domain.book.dto.response.BookDetailResponseDto; import org.sopt.lequuServer.domain.book.model.Book; -import org.sopt.lequuServer.domain.book.model.Favorite; import org.sopt.lequuServer.domain.book.repository.BookRepository; -import org.sopt.lequuServer.domain.book.repository.FavoriteRepository; import org.sopt.lequuServer.domain.book.service.BookService; import org.sopt.lequuServer.domain.member.model.Member; import org.sopt.lequuServer.domain.member.repository.MemberRepository; @@ -40,7 +37,6 @@ public class BookFacade { private final PostedStickerRepository postedStickerRepository; private final BadWordFilterService badWordFilterService; private final S3Service s3Service; - private final FavoriteRepository favoriteRepository; @Transactional public BookCreateResponseDto createBook(BookCreateRequestDto request, Long memberId) { @@ -106,15 +102,4 @@ public BookDetailResponseDto getBookDetail(String bookUuid) { return BookDetailResponseDto.of(book); } - @Transactional - public void createFavorite(Long memberId, FavoriteCreateRequestDto request) { - Member member = memberRepository.findByIdOrThrow(memberId); - Book book = bookRepository.findByIdOrThrow(request.bookId()); - - Favorite favorite = Favorite.of(member, book); - favoriteRepository.save(favorite); - - book.addFavorite(favorite); - member.addFavorite(favorite); - } // memberId와 bookId를 favorite에 저장하는 로직 } \ No newline at end of file diff --git a/src/main/java/org/sopt/lequuServer/domain/book/model/Book.java b/src/main/java/org/sopt/lequuServer/domain/book/model/Book.java index d123de9..1a80a47 100644 --- a/src/main/java/org/sopt/lequuServer/domain/book/model/Book.java +++ b/src/main/java/org/sopt/lequuServer/domain/book/model/Book.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; import lombok.*; +import org.sopt.lequuServer.domain.favorite.model.Favorite; import org.sopt.lequuServer.domain.note.model.Note; import org.sopt.lequuServer.domain.sticker.model.PostedSticker; import org.sopt.lequuServer.domain.member.model.Member; diff --git a/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java b/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java index c96c9d1..dbbe180 100644 --- a/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java +++ b/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java @@ -1,19 +1,16 @@ package org.sopt.lequuServer.domain.common.controller; import lombok.RequiredArgsConstructor; -import org.sopt.lequuServer.domain.book.dto.request.FavoriteCreateRequestDto; -import org.sopt.lequuServer.domain.book.facade.BookFacade; import org.sopt.lequuServer.domain.common.dto.response.PopularBookResponseDto; import org.sopt.lequuServer.domain.common.dto.response.SplashDto; import org.sopt.lequuServer.domain.common.facade.CommonFacade; -import org.sopt.lequuServer.global.auth.jwt.JwtProvider; import org.sopt.lequuServer.global.common.dto.ApiResponse; import org.sopt.lequuServer.global.exception.enums.SuccessType; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; -import java.security.Principal; import java.util.List; @RestController @@ -22,7 +19,6 @@ public class CommonController implements CommonApi { private final CommonFacade commonFacade; - private final BookFacade bookFacade; @GetMapping("/splash") public ResponseEntity> getSplash() { @@ -39,9 +35,4 @@ public ResponseEntity> test() { throw new RuntimeException("테스트용 에러 발생"); } - @PostMapping("/home") - public ResponseEntity> createFavorite(Principal principal, @RequestBody FavoriteCreateRequestDto request) { - bookFacade.createFavorite(JwtProvider.getUserFromPrincial(principal), request); - return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(SuccessType.CREATE_FAVORITE_SUCCESS)); - } } \ No newline at end of file diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java new file mode 100644 index 0000000..1151709 --- /dev/null +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java @@ -0,0 +1,30 @@ +package org.sopt.lequuServer.domain.favorite.controller; + +import lombok.RequiredArgsConstructor; +import org.sopt.lequuServer.domain.favorite.dto.request.FavoriteCreateRequestDto; +import org.sopt.lequuServer.domain.favorite.facade.FavoriteFacade; +import org.sopt.lequuServer.global.auth.jwt.JwtProvider; +import org.sopt.lequuServer.global.common.dto.ApiResponse; +import org.sopt.lequuServer.global.exception.enums.SuccessType; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +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; + +import java.security.Principal; + +@RestController +@RequiredArgsConstructor +@RequestMapping("api/favorite") +public class FavoriteController { + + private final FavoriteFacade favoriteFacade; + + @PostMapping + public ResponseEntity> createFavorite(Principal principal, @RequestBody FavoriteCreateRequestDto request) { + favoriteFacade.createFavorite(JwtProvider.getUserFromPrincial(principal), request); + return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(SuccessType.CREATE_FAVORITE_SUCCESS)); + } +} diff --git a/src/main/java/org/sopt/lequuServer/domain/book/dto/request/FavoriteCreateRequestDto.java b/src/main/java/org/sopt/lequuServer/domain/favorite/dto/request/FavoriteCreateRequestDto.java similarity index 70% rename from src/main/java/org/sopt/lequuServer/domain/book/dto/request/FavoriteCreateRequestDto.java rename to src/main/java/org/sopt/lequuServer/domain/favorite/dto/request/FavoriteCreateRequestDto.java index a55a094..8fa169e 100644 --- a/src/main/java/org/sopt/lequuServer/domain/book/dto/request/FavoriteCreateRequestDto.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/dto/request/FavoriteCreateRequestDto.java @@ -1,4 +1,4 @@ -package org.sopt.lequuServer.domain.book.dto.request; +package org.sopt.lequuServer.domain.favorite.dto.request; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java b/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java new file mode 100644 index 0000000..0a8665c --- /dev/null +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java @@ -0,0 +1,34 @@ +package org.sopt.lequuServer.domain.favorite.facade; + +import lombok.RequiredArgsConstructor; +import org.sopt.lequuServer.domain.book.model.Book; +import org.sopt.lequuServer.domain.book.repository.BookRepository; +import org.sopt.lequuServer.domain.favorite.dto.request.FavoriteCreateRequestDto; +import org.sopt.lequuServer.domain.favorite.model.Favorite; +import org.sopt.lequuServer.domain.favorite.repository.FavoriteRepository; +import org.sopt.lequuServer.domain.member.model.Member; +import org.sopt.lequuServer.domain.member.repository.MemberRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class FavoriteFacade { + + private final FavoriteRepository favoriteRepository; + private final MemberRepository memberRepository; + private final BookRepository bookRepository; + + @Transactional + public void createFavorite(Long memberId, FavoriteCreateRequestDto request) { + Member member = memberRepository.findByIdOrThrow(memberId); + Book book = bookRepository.findByIdOrThrow(request.bookId()); + + Favorite favorite = Favorite.of(member, book); + favoriteRepository.save(favorite); + + book.addFavorite(favorite); + member.addFavorite(favorite); + } // memberId와 bookId를 favorite 에 저장하는 로직 +} diff --git a/src/main/java/org/sopt/lequuServer/domain/book/model/Favorite.java b/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java similarity index 87% rename from src/main/java/org/sopt/lequuServer/domain/book/model/Favorite.java rename to src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java index bed9c52..3b71c10 100644 --- a/src/main/java/org/sopt/lequuServer/domain/book/model/Favorite.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java @@ -1,7 +1,8 @@ -package org.sopt.lequuServer.domain.book.model; +package org.sopt.lequuServer.domain.favorite.model; import jakarta.persistence.*; import lombok.*; +import org.sopt.lequuServer.domain.book.model.Book; import org.sopt.lequuServer.domain.member.model.Member; @Entity diff --git a/src/main/java/org/sopt/lequuServer/domain/book/repository/FavoriteRepository.java b/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java similarity index 55% rename from src/main/java/org/sopt/lequuServer/domain/book/repository/FavoriteRepository.java rename to src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java index 8a586c2..d497d55 100644 --- a/src/main/java/org/sopt/lequuServer/domain/book/repository/FavoriteRepository.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java @@ -1,6 +1,6 @@ -package org.sopt.lequuServer.domain.book.repository; +package org.sopt.lequuServer.domain.favorite.repository; -import org.sopt.lequuServer.domain.book.model.Favorite; +import org.sopt.lequuServer.domain.favorite.model.Favorite; import org.springframework.data.jpa.repository.JpaRepository; public interface FavoriteRepository extends JpaRepository { diff --git a/src/main/java/org/sopt/lequuServer/domain/member/model/Member.java b/src/main/java/org/sopt/lequuServer/domain/member/model/Member.java index c43fe9e..312e5dd 100644 --- a/src/main/java/org/sopt/lequuServer/domain/member/model/Member.java +++ b/src/main/java/org/sopt/lequuServer/domain/member/model/Member.java @@ -2,7 +2,7 @@ import jakarta.persistence.*; import lombok.*; -import org.sopt.lequuServer.domain.book.model.Favorite; +import org.sopt.lequuServer.domain.favorite.model.Favorite; import org.sopt.lequuServer.domain.note.model.Note; import org.sopt.lequuServer.domain.book.model.Book; import org.sopt.lequuServer.domain.sticker.model.PostedSticker; From 1fb5f493975300f14cc479f7c1302cec41796d98 Mon Sep 17 00:00:00 2001 From: eeddiinn Date: Mon, 11 Mar 2024 01:00:50 +0900 Subject: [PATCH 3/7] =?UTF-8?q?=E2=9C=A8=20[FEAT]=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=A6=90=EA=B2=A8=EC=B0=BE=EA=B8=B0=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20api=20=EA=B5=AC=ED=98=84=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FavoriteController.java | 12 ++++++---- .../dto/response/FavoriteBookResponseDto.java | 24 +++++++++++++++++++ .../favorite/facade/FavoriteFacade.java | 15 +++++++++++- .../repository/FavoriteRepository.java | 4 ++++ .../global/exception/enums/SuccessType.java | 1 + 5 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/sopt/lequuServer/domain/favorite/dto/response/FavoriteBookResponseDto.java diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java index 1151709..d8cad10 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java @@ -2,18 +2,17 @@ import lombok.RequiredArgsConstructor; import org.sopt.lequuServer.domain.favorite.dto.request.FavoriteCreateRequestDto; +import org.sopt.lequuServer.domain.favorite.dto.response.FavoriteBookResponseDto; import org.sopt.lequuServer.domain.favorite.facade.FavoriteFacade; import org.sopt.lequuServer.global.auth.jwt.JwtProvider; import org.sopt.lequuServer.global.common.dto.ApiResponse; import org.sopt.lequuServer.global.exception.enums.SuccessType; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -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; +import org.springframework.web.bind.annotation.*; import java.security.Principal; +import java.util.List; @RestController @RequiredArgsConstructor @@ -27,4 +26,9 @@ public ResponseEntity> createFavorite(Principal principal, @Reque favoriteFacade.createFavorite(JwtProvider.getUserFromPrincial(principal), request); return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(SuccessType.CREATE_FAVORITE_SUCCESS)); } + + @GetMapping + public ResponseEntity>> getFavorite(Principal principal) { + return ResponseEntity.ok(ApiResponse.success(SuccessType.GET_FAVORITE_SUCCESS, favoriteFacade.getFavorite(JwtProvider.getUserFromPrincial(principal)))); + } } diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/dto/response/FavoriteBookResponseDto.java b/src/main/java/org/sopt/lequuServer/domain/favorite/dto/response/FavoriteBookResponseDto.java new file mode 100644 index 0000000..81eecd9 --- /dev/null +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/dto/response/FavoriteBookResponseDto.java @@ -0,0 +1,24 @@ +package org.sopt.lequuServer.domain.favorite.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import org.sopt.lequuServer.domain.book.model.Book; + +public record FavoriteBookResponseDto( + + @Schema(description = "레큐북 고유 id", example = "1") + Long bookId, + + @Schema(description = "레큐북 UUID", example = "ee4f66f9-9cf4-4b28-90f4-f71d0ecba021") + String bookUuid, + + @Schema(description = "최애 이름", example = "LeoJ") + String favoriteName, + + @Schema(description = "최애 사진", example = "https://dzfv99wxq6tx0.cloudfront.net/books/favorite_image/b4006561-382b-479e-ae1d-e841922e883f.jpg") + String favoriteImage +) { + public static FavoriteBookResponseDto of(Book book) { + return new FavoriteBookResponseDto(book.getId(), book.getUuid(), book.getFavoriteName(), + book.getFavoriteImage()); + } +} diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java b/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java index 0a8665c..c895d97 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java @@ -4,6 +4,7 @@ import org.sopt.lequuServer.domain.book.model.Book; import org.sopt.lequuServer.domain.book.repository.BookRepository; import org.sopt.lequuServer.domain.favorite.dto.request.FavoriteCreateRequestDto; +import org.sopt.lequuServer.domain.favorite.dto.response.FavoriteBookResponseDto; import org.sopt.lequuServer.domain.favorite.model.Favorite; import org.sopt.lequuServer.domain.favorite.repository.FavoriteRepository; import org.sopt.lequuServer.domain.member.model.Member; @@ -11,6 +12,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.stream.Collectors; + @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -31,4 +35,13 @@ public void createFavorite(Long memberId, FavoriteCreateRequestDto request) { book.addFavorite(favorite); member.addFavorite(favorite); } // memberId와 bookId를 favorite 에 저장하는 로직 -} + + public List getFavorite(Long memberId) { + Member member = memberRepository.findByIdOrThrow(memberId); + List favorites = favoriteRepository.findByMember(member); + + return favorites.stream() + .map(favorite -> FavoriteBookResponseDto.of(favorite.getBook())) + .collect(Collectors.toList()); + } // memberId를 이용해 그 멤버가 즐겨찾기 해놓은 레큐북 목록들을 반환하는 로직 +} \ No newline at end of file diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java b/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java index d497d55..46366ed 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java @@ -1,8 +1,12 @@ package org.sopt.lequuServer.domain.favorite.repository; import org.sopt.lequuServer.domain.favorite.model.Favorite; +import org.sopt.lequuServer.domain.member.model.Member; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + public interface FavoriteRepository extends JpaRepository { + List findByMember(Member member); } diff --git a/src/main/java/org/sopt/lequuServer/global/exception/enums/SuccessType.java b/src/main/java/org/sopt/lequuServer/global/exception/enums/SuccessType.java index 572ffa4..a356810 100644 --- a/src/main/java/org/sopt/lequuServer/global/exception/enums/SuccessType.java +++ b/src/main/java/org/sopt/lequuServer/global/exception/enums/SuccessType.java @@ -27,6 +27,7 @@ public enum SuccessType { GET_MYPAGE_BOOK_SUCCESS(HttpStatus.OK, "마이페이지의 유저 닉네임과 내 레큐북 조회에 성공했습니다."), GET_MYPAGE_NOTE_SUCCESS(HttpStatus.OK, "마이페이지의 유저 닉네임과 내 레큐노트 조회에 성공했습니다."), GET_BOOK_DETAIL_SUCCESS(HttpStatus.OK, "레큐북 상세 조회에 성공했습니다"), + GET_FAVORITE_SUCCESS(HttpStatus.OK, "즐겨찾는 레큐북 조회에 성공했습니다."), /** * 201 CREATED From 07d71975e36c7a281d3627bb72ec3a2ac459faf7 Mon Sep 17 00:00:00 2001 From: dong2ast Date: Mon, 11 Mar 2024 22:19:38 +0900 Subject: [PATCH 4/7] =?UTF-8?q?=E2=9C=A8=20[FEAT]=20Swagger=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/favorite/controller/FavoriteController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java index d8cad10..43e151f 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java @@ -1,5 +1,6 @@ package org.sopt.lequuServer.domain.favorite.controller; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import lombok.RequiredArgsConstructor; import org.sopt.lequuServer.domain.favorite.dto.request.FavoriteCreateRequestDto; import org.sopt.lequuServer.domain.favorite.dto.response.FavoriteBookResponseDto; @@ -14,6 +15,7 @@ import java.security.Principal; import java.util.List; +@SecurityRequirement(name = "JWT Authorization") @RestController @RequiredArgsConstructor @RequestMapping("api/favorite") From 65cf0b358c03068117c4f514af84e7529550e4cc Mon Sep 17 00:00:00 2001 From: eeddiinn Date: Tue, 12 Mar 2024 23:06:50 +0900 Subject: [PATCH 5/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=20[REFACTOR]=20PR=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../favorite/controller/FavoriteApi.java | 37 +++++++++++++++++++ .../controller/FavoriteController.java | 4 +- .../domain/favorite/model/Favorite.java | 11 ++++-- 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteApi.java diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteApi.java b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteApi.java new file mode 100644 index 0000000..a55818c --- /dev/null +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteApi.java @@ -0,0 +1,37 @@ +package org.sopt.lequuServer.domain.favorite.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.sopt.lequuServer.domain.favorite.dto.request.FavoriteCreateRequestDto; +import org.sopt.lequuServer.domain.favorite.dto.response.FavoriteBookResponseDto; +import org.sopt.lequuServer.global.common.dto.ApiResponse; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; + +import java.security.Principal; +import java.util.List; + +@Tag(name = "Favorite", description = "즐겨찾기 API") +public interface FavoriteApi { + + @SecurityRequirement(name = "JWT Authorization") + @io.swagger.v3.oas.annotations.responses.ApiResponse( + responseCode = "201", + description = "즐겨찾기 레큐북 등록을 성공했습니다." + ) + @Operation(summary = "즐겨찾기 레큐북 생성") + public ResponseEntity> createFavorite(Principal principal, @RequestBody FavoriteCreateRequestDto request); + + @SecurityRequirement(name = "JWT Authorization") + @io.swagger.v3.oas.annotations.responses.ApiResponse( + responseCode = "200", + description = "즐겨찾는 레큐북 조회에 성공했습니다.", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = FavoriteBookResponseDto.class))) + ) + @Operation(summary = "즐겨찾는 레큐북 조회") + public ResponseEntity>> getFavorite(Principal principal); +} \ No newline at end of file diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java index d8cad10..6041c38 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/controller/FavoriteController.java @@ -16,8 +16,8 @@ @RestController @RequiredArgsConstructor -@RequestMapping("api/favorite") -public class FavoriteController { +@RequestMapping("/api/favorite") +public class FavoriteController implements FavoriteApi { private final FavoriteFacade favoriteFacade; diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java b/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java index 3b71c10..f9fe3f3 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java @@ -16,11 +16,11 @@ public class Favorite { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "book_id") private Book book; @@ -31,6 +31,9 @@ public Favorite(Member member, Book book) { } public static Favorite of(Member member, Book book) { - return new Favorite(member, book); + Favorite favorite = new Favorite(member, book); + book.addFavorite(favorite); + member.addFavorite(favorite); + return favorite; } -} +} \ No newline at end of file From 32959edb51e814ce9b27bcc31157ce9b4338507f Mon Sep 17 00:00:00 2001 From: eeddiinn Date: Tue, 12 Mar 2024 23:25:26 +0900 Subject: [PATCH 6/7] =?UTF-8?q?=E2=9C=A8=20[FEAT]=20=EC=A6=90=EA=B2=A8?= =?UTF-8?q?=EC=B0=BE=EA=B8=B0=20=EB=A0=88=ED=81=90=EB=B6=81=20=EC=B5=9C?= =?UTF-8?q?=EC=8B=A0=EC=88=9C=EC=9C=BC=EB=A1=9C=203=EA=B0=9C=EB=A7=8C=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lequuServer/domain/favorite/facade/FavoriteFacade.java | 3 ++- .../org/sopt/lequuServer/domain/favorite/model/Favorite.java | 3 ++- .../domain/favorite/repository/FavoriteRepository.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java b/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java index c895d97..2244952 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java @@ -38,9 +38,10 @@ public void createFavorite(Long memberId, FavoriteCreateRequestDto request) { public List getFavorite(Long memberId) { Member member = memberRepository.findByIdOrThrow(memberId); - List favorites = favoriteRepository.findByMember(member); + List favorites = favoriteRepository.findByMemberOrderByCreatedAtDesc(member); return favorites.stream() + .limit(3) // 최신순 3개만 가져오기 .map(favorite -> FavoriteBookResponseDto.of(favorite.getBook())) .collect(Collectors.toList()); } // memberId를 이용해 그 멤버가 즐겨찾기 해놓은 레큐북 목록들을 반환하는 로직 diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java b/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java index f9fe3f3..14b7fe9 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/model/Favorite.java @@ -4,12 +4,13 @@ import lombok.*; import org.sopt.lequuServer.domain.book.model.Book; import org.sopt.lequuServer.domain.member.model.Member; +import org.sopt.lequuServer.global.common.model.BaseTimeEntity; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "favorite") -public class Favorite { +public class Favorite extends BaseTimeEntity { @Id @Column(name = "favorite_id") diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java b/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java index 46366ed..e76b6ad 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/repository/FavoriteRepository.java @@ -7,6 +7,6 @@ import java.util.List; public interface FavoriteRepository extends JpaRepository { - List findByMember(Member member); + List findByMemberOrderByCreatedAtDesc(Member member); } From 0b545cb2f68a8f1f46fb1bc6c2d04ea839c73611 Mon Sep 17 00:00:00 2001 From: dong2ast Date: Wed, 13 Mar 2024 13:08:43 +0900 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20[CHORE]=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=EB=90=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lequuServer/domain/common/controller/CommonController.java | 1 - .../lequuServer/domain/favorite/facade/FavoriteFacade.java | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java b/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java index dbbe180..2dd6288 100644 --- a/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java +++ b/src/main/java/org/sopt/lequuServer/domain/common/controller/CommonController.java @@ -34,5 +34,4 @@ public ResponseEntity>> getHome() { public ResponseEntity> test() { throw new RuntimeException("테스트용 에러 발생"); } - } \ No newline at end of file diff --git a/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java b/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java index 2244952..8816827 100644 --- a/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java +++ b/src/main/java/org/sopt/lequuServer/domain/favorite/facade/FavoriteFacade.java @@ -31,9 +31,6 @@ public void createFavorite(Long memberId, FavoriteCreateRequestDto request) { Favorite favorite = Favorite.of(member, book); favoriteRepository.save(favorite); - - book.addFavorite(favorite); - member.addFavorite(favorite); } // memberId와 bookId를 favorite 에 저장하는 로직 public List getFavorite(Long memberId) {