상품 상세 페이지에서 상품 생성 시간과 수정 시간 추가

뚜우웅이·2025년 5월 29일

캡스톤 디자인

목록 보기
32/35

ProductDetailResponse와 ProductSummaryResponse가 거의 똑같은 구조를 가지고 있어 중복이 심하기 때문에 통합을 해준다.
그 후에 상품 생성 시간과 수정 시간을 응답에 넣어준다.

User

UserProfileDto

public class UserProfileDto {

    @Builder
    @Schema(description = "판매 내역 페이지 응답")
    public record SellingHistoryResponse(
        @Schema(description = "판매 중인 상품 목록")
        List<ProductDto.ProductResponse> activeProducts,
        
        @Schema(description = "판매 완료된 상품 목록")
        List<ProductDto.ProductResponse> soldProducts,
        
        @Schema(description = "총 상품 수", example = "10")
        int totalProductCount
    ) {}

    @Builder
    @Schema(description = "구매 내역 페이지 응답")
    public record PurchaseHistoryResponse(
            @Schema(description = "구매 내역 목록")
            List<ProductDto.ProductResponse> purchases,
            
            @Schema(description = "총 구매 수", example = "5")
            int totalPurchaseCount
    ) {}

}

UserDto에서는 ProductResponse을 가져와서 상품들을 보여주게 된다.

UserController

ProductDetailResponse로 작성한 반환 타입을 모두 ProductDto.ProductResponse로 변경해준다.

UserProfileService

서비스 클래스들의 반환 타입도 ProductDto.ProductResponse로 변경해준다.

Product

DTO

ProductDto

// 통합된 상품 응답 DTO - 모든 API에서 사용
    @Builder
    @Schema(description = "상품 응답")
    public record ProductResponse(
            @Schema(description = "상품 ID", example = "1")
            Long id,

            @Schema(description = "상품명", example = "새 노트북")
            String name,

            @Schema(description = "상품 설명", example = "거의 사용하지 않은 노트북입니다.")
            String description,

            @Schema(description = "가격", example = "1000000")
            Long price,

            @Schema(description = "재고 수량", example = "1")
            Integer stock,

            @Schema(description = "카테고리 표시명", example = "전자기기")
            String category,

            @Schema(description = "상품 상태", example = "판매중")
            String status,

            @Schema(description = "썸네일 이미지 URL", example = "https://example.com/thumbnail.jpg")
            String thumbnailUrl,

            @Schema(description = "이미지 URL 목록")
            List<String> imageUrls,

            @Schema(description = "판매자 ID", example = "123")
            Long sellerId,

            @Schema(description = "판매자 이름", example = "홍길동")
            String sellerName,

            @Schema(description = "상품 등록일", example = "2025-01-15T10:30:00")
            LocalDateTime createdDate,

            @Schema(description = "상품 수정일", example = "2025-01-16T14:20:00")
            LocalDateTime updatedDate,

            @Schema(description = "조회수", example = "42")
            Long viewCount,

            @Schema(description = "관심 등록 수", example = "7")
            Long wishlistCount,

            @Schema(description = "현재 사용자의 관심 등록 여부", example = "true")
            boolean isWishlisted
    ) {
        // 완전한 정보로 생성 (상세 조회, 목록 조회용)
        public static ProductResponse from(Product product, Long viewCount, Long wishlistCount, boolean isWishlisted) {
            return ProductResponse.builder()
                    .id(product.getId())
                    .name(product.getName())
                    .description(product.getDescription())
                    .price(product.getPrice())
                    .stock(product.getStock())
                    .category(product.getCategory().getDisplayName())
                    .status(product.getStatus().getDisplayName())
                    .thumbnailUrl(product.getRepresentativeThumbnailUrl())
                    .imageUrls(product.getImages().stream()
                            .map(ProductImage::getImageUrl)
                            .collect(Collectors.toList()))
                    .sellerId(product.getSeller().getId())
                    .sellerName(product.getSeller().getName())
                    .createdDate(product.getCreatedDate())
                    .updatedDate(product.getUpdatedDate())
                    .viewCount(viewCount != null ? viewCount : 0L)
                    .wishlistCount(wishlistCount != null ? wishlistCount : 0L)
                    .isWishlisted(isWishlisted)
                    .build();
        }

        // 기본 정보만으로 생성 (등록, 수정 결과용 - 통계 정보 없음)
        public static ProductResponse from(Product product) {
            return from(product, 0L, 0L, false);
        }
    }

상품 상제 정보와 관련된 응답을 하나의 DTO로 사용할 수 있게 통합한 뒤에 생성 시간과, 수정 시간에 대한 정보를 넣어준다.

ProductWithStatsDto

@Schema(description = "상품과 관련 통계 정보 포함 DTO")
public record ProductWithStatsDto(
        @Schema(description = "상품 정보", required = true)
        Product product,

        @Schema(description = "상품 조회수", example = "42")
        Long viewCount,

        @Schema(description = "관심 등록 수", example = "7")
        Long wishlistCount,

        @Schema(description = "현재 사용자의 관심 등록 여부", example = "true")
        boolean isWishlisted
) {

    public ProductWithStatsDto {
        // null 체크 및 기본값 설정
        viewCount = viewCount != null ? viewCount : 0L;
        wishlistCount = wishlistCount != null ? wishlistCount : 0L;
    }

    public ProductDto.ProductResponse toProductResponse() {
        return ProductDto.ProductResponse.from(
                product,
                viewCount,
                wishlistCount,
                isWishlisted
        );
    }
}

ProductResponse로 반환값을 변경해준다.

Controller

ProductResponse로 반환값을 변경해준다.

Service

ProductManagementService, ProductStatusService

ProductResponse로 반환값을 변경해준다.

ProductWishlistService

ProductResponse로 반환값을 변경해준 뒤 메서드를 수정해준다.

    public List<ProductDto.ProductResponse> getUserWishlistDetailDto(Long userId) {
        User user = getUser(userId);
        return productWishlistRepository.findAllByUser(user).stream()
                .map(wishlist -> {
                    Product product = wishlist.getProduct();

                    Long viewCount = viewService.getViewCount(product.getId());
                    Long wishlistCount = getWishlistCount(product.getId());
                    // 이미 위시리스트에서 가져온 상품이므로 무조건 true
                    boolean isWishlisted = true;

                    return ProductDto.ProductResponse.from(product, viewCount, wishlistCount, isWishlisted);
                })
                .toList();
    }

이미 위시리스트에 있는 상품이니 항상 true로 가져온다.

ProductQueryService

ProductResponse로 반환값을 변경해준다.

    // 상품 목록 조회
    public Page<ProductDto.ProductResponse> getFilteredProducts(ProductCategory category, String keyword, ProductStatus status,
                                                                Long minPrice, Long maxPrice, ProductSort sort,
                                                                Pageable pageable, Long userId) {
        return productRepository.findProductsWithFilters(category, keyword, status, minPrice, maxPrice, sort, pageable, userId)
                .map(ProductWithStatsDto::toProductResponse);
    }

DTO 변경하는 로직을 변경해준다.

profile
공부하는 초보 개발자

0개의 댓글