Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,47 @@ public ApiResponse<ProductDetailResponse> getProduct(

return ApiResponse.ok(product);
}


/**
* 제조사 목록 조회 API
* @param category 카테고리
*/
@GetMapping("/mnf")
public ApiResponse<SliceResponse<String>> getManufacturers(
PageRequest pageRequest,
@RequestParam CategoryType category) {

/// Pageable
Pageable pageable = org.springframework.data.domain.PageRequest.of(
pageRequest.getPage() - 1,
pageRequest.getSize(),
Sort.by(Sort.Direction.DESC, "id")
);

/// 서비스
Slice<String> responses = productService.getManufacturers(category.getValue(), pageable);

/// SliceResponse 변환 후, 리턴
return ApiResponse.ok(SliceResponse.from(responses));
}


/**
* 전체 상품 개수 조회 API
* @param category 카테 고리
*/
@GetMapping("/total")
public ApiResponse<Long> getTotalProducts(
@RequestParam CategoryType category
) {

/// 서비스 호출
Long response = productService.getCountProducts(category.getValue());

/// 리턴
return ApiResponse.ok(response);
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public record ProductDetailResponse(
@Schema(description = "상품 썸네일 이미지 URL", example = "https://example.com/product/101.jpg")
String thumbnail,

@Schema(description = "원본 상품 구매 URL", example = "https://example.com/product")
String siteUrl,

@Schema(description = "제조사명", example = "독거미")
String manufacturerName,

Expand Down Expand Up @@ -64,6 +67,7 @@ public static ProductDetailResponse from(Product product) {
return ProductDetailResponse.builder()
.id(product.getId())
.thumbnail(product.getThumbnail())
.siteUrl(product.getDetailPageUrl())
.manufacturerName(product.getManufacturer())
.category(product.getCategory())
.productName(product.getName())
Expand All @@ -80,6 +84,7 @@ public static ProductDetailResponse from(Product product, boolean likedByMe) {
return ProductDetailResponse.builder()
.id(product.getId())
.thumbnail(product.getThumbnail())
.siteUrl(product.getDetailPageUrl())
.manufacturerName(product.getManufacturer())
.category(product.getCategory())
.productName(product.getName())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@
@Tag(name = "상품 조회 API", description = "상품 조회를 수행하는 API 입니다.")
public interface ProductControllerSpec {


@Operation(
summary = "상품 개수 조회 API",
description = "카테고리별 상품 전체 개수를 파악합니다."
)
ApiResponse<Long> getTotalProducts(
@RequestParam CategoryType category
);

/**
* 상품 상세 조회 API
* @param id 상품 아이디
Expand Down Expand Up @@ -66,5 +75,16 @@ ApiResponse<SliceResponse<ProductListResponse>> getProductList(

@Parameter(hidden = true)
@AuthenticationPrincipal PrincipalDetails principalDetails);


@Operation(
summary = "제조사 목록 조회 API",
description = "카테고리에 따라서 제조사 목록을 조회할 수 있습니다."
)
ApiResponse<SliceResponse<String>> getManufacturers(
PageRequest pageRequest,

@Parameter(description = "카테고리", required = true, example = "keyboard")
@RequestParam CategoryType category);
}

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
public class ProductMongoAdapter implements ProductPort {

private final ProductDocumentRepository documentRepository;

// =================
// 상품 상세 조회
// =================
Expand Down Expand Up @@ -94,6 +93,14 @@ public Slice<Product> getProducts(String category, List<String> manufacturer,
map(ProductDocument::toDomain);
}

/// 카테고리 기반 제조사 목록 조회
@Override
public List<String> getManufacturers(String category) {

/// DB 조회
return documentRepository.findManufacturersByCategory(category);
}

// =================
// 상품 조회
// =================
Expand All @@ -120,6 +127,15 @@ public Map<String, Product> getProductsByIds(List<String> productIds) {
.collect(Collectors.toMap(Product::getId, Function.identity()));
}

/**
* 상품 개수 조회
* @param category 카테고리
*/
@Override
public Long getProductsCount(String category) {
return documentRepository.countByCategory(category);
}

// =================
// 상품 추천
// =================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class ProductDocument {

private String manufacturer;

@Field("detail_purchase_url")
@Field("detail_page_url")
private String detailPageUrl;

@Field("options")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ Slice<ProductDocument> findByCategoryAndPriceRange(
Pageable pageable
);

@Aggregation(pipeline = {
"{ '$match': { 'category': ?0 } }",
"{ '$group': { '_id': '$manufacturer' } }"
})
List<String> findManufacturersByCategory(String category);


/// 카테고리 기반 목록 조회 (카테고리, 제조사, 가격 포함)
@Query("""
{
Expand Down Expand Up @@ -77,6 +84,8 @@ Slice<ProductDocument> findByCategoryAndManufacturerAndPriceRange(
})
List<ProductDocument> findRandomExcludeIds(List<String> excludedIds, int limit);

/// 상품 개수
Long countByCategory(String category);
// =================
// 삭제 함수
// =================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ public interface ProductUseCase {
// 카테고리별 목록 조회 (카테고리, 제조사, 가격 포함)
Slice<ProductListResponse> getProductsByCategoryIdAndManufacturerIdAndPrice(UUID userId, String categoryId, List<String> manufacturer, Integer minPrice, Integer maxPrice, Pageable pageable);

/// 상품 개수 조회
Long getCountProducts(String categoryId);

/// 상품 상세 조회
ProductDetailResponse getProduct(UUID userId, String id);

/// 카테고리 목록 조회
Slice<String> getManufacturers(String categoryId, Pageable pageable);

/// 외부 의존성
// 커스텀 키보드에 맞는 부품들 조회
Slice<ProductListResponse> getProductsByLayout(UUID userId, String categoryId, CustomKeyboardLayout layout, Pageable pageable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public interface ProductPort {
/// 카테고리 기반 상품 목록 조회 (카테고리, 제조사, 가격 포함)
Slice<Product> getProducts(String category, List<String> manufacturer, Integer minPrice, Integer maxPrice, Pageable pageable);

/// 카테고리 기반 제조사 조회
List<String> getManufacturers(String category);


// =================
// 상품 조회
// =================
Expand All @@ -44,6 +48,9 @@ public interface ProductPort {
/// 상품 ID들 바탕으로 조회
Map<String, Product> getProductsByIds(List<String> productIds);

/// 상품 개수 조회
Long getProductsCount(String category);

// =================
// 상품 추천
// =================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ public Slice<ProductListResponse> getProductsByCategoryIdAndManufacturerIdAndPri
return toProductListResponse(userId, categoryId, products);
}

/**
* 카테고리에 따른 전체 상품 개수
* @param categoryId 카테고리
*/
@Override
public Long getCountProducts(String categoryId) {

/// Port에서 조회
return productPort.getProductsCount(categoryId);
}

// =================
// 상품 상세 조회
// =================
Expand Down Expand Up @@ -150,6 +161,27 @@ public ProductDetailResponse getProduct(UUID userId, String id) {

}

/**
* 모든 제조사를 가져오는 로직입니다.
* @param categoryId 조회할 카테고리 ID
*/
@Override
public Slice<String> getManufacturers(String categoryId, Pageable pageable) {

/// Port에서 일단 전부 조회
// TODO! DB가 적기 때문에, 일단은 다 가져와서 슬라이싱,,, 추후에 데이터의 개수가 많아지게 된다면 로직을 다시 생각해야 될 듯
List<String> manufacturers = productPort.getManufacturers(categoryId);

// 페이징 적용
int start = (int) pageable.getOffset();
int end = Math.min(start + pageable.getPageSize(), manufacturers.size());
List<String> content = manufacturers.subList(start, end);

boolean hasNext = end < manufacturers.size();

return new SliceImpl<>(content, pageable, hasNext);
}

// ========================
// 외부 의존성
// ========================
Expand Down
Loading