Skip to content

Commit

Permalink
상품 조회 API 구현 및 상품 컬럼 추가 (#67)
Browse files Browse the repository at this point in the history
* feat(#59): 단일상품조회 API 구현

* feat(#59): 주문시 상품정보를 가져오는 내부 API 정의
- 요청에서 삭제된 상품정보는 아예 넘어오지 않아서 없는 경우 not found exception

* feat(#59): 상품엔티티에 필터링과 관련된 컬럼 추가
- 상품 조회시 필요한 필터링 요소로 브랜드이름, 메인컬러, 사이즈, 태그 추가 및 쿠폰여부 제거
- 태그로 "COUPON", "EXPRESS_DELIVERY", "FREE_SHIPPING", "DISCOUNT", "NEW", "1+1", "RECOMMEND"가 추가될 수 있음
- 상품 조회시 필요한 정렬 요소로 리뷰카운트, 세일즈카운트 속성 추가 나중에 리뷰추가나 주문시 해당 count 증가가 필요
- 엔티티 속성추가로 변동되는 모든 dto, mapper 요소를 함께 수정
  • Loading branch information
yooyouny authored Oct 7, 2024
1 parent 73efe72 commit 7a2f1cf
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.sparta.product_dto;

import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class ProductDto {
private UUID productId;
private String productName;
private BigDecimal originalPrice;
private BigDecimal discountedPrice;
private Double discountPercent;
private int stock;
private List<String> tags;

@Builder
private ProductDto(
UUID productId,
String productName,
BigDecimal originalPrice,
BigDecimal discountedPrice,
Double discountPercent,
int stock,
List<String> tags,
boolean isCoupon) {
this.productId = productId;
this.productName = productName;
this.originalPrice = originalPrice;
this.discountedPrice = discountedPrice;
this.discountPercent = discountPercent;
this.stock = stock;
this.tags = tags;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.sparta.product_dto;

import java.util.List;

public record ProductReadRequest(List<String> productIds) {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,54 @@
import com.sparta.product.domain.model.Product;
import com.sparta.product.presentation.request.ProductCreateRequest;
import com.sparta.product.presentation.request.ProductUpdateRequest;
import com.sparta.product_dto.ProductDto;

public class ProductMapper {

public static ProductDto fromEntity(Product product) {
return ProductDto.builder()
.productId(product.getProductId())
.productName(product.getProductName())
.discountPercent(product.getDiscountPercent())
.discountedPrice(product.getDiscountedPrice())
.stock(product.getStock())
.tags(product.getTags())
.build();
}

public static Product toEntity(ProductCreateRequest request) {
return Product.builder()
.categoryId(request.categoryId())
.productName(request.productName())
.brandName(request.brandName())
.mainColor(request.mainColor())
.size(request.size())
.description(request.description())
.originalPrice(request.originalPrice())
.discountPercent(request.discountPercent())
.thumbnailImgUrl(request.thumbnailImgUrl())
.detailImgUrl(request.detailImgUrl())
.stock(request.stock())
.limitCountPerUser(request.limitCountPerUser())
.isCoupon(request.isCoupon())
.tags(request.tags())
.build();
}

public static void updateProduct(ProductUpdateRequest request, Product existingProduct) {
existingProduct.updateProduct(
request.categoryId(),
request.productName(),
request.brandName(),
request.mainColor(),
request.size(),
request.originalPrice(),
request.discountPercent(),
request.stock(),
request.description(),
request.thumbnailImgUrl(),
request.detailImgUrl(),
request.limitCountPerUser(),
request.isPublic(),
request.isCoupon());
request.tags(),
request.isPublic());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
import com.sparta.product.presentation.request.ProductCreateRequest;
import com.sparta.product.presentation.request.ProductUpdateRequest;
import com.sparta.product.presentation.response.ProductResponse;
import com.sparta.product_dto.ProductDto;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -49,6 +52,17 @@ public ProductResponse deleteProduct(UUID productId) {
return ProductResponse.fromEntity(product);
}

public ProductResponse getProduct(UUID productId) {
return ProductResponse.fromEntity(getSavedProduct(productId));
}

public List<ProductDto> getProductList(List<String> productIds) {
return productIds.stream()
.map(productId -> getSavedProduct(UUID.fromString(productId)))
.map(ProductMapper::fromEntity)
.collect(Collectors.toList());
}

private Product getSavedProduct(UUID productId) {
return productRepository
.findByProductIdAndIsDeletedFalse(productId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.sparta.common.domain.entity.BaseEntity;
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -15,31 +16,30 @@
@Getter
public class Product extends BaseEntity implements Persistable {
@PrimaryKey private UUID productId = UUID.randomUUID();

@Column public Long categoryId;

@Column public String productName;
@Column public String brandName;
@Column public String mainColor;
@Column public String size;
@Column public String description;

@Column public BigDecimal originalPrice;

@Column public BigDecimal discountedPrice;

@Column public Double discountPercent;

@Column public int stock;

@Column public String description;

@Column public String thumbnailImgUrl;

@Column public String detailImgUrl;

@Column public int limitCountPerUser = 0;
@Column public double averageRating = 0.0; // TODO :: 리뷰가 등록될떄마다 평균평점 계산
@Column public double averageRating = 0.0;
@Column public long reviewCount = 0;
@Column public long salesCount = 0;

@Column public boolean isPublic = true;
@Column public boolean soldout = false;
@Column public boolean isDeleted = false;
@Column public boolean isCoupon;
@Column public List<String> tags;
@Transient private boolean isNew = false;

@Override
Expand All @@ -57,16 +57,22 @@ public boolean isNew() {
private Product(
Long categoryId,
String productName,
String brandName,
String mainColor,
String size,
BigDecimal originalPrice,
Double discountPercent,
int stock,
String description,
String thumbnailImgUrl,
String detailImgUrl,
int limitCountPerUser,
boolean isCoupon) {
List<String> tags) {
this.categoryId = categoryId;
this.productName = productName;
this.brandName = brandName;
this.mainColor = mainColor;
this.size = size;
this.originalPrice = originalPrice;
this.discountPercent = discountPercent;
applyDiscount(discountPercent);
Expand All @@ -75,33 +81,39 @@ private Product(
this.thumbnailImgUrl = thumbnailImgUrl;
this.detailImgUrl = detailImgUrl;
this.limitCountPerUser = limitCountPerUser;
this.isCoupon = isCoupon;
this.tags = tags;
}

public void updateProduct(
Long categoryId,
String productName,
String brandName,
String mainColor,
String size,
BigDecimal originalPrice,
Double discountPercent,
Integer stock,
String description,
String thumbnailImgUrl,
String detailImgUrl,
Integer limitCountPerUser,
boolean isPublic,
boolean isCoupon) {
List<String> tags,
boolean isPublic) {
this.categoryId = categoryId;
this.productName = productName;
this.brandName = brandName;
this.mainColor = mainColor;
this.size = size;
this.originalPrice = originalPrice;
this.discountPercent = discountPercent;
applyDiscount(discountPercent);
this.stock = stock;
this.description = description;
this.thumbnailImgUrl = thumbnailImgUrl;
this.detailImgUrl = detailImgUrl;
this.tags = tags;
this.limitCountPerUser = limitCountPerUser;
this.isPublic = isPublic;
this.isCoupon = isCoupon;
}

public UUID getProductId() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.sparta.product.presentation.response.ProductResponse;
import java.math.BigDecimal;
import java.util.List;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -15,6 +16,9 @@ public class ProductSearchDto {
@Id private String productId;
private Long categoryId;
private String productName;
private String brandName;
private String mainColor;
private String size;
private BigDecimal originalPrice;
private BigDecimal discountedPrice;
private Double discountPercent;
Expand All @@ -24,14 +28,17 @@ public class ProductSearchDto {
private double averageRating;
private boolean isPublic;
private boolean soldout;
private List<String> tags;
private boolean isDeleted;
private boolean isCoupon;

@Builder
private ProductSearchDto(
String productId,
Long categoryId,
String productName,
String brandName,
String mainColor,
String size,
BigDecimal originalPrice,
BigDecimal discountedPrice,
Double discountPercent,
Expand All @@ -42,10 +49,13 @@ private ProductSearchDto(
boolean isPublic,
boolean soldout,
boolean isDeleted,
boolean isCoupon) {
List<String> tags) {
this.productId = productId;
this.categoryId = categoryId;
this.productName = productName;
this.brandName = brandName;
this.mainColor = mainColor;
this.size = size;
this.originalPrice = originalPrice;
this.discountedPrice = discountedPrice;
this.discountPercent = discountPercent;
Expand All @@ -56,14 +66,17 @@ private ProductSearchDto(
this.isPublic = isPublic;
this.soldout = soldout;
this.isDeleted = isDeleted;
this.isCoupon = isCoupon;
this.tags = tags;
}

public static ProductSearchDto toDto(ProductResponse product) {
return ProductSearchDto.builder()
.productId(product.getProductId())
.categoryId(product.getCategoryId())
.productName(product.getProductName())
.brandName(product.getBrandName())
.mainColor(product.getMainColor())
.size(product.getSize())
.originalPrice(product.getOriginalPrice())
.discountedPrice(product.getDiscountedPrice())
.discountPercent(product.getDiscountPercent())
Expand All @@ -73,7 +86,6 @@ public static ProductSearchDto toDto(ProductResponse product) {
.averageRating(product.getAverageRating())
.isPublic(product.isPublic())
.isDeleted(product.isDeleted())
.isCoupon(product.isCoupon())
.soldout(product.isSoldout())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.sparta.common.domain.response.ApiResponse;
import com.sparta.product.application.ProductFacadeService;
import com.sparta.product.application.ProductService;
import com.sparta.product.presentation.request.ProductCreateRequest;
import com.sparta.product.presentation.request.ProductUpdateRequest;
import com.sparta.product.presentation.response.ProductResponse;
Expand All @@ -10,6 +11,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -24,6 +26,7 @@
@Validated
public class ProductController {
private final ProductFacadeService facadeService;
private final ProductService productService;

@PostMapping
public ApiResponse<String> createProduct(@RequestBody ProductCreateRequest request) {
Expand All @@ -45,4 +48,10 @@ public ApiResponse<ProductResponse> updateStatus(
public ApiResponse<Boolean> deleteProduct(@PathVariable("productId") @NotNull UUID productId) {
return ApiResponse.ok(facadeService.deleteProduct(productId));
}

@GetMapping("/{productId}")
public ApiResponse<ProductResponse> getProduct(
@PathVariable("productId") @NotNull UUID productId) {
return ApiResponse.ok(productService.getProduct(productId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.sparta.product.presentation.controller;

import com.sparta.product.application.ProductService;
import com.sparta.product_dto.ProductDto;
import com.sparta.product_dto.ProductReadRequest;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/internal/products")
public class ProductInternalController {
private final ProductService productService;

@GetMapping
public List<ProductDto> getProductList(@RequestBody ProductReadRequest request) {
return productService.getProductList(request.productIds());
}
}
Loading

0 comments on commit 7a2f1cf

Please sign in to comment.