Skip to content

Commit b99564f

Browse files
committed
Feat: 리스트 조회시 좋아요 여부 반환
1 parent 809e2e8 commit b99564f

File tree

5 files changed

+37
-11
lines changed

5 files changed

+37
-11
lines changed

src/main/java/com/DecodEat/domain/products/controller/ProductController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ public ApiResponse<ProductRegisterResponseDto> registerProduct(
6767
)
6868
@GetMapping("/latest")
6969
public ApiResponse<ProductResponseDTO.ProductListResultDTO> getProductList(
70-
@RequestParam(required = false) Long cursorId) {
71-
return ApiResponse.onSuccess(productService.getProducts(cursorId));
70+
@RequestParam(required = false) Long cursorId, @OptionalUser User user) {
71+
return ApiResponse.onSuccess(productService.getProducts(cursorId, user));
7272
}
7373

7474
@GetMapping("/search/autocomplete")

src/main/java/com/DecodEat/domain/products/converter/ProductConverter.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import java.util.List;
1212
import java.util.Map;
13+
import java.util.Set;
1314
import java.util.stream.Collectors;
1415

1516
import static com.DecodEat.domain.products.entity.RawMaterial.RawMaterialCategory.*;
@@ -69,13 +70,14 @@ public static ProductRegisterResponseDto toProductRegisterDto(Product product, L
6970
}
7071

7172
// 단일 Product → ProductListItemDTO 변환
72-
public static ProductResponseDTO.ProductListItemDTO toProductListItemDTO(Product product){
73+
public static ProductResponseDTO.ProductListItemDTO toProductListItemDTO(Product product, boolean isLiked) {
7374
return ProductResponseDTO.ProductListItemDTO.builder()
7475
.productId(product.getProductId())
7576
.manufacturer(product.getManufacturer())
7677
.productName(product.getProductName())
7778
.productImage(product.getProductImage())
7879
.decodeStatus(product.getDecodeStatus())
80+
.isLiked(isLiked)
7981
.build();
8082
}
8183

@@ -107,9 +109,9 @@ public static ProductRegisterHistoryDto toProductRegisterHistoryDto(Product prod
107109

108110

109111
// Slice<Product> → ProductListResultDTO 변환
110-
public static ProductResponseDTO.ProductListResultDTO toProductListResultDTO(Slice<Product> slice) {
112+
public static ProductResponseDTO.ProductListResultDTO toProductListResultDTO(Slice<Product> slice, Set<Long> likedProductIds) {
111113
List<ProductResponseDTO.ProductListItemDTO> productList = slice.getContent().stream()
112-
.map(ProductConverter::toProductListItemDTO)
114+
.map(product -> toProductListItemDTO(product, likedProductIds.contains(product.getProductId())))
113115
.toList();
114116

115117
Long nextCursorId = (slice.hasNext() && !productList.isEmpty())

src/main/java/com/DecodEat/domain/products/dto/response/ProductResponseDTO.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ public static class ProductListItemDTO {
5555

5656
@Schema(description = "뷴석 상태", example = "COMPLETED")
5757
private DecodeStatus decodeStatus;
58+
59+
@Schema(description = "좋아요 여부", example = "true")
60+
private boolean isLiked;
5861
}
5962

6063
}

src/main/java/com/DecodEat/domain/products/repository/ProductLikeRepository.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@
44
import com.DecodEat.domain.products.entity.ProductLike;
55
import com.DecodEat.domain.users.entity.User;
66
import org.springframework.data.jpa.repository.JpaRepository;
7+
import org.springframework.data.jpa.repository.Query;
8+
import org.springframework.data.repository.query.Param;
79

10+
import java.util.List;
811
import java.util.Optional;
912

1013
public interface ProductLikeRepository extends JpaRepository<ProductLike, Long> {
1114

1215
Optional<ProductLike> findByUserAndProduct(User user, Product product);
1316

17+
// 여러 제품에 대한 좋아요 여부 조회 ( 제품 리스트 조회시 N + 1 문제 해결)
18+
@Query("SELECT pl.product.productId " +
19+
"FROM ProductLike pl " +
20+
"WHERE pl.user = :user AND pl.product.productId IN :productIds")
21+
List<Long> findLikedProductIdsByUserAndProductIds(@Param("user") User user,
22+
@Param("productIds") List<Long> productIds);
23+
1424
boolean existsByUserAndProduct(User user, Product product);
1525

1626
}

src/main/java/com/DecodEat/domain/products/service/ProductService.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@
2727
import org.springframework.web.multipart.MultipartFile;
2828

2929
import javax.swing.*;
30-
import java.util.ArrayList;
31-
import java.util.List;
32-
import java.util.Optional;
33-
import java.util.UUID;
30+
import java.util.*;
3431
import java.util.stream.Collectors;
3532

3633
import static com.DecodEat.global.apiPayload.code.status.ErrorStatus.*;
@@ -115,11 +112,25 @@ public ProductRegisterResponseDto addProduct(User user, ProductRegisterRequestDt
115112
}
116113

117114
@Transactional(readOnly = true)
118-
public ProductResponseDTO.ProductListResultDTO getProducts(Long cursorId) {
115+
public ProductResponseDTO.ProductListResultDTO getProducts(Long cursorId, User user) {
119116
Pageable pageable = PageRequest.of(0, PAGE_SIZE);
120117
Slice<Product> slice = productRepository.findCompletedProductsByCursor(cursorId, pageable);
121118

122-
return ProductConverter.toProductListResultDTO(slice);
119+
// 기본값: 전부 false
120+
Set<Long> likedProductIds = Collections.emptySet();
121+
122+
// user가 null이 아닐 때만 DB에서 좋아요 여부 조회
123+
if (user != null && !slice.isEmpty()) {
124+
List<Long> productIds = slice.getContent().stream()
125+
.map(Product::getProductId)
126+
.toList();
127+
128+
likedProductIds = new HashSet<>(
129+
productLikeRepository.findLikedProductIdsByUserAndProductIds(user, productIds)
130+
);
131+
}
132+
133+
return ProductConverter.toProductListResultDTO(slice, likedProductIds);
123134
}
124135

125136
// todo: 검색은 상품 엔티티와 1:1 매핑 불가능 -> userbehavior 어떻게?

0 commit comments

Comments
 (0)