From 4133b712edcfffadfc946299a988d1959cb34c24 Mon Sep 17 00:00:00 2001 From: yeon015 Date: Sun, 13 Aug 2023 00:12:08 +0900 Subject: [PATCH] =?UTF-8?q?feat(#125)=20:=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20=EC=82=AD=EC=A0=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trothcam/config/SecurityConfig.java | 3 +- .../controller/web/LikeProductController.java | 41 ++++++++++++++ .../trothly/trothcam/domain/image/Image.java | 4 ++ .../trothcam/domain/like/LikeProduct.java | 5 ++ .../domain/like/LikeProductRepository.java | 14 +++++ .../trothcam/domain/product/Product.java | 2 +- .../domain/product/ProductRepository.java | 4 +- .../trothcam/dto/web/LikeProductReqDto.java | 13 +++++ .../trothly/trothcam/dto/web/LikeResDto.java | 13 +++++ .../service/web/LikeProductService.java | 53 +++++++++++++++++++ .../trothcam/service/web/ProductService.java | 22 ++++---- 11 files changed, 159 insertions(+), 15 deletions(-) create mode 100644 src/main/java/trothly/trothcam/controller/web/LikeProductController.java create mode 100644 src/main/java/trothly/trothcam/domain/like/LikeProductRepository.java create mode 100644 src/main/java/trothly/trothcam/dto/web/LikeProductReqDto.java create mode 100644 src/main/java/trothly/trothcam/dto/web/LikeResDto.java create mode 100644 src/main/java/trothly/trothcam/service/web/LikeProductService.java diff --git a/src/main/java/trothly/trothcam/config/SecurityConfig.java b/src/main/java/trothly/trothcam/config/SecurityConfig.java index 84943a1..41919f7 100644 --- a/src/main/java/trothly/trothcam/config/SecurityConfig.java +++ b/src/main/java/trothly/trothcam/config/SecurityConfig.java @@ -36,7 +36,7 @@ public void configure(WebSecurity web) { "/auth/google", "/auth/validate-token", "/auth/check-id/**", "/auth/signup", "/auth/login", "/auth/logout", - "/h2-console/**", "/health-check", "/sample/**"); + "/h2-console/**", "/health-check", "/sample/**", "/api/image/**"); } // 스프링시큐리티 설정 @@ -62,6 +62,7 @@ protected void configure(HttpSecurity http) throws Exception { .antMatchers("/h2-console/**").permitAll() .antMatchers("/health-check").permitAll() .antMatchers("/sample/**").permitAll() + .antMatchers("/api/image/**").permitAll() //.antMatchers("/**").permitAll() // 로그인 개발 끝나면 삭제 .anyRequest().authenticated() .and() diff --git a/src/main/java/trothly/trothcam/controller/web/LikeProductController.java b/src/main/java/trothly/trothcam/controller/web/LikeProductController.java new file mode 100644 index 0000000..e215ba5 --- /dev/null +++ b/src/main/java/trothly/trothcam/controller/web/LikeProductController.java @@ -0,0 +1,41 @@ +package trothly.trothcam.controller.web; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.*; +import trothly.trothcam.domain.member.Member; +import trothly.trothcam.dto.web.LikeProductReqDto; +import trothly.trothcam.dto.web.LikeResDto; +import trothly.trothcam.exception.base.BaseResponse; +import trothly.trothcam.exception.custom.BadRequestException; +import trothly.trothcam.service.web.LikeProductService; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/api/like-product") +public class LikeProductController { + + private final LikeProductService likeProductService; + + /* 좋아요 저장 */ + @PostMapping("") + public BaseResponse saveLike(@RequestBody LikeProductReqDto req, @AuthenticationPrincipal Member member) { + if(req.getProductId() == null) { + throw new BadRequestException("존재하지 않는 상품 아이디 입니다."); + } + + LikeResDto res = likeProductService.saveLike(req, member); + return BaseResponse.onSuccess(res); + } + + /* 좋아요 삭제 */ + @DeleteMapping("") + public BaseResponse deleteLike(@RequestBody LikeProductReqDto req, @AuthenticationPrincipal Member member) { + if(req.getProductId() == null) { + throw new BadRequestException("존재하지 않는 상품 아이디 입니다."); + } + + LikeResDto res = likeProductService.deleteLike(req, member); + return BaseResponse.onSuccess(res); + } +} diff --git a/src/main/java/trothly/trothcam/domain/image/Image.java b/src/main/java/trothly/trothcam/domain/image/Image.java index dc5ba26..6e250f4 100644 --- a/src/main/java/trothly/trothcam/domain/image/Image.java +++ b/src/main/java/trothly/trothcam/domain/image/Image.java @@ -3,6 +3,8 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; import trothly.trothcam.domain.core.BaseTimeEntity; import trothly.trothcam.domain.member.Member; @@ -11,6 +13,8 @@ @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +@DynamicUpdate @Table(name = "image") public class Image extends BaseTimeEntity { diff --git a/src/main/java/trothly/trothcam/domain/like/LikeProduct.java b/src/main/java/trothly/trothcam/domain/like/LikeProduct.java index d9a9388..d2b42ee 100644 --- a/src/main/java/trothly/trothcam/domain/like/LikeProduct.java +++ b/src/main/java/trothly/trothcam/domain/like/LikeProduct.java @@ -26,4 +26,9 @@ public class LikeProduct extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; + + public LikeProduct(Product product, Member member){ + this.product = product; + this.member = member; + } } diff --git a/src/main/java/trothly/trothcam/domain/like/LikeProductRepository.java b/src/main/java/trothly/trothcam/domain/like/LikeProductRepository.java new file mode 100644 index 0000000..86db10f --- /dev/null +++ b/src/main/java/trothly/trothcam/domain/like/LikeProductRepository.java @@ -0,0 +1,14 @@ +package trothly.trothcam.domain.like; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface LikeProductRepository extends JpaRepository { + + Optional findByProductIdAndMemberId(Long productId, Long memberId); + + Long countById(Long id); +} diff --git a/src/main/java/trothly/trothcam/domain/product/Product.java b/src/main/java/trothly/trothcam/domain/product/Product.java index 033a01b..7fd52d1 100644 --- a/src/main/java/trothly/trothcam/domain/product/Product.java +++ b/src/main/java/trothly/trothcam/domain/product/Product.java @@ -51,7 +51,7 @@ public class Product extends BaseTimeEntity { private int views; @Column(name = "likes", nullable = false) - private int likes; + private Long likes; @Column(name = "public_yn", nullable = false) @Enumerated(EnumType.STRING) diff --git a/src/main/java/trothly/trothcam/domain/product/ProductRepository.java b/src/main/java/trothly/trothcam/domain/product/ProductRepository.java index 5275fd2..a599a97 100644 --- a/src/main/java/trothly/trothcam/domain/product/ProductRepository.java +++ b/src/main/java/trothly/trothcam/domain/product/ProductRepository.java @@ -9,6 +9,6 @@ @Repository public interface ProductRepository extends JpaRepository { - List findAllByMember_WebIdAndPublicYn_Y(String webId); // 공개 인증서 조회 - List findAllByMember_WebIdAndPublicYn_N(String webId); // 비공개 인증서 조회 +// List findAllByMember_WebIdAndPublicYn_Y(String webId); // 공개 인증서 조회 +// List findAllByMember_WebIdAndPublicYn_N(String webId); // 비공개 인증서 조회 } diff --git a/src/main/java/trothly/trothcam/dto/web/LikeProductReqDto.java b/src/main/java/trothly/trothcam/dto/web/LikeProductReqDto.java new file mode 100644 index 0000000..ef484b0 --- /dev/null +++ b/src/main/java/trothly/trothcam/dto/web/LikeProductReqDto.java @@ -0,0 +1,13 @@ +package trothly.trothcam.dto.web; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class LikeProductReqDto { + private Long productId; +} diff --git a/src/main/java/trothly/trothcam/dto/web/LikeResDto.java b/src/main/java/trothly/trothcam/dto/web/LikeResDto.java new file mode 100644 index 0000000..14a77dd --- /dev/null +++ b/src/main/java/trothly/trothcam/dto/web/LikeResDto.java @@ -0,0 +1,13 @@ +package trothly.trothcam.dto.web; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class LikeResDto { + private String message; +} diff --git a/src/main/java/trothly/trothcam/service/web/LikeProductService.java b/src/main/java/trothly/trothcam/service/web/LikeProductService.java new file mode 100644 index 0000000..77cc6d7 --- /dev/null +++ b/src/main/java/trothly/trothcam/service/web/LikeProductService.java @@ -0,0 +1,53 @@ +package trothly.trothcam.service.web; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import trothly.trothcam.domain.like.LikeProduct; +import trothly.trothcam.domain.like.LikeProductRepository; +import trothly.trothcam.domain.member.Member; +import trothly.trothcam.domain.product.Product; +import trothly.trothcam.domain.product.ProductRepository; +import trothly.trothcam.dto.web.LikeProductReqDto; +import trothly.trothcam.dto.web.LikeResDto; +import trothly.trothcam.exception.base.BaseException; +import trothly.trothcam.exception.custom.BadRequestException; + +import java.util.Optional; + +@Service +@Transactional +@RequiredArgsConstructor +public class LikeProductService { + + private final LikeProductRepository likeProductRepository; + private final ProductRepository productRepository; + + // 좋아요 저장 + public LikeResDto saveLike(LikeProductReqDto req, Member member) throws BaseException { + Optional like = likeProductRepository.findByProductIdAndMemberId(req.getProductId(), member.getId()); + + if(like.isPresent()) { + throw new BadRequestException("이미 좋아요를 누른 상품입니다."); + } + + Product product = productRepository.findById(req.getProductId()).orElseThrow( + () -> new BadRequestException("존재하지 않는 상품입니다.") + ); + + LikeProduct newLike = likeProductRepository.save(new LikeProduct(product, member)); + + return new LikeResDto("좋아요 성공"); + } + + // 좋아요 삭제 + public LikeResDto deleteLike(LikeProductReqDto req, Member member) throws BaseException { + LikeProduct likeProduct = likeProductRepository.findByProductIdAndMemberId(req.getProductId(), member.getId()).orElseThrow( + () -> new BadRequestException("좋아요를 누르지 않은 상품입니다.") + ); + + likeProductRepository.deleteById(likeProduct.getId()); + + return new LikeResDto("좋아요 해제 성공"); + } +} diff --git a/src/main/java/trothly/trothcam/service/web/ProductService.java b/src/main/java/trothly/trothcam/service/web/ProductService.java index e354df1..e2383d6 100644 --- a/src/main/java/trothly/trothcam/service/web/ProductService.java +++ b/src/main/java/trothly/trothcam/service/web/ProductService.java @@ -25,15 +25,15 @@ @RequiredArgsConstructor public class ProductService { - private final ProductRepository productRepository; - - /* 공개 인증서 조회 */ - @Transactional(readOnly = true) - public List findPublicProducts(String webId) throws BaseException { - List findProducts = productRepository.findAllByMember_WebIdAndPublicYn_Y(webId); - if (findProducts == null || findProducts.isEmpty()) - throw new ProductNotFoundException(ErrorCode.PRODUCT_NOT_FOUND); - - return findProducts; - } +// private final ProductRepository productRepository; +// +// /* 공개 인증서 조회 */ +// @Transactional(readOnly = true) +// public List findPublicProducts(String webId) throws BaseException { +// List findProducts = productRepository.findAllByMember_WebIdAndPublicYn_Y(webId); +// if (findProducts == null || findProducts.isEmpty()) +// throw new ProductNotFoundException(ErrorCode.PRODUCT_NOT_FOUND); +// +// return findProducts; +// } }