diff --git a/src/main/generated/kw/zeropick/member/domain/QMember.java b/src/main/generated/kw/zeropick/member/domain/QMember.java index 897a07a..c5d5553 100644 --- a/src/main/generated/kw/zeropick/member/domain/QMember.java +++ b/src/main/generated/kw/zeropick/member/domain/QMember.java @@ -27,6 +27,8 @@ public class QMember extends EntityPathBase { public final NumberPath id = createNumber("id", Long.class); + public final EnumPath interest = createEnum("interest", MemberInterest.class); + public final EnumPath marketingAgree = createEnum("marketingAgree", MarketingAgree.class); public final StringPath name = createString("name"); diff --git a/src/main/java/kw/zeropick/home/controller/HomeController.java b/src/main/java/kw/zeropick/home/controller/HomeController.java index bb4fd46..f8b940c 100644 --- a/src/main/java/kw/zeropick/home/controller/HomeController.java +++ b/src/main/java/kw/zeropick/home/controller/HomeController.java @@ -9,11 +9,8 @@ import kw.zeropick.home.service.HomeService; import kw.zeropick.payload.ApiResponse; import kw.zeropick.product.domain.Category; -import kw.zeropick.product.dto.ProductDto; -import kw.zeropick.product.service.ProductService; import lombok.Builder; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -28,27 +25,12 @@ public class HomeController { private final HomeService homeService; -// @Operation(summary = "홈 화면 조회", description = "홈 화면을 조회합니다.") -// @GetMapping -// public ResponseEntity home(@RequestHeader(value = "Authorization", required = false) String token) { -// -// if (token != null) { -// Long memberId = LoginUser.get().getId(); // 회원일 경우 ID 가져오기 -// return ResponseEntity.ok( -// HomeResponse.builder() -// .topPopularityProducts(homeService.getTopPopularityProducts(4)) -//// .recommendedProducts(homeService.getRecommendedProducts(memberId)) -// .build() -// ); -// } else{ -// // 비회원일 경우 -// return ResponseEntity.ok( -// HomeResponse.builder() -// .topPopularityProducts(homeService.getTopPopularityProducts(4)) -// .build() -// ); -// } -// } + @Operation(summary = "홈 화면 조회", description = "홈 화면을 조회합니다.") + @GetMapping + public ResponseEntity home(@RequestHeader(value = "Authorization", required = false) String token) { + HomeResponse homeResponse = homeService.getHomeResponse(token); + return ResponseEntity.ok(homeResponse); + } @Operation(summary = "홈 카테고리 베스트 조회", description = "카테고리 베스트를 조회합니다.") diff --git a/src/main/java/kw/zeropick/home/service/HomeService.java b/src/main/java/kw/zeropick/home/service/HomeService.java index 2348c4f..3bb0f91 100644 --- a/src/main/java/kw/zeropick/home/service/HomeService.java +++ b/src/main/java/kw/zeropick/home/service/HomeService.java @@ -1,12 +1,13 @@ package kw.zeropick.home.service; import java.util.List; + +import kw.zeropick.home.dto.response.HomeResponse; import kw.zeropick.home.dto.response.ProductBestResponse; import kw.zeropick.product.domain.Category; import kw.zeropick.product.domain.Product; public interface HomeService { List categoryBest(Long memberId, Category category); - List getTopPopularityProducts(int limit, String token); - ProductBestResponse toProductBestResponse (Product product); + HomeResponse getHomeResponse(String token); } diff --git a/src/main/java/kw/zeropick/home/service/HomeServiceImpl.java b/src/main/java/kw/zeropick/home/service/HomeServiceImpl.java index 5f01f86..98c34b6 100644 --- a/src/main/java/kw/zeropick/home/service/HomeServiceImpl.java +++ b/src/main/java/kw/zeropick/home/service/HomeServiceImpl.java @@ -2,7 +2,10 @@ import java.util.List; import kw.zeropick.common.LoginUser; +import kw.zeropick.home.dto.response.HomeResponse; import kw.zeropick.home.dto.response.ProductBestResponse; +import kw.zeropick.member.domain.MemberInterest; +import kw.zeropick.member.service.MemberService; import kw.zeropick.product.domain.Category; import kw.zeropick.product.domain.Product; import kw.zeropick.product.domain.ProductSort; @@ -26,6 +29,7 @@ public class HomeServiceImpl implements HomeService { private final ProductService productService; private final ReviewService reviewService; + private final MemberService memberService; @Override public List categoryBest(Long memberId, Category category) { @@ -59,69 +63,107 @@ public List categoryBest(Long memberId, Category category) return bestResponses; } - +// +// @Override +// @Transactional +// public ProductBestResponse toProductBestResponse (Product product){ +// Long memberId = null; +// try { +// memberId = LoginUser.get().getId(); // 로그인 사용자 정보 가져오기 +// } catch (Exception e) { +// // 비회원인 경우 memberId는 null로 설정 +// } +// +// ProductBestResponse.ProductBestResponseBuilder builder = ProductBestResponse.builder() +// .id(product.getId()) +// .productName(product.getProductName()) +// .category(product.getCategory()) +// .zeroSugar(product.getZeroSugar()) +// .zeroKcal(product.getZeroKcal()) +// .price(product.getPrice()) +// .starRate(product.getStarRate()) +// .imageUrl(product.getImageUrl()) +// .reviewCount(product.getReviewCount()); +// +// if (memberId != null) { // 회원일 경우 +// builder.bookmarked(productService.isBookmarkedByUser(product.getId(), memberId)) +// .compared(productService.isComparedByUser(product.getId(), memberId)); +// } else { // 비회원일 경우 +// builder.bookmarked(null) +// .compared(null); +// } +// +// return builder.build(); +// } + @Override @Transactional - public ProductBestResponse toProductBestResponse (Product product){ - Long memberId = null; - try { - memberId = LoginUser.get().getId(); // 로그인 사용자 정보 가져오기 - } catch (Exception e) { - // 비회원인 경우 memberId는 null로 설정 - } + public HomeResponse getHomeResponse(String token) { + HomeResponse.HomeResponseBuilder responseBuilder = HomeResponse.builder(); + + // 공통 인기 상품 검색 요청 생성 + ProductSearchRequest popularRequest = ProductSearchRequest.builder() + .sort(ProductSort.POPULARITY) + .build(); + + // 인기 상품 검색 (4개) + List topPopularityProducts = productService.productSearch(1L, 0, 4, popularRequest) + .getContent() + .stream() + .map(this::toProductBestResponse) + .collect(Collectors.toList()); + + responseBuilder.topPopularityProducts(topPopularityProducts); + + // 회원일 경우 추가적으로 추천 상품을 검색 + if (token != null) { + MemberInterest memberInterest = memberService.getMemberInterest(1L); + + ProductSearchRequest recommendedRequest = createRecommendedRequest(memberInterest); + + List recommendedProducts = productService.productSearch(1L, 0, 4, recommendedRequest) + .getContent() + .stream() + .map(this::toProductBestResponse) + .collect(Collectors.toList()); - ProductBestResponse.ProductBestResponseBuilder builder = ProductBestResponse.builder() - .id(product.getId()) - .productName(product.getProductName()) - .category(product.getCategory()) - .zeroSugar(product.getZeroSugar()) - .zeroKcal(product.getZeroKcal()) - .price(product.getPrice()) - .starRate(product.getStarRate()) - .imageUrl(product.getImageUrl()) - .reviewCount(product.getReviewCount()); - - if (memberId != null) { // 회원일 경우 - builder.bookmarked(productService.isBookmarkedByUser(product.getId(), memberId)) - .compared(productService.isComparedByUser(product.getId(), memberId)); - } else { // 비회원일 경우 - builder.bookmarked(null) - .compared(null); + responseBuilder.recommendedProducts(recommendedProducts); } - return builder.build(); + return responseBuilder.build(); } - @Override - @Transactional - public List getTopPopularityProducts ( int limit, String token){ - // 인기 상품 검색 요청 생성 - ProductSearchRequest productSearchRequest = ProductSearchRequest.builder() - .zeroKcal(Boolean.TRUE) - - .sort(ProductSort.POPULARITY) + private ProductBestResponse toProductBestResponse(ProductDto productDto) { + return ProductBestResponse.builder() + .id(productDto.getId()) + .productName(productDto.getProductName()) + .category(productDto.getCategory()) + .zeroSugar(productDto.getZeroSugar()) + .zeroKcal(productDto.getZeroKcal()) + .price(productDto.getPrice()) + .starRate(productDto.getStarRate()) + .imageUrl(productDto.getImageUrl()) + .reviewCount(productDto.getReviewCount()) + .bookmarked(productDto.getBookmarked()) + .compared(productDto.getCompared()) .build(); + } + + private ProductSearchRequest createRecommendedRequest(MemberInterest memberInterest) { + ProductSearchRequest.ProductSearchRequestBuilder requestBuilder = ProductSearchRequest.builder() + .sort(ProductSort.POPULARITY); - // 상품 검색 서비스 호출 (limit 개수만 가져옴) - Page productDtos = productService.productSearch(1L, 0, limit, productSearchRequest); - - // ProductDto 리스트를 ProductBestResponse로 매핑 - return productDtos.getContent().stream() - .map(productDto -> ProductBestResponse.builder() - .id(productDto.getId()) - .productName(productDto.getProductName()) - .category(productDto.getCategory()) - .zeroSugar(productDto.getZeroSugar()) - .zeroKcal(productDto.getZeroKcal()) - .price(productDto.getPrice()) - .starRate(productDto.getStarRate()) - .imageUrl(productDto.getImageUrl()) - .reviewCount(productDto.getReviewCount()) - .reviewResponse(null) // 리뷰 관련 로직 필요 시 업데이트 - .bookmarked(productDto.getBookmarked()) - .compared(productDto.getCompared()) - .build() - ) - .toList(); + if (memberInterest == MemberInterest.BOTH) { + requestBuilder.zeroSugar(true).zeroKcal(true); + } else if (memberInterest == MemberInterest.ZEROKCAL) { + requestBuilder.zeroSugar(false).zeroKcal(true); + } else if (memberInterest == MemberInterest.ZEROSUGAR) { + requestBuilder.zeroSugar(true).zeroKcal(false); + } else if (memberInterest == MemberInterest.NONE) { + requestBuilder.zeroSugar(false).zeroKcal(false); + } + + return requestBuilder.build(); } + } \ No newline at end of file diff --git a/src/main/java/kw/zeropick/member/domain/Member.java b/src/main/java/kw/zeropick/member/domain/Member.java index b4ccbc3..3d0ada7 100644 --- a/src/main/java/kw/zeropick/member/domain/Member.java +++ b/src/main/java/kw/zeropick/member/domain/Member.java @@ -35,9 +35,8 @@ public class Member { @NotNull private String password; - -// @Convert(converter = StringListToStringConverter.class) -// private List field; + @Enumerated(EnumType.STRING) + private MemberInterest interest; @NotNull @Enumerated(EnumType.STRING) diff --git a/src/main/java/kw/zeropick/member/domain/MemberInterest.java b/src/main/java/kw/zeropick/member/domain/MemberInterest.java new file mode 100644 index 0000000..c5ef6ea --- /dev/null +++ b/src/main/java/kw/zeropick/member/domain/MemberInterest.java @@ -0,0 +1,8 @@ +package kw.zeropick.member.domain; + +public enum MemberInterest { + BOTH, + ZEROKCAL, + ZEROSUGAR, + NONE +} diff --git a/src/main/java/kw/zeropick/member/service/MemberService.java b/src/main/java/kw/zeropick/member/service/MemberService.java index 10e2bde..8711dd3 100644 --- a/src/main/java/kw/zeropick/member/service/MemberService.java +++ b/src/main/java/kw/zeropick/member/service/MemberService.java @@ -1,8 +1,10 @@ package kw.zeropick.member.service; +import jakarta.persistence.EntityNotFoundException; import kw.zeropick.common.domain.exception.ResourceNotFoundException; import kw.zeropick.member.controller.response.MemberInfoResponse; import kw.zeropick.member.domain.Member; +import kw.zeropick.member.domain.MemberInterest; import kw.zeropick.member.domain.exception.ConfirmPasswordMismatchException; import kw.zeropick.member.domain.exception.FieldUpdateException; import kw.zeropick.member.domain.exception.InvalidMemberDataException; @@ -91,5 +93,11 @@ public Member updateMemberInfo(Long memberId, MemberInfoChangeDto memberInfoChan return member; } + public MemberInterest getMemberInterest(Long memberId) { + Member member = memberJpaRepository.findById(memberId) + .orElseThrow(() -> new EntityNotFoundException("해당 회원을 찾을 수 없습니다. ID: " + memberId)); + + return member.getInterest(); + } }