Skip to content
This repository has been archived by the owner on Aug 13, 2022. It is now read-only.

[#45] 주문기능 제작 #46

Merged
merged 28 commits into from
Jan 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f782b3b
장바구니 기능 구현
Nov 28, 2019
6cb06dd
cart index delete 기능 구현 및 Test code 작성
Nov 29, 2019
54f8112
- Redis tranasaction 적용
Dec 2, 2019
7cafad5
장바구니 로직 추가
Dec 3, 2019
fe79388
- OrderDTO 생성
binaryyoung Dec 3, 2019
454c57c
- 캐싱하기 적합한 DTO를 사용하도록 변경
Dec 3, 2019
82905b6
빈 테스트코드 추가(Test ERROR)
Dec 3, 2019
489e028
OrderDTO에 @JsonFormat 추가
binaryyoung Dec 4, 2019
15d2f50
리뷰 반영
Dec 4, 2019
0989bc5
사용하지 않는 menuService 제거
Dec 9, 2019
9db3122
DTO를 Inner Class로 분리
Dec 9, 2019
e6cbc9b
가상 결제 구현
Dec 9, 2019
691a57e
사용하지 않는 코드 제거
Dec 10, 2019
b9d20d0
주문 로직 개발
Dec 11, 2019
a437709
계산서 발행 로직 작성 및 리뷰 일부 반영
Dec 13, 2019
792dc36
거리 계산로직 추가
Dec 13, 2019
4341748
배달료 계산 로직 추가
Dec 13, 2019
a280675
insert문을 벌크 insert로 진행하도록 변경
Dec 17, 2019
85a5f6e
주문 기능 제작
Dec 17, 2019
0d394c2
계산서 발행 시 메뉴, 메뉴 옵션에 의해 다수의 SELECT 쿼리가 질의되는 문제 해결
Dec 18, 2019
224158e
자신의 주문 정보 조회 기능 추가
Dec 18, 2019
4dc041c
OrderDTO 불변객체로 변경
Dec 19, 2019
1ddf344
유효성 검사 추가 및 변경
Dec 19, 2019
aeea70a
OrderDTO 수정으로 인한 버그 수정
Dec 19, 2019
a2f8bc4
리뷰 반영
Dec 23, 2019
cff527d
가상 결제 시스템 브랜치와 병합
Dec 24, 2019
8e1b0c3
가상 결제 진행 개발
Dec 24, 2019
a1732c1
Merge branch 'develop' into feature/20
yyy9942 Jan 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/main/java/com/delfood/config/RedisConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.sql.SQLException;
import java.time.Duration;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -17,6 +19,9 @@
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
public class RedisConfig {
Expand All @@ -29,7 +34,7 @@ public class RedisConfig {
@Value("${spring.redis.password}")
private String redisPwd;

@Value("${spring.redis.defaultExpireSecond}")
@Value("${default.expire.second}")
private long defaultExpireSecond;


Expand Down Expand Up @@ -90,7 +95,8 @@ public RedisTemplate<String, Object> redisTemplate(ObjectMapper objectMapper) {
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(serializer);

redisTemplate.setEnableTransactionSupport(true); // transaction 허용

return redisTemplate;
}

Expand Down Expand Up @@ -125,5 +131,6 @@ public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectio
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory)
.cacheDefaults(configuration).build();
}



}
66 changes: 66 additions & 0 deletions src/main/java/com/delfood/controller/CartControllelr.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.delfood.controller;

import com.delfood.aop.MemberLoginCheck;
import com.delfood.dto.ItemDTO;
import com.delfood.service.CartService;
import com.delfood.utils.SessionUtil;
import java.util.List;
import javax.servlet.http.HttpSession;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CartControllelr {

@Autowired
private CartService cartService;

@PostMapping("/members/cart/menus")
@MemberLoginCheck
public void addMenu(@RequestBody ItemDTO item, HttpSession session) {
cartService.addOrdersItem(item, SessionUtil.getLoginMemberId(session));
}

@GetMapping("/members/cart/menus")
@MemberLoginCheck
public List<ItemDTO> getCart(HttpSession session) {
return cartService.getItems(SessionUtil.getLoginMemberId(session));
}

@DeleteMapping("/members/cart/menus")
@MemberLoginCheck
public void clearCart(HttpSession session) {
cartService.claer(SessionUtil.getLoginMemberId(session));
}

@DeleteMapping("/members/cart/menus/{index}")
@MemberLoginCheck
public void deleteCartMenu(HttpSession session, @PathVariable long index) {
cartService.deleteCartMenu(SessionUtil.getLoginMemberId(session), index);
}

@GetMapping("/members/cart/price")
@MemberLoginCheck
public CartPriceResponse cartPrice(HttpSession session) {
String memberId = SessionUtil.getLoginMemberId(session);
return new CartPriceResponse(cartService.getItems(memberId), cartService.allPrice(memberId));
}



// Response
@Getter
@AllArgsConstructor
private static class CartPriceResponse {
private List<ItemDTO> items;
private long totalPrice;
}

}
142 changes: 142 additions & 0 deletions src/main/java/com/delfood/controller/OrderController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package com.delfood.controller;

import com.delfood.aop.MemberLoginCheck;
import com.delfood.controller.response.OrderResponse;
import com.delfood.dto.ItemsBillDTO;
import com.delfood.dto.OrderDTO;
import com.delfood.dto.OrderItemDTO;
import com.delfood.error.exception.order.TotalPriceMismatchException;
import com.delfood.dto.OrderBillDTO;
import com.delfood.service.OrderService;
import com.delfood.utils.SessionUtil;
import java.util.List;
import javax.servlet.http.HttpSession;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import org.codehaus.commons.nullanalysis.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/orders/")
@Log4j2
public class OrderController {

@Autowired
OrderService orderService;

/**
* 아이템들의 가격과 정보를 조회한다.
* @author jun
* @param items 가격을 계산할 아이템들
* @return
*/
@GetMapping("price")
@MemberLoginCheck
public long getItemsBill(HttpSession session, @RequestBody List<OrderItemDTO> items) {
return orderService.totalPrice(SessionUtil.getLoginMemberId(session), items);
}

/**
* 주문 정보를 조회한다. 주문한 메뉴, 옵션, 가격 등의 정보를 조회할 수 있다.
* @author jun
* @param orderId 주문번호
* @return
*/
@GetMapping("{orderId}/bill")
@MemberLoginCheck
public OrderBillDTO orderInfo(@PathVariable("orderId") Long orderId) {
return orderService.getPreOrderBill(orderId);
}

/**
* 주문을 진행한다.
* 클라이언트에서 계산한 총 가격과 서버에서 계산한 총 가격이 다를 시 에러를 발생시킨다.
* @param session 사용자의 세션
* @param request 주문 정보
* @return
*/
@PostMapping
@MemberLoginCheck
public OrderResponse order(HttpSession session, @RequestBody OrderRequest request) {
if (request.getItems().isEmpty()) {
// items가 null일때도 NullpointerException이 발생한다
throw new NullPointerException("아이템이 없습니다.");
}

// 해당 아이템들이 해당 매장의 것인지 검증
if (orderService.isShopItems(request.getItems(), request.getShopId()) == false) {
log.error("주문하신 매장의 메뉴 또는 옵션이 아닙니다.");
throw new IllegalArgumentException("주문하신 매장의 메뉴 또는 옵션이 아닙니다.");
}
// 클라이언트가 계산한 금액과 서버에서 계산한 금액이 같은지 비교
long totalPriceFromServer =
orderService.totalPrice(SessionUtil.getLoginMemberId(session), request.getItems());
if (totalPriceFromServer != request.getTotalPrice()) {
log.error("Total Price Mismatch! client price : {}, server price : {}",
request.getTotalPrice(),
totalPriceFromServer);
throw new TotalPriceMismatchException("Total Price Mismatch!");
}

return orderService.order(SessionUtil.getLoginMemberId(session), request.getItems(),
request.getShopId());
}

/**
* 아이템 리스트들을 상세하게 계산서로 발행한다.
* @param session 사용자의 세션
* @param items 주문하기 전 아이템들
* @return
*/
@GetMapping("bill")
@MemberLoginCheck
public ItemsBillDTO getBill(HttpSession session, @RequestBody List<OrderItemDTO> items) {
return orderService.getBill(SessionUtil.getLoginMemberId(session), items);
}

/**
* 회원 주문내역을 모두 조회한다.
* 추후 페이징 추가 해야한다.
* @author jun
* @param session 사용자의 세션
* @return
*/
@GetMapping
@MemberLoginCheck
public List<OrderDTO> myOrders(HttpSession session, @Nullable Long lastViewedOrderId) {
return orderService.getMemberOrder(SessionUtil.getLoginMemberId(session), lastViewedOrderId);
}

/**
* 주문 번호를 기반으로 주문 상세내역을 조회한다.
* 추후 해당 회원의 주문인지 확인하는 로직을 작성해야한다.
* @param session 사용자의 세션
* @param orderId 주문 아이디
* @return
*/
@GetMapping("{orderId}")
@MemberLoginCheck
public OrderDTO getOrder(HttpSession session, @PathVariable Long orderId) {
OrderDTO orderInfo = orderService.getOrder(orderId);
String memberId = SessionUtil.getLoginMemberId(session);
if (memberId.equals(orderInfo.getMemberId()) == false) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

세션에서 가져온건데 유저랑 다를일은 없을 것 같네요. 이거는 처리해주지 않아도 되는 예외같습니다

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 회원이 주문한 것이 아닌 다른 회원의 주문일 때 문제가 될 수 있어서 처리하였습니다.

throw new IllegalArgumentException("해당 회원의 주문이 아닙니다!");
}
return orderInfo;
}

// request
@Getter
private static class OrderRequest {
private Long shopId;
private List<OrderItemDTO> items;
private long totalPrice;
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/delfood/controller/response/OrderResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.delfood.controller.response;

import com.delfood.dto.ItemsBillDTO;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class OrderResponse {
ItemsBillDTO bill;
Long orderId;
}
Loading