From 5311727aa51c8fd85cf4d58d5de49810f754166a Mon Sep 17 00:00:00 2001 From: myqewr Date: Tue, 13 Jan 2026 21:50:17 +0900 Subject: [PATCH] =?UTF-8?q?fix=20:=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20?= =?UTF-8?q?=EC=A2=8B=EC=95=84=EC=9A=94/=EC=83=81=ED=92=88=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=20api=20bug=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/post-api.adoc | 3 +++ .../dto/response/LoadPostDetailResponse.java | 8 +++++- .../dto/response/PostProductResponse.java | 16 ++++++++--- .../post/PostDomainPersistenceAdapter.java | 15 ++++++++++- .../post/UpdatePostProductPort.java | 2 ++ .../post/LoadProductsByHashTagService.java | 3 +++ .../product/CreateProductLikeService.java | 27 ++++++++++++++++--- .../vo/post/PostProductDetailVo.java | 2 ++ .../ftm/server/domain/entity/PostProduct.java | 8 ++++++ .../ftm/server/post/LoadPostDetailTest.java | 3 +++ 10 files changed, 78 insertions(+), 9 deletions(-) diff --git a/src/docs/asciidoc/post-api.adoc b/src/docs/asciidoc/post-api.adoc index 143e53b..dcf552e 100644 --- a/src/docs/asciidoc/post-api.adoc +++ b/src/docs/asciidoc/post-api.adoc @@ -378,6 +378,9 @@ include::{snippetsDir}/createProductLike/2/http-response.adoc[] ==== Request include::{snippetsDir}/loadPostProducts/1/http-request.adoc[] +==== Request Query Parameters +include::{snippetsDir}/loadPostProducts/1/query-parameters.adoc[] + ==== Request Body Parameters include::{snippetsDir}/loadPostProducts/1/request-fields.adoc[] diff --git a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadPostDetailResponse.java b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadPostDetailResponse.java index 27fa8f8..c66beee 100644 --- a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadPostDetailResponse.java +++ b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadPostDetailResponse.java @@ -4,6 +4,7 @@ import com.ftm.server.application.vo.post.PostDetailVo; import com.ftm.server.domain.enums.PostHashtag; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import lombok.Getter; @@ -33,7 +34,12 @@ private LoadPostDetailResponse(PostDetailVo postDetailVo) { this.postId = postDetailVo.getPostId(); this.title = postDetailVo.getTitle(); this.content = postDetailVo.getContent(); - this.hashtags = Arrays.stream(postDetailVo.getHashtags()).map(PostHashtag::getTag).toList(); + this.hashtags = + postDetailVo.getHashtags() == null || postDetailVo.getHashtags().length == 0 + ? new ArrayList<>() + : Arrays.stream(postDetailVo.getHashtags()) + .map(PostHashtag::getTag) + .toList(); this.viewCount = postDetailVo.getViewCount(); this.likeCount = postDetailVo.getLikeCount(); this.createdAt = postDetailVo.getCreatedAt(); diff --git a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/PostProductResponse.java b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/PostProductResponse.java index ca544e1..c728d25 100644 --- a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/PostProductResponse.java +++ b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/PostProductResponse.java @@ -2,6 +2,7 @@ import com.ftm.server.application.vo.post.PostProductDetailVo; import com.ftm.server.domain.enums.ProductHashtag; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import lombok.Getter; @@ -12,6 +13,7 @@ public class PostProductResponse { private final Long postProductId; private final String name; private final String brand; + private final Long recommendedCount; private final List hashtags; private final PostProductImageResponse postProductImage; @@ -19,12 +21,18 @@ private PostProductResponse(PostProductDetailVo postProductDetailVo) { this.postProductId = postProductDetailVo.getPostProductId(); this.name = postProductDetailVo.getName(); this.brand = postProductDetailVo.getBrand(); + this.recommendedCount = postProductDetailVo.getRecommendedCount(); this.hashtags = - Arrays.stream(postProductDetailVo.getHashtags()) - .map(ProductHashtag::getTag) - .toList(); + postProductDetailVo.getHashtags() == null + || postProductDetailVo.getHashtags().length == 0 + ? new ArrayList<>() + : Arrays.stream(postProductDetailVo.getHashtags()) + .map(ProductHashtag::getTag) + .toList(); this.postProductImage = - PostProductImageResponse.from(postProductDetailVo.getPostProductImage()); + postProductDetailVo.getPostProductImage() == null + ? null + : PostProductImageResponse.from(postProductDetailVo.getPostProductImage()); } public static PostProductResponse from(PostProductDetailVo postProductDetailVo) { diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/adapter/post/PostDomainPersistenceAdapter.java b/src/main/java/com/ftm/server/adapter/out/persistence/adapter/post/PostDomainPersistenceAdapter.java index 9edf47e..ab9f4da 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/adapter/post/PostDomainPersistenceAdapter.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/adapter/post/PostDomainPersistenceAdapter.java @@ -323,6 +323,19 @@ public void updatePostProducts(List postProducts) { } } + @Override + public void updatePostProduct(PostProduct postProduct) { + PostProductJpaEntity postProductJpaEntity = + postProductRepository + .findById(postProduct.getId()) + .orElseThrow( + () -> + new CustomException( + ErrorResponseCode.POST_PRODUCT_NOT_FOUND)); + + postProductJpaEntity.updatePostProductForDomainEntity(postProduct); + } + @Override public void updatePostProductImages(List postProductImages) { List ids = postProductImages.stream().map(PostProductImage::getId).toList(); @@ -444,7 +457,7 @@ public List findProductLikeByUser( @Override public void deletePostLike(Long postLikeId) { - productLikeRepository.deleteById(postLikeId); + postLikeRepository.deleteById(postLikeId); } @Override diff --git a/src/main/java/com/ftm/server/application/port/out/persistence/post/UpdatePostProductPort.java b/src/main/java/com/ftm/server/application/port/out/persistence/post/UpdatePostProductPort.java index 055b6c8..8535250 100644 --- a/src/main/java/com/ftm/server/application/port/out/persistence/post/UpdatePostProductPort.java +++ b/src/main/java/com/ftm/server/application/port/out/persistence/post/UpdatePostProductPort.java @@ -8,4 +8,6 @@ public interface UpdatePostProductPort { void updatePostProducts(List postProducts); + + void updatePostProduct(PostProduct postProducts); } diff --git a/src/main/java/com/ftm/server/application/service/post/LoadProductsByHashTagService.java b/src/main/java/com/ftm/server/application/service/post/LoadProductsByHashTagService.java index 71d89da..8049c87 100644 --- a/src/main/java/com/ftm/server/application/service/post/LoadProductsByHashTagService.java +++ b/src/main/java/com/ftm/server/application/service/post/LoadProductsByHashTagService.java @@ -97,6 +97,9 @@ public LoadProductsByHashTagVoWrapper execute( } else { loadProductAndUserLikeVos = loadProductLikePort.findProductLikeByUser(userId, productIds); + System.out.println("!!!!!!!!!!!!!!\n\n\\n"); + System.out.println(loadProductAndUserLikeVos.size()); + System.out.println(loadProductAndUserLikeVos.get(0)); } Map productLikeMap = loadProductAndUserLikeVos.stream() diff --git a/src/main/java/com/ftm/server/application/service/post/product/CreateProductLikeService.java b/src/main/java/com/ftm/server/application/service/post/product/CreateProductLikeService.java index b87a8ac..38989f5 100644 --- a/src/main/java/com/ftm/server/application/service/post/product/CreateProductLikeService.java +++ b/src/main/java/com/ftm/server/application/service/post/product/CreateProductLikeService.java @@ -1,10 +1,13 @@ package com.ftm.server.application.service.post.product; import com.ftm.server.application.port.in.post.CreateProductLikeUseCase; -import com.ftm.server.application.port.out.persistence.post.DeleteProductLikePort; -import com.ftm.server.application.port.out.persistence.post.LoadProductLikePort; -import com.ftm.server.application.port.out.persistence.post.SaveProductLikePort; +import com.ftm.server.application.port.out.persistence.post.*; +import com.ftm.server.application.query.FindByIdsQuery; +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import com.ftm.server.domain.entity.PostProduct; import com.ftm.server.domain.entity.ProductLike; +import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -15,12 +18,24 @@ public class CreateProductLikeService implements CreateProductLikeUseCase { private final LoadProductLikePort loadProductLikePort; + private final LoadPostProductPort loadPostProductPort; private final SaveProductLikePort saveProductLikePort; private final DeleteProductLikePort deleteProductLikePort; + private final UpdatePostProductPort updatePostProductPort; @Transactional public Boolean execute(Long userId, Long productId) { + PostProduct postProduct = + loadPostProductPort + .loadPostProductsByIds(FindByIdsQuery.from(List.of(productId))) + .stream() + .findFirst() + .orElseThrow( + () -> + new CustomException( + ErrorResponseCode.POST_PRODUCT_NOT_FOUND)); + // 이미 등록된 좋아요 있는지 확인 Optional optionalProductLikeId = loadProductLikePort.findOneByUserAndProduct(userId, productId); @@ -29,12 +44,18 @@ public Boolean execute(Long userId, Long productId) { if (optionalProductLikeId.isEmpty()) { ProductLike productLike = ProductLike.create(productId, userId); saveProductLikePort.saveProductLike(productLike); + + postProduct.plusRecommendedCountByOne(); + updatePostProductPort.updatePostProduct(postProduct); return true; } // 있으면 삭제 else { deleteProductLikePort.deleteProductLike(optionalProductLikeId.get()); + + postProduct.minusRecommendedCountByOne(); + updatePostProductPort.updatePostProduct(postProduct); return false; } } diff --git a/src/main/java/com/ftm/server/application/vo/post/PostProductDetailVo.java b/src/main/java/com/ftm/server/application/vo/post/PostProductDetailVo.java index dc70b4a..f7b79a7 100644 --- a/src/main/java/com/ftm/server/application/vo/post/PostProductDetailVo.java +++ b/src/main/java/com/ftm/server/application/vo/post/PostProductDetailVo.java @@ -18,6 +18,7 @@ public class PostProductDetailVo { private final LocalDateTime createdAt; private final LocalDateTime updatedAt; private final PostProductImage postProductImage; + private final Long recommendedCount; private PostProductDetailVo(PostProduct postProduct, PostProductImage postProductImage) { this.postProductId = postProduct.getId(); @@ -27,6 +28,7 @@ private PostProductDetailVo(PostProduct postProduct, PostProductImage postProduc this.createdAt = postProduct.getCreatedAt(); this.updatedAt = postProduct.getUpdatedAt(); this.postProductImage = postProductImage; + this.recommendedCount = postProduct.getRecommendedCount(); } public static List listFrom( diff --git a/src/main/java/com/ftm/server/domain/entity/PostProduct.java b/src/main/java/com/ftm/server/domain/entity/PostProduct.java index 76a6ccc..1b447f2 100644 --- a/src/main/java/com/ftm/server/domain/entity/PostProduct.java +++ b/src/main/java/com/ftm/server/domain/entity/PostProduct.java @@ -85,4 +85,12 @@ public void validatePost(Long postId) { throw new CustomException(ErrorResponseCode.UNAUTHORIZED_POST_PRODUCT_ACCESS); } } + + public void plusRecommendedCountByOne() { + this.recommendedCount += 1; + } + + public void minusRecommendedCountByOne() { + this.recommendedCount -= 1; + } } diff --git a/src/test/java/com/ftm/server/post/LoadPostDetailTest.java b/src/test/java/com/ftm/server/post/LoadPostDetailTest.java index f03b3bd..3c4f549 100644 --- a/src/test/java/com/ftm/server/post/LoadPostDetailTest.java +++ b/src/test/java/com/ftm/server/post/LoadPostDetailTest.java @@ -89,6 +89,9 @@ public class LoadPostDetailTest extends BaseTest { fieldWithPath("data.postProducts[].brand") .type(STRING) .description("게시글 상품 브랜드"), + fieldWithPath("data.postProducts[].recommendedCount") + .type(NUMBER) + .description("게시글 상품 추천수"), fieldWithPath("data.postProducts[].hashtags[]") .type(ARRAY) .description("게시글 상품 해시태그 목록"),