diff --git a/server-yml b/server-yml index a2dc8164..247c1e4e 160000 --- a/server-yml +++ b/server-yml @@ -1 +1 @@ -Subproject commit a2dc8164e7a0e08037521a2eef49a811a0d1857d +Subproject commit 247c1e4e5c3b71a3ca12b7759a8e7f086e617746 diff --git a/src/main/java/org/hankki/hankkiserver/api/favorite/controller/FavoriteController.java b/src/main/java/org/hankki/hankkiserver/api/favorite/controller/FavoriteController.java index dba6479f..7b58cee3 100644 --- a/src/main/java/org/hankki/hankkiserver/api/favorite/controller/FavoriteController.java +++ b/src/main/java/org/hankki/hankkiserver/api/favorite/controller/FavoriteController.java @@ -5,6 +5,7 @@ import org.hankki.hankkiserver.api.dto.HankkiResponse; import org.hankki.hankkiserver.api.favorite.controller.request.FavoriteDeleteRequest; import org.hankki.hankkiserver.api.favorite.service.FavoriteCommandService; +import org.hankki.hankkiserver.api.favorite.service.command.FavoriteGetCommand; import org.hankki.hankkiserver.api.favorite.service.command.FavoritePostCommand; import org.hankki.hankkiserver.api.favorite.controller.request.FavoritePostRequest; import org.hankki.hankkiserver.api.favorite.service.command.FavoritesDeleteCommand; @@ -12,6 +13,10 @@ import org.hankki.hankkiserver.common.code.CommonSuccessCode; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.hankki.hankkiserver.api.favorite.service.FavoriteQueryService; +import org.hankki.hankkiserver.api.favorite.service.response.FavoriteFindResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -21,6 +26,7 @@ public class FavoriteController { private final FavoriteCommandService favoriteCommandService; + private final FavoriteQueryService favoriteQueryService; @PostMapping("/favorites") public HankkiResponse createFavorite(@UserId final Long userId, @RequestBody @Valid final FavoritePostRequest request) { @@ -35,4 +41,9 @@ public HankkiResponse deleteFavorite(@UserId final Long userId, @RequestBo favoriteCommandService.deleteFavorites(FavoritesDeleteCommand.of(userId, request)); return HankkiResponse.success(CommonSuccessCode.NO_CONTENT); } + + @GetMapping("/favorites/{favoriteId}") + public HankkiResponse getFavorite(@UserId final Long userId, @PathVariable(name = "favoriteId") final Long favoriteId) { + return HankkiResponse.success(CommonSuccessCode.OK, favoriteQueryService.findFavorite(FavoriteGetCommand.of(userId, favoriteId))); + } } \ No newline at end of file diff --git a/src/main/java/org/hankki/hankkiserver/api/favorite/service/FavoriteQueryService.java b/src/main/java/org/hankki/hankkiserver/api/favorite/service/FavoriteQueryService.java new file mode 100644 index 00000000..2a9a1cd4 --- /dev/null +++ b/src/main/java/org/hankki/hankkiserver/api/favorite/service/FavoriteQueryService.java @@ -0,0 +1,26 @@ +package org.hankki.hankkiserver.api.favorite.service; + +import lombok.RequiredArgsConstructor; +import org.hankki.hankkiserver.api.auth.service.UserFinder; +import org.hankki.hankkiserver.api.favorite.service.command.FavoriteGetCommand; +import org.hankki.hankkiserver.api.favorite.service.response.FavoriteFindResponse; +import org.hankki.hankkiserver.common.code.UserErrorCode; +import org.hankki.hankkiserver.common.exception.UnauthorizedException; +import org.hankki.hankkiserver.domain.favorite.model.Favorite; +import org.hankki.hankkiserver.domain.favoritestore.model.FavoriteStore; +import org.hankki.hankkiserver.domain.user.model.User; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class FavoriteQueryService { + + private final FavoriteFinder favoriteFinder; + + @Transactional(readOnly = true) + public FavoriteFindResponse findFavorite(final FavoriteGetCommand command) { + Favorite favorite = favoriteFinder.findById(command.favoriteId()); + return FavoriteFindResponse.of(favorite, favorite.getFavoriteStores().stream().map(FavoriteStore::getStore).toList()); + } +} diff --git a/src/main/java/org/hankki/hankkiserver/api/favorite/service/command/FavoriteGetCommand.java b/src/main/java/org/hankki/hankkiserver/api/favorite/service/command/FavoriteGetCommand.java new file mode 100644 index 00000000..765d41de --- /dev/null +++ b/src/main/java/org/hankki/hankkiserver/api/favorite/service/command/FavoriteGetCommand.java @@ -0,0 +1,10 @@ +package org.hankki.hankkiserver.api.favorite.service.command; + +public record FavoriteGetCommand( + Long userId, + Long favoriteId +) { + public static FavoriteGetCommand of(final Long userId, final Long favoriteId) { + return new FavoriteGetCommand(userId, favoriteId); + } +} \ No newline at end of file diff --git a/src/main/java/org/hankki/hankkiserver/api/favorite/service/response/FavoriteFindResponse.java b/src/main/java/org/hankki/hankkiserver/api/favorite/service/response/FavoriteFindResponse.java new file mode 100644 index 00000000..73d57243 --- /dev/null +++ b/src/main/java/org/hankki/hankkiserver/api/favorite/service/response/FavoriteFindResponse.java @@ -0,0 +1,31 @@ +package org.hankki.hankkiserver.api.favorite.service.response; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.hankki.hankkiserver.domain.favorite.model.Favorite; +import org.hankki.hankkiserver.domain.store.model.Store; + +public record FavoriteFindResponse( + String title, + List details, + List stores +) { + + public static FavoriteFindResponse of(final Favorite favorite, final List stores) { + + List details = new ArrayList<>(); + if (!isDetailNull(favorite.getDetail())) { + details = Arrays.asList(favorite.getDetail().split(" ")); + } + + return new FavoriteFindResponse( + favorite.getName(), + details, + stores.stream().map(FavoriteStoreFindResponse::of).toList()); + } + + public static boolean isDetailNull(String detail) { + return detail == null; + } +} diff --git a/src/main/java/org/hankki/hankkiserver/api/favorite/service/response/FavoriteStoreFindResponse.java b/src/main/java/org/hankki/hankkiserver/api/favorite/service/response/FavoriteStoreFindResponse.java new file mode 100644 index 00000000..1aa084cf --- /dev/null +++ b/src/main/java/org/hankki/hankkiserver/api/favorite/service/response/FavoriteStoreFindResponse.java @@ -0,0 +1,25 @@ +package org.hankki.hankkiserver.api.favorite.service.response; + +import org.hankki.hankkiserver.domain.store.model.Store; +import org.hankki.hankkiserver.domain.store.model.StoreCategory; + +public record FavoriteStoreFindResponse( + Long id, + String name, + String imageUrl, + String category, + int lowestPrice, + int heartCount +) { + + public static FavoriteStoreFindResponse of(Store store) { + + return new FavoriteStoreFindResponse( + store.getId(), + store.getName(), + store.getImage(), + store.getCategory().getName(), + store.getLowestPrice(), + store.getHeartCount()); + } +} diff --git a/src/main/java/org/hankki/hankkiserver/domain/favorite/model/Favorite.java b/src/main/java/org/hankki/hankkiserver/domain/favorite/model/Favorite.java index c7f97a10..7ad6bd39 100644 --- a/src/main/java/org/hankki/hankkiserver/domain/favorite/model/Favorite.java +++ b/src/main/java/org/hankki/hankkiserver/domain/favorite/model/Favorite.java @@ -10,6 +10,7 @@ import org.hankki.hankkiserver.domain.common.BaseTimeEntity; import org.hankki.hankkiserver.domain.favoritestore.model.FavoriteStore; import org.hankki.hankkiserver.domain.user.model.User; +import org.hibernate.annotations.BatchSize; @Entity @Getter @@ -34,6 +35,7 @@ public class Favorite extends BaseTimeEntity { private String image_url; @OneToMany(mappedBy = "favorite") + @BatchSize(size = 100) private List favoriteStores = new ArrayList<>(); public static Favorite create(User user, String name, String detail) { diff --git a/src/main/java/org/hankki/hankkiserver/domain/store/model/Store.java b/src/main/java/org/hankki/hankkiserver/domain/store/model/Store.java index 46402d86..61f7ffc8 100644 --- a/src/main/java/org/hankki/hankkiserver/domain/store/model/Store.java +++ b/src/main/java/org/hankki/hankkiserver/domain/store/model/Store.java @@ -1,17 +1,19 @@ package org.hankki.hankkiserver.domain.store.model; import jakarta.persistence.*; +import java.util.ArrayList; +import java.util.List; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import org.hankki.hankkiserver.domain.common.BaseTimeEntity; import org.hankki.hankkiserver.domain.common.Point; import org.hankki.hankkiserver.domain.heart.model.Heart; - -import java.util.List; +import org.hibernate.annotations.BatchSize; @Entity @Getter +@BatchSize(size = 100) @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Store extends BaseTimeEntity { @@ -45,6 +47,17 @@ public class Store extends BaseTimeEntity { @Column(nullable = false) private boolean isDeleted; + @OneToMany(mappedBy = "store") + @BatchSize(size = 100) + private List storeImages = new ArrayList<>(); + + public String getImage() { + if (storeImages.isEmpty()) { + return "default.com"; + } + return storeImages.get(0).getImageUrl(); + } + public void decreaseHeartCount() { this.heartCount--; }