diff --git a/customer-vue/src/views/OrderHistory.vue b/customer-vue/src/views/OrderHistory.vue index 20a4f9e..639885b 100644 --- a/customer-vue/src/views/OrderHistory.vue +++ b/customer-vue/src/views/OrderHistory.vue @@ -79,20 +79,27 @@ export default { const orders = data.orders; orders.forEach( (order) => { - let orderItemNames = []; - order.orderItems.forEach(orderItem => { - orderItemNames.push(orderItem.orderItemName); - }) - this.cards.push({ orderId: order.orderId, orderTime: order.orderTime, storeName: order.storeName, orderPrice: order.orderPrice, - orderStatus: order.orderStatus, - orderItemNames: orderItemNames.join(", ") + orderStatus: this.getOrderStatusName(order.orderStatus), + orderItemNames: this.getOrderItemName(order.orderItems) }) }); + }, + getOrderStatusName(orderStatus) { + if (orderStatus === "REJECT") return "주문 거절"; + if (orderStatus === "ORDER") return "주문 중"; + if (orderStatus === "PLACED") return "주문 수락"; + return orderStatus; + }, + getOrderItemName(orderItems) { + const itemSize = orderItems.length; + if (itemSize == 1) return orderItems[0].orderItemName; + else if (itemSize > 1) return orderItems[0].orderItemName + " 외 " + (itemSize - 1) + "건"; + else return "없음"; } } } diff --git a/order-service/src/docs/asciidoc/api-docs.adoc b/order-service/src/docs/asciidoc/api-docs.adoc index b6f73e3..f5c4776 100644 --- a/order-service/src/docs/asciidoc/api-docs.adoc +++ b/order-service/src/docs/asciidoc/api-docs.adoc @@ -72,16 +72,16 @@ operation::order-patch[snippets='curl-request,http-request,http-response,path-pa === 주문 페이지 - 페이지 offset : 6 -operation::orderMain-get[snippets='curl-request,http-request,http-response,request-parameters,response-fields'] +operation::orderMain-get[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields'] === 점주 서비스 - 주문 페이지 (잘못된 파라미터 형식) -operation::orderMain-get-badParameterException[snippets='curl-request,http-request,http-response,request-parameters,response-fields'] +operation::orderMain-get-badParameterException[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields'] === 점주 서비스 - 지난 주문 페이지 -operation::prevOrder-get[snippets='curl-request,http-request,http-response,request-parameters,response-fields'] +operation::prevOrder-get[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields'] === 점주 서비스 - 지난 주문 페이지 (잘못된 파라미터 형식) -operation::prevOrder-get-BindException[snippets='curl-request,http-request,http-response,request-parameters,response-fields'] +operation::prevOrder-get-BindException[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields'] == Just Pick-up === 주문 내역 페이지 diff --git a/order-service/src/main/java/com/justpickup/orderservice/OrderServiceApplication.java b/order-service/src/main/java/com/justpickup/orderservice/OrderServiceApplication.java index a785347..698d9fd 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/OrderServiceApplication.java +++ b/order-service/src/main/java/com/justpickup/orderservice/OrderServiceApplication.java @@ -1,17 +1,9 @@ package com.justpickup.orderservice; -import com.justpickup.orderservice.domain.order.entity.Order; -import com.justpickup.orderservice.domain.order.repository.OrderRepository; -import com.justpickup.orderservice.domain.orderItem.entity.OrderItem; -import com.justpickup.orderservice.domain.orderItemOption.entity.OrderItemOption; -import com.justpickup.orderservice.domain.transaction.entity.Transaction; -import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; -import org.springframework.context.annotation.Bean; -import org.springframework.transaction.annotation.Transactional; @SpringBootApplication @EnableEurekaClient @@ -22,38 +14,4 @@ public class OrderServiceApplication { SpringApplication.run(OrderServiceApplication.class, args); } - @Bean - @Transactional - CommandLineRunner run(OrderRepository orderRepository) { - return args -> { - Long userId = 2L; - Long userCouponId = null; - Long storeId = 1L; - Long orderPrice = 1000L; - - for (int i = 1; i <= 20; i++) { - Transaction transaction = Transaction.of(); - - Long itemId = 1L; - Long price = 100L; - Long count = 1L; - OrderItem orderItem = OrderItem.of(itemId + i, price * i, count + i, - OrderItemOption.of(), OrderItemOption.of()); - - OrderItem orderItem1 = OrderItem.of(itemId + i + 1, price * (i + 1), count + (i + 1), - OrderItemOption.of(), OrderItemOption.of()); - - Order order = Order.of(userId, userCouponId, storeId, orderPrice * i, transaction, orderItem, orderItem1); - - if (i % 2 == 0) { - order.placed(); - } else { - order.order(); - } - - orderRepository.save(order); - } - }; - } - } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderHistoryDto.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderHistoryDto.java new file mode 100644 index 0000000..f90dcb2 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderHistoryDto.java @@ -0,0 +1,80 @@ +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 lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class OrderHistoryDto { + private Long id; + private LocalDateTime orderTime; + private long price; + private OrderStatus orderStatus; + private Long storeId; + private String storeName; + private List<_OrderHistoryItem> orderItems = new ArrayList<>(); + + @Builder + public OrderHistoryDto(Long id, LocalDateTime orderTime, long price, OrderStatus orderStatus, Long storeId, String storeName, List<_OrderHistoryItem> orderItems) { + this.id = id; + this.orderTime = orderTime; + this.price = price; + this.orderStatus = orderStatus; + this.storeId = storeId; + this.storeName = storeName; + this.orderItems = orderItems; + } + + @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class _OrderHistoryItem { + private Long id; + private Long itemId; + private String itemName; + + @Builder + public _OrderHistoryItem(Long id, Long itemId, String itemName) { + this.id = id; + this.itemId = itemId; + this.itemName = itemName; + } + + public static _OrderHistoryItem of(OrderItem orderItem) { + _OrderHistoryItem orderHistoryItem = new _OrderHistoryItem(); + orderHistoryItem.id = orderItem.getId(); + orderHistoryItem.itemId = orderItem.getItemId(); + return orderHistoryItem; + } + + public void changeItemName(String itemName) { + this.itemName = itemName; + } + } + + public static OrderHistoryDto of(Order order) { + OrderHistoryDto orderHistoryDto = new OrderHistoryDto(); + orderHistoryDto.id = order.getId(); + orderHistoryDto.orderTime = order.getOrderTime(); + orderHistoryDto.price = order.getOrderPrice(); + orderHistoryDto.orderStatus = order.getOrderStatus(); + orderHistoryDto.storeId = order.getUserId(); + + orderHistoryDto.orderItems = order.getOrderItems().stream() + .map(_OrderHistoryItem::of) + .collect(Collectors.toList()); + return orderHistoryDto; + } + + public void changeStoreName(String storeName) { + this.storeName = storeName; + } +} diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderMainDto.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderMainDto.java index 37be351..8b9b0cd 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderMainDto.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderMainDto.java @@ -50,6 +50,10 @@ public class OrderMainDto { .orderItems(orderItems) .build(); } + + public void changeUserName(String userName) { + this.userName = userName; + } } @Getter @Builder @@ -64,5 +68,9 @@ public class OrderMainDto { .itemId(orderItem.getItemId()) .build(); } + + public void changeItemName(String itemName) { + this.itemName = itemName; + } } } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/PrevOrderDto.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/PrevOrderDto.java new file mode 100644 index 0000000..9de89fd --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/PrevOrderDto.java @@ -0,0 +1,88 @@ +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 lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.toList; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class PrevOrderDto { + private Long id; + private OrderStatus orderStatus; + private LocalDateTime orderTime; + private long orderPrice; + private Long userId; + private String userName; + + private List<_PrevOrderItem> orderItems = new ArrayList<>(); + + @Builder + public PrevOrderDto(Long id, OrderStatus orderStatus, LocalDateTime orderTime, long orderPrice, Long userId, String userName, List<_PrevOrderItem> orderItems) { + this.id = id; + this.orderStatus = orderStatus; + this.orderTime = orderTime; + this.orderPrice = orderPrice; + this.userId = userId; + this.userName = userName; + this.orderItems = orderItems; + } + + @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class _PrevOrderItem { + private Long id; + private Long itemId; + private String name; + + @Builder + public _PrevOrderItem(Long id, Long itemId, String name) { + this.id = id; + this.itemId = itemId; + this.name = name; + } + + // 생성 메소드 + static _PrevOrderItem of(OrderItem orderItem) { + _PrevOrderItem prevOrderItem = new _PrevOrderItem(); + prevOrderItem.id = orderItem.getId(); + prevOrderItem.itemId = orderItem.getItemId(); + return prevOrderItem; + } + + public void changeName(String name) { + this.name = name; + } + } + + // 생성 메소드 + public static PrevOrderDto of(Order order) { + PrevOrderDto prevOrder = new PrevOrderDto(); + prevOrder.id = order.getId(); + prevOrder.orderStatus = order.getOrderStatus(); + prevOrder.orderTime = order.getOrderTime(); + prevOrder.orderPrice = order.getOrderPrice(); + prevOrder.userId = order.getUserId(); + + prevOrder.orderItems = order.getOrderItems() + .stream() + .map(_PrevOrderItem::of) + .collect(toList()); + + return prevOrder; + } + + public void changeUserName(String userName) { + this.userName = userName; + } + +} \ No newline at end of file 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 82c58a4..09465ea 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 @@ -30,11 +30,11 @@ public class Order extends BaseEntity { private Long storeId; - private Long orderPrice; + private long orderPrice; private LocalDateTime orderTime; - private Long usedPoint; + private long usedPoint; @Enumerated(EnumType.STRING) private OrderStatus orderStatus; @@ -46,32 +46,11 @@ public class Order extends BaseEntity { @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) private List orderItems = new ArrayList<>(); - public static Order of(Long userId, Long userCouponId, Long storeId, Long orderPrice, - Transaction transaction, OrderItem... orderItems) { + public static Order of(Long userId, Long userCouponId, Long storeId, OrderItem orderItem) { Order order = new Order(); order.userId = userId; order.userCouponId = userCouponId; order.storeId = storeId; - order.orderPrice = orderPrice; - - order.setTransaction(transaction); - for (OrderItem orderItem : orderItems) { - order.addOrderItem(orderItem); - } - - order.usedPoint = 0L; - order.orderStatus = OrderStatus.PLACED; - order.orderTime = LocalDateTime.now(); - return order; - } - - public static Order of(Long userId, Long userCouponId, Long storeId, Long orderPrice, - OrderItem orderItem) { - Order order = new Order(); - order.userId = userId; - order.userCouponId = userCouponId; - order.storeId = storeId; - order.orderPrice = orderPrice; order.addOrderItem(orderItem); @@ -81,14 +60,25 @@ public class Order extends BaseEntity { return order; } - public void setTransaction(Transaction transaction) { - this.transaction = transaction; - transaction.setOrder(this); + public static Order of(Long userId, Long userCouponId, Long storeId, List orderItems) { + Order order = new Order(); + order.userId = userId; + order.userCouponId = userCouponId; + order.storeId = storeId; + + for (OrderItem item : orderItems) { + order.addOrderItem(item); + } + + order.usedPoint = 0L; + order.orderStatus = OrderStatus.PENDING; + order.orderTime = LocalDateTime.now(); + return order; } public Order addOrderItem(OrderItem orderItem) { this.orderItems.add(orderItem); - this.orderPrice += (orderItem.getPrice()*orderItem.getCount()); + this.orderPrice += orderItem.getTotalPrice(); orderItem.setOrder(this); return this; } @@ -98,16 +88,19 @@ public class Order extends BaseEntity { return this; } - public void placed() { - this.orderStatus = OrderStatus.PLACED; - } - public void order() { this.orderStatus = OrderStatus.ORDER; } - public void reject() { - this.orderStatus = OrderStatus.REJECT; + /** + * 전체 주문 가격 조회 + */ + public int getTotalPrice() { + int totalPrice = 0; + for (OrderItem orderItem : orderItems) { + totalPrice += orderItem.getTotalPrice(); + } + return totalPrice; } public void fail() { 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 e308431..3a913db 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 @@ -44,7 +44,7 @@ public class OrderRepositoryCustom { List orders = queryFactory .selectFrom(order) - .join(order.transaction).fetchJoin() + .leftJoin(order.transaction) .where( orderIdLt(condition.getLastOrderId()), order.orderTime.between(start, end), @@ -75,7 +75,7 @@ public class OrderRepositoryCustom { Long count = queryFactory .select(order.countDistinct()) .from(order) - .innerJoin(order.transaction) + .leftJoin(order.transaction) .where( order.orderTime.between(search.getStartDateTime(), search.getEndDateTime()), order.storeId.eq(storeId) @@ -85,7 +85,7 @@ public class OrderRepositoryCustom { // 데이터 가져오기 List orders = queryFactory .selectFrom(order) - .join(order.transaction).fetchJoin() + .leftJoin(order.transaction).fetchJoin() .where( order.orderTime.between(search.getStartDateTime(), search.getEndDateTime()), order.storeId.eq(storeId) @@ -103,7 +103,7 @@ public class OrderRepositoryCustom { public SliceImpl findOrderHistory(Pageable pageable, Long userId) { List contents = queryFactory .selectFrom(order) - .join(order.transaction).fetchJoin() + .leftJoin(order.transaction).fetchJoin() .where( order.userId.eq(userId) ) 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 647f5ad..846671e 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 @@ -8,12 +8,11 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.SliceImpl; public interface OrderService { - OrderMainDto findOrderMain(OrderSearchCondition condition, Long storeId); - Page findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long storeId); - SliceImpl findOrderHistory(Pageable pageable, Long userId); + OrderMainDto findOrderMain(OrderSearchCondition condition, Long userId); + Page findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long userId); + SliceImpl findOrderHistory(Pageable pageable, Long userId); void addItemToBasket(OrderItemDto orderItemDto,Long storeId, Long userId); FetchOrderDto fetchOrder(Long userId); void saveOrder(Long userId); - void modifyOrder(Long userId, OrderStatus orderStatus); } 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 0c15888..5ba1aa3 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 @@ -9,6 +9,12 @@ 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.orderItemOption.entity.OrderItemOption; +import com.justpickup.orderservice.global.client.store.GetItemsResponse; +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.user.GetCustomerResponse; +import com.justpickup.orderservice.global.client.user.UserClient; import com.justpickup.orderservice.global.client.store.GetItemResponse; import com.justpickup.orderservice.global.client.store.GetStoreReseponse; import com.justpickup.orderservice.global.client.store.StoreClient; @@ -22,15 +28,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import java.util.*; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; @Service @RequiredArgsConstructor @@ -40,47 +43,148 @@ public class OrderServiceImpl implements OrderService { private final OrderRepository orderRepository; private final OrderRepositoryCustom orderRepositoryCustom; - + private final OrderSender orderSender; private final StoreClient storeClient; - + private final UserClient userClient; + @Override - public OrderMainDto findOrderMain(OrderSearchCondition condition, Long storeId) { + public OrderMainDto findOrderMain(OrderSearchCondition condition, Long userId) { + // storeId 가져오기 + StoreByUserIdResponse storeResponse = storeClient.getStoreByUserId(userId).getData(); + // 주문 가져오기 - OrderMainResult orderMainResult = orderRepositoryCustom.findOrderMain(condition, storeId); + OrderMainResult orderMainResult = orderRepositoryCustom.findOrderMain(condition, storeResponse.getId()); - // 사용자명 및 아이템 이름 가져오기 -// getUserNameAndItemName(orderDtoList); + // 사용자 고유번호 및 아이템 고유번호 필터링 + Set userIds = new HashSet<>(); + Set itemIds = new HashSet<>(); - return OrderMainDto.of(orderMainResult.getOrders(), orderMainResult.isHasNext()); + OrderMainDto returnDto = OrderMainDto.of(orderMainResult.getOrders(), orderMainResult.isHasNext()); + List orders = returnDto.getOrders(); + + // userId 및 itemId Set에 추가 + for (OrderMainDto._Order order : orders) { + userIds.add(order.getUserId()); + for (OrderMainDto._OrderItem orderItem : order.getOrderItems()) { + itemIds.add(orderItem.getItemId()); + } + } + + // item name 가져오기 + Map itemNameMap = getItemNameMap(itemIds); + + // user name 가져오기 + Map userNameMap = getUserNameMap(userIds); + + // 해당 ID에 맞게 이름 설정해주기 + for (OrderMainDto._Order order : orders) { + String userName = userNameMap.get(order.getUserId()); + order.changeUserName(userName); + for (OrderMainDto._OrderItem orderItem : order.getOrderItems()) { + String itemName = itemNameMap.get(orderItem.getItemId()); + orderItem.changeItemName(itemName); + } + } + + return returnDto; + } + + private Map getUserNameMap(Iterable userIds) { + List userResponses = userClient.getCustomers(userIds).getData(); + return userResponses.stream() + .collect( + toMap(GetCustomerResponse::getUserId, GetCustomerResponse::getUserName) + ); + } + + private Map getItemNameMap(Iterable itemIds) { + List itemResponses = storeClient.getItems(itemIds).getData(); + return itemResponses.stream() + .collect( + toMap(GetItemsResponse::getId, GetItemsResponse::getName) + ); } @Override - public Page findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long storeId) { - Page orderPage = orderRepositoryCustom.findPrevOrderMain(search, pageable, storeId); + public Page findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long userId) { + StoreByUserIdResponse store = storeClient.getStoreByUserId(userId).getData(); - List orderDtoList = orderPage.getContent() + Page orderPage = orderRepositoryCustom.findPrevOrderMain(search, pageable, store.getId()); + + List prevOrderDtoList = orderPage.getContent() .stream() - .map(OrderDto::createFullField) + .map(PrevOrderDto::of) .collect(toList()); // 사용자명 및 아이템 이름 가져오기 -// getUserNameAndItemName(orderDtoList); + Set userIds = new HashSet<>(); + Set itemIds = new HashSet<>(); - return PageableExecutionUtils.getPage(orderDtoList, pageable, orderPage::getTotalElements); + for (PrevOrderDto prevOrderDto : prevOrderDtoList) { + userIds.add(prevOrderDto.getUserId()); + for (PrevOrderDto._PrevOrderItem orderItem : prevOrderDto.getOrderItems()) { + itemIds.add(orderItem.getItemId()); + } + } + + // item name 가져오기 + Map itemNameMap = getItemNameMap(itemIds); + + // user name 가져오기 + Map userNameMap = getUserNameMap(userIds); + + for (PrevOrderDto prevOrderDto : prevOrderDtoList) { + String userName = userNameMap.get(prevOrderDto.getUserId()); + prevOrderDto.changeUserName(userName); + for (PrevOrderDto._PrevOrderItem orderItem : prevOrderDto.getOrderItems()) { + String itemName = itemNameMap.get(orderItem.getItemId()); + orderItem.changeName(itemName); + } + } + + return PageableExecutionUtils.getPage(prevOrderDtoList, pageable, orderPage::getTotalElements); } @Override - public SliceImpl findOrderHistory(Pageable pageable, Long userId) { + public SliceImpl findOrderHistory(Pageable pageable, Long userId) { SliceImpl orderHistory = orderRepositoryCustom.findOrderHistory(pageable, userId); - List contents = orderHistory.getContent() + List orderHistoryDtoList = orderHistory.getContent() .stream() - .map(OrderDto::createFullField) + .map(OrderHistoryDto::of) .collect(toList()); - // TODO: 2022/03/07 Feign Client 통신 + Set storeIds = new HashSet<>(); + Set itemIds = new HashSet<>(); + for (OrderHistoryDto orderHistoryDto : orderHistoryDtoList) { + storeIds.add(orderHistoryDto.getStoreId()); + for (OrderHistoryDto._OrderHistoryItem orderItem : orderHistoryDto.getOrderItems()) { + itemIds.add(orderItem.getItemId()); + } + } - return new SliceImpl<>(contents, pageable, orderHistory.hasNext()); + Map storeNameMap = this.getStoreNameMap(storeIds); + Map itemNameMap = this.getItemNameMap(itemIds); + + for (OrderHistoryDto orderHistoryDto : orderHistoryDtoList) { + String userName = storeNameMap.get(orderHistoryDto.getStoreId()); + orderHistoryDto.changeStoreName(userName); + for (OrderHistoryDto._OrderHistoryItem orderItem : orderHistoryDto.getOrderItems()) { + String itemName = itemNameMap.get(orderItem.getItemId()); + orderItem.changeItemName(itemName); + } + } + + return new SliceImpl<>(orderHistoryDtoList, pageable, orderHistory.hasNext()); + } + + private Map getStoreNameMap(Set storeIds) { + List storeResponses = storeClient.getStoreAllById(storeIds).getData(); + Map storeMap = storeResponses.stream() + .collect( + toMap(GetStoreResponse::getId, GetStoreResponse::getName) + ); + return storeMap; } @Override @@ -107,7 +211,7 @@ public class OrderServiceImpl implements OrderService { .getStoreId().equals(storeId)) throw new OrderException("장바구니에 여러 카페의 메뉴를 담을수 없습니다."); }else{ - orderRepository.save(Order.of(userId,userCouponId,storeId,0L,orderItem)); + orderRepository.save(Order.of(userId,userCouponId,storeId,orderItem)); } } 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 07f68d5..64eeb1e 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 @@ -4,6 +4,7 @@ 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.dto.Result; +import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; @@ -34,7 +35,7 @@ public class OrderController { return ResponseEntity.ok(Result.createSuccessResult(null)); } - @Data @NoArgsConstructor + @Data @NoArgsConstructor @AllArgsConstructor static class PatchOrderRequest { private OrderStatus orderStatus; } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiController.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiController.java index 539a553..a915d27 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiController.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiController.java @@ -1,7 +1,7 @@ package com.justpickup.orderservice.domain.order.web; import com.justpickup.orderservice.domain.order.dto.FetchOrderDto; -import com.justpickup.orderservice.domain.order.dto.OrderDto; +import com.justpickup.orderservice.domain.order.dto.OrderHistoryDto; import com.justpickup.orderservice.domain.order.entity.OrderStatus; import com.justpickup.orderservice.domain.order.service.OrderService; import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; @@ -36,7 +36,7 @@ public class OrderCustomerApiController { @PageableDefault(page = 0, size = 3) Pageable pageable) { Long userId = Long.parseLong(userHeader); - SliceImpl orderHistory = orderService.findOrderHistory(pageable, userId); + SliceImpl orderHistory = orderService.findOrderHistory(pageable, userId); OrderHistoryResponse orderHistoryResponse = new OrderHistoryResponse(orderHistory.getContent(), orderHistory.hasNext()); @@ -47,45 +47,45 @@ public class OrderCustomerApiController { @Data @NoArgsConstructor static class OrderHistoryResponse { - private List<_Order> orders; + private List<_OrderResponse> orders; private boolean hasNext; - public OrderHistoryResponse(List orders, boolean hasNext) { - this.orders = orders.stream().map(_Order::new).collect(Collectors.toList()); + public OrderHistoryResponse(List orders, boolean hasNext) { + this.orders = orders.stream().map(_OrderResponse::new).collect(Collectors.toList()); this.hasNext = hasNext; } @Data - static class _Order { + static class _OrderResponse { private Long orderId; private String orderTime; private OrderStatus orderStatus; private String storeName; private Long orderPrice; - private List<_OrderItem> orderItems; + private List<_OrderItemResponse> orderItems; - public _Order(OrderDto orderDto) { - this.orderId = orderDto.getId(); - this.orderTime = orderDto.getOrderTime() + public _OrderResponse(OrderHistoryDto orderHistoryDto) { + this.orderId = orderHistoryDto.getId(); + this.orderTime = orderHistoryDto.getOrderTime() .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); - this.orderStatus = orderDto.getOrderStatus(); - this.storeName = orderDto.getStoreId().toString(); - this.orderPrice = orderDto.getOrderPrice(); - this.orderItems = orderDto.getOrderItemDtoList() + this.orderStatus = orderHistoryDto.getOrderStatus(); + this.storeName = orderHistoryDto.getStoreName(); + this.orderPrice = orderHistoryDto.getPrice(); + this.orderItems = orderHistoryDto.getOrderItems() .stream() - .map(_OrderItem::new) + .map(_OrderItemResponse::new) .collect(Collectors.toList()); } } @Data - static class _OrderItem { + static class _OrderItemResponse { private Long orderItemId; private String orderItemName; - public _OrderItem(OrderItemDto orderItemDto) { - this.orderItemId = orderItemDto.getItemId(); - this.orderItemName = orderItemDto.getItemId().toString(); + public _OrderItemResponse(OrderHistoryDto._OrderHistoryItem orderHistoryItem) { + this.orderItemId = orderHistoryItem.getItemId(); + this.orderItemName = orderHistoryItem.getItemName(); } } } @@ -131,6 +131,4 @@ public class OrderCustomerApiController { return ResponseEntity.status(HttpStatus.CREATED).body(Result.createSuccessResult(null)); } - - } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderOwnerApiController.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderOwnerApiController.java index 91d32c1..04cccde 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderOwnerApiController.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderOwnerApiController.java @@ -1,13 +1,12 @@ package com.justpickup.orderservice.domain.order.web; -import com.justpickup.orderservice.domain.order.dto.OrderDto; import com.justpickup.orderservice.domain.order.dto.OrderMainDto; import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition; +import com.justpickup.orderservice.domain.order.dto.PrevOrderDto; import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch; import com.justpickup.orderservice.domain.order.entity.OrderStatus; import com.justpickup.orderservice.domain.order.service.OrderService; import com.justpickup.orderservice.domain.order.validator.PrevOrderSearchValidator; -import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; import com.justpickup.orderservice.global.dto.Result; import lombok.AllArgsConstructor; import lombok.Data; @@ -22,6 +21,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -41,12 +41,11 @@ public class OrderOwnerApiController { private final PrevOrderSearchValidator prevOrderSearchValidator; @GetMapping("/order-main") - public ResponseEntity orderMain(@Valid OrderSearchCondition condition) { - // TODO: 2022/03/10 Feign client storeId 가져오기 구현 필요 - Long userId = 1L; - Long storeId = 1L; + public ResponseEntity orderMain(@Valid OrderSearchCondition condition, + @RequestHeader(value="user-id") String userHeader) { + Long userId = Long.valueOf(userHeader); - OrderMainDto orderMainDto = orderService.findOrderMain(condition, storeId); + OrderMainDto orderMainDto = orderService.findOrderMain(condition, userId); OrderMainResponse orderMainResponse = new OrderMainResponse(orderMainDto); @@ -101,6 +100,7 @@ public class OrderOwnerApiController { @GetMapping("/prev-order") public ResponseEntity findPrevOrder(@Valid PrevOrderSearch prevOrderSearch, @PageableDefault(page = 0, size = 10) Pageable pageable, + @RequestHeader(value="user-id") String userHeader, BindingResult bindingResult) throws BindException { // validation if (bindingResult.hasErrors()) throw new BindException(bindingResult); @@ -108,7 +108,8 @@ public class OrderOwnerApiController { if (bindingResult.hasErrors()) throw new BindException(bindingResult); // get data - Page prevOrderMain = orderService.findPrevOrderMain(prevOrderSearch, pageable, 1L); + Long userId = Long.valueOf(userHeader); + Page prevOrderMain = orderService.findPrevOrderMain(prevOrderSearch, pageable, userId); // format data ResponsePrevOrder responsePrevOrder = @@ -118,42 +119,42 @@ public class OrderOwnerApiController { @Data @AllArgsConstructor @NoArgsConstructor static class ResponsePrevOrder { - private List orders; + private List<_Order> orders; private Page page; - public ResponsePrevOrder(List orderDtoList, int startPage, int totalPage) { - orders = orderDtoList.stream().map(OrderVo::new).collect(toList()); + public ResponsePrevOrder(List orderDtoList, int startPage, int totalPage) { + orders = orderDtoList.stream().map(_Order::new).collect(toList()); page = new Page(startPage, totalPage); } @Data - static class OrderVo { + static class _Order { private Long orderId; private OrderStatus orderStatus; private String orderTime; private Long orderPrice; private String userName; - private List orderItems; + private List<_OrderItem> orderItems; - public OrderVo(OrderDto orderDto) { - this.orderId = orderDto.getId(); - this.orderStatus = orderDto.getOrderStatus(); - this.orderTime = orderDto.getOrderTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - this.orderPrice = orderDto.getOrderPrice(); - this.userName = orderDto.getUserName(); - this.orderItems = orderDto.getOrderItemDtoList() - .stream().map(OrderItemVo::new).collect(toList()); + public _Order(PrevOrderDto prevOrderDto) { + this.orderId = prevOrderDto.getId(); + this.orderStatus = prevOrderDto.getOrderStatus(); + this.orderTime = prevOrderDto.getOrderTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + this.orderPrice = prevOrderDto.getOrderPrice(); + this.userName = prevOrderDto.getUserName(); + this.orderItems = prevOrderDto.getOrderItems() + .stream().map(_OrderItem::new).collect(toList()); } } @Data - static class OrderItemVo { + static class _OrderItem { private Long orderItemId; private String orderItemName; - public OrderItemVo(OrderItemDto orderItemDto) { + public _OrderItem(PrevOrderDto._PrevOrderItem orderItemDto) { this.orderItemId = orderItemDto.getId(); - this.orderItemName = orderItemDto.getItemName(); + this.orderItemName = orderItemDto.getName(); } } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/orderItem/entity/OrderItem.java b/order-service/src/main/java/com/justpickup/orderservice/domain/orderItem/entity/OrderItem.java index d39bd3a..379a093 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/orderItem/entity/OrderItem.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/orderItem/entity/OrderItem.java @@ -1,7 +1,6 @@ package com.justpickup.orderservice.domain.orderItem.entity; import com.justpickup.orderservice.domain.order.entity.Order; -import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; import com.justpickup.orderservice.domain.orderItemOption.entity.OrderItemOption; import com.justpickup.orderservice.global.entity.BaseEntity; import lombok.AccessLevel; @@ -65,4 +64,11 @@ public class OrderItem extends BaseEntity { } return orderItem; } + + /** + * 주문상품 전체 가격 조회 + */ + public long getTotalPrice() { + return price * count; + } } diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/SqlCommandLineRunner.java b/order-service/src/main/java/com/justpickup/orderservice/global/SqlCommandLineRunner.java new file mode 100644 index 0000000..bfd9acd --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/global/SqlCommandLineRunner.java @@ -0,0 +1,88 @@ +package com.justpickup.orderservice.global; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.justpickup.orderservice.domain.order.entity.Order; +import com.justpickup.orderservice.domain.order.entity.OrderStatus; +import com.justpickup.orderservice.domain.order.repository.OrderRepository; +import com.justpickup.orderservice.domain.orderItem.entity.OrderItem; +import com.justpickup.orderservice.domain.orderItemOption.entity.OrderItemOption; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +@RequiredArgsConstructor +public class SqlCommandLineRunner implements CommandLineRunner { + + private final OrderRepository orderRepository; + private final ObjectMapper objectMapper; + + String storeJson = "[{\"id\":1,\"name\":\"커피온리 마포역점\",\"items\":[{\"id\":40,\"name\":\"아메리카노\",\"price\":1500,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":40,\"name\":\"아메리카노\",\"price\":1500,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":45,\"name\":\"카페라떼\",\"price\":2000,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":45,\"name\":\"카페라떼\",\"price\":2000,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":46,\"name\":\"카페모카\",\"price\":3900,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":46,\"name\":\"카페모카\",\"price\":3900,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":47,\"name\":\"콜드브루\",\"price\":2500,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"}]},{\"id\":47,\"name\":\"콜드브루\",\"price\":2500,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"}]},{\"id\":48,\"name\":\"녹차라떼\",\"price\":3000,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":48,\"name\":\"녹차라떼\",\"price\":3000,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":42,\"name\":\"딸기라떼\",\"price\":3000,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":42,\"name\":\"딸기라떼\",\"price\":3000,\"itemOptions\":[{\"id\":41,\"name\":\"ICE\"},{\"id\":43,\"name\":\"HOT\"}]},{\"id\":49,\"name\":\"녹차\",\"price\":3000,\"itemOptions\":[{\"id\":43,\"name\":\"HOT\"}]},{\"id\":49,\"name\":\"녹차\",\"price\":3000,\"itemOptions\":[{\"id\":43,\"name\":\"HOT\"}]},{\"id\":44,\"name\":\"히비스커스 티\",\"price\":3000,\"itemOptions\":[{\"id\":43,\"name\":\"HOT\"}]},{\"id\":44,\"name\":\"히비스커스 티\",\"price\":3000,\"itemOptions\":[{\"id\":43,\"name\":\"HOT\"}]}]},{\"id\":3,\"name\":\"만랩커피 마포점\",\"items\":[{\"id\":53,\"name\":\"아메리카노\",\"price\":1500,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":53,\"name\":\"아메리카노\",\"price\":1500,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":58,\"name\":\"카페라떼\",\"price\":2000,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":58,\"name\":\"카페라떼\",\"price\":2000,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":59,\"name\":\"카페모카\",\"price\":3900,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":59,\"name\":\"카페모카\",\"price\":3900,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":60,\"name\":\"콜드브루\",\"price\":2500,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"}]},{\"id\":60,\"name\":\"콜드브루\",\"price\":2500,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"}]},{\"id\":61,\"name\":\"녹차라떼\",\"price\":3000,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":61,\"name\":\"녹차라떼\",\"price\":3000,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":55,\"name\":\"딸기라떼\",\"price\":3000,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":55,\"name\":\"딸기라떼\",\"price\":3000,\"itemOptions\":[{\"id\":54,\"name\":\"ICE\"},{\"id\":56,\"name\":\"HOT\"}]},{\"id\":62,\"name\":\"녹차\",\"price\":3000,\"itemOptions\":[{\"id\":56,\"name\":\"HOT\"}]},{\"id\":62,\"name\":\"녹차\",\"price\":3000,\"itemOptions\":[{\"id\":56,\"name\":\"HOT\"}]},{\"id\":57,\"name\":\"히비스커스 티\",\"price\":3000,\"itemOptions\":[{\"id\":56,\"name\":\"HOT\"}]},{\"id\":57,\"name\":\"히비스커스 티\",\"price\":3000,\"itemOptions\":[{\"id\":56,\"name\":\"HOT\"}]}]},{\"id\":5,\"name\":\"이디야커피 마포오벨리스크점\",\"items\":[{\"id\":66,\"name\":\"아메리카노\",\"price\":1500,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":66,\"name\":\"아메리카노\",\"price\":1500,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":71,\"name\":\"카페라떼\",\"price\":2000,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":71,\"name\":\"카페라떼\",\"price\":2000,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":72,\"name\":\"카페모카\",\"price\":3900,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":72,\"name\":\"카페모카\",\"price\":3900,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":73,\"name\":\"콜드브루\",\"price\":2500,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"}]},{\"id\":73,\"name\":\"콜드브루\",\"price\":2500,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"}]},{\"id\":74,\"name\":\"녹차라떼\",\"price\":3000,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":74,\"name\":\"녹차라떼\",\"price\":3000,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":68,\"name\":\"딸기라떼\",\"price\":3000,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":68,\"name\":\"딸기라떼\",\"price\":3000,\"itemOptions\":[{\"id\":67,\"name\":\"ICE\"},{\"id\":69,\"name\":\"HOT\"}]},{\"id\":75,\"name\":\"녹차\",\"price\":3000,\"itemOptions\":[{\"id\":69,\"name\":\"HOT\"}]},{\"id\":75,\"name\":\"녹차\",\"price\":3000,\"itemOptions\":[{\"id\":69,\"name\":\"HOT\"}]},{\"id\":70,\"name\":\"히비스커스 티\",\"price\":3000,\"itemOptions\":[{\"id\":69,\"name\":\"HOT\"}]},{\"id\":70,\"name\":\"히비스커스 티\",\"price\":3000,\"itemOptions\":[{\"id\":69,\"name\":\"HOT\"}]}]},{\"id\":7,\"name\":\"이디야커피 대림역점\",\"items\":[{\"id\":79,\"name\":\"아메리카노\",\"price\":1500,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":79,\"name\":\"아메리카노\",\"price\":1500,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":84,\"name\":\"카페라떼\",\"price\":2000,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":84,\"name\":\"카페라떼\",\"price\":2000,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":85,\"name\":\"카페모카\",\"price\":3900,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":85,\"name\":\"카페모카\",\"price\":3900,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":86,\"name\":\"콜드브루\",\"price\":2500,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"}]},{\"id\":86,\"name\":\"콜드브루\",\"price\":2500,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"}]},{\"id\":87,\"name\":\"녹차라떼\",\"price\":3000,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":87,\"name\":\"녹차라떼\",\"price\":3000,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":81,\"name\":\"딸기라떼\",\"price\":3000,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":81,\"name\":\"딸기라떼\",\"price\":3000,\"itemOptions\":[{\"id\":80,\"name\":\"ICE\"},{\"id\":82,\"name\":\"HOT\"}]},{\"id\":88,\"name\":\"녹차\",\"price\":3000,\"itemOptions\":[{\"id\":82,\"name\":\"HOT\"}]},{\"id\":88,\"name\":\"녹차\",\"price\":3000,\"itemOptions\":[{\"id\":82,\"name\":\"HOT\"}]},{\"id\":83,\"name\":\"히비스커스 티\",\"price\":3000,\"itemOptions\":[{\"id\":82,\"name\":\"HOT\"}]},{\"id\":83,\"name\":\"히비스커스 티\",\"price\":3000,\"itemOptions\":[{\"id\":82,\"name\":\"HOT\"}]}]}]"; + + @Data + static class _Store { + private Long id; + private String name; + private List<_Item> items = new ArrayList<>(); + + @NoArgsConstructor + @Data + static class _Item { + private Long id; + private String name; + private Long price; + List<_ItemOption> itemOptions = new ArrayList<>(); + } + + @NoArgsConstructor @Data + static class _ItemOption { + private Long id; + private String name; + } + } + + @Override + public void run(String... args) throws Exception { + Long userId = 2L; + Long userCouponId = null; + + for (int i = 0; i <= 100; i++) { + if (i % 2 == 0) userId = 2L; + else userId = 3L; + + List orders = new ArrayList<>(); + _Store[] stores = objectMapper.readValue(storeJson, _Store[].class); + for (_Store store : stores) { + Long storeId = store.getId(); + + List orderItems = new ArrayList<>(); + for (_Store._Item item : store.getItems()) { + Long itemId = item.getId(); + Long price = item.getPrice(); + + List orderItemOptions = new ArrayList<>(); + for (_Store._ItemOption itemOption : item.getItemOptions()) { + Long itemOptionId = itemOption.getId(); + + OrderItemOption of = OrderItemOption.of(itemOptionId); + orderItemOptions.add(of); + } + OrderItem orderItem = OrderItem.of(itemId, price, 2L, orderItemOptions); + orderItems.add(orderItem); + } + + Order order = Order.of(userId, userCouponId, storeId, orderItems); + if (i % 2 == 0) order.setOrderStatus(OrderStatus.ORDER); + else order.setOrderStatus(OrderStatus.REJECT); + orders.add(order); + } + + orderRepository.saveAll(orders); + } + } +} diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemsResponse.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemsResponse.java new file mode 100644 index 0000000..1702a17 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemsResponse.java @@ -0,0 +1,9 @@ +package com.justpickup.orderservice.global.client.store; + +import lombok.Data; + +@Data +public class GetItemsResponse { + private Long id; + private String name; +} diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetStoreResponse.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetStoreResponse.java new file mode 100644 index 0000000..7510bd7 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetStoreResponse.java @@ -0,0 +1,10 @@ +package com.justpickup.orderservice.global.client.store; + +import lombok.Data; + +@Data +public class GetStoreResponse { + private Long id; + private String name; + private String phoneNumber; +} diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/StoreByUserIdResponse.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/StoreByUserIdResponse.java new file mode 100644 index 0000000..e0a8c86 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/StoreByUserIdResponse.java @@ -0,0 +1,9 @@ +package com.justpickup.orderservice.global.client.store; + +import lombok.Data; + +@Data +public class StoreByUserIdResponse { + private Long id; + 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 cbcb1ea..8581c8e 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 @@ -4,12 +4,25 @@ import com.justpickup.orderservice.global.dto.Result; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestHeader; import java.util.List; -@FeignClient("store-service") +@FeignClient("STORE-SERVICE") public interface StoreClient { + @GetMapping("/item/{itemId}") + Result getItem(@PathVariable("itemId") Long itemId); + + @GetMapping("/items/{itemIds}") + Result> getItems(@PathVariable("itemIds") Iterable itemIds); + + @GetMapping("/api/owner/store/") + Result getStoreByUserId(@RequestHeader(value="user-id") Long userId); + + @GetMapping("/stores/{storeId}") + Result> getStoreAllById(@PathVariable("storeId") Iterable storeIds); + @GetMapping("/store/{storeId}") Result getStore(@PathVariable(value = "storeId") String storeId); diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/user/UserClient.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/user/UserClient.java index 4a81250..350df7f 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/global/client/user/UserClient.java +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/user/UserClient.java @@ -5,9 +5,14 @@ import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -@FeignClient(name = "USER-SERVICE", url = "127.0.0.1:8001/user-service") +import java.util.List; + +@FeignClient("USER-SERVICE") public interface UserClient { @GetMapping("/customer/{userId}") - Result getUser(@PathVariable("userId") Long userId); + Result getCustomerById(@PathVariable("userId") Long userId); + + @GetMapping("/customers/{userIds}") + Result> getCustomers(@PathVariable("userIds") Iterable userIds); } diff --git a/order-service/src/main/resources/static/docs/api-docs.html b/order-service/src/main/resources/static/docs/api-docs.html deleted file mode 100644 index 148f1af..0000000 --- a/order-service/src/main/resources/static/docs/api-docs.html +++ /dev/null @@ -1,836 +0,0 @@ - - - - - - - -개요 - - - - - - -
-
-

HTTP 동사

-
-
-

본 REST API에서 사용하는 HTTP 동사(verbs)는 가능한한 표준 HTTP와 REST 규약을 따릅니다.

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
동사용례

GET

리소스를 가져올 때 사용

POST

새 리소스를 만들 때 사용

PUT

기존 리소스를 수정할 때 사용

PATCH

기존 리소스의 일부를 수정할 때 사용

DELETE

기존 리소스를 삭제할 떄 사용

-
-
-
-

HTTP 상태 코드

-
-
-

본 REST API에서 사용하는 HTTP 상태 코드는 가능한 표준 HTTP와 REST 규약을 따릅니다.

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
상태 코드용례

200 OK

요청을 성공적으로 처리함

201 Created

새 리소스를 성공적으로 생성함. 응답의 Location 헤더에 해당 리소스의 URI가 담겨있다.

204 No Content

기존 리소스를 성공적으로 수정함.

400 Bad Request

잘못된 요청을 보낸 경우. 응답 본문에 더 오류에 대한 정보가 담겨있다.

404 Not Found

요청한 리소스가 없음.

409 Conflict

클라이언트의 요청이 서버의 상태와 충돌이 발생한 경우.

-
-
-
-

snippets 작성 컨벤션

-
-
-

domain-httpRequestCode-etc

-
-
-
-
-

주문

-
-
-

점주 서비스 - 주문 페이지

-
-
    -
  • -

    페이지 offset : 6

    -
  • -
-
-
-

Curl request

-
-
-
$ curl 'http://127.0.0.1:8001/orderMain?orderDate=2022-02-03&lastOrderId=7' -i -X GET
-
-
-
-
-

HTTP request

-
-
-
GET /orderMain?orderDate=2022-02-03&lastOrderId=7 HTTP/1.1
-Host: 127.0.0.1:8001
-
-
-
-
-

HTTP response

-
-
-
HTTP/1.1 200 OK
-Content-Type: application/json
-Content-Length: 769
-
-{
-  "code" : "SUCCESS",
-  "message" : "",
-  "data" : [ {
-    "orderId" : 1,
-    "userId" : 1,
-    "userName" : "닉네임",
-    "orderItemResponses" : [ {
-      "orderItemId" : 100,
-      "itemId" : 100,
-      "itemName" : "아이템1"
-    }, {
-      "orderItemId" : 101,
-      "itemId" : 101,
-      "itemName" : "아이템2"
-    } ],
-    "orderStatus" : "PLACED",
-    "orderTime" : "2022-02-03 14:00:00"
-  }, {
-    "orderId" : 2,
-    "userId" : 1,
-    "userName" : "닉네임",
-    "orderItemResponses" : [ {
-      "orderItemId" : 102,
-      "itemId" : 102,
-      "itemName" : "아이템3"
-    }, {
-      "orderItemId" : 103,
-      "itemId" : 103,
-      "itemName" : "아이템2"
-    } ],
-    "orderStatus" : "CANCELED",
-    "orderTime" : "2022-02-03 15:00:00"
-  } ]
-}
-
-
-
-
-

Request parameters

- ---- - - - - - - - - - - - - - - - - -
ParameterDescription

orderDate

주문 날짜 YYYY-MM-DD

lastOrderId

페이지의 마지막 주문 고유 번호

-
-
-

Response fields

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PathTypeDescription

code

String

결과 코드 SUCCESS/ERROR

message

String

메시지

data[*].orderId

Number

주문 고유 번호

data[*].userId

Number

고객 고유 번호

data[*].userName

String

고객 이름

data[*].orderItemResponses[*].orderItemId

Number

장바구니 고유번호

data[*].orderItemResponses[*].itemId

Number

상품 고유번호

data[*].orderItemResponses[*].itemName

String

상품 이름

data[*].orderStatus

String

주문 상태

data[*].orderTime

String

주문 시간

-
-
-
-

점주 서비스 - 주문 페이지 (잘못된 파라미터 형식)

-
-

Curl request

-
-
-
$ curl 'http://127.0.0.1:8001/orderMain?orderDate=20220203&lastOrderId=7' -i -X GET
-
-
-
-
-

HTTP request

-
-
-
GET /orderMain?orderDate=20220203&lastOrderId=7 HTTP/1.1
-Host: 127.0.0.1:8001
-
-
-
-
-

HTTP response

-
-
-
HTTP/1.1 400 Bad Request
-Content-Type: application/json
-Content-Length: 160
-
-{
-  "code" : "ERROR",
-  "message" : "[orderDate](은)는 YYYY-MM-DD 형식에 맞게 작성되지 않았습니다. 입력된 값: [20220203]",
-  "data" : null
-}
-
-
-
-
-

Request parameters

- ---- - - - - - - - - - - - - - - - - -
ParameterDescription

orderDate

주문 날짜 YYYY-MM-DD

lastOrderId

페이지의 마지막 주문 고유 번호

-
-
-

Response fields

- ----- - - - - - - - - - - - - - - - - - - - - - - - - -
PathTypeDescription

code

String

결과 코드 SUCCESS/ERROR

message

String

메시지

data

Null

데이터

-
-
-
-
-
- - - - - - \ No newline at end of file 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 a5a68df..b17c477 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 @@ -42,9 +42,6 @@ class OrderControllerTest { @MockBean OrderService orderService; - @MockBean - OrderRepository orderRepository; - @Test @DisplayName("[PATCH] 주문 수정") public void patchOrder() throws Exception { diff --git a/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java b/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java index 6105adc..8c9dbf8 100644 --- a/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java +++ b/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.justpickup.orderservice.config.TestConfig; import com.justpickup.orderservice.domain.order.dto.FetchOrderDto; import com.justpickup.orderservice.domain.order.dto.OrderDto; +import com.justpickup.orderservice.domain.order.dto.OrderHistoryDto; import com.justpickup.orderservice.domain.order.entity.OrderStatus; import com.justpickup.orderservice.domain.order.repository.OrderRepository; import com.justpickup.orderservice.domain.order.service.OrderService; @@ -57,9 +58,6 @@ class OrderCustomerApiControllerTest { @MockBean OrderService orderService; - @MockBean - OrderRepository orderRepository; - private final String url = "/api/customer/order"; @Test @@ -103,21 +101,25 @@ class OrderCustomerApiControllerTest { ; } - private SliceImpl getWillReturnOrderHistory(Pageable pageable) { + private SliceImpl getWillReturnOrderHistory(Pageable pageable) { - List contents = new ArrayList<>(); + List contents = new ArrayList<>(); for (long i = 1; i <= 3; i++) { - OrderItemDto orderItemDto_1 = OrderItemDto.builder().id(i * 10).itemId(i * 100).build(); - OrderItemDto orderItemDto_2 = OrderItemDto.builder().id((i + 1) * 20L).itemId((i + 1) *200L).build(); + OrderHistoryDto._OrderHistoryItem orderItemDto_1 = + OrderHistoryDto._OrderHistoryItem.builder() + .id(i * 10).itemId(i * 100).build(); + OrderHistoryDto._OrderHistoryItem orderItemDto_2 = + OrderHistoryDto._OrderHistoryItem.builder() + .id((i + 1) * 20L).itemId((i + 1) *200L).build(); int hour = 20; - OrderDto orderDto = OrderDto.builder() + OrderHistoryDto orderDto = OrderHistoryDto.builder() .id(i) .orderTime(LocalDateTime.of(2022, 3, 7, --hour, 0, 0)) .orderStatus(OrderStatus.PLACED) .storeId(i + 1000) - .orderPrice(i * 10_000) - .orderItemDtoList(List.of(orderItemDto_1, orderItemDto_2)) + .price(i * 10_000) + .orderItems(List.of(orderItemDto_1, orderItemDto_2)) .build(); contents.add(orderDto); diff --git a/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderOwnerApiControllerTest.java b/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderOwnerApiControllerTest.java index f1e8bb2..64192c6 100644 --- a/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderOwnerApiControllerTest.java +++ b/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderOwnerApiControllerTest.java @@ -2,12 +2,9 @@ package com.justpickup.orderservice.domain.order.web; import com.fasterxml.jackson.databind.ObjectMapper; import com.justpickup.orderservice.config.TestConfig; -import com.justpickup.orderservice.domain.order.dto.OrderDto; -import com.justpickup.orderservice.domain.order.dto.OrderMainDto; +import com.justpickup.orderservice.domain.order.dto.*; import com.justpickup.orderservice.domain.order.dto.OrderMainDto._Order; import com.justpickup.orderservice.domain.order.dto.OrderMainDto._OrderItem; -import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition; -import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch; import com.justpickup.orderservice.domain.order.entity.OrderStatus; import com.justpickup.orderservice.domain.order.repository.OrderRepository; import com.justpickup.orderservice.domain.order.service.OrderService; @@ -35,6 +32,8 @@ import java.util.List; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; @@ -62,9 +61,6 @@ class OrderOwnerApiControllerTest { @SpyBean PrevOrderSearchValidator prevOrderSearchValidator; - @MockBean - OrderRepository orderRepository; - private final String url = "/api/owner/order"; @Test @@ -83,6 +79,7 @@ class OrderOwnerApiControllerTest { // WHEN ResultActions actions = mockMvc.perform(get(url + "/order-main") + .header("user-id", "1") .param("orderDate", orderDate) .param("lastOrderId", String.valueOf(lastOrderId)) ); @@ -100,6 +97,9 @@ class OrderOwnerApiControllerTest { parameterWithName("orderDate").description("주문 날짜 YYYY-MM-DD"), parameterWithName("lastOrderId").optional().description("페이지의 마지막 주문 고유 번호") ), + requestHeaders( + headerWithName("user-id").description("유저 고유번호") + ), responseFields( fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), fieldWithPath("message").description("메시지"), @@ -145,6 +145,7 @@ class OrderOwnerApiControllerTest { // WHEN ResultActions actions = mockMvc.perform(get(url + "/order-main") + .header("user-id", "1") .param("orderDate", orderDate) .param("lastOrderId", String.valueOf(lastOrderId)) ); @@ -160,6 +161,9 @@ class OrderOwnerApiControllerTest { parameterWithName("orderDate").description("주문 날짜 YYYY-MM-DD"), parameterWithName("lastOrderId").optional().description("페이지의 마지막 주문 고유 번호") ), + requestHeaders( + headerWithName("user-id").description("유저 고유번호") + ), responseFields( fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), fieldWithPath("message").description("메시지"), @@ -170,44 +174,44 @@ class OrderOwnerApiControllerTest { ; } - private List getOrderMainDtoList() { - OrderItemDto orderItemDto_100 = OrderItemDto.builder() + private List getOrderMainDtoList() { + PrevOrderDto._PrevOrderItem orderItemDto_100 = PrevOrderDto._PrevOrderItem.builder() .id(100L) .itemId(100L) .build(); - orderItemDto_100.setItemName("아이템1"); - OrderItemDto orderItemDto_101 = OrderItemDto.builder() + orderItemDto_100.changeName("아이템1"); + PrevOrderDto._PrevOrderItem orderItemDto_101 = PrevOrderDto._PrevOrderItem.builder() .id(101L) .itemId(101L) .build(); - orderItemDto_101.setItemName("아이템2"); - OrderItemDto orderItemDto_102 = OrderItemDto.builder() + orderItemDto_101.changeName("아이템2"); + PrevOrderDto._PrevOrderItem orderItemDto_102 = PrevOrderDto._PrevOrderItem.builder() .id(102L) .itemId(102L) .build(); - orderItemDto_102.setItemName("아이템3"); - OrderItemDto orderItemDto_103 = OrderItemDto.builder() + orderItemDto_102.changeName("아이템3"); + PrevOrderDto._PrevOrderItem orderItemDto_103 = PrevOrderDto._PrevOrderItem.builder() .id(103L) .itemId(103L) .build(); - orderItemDto_103.setItemName("아이템2"); + orderItemDto_103.changeName("아이템2"); - OrderDto orderDto_1 = OrderDto.builder() + PrevOrderDto orderDto_1 = PrevOrderDto.builder() .id(1L) .userId(1L) - .orderItemDtoList(List.of(orderItemDto_100, orderItemDto_101)) + .orderItems(List.of(orderItemDto_100, orderItemDto_101)) .orderStatus(OrderStatus.PLACED) .orderTime(LocalDateTime.of(2022, 2, 3, 14, 0, 0)) .build(); - orderDto_1.setUserName("닉네임"); - OrderDto orderDto_2 = OrderDto.builder() + orderDto_1.changeUserName("닉네임"); + PrevOrderDto orderDto_2 = PrevOrderDto.builder() .id(2L) .userId(1L) - .orderItemDtoList(List.of(orderItemDto_102, orderItemDto_103)) + .orderItems(List.of(orderItemDto_102, orderItemDto_103)) .orderStatus(OrderStatus.FAIL) .orderTime(LocalDateTime.of(2022, 2, 3, 15, 0, 0)) .build(); - orderDto_2.setUserName("닉네임"); + orderDto_2.changeUserName("닉네임"); return List.of(orderDto_1, orderDto_2); } @@ -229,6 +233,7 @@ class OrderOwnerApiControllerTest { // WHEN ResultActions actions = mockMvc.perform(get(url + "/prev-order") + .header("user-id", "1") .param("startDate", startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) .param("endDate", endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) .param("page", page) @@ -254,6 +259,9 @@ class OrderOwnerApiControllerTest { parameterWithName("endDate").description("종료날짜 YYYY-MM-DD"), parameterWithName("page").optional().description("검색 페이지 (0부터 시작)") ), + requestHeaders( + headerWithName("user-id").description("유저 고유번호") + ), responseFields( fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), fieldWithPath("message").description("메시지"), @@ -283,6 +291,7 @@ class OrderOwnerApiControllerTest { // THEN ResultActions actions = mockMvc.perform(get(url + "/prev-order") + .header("user-id", "1") .param("startDate", startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) .param("endDate", endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) .param("page", page) @@ -300,6 +309,9 @@ class OrderOwnerApiControllerTest { parameterWithName("endDate").description("종료날짜 YYYY-MM-DD"), parameterWithName("page").optional().description("검색 페이지 (0부터 시작)") ), + requestHeaders( + headerWithName("user-id").description("유저 고유번호") + ), responseFields( fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), fieldWithPath("message").description("메시지"), diff --git a/owner-apigateway-service/src/main/resources/application.yml b/owner-apigateway-service/src/main/resources/application.yml index e97254b..c7fbc31 100644 --- a/owner-apigateway-service/src/main/resources/application.yml +++ b/owner-apigateway-service/src/main/resources/application.yml @@ -39,6 +39,7 @@ spring: - PUT - OPTIONS - DELETE + - PATCH allowedHeaders: '*' allow-credentials: true routes: diff --git a/owner-vue/src/components/OrderCard.vue b/owner-vue/src/components/OrderCard.vue index afae546..193eb7f 100644 --- a/owner-vue/src/components/OrderCard.vue +++ b/owner-vue/src/components/OrderCard.vue @@ -5,7 +5,12 @@ 상세보기 - {{ itemNames.join(", ") }} + + {{ itemNames[0] }} + + + {{ itemNames[0] }} 외 {{ itemNames.length - 1 }}건 + {{ orderTime }} @@ -56,7 +61,7 @@ export default { }, props: { id: Number, - userName: Number, + userName: String, itemNames: [], orderTime: String, orderStatus: String diff --git a/owner-vue/src/views/PrevOrder.vue b/owner-vue/src/views/PrevOrder.vue index be67d30..3ca027c 100644 --- a/owner-vue/src/views/PrevOrder.vue +++ b/owner-vue/src/views/PrevOrder.vue @@ -49,24 +49,11 @@ export default { 'date-picker': DatePicker }, mounted: function() { - orderApi.requestPrevOrder(this.startDate, this.endDate, this.page - 1) - .then( (response) => { - this.renderList(response.data); - }) - .catch( (error) => { - console.log(error); - }); + this.search(); }, watch: { - "page": function (newPage) { - orderApi.requestPrevOrder(this.startDate, this.endDate, newPage - 1) - .then( (response) => { - this.renderList(response.data); - }) - .catch( (error) => { - console.log(error); - console.log(error.response.data); - }); + "page": function () { + this.search(); } }, data: function() { @@ -98,7 +85,6 @@ export default { orders: [], } }, - methods: { search: function() { if(!this.checkDate()) return; @@ -116,16 +102,12 @@ export default { this.orders = []; orders.forEach(order => { - let orderItemNames = []; - order.orderItems.forEach(orderItem => { - orderItemNames.push(orderItem.orderItemId); - }) this.orders.push({ orderId: order.orderId, - orderStatus: order.orderStatus, + orderStatus: this.getOrderStatusName(order.orderStatus), orderTime: order.orderTime, - orderItemNames: orderItemNames.join(", "), + orderItemNames: this.getOrderItemName(order.orderItems), orderPrice: order.orderPrice, userName: order.userName }); @@ -154,6 +136,21 @@ export default { }, inputEndDate: function(value) { this.endDate = value; + }, + getOrderStatusName: function(orderStatus) { + if (orderStatus === "ORDER") return "주문"; + if (orderStatus === "PLACED") return "주문 수락"; + if (orderStatus === "REJECT") return "주문 거절"; + return orderStatus; + }, + getOrderItemName: function(orderItems) { + const orderItemLength = orderItems.length; + const orderItemName = orderItems[0].orderItemName; + if (orderItemLength == 1) { + return orderItemName; + } else if (orderItemLength > 1) { + return orderItemName + " 외 " + (orderItemLength - 1) + "건"; + } } } } diff --git a/store-service/src/docs/asciidoc/api-docs.adoc b/store-service/src/docs/asciidoc/api-docs.adoc index bdba3b4..f080c60 100644 --- a/store-service/src/docs/asciidoc/api-docs.adoc +++ b/store-service/src/docs/asciidoc/api-docs.adoc @@ -69,7 +69,13 @@ domain-httpRequestCode-etc operation::item-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] === 상품 조회 (존재하지 않는 상품) operation::item-get-notExistItemException[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] +=== 상품 리스트 조회 +operation::items-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] + +== 상품 (판매자) +=== 상품 조회 +======= === 상품 리스트 조회(구매자) operation::customer-itemList-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] @@ -92,9 +98,6 @@ operation::get-categoryList[snippets='curl-request,http-request,http-response,re operation::put-categoryList[snippets='curl-request,http-request,http-response,request-body,request-fields'] - - - == 매장 === 매장 검색 조회 operation::api-customer-store-search[snippets='curl-request,http-request,http-response,request-parameters,response-fields'] @@ -102,4 +105,7 @@ operation::api-customer-store-search[snippets='curl-request,http-request,http-re operation::favoriteStore-get[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields'] === 매장 조회 operation::store-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] - +=== 매장 조회 (회원 고유번호) +operation::api-get-store-byUserId[snippets='curl-request,http-request,http-response,request-headers,response-fields'] +=== 매장 리스트 조회 +operation::stores-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/ItemsDto.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/ItemsDto.java new file mode 100644 index 0000000..b0127be --- /dev/null +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/ItemsDto.java @@ -0,0 +1,26 @@ +package com.justpickup.storeservice.domain.item.dto; + +import com.justpickup.storeservice.domain.item.entity.Item; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ItemsDto { + private Long itemId; + private String itemName; + + @Builder + public ItemsDto(Long itemId, String itemName) { + this.itemId = itemId; + this.itemName = itemName; + } + + public static ItemsDto of(Item item) { + ItemsDto itemsDto = new ItemsDto(); + itemsDto.itemId = item.getId(); + itemsDto.itemName = item.getName(); + return itemsDto; + } +} diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemService.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemService.java index 277dcad..2ca0050 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemService.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemService.java @@ -3,6 +3,7 @@ package com.justpickup.storeservice.domain.item.service; import com.justpickup.storeservice.domain.item.dto.FetchItemDto; import com.justpickup.storeservice.domain.item.dto.GetItemDto; import com.justpickup.storeservice.domain.item.dto.ItemDto; +import com.justpickup.storeservice.domain.item.dto.ItemsDto; import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -16,9 +17,11 @@ public interface ItemService { List getItemAndItemOptions(List itemIds); FetchItemDto fetchItem(Long itemId); - Page findItemList(Long userId,String word, Pageable pageable); + Page findMenuItemList(Long userId, String word, Pageable pageable); void putItem(Long itemId, String itemName, Long itemPrice, Long categoryId, List itemOptionDtos); void createItem( Long userId, String itemName, Long itemPrice, Long categoryId, List itemOptionDtos); + + List findItems(List itemIds); } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemServiceImpl.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemServiceImpl.java index 105dc62..98db5a1 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemServiceImpl.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemServiceImpl.java @@ -5,6 +5,7 @@ import com.justpickup.storeservice.domain.category.repository.CategoryRepository import com.justpickup.storeservice.domain.item.dto.FetchItemDto; import com.justpickup.storeservice.domain.item.dto.GetItemDto; import com.justpickup.storeservice.domain.item.dto.ItemDto; +import com.justpickup.storeservice.domain.item.dto.ItemsDto; import com.justpickup.storeservice.domain.item.entity.Item; import com.justpickup.storeservice.domain.item.exception.NotExistItemException; import com.justpickup.storeservice.domain.item.repository.ItemRepository; @@ -37,8 +38,6 @@ public class ItemServiceImpl implements ItemService { private final CategoryRepository categoryRepository; private final StoreRepository storeRepository; - - @Override public ItemDto findItemByItemId(Long itemId) { Item findItem = itemRepository.findById(itemId) @@ -66,9 +65,9 @@ public class ItemServiceImpl implements ItemService { @Override - public Page findItemList( Long userId,String word, Pageable pageable) { + public Page findMenuItemList(Long userId, String word, Pageable pageable) { - Page itemList = itemRepositoryCustom.findItem(userId,word,pageable); + Page itemList = itemRepositoryCustom.findItem(userId, word, pageable); return PageableExecutionUtils.getPage(itemList.stream() .map(ItemDto::createWithCategory) .collect(Collectors.toList()),pageable,itemList::getTotalElements); @@ -122,4 +121,12 @@ public class ItemServiceImpl implements ItemService { itemRepository.save(createdItem); } + + @Override + public List findItems(List itemIds) { + return itemRepository.findAllById(itemIds) + .stream() + .map(ItemsDto::of) + .collect(Collectors.toList()); + } } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemController.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemController.java index d18b5c8..ba104f3 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemController.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemController.java @@ -1,21 +1,20 @@ package com.justpickup.storeservice.domain.item.web; import com.justpickup.storeservice.domain.item.dto.ItemDto; +import com.justpickup.storeservice.domain.item.dto.ItemsDto; import com.justpickup.storeservice.domain.item.service.ItemService; -import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto; -import com.justpickup.storeservice.domain.itemoption.entity.OptionType; import com.justpickup.storeservice.global.dto.Result; import com.justpickup.storeservice.global.entity.Yn; -import lombok.*; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; import java.util.List; import java.util.stream.Collectors; @@ -50,5 +49,26 @@ public class ItemController { } } + @GetMapping("/items/{itemIds}") + public ResponseEntity getItems(@PathVariable List itemIds) { + List items = itemService.findItems(itemIds); + + List responses = items.stream() + .map(GetItemsResponse::new) + .collect(Collectors.toList()); + + return ResponseEntity.ok(Result.createSuccessResult(responses)); + } + + @Data @NoArgsConstructor + static class GetItemsResponse { + private Long id; + private String name; + + public GetItemsResponse(ItemsDto itemsDto) { + this.id = itemsDto.getItemId(); + this.name = itemsDto.getItemName(); + } + } } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemOwnerApiController.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemOwnerApiController.java index f77330a..7d8d704 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemOwnerApiController.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemOwnerApiController.java @@ -35,7 +35,7 @@ public class ItemOwnerApiController { Page itemDtoList = - itemService.findItemList(Long.parseLong(userId), + itemService.findMenuItemList(Long.parseLong(userId), word.orElse(""), pageable); List itemList = itemDtoList.stream() diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/entity/ItemOption.java b/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/entity/ItemOption.java index d674b96..8b03e34 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/entity/ItemOption.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/itemoption/entity/ItemOption.java @@ -31,7 +31,6 @@ public class ItemOption extends BaseEntity { // == 연관관계 편의 메소드 == // public void setItem(Item item) { this.item = item; - item.getItemOptions().add(this); } public ItemOption(OptionType optionType, String name, Item item) { diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/store/dto/StoreByUserIdDto.java b/store-service/src/main/java/com/justpickup/storeservice/domain/store/dto/StoreByUserIdDto.java new file mode 100644 index 0000000..0e9e9a6 --- /dev/null +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/store/dto/StoreByUserIdDto.java @@ -0,0 +1,24 @@ +package com.justpickup.storeservice.domain.store.dto; + +import com.justpickup.storeservice.domain.store.entity.Store; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class StoreByUserIdDto { + private Long id; + private String name; + + @Builder + public StoreByUserIdDto(Long id, String name) { + this.id = id; + this.name = name; + } + + public static StoreByUserIdDto of(Store store) { + return StoreByUserIdDto.builder() + .id(store.getId()) + .name(store.getName()) + .build(); + } +} diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/store/dto/StoreDto.java b/store-service/src/main/java/com/justpickup/storeservice/domain/store/dto/StoreDto.java index 2dd6c27..86ddfd1 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/store/dto/StoreDto.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/store/dto/StoreDto.java @@ -1,21 +1,30 @@ package com.justpickup.storeservice.domain.store.dto; import com.justpickup.storeservice.domain.store.entity.Store; -import lombok.AllArgsConstructor; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; @Getter -@AllArgsConstructor -@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class StoreDto { private Long id; private String name; private String phoneNumber; - public StoreDto(Store store) { - this.id = store.getId(); - this.name = store.getName(); - this.phoneNumber = store.getPhoneNumber(); + @Builder + public StoreDto(Long id, String name, String phoneNumber) { + this.id = id; + this.name = name; + this.phoneNumber = phoneNumber; + } + + public static StoreDto of(Store store) { + StoreDto storeDto = new StoreDto(); + storeDto.id = store.getId(); + storeDto.name = store.getName(); + storeDto.phoneNumber = store.getPhoneNumber(); + return storeDto; } } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/store/service/StoreService.java b/store-service/src/main/java/com/justpickup/storeservice/domain/store/service/StoreService.java index 1787b50..56a83ee 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/store/service/StoreService.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/store/service/StoreService.java @@ -2,6 +2,7 @@ package com.justpickup.storeservice.domain.store.service; import com.justpickup.storeservice.domain.store.dto.SearchStoreCondition; import com.justpickup.storeservice.domain.store.dto.SearchStoreResult; +import com.justpickup.storeservice.domain.store.dto.StoreByUserIdDto; import com.justpickup.storeservice.domain.store.dto.StoreDto; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.SliceImpl; @@ -11,5 +12,7 @@ import java.util.List; public interface StoreService { SliceImpl findSearchStoreScroll(SearchStoreCondition condition, Pageable pageable); List findFavoriteStore(SearchStoreCondition condition, Long userId); - StoreDto findStore(Long storeId); + StoreDto findStoreById(Long storeId); + StoreByUserIdDto findStoreByUserId(Long userId); + List findStoreAllById(Iterable storeIds); } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/store/service/StoreServiceImpl.java b/store-service/src/main/java/com/justpickup/storeservice/domain/store/service/StoreServiceImpl.java index 3caf57e..aa06ef2 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/store/service/StoreServiceImpl.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/store/service/StoreServiceImpl.java @@ -3,6 +3,7 @@ package com.justpickup.storeservice.domain.store.service; import com.justpickup.storeservice.domain.favoritestore.repository.FavoriteStoreCustom; import com.justpickup.storeservice.domain.store.dto.SearchStoreCondition; import com.justpickup.storeservice.domain.store.dto.SearchStoreResult; +import com.justpickup.storeservice.domain.store.dto.StoreByUserIdDto; import com.justpickup.storeservice.domain.store.dto.StoreDto; import com.justpickup.storeservice.domain.store.entity.Store; import com.justpickup.storeservice.domain.store.exception.NotExistStoreException; @@ -14,6 +15,7 @@ import org.springframework.data.domain.SliceImpl; import org.springframework.stereotype.Service; import java.util.List; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -47,10 +49,26 @@ public class StoreServiceImpl implements StoreService { } @Override - public StoreDto findStore(Long storeId) { + public StoreDto findStoreById(Long storeId) { Store store = storeRepository.findById(storeId) .orElseThrow(() -> new NotExistStoreException(storeId + "는 없는 매장 고유번호입니다.")); - return new StoreDto(store); + return StoreDto.of(store); + } + + @Override + public StoreByUserIdDto findStoreByUserId(Long userId) { + Store store = storeRepository.findByUserId(userId) + .orElseThrow(() -> new NotExistStoreException(userId + "의 매장은 없습니다.")); + + return StoreByUserIdDto.of(store); + } + + @Override + public List findStoreAllById(Iterable storeIds) { + return storeRepository.findAllById(storeIds) + .stream() + .map(StoreDto::of) + .collect(Collectors.toList()); } } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/store/web/StoreController.java b/store-service/src/main/java/com/justpickup/storeservice/domain/store/web/StoreController.java index 3bbe6f2..32fa705 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/store/web/StoreController.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/store/web/StoreController.java @@ -9,19 +9,20 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.List; +import java.util.stream.Collectors; + @RestController @RequiredArgsConstructor -@RequestMapping("/store") public class StoreController { private final StoreService storeService; - @GetMapping("/{storeId}") + @GetMapping("/store/{storeId}") public ResponseEntity getStore(@PathVariable("storeId") Long storeId) { - StoreDto storeDto = storeService.findStore(storeId); + StoreDto storeDto = storeService.findStoreById(storeId); GetStoreResponse getStoreResponse = new GetStoreResponse(storeDto); return ResponseEntity.ok(Result.createSuccessResult(getStoreResponse)); @@ -39,4 +40,16 @@ public class StoreController { this.phoneNumber = storeDto.getPhoneNumber(); } } + + @GetMapping("/stores/{storeIds}") + public ResponseEntity getStores(@PathVariable("storeIds") List storeIds) { + + List storeDtoList = storeService.findStoreAllById(storeIds); + + List responses = storeDtoList.stream() + .map(GetStoreResponse::new) + .collect(Collectors.toList()); + + return ResponseEntity.ok(Result.createSuccessResult(responses)); + } } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/store/web/StoreOwnerApiController.java b/store-service/src/main/java/com/justpickup/storeservice/domain/store/web/StoreOwnerApiController.java new file mode 100644 index 0000000..8e13161 --- /dev/null +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/store/web/StoreOwnerApiController.java @@ -0,0 +1,43 @@ +package com.justpickup.storeservice.domain.store.web; + +import com.justpickup.storeservice.domain.store.dto.StoreByUserIdDto; +import com.justpickup.storeservice.domain.store.service.StoreService; +import com.justpickup.storeservice.global.dto.Result; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +@Slf4j +public class StoreOwnerApiController { + + private final StoreService storeService; + + @GetMapping("/owner/store") + public ResponseEntity getStoreByUserId(@RequestHeader("user-id") String userHeader) { + Long userId = Long.valueOf(userHeader); + + StoreByUserIdDto dto = storeService.findStoreByUserId(userId); + + return ResponseEntity.ok(Result.createSuccessResult(dto)); + } + + @Data + static class StoreByUserIdResponse { + private Long id; + private String name; + + public StoreByUserIdResponse(StoreByUserIdDto dto) { + this.id = dto.getId(); + this.name = dto.getName(); + } + + } +} diff --git a/store-service/src/main/java/com/justpickup/storeservice/global/SqlCommandLineRunner.java b/store-service/src/main/java/com/justpickup/storeservice/global/SqlCommandLineRunner.java index 2e0fedb..f2c51fe 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/global/SqlCommandLineRunner.java +++ b/store-service/src/main/java/com/justpickup/storeservice/global/SqlCommandLineRunner.java @@ -1,5 +1,6 @@ package com.justpickup.storeservice.global; +import com.fasterxml.jackson.databind.ObjectMapper; import com.justpickup.storeservice.domain.category.entity.Category; import com.justpickup.storeservice.domain.category.repository.CategoryRepository; import com.justpickup.storeservice.domain.favoritestore.entity.FavoriteStore; @@ -12,22 +13,76 @@ import com.justpickup.storeservice.domain.map.entity.Map; import com.justpickup.storeservice.domain.store.entity.Store; import com.justpickup.storeservice.domain.store.repository.StoreRepository; import com.justpickup.storeservice.global.entity.Address; +import lombok.Data; +import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.stream.Collectors; //@Component @RequiredArgsConstructor +@Slf4j public class SqlCommandLineRunner implements CommandLineRunner { private final StoreRepository storeRepository; private final FavoriteStoreRepository favoriteStoreRepository; private final ItemRepository itemRepository; private final CategoryRepository categoryRepository; + private final ObjectMapper objectMapper; + @Data + static class _Store { + private Long id; + private String name; + private List<_Item> items = new ArrayList<>(); + + public _Store(Store store) { + this.id = store.getId(); + this.name = store.getName(); + this.items = store.getItems() + .stream() + .map(_Item::new) + .collect(Collectors.toList()); + } + + @NoArgsConstructor @Data + static class _Item { + private Long id; + private String name; + private Long price; + List<_ItemOption> itemOptions = new ArrayList<>(); + + public _Item(Item item) { + this.id = item.getId(); + this.name = item.getName(); + this.price = item.getPrice(); + this.itemOptions = item.getItemOptions() + .stream() + .map(_ItemOption::new) + .collect(Collectors.toList()); + } + } + + @NoArgsConstructor @Data + static class _ItemOption { + private Long id; + private String name; + + public _ItemOption(ItemOption itemOption) { + this.id = itemOption.getId(); + this.name = itemOption.getName(); + } + } + } + + @Transactional @Override public void run(String... args) throws Exception { List stores = new ArrayList<>(); @@ -37,9 +92,14 @@ public class SqlCommandLineRunner implements CommandLineRunner { createFavoriteStore(favoriteStoreRepository, stores); createItemAndCategories(itemRepository, categoryRepository, stores); + + List<_Store> list = stores.stream().map(_Store::new).collect(Collectors.toList()); + String json = objectMapper.writeValueAsString(list); + log.info("[Test] {}", json); } - private void createItemAndCategories(ItemRepository itemRepository, CategoryRepository categoryRepository, List stores) { + + void createItemAndCategories(ItemRepository itemRepository, CategoryRepository categoryRepository, List stores) { stores.forEach(store -> { Category 카페인 = categoryRepository.save(Category.of("카페인", 0, store)); Category 디카페인 = categoryRepository.save(Category.of("디카페인", 1, store)); @@ -56,17 +116,20 @@ public class SqlCommandLineRunner implements CommandLineRunner { Item 딸기라떼 = Item.of("딸기라떼", 3000L, 디카페인, store, List.of(ice, hot)); Item 녹차 = Item.of("녹차", 3000L, 티, store, List.of(hot)); Item 히비스커스 = Item.of("히비스커스 티", 3000L, 티, store, List.of(hot)); - itemRepository.saveAll(List.of(아메리카노, 카페라떼, 콜드브루, 녹차라떼, 딸기라떼, 녹차, 히비스커스)); + + List items = List.of(아메리카노, 카페라떼, 카페모카, 콜드브루, 녹차라떼, 딸기라떼, 녹차, 히비스커스); + itemRepository.saveAll(items); + + items.forEach(item -> store.addItem(item)); }); } - - private void createFavoriteStore(FavoriteStoreRepository favoriteStoreRepository, List stores) { + void createFavoriteStore(FavoriteStoreRepository favoriteStoreRepository, List stores) { List userList = List.of(1L,2L,3L,4L,5L,6L,7L); userList.forEach(userId -> stores.forEach(store -> favoriteStoreRepository.save(FavoriteStore.of(userId, store)))); } - private void createStores(StoreRepository storeRepository, List stores) { + void createStores(StoreRepository storeRepository, List stores) { stores.add( Store.of( new Address("서울시", "마포구 도화동", "201-20"), diff --git a/store-service/src/main/java/com/justpickup/storeservice/global/client/user/UserClient.java b/store-service/src/main/java/com/justpickup/storeservice/global/client/user/UserClient.java index 941b739..a6b5684 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/global/client/user/UserClient.java +++ b/store-service/src/main/java/com/justpickup/storeservice/global/client/user/UserClient.java @@ -5,9 +5,9 @@ import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -@FeignClient(name = "USER-SERVICE", url = "127.0.0.1:8001/user-service") +@FeignClient("USER-SERVICE") public interface UserClient { @GetMapping("/customer/{userId}") - Result getUser(@PathVariable("userId") Long userId); + Result getCustomerById(@PathVariable("userId") Long userId); } diff --git a/store-service/src/main/resources/application.yml b/store-service/src/main/resources/application.yml index aa4cc03..c66a93b 100644 --- a/store-service/src/main/resources/application.yml +++ b/store-service/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 12343 + port: 0 spring: application: @@ -27,10 +27,11 @@ spring: username: postgres password: admin - sql: - init: - data-locations: classpath:data/data.sql - mode: always + +# sql: +# init: +# data-locations: classpath:data/data.sql +# mode: always eureka: diff --git a/store-service/src/main/resources/static/docs/api-docs.html b/store-service/src/main/resources/static/docs/api-docs.html deleted file mode 100644 index 590a541..0000000 --- a/store-service/src/main/resources/static/docs/api-docs.html +++ /dev/null @@ -1,778 +0,0 @@ - - - - - - - -개요 - - - - - - -
-
-

HTTP 동사

-
-
-

본 REST API에서 사용하는 HTTP 동사(verbs)는 가능한한 표준 HTTP와 REST 규약을 따릅니다.

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
동사용례

GET

리소스를 가져올 때 사용

POST

새 리소스를 만들 때 사용

PUT

기존 리소스를 수정할 때 사용

PATCH

기존 리소스의 일부를 수정할 때 사용

DELETE

기존 리소스를 삭제할 떄 사용

-
-
-
-

HTTP 상태 코드

-
-
-

본 REST API에서 사용하는 HTTP 상태 코드는 가능한 표준 HTTP와 REST 규약을 따릅니다.

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
상태 코드용례

200 OK

요청을 성공적으로 처리함

201 Created

새 리소스를 성공적으로 생성함. 응답의 Location 헤더에 해당 리소스의 URI가 담겨있다.

204 No Content

기존 리소스를 성공적으로 수정함.

400 Bad Request

잘못된 요청을 보낸 경우. 응답 본문에 더 오류에 대한 정보가 담겨있다.

404 Not Found

요청한 리소스가 없음.

409 Conflict

클라이언트의 요청이 서버의 상태와 충돌이 발생한 경우.

-
-
-
-

snippets 작성 컨벤션

-
-
-

domain-httpRequestCode-etc

-
-
-
-
-

상품

-
-
-

상품 조회

-
-

Curl request

-
-
-
$ curl 'http://127.0.0.1:8001/item/1' -i -X GET
-
-
-
-
-

HTTP request

-
-
-
GET /item/1 HTTP/1.1
-Host: 127.0.0.1:8001
-
-
-
-
-

HTTP response

-
-
-
HTTP/1.1 200 OK
-Content-Type: application/json
-Content-Length: 146
-
-{
-  "code" : "SUCCESS",
-  "message" : "",
-  "data" : {
-    "id" : 1,
-    "name" : "아메리카노",
-    "salesYn" : "Y",
-    "price" : 1500
-  }
-}
-
-
-
-
-

Path parameters

- - ---- - - - - - - - - - - - - -
Table 1. /item/{itemId}
ParameterDescription

itemId

상품 고유 번호

-
-
-

Response fields

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PathTypeDescription

code

String

결과 코드 SUCCESS/ERROR

message

String

메시지

data.id

Number

상품 고유 번호

data.name

String

상품 이름

data.salesYn

String

화면 표시 여부 Y/N

data.price

Number

상품 가격

-
-
-
-

상품 조회 (존재하지 않는 상품)

-
-

Curl request

-
-
-
$ curl 'http://127.0.0.1:8001/item/9999' -i -X GET
-
-
-
-
-

HTTP request

-
-
-
GET /item/9999 HTTP/1.1
-Host: 127.0.0.1:8001
-
-
-
-
-

HTTP response

-
-
-
HTTP/1.1 409 Conflict
-Content-Type: application/json
-Content-Length: 93
-
-{
-  "code" : "ERROR",
-  "message" : "존재하지 않는 상품입니다.",
-  "data" : null
-}
-
-
-
-
-

Path parameters

- - ---- - - - - - - - - - - - - -
Table 1. /item/{itemId}
ParameterDescription

itemId

상품 고유 번호

-
-
-

Response fields

- ----- - - - - - - - - - - - - - - - - - - - - - - - - -
PathTypeDescription

code

String

결과 코드 SUCCESS/ERROR

message

String

메시지

data

Null

데이터

-
-
-
-
-
- - - - - - \ No newline at end of file diff --git a/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemControllerTest.java b/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemControllerTest.java index a330a9b..e495705 100644 --- a/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemControllerTest.java +++ b/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemControllerTest.java @@ -2,11 +2,10 @@ package com.justpickup.storeservice.domain.item.web; import com.fasterxml.jackson.databind.ObjectMapper; import com.justpickup.storeservice.config.TestConfig; -import com.justpickup.storeservice.domain.favoritestore.repository.FavoriteStoreRepository; import com.justpickup.storeservice.domain.item.dto.ItemDto; +import com.justpickup.storeservice.domain.item.dto.ItemsDto; import com.justpickup.storeservice.domain.item.exception.NotExistItemException; import com.justpickup.storeservice.domain.item.service.ItemService; -import com.justpickup.storeservice.domain.store.repository.StoreRepository; import com.justpickup.storeservice.global.dto.Code; import com.justpickup.storeservice.global.entity.Yn; import org.junit.jupiter.api.DisplayName; @@ -19,6 +18,10 @@ import org.springframework.context.annotation.Import; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + import static org.mockito.BDDMockito.given; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; @@ -44,12 +47,6 @@ class ItemControllerTest { @MockBean ItemService itemService; - @MockBean - private StoreRepository storeRepository; - - @MockBean - private FavoriteStoreRepository favoriteStoreRepository; - @Test @DisplayName("상품 조회") void getItem() throws Exception { @@ -122,5 +119,52 @@ class ItemControllerTest { ; } + @Test + @DisplayName("[GET] 아이템 리스트 조회") + void getItems() throws Exception { + // GIVEN + List itemIds = List.of(1L, 2L, 3L); + + given(itemService.findItems(itemIds)) + .willReturn(itemsWillReturnDto(itemIds)); + + String itemIdsParam = itemIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + + // THEN + ResultActions actions = mockMvc.perform(get("/items/{itemIds}", itemIdsParam)); + // WHEN + actions.andExpect(status().isOk()) + .andExpect(jsonPath("code").value(Code.SUCCESS.name())) + .andExpect(jsonPath("message").value("")) + .andDo(print()) + .andDo(document("items-get", + pathParameters( + parameterWithName("itemIds").description("상품 고유 번호들") + ), + responseFields( + fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data[*].id").description("상품 고유 번호"), + fieldWithPath("data[*].name").description("상품 이름") + ) + )) + ; + } + + private List itemsWillReturnDto(List itemIds) { + List items = new ArrayList<>(); + + for (Long itemId : itemIds) { + ItemsDto itemsDto = ItemsDto.builder() + .itemId(itemId) + .itemName("아이템 이름" + itemId) + .build(); + items.add(itemsDto); + } + + return items; + } } \ No newline at end of file diff --git a/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemOwnerApiControllerTest.java b/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemOwnerApiControllerTest.java index db657c5..f4fab7e 100644 --- a/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemOwnerApiControllerTest.java +++ b/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemOwnerApiControllerTest.java @@ -3,12 +3,10 @@ package com.justpickup.storeservice.domain.item.web; import com.fasterxml.jackson.databind.ObjectMapper; import com.justpickup.storeservice.config.TestConfig; import com.justpickup.storeservice.domain.category.dto.CategoryDto; -import com.justpickup.storeservice.domain.favoritestore.repository.FavoriteStoreRepository; import com.justpickup.storeservice.domain.item.dto.FetchItemDto; import com.justpickup.storeservice.domain.item.dto.ItemDto; import com.justpickup.storeservice.domain.item.service.ItemService; import com.justpickup.storeservice.domain.itemoption.entity.OptionType; -import com.justpickup.storeservice.domain.store.repository.StoreRepository; import com.justpickup.storeservice.global.dto.Code; import com.justpickup.storeservice.global.entity.Yn; import org.junit.jupiter.api.DisplayName; @@ -78,7 +76,7 @@ class ItemOwnerApiControllerTest { Page page = PageableExecutionUtils.getPage(items, Pageable.ofSize(10), () -> 1); - given(itemService.findItemList(eq(1L),eq(""),any())) + given(itemService.findMenuItemList(eq(1L),eq(""),any())) .willReturn(page); // WHEN diff --git a/store-service/src/test/java/com/justpickup/storeservice/domain/store/web/StoreControllerTest.java b/store-service/src/test/java/com/justpickup/storeservice/domain/store/web/StoreControllerTest.java index 09737d0..cdd5fff 100644 --- a/store-service/src/test/java/com/justpickup/storeservice/domain/store/web/StoreControllerTest.java +++ b/store-service/src/test/java/com/justpickup/storeservice/domain/store/web/StoreControllerTest.java @@ -3,6 +3,7 @@ package com.justpickup.storeservice.domain.store.web; import com.justpickup.storeservice.config.TestConfig; import com.justpickup.storeservice.domain.store.dto.StoreDto; import com.justpickup.storeservice.domain.store.service.StoreService; +import com.justpickup.storeservice.global.dto.Code; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -13,6 +14,10 @@ import org.springframework.context.annotation.Import; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + import static org.mockito.BDDMockito.given; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; @@ -21,6 +26,7 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.response 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; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(StoreController.class) @@ -41,7 +47,7 @@ class StoreControllerTest { void getStore() throws Exception { //given String storeId = "1"; - given(storeService.findStore(1L)).willReturn(getWillReturnStore()); + given(storeService.findStoreById(1L)).willReturn(getWillReturnStore()); //when ResultActions actions = mockMvc.perform(get("/store/{storeId}", storeId)); @@ -66,4 +72,52 @@ class StoreControllerTest { private StoreDto getWillReturnStore() { return StoreDto.builder().id(1L).name("이디야커피 대림역점").phoneNumber("010-1234-5678").build(); } + + @Test + @DisplayName("[GET] 매장 정보들 가져오기") + void getStores() throws Exception { + // GIVEN + List storeIds = List.of(1L, 2L, 3L); + + given(storeService.findStoreAllById(storeIds)) + .willReturn(storesWillReturnDto(storeIds)); + + String storeIdsParam = storeIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + + // THEN + ResultActions actions = mockMvc.perform(get("/stores/{storeIds}", storeIdsParam)); + // WHEN + actions.andExpect(status().isOk()) + .andExpect(jsonPath("code").value(Code.SUCCESS.name())) + .andExpect(jsonPath("message").value("")) + .andDo(print()) + .andDo(document("stores-get", + pathParameters( + parameterWithName("storeIds").description("매장 고유 번호들") + ), + responseFields( + fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data[*].id").description("매장 고유 번호"), + fieldWithPath("data[*].name").description("매장 이름"), + fieldWithPath("data[*].phoneNumber").description("매장 휴대폰 번호") + ) + )) + ; + } + + private List storesWillReturnDto(List storeIds) { + List stores = new ArrayList<>(); + for (Long storeId : storeIds) { + StoreDto storeDto = StoreDto.builder() + .id(storeId) + .name("매장 이름" + storeId) + .phoneNumber("010-1234-5678") + .build(); + stores.add(storeDto); + } + return stores; + } } \ No newline at end of file diff --git a/store-service/src/test/java/com/justpickup/storeservice/domain/store/web/StoreOwnerApiControllerTest.java b/store-service/src/test/java/com/justpickup/storeservice/domain/store/web/StoreOwnerApiControllerTest.java new file mode 100644 index 0000000..598ef1e --- /dev/null +++ b/store-service/src/test/java/com/justpickup/storeservice/domain/store/web/StoreOwnerApiControllerTest.java @@ -0,0 +1,75 @@ +package com.justpickup.storeservice.domain.store.web; + +import com.justpickup.storeservice.config.TestConfig; +import com.justpickup.storeservice.domain.store.dto.StoreByUserIdDto; +import com.justpickup.storeservice.domain.store.service.StoreService; +import com.justpickup.storeservice.global.dto.Code; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(StoreOwnerApiController.class) +@Import(TestConfig.class) +@AutoConfigureRestDocs(uriHost = "just-pickup.com", uriPort = 8000) +class StoreOwnerApiControllerTest { + + private final String url = "/api"; + + @Autowired + MockMvc mockMvc; + + @MockBean + StoreService storeService; + + @Test + @DisplayName("[API] [GET] 회원 고유번호로 매장 정보 찾기") + void getStoreByUserId() throws Exception { + // GIVEN + String userHeader = "1"; + Long userId = Long.valueOf(userHeader); + StoreByUserIdDto willReturnDto = StoreByUserIdDto.builder().id(10L).name("한강커피").build(); + given(storeService.findStoreByUserId(userId)).willReturn(willReturnDto); + + // THEN + ResultActions actions = mockMvc.perform(get(url + "/owner/store") + .header("user-id", userHeader) + ); + + // WHEN + actions.andExpect(status().isOk()) + .andExpect(jsonPath("code").value(Code.SUCCESS.name())) + .andExpect(jsonPath("data").exists()) + .andDo(print()) + .andDo(document("api-get-store-byUserId", + requestHeaders( + headerWithName("user-id").description("로그인한 유저 id") + ), + responseFields( + fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data.id").description("매장 고유번호"), + fieldWithPath("data.name").description("매장 이름") + ) + )) + ; + + } +} \ No newline at end of file diff --git a/user-service/src/docs/asciidoc/api-docs.adoc b/user-service/src/docs/asciidoc/api-docs.adoc index 9204d08..cae79a5 100644 --- a/user-service/src/docs/asciidoc/api-docs.adoc +++ b/user-service/src/docs/asciidoc/api-docs.adoc @@ -71,6 +71,8 @@ operation::customer-get-mypage[snippets='curl-request,http-request,http-response operation::customer-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] === 회원 조회 (존재하지 않는 회원) operation::customer-get-notExistUserException[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] +=== 회원 조회 +operation::customers-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] == 점주 === 회원가입 - 점주 diff --git a/user-service/src/main/java/com/justpickup/userservice/UserServiceApplication.java b/user-service/src/main/java/com/justpickup/userservice/UserServiceApplication.java index 9b26de3..e7ad12a 100644 --- a/user-service/src/main/java/com/justpickup/userservice/UserServiceApplication.java +++ b/user-service/src/main/java/com/justpickup/userservice/UserServiceApplication.java @@ -1,12 +1,8 @@ package com.justpickup.userservice; -import com.justpickup.userservice.domain.user.dto.StoreOwnerDto; -import com.justpickup.userservice.domain.user.service.UserService; -import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; -import org.springframework.context.annotation.Bean; @SpringBootApplication @EnableEurekaClient @@ -16,13 +12,4 @@ public class UserServiceApplication { SpringApplication.run(UserServiceApplication.class, args); } - @Bean - CommandLineRunner run(UserService userService) { - return args -> { - StoreOwnerDto park = StoreOwnerDto.builder() - .email("test@gmail.com").password("1234").name("Park").phoneNumber("010-1234-5678") - .build(); - userService.saveStoreOwner(park); - }; - } } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/StoreOwnerRepository.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/StoreOwnerRepository.java new file mode 100644 index 0000000..920c1c6 --- /dev/null +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/StoreOwnerRepository.java @@ -0,0 +1,9 @@ +package com.justpickup.userservice.domain.user.repository; + +import com.justpickup.userservice.domain.user.entity.StoreOwner; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface StoreOwnerRepository extends JpaRepository { +} diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java index 3d09f91..692a158 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java @@ -3,7 +3,10 @@ package com.justpickup.userservice.domain.user.service; import com.justpickup.userservice.domain.user.dto.CustomerDto; import com.justpickup.userservice.domain.user.dto.StoreOwnerDto; +import java.util.List; + public interface UserService { CustomerDto findCustomerByUserId(Long userId); void saveStoreOwner(StoreOwnerDto storeOwnerDto); + List findCustomerByUserIds(List userIds); } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java index 7ac0eda..379d882 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java @@ -22,10 +22,12 @@ import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor -@Transactional(readOnly = true,propagation = Propagation.SUPPORTS) +@Transactional(readOnly = true, propagation = Propagation.SUPPORTS) @Slf4j public class UserServiceImpl implements UserService, UserDetailsService { @@ -64,7 +66,15 @@ public class UserServiceImpl implements UserService, UserDetailsService { StoreOwner storeOwner = new StoreOwner(email, encode, storeOwnerDto.getName(), storeOwnerDto.getPhoneNumber(), storeOwnerDto.getBusinessNumber()); - StoreOwner save = userRepository.save(storeOwner); + userRepository.save(storeOwner); + } + + @Override + public List findCustomerByUserIds(List userIds) { + return customerRepository.findAllById(userIds) + .stream() + .map(CustomerDto::new) + .collect(Collectors.toList()); } } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java index 1525635..9a7cfe3 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java @@ -16,6 +16,8 @@ import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import javax.validation.constraints.Email; import javax.validation.constraints.NotEmpty; +import java.util.List; +import java.util.stream.Collectors; @RestController @RequiredArgsConstructor @@ -52,7 +54,7 @@ public class UserController { @GetMapping("/customer/{userId}") - public ResponseEntity getCustomer(@Valid @PathVariable("userId") Long userId) { + public ResponseEntity getCustomer(@PathVariable("userId") Long userId) { CustomerDto customerDto = userService.findCustomerByUserId(userId); @@ -62,6 +64,19 @@ public class UserController { .body(Result.createSuccessResult(getCustomerResponse)); } + @GetMapping("/customers/{userIds}") + public ResponseEntity getCustomers(@PathVariable List userIds) { + + List customers = userService.findCustomerByUserIds(userIds); + + List responses = customers + .stream() + .map(GetCustomerResponse::new) + .collect(Collectors.toList()); + + return ResponseEntity.ok(Result.createSuccessResult(responses)); + } + @Data @NoArgsConstructor @AllArgsConstructor static class GetCustomerResponse { private Long userId; diff --git a/user-service/src/main/java/com/justpickup/userservice/global/SqlCommandLineRunner.java b/user-service/src/main/java/com/justpickup/userservice/global/SqlCommandLineRunner.java new file mode 100644 index 0000000..c9e3634 --- /dev/null +++ b/user-service/src/main/java/com/justpickup/userservice/global/SqlCommandLineRunner.java @@ -0,0 +1,33 @@ +package com.justpickup.userservice.global; + +import com.justpickup.userservice.domain.user.entity.AuthType; +import com.justpickup.userservice.domain.user.entity.Customer; +import com.justpickup.userservice.domain.user.entity.StoreOwner; +import com.justpickup.userservice.domain.user.repository.CustomerRepository; +import com.justpickup.userservice.domain.user.repository.StoreOwnerRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class SqlCommandLineRunner implements CommandLineRunner { + + private final BCryptPasswordEncoder bCryptPasswordEncoder; + private final StoreOwnerRepository storeOwnerRepository; + private final CustomerRepository customerRepository; + + @Override + public void run(String... args) throws Exception { + String encode = bCryptPasswordEncoder.encode("1234"); + + StoreOwner owner = new StoreOwner("owner@gmail.com", encode, + "점주 테스트 계정", "010-9876-5432", null); + storeOwnerRepository.save(owner); + + Customer customer = new Customer("customer@gmail.com", encode, + "고객 테스트 계정", "010-1234-5678", AuthType.NAVER); + customerRepository.save(customer); + } +} diff --git a/user-service/src/main/resources/application.yml b/user-service/src/main/resources/application.yml index 6290679..a156c8a 100644 --- a/user-service/src/main/resources/application.yml +++ b/user-service/src/main/resources/application.yml @@ -1,4 +1,4 @@ -server.port: 60000 +server.port: 0 spring: application: @@ -47,6 +47,7 @@ logging: decorator.datasource.p6spy: enable-logging: true +# 3600000 token: access-expired-time: 3600000 refresh-expired-time: 604800000 diff --git a/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java b/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java index 7f7648a..0575454 100644 --- a/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java +++ b/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java @@ -25,6 +25,10 @@ import org.springframework.restdocs.headers.HeaderDocumentation; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.willThrow; @@ -248,4 +252,51 @@ class UserControllerTest { )) ; } + + @Test + @DisplayName("[GET] 고객 리스트 조회") + void getCustomers() throws Exception { + // GIVEN + List customerIds = List.of(1L, 2L, 3L); + + given(userService.findCustomerByUserIds(customerIds)) + .willReturn(customerWillReturnDto(customerIds)); + + String customerIdsParam = customerIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + // THEN + ResultActions actions = mockMvc.perform(get("/customers/{customerIds}", customerIdsParam)); + // WHEN + actions.andExpect(status().isOk()) + .andExpect(jsonPath("code").value(Code.SUCCESS.name())) + .andExpect(jsonPath("message").value("")) + .andDo(print()) + .andDo(document("customers-get", + pathParameters( + parameterWithName("customerIds").description("회원 고유 번호들") + ), + responseFields( + fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data[*].userId").description("회원 고유 번호"), + fieldWithPath("data[*].userName").description("회원 이름"), + fieldWithPath("data[*].phoneNumber").description("회원 전화번호") + ) + )) + ; + } + + private List customerWillReturnDto(List customerIds) { + List customerDtoList = new ArrayList<>(); + for (Long customerId : customerIds) { + CustomerDto customerDto = CustomerDto.builder() + .id(customerId) + .name("이름" + customerId) + .phoneNumber("010-1234-5678") + .build(); + customerDtoList.add(customerDto); + } + return customerDtoList; + } } \ No newline at end of file