Skip to content

Commit

Permalink
Merge pull request #30 from Uni-Made/feature/#13
Browse files Browse the repository at this point in the history
✨ [FEATURE] 찜하기 기능 구현 (#13)
  • Loading branch information
moonyaeyoon authored Jul 19, 2024
2 parents afa640e + 5aa9113 commit 2be01d9
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package umc.unimade.domain.accounts.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import umc.unimade.domain.accounts.entity.Buyer;

public interface BuyerRepository extends JpaRepository<Buyer, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package umc.unimade.domain.favorite.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import umc.unimade.domain.accounts.entity.Buyer;
import umc.unimade.domain.favorite.entity.FavoriteProduct;
import umc.unimade.domain.products.entity.Products;

import java.util.Optional;

public interface FavoriteProductRepository extends JpaRepository<FavoriteProduct, Long> {
Optional<FavoriteProduct> findByProductAndBuyer(Products product, Buyer buyer);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package umc.unimade.domain.favorite.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import umc.unimade.domain.favorite.entity.FavoriteSeller;


public interface FavoriteSellerRepository extends JpaRepository<FavoriteSeller, Long> {
}
19 changes: 19 additions & 0 deletions src/main/java/umc/unimade/domain/products/ProductsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@
import lombok.*;
import umc.unimade.domain.products.dto.ProductResponse;
import umc.unimade.domain.products.entity.ViewType;
import umc.unimade.domain.products.service.ProductsCommandService;
import umc.unimade.domain.products.service.ProductsQueryService;
import umc.unimade.global.common.ApiResponse;
import umc.unimade.global.common.ErrorCode;
import umc.unimade.global.common.exception.ProductsExceptionHandler;
import umc.unimade.global.common.exception.UserExceptionHandler;


@RestController
@RequestMapping("/api/products")
@RequiredArgsConstructor
public class ProductsController {
private final ProductsQueryService productsQueryService;
private final ProductsCommandService productsCommandService;

@Tag(name = "Products", description = "판매 상품 관련 API")
@Operation(summary = "판매 상품 정보 가져오기")
Expand All @@ -30,9 +33,25 @@ public class ProductsController {
try {
PageRequest pageRequest = PageRequest.of(page, size);
return ResponseEntity.ok(ApiResponse.onSuccess(productsQueryService.getProduct(productId, viewType, pageRequest)));
}
catch (IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.onFailure(HttpStatus.BAD_REQUEST.name(), e.getMessage()));
} catch (ProductsExceptionHandler e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.onFailure(ErrorCode.PRODUCT_NOT_FOUND.getCode(), ErrorCode.PRODUCT_NOT_FOUND.getMessage()));
}
}

//To do : buyerId 추후에 토큰으로 변경
@Tag(name = "favoriteProduct", description = "상품 찜하기/취소 API")
@Operation(summary = "찜하지 않은 상태라면 찜하기. \n 찜한 상태라면 찜하기 취소")
@PostMapping("/favorite/{productId}/{buyerId}")
public ResponseEntity<ApiResponse<Void>> toggleFavoriteProduct(@PathVariable Long productId, @PathVariable Long buyerId) {
try {
return ResponseEntity.ok(productsCommandService.toggleFavoriteProduct(productId, buyerId));
} catch (IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.onFailure(HttpStatus.BAD_REQUEST.name(), e.getMessage()));
} catch (UserExceptionHandler e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.onFailure(ErrorCode.BUYER_NOT_FOUND.getCode(), ErrorCode.BUYER_NOT_FOUND.getMessage()));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package umc.unimade.domain.products.service;

import io.netty.util.internal.ObjectPool;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import umc.unimade.domain.accounts.entity.Buyer;
import umc.unimade.domain.accounts.repository.BuyerRepository;
import umc.unimade.domain.favorite.entity.FavoriteProduct;
import umc.unimade.domain.favorite.repository.FavoriteProductRepository;
import umc.unimade.domain.favorite.repository.FavoriteSellerRepository;
import umc.unimade.domain.products.ProductRepository;
import umc.unimade.domain.products.entity.Products;
import umc.unimade.global.common.ApiResponse;
import umc.unimade.global.common.ErrorCode;
import umc.unimade.global.common.exception.ProductsExceptionHandler;
import umc.unimade.global.common.exception.UserExceptionHandler;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class ProductsCommandService {

private final FavoriteProductRepository favoriteProductRepository;
private final FavoriteSellerRepository favoriteSellerRepository;
private final ProductRepository productRepository;
private final BuyerRepository buyerRepository;

@Transactional
public ApiResponse<Void> toggleFavoriteProduct(Long productId, Long buyerId) {
Products product = findProductById(productId);
Buyer buyer = findBuyerById(buyerId);
Optional<FavoriteProduct> existingFavorite = findFavoriteProduct(product,buyer);

if (existingFavorite.isPresent()) {
favoriteProductRepository.delete(existingFavorite.get());
return ApiResponse.CANCELED_LIKE();
}else{
FavoriteProduct favoriteProduct = FavoriteProduct.builder()
.buyer(buyer)
.product(product)
.build();
favoriteProductRepository.save(favoriteProduct);
return ApiResponse.SUCCESS_LIKE();
}
}



private Buyer findBuyerById(Long buyerId) {
return buyerRepository.findById(buyerId).orElseThrow(() -> new UserExceptionHandler(ErrorCode.BUYER_NOT_FOUND));
}
private Products findProductById(Long productId){
return productRepository.findById(productId).orElseThrow(() -> new ProductsExceptionHandler(ErrorCode.PRODUCT_NOT_FOUND));
}
private Optional<FavoriteProduct> findFavoriteProduct(Products product, Buyer buyer) {
return favoriteProductRepository.findByProductAndBuyer(product, buyer);
}
}
2 changes: 1 addition & 1 deletion src/main/java/umc/unimade/global/common/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public enum ErrorCode implements BaseErrorCode {

// Accounts 관련 에러
USER_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "USER4000", "사용자가 이미 존재합니다."),

BUYER_NOT_FOUND(HttpStatus.NOT_FOUND, "USER4040", "구매자를 찾을 수 없습니다."),
// Products 관련 에러
PRODUCT_NOT_FOUND(HttpStatus.NOT_FOUND, "PRODUCT4040", "해당 제품을 찾을 수 없습니다.");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package umc.unimade.global.common.exception;

import umc.unimade.global.common.BaseErrorCode;

public class UserExceptionHandler extends CustomException{

public UserExceptionHandler (BaseErrorCode code ){
super(code);
}
}

0 comments on commit 2be01d9

Please sign in to comment.