diff --git a/customer-vue/src/api/order.js b/customer-vue/src/api/order.js index 7b3002f..e65bab7 100644 --- a/customer-vue/src/api/order.js +++ b/customer-vue/src/api/order.js @@ -26,6 +26,8 @@ export default { }, deleteOrderItem(orderItemId){ return axios.delete(process.env.VUE_APP_ORDER_API_URL + "/orderItem/"+orderItemId); + }, + getOrderDetail(orderId) { + return axios.get(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL + "/order-service/api/order-detail/" + orderId); } - } \ No newline at end of file diff --git a/customer-vue/src/components/OrderHistoryCard.vue b/customer-vue/src/components/OrderHistoryCard.vue index 4ae1f59..3d354ec 100644 --- a/customer-vue/src/components/OrderHistoryCard.vue +++ b/customer-vue/src/components/OrderHistoryCard.vue @@ -12,7 +12,7 @@ - {{ card.orderStatus }} + {{ card.orderStatus | getOrderStatusName }}
{{ card.orderItemNames }} @@ -50,6 +50,7 @@ export default { name: "OrderHistoryCard", props: { card: { + orderId: String, storeId: Number, storeName: String, orderTime: String, @@ -66,7 +67,10 @@ export default { }) }, clickDetail: function() { - alert("준비 중입니다."); + this.$router.push({ + name: "order-detail", + params: {orderId: this.card.orderId} + }); } } } diff --git a/customer-vue/src/main.js b/customer-vue/src/main.js index 9f625bf..3f7aea6 100644 --- a/customer-vue/src/main.js +++ b/customer-vue/src/main.js @@ -19,10 +19,29 @@ axios.interceptors.request.use(function (config) { config.headers.Authorization = "Bearer " + jwt.getToken(); return config; }); + Vue.filter('currency', function (value) { var num = new Number(value); return num.toFixed(0).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,") }); +Vue.filter('getOrderStatusName', function (orderStatus) { + switch (orderStatus) { + case "PLACED": + return "주문신청"; + case "ACCEPTED": + return "주문수락"; + case "REJECTED": + return "주문거절"; + case "WAITING": + return "픽업대기"; + case "FINISHED": + return "픽업완료"; + case "FAILED": + return "주문실패"; + default: + break; + } +}); axios.interceptors.response.use( (response) => { @@ -43,6 +62,8 @@ axios.interceptors.response.use( alert("권한이 없습니다. 다시 로그인 해주세요"); return Promise.reject(error2); } + } else { + if (error.response.data.message) alert(error.response.data.message); } return Promise.reject(error); } diff --git a/customer-vue/src/router/router.js b/customer-vue/src/router/router.js index c17e0c4..084719c 100644 --- a/customer-vue/src/router/router.js +++ b/customer-vue/src/router/router.js @@ -82,6 +82,13 @@ const routes = [ name: 'mypage', component: () => import('../views/MyPage') }, + { + path: "/order-detail/:orderId", + beforeEnter: authCheck, + name: 'order-detail', + props: true, + component: () => import('../views/OrderDetail') + }, ] }, { diff --git a/customer-vue/src/views/OrderDetail.vue b/customer-vue/src/views/OrderDetail.vue new file mode 100644 index 0000000..7c1e299 --- /dev/null +++ b/customer-vue/src/views/OrderDetail.vue @@ -0,0 +1,137 @@ + + + + + \ No newline at end of file diff --git a/customer-vue/src/views/OrderHistory.vue b/customer-vue/src/views/OrderHistory.vue index 8b6f055..63831ee 100644 --- a/customer-vue/src/views/OrderHistory.vue +++ b/customer-vue/src/views/OrderHistory.vue @@ -51,14 +51,10 @@ export default { methods: { search: async function() { this.isLoading = true; - try { - this.page = 0; - const response = await orderApi.requestOrderHistory(this.page); - this.cards = []; - this.renderCard(response.data); - } catch (error) { - console.log(error); - } + this.page = 0; + const response = await orderApi.requestOrderHistory(this.page); + this.cards = []; + this.renderCard(response.data); this.isLoading = false; }, more: async function() { @@ -85,19 +81,11 @@ export default { storeId: order.storeId, storeName: order.storeName, orderPrice: order.orderPrice, - orderStatus: this.getOrderStatusName(order.orderStatus), + orderStatus: order.orderStatus, orderItemNames: this.getOrderItemName(order.orderItems) }) }); }, - getOrderStatusName(orderStatus) { - if (orderStatus === "PLACED") return "주문신청"; - if (orderStatus === "REJECTED") return "주문거절"; - if (orderStatus === "ACCEPTED") return "주문수락"; - if (orderStatus === "WAITING") return "픽업대기"; - if (orderStatus === "FINISHED") return "픽업완료"; - return orderStatus; - }, getOrderItemName(orderItems) { const itemSize = orderItems.length; if (itemSize == 1) return orderItems[0].orderItemName; diff --git a/order-service/src/docs/asciidoc/api-docs.adoc b/order-service/src/docs/asciidoc/api-docs.adoc index 47a3793..036edc3 100644 --- a/order-service/src/docs/asciidoc/api-docs.adoc +++ b/order-service/src/docs/asciidoc/api-docs.adoc @@ -67,6 +67,8 @@ domain-httpRequestCode-etc == 주문 === 주문 수정 operation::order-patch[snippets='curl-request,http-request,http-response,path-parameters,request-fields,response-fields'] +=== 주문 상세보기 +operation::api-orderDetail[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] == 점주 서비스 === 주문 페이지 diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderDetailDto.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderDetailDto.java new file mode 100644 index 0000000..9665d44 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderDetailDto.java @@ -0,0 +1,122 @@ +package com.justpickup.orderservice.domain.order.dto; + +import com.justpickup.orderservice.domain.order.entity.Order; +import com.justpickup.orderservice.domain.order.entity.OrderStatus; +import com.justpickup.orderservice.domain.orderItem.entity.OrderItem; +import com.justpickup.orderservice.domain.orderItemOption.entity.OrderItemOption; +import com.justpickup.orderservice.global.client.store.OptionType; +import lombok.*; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) +public class OrderDetailDto { + + private Long id; + private LocalDateTime orderTime; + private Long orderPrice; + private OrderStatus orderStatus; + private String storeName; + private OrderDetailUser user; + private List orderItems = new ArrayList<>(); + + @Builder + public OrderDetailDto(Long id, LocalDateTime orderTime, Long orderPrice, OrderStatus orderStatus, + String storeName, OrderDetailUser user, List orderItems) { + this.id = id; + this.orderTime = orderTime; + this.orderPrice = orderPrice; + this.orderStatus = orderStatus; + this.storeName = storeName; + this.user = user; + this.orderItems = orderItems; + } + + public static OrderDetailDto of(Order order, String storeName, + List orderItems, OrderDetailUser orderDetailUser) { + OrderDetailDto orderDetailDto = new OrderDetailDto(); + orderDetailDto.id = order.getId(); + orderDetailDto.orderTime = order.getOrderTime(); + orderDetailDto.orderPrice = order.getOrderPrice(); + orderDetailDto.orderStatus = order.getOrderStatus(); + + orderDetailDto.storeName = storeName; + + orderDetailDto.user = orderDetailUser; + orderDetailDto.orderItems = orderItems; + return orderDetailDto; + } + + @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class OrderDetailUser { + private Long id; + private String name; + private String phoneNumber; + + @Builder + public OrderDetailUser(Long id, String name, String phoneNumber) { + this.id = id; + this.name = name; + this.phoneNumber = phoneNumber; + } + } + + @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class OrderDetailItem { + private Long id; + private Long itemId; + private long totalPrice; + private long count; + private String name; + private List options = new ArrayList<>(); + + @Builder + public OrderDetailItem(Long id, Long itemId, long totalPrice, long count, String name, List options) { + this.id = id; + this.itemId = itemId; + this.totalPrice = totalPrice; + this.count = count; + this.name = name; + this.options = options; + } + + public static OrderDetailItem of(OrderItem orderItem, String name, List orderDetailItemOption) { + OrderDetailItem orderDetailItem = new OrderDetailItem(); + orderDetailItem.id = orderItem.getId(); + orderDetailItem.itemId = orderItem.getItemId(); + orderDetailItem.totalPrice = orderItem.getTotalPrice(); + orderDetailItem.count = orderItem.getCount(); + orderDetailItem.name = name; + orderDetailItem.options = orderDetailItemOption; + return orderDetailItem; + } + + } + + @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class OrderDetailItemOption { + private Long id; + private Long itemOptionId; + private String name; + private OptionType optionType; + + @Builder + public OrderDetailItemOption(Long id, Long itemOptionId, String name, OptionType optionType) { + this.id = id; + this.itemOptionId = itemOptionId; + this.name = name; + this.optionType = optionType; + } + + public static OrderDetailItemOption of(OrderItemOption orderItemOption, String name, OptionType optionType) { + OrderDetailItemOption orderDetailItemOption = new OrderDetailItemOption(); + orderDetailItemOption.id = orderItemOption.getId(); + orderDetailItemOption.itemOptionId = orderItemOption.getItemOptionId(); + orderDetailItemOption.name = name; + orderDetailItemOption.optionType = optionType; + return orderDetailItemOption; + } + } +} diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/Order.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/Order.java index faa1f51..ef7406d 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/Order.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/Order.java @@ -112,9 +112,4 @@ public class Order extends BaseEntity { public void fail() { this.orderStatus = OrderStatus.FAILED; } - - - public void changeOrderDate(LocalDateTime orderTime){ - this.orderTime = orderTime; - } } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/repository/OrderRepositoryCustom.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/repository/OrderRepositoryCustom.java index 7811f9f..86aaf15 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/repository/OrderRepositoryCustom.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/repository/OrderRepositoryCustom.java @@ -80,6 +80,7 @@ public class OrderRepositoryCustom { .leftJoin(order.transaction) .where( order.orderTime.between(search.getStartDateTime(), search.getEndDateTime()), + order.orderStatus.ne(OrderStatus.PENDING), order.storeId.eq(storeId) ) .fetchOne(); diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderService.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderService.java index b7a95e4..2bb4fa3 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderService.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderService.java @@ -16,4 +16,5 @@ public interface OrderService { FetchOrderDto fetchOrder(Long userId); void saveOrder(Long userId); void modifyOrder(Long userId, OrderStatus orderStatus); + OrderDetailDto findOrderDetail(Long orderId); } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java index dc79f8e..a428594 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java @@ -8,11 +8,10 @@ import com.justpickup.orderservice.domain.order.repository.OrderRepository; import com.justpickup.orderservice.domain.order.repository.OrderRepositoryCustom; import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; import com.justpickup.orderservice.domain.orderItem.entity.OrderItem; +import com.justpickup.orderservice.domain.orderItem.repository.OrderItemRepositoryCustom; import com.justpickup.orderservice.domain.orderItemOption.entity.OrderItemOption; -import com.justpickup.orderservice.global.client.store.GetItemResponse; -import com.justpickup.orderservice.global.client.store.GetStoreResponse; -import com.justpickup.orderservice.global.client.store.StoreByUserIdResponse; -import com.justpickup.orderservice.global.client.store.StoreClient; +import com.justpickup.orderservice.global.client.store.*; +import com.justpickup.orderservice.global.client.user.GetCustomerResponse; import com.justpickup.orderservice.global.client.user.UserClient; import com.justpickup.orderservice.global.dto.Result; import lombok.RequiredArgsConstructor; @@ -27,7 +26,9 @@ import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; +import static com.justpickup.orderservice.domain.order.dto.OrderDetailDto.*; import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; @Service @RequiredArgsConstructor @@ -37,6 +38,7 @@ public class OrderServiceImpl implements OrderService { private final OrderRepository orderRepository; private final OrderRepositoryCustom orderRepositoryCustom; + private final OrderItemRepositoryCustom orderItemRepositoryCustom; private final StoreClient storeClient; private final UserClient userClient; @@ -266,4 +268,70 @@ public class OrderServiceImpl implements OrderService { return DashBoardDto.of(orderPrices , bestSellItem, sellAmountAWeeks); } + + @Override + public OrderDetailDto findOrderDetail(Long orderId) { + Order order = orderRepository.findById(orderId) + .orElseThrow(() -> new OrderException(orderId + "는 없는 주문 번호입니다.")); + + List orderItemsWithOptions = orderItemRepositoryCustom.getOrderItemsWithOptions(order.getId()); + + + + Set itemIds = new HashSet<>(); + + // 아이템 이름 및 옵션 이름 가져오기 + for (OrderItem orderItem : orderItemsWithOptions) { + itemIds.add(orderItem.getItemId()); + } + + Map itemAndItemOptionMap = storeClient.getItemAndItemOptionMap(itemIds); + + List orderDetailItems = orderItemsWithOptions.stream() + .map(orderItem -> { + // 주문 상세 옵션 생성 + GetItemResponse itemResponse = itemAndItemOptionMap.get(orderItem.getItemId()); + + // 아이템 옵션 맵 생성 + Map itemOptionMap = itemResponse.getItemOptions().stream() + .collect( + toMap(GetItemResponse.ItemOptionDto::getId, itemOptionDto -> itemOptionDto) + ); + + List orderDetailItemOptions = orderItem.getOrderItemOptions() + .stream() + .map(orderItemOption -> { + // 옵션 아이디에 해당하는 아이템 옵션 객체 가져오기 + GetItemResponse.ItemOptionDto itemOptionDto = + itemOptionMap.get(orderItemOption.getItemOptionId()); + + return OrderDetailItemOption.of( + orderItemOption, + itemOptionDto.getName(), + itemOptionDto.getOptionType() + ); + }) + .collect(toList()); + // 아이템 아이디에 해당하는 아이템 이름 가져오기 + String itemName = itemResponse.getName(); + return OrderDetailItem.of(orderItem, itemName, orderDetailItemOptions); + }) + .collect(toList()); + + // 고객 정보 가져오기 + GetCustomerResponse customerInfo = userClient.getCustomerById(order.getUserId()).getData(); + + // 주문한 사용자 정보 생성 + OrderDetailUser orderDetailUser = OrderDetailUser.builder() + .id(customerInfo.getUserId()) + .phoneNumber(customerInfo.getPhoneNumber()) + .name(customerInfo.getUserName()) + .build(); + + // 매장 정보 가져오기 + GetStoreResponse storeInfo = storeClient.getStore(String.valueOf(order.getStoreId())).getData(); + + return OrderDetailDto.of(order, storeInfo.getName(), orderDetailItems, orderDetailUser); + } + } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderController.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderController.java index 7639088..e9df423 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderController.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderController.java @@ -1,8 +1,10 @@ package com.justpickup.orderservice.domain.order.web; +import com.justpickup.orderservice.domain.order.dto.OrderDetailDto; import com.justpickup.orderservice.domain.order.entity.OrderStatus; import com.justpickup.orderservice.domain.order.exception.OrderException; import com.justpickup.orderservice.domain.order.service.OrderService; +import com.justpickup.orderservice.global.client.store.OptionType; import com.justpickup.orderservice.global.dto.Result; import lombok.AllArgsConstructor; import lombok.Data; @@ -10,10 +12,12 @@ import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; @RestController @RequiredArgsConstructor @@ -26,7 +30,7 @@ public class OrderController { public ResponseEntity patchOrder(@PathVariable("orderId") Long orderId, @RequestBody PatchOrderRequest patchOrderRequest) { OrderStatus orderStatus = patchOrderRequest.getOrderStatus(); - if (orderStatus == OrderStatus.PENDING && orderStatus != OrderStatus.FAILED) { + if (orderStatus == OrderStatus.PENDING || orderStatus == OrderStatus.FAILED) { throw new OrderException(orderStatus.getMessage() + "는 변경 불가능합니다."); } @@ -39,4 +43,83 @@ public class OrderController { static class PatchOrderRequest { private OrderStatus orderStatus; } + + @GetMapping("/api/order-detail/{orderId}") + public ResponseEntity getOrderDetail(@PathVariable Long orderId) { + + OrderDetailDto orderDetail = orderService.findOrderDetail(orderId); + return ResponseEntity.ok(Result.createSuccessResult(new OrderDetailResponse(orderDetail))); + } + + @Data @NoArgsConstructor @AllArgsConstructor + static class OrderDetailResponse { + private Long id; + private OrderStatus orderStatus; + private String orderTime; + private Long orderPrice; + private String storeName; + private OrderDetailUserResponse user; + private List orderItems = new ArrayList<>(); + + public OrderDetailResponse(OrderDetailDto dto) { + this.id = dto.getId(); + this.orderStatus = dto.getOrderStatus(); + this.orderTime = dto.getOrderTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); + this.orderPrice = dto.getOrderPrice(); + this.storeName = dto.getStoreName(); + this.user = new OrderDetailUserResponse(dto.getUser()); + this.orderItems = dto.getOrderItems().stream() + .map(OrderDetailItemResponse::new) + .collect(Collectors.toList()); + } + + @Data + static class OrderDetailUserResponse { + private Long id; + private String name; + private String phoneNumber; + + public OrderDetailUserResponse(OrderDetailDto.OrderDetailUser user) { + this.id = user.getId(); + this.name = user.getName(); + this.phoneNumber = user.getPhoneNumber(); + } + } + + @Data @NoArgsConstructor + static class OrderDetailItemResponse { + private Long id; + private Long itemId; + private long totalPrice; + private long count; + private String name; + private List options = new ArrayList<>(); + + public OrderDetailItemResponse(OrderDetailDto.OrderDetailItem orderDetailItem) { + this.id = orderDetailItem.getId(); + this.itemId = orderDetailItem.getItemId(); + this.totalPrice = orderDetailItem.getTotalPrice(); + this.count = orderDetailItem.getCount(); + this.name = orderDetailItem.getName(); + this.options = orderDetailItem.getOptions().stream() + .map(OrderDetailItemOptionResponse::new) + .collect(Collectors.toList()); + } + } + + @Data @NoArgsConstructor + static class OrderDetailItemOptionResponse { + private Long id; + private Long itemOptionId; + private String name; + private OptionType optionType; + + public OrderDetailItemOptionResponse(OrderDetailDto.OrderDetailItemOption itemOption) { + this.id = itemOption.getId(); + this.itemOptionId = itemOption.getItemOptionId(); + this.name = itemOption.getName(); + this.optionType = itemOption.getOptionType(); + } + } + } } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/orderItem/repository/OrderItemRepositoryCustom.java b/order-service/src/main/java/com/justpickup/orderservice/domain/orderItem/repository/OrderItemRepositoryCustom.java new file mode 100644 index 0000000..ddcda8b --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/orderItem/repository/OrderItemRepositoryCustom.java @@ -0,0 +1,27 @@ +package com.justpickup.orderservice.domain.orderItem.repository; + +import com.justpickup.orderservice.domain.orderItem.entity.OrderItem; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +import static com.justpickup.orderservice.domain.orderItem.entity.QOrderItem.orderItem; + +@Repository +@RequiredArgsConstructor +public class OrderItemRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + public List getOrderItemsWithOptions(Long orderId) { + return queryFactory.selectFrom(orderItem) + .leftJoin(orderItem.orderItemOptions).fetchJoin() + .where( + orderItem.order.id.eq(orderId) + ) + .distinct() + .fetch(); + } +} diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemResponse.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemResponse.java index a4d2c56..6cf5284 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemResponse.java +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemResponse.java @@ -4,7 +4,6 @@ import com.justpickup.orderservice.global.entity.Yn; import lombok.*; import java.util.List; -import java.util.stream.Collectors; @Getter @NoArgsConstructor diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/ItemOptionsResponse.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/ItemOptionsResponse.java new file mode 100644 index 0000000..1eba651 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/ItemOptionsResponse.java @@ -0,0 +1,10 @@ +package com.justpickup.orderservice.global.client.store; + +import lombok.Data; + +@Data +public class ItemOptionsResponse { + private Long id; + private OptionType optionType; + private String name; +} diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/StoreClient.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/StoreClient.java index d132873..8842fcb 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/StoreClient.java +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/StoreClient.java @@ -32,7 +32,7 @@ public interface StoreClient { Result getStore(@PathVariable(value = "storeId") String storeId); @GetMapping("/api/customer/items/{itemId}") - Result> getItemAndItemOptions(@PathVariable(value = "itemId") List itemIds); + Result> getItemAndItemOptions(@PathVariable(value = "itemId") Iterable itemIds); default Map getStoreNameMap(Set storeIds) { List storeResponses = this.getStoreAllById(storeIds).getData(); @@ -50,5 +50,11 @@ public interface StoreClient { ); } - + default Map getItemAndItemOptionMap(Iterable itemIds) { + List responses = this.getItemAndItemOptions(itemIds).getData(); + return responses.stream() + .collect( + toMap(GetItemResponse::getId, getItemsResponse -> getItemsResponse) + ); + } } diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/exception/GlobalExceptionHandler.java b/order-service/src/main/java/com/justpickup/orderservice/global/exception/GlobalExceptionHandler.java index 4d08327..cb4516f 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/global/exception/GlobalExceptionHandler.java +++ b/order-service/src/main/java/com/justpickup/orderservice/global/exception/GlobalExceptionHandler.java @@ -19,6 +19,8 @@ public class GlobalExceptionHandler { HttpStatus status = ce.getStatus(); Result errorResult = ce.getErrorResult(); + log.warn("[CustomException] {}, {}", status, errorResult); + return ResponseEntity.status(status) .body(errorResult); } diff --git a/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderControllerTest.java b/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderControllerTest.java index b17c477..89ad9ee 100644 --- a/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderControllerTest.java +++ b/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderControllerTest.java @@ -1,12 +1,12 @@ package com.justpickup.orderservice.domain.order.web; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.justpickup.orderservice.config.TestConfig; +import com.justpickup.orderservice.domain.order.dto.OrderDetailDto; import com.justpickup.orderservice.domain.order.entity.OrderStatus; -import com.justpickup.orderservice.domain.order.repository.OrderRepository; import com.justpickup.orderservice.domain.order.service.OrderService; import com.justpickup.orderservice.domain.order.web.OrderController.PatchOrderRequest; +import com.justpickup.orderservice.global.client.store.OptionType; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -18,11 +18,14 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; -import static org.junit.jupiter.api.Assertions.*; +import java.time.LocalDateTime; +import java.util.List; + +import static org.mockito.BDDMockito.given; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @@ -77,4 +80,98 @@ class OrderControllerTest { ; } + + @Test + @DisplayName("[GET] 주문 상세 내역 가져오기") + void getOrderDetail() throws Exception { + // GIVEN + Long orderId = 1589L; + + given(orderService.findOrderDetail(orderId)).willReturn(getOrderDetailWillReturn(orderId)); + // THEN + ResultActions actions = mockMvc.perform(get("/api/order-detail/{orderId}", String.valueOf(orderId))); + // WHEN + actions.andExpect(status().isOk()) + .andDo(print()) + .andDo(document("api-orderDetail", + pathParameters( + parameterWithName("orderId").description("주문 고유번호") + ), + responseFields( + fieldWithPath("code").description("결과코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메세지"), + fieldWithPath("data.id").description("주문 고유번호"), + fieldWithPath("data.orderTime").description("주문 시간 [yyy-MM-dd]"), + fieldWithPath("data.orderPrice").description("주문 금액"), + fieldWithPath("data.user.id").description("주문한 회원 고유번호"), + fieldWithPath("data.user.name").description("주문한 회원 이름"), + fieldWithPath("data.user.phoneNumber").description("주문한 회원 전화번호"), + fieldWithPath("data.orderItems[*].id").description("주문아이템 고유번호"), + fieldWithPath("data.orderItems[*].itemId").description("아이템 고유번호"), + fieldWithPath("data.orderItems[*].totalPrice").description("주문아이템 총합계"), + fieldWithPath("data.orderItems[*].count").description("주문아이템 수량"), + fieldWithPath("data.orderItems[*].name").description("아이템 이름"), + fieldWithPath("data.orderItems[*].options[*].id").description("주문아이템옵션 고유번호"), + fieldWithPath("data.orderItems[*].options[*].itemOptionId").description("아이템옵션 고유번호"), + fieldWithPath("data.orderItems[*].options[*].name").description("아이템옵션 이름"), + fieldWithPath("data.orderItems[*].options[*].optionType").description("아이템옵션 타입") + ) + )) + ; + } + + private OrderDetailDto getOrderDetailWillReturn(Long orderId) { + OrderDetailDto.OrderDetailUser orderDetailUser = OrderDetailDto.OrderDetailUser.builder() + .id(6L) + .name("박상범") + .phoneNumber("010-1234-5678") + .build(); + + long id = 11371L; + long itemOptionId = 40L; + OrderDetailDto.OrderDetailItemOption ice = OrderDetailDto.OrderDetailItemOption.builder() + .id(id++) + .itemOptionId(itemOptionId++) + .name("ICE") + .optionType(OptionType.REQUIRED) + .build(); + + OrderDetailDto.OrderDetailItemOption hot = OrderDetailDto.OrderDetailItemOption.builder() + .id(id++) + .itemOptionId(itemOptionId++) + .name("HOT") + .optionType(OptionType.REQUIRED) + .build(); + + OrderDetailDto.OrderDetailItemOption plus = OrderDetailDto.OrderDetailItemOption.builder() + .id(id++) + .itemOptionId(itemOptionId++) + .name("시럽 추가") + .optionType(OptionType.OTHER) + .build(); + + OrderDetailDto.OrderDetailItem 카페라떼 = OrderDetailDto.OrderDetailItem.builder() + .id(id++) + .itemId(itemOptionId++) + .count(2) + .name("카페라떼") + .options(List.of(hot, plus)) + .build(); + + OrderDetailDto.OrderDetailItem 아메리카노 = OrderDetailDto.OrderDetailItem.builder() + .id(id++) + .itemId(itemOptionId++) + .count(2) + .options(List.of(ice)) + .name("아메리카노") + .build(); + + return OrderDetailDto.builder() + .id(orderId) + .orderTime(LocalDateTime.now()) + .orderPrice(76600L) + .user(orderDetailUser) + .orderItems(List.of(카페라떼, 아메리카노)) + .build(); + } } \ No newline at end of file diff --git a/owner-vue/src/api/order.js b/owner-vue/src/api/order.js index cdc0d8b..d298a78 100644 --- a/owner-vue/src/api/order.js +++ b/owner-vue/src/api/order.js @@ -28,5 +28,8 @@ export default { }, findDashboard(){ return axios.get(process.env.VUE_APP_API_URL + "/order/dashboard"); + }, + getOrderDetail(orderId) { + return axios.get(process.env.VUE_APP_OWNER_SERVICE_BASEURL + "/order-service/api/order-detail/" + orderId); } } \ No newline at end of file diff --git a/owner-vue/src/components/OrderCard.vue b/owner-vue/src/components/OrderCard.vue index 15dffad..2ddcd09 100644 --- a/owner-vue/src/components/OrderCard.vue +++ b/owner-vue/src/components/OrderCard.vue @@ -1,84 +1,96 @@ diff --git a/owner-vue/src/components/OrderDetailDialog.vue b/owner-vue/src/components/OrderDetailDialog.vue new file mode 100644 index 0000000..ad55eed --- /dev/null +++ b/owner-vue/src/components/OrderDetailDialog.vue @@ -0,0 +1,166 @@ + + + + + \ No newline at end of file diff --git a/owner-vue/src/main.js b/owner-vue/src/main.js index 408e90d..2a37957 100644 --- a/owner-vue/src/main.js +++ b/owner-vue/src/main.js @@ -27,8 +27,10 @@ Vue.filter('getOrderStatusName', function (orderStatus) { return "픽업대기중"; case "FINISHED": return "픽업완료됨"; + case "FAILED": + return "주문실패"; default: - break; + return orderStatus; } }); diff --git a/owner-vue/src/views/PrevOrder.vue b/owner-vue/src/views/PrevOrder.vue index bf1615e..c4508cf 100644 --- a/owner-vue/src/views/PrevOrder.vue +++ b/owner-vue/src/views/PrevOrder.vue @@ -25,6 +25,12 @@ hide-default-footer class="elevation-1" > +
findByItem(Long itemId) { - - return queryFactory.selectFrom(QItemOption.itemOption) - .join(QItemOption.itemOption.item) - .on(item.id.eq(itemId)) - .fetch(); - } - - } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/service/ItemOptionService.java b/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/service/ItemOptionService.java index 0a1bad5..6d54383 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/service/ItemOptionService.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/service/ItemOptionService.java @@ -1,25 +1,4 @@ package com.justpickup.storeservice.domain.itemoption.service; -import com.justpickup.storeservice.domain.item.dto.ItemDto; -import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto; -import com.justpickup.storeservice.domain.itemoption.repository.ItemOptionRepository; -import com.justpickup.storeservice.domain.itemoption.repository.ItemOptionRepositoryCustom; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.stream.Collectors; - -@Service -@Slf4j -@RequiredArgsConstructor -public class ItemOptionService { - private final ItemOptionRepositoryCustom itemOptionRepositoryCustom; - - public List getItemOption( ItemDto itemDto){ - return itemOptionRepositoryCustom.findByItem(itemDto.getId()) - .stream().map(ItemOptionDto::new) - .collect(Collectors.toList()); - } +public interface ItemOptionService { } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/service/ItemOptionServiceImpl.java b/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/service/ItemOptionServiceImpl.java new file mode 100644 index 0000000..2191f74 --- /dev/null +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/service/ItemOptionServiceImpl.java @@ -0,0 +1,12 @@ +package com.justpickup.storeservice.domain.itemoption.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + + +@Slf4j +@RequiredArgsConstructor +@Service +public class ItemOptionServiceImpl implements ItemOptionService { +} diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/web/ItemOptionController.java b/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/web/ItemOptionController.java index f278507..c0e0fe3 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/web/ItemOptionController.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/web/ItemOptionController.java @@ -1,5 +1,6 @@ package com.justpickup.storeservice.domain.itemoption.web; +import com.justpickup.storeservice.domain.itemoption.service.ItemOptionService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.RestController; @@ -7,6 +8,5 @@ import org.springframework.web.bind.annotation.RestController; @RequiredArgsConstructor public class ItemOptionController { - - + private final ItemOptionService itemOptionService; }