diff --git a/customer-vue/src/api/store.js b/customer-vue/src/api/store.js index 22f0b11..fedeb42 100644 --- a/customer-vue/src/api/store.js +++ b/customer-vue/src/api/store.js @@ -16,33 +16,9 @@ export default { getCategoryList(){ return axios.get(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+'/store-service/category/'); }, - putCategoryList(data){ - return axios({ - method:'put', - url:process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+'/store-service/category', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json;charset=UTF-8' - }, - data: data, - responseType:'json' - }) - }, - getItemById(itemId){ + fetchItem(itemId){ return axios.get(process.env.VUE_APP_STORE_API_URL+'/item/'+itemId) }, - saveItem(method, itemData){ - return axios({ - method:method, - url: process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+'/store-service/item', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json;charset=UTF-8' - }, - data: itemData, - responseType:'json' - }) - }, getFavoriteStore(latitude, longitude,){ const options = { params: { diff --git a/customer-vue/src/router/router.js b/customer-vue/src/router/router.js index 2737a03..9a54e2f 100644 --- a/customer-vue/src/router/router.js +++ b/customer-vue/src/router/router.js @@ -60,7 +60,7 @@ const routes = [ component: () => import('../views/LoginPage') }, { - path: "/item/:storeId/:itemId", + path: "/item/:itemId", name: 'itemDetail', component: () => import('../views/ItemDetail') }, diff --git a/customer-vue/src/views/ItemDetail.vue b/customer-vue/src/views/ItemDetail.vue index da391a2..715ee43 100644 --- a/customer-vue/src/views/ItemDetail.vue +++ b/customer-vue/src/views/ItemDetail.vue @@ -40,7 +40,7 @@ append-outer-icon="mdi-plus" prepend-icon="mdi-minus" filled - type="number" + hide-details @click:append-outer="addItemCount(1)" @click:prepend="addItemCount(-1)" /> @@ -91,7 +91,6 @@ export default { name: "ItemDetail", async beforeMount() { console.log(this.$route.params) - this.storeId = this.$route.params.storeId this.itemId = this.$route.params.itemId this.setItem.storeId = this.storeId; await this.getItemData() @@ -102,7 +101,7 @@ export default { }, otherGroup:function(){ return this.parseGroup('OTHER') - } + }, }, data: function() { return { @@ -123,12 +122,14 @@ export default { }, methods: { getItemData: async function (){ - storeApi.getItemById(this.itemId) + storeApi.fetchItem(this.itemId) .then(response=>{ console.log(response) - this.itemData = response.data.data; - this.setItem.itemId = this.itemData.id; - this.setItem.price = this.itemData.price; + this.itemData = response.data.data + this.setItem.itemId = this.itemData.id + this.setItem.price = this.itemData.price + this.storeId = this.itemData.storeId + this.setItem.storeId = this.itemData.storeId }) .catch(error=>{ console.log(error) diff --git a/customer-vue/src/views/OrderPage.vue b/customer-vue/src/views/OrderPage.vue index c5f79a3..df1c272 100644 --- a/customer-vue/src/views/OrderPage.vue +++ b/customer-vue/src/views/OrderPage.vue @@ -19,21 +19,22 @@ {{ orderItem.itemId }} + + 수량 : {{ orderItem.count }} +
{{ orderItem.itemOptionIds.join(', ')}}
- 합계 : {{ orderItem.price }} 원 + 합계 : {{ orderItem.count * orderItem.price }} 원
- - @@ -76,6 +77,7 @@ export default { itemId:Number, itemOptionIds:Array, price:Number, + count:Number, }], totalPrice:Number, diff --git a/order-service/build.gradle b/order-service/build.gradle index f4ad1b7..a692e77 100644 --- a/order-service/build.gradle +++ b/order-service/build.gradle @@ -62,6 +62,9 @@ dependencies { annotationProcessor "jakarta.persistence:jakarta.persistence-api" // java.lang.NoClassDefFoundError(javax.annotation.Generated) 발생 대응 annotationProcessor "jakarta.annotation:jakarta.annotation-api" + + + } dependencyManagement { diff --git a/order-service/src/docs/asciidoc/api-docs.adoc b/order-service/src/docs/asciidoc/api-docs.adoc index 4f6fe6d..fc03fa9 100644 --- a/order-service/src/docs/asciidoc/api-docs.adoc +++ b/order-service/src/docs/asciidoc/api-docs.adoc @@ -81,4 +81,9 @@ operation::prevOrder-get-BindException[snippets='curl-request,http-request,http- == Just Pick-up === 주문 내역 페이지 -operation::api-customer-order-history[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields'] \ No newline at end of file +operation::api-customer-order-history[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields'] + + + + +operation::add-item-to-basket[snippets='curl-request,http-request,http-response,request-headers,request-body,request-fields'] \ No newline at end of file diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderDto.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderDto.java index 4574286..45545ee 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderDto.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/OrderDto.java @@ -1,5 +1,7 @@ package com.justpickup.orderservice.domain.order.dto; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.justpickup.orderservice.domain.order.entity.Order; import com.justpickup.orderservice.domain.order.entity.OrderStatus; import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; @@ -7,12 +9,14 @@ import com.justpickup.orderservice.domain.orderItem.entity.OrderItem; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; -@Getter @NoArgsConstructor +@Getter @Setter +@NoArgsConstructor public class OrderDto { private Long id; @@ -26,6 +30,7 @@ public class OrderDto { private Long storeId; + @JsonDeserialize(using = LocalDateTimeDeserializer.class) private LocalDateTime orderTime; private Long usedPoint; 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 94c114d..aa4d9a6 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 @@ -75,7 +75,7 @@ public class Order extends BaseEntity { order.addOrderItem(orderItem); order.usedPoint = 0L; - order.orderStatus = OrderStatus.PLACED; + order.orderStatus = OrderStatus.PENDING; order.orderTime = LocalDateTime.now(); return order; } @@ -87,8 +87,13 @@ public class Order extends BaseEntity { public Order addOrderItem(OrderItem orderItem) { this.orderItems.add(orderItem); - this.orderPrice += orderItem.getPrice(); + this.orderPrice += (orderItem.getPrice()*orderItem.getCount()); orderItem.setOrder(this); return this; } + + public Order setOrderStatus(OrderStatus orderStatus){ + this.orderStatus = orderStatus; + return this; + } } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/exception/OrderException.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/exception/OrderException.java new file mode 100644 index 0000000..e03112f --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/exception/OrderException.java @@ -0,0 +1,11 @@ +package com.justpickup.orderservice.domain.order.exception; + +import com.justpickup.orderservice.global.exception.CustomException; +import org.springframework.http.HttpStatus; + +public class OrderException extends CustomException { + + public OrderException(String message) { + super(HttpStatus.CONFLICT, message); + } +} 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 5f969bf..4e847cd 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 @@ -1,11 +1,17 @@ package com.justpickup.orderservice.domain.order.service; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.justpickup.orderservice.domain.order.dto.FetchOrderDto; 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.Order; import com.justpickup.orderservice.domain.order.entity.OrderStatus; +import com.justpickup.orderservice.domain.order.exception.OrderException; import com.justpickup.orderservice.domain.order.repository.OrderRepository; import com.justpickup.orderservice.domain.order.repository.OrderRepositoryCustom; import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; @@ -17,15 +23,17 @@ import com.justpickup.orderservice.global.client.store.GetItemResponse; 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 lombok.RequiredArgsConstructor; +import lombok.*; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.SliceImpl; import org.springframework.data.support.PageableExecutionUtils; +import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -42,6 +50,7 @@ public class OrderServiceImpl implements OrderService { private final OrderRepositoryCustom orderRepositoryCustom; private final StoreClient storeClient; private final UserClient userClient; + private final KafkaTemplate kafkaTemplate; @Override public List findOrderMain(OrderSearchCondition condition, Long storeId) { @@ -124,22 +133,80 @@ public class OrderServiceImpl implements OrderService { if(optionalOrder.isPresent()){ if(optionalOrder.get().addOrderItem(orderItem) .getStoreId().equals(storeId)) - throw new RuntimeException("장바구니에 여러 카페의 메뉴를 담을수 없습니다."); + throw new OrderException("장바구니에 여러 카페의 메뉴를 담을수 없습니다."); }else{ - orderRepository.save(Order.of(userId,userCouponId,storeId,orderItemDto.getPrice(),orderItem)); + orderRepository.save(Order.of(userId,userCouponId,storeId,0L,orderItem)); } } @Override public FetchOrderDto fetchOrder(Long userId) { Order order = orderRepositoryCustom.fetchOrder(userId) - .orElseThrow(RuntimeException::new); + .orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다.")); return new FetchOrderDto(order); } @Override + @Transactional public void saveOrder(Long userId) { - + Order order = orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING) + .orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다.")) + .setOrderStatus(OrderStatus.PLACED); + try{ + send("orderPlaced",KafkaSendOrderDto.createPrimitiveField(order)); + }catch (Exception ex){ + throw new OrderException(ex.getMessage()); + } } + + + public void send(String topic, KafkaSendOrderDto kafkaSendOrderDto) throws Exception{ + ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); + String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto); + kafkaTemplate.send(topic, jsonInString); + log.info("kafka Producer sent data from the Order microservice: "+ kafkaSendOrderDto); + } + + @NoArgsConstructor + @Data + @AllArgsConstructor + @Builder + static class KafkaSendOrderDto{ + private Long id; + + private Long userId; + + private String userName; + + private Long userCouponId; + + private Long orderPrice; + + private Long storeId; + +// @JsonDeserialize(using = LocalDateTimeDeserializer.class) + private LocalDateTime orderTime; + + private Long usedPoint; + + private OrderStatus orderStatus; + + private List orderItemDtoList; + + // == 생성 메소드 == // + public static KafkaSendOrderDto createPrimitiveField(Order order) { + return KafkaSendOrderDto.builder() + .id(order.getId()) + .userId(order.getUserId()) + .userCouponId(order.getUserCouponId()) + .orderPrice(order.getOrderPrice()) + .orderTime(order.getOrderTime()) + .storeId(order.getStoreId()) + .usedPoint(order.getUsedPoint()) + .orderStatus(order.getOrderStatus()) + .build(); + } + } + } 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 3ce6811..9e6695f 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 @@ -98,7 +98,7 @@ public class OrderCustomerApiController { public ResponseEntity addItemToBasket( @RequestBody RequestItem requestItem, @RequestHeader(value = "user-id") String userId){ OrderItemDto orderItemDto = OrderItemDto.of(-1L, - requestItem.itemId, + requestItem.getItemId(), requestItem.getPrice(), requestItem.getCount(), requestItem.getItemOptionIds().stream().map(OrderItemOptionDto::new).collect(Collectors.toList())); @@ -120,17 +120,17 @@ public class OrderCustomerApiController { } @GetMapping("/orders") - public ResponseEntity getOrder(@RequestHeader(value = "user-id") String userId){ + public ResponseEntity fetchOrder(@RequestHeader(value = "user-id") String userId){ FetchOrderDto fetchOrderDto = orderService.fetchOrder(Long.parseLong(userId)); - ResponseOrder responseOrder = new ResponseOrder(fetchOrderDto); + FetchOrderResponse fetchOrderResponse = new FetchOrderResponse(fetchOrderDto); - return ResponseEntity.ok(Result.createSuccessResult(responseOrder)); + return ResponseEntity.ok(Result.createSuccessResult(fetchOrderResponse)); } @Data @NoArgsConstructor @AllArgsConstructor - public static class ResponseOrder{ + public static class FetchOrderResponse { private Long storeId; private List<_OrderItemDto> _orderItemDtos; private Long totalPrice; @@ -142,6 +142,7 @@ public class OrderCustomerApiController { private Long itemId; private List itemOptionIds; private Long price; + private Long count; public _OrderItemDto(OrderItemDto orderItemDto) { @@ -151,10 +152,11 @@ public class OrderCustomerApiController { .map(OrderItemOptionDto::getId) .collect(Collectors.toList()); this.price = orderItemDto.getPrice(); + this.count = orderItemDto.getCount(); } } - public ResponseOrder(FetchOrderDto fetchOrderDto){ + public FetchOrderResponse(FetchOrderDto fetchOrderDto){ this.storeId = fetchOrderDto.getStoreId(); this._orderItemDtos = fetchOrderDto.getOrderItemDtoList().stream() .map(_OrderItemDto::new) diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/config/KafkaConfig.java b/order-service/src/main/java/com/justpickup/orderservice/global/config/KafkaConfig.java new file mode 100644 index 0000000..f090c97 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/global/config/KafkaConfig.java @@ -0,0 +1,42 @@ +package com.justpickup.orderservice.global.config; + +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; + +import java.util.HashMap; +import java.util.Map; + +@EnableKafka +@Configuration +public class KafkaConfig { + + public KafkaConfig(@Value("${kafka.host}") String kafkaServerHost, + @Value("${kafka.port}")String kafkaServerPort) { + this.kafkaServerHost = kafkaServerHost; + this.kafkaServerPort = kafkaServerPort; + } + private final String kafkaServerHost; + private final String kafkaServerPort; + + @Bean + public ProducerFactory producerFactory(){ + Map properties = new HashMap<>(); + properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServerHost+":"+kafkaServerPort); + properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + + return new DefaultKafkaProducerFactory<>(properties); + } + + @Bean + public KafkaTemplate kafkaTemplate(){ + return new KafkaTemplate<>(producerFactory()); + } +} diff --git a/order-service/src/main/resources/application.yml b/order-service/src/main/resources/application.yml index e85d530..3a554d1 100644 --- a/order-service/src/main/resources/application.yml +++ b/order-service/src/main/resources/application.yml @@ -36,4 +36,8 @@ logging: # jpa query, parameter 로그 (p6spy) decorator.datasource.p6spy: - enable-logging: true \ No newline at end of file + enable-logging: true + +kafka: + host: 127.0.0.1 + port: 9092 \ No newline at end of file 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 5447e18..eed18ce 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 @@ -2,13 +2,16 @@ 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.FetchOrderDto; import com.justpickup.orderservice.domain.order.dto.OrderDto; import com.justpickup.orderservice.domain.order.entity.OrderStatus; import com.justpickup.orderservice.domain.order.repository.OrderRepository; import com.justpickup.orderservice.domain.order.service.OrderService; import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; +import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatchers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -17,20 +20,23 @@ import org.springframework.context.annotation.Import; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.SliceImpl; +import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import java.time.LocalDateTime; 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.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.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.requestParameters; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @@ -117,4 +123,77 @@ class OrderCustomerApiControllerTest { return new SliceImpl<>(contents, pageable, true); } + + @Test + @DisplayName("장바구니 아이템 추가_성공") + void addItemToBasket() throws Exception { + //Given + OrderCustomerApiController.RequestItem requestItem; +// OrderItemDto orderItemDto; +// FetchOrderDto fetchOrderDto; + { + //givenData + requestItem = new OrderCustomerApiController.RequestItem( + 102L, 1L, 3000L, 4L, List.of(1L, 2L, 3L, 4L, 5L) + ); + +// orderItemDto = OrderItemDto.of(-1L, +// requestItem.getItemId(), +// requestItem.getPrice(), +// requestItem.getCount(), +// requestItem.getItemOptionIds().stream().map(OrderItemOptionDto::new).collect(Collectors.toList())); + + //willReturn data + + } + //When + String body = objectMapper.writeValueAsString(requestItem); + + ResultActions actions = mockMvc.perform(post(url + "/item") + .header("user-id", "2") + .content(body) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + ); + + //Then + + actions.andExpect(status().isNoContent()) + .andDo(print()) + .andDo(document("add-item-to-basket", + requestHeaders(headerWithName("user-id").description("유저 고유번호")), + requestFields( + fieldWithPath("itemId").description("아이템 고유번호"), + fieldWithPath("storeId").description("매장 고유번호"), + fieldWithPath("price").description("아이템 가격"), + fieldWithPath("count").description("아이템 갯수"), + fieldWithPath("itemOptionIds").description("아이템 옵션들") + ) + )); + } + + @Test + @DisplayName("장바구니 정보 조회_성공") + void fetchOrder() throws Exception{ + //Given + + //When + + //Then + + } + + @Test + @DisplayName("주문 및 mq produce_성공") + void saveOrder() throws Exception{ + //Given + + //When + + //Then + + } + + + } \ No newline at end of file diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/FetchItemDto.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/FetchItemDto.java new file mode 100644 index 0000000..cf2fc09 --- /dev/null +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/FetchItemDto.java @@ -0,0 +1,46 @@ +package com.justpickup.storeservice.domain.item.dto; + +import com.justpickup.storeservice.domain.category.dto.CategoryDto; +import com.justpickup.storeservice.domain.item.entity.Item; +import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto; +import com.justpickup.storeservice.domain.store.dto.StoreDto; +import com.justpickup.storeservice.global.entity.Yn; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class FetchItemDto { + + private Long id; + + private String name; + + private Yn salesYn; + + private Long price; + + private CategoryDto categoryDto; + + private List itemOptions; + + private StoreDto storeDto; + + public FetchItemDto(Item item) { + this.id = item.getId(); + this.name = item.getName(); + this.salesYn = item.getSalesYn(); + this.price = item.getPrice(); + this.categoryDto = new CategoryDto(item.getCategory()); + this.itemOptions = item.getItemOptions().stream().map(ItemOptionDto::new).collect(Collectors.toList()); + this.storeDto = new StoreDto(item.getStore().getId(), item.getStore().getName()); + } + +} diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/ItemDto.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/ItemDto.java index 6b094d2..06bdcba 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/ItemDto.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/ItemDto.java @@ -79,9 +79,4 @@ public class ItemDto { .build(); } - // TODO: 2022/02/03 queryDsl 쿼리 생성 시 구현 필요 -// public static ItemDto createFullItemDto(Item item) { -// return null -// } - } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/repository/ItemRepositoryCustom.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/repository/ItemRepositoryCustom.java index de29b2a..bbe3fd8 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/repository/ItemRepositoryCustom.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/repository/ItemRepositoryCustom.java @@ -3,9 +3,7 @@ package com.justpickup.storeservice.domain.item.repository; import com.justpickup.storeservice.domain.category.entity.QCategory; import com.justpickup.storeservice.domain.item.entity.Item; import com.justpickup.storeservice.domain.item.entity.QItem; -import com.justpickup.storeservice.domain.itemoption.entity.ItemOption; import com.justpickup.storeservice.domain.itemoption.entity.QItemOption; -import com.justpickup.storeservice.domain.store.entity.QStore; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -22,7 +20,7 @@ public class ItemRepositoryCustom { private final JPAQueryFactory queryFactory; - public Optional findById(Long itemId){ + public Optional fetchItem(Long itemId){ Item item = queryFactory.selectFrom(QItem.item) .join(QItem.item.itemOptions, QItemOption.itemOption).fetchJoin() .join(QItem.item.category,QCategory.category).fetchJoin() 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 c1c34c8..a59e454 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 @@ -1,7 +1,7 @@ package com.justpickup.storeservice.domain.item.service; +import com.justpickup.storeservice.domain.item.dto.FetchItemDto; import com.justpickup.storeservice.domain.item.dto.ItemDto; -import com.justpickup.storeservice.domain.item.web.ItemController; import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -12,7 +12,7 @@ public interface ItemService { ItemDto findItemByItemId(Long itemId); - ItemDto findFullItemByItemId(Long itemId); + FetchItemDto fetchItem(Long itemId); Page findItemList(Long storeId,String word, Pageable pageable); 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 f0e71c5..43823b6 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 @@ -2,13 +2,13 @@ package com.justpickup.storeservice.domain.item.service; import com.justpickup.storeservice.domain.category.entity.Category; import com.justpickup.storeservice.domain.category.repository.CategoryRepository; +import com.justpickup.storeservice.domain.item.dto.FetchItemDto; import com.justpickup.storeservice.domain.item.dto.ItemDto; import com.justpickup.storeservice.domain.item.entity.Item; import com.justpickup.storeservice.domain.item.exception.NotExistItemException; import com.justpickup.storeservice.domain.item.repository.ItemRepository; import com.justpickup.storeservice.domain.item.repository.ItemRepositoryCustom; import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto; -import com.justpickup.storeservice.domain.itemoption.entity.ItemOption; import com.justpickup.storeservice.domain.itemoption.repository.ItemOptionRepository; import com.justpickup.storeservice.domain.store.entity.Store; import com.justpickup.storeservice.domain.store.repository.StoreRepository; @@ -22,7 +22,6 @@ import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; @Service @@ -48,11 +47,11 @@ public class ItemServiceImpl implements ItemService { } @Override - public ItemDto findFullItemByItemId(Long itemId) { - Item findItem = itemRepositoryCustom.findById(itemId) + public FetchItemDto fetchItem(Long itemId) { + Item findItem = itemRepositoryCustom.fetchItem(itemId) .orElseThrow(() -> new NotExistItemException("존재하지 않는 아이템 입니다.")); - return ItemDto.createWithCategoryItemDtoAndItemOption(findItem); + return new FetchItemDto(findItem); } diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemCustomerApiController.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemCustomerApiController.java index 2555d59..a28e6eb 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemCustomerApiController.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/web/ItemCustomerApiController.java @@ -1,5 +1,6 @@ package com.justpickup.storeservice.domain.item.web; +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.dto.ItemOptionDto; @@ -7,17 +8,11 @@ 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 org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; @RestController @@ -30,9 +25,9 @@ public class ItemCustomerApiController { @GetMapping("/item/{itemId}") public ResponseEntity getItem(@PathVariable("itemId") Long itemId) { - ItemDto itemByItemId = itemService.findFullItemByItemId(itemId); + FetchItemDto fetchItem = itemService.fetchItem(itemId); - GetItemResponse getItemResponse = new GetItemResponse(itemByItemId); + GetItemResponse getItemResponse = new GetItemResponse(fetchItem); return ResponseEntity.status(HttpStatus.OK) .body(Result.createSuccessResult(getItemResponse)); } @@ -45,16 +40,18 @@ public class ItemCustomerApiController { private Long price; private Long CategoryId; private List itemOptions; + private Long storeId; - public GetItemResponse(ItemDto itemDto) { - this.id = itemDto.getId(); - this.name = itemDto.getName(); - this.salesYn = itemDto.getSalesYn(); - this.price = itemDto.getPrice(); - this.CategoryId = itemDto.getCategoryDto().getId(); - this.itemOptions = itemDto.getItemOptions() + public GetItemResponse(FetchItemDto fetchItemDto) { + this.id = fetchItemDto.getId(); + this.name = fetchItemDto.getName(); + this.salesYn = fetchItemDto.getSalesYn(); + this.price = fetchItemDto.getPrice(); + this.CategoryId = fetchItemDto.getCategoryDto().getId(); + this.itemOptions = fetchItemDto.getItemOptions() .stream().map(ItemOptionResponse::new) .collect(Collectors.toList()); + this.storeId = fetchItemDto.getStoreDto().getStoreId(); } @Data 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 8da50a4..918940f 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 @@ -1,5 +1,6 @@ package com.justpickup.storeservice.domain.item.web; +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.dto.ItemOptionDto; @@ -91,9 +92,9 @@ public class ItemOwnerApiController { @GetMapping("/item/{itemId}") public ResponseEntity getItem(@PathVariable("itemId") Long itemId) { - ItemDto itemByItemId = itemService.findFullItemByItemId(itemId); + FetchItemDto fetchItemDto = itemService.fetchItem(itemId); - GetItemResponse getItemResponse = new GetItemResponse(itemByItemId); + GetItemResponse getItemResponse = new GetItemResponse(fetchItemDto); return ResponseEntity.status(HttpStatus.OK) .body(Result.createSuccessResult(getItemResponse)); } @@ -107,13 +108,13 @@ public class ItemOwnerApiController { private Long CategoryId; private List itemOptions; - public GetItemResponse(ItemDto itemDto) { - this.id = itemDto.getId(); - this.name = itemDto.getName(); - this.salesYn = itemDto.getSalesYn(); - this.price = itemDto.getPrice(); - this.CategoryId = itemDto.getCategoryDto().getId(); - this.itemOptions = itemDto.getItemOptions() + public GetItemResponse(FetchItemDto fetchItemDto) { + this.id = fetchItemDto.getId(); + this.name = fetchItemDto.getName(); + this.salesYn = fetchItemDto.getSalesYn(); + this.price = fetchItemDto.getPrice(); + this.CategoryId = fetchItemDto.getCategoryDto().getId(); + this.itemOptions = fetchItemDto.getItemOptions() .stream().map(ItemOptionResponse::new) .collect(Collectors.toList()); } 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 new file mode 100644 index 0000000..fcc49b7 --- /dev/null +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/store/dto/StoreDto.java @@ -0,0 +1,13 @@ +package com.justpickup.storeservice.domain.store.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class StoreDto { + private Long storeId; + private String storeName; +} 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 b999e7a..0b4a5e7 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 @@ -4,8 +4,8 @@ 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.exception.NotExistItemException; import com.justpickup.storeservice.domain.item.service.ItemService; import com.justpickup.storeservice.domain.itemoption.entity.OptionType; import com.justpickup.storeservice.domain.store.repository.StoreRepository; @@ -21,15 +21,12 @@ import org.springframework.context.annotation.Import; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; -import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; -import javax.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; -import java.util.function.LongSupplier; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -124,7 +121,7 @@ class ItemOwnerApiControllerTest { void getItem() throws Exception { // GIVEN long itemId = 1L; - ItemDto willReturnDto = ItemDto.builder() + FetchItemDto willReturnDto = FetchItemDto.builder() .id(1L) .salesYn(Yn.Y) .price(1500L) @@ -132,7 +129,7 @@ class ItemOwnerApiControllerTest { .itemOptions(new ArrayList<>()) .categoryDto(new CategoryDto()) .build(); - given(itemService.findFullItemByItemId(itemId)) + given(itemService.fetchItem(itemId)) .willReturn(willReturnDto); // WHEN