diff --git a/src/main/java/kw/zeropick/home/controller/HomeController.java b/src/main/java/kw/zeropick/home/controller/HomeController.java index 99c6194..157c5e4 100644 --- a/src/main/java/kw/zeropick/home/controller/HomeController.java +++ b/src/main/java/kw/zeropick/home/controller/HomeController.java @@ -2,17 +2,22 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +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.home.service.HomeService; import kw.zeropick.payload.ApiResponse; +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.*; + @Tag(name = "home", description = "홈 화면 API") @Builder @RestController @@ -44,4 +49,26 @@ public class HomeController { // } // } + + @Operation(summary = "홈 카테고리 베스트 조회", description = "카테고리 베스트를 조회합니다.") + @GetMapping("/category") + public ResponseEntity homeCategory(@RequestParam Category category) { + Long memberId = LoginUser.get().getId(); + try { + List productBestResponses = homeService.categoryBest(memberId, category); + return ResponseEntity.ok( + ApiResponse.builder() + .check(true) + .information(productBestResponses) + .build() + ); + } catch (Exception e) { + return ResponseEntity.internalServerError().body( + ApiResponse.builder() + .check(false) + .information(e.getMessage()) + .build() + ); + } + } } \ No newline at end of file diff --git a/src/main/java/kw/zeropick/home/dto/response/ProductBestResponse.java b/src/main/java/kw/zeropick/home/dto/response/ProductBestResponse.java index 3891c4d..fe7de5f 100644 --- a/src/main/java/kw/zeropick/home/dto/response/ProductBestResponse.java +++ b/src/main/java/kw/zeropick/home/dto/response/ProductBestResponse.java @@ -1,40 +1,40 @@ -package kw.zeropick.home.dto.response; - -import kw.zeropick.product.domain.Category; -import kw.zeropick.review.dto.response.ReviewResponse; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.Setter; - -@Builder -@Data -@AllArgsConstructor -public class ProductBestResponse { - private Long id; - - private String productName; - - private Category category; - - private Boolean zeroSugar; - - private Boolean zeroKcal; - - private int price; - - private Double starRate; - - private String imageUrl; - - private int reviewCount; - - private ReviewResponse reviewResponse; - - // 좋아요 여부 - @Setter - private Boolean bookmarked; - // 비교함 여부 - @Setter - private Boolean compared; -} +package kw.zeropick.home.dto.response; + +import kw.zeropick.product.domain.Category; +import kw.zeropick.review.dto.response.ReviewResponse; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.Setter; + +@Builder +@Data +@AllArgsConstructor +public class ProductBestResponse { + private Long id; + + private String productName; + + private Category category; + + private Boolean zeroSugar; + + private Boolean zeroKcal; + + private int price; + + private Double starRate; + + private String imageUrl; + + private int reviewCount; + + private ReviewResponse reviewResponse; + + // 좋아요 여부 + @Setter + private Boolean bookmarked; + // 비교함 여부 + @Setter + private Boolean compared; +} diff --git a/src/main/java/kw/zeropick/home/service/HomeService.java b/src/main/java/kw/zeropick/home/service/HomeService.java index aff6dd8..70290a1 100644 --- a/src/main/java/kw/zeropick/home/service/HomeService.java +++ b/src/main/java/kw/zeropick/home/service/HomeService.java @@ -1,9 +1,10 @@ package kw.zeropick.home.service; -import kw.zeropick.home.dto.response.ProductBestResponse; - import java.util.List; +import kw.zeropick.home.dto.response.ProductBestResponse; +import kw.zeropick.product.domain.Category; public interface HomeService { + List categoryBest(Long memberId, Category category); List getTopPopularityProducts(int limit, 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 fb5879f..4f4d34c 100644 --- a/src/main/java/kw/zeropick/home/service/HomeServiceImpl.java +++ b/src/main/java/kw/zeropick/home/service/HomeServiceImpl.java @@ -1,28 +1,68 @@ package kw.zeropick.home.service; +import java.util.List; import kw.zeropick.common.LoginUser; import kw.zeropick.home.dto.response.ProductBestResponse; +import kw.zeropick.product.domain.Category; import kw.zeropick.product.domain.Product; import kw.zeropick.product.domain.ProductSort; import kw.zeropick.product.dto.ProductDto; import kw.zeropick.product.dto.request.ProductSearchRequest; import kw.zeropick.product.service.ProductService; +import kw.zeropick.review.dto.response.ReviewResponse; +import kw.zeropick.review.service.ReviewService; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -import java.util.List; import java.util.stream.Collectors; + @Service @Transactional @RequiredArgsConstructor -public class HomeServiceImpl implements HomeService{ - +public class HomeServiceImpl implements HomeService { private final ProductService productService; + private final ReviewService reviewService; - private ProductBestResponse toProductBestResponse(Product product) { + @Override + public List categoryBest(Long memberId, Category category) { + ProductSearchRequest productSearchRequest = ProductSearchRequest.builder() + .category(category) + .sort(ProductSort.POPULARITY) + .build(); + + Page productDtos = productService.productSearch(memberId, 0, 3, productSearchRequest); + Pageable pageable = PageRequest.of(0, 1); + + List bestResponses = productDtos.getContent().stream().map(productDto -> { + Page reviews = reviewService.getReviews(productDto.getId(), null, "latest", pageable); + ReviewResponse latestReview = reviews.getContent().isEmpty() ? null : reviews.getContent().get(0); + + 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()) + .reviewResponse(latestReview) + .bookmarked(productDto.getBookmarked()) + .compared(productDto.getCompared()) + .build(); + }).toList(); + + return bestResponses; + } + + @Override + @Transactional + private ProductBestResponse toProductBestResponse (Product product){ Long memberId = null; try { memberId = LoginUser.get().getId(); // 로그인 사용자 정보 가져오기 @@ -54,7 +94,7 @@ private ProductBestResponse toProductBestResponse(Product product) { @Override @Transactional - public List getTopPopularityProducts(int limit, String token) { + public List getTopPopularityProducts ( int limit, String token){ // 인기 상품 검색 요청 생성 ProductSearchRequest productSearchRequest = ProductSearchRequest.builder() .zeroKcal(Boolean.TRUE) @@ -84,5 +124,4 @@ public List getTopPopularityProducts(int limit, String toke ) .toList(); } - -} +} \ No newline at end of file diff --git a/src/main/java/kw/zeropick/product/domain/Product.java b/src/main/java/kw/zeropick/product/domain/Product.java index fab4dfd..cb1fe1a 100644 --- a/src/main/java/kw/zeropick/product/domain/Product.java +++ b/src/main/java/kw/zeropick/product/domain/Product.java @@ -95,11 +95,13 @@ public void setTags(List tags) { this.tags = tags; } - public void setPopularity(){ - this.popularity = this.viewCount*150 + this.bookmarkCount*250 + this.reviewCount*250 + Integer.parseInt(String.valueOf(this.starRate*20*350)); + public void setPopularity() { + int starRateScore = this.starRate != null ? (int) Math.round(this.starRate * 20 * 350) : 0; + this.popularity = this.viewCount * 150 + this.bookmarkCount * 250 + this.reviewCount * 250 + starRateScore; } + } diff --git a/src/main/java/kw/zeropick/review/service/ReviewServiceImpl.java b/src/main/java/kw/zeropick/review/service/ReviewServiceImpl.java index c2e63de..5cf11ec 100644 --- a/src/main/java/kw/zeropick/review/service/ReviewServiceImpl.java +++ b/src/main/java/kw/zeropick/review/service/ReviewServiceImpl.java @@ -229,6 +229,14 @@ public void deleteReview(Long reviewId) { Review review = reviewRepository.findById(reviewId) .orElseThrow(() -> new EntityNotFoundException("해당 리뷰를 찾을 수 없습니다.")); + // 이미지 삭제 추가 + List oldImageUrls = review.getImageUrls(); + if(!oldImageUrls.isEmpty()) { + for (String imageUrl : oldImageUrls) { + s3Util.deleteFile(imageUrl); + } + } + Product product = review.getProduct(); // 리뷰의 평점을 상품에서 제거