봄수의 연구실

🐥 카카오 테크 캠퍼스 - 2단계 5주차 과제 분석 본문

프로젝트/카카오 테크 캠퍼스

🐥 카카오 테크 캠퍼스 - 2단계 5주차 과제 분석

berom 2023. 7. 25. 22:19

과제 목표

카카오 쇼핑 프로젝트 전체 코드를 리팩토링한다
 - AOP로 유효성검사 적용하기
 - GlobalExceptionHanlder -> 예외 처리하기
 - 구현하기
 - 장바구니 담기
 - 장바구니 수정(주문하기) -> 예외처리하기
 - 결재하기 기능 구현 (장바구니가 꼭 초기화 되어야함)
 - 주문결과 확인 기능 구현

필수 적용 사항

  • AOP가 적용되었는가?
  • GlobalExceptionHandler가 적용되었는가?
  • 장바구니 담기시 모든 예외가 처리 완료되었는가?
  • 장바구니 수정시 모든 예외가 처리 완료되었는가?
  • 결재하기와 주문결과 확인 코드가 완료되었는가?

1. 장바구니 담기 : /carts/add

@Transactional(readOnly = true)
@RequiredArgsConstructor
@Service
public class CartService {

    private final CartJPARepository cartJPARepository;
    private final OptionJPARepository optionJPARepository;

    @Transactional
    public void addCartList(List<CartRequest.SaveDTO> requestDTOs, User sessionUser) {

        Map<Integer, Integer> optionIdToQuantityMap = consolidateQuantities(requestDTOs);

        for (Integer optionId : optionIdToQuantityMap.keySet()) {
            Option option = findOption(optionId);
            int quantity = optionIdToQuantityMap.get(optionId);
            int price = option.getPrice() * quantity;

            Cart cart = cartJPARepository.findByOptionIdAndUserId(optionId, sessionUser.getId()).orElse(null);
            if (cart != null) {
                cartJPARepository.updateQuantityAndPrice(cart.getId(), cart.getQuantity()+quantity, cart.getPrice()+price);
            } else {
                Cart newCart = Cart.builder().user(sessionUser).option(option).quantity(quantity).price(price).build();
                cartJPARepository.save(newCart);
            }
        }
    }

해결해야 할 문제

2. 장바구니 수정(주문하기) : /carts/update

@Transactional
public CartResponse.UpdateDTO update(List<CartRequest.UpdateDTO> requestDTOs, User user) {
  List<Cart> cartList = cartJPARepository.findAllByUserId(user.getId());

  // 1. 유저 장바구니에 아무것도 없으면 예외처리

  // 2. cartId:1, cartId:1 이렇게 requestDTOs에 동일한 장바구니 아이디가 두번 들어오면 예외처리

  // 3. 유저 장바구니에 없는 cartId가 들어오면 예외처리

  // 위에 3개를 처리하지 않아도 프로그램은 잘돌아간다. 예를 들어 1번을 처리하지 않으면 for문을 돌지 않고, cartList가 빈배열 []로 정상응답이 나감.
  for (Cart cart : cartList) {
		for (CartRequest.UpdateDTO updateDTO : requestDTOs) {
			 if (cart.getId() == updateDTO.getCartId()) {
				  cart.update(updateDTO.getQuantity(), cart.getOption().getPrice() * updateDTO.getQuantity());
			 }
		}
  }

  return new CartResponse.UpdateDTO(cartList);
}

해결해야 할 문제

3. 결제하기 기능 구현 : /carts/orders/save

해결해야 할 문제

응답 Json 확인

  • 기본 응답 인터페이스는 제거하고 바로 분석을 합니다
{
    "id": 2,
    "products": [
      {
        "productName": "기본에 슬라이딩 지퍼백 크리스마스/플라워에디션 에디션 외 주방용품 특가전",
        "items": [
          {
            "id": 4,
            "optionName": "01. 슬라이딩 지퍼백 크리스마스에디션 4종",
            "quantity": 10,
            "price": 100000
          },
          {
            "id": 5,
            "optionName": "02. 슬라이딩 지퍼백 플라워에디션 5종",
            "quantity": 10,
            "price": 109000
          }
        ]
      }
    ],
    "totalPrice": 209000
  • Order DTO
    • id
    • products : List
    • totalPrice
  • Product DTO
    • productName //option에 묶인 Product로 가져온다
    • items : List // option과 user로 생성한다
  • Item DTO
    • id
    • option Name
    • quantity
    • price

핵심 로직

  • user Id로 cart_tb의 물건을 모두 가져온다

  • Order Insert

  • Item Insert

  • 어떤 쿼리가 필요할까?

    • user Id로 새로운 order 생성
    • product Id,Product Name을 얻으려고 Option 조회해야 함
    • cart table에서 얻은 option Id로 Item insert해야함

4. 주문결과 확인 기능 구현 : /carts/orders/

// (기능10) 주문 결과 확인 GET// /orders/{id}  
public void findById() {  
  
}

응답 Json 확인

처음 주문 결과를 확인하면 아래와 같은 응답을 반환합니다

{
    "success": true,
    "response": {
        "id": 2,
        "products": [
            {
                "productName": "Basic Sliding Zipper Bag Christmas/Flower Edition Special exhibition on kitchen items other than Dition",
                "items": [
                    {
                        "id": 4,
                        "optionName": "01. Sliding Zipper Bag Christmas Edition 4 bell",
                        "quantity": 10,
                        "price": 100000
                    },
                    {
                        "id": 5,
                        "optionName": "02. Sliding Zipper Bag Flower Edition 5 bell",
                        "quantity": 10,
                        "price": 109000
                    }
                ]
            }
        ],
        "totalPrice": 209000
    },
    "error": null
}

상세 Json 확인 : DTO 분석

{
	"id": 2,
	"products": [
		{
			 "productName": "Basic Sliding Zipper Bag Christmas/Flower Edition Special exhibition on kitchen items other than Dition",
			 "items": [
				  {
						"id": 4,
						"optionName": "01. Sliding Zipper Bag Christmas Edition 4 bell",
						"quantity": 10,
						"price": 100000
				  },
				  {
						"id": 5,
						"optionName": "02. Sliding Zipper Bag Flower Edition 5 bell",
						"quantity": 10,
						"price": 109000
				  }
			 ]
		}
	],
	"totalPrice": 209000
}
  • 필요한 필드
    • id : Product Id
    • products : Product List
    • totalPrice : 전체 가격

products에 대한 DTO가 추가로 필요함을 알 수 있다

Product Json 확인

"products": [
	{
		 "productName": "Basic Sliding Zipper Bag Christmas/Flower Edition Special exhibition on kitchen items other than Dition",
		 "items": [
			  {
					"id": 4,
					"optionName": "01. Sliding Zipper Bag Christmas Edition 4 bell",
					"quantity": 10,
					"price": 100000
			  },
			  {
					"id": 5,
					"optionName": "02. Sliding Zipper Bag Flower Edition 5 bell",
					"quantity": 10,
					"price": 109000
			  }
		 ]
	}
],
  • 필요한 필드
    • productName : product 이름
    • items : item List

Items Json 확인

"items": [
	{
		"id": 4,
		"optionName": "01. Sliding Zipper Bag Christmas Edition 4 bell",
		"quantity": 10,
		"price": 100000
	},
	{
		"id": 5,
		"optionName": "02. Sliding Zipper Bag Flower Edition 5 bell",
		"quantity": 10,
		"price": 109000
	}
]
  • 필요한 필드
    • id
    • option Name
    • quantity
    • price

부족한 점이나 잘못 된 점을 알려주시면 시정하겠습니다 :>