스프링 쇼핑몰 프로젝트 3주차

윤장원·2023년 6월 5일
0

쇼핑몰프로젝트

목록 보기
3/5

상품 조회하기 리팩토링

최신순, 낮은 가격순, 주문 횟수 많은 순으로 상품 조회하기 기능의 구조가 동일하여 하나의 요청 형식으로 수정했다. 요청할 때 page, size, sort 형식을 함께 보내면 그에 맞는 결과를 가져온다.

ProductController

@GetMapping("/list")
  public ResponseEntity<List<ProductInfo>> getLatestProducts(Pageable pageable) {
    return ResponseEntity.ok(productService.getProducts(pageable));
  }

ProductService

public List<ProductInfo> getProducts(Pageable pageable) {
    Page<Product> products = productRepository.findAll(pageable);

    return ProductInfo.toList(products);
  }

상품 상세 정보 불러오기

상품 id를 받으면 상품 상세 정보를 불러오는 기능 구현했다.

ProductController

@GetMapping("/info/{id}")
  public ResponseEntity<ProductInfo> getProductInfo(
      @PathVariable long id
  ) {
    return ResponseEntity.ok(productService.getProductInfo(id));
  }

ProductService

public ProductInfo getProductInfo(Long id) {
    Product product = productRepository.findById(id)
        .orElseThrow(() -> new CustomException(ErrorCode.PRODUCT_NOT_FOUND));

    return ProductInfo.from(product);
  }

장바구니 담기

장바구니 정보를 담을 Cart 엔티티를 생성했다.

Cart

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
public class Cart {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @ManyToOne
  @JoinColumn(name = "customer_id")
  @ToString.Exclude
  private Customer customer;

  @ManyToOne
  @JoinColumn(name = "product_id")
  @ToString.Exclude
  private Product product;

  private Integer quantity;
}

JWT 토큰에 담긴 Customer Id로 Customer를 조회하고, 장바구니 담기할 때 Product가 존재하는지 확인한다. 해당 상품의 남은 수량과 장바구니에 담는 수량을 비교하여 장바구니 수량이 더 많으면 Custom Error가 발생하게 했다. 만약 해당 Customer Id, Product Id를 가지고 있는 장바구니가 존재하면 해당 장바구니에서 상품 수량을 추가하는 기능을 구현했다.

CartController

@PostMapping
  @PreAuthorize("hasRole('CUSTOMER')")
  public ResponseEntity<String> registerProduct(
      @RequestHeader(name = HttpHeaders.AUTHORIZATION) String token,
      @RequestBody AddCartForm form
  ) {
    cartService.addCart(token, form);
    return ResponseEntity.ok(ADD_CART_SUCCESS);
  }

CartService

public void addCart(String token, AddCartForm form) {
    UserVo vo = provider.getUserVo(token);

    Customer customer = customerRepository.findById(vo.getId())
        .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

    Product product = productRepository.findById(form.getProductId())
        .orElseThrow(() -> new CustomException(ErrorCode.PRODUCT_NOT_FOUND));

    Optional<Cart> optionalExistCart = cartRepository.findByCustomerIdAndProductId(
        vo.getId(),
        form.getProductId());

    if (optionalExistCart.isPresent()) {
      Cart existCart = optionalExistCart.get();

      Integer totalQuantity = existCart.getQuantity() + form.getQuantity();

      if (!checkQuantity(product.getQuantity(), totalQuantity)) {
        throw new CustomException(ErrorCode.NOT_ENOUGH_QUANTITY);
      }

      existCart.setQuantity(totalQuantity);

      cartRepository.save(existCart);
    } else {

      if (!checkQuantity(product.getQuantity(), form.getQuantity())) {
        throw new CustomException(ErrorCode.NOT_ENOUGH_QUANTITY);
      }

      Cart cart = Cart.builder()
          .customer(customer)
          .product(product)
          .quantity(form.getQuantity())
          .build();

      cartRepository.save(cart);
    }
  }

장바구니 수정, 삭제

CartController

  @PutMapping
  @PreAuthorize("hasRole('CUSTOMER')")
  public ResponseEntity<String> editCart(
      @RequestHeader(name = HttpHeaders.AUTHORIZATION) String token,
      @RequestBody EditCartForm form
  ) {
    cartService.editCart(token, form);
    return ResponseEntity.ok(EDIT_CART_SUCCESS);
  }

  @ApiOperation(value = "하나의 상품을 장바구니에서 제거")
  @DeleteMapping("/item/{id}")
  @PreAuthorize("hasRole('CUSTOMER')")
  public ResponseEntity<String> deleteCartItem(
      @RequestHeader(name = HttpHeaders.AUTHORIZATION) String token,
      @Parameter(name = "id", description = "장바구니 아이디")
      @PathVariable("id") long id
  ) {
    cartService.deleteCartItem(token, id);
    return ResponseEntity.ok(DELETE_CART_ITEM_SUCCESS);
  }

  @ApiOperation(value = "장바구니 전체 삭제")
  @DeleteMapping("/items")
  @PreAuthorize("hasRole('CUSTOMER')")
  public ResponseEntity<String> deleteAllCart(
      @RequestHeader(name = HttpHeaders.AUTHORIZATION) String token
  ) {
    long cnt = cartService.deleteAllCart(token);
    return ResponseEntity.ok(cnt + "개의 상품 " + DELETE_ALL_CART_SUCCESS);
  }

CartService

@Override
  public void editCart(String token, EditCartForm form) {
    Customer customer = getCustomerFromToken(token);

    Product product = productRepository.findById(form.getProductId())
        .orElseThrow(() -> new CustomException(ErrorCode.PRODUCT_NOT_FOUND));

    Cart cart = cartRepository.findByCustomerIdAndProductId(customer.getId(), product.getId())
        .orElseThrow(() -> new CustomException(ErrorCode.CART_NOT_FOUND));

    if (!checkQuantity(product.getQuantity(), form.getQuantity())) {
      throw new CustomException(ErrorCode.NOT_ENOUGH_QUANTITY);
    }

    cart.setQuantity(form.getQuantity());

    cartRepository.save(cart);
  }

  @Override
  public void deleteCartItem(String token, Long productId) {
    Customer customer = getCustomerFromToken(token);

    Product product = productRepository.findById(productId)
        .orElseThrow(() -> new CustomException(ErrorCode.PRODUCT_NOT_FOUND));

    Cart cart = cartRepository.findByCustomerIdAndProductId(customer.getId(), product.getId())
        .orElseThrow(() -> new CustomException(ErrorCode.CART_NOT_FOUND));

    cartRepository.delete(cart);
  }
  
  @Override
  @Transactional
  public long deleteAllCart(String token) {
    Customer customer = getCustomerFromToken(token);

    Long cnt = cartRepository.deleteByCustomerId(customer.getId());

    return cnt;
  }

0개의 댓글