feat(order-service): 주문 내역 API 구현

- Slice 형식으로 주문 내역 API 구현
This commit is contained in:
bum12ark
2022-03-07 17:22:24 +09:00
parent 6e289bb231
commit 9c538d0b3a
6 changed files with 302 additions and 4 deletions

View File

@@ -24,6 +24,8 @@ public class OrderDto {
private Long orderPrice; private Long orderPrice;
private Long storeId;
private LocalDateTime orderTime; private LocalDateTime orderTime;
private Long usedPoint; private Long usedPoint;
@@ -35,13 +37,14 @@ public class OrderDto {
private List<OrderItemDto> orderItemDtoList; private List<OrderItemDto> orderItemDtoList;
@Builder @Builder
public OrderDto(Long id, Long userId, Long userCouponId, Long orderPrice, LocalDateTime orderTime, public OrderDto(Long id, Long userId, Long userCouponId, Long orderPrice, LocalDateTime orderTime, Long storeId,
Long usedPoint, OrderStatus orderStatus, List<OrderItemDto> orderItemDtoList) { Long usedPoint, OrderStatus orderStatus, List<OrderItemDto> orderItemDtoList) {
this.id = id; this.id = id;
this.userId = userId; this.userId = userId;
this.userCouponId = userCouponId; this.userCouponId = userCouponId;
this.orderPrice = orderPrice; this.orderPrice = orderPrice;
this.orderTime = orderTime; this.orderTime = orderTime;
this.storeId = storeId;
this.usedPoint = usedPoint; this.usedPoint = usedPoint;
this.orderStatus = orderStatus; this.orderStatus = orderStatus;
this.orderItemDtoList = orderItemDtoList; this.orderItemDtoList = orderItemDtoList;
@@ -55,6 +58,7 @@ public class OrderDto {
.userCouponId(order.getUserCouponId()) .userCouponId(order.getUserCouponId())
.orderPrice(order.getOrderPrice()) .orderPrice(order.getOrderPrice())
.orderTime(order.getOrderTime()) .orderTime(order.getOrderTime())
.storeId(order.getStoreId())
.usedPoint(order.getUsedPoint()) .usedPoint(order.getUsedPoint())
.orderStatus(order.getOrderStatus()) .orderStatus(order.getOrderStatus())
.build(); .build();
@@ -72,6 +76,7 @@ public class OrderDto {
.userCouponId(order.getUserCouponId()) .userCouponId(order.getUserCouponId())
.orderPrice(order.getOrderPrice()) .orderPrice(order.getOrderPrice())
.orderTime(order.getOrderTime()) .orderTime(order.getOrderTime())
.storeId(order.getStoreId())
.usedPoint(order.getUsedPoint()) .usedPoint(order.getUsedPoint())
.orderStatus(order.getOrderStatus()) .orderStatus(order.getOrderStatus())
.orderItemDtoList(orderItemDtoList) .orderItemDtoList(orderItemDtoList)

View File

@@ -8,6 +8,7 @@ import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.support.PageableExecutionUtils; import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@@ -80,4 +81,27 @@ public class OrderRepositoryCustom {
return PageableExecutionUtils.getPage(orders, pageable, () -> count); return PageableExecutionUtils.getPage(orders, pageable, () -> count);
} }
// Customer History
public SliceImpl<Order> findOrderHistory(Pageable pageable, Long userId) {
List<Order> contents = queryFactory
.selectFrom(order)
.join(order.transaction).fetchJoin()
.where(
order.userId.eq(userId)
)
.orderBy(order.orderTime.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize() + 1)
.distinct()
.fetch();
boolean hasNext = false;
if (contents.size() > pageable.getPageSize()) {
contents.remove(pageable.getPageSize());
hasNext = true;
}
return new SliceImpl<>(contents, pageable, hasNext);
}
} }

View File

@@ -5,11 +5,12 @@ import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch; import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.SliceImpl;
import java.util.List; import java.util.List;
public interface OrderService { public interface OrderService {
List<OrderDto> findOrderMain(OrderSearchCondition condition, Long storeId); List<OrderDto> findOrderMain(OrderSearchCondition condition, Long storeId);
Page<OrderDto> findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long storeId); Page<OrderDto> findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long storeId);
SliceImpl<OrderDto> findOrderHistory(Pageable pageable, Long userId);
} }

View File

@@ -14,6 +14,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.support.PageableExecutionUtils; import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -42,7 +43,7 @@ public class OrderServiceImpl implements OrderService {
.collect(Collectors.toList()); .collect(Collectors.toList());
// 사용자명 및 아이템 이름 가져오기 // 사용자명 및 아이템 이름 가져오기
getUserNameAndItemName(orderDtoList); // getUserNameAndItemName(orderDtoList);
return orderDtoList; return orderDtoList;
} }
@@ -57,11 +58,25 @@ public class OrderServiceImpl implements OrderService {
.collect(Collectors.toList()); .collect(Collectors.toList());
// 사용자명 및 아이템 이름 가져오기 // 사용자명 및 아이템 이름 가져오기
getUserNameAndItemName(orderDtoList); // getUserNameAndItemName(orderDtoList);
return PageableExecutionUtils.getPage(orderDtoList, pageable, orderPage::getTotalElements); return PageableExecutionUtils.getPage(orderDtoList, pageable, orderPage::getTotalElements);
} }
@Override
public SliceImpl<OrderDto> findOrderHistory(Pageable pageable, Long userId) {
SliceImpl<Order> orderHistory = orderRepositoryCustom.findOrderHistory(pageable, userId);
List<OrderDto> contents = orderHistory.getContent()
.stream()
.map(OrderDto::createFullField)
.collect(Collectors.toList());
// TODO: 2022/03/07 Feign Client 통신
return new SliceImpl<>(contents, pageable, orderHistory.hasNext());
}
private void getUserNameAndItemName(List<OrderDto> orderDtoList) { private void getUserNameAndItemName(List<OrderDto> orderDtoList) {
orderDtoList.forEach(orderDto -> { orderDtoList.forEach(orderDto -> {
GetCustomerResponse getCustomerResponse = GetCustomerResponse getCustomerResponse =

View File

@@ -0,0 +1,92 @@
package com.justpickup.orderservice.domain.order.web;
import com.justpickup.orderservice.domain.order.dto.OrderDto;
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
import com.justpickup.orderservice.domain.order.service.OrderService;
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
import com.justpickup.orderservice.global.dto.Result;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
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;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/customer/order")
@RequiredArgsConstructor
@Slf4j
public class OrderCustomerApiController {
private final OrderService orderService;
@GetMapping("/history")
public ResponseEntity<Result> getOrderHistory(@RequestHeader(value = "user-id") String userHeader,
@PageableDefault(page = 0, size = 3) Pageable pageable) {
Long userId = Long.parseLong(userHeader);
SliceImpl<OrderDto> orderHistory = orderService.findOrderHistory(pageable, userId);
OrderHistoryResponse orderHistoryResponse =
new OrderHistoryResponse(orderHistory.getContent(), orderHistory.hasNext());
return ResponseEntity.status(HttpStatus.OK)
.body(Result.createSuccessResult(orderHistoryResponse));
}
@Data @NoArgsConstructor
static class OrderHistoryResponse {
private List<_Order> orders;
private boolean hasNext;
public OrderHistoryResponse(List<OrderDto> orders, boolean hasNext) {
this.orders = orders.stream().map(_Order::new).collect(Collectors.toList());
this.hasNext = hasNext;
}
@Data
static class _Order {
private Long orderId;
private String orderTime;
private OrderStatus orderStatus;
private String storeName;
private Long orderPrice;
private List<_OrderItem> orderItems;
public _Order(OrderDto orderDto) {
this.orderId = orderDto.getId();
this.orderTime = orderDto.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()
.stream()
.map(_OrderItem::new)
.collect(Collectors.toList());
}
}
@Data
static class _OrderItem {
private Long orderItemId;
private String orderItemName;
public _OrderItem(OrderItemDto orderItemDto) {
this.orderItemId = orderItemDto.getItemId();
this.orderItemName = orderItemDto.getItemId().toString();
}
}
}
}

View File

@@ -0,0 +1,161 @@
package com.justpickup.orderservice.domain.order.web;
import com.justpickup.orderservice.domain.order.dto.OrderDto;
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.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;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/owner/order")
@RequiredArgsConstructor
@Slf4j
public class OrderOwnerApiController {
private final OrderService orderService;
private final PrevOrderSearchValidator prevOrderSearchValidator;
@GetMapping("/order-main")
public ResponseEntity<Result> orderMain(@Valid OrderSearchCondition condition) {
Long userId = 1L;
Long storeId = 1L;
List<OrderDto> orderDto = orderService.findOrderMain(condition, storeId);
List<OrderMainResponse> orderMainResponses = orderDto.stream()
.map(OrderMainResponse::new)
.collect(Collectors.toList());
return ResponseEntity.status(HttpStatus.OK)
.body(Result.createSuccessResult(orderMainResponses));
}
@Data
@NoArgsConstructor
@AllArgsConstructor
static class OrderMainResponse {
private Long orderId;
private Long userId;
private String userName;
private List<OrderItemResponse> orderItemResponses;
private OrderStatus orderStatus;
private String orderTime;
public OrderMainResponse(OrderDto orderDto) {
List<OrderItemResponse> orderItemDtoList = orderDto.getOrderItemDtoList()
.stream()
.map(OrderItemResponse::new)
.collect(Collectors.toList());
this.orderId = orderDto.getId();
this.userId = orderDto.getUserId();
this.userName = orderDto.getUserName();
this.orderItemResponses = orderItemDtoList;
this.orderStatus = orderDto.getOrderStatus();
this.orderTime = orderDto.getOrderTime()
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
}
@Data
static class OrderItemResponse {
private Long orderItemId;
private Long itemId;
private String itemName;
public OrderItemResponse(OrderItemDto orderItemDto) {
this.orderItemId = orderItemDto.getId();
this.itemId = orderItemDto.getItemId();
this.itemName = orderItemDto.getItemName();
}
}
@GetMapping("/prev-order")
public ResponseEntity<Result> findPrevOrder(@Valid PrevOrderSearch prevOrderSearch,
@PageableDefault(page = 0, size = 10) Pageable pageable,
BindingResult bindingResult) throws BindException {
// validation
if (bindingResult.hasErrors()) throw new BindException(bindingResult);
prevOrderSearchValidator.validate(prevOrderSearch, bindingResult);
if (bindingResult.hasErrors()) throw new BindException(bindingResult);
// get data
Page<OrderDto> prevOrderMain = orderService.findPrevOrderMain(prevOrderSearch, pageable, 1L);
// format data
ResponsePrevOrder responsePrevOrder =
new ResponsePrevOrder(prevOrderMain.getContent(), prevOrderMain.getNumber(), prevOrderMain.getTotalPages());
return ResponseEntity.ok(Result.createSuccessResult(responsePrevOrder));
}
@Data @AllArgsConstructor @NoArgsConstructor
static class ResponsePrevOrder {
private List<OrderVo> orders;
private Page page;
public ResponsePrevOrder(List<OrderDto> orderDtoList, int startPage, int totalPage) {
orders = orderDtoList.stream().map(OrderVo::new).collect(Collectors.toList());
page = new Page(startPage, totalPage);
}
@Data
static class OrderVo {
private Long orderId;
private OrderStatus orderStatus;
private String orderTime;
private Long orderPrice;
private String userName;
private List<OrderItemVo> 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(Collectors.toList());
}
}
@Data
static class OrderItemVo {
private Long orderItemId;
private String orderItemName;
public OrderItemVo(OrderItemDto orderItemDto) {
this.orderItemId = orderItemDto.getId();
this.orderItemName = orderItemDto.getItemName();
}
}
@Data @AllArgsConstructor
static class Page {
int startPage;
int totalPage;
}
}
}