From 47491f32454d6fb2cf15c8fb0448c07150c728fd Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Mon, 14 Mar 2022 21:16:28 +0900 Subject: [PATCH 01/10] =?UTF-8?q?feat(order-service):=20order-service=20fe?= =?UTF-8?q?ign=20=ED=86=B5=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - store-service와 feign 통신 코드 작성 --- .../src/main/resources/application.yml | 4 +- customer-vue/src/views/OrderPage.vue | 43 +++++------ .../src/main/resources/application.yml | 4 - .../domain/order/dto/FetchOrderDto.java | 46 +++++++---- .../domain/order/entity/Order.java | 5 ++ .../domain/order/entity/OrderListener.java | 29 ++++++- .../order/web/OrderCustomerApiController.java | 45 +---------- .../global/client/store/GetItemResponse.java | 26 ++++++- .../global/config/KafkaConfig.java | 1 + .../src/main/resources/application.yml | 4 +- .../domain/item/dto/GetItemDto.java | 57 ++++++++++++++ .../item/repository/ItemRepositoryCustom.java | 26 +++++-- .../domain/item/service/ItemService.java | 2 + .../domain/item/service/ItemServiceImpl.java | 10 +++ .../item/web/ItemCustomerApiController.java | 10 ++- .../global/SqlCommandLineRunner.java | 2 +- .../src/main/resources/application.yml | 13 ++-- .../src/main/resources/data/data.sql | 77 +++++++++++++++++++ .../src/main/resources/application.yml | 5 +- 19 files changed, 298 insertions(+), 111 deletions(-) create mode 100644 store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/GetItemDto.java create mode 100644 store-service/src/main/resources/data/data.sql diff --git a/customer-apigateway-service/src/main/resources/application.yml b/customer-apigateway-service/src/main/resources/application.yml index 26d7045..2f7e934 100644 --- a/customer-apigateway-service/src/main/resources/application.yml +++ b/customer-apigateway-service/src/main/resources/application.yml @@ -46,7 +46,7 @@ spring: allow-credentials: true routes: - id: order-service - uri: lb://ORDER-SERVCIE + uri: lb://ORDER-SERVICE predicates: - Path=/order-service/** filters: @@ -54,7 +54,7 @@ spring: - RewritePath=/order-service/(?.*),/$\{segment} - id: store-service - uri: lb://STORE-SERVCIE + uri: lb://STORE-SERVICE predicates: - Path=/store-service/** filters: diff --git a/customer-vue/src/views/OrderPage.vue b/customer-vue/src/views/OrderPage.vue index df1c272..27daf17 100644 --- a/customer-vue/src/views/OrderPage.vue +++ b/customer-vue/src/views/OrderPage.vue @@ -2,12 +2,12 @@
-
{{ orderData.storeId }}
+
{{ orderData.storeName }}
- {{ orderItem.itemId }} + {{ orderItem.itemName }} 수량 : {{ orderItem.count }} -
- {{ orderItem.itemOptionIds.join(', ')}} +
+ {{ orderItem.orderItemOptionDtoList ? + orderItem.orderItemOptionDtoList.map(x=>x.name).join(', ') + : null}}
합계 : {{ orderItem.count * orderItem.price }} 원 @@ -46,7 +48,7 @@ -
합계 : {{orderData.totalPrice}} 원
+
합계 : {{orderData.orderPrice}} 원
{ + console.log(response) this.orderData=response.data.data }) .catch(error=>{ - console.log(error) - this.$router.replace("/") + console.log(error.response) + + // this.$router.replace("/") }) }, } diff --git a/notification-service/src/main/resources/application.yml b/notification-service/src/main/resources/application.yml index 043b2c3..27f02e2 100644 --- a/notification-service/src/main/resources/application.yml +++ b/notification-service/src/main/resources/application.yml @@ -40,7 +40,3 @@ logging: # jpa query, parameter 로그 (p6spy) decorator.datasource.p6spy: enable-logging: true - -#feign key -token: - feign: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmZWlnbiIsImV4cCI6MTE2NDY5NzY4NzAsImlhdCI6MTY0Njk3Njg3MH0.5x4Nx7oMnpF0_kZpbZsiB1u9eEbQ4IKIhJlEsa3D22cjZjvTHKz57GCz0sgXb_olhSNIVv9xF41A29-XYiFeBQ \ No newline at end of file diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/FetchOrderDto.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/FetchOrderDto.java index 70f42de..ac4df70 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/FetchOrderDto.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/FetchOrderDto.java @@ -1,18 +1,15 @@ package com.justpickup.orderservice.domain.order.dto; -import com.justpickup.orderservice.domain.order.entity.Order; -import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; -import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; +import com.justpickup.orderservice.domain.orderItem.entity.OrderItem; +import com.justpickup.orderservice.global.client.store.GetItemResponse; +import lombok.*; import java.util.List; -import java.util.stream.Collectors; @Getter @NoArgsConstructor @AllArgsConstructor +@Builder public class FetchOrderDto { private Long id; @@ -20,19 +17,36 @@ public class FetchOrderDto { private Long orderPrice; - private Long storeId; + private String storeName; private List orderItemDtoList; + @Getter + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class OrderItemDto{ - public FetchOrderDto(Order order) { - this.id = order.getId(); - this.userId = order.getUserId(); - this.orderPrice = order.getOrderPrice(); - this.storeId = order.getStoreId(); - this.orderItemDtoList = order.getOrderItems().stream() - .map(orderItem -> OrderItemDto.of(orderItem.getId(),orderItem.getItemId(),orderItem.getPrice(),orderItem.getCount(),orderItem.getOrderItemOptions().stream().map(orderItemOption -> new OrderItemOptionDto(orderItemOption.getId())).collect(Collectors.toList()))) - .collect(Collectors.toList()); + private Long id; + + private Long itemId; + + private String itemName; + + private List orderItemOptionDtoList; + + private Long price; + + private Long count; + + public OrderItemDto(GetItemResponse getItemResponse, OrderItem orderItem) { + this.id = orderItem.getId(); + this.itemId = getItemResponse.getId(); + this.itemName = getItemResponse.getName(); + this.orderItemOptionDtoList = getItemResponse.getItemOptions(); + this.price = orderItem.getPrice(); + this.count = orderItem.getCount(); + } } } 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 173b20d..82c58a4 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 @@ -16,6 +16,7 @@ import java.util.List; @Entity @Table(name = "orders") @Getter +@EntityListeners(value = {OrderListener.class}) @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Order extends BaseEntity { @@ -108,4 +109,8 @@ public class Order extends BaseEntity { public void reject() { this.orderStatus = OrderStatus.REJECT; } + + public void fail() { + this.orderStatus = OrderStatus.FAIL; + } } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java index 14fcdf7..7876cff 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java @@ -1,18 +1,45 @@ package com.justpickup.orderservice.domain.order.entity; +import com.justpickup.orderservice.domain.order.exception.OrderException; +import com.justpickup.orderservice.domain.order.service.OrderSender; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import javax.persistence.EntityManager; import javax.persistence.PostUpdate; @Slf4j +@NoArgsConstructor public class OrderListener { + @Autowired + @Lazy + private OrderSender orderSender; + @PostUpdate - private void postUpdate(Order order) { + @Transactional(propagation = Propagation.REQUIRES_NEW) + void postUpdate(Order order) { OrderStatus orderStatus = order.getOrderStatus(); if (orderStatus == OrderStatus.ORDER) { // TODO: 2022/03/10 Kafka 알림 전송 log.info("[OrderListener] {}", OrderStatus.ORDER.name()); + + try{ + orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order)); + }catch (Exception ex){ + + order.fail(); + + throw new OrderException(ex.getMessage()); + } + + } else if (orderStatus == OrderStatus.PLACED) { log.info("[OrderListener] {}", OrderStatus.PLACED.name()); } 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 9e6695f..539a553 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 @@ -116,55 +116,12 @@ public class OrderCustomerApiController { private Long price; private Long count; private List itemOptionIds ; - } @GetMapping("/orders") public ResponseEntity fetchOrder(@RequestHeader(value = "user-id") String userId){ FetchOrderDto fetchOrderDto = orderService.fetchOrder(Long.parseLong(userId)); - FetchOrderResponse fetchOrderResponse = new FetchOrderResponse(fetchOrderDto); - - return ResponseEntity.ok(Result.createSuccessResult(fetchOrderResponse)); - } - - @Data - @NoArgsConstructor - @AllArgsConstructor - public static class FetchOrderResponse { - private Long storeId; - private List<_OrderItemDto> _orderItemDtos; - private Long totalPrice; - - @Data - @NoArgsConstructor - @AllArgsConstructor - public static class _OrderItemDto { - private Long itemId; - private List itemOptionIds; - private Long price; - private Long count; - - public _OrderItemDto(OrderItemDto orderItemDto) { - - this.itemId = orderItemDto.getItemId(); - this.itemOptionIds = orderItemDto.getOrderItemOptionDtoList() - .stream() - .map(OrderItemOptionDto::getId) - .collect(Collectors.toList()); - this.price = orderItemDto.getPrice(); - this.count = orderItemDto.getCount(); - } - } - - public FetchOrderResponse(FetchOrderDto fetchOrderDto){ - this.storeId = fetchOrderDto.getStoreId(); - this._orderItemDtos = fetchOrderDto.getOrderItemDtoList().stream() - .map(_OrderItemDto::new) - .collect(Collectors.toList()); - this.totalPrice = fetchOrderDto.getOrderPrice(); - - } - + return ResponseEntity.ok(Result.createSuccessResult(fetchOrderDto)); } @PostMapping("/orders") diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemResponse.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemResponse.java index a750e95..a4d2c56 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemResponse.java +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetItemResponse.java @@ -1,12 +1,34 @@ package com.justpickup.orderservice.global.client.store; import com.justpickup.orderservice.global.entity.Yn; -import lombok.Data; +import lombok.*; -@Data +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@NoArgsConstructor +@AllArgsConstructor public class GetItemResponse { private Long id; + private String name; + private Yn salesYn; + private Long price; + + private List itemOptions; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class ItemOptionDto{ + private Long id; + + private OptionType optionType; + + private String name; + + } } 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 index f090c97..a1e6a49 100644 --- 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 @@ -31,6 +31,7 @@ public class KafkaConfig { 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); +// properties.put(ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, 5000); return new DefaultKafkaProducerFactory<>(properties); } diff --git a/owner-apigateway-service/src/main/resources/application.yml b/owner-apigateway-service/src/main/resources/application.yml index 4cc49c7..e97254b 100644 --- a/owner-apigateway-service/src/main/resources/application.yml +++ b/owner-apigateway-service/src/main/resources/application.yml @@ -43,7 +43,7 @@ spring: allow-credentials: true routes: - id: order-service - uri: lb://ORDER-SERVCIE + uri: lb://ORDER-SERVICE predicates: - Path=/order-service/** filters: @@ -51,7 +51,7 @@ spring: - RewritePath=/order-service/(?.*),/$\{segment} - id: store-service - uri: lb://STORE-SERVCIE + uri: lb://STORE-SERVICE predicates: - Path=/store-service/** filters: diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/GetItemDto.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/GetItemDto.java new file mode 100644 index 0000000..a669ad8 --- /dev/null +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/GetItemDto.java @@ -0,0 +1,57 @@ +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.itemoption.entity.ItemOption; +import com.justpickup.storeservice.domain.itemoption.entity.OptionType; +import com.justpickup.storeservice.global.entity.Yn; +import lombok.*; + +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class GetItemDto { + + private Long id; + + private String name; + + private Yn salesYn; + + private Long price; + + private List itemOptions; + + public GetItemDto(Item item) { + this.id = item.getId(); + this.name = item.getName(); + this.salesYn = item.getSalesYn(); + this.price = item.getPrice(); + this.itemOptions = item.getItemOptions().stream(). + map(ItemOptionDto::new) + .collect(Collectors.toList()); + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + @Builder + static class ItemOptionDto{ + private Long id; + + private OptionType optionType; + + private String name; + + public ItemOptionDto (ItemOption itemOption){ + this.id = itemOption.getId(); + this.optionType = itemOption.getOptionType(); + this.name = itemOption.getName(); + } + } +} 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 46d14ca..300a870 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 @@ -1,9 +1,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.QItemOption; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -14,6 +12,10 @@ import org.springframework.stereotype.Repository; import java.util.List; import java.util.Optional; +import static com.justpickup.storeservice.domain.category.entity.QCategory.category; +import static com.justpickup.storeservice.domain.item.entity.QItem.item; +import static com.justpickup.storeservice.domain.itemoption.entity.QItemOption.itemOption; + @Repository @RequiredArgsConstructor public class ItemRepositoryCustom { @@ -21,15 +23,25 @@ public class ItemRepositoryCustom { private final JPAQueryFactory queryFactory; 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() - .where(QItem.item.id.eq(itemId)) + Item fetchItem = queryFactory.selectFrom(item) + .join(item.itemOptions, itemOption).fetchJoin() + .join(item.category,category).fetchJoin() + .where(item.id.eq(itemId)) .fetchOne(); - return Optional.ofNullable(item); + return Optional.ofNullable(fetchItem); } + public List getItemAndItemOptions(List itemIds){ + + return queryFactory.selectFrom(item) + .join(item.itemOptions,itemOption).fetchJoin() + .where(item.id.in(itemIds)) + .fetch(); + + } + + public Page findItem(Long userId,String word, Pageable pageable){ //count 가져오기 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 21c3666..277dcad 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,6 +1,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.itemoption.dto.ItemOptionDto; import org.springframework.data.domain.Page; @@ -12,6 +13,7 @@ public interface ItemService { ItemDto findItemByItemId(Long itemId); + List getItemAndItemOptions(List itemIds); FetchItemDto fetchItem(Long itemId); Page findItemList(Long userId,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 23e8528..105dc62 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 @@ -3,6 +3,7 @@ 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.GetItemDto; import com.justpickup.storeservice.domain.item.dto.ItemDto; import com.justpickup.storeservice.domain.item.entity.Item; import com.justpickup.storeservice.domain.item.exception.NotExistItemException; @@ -46,6 +47,15 @@ public class ItemServiceImpl implements ItemService { return ItemDto.createWithCategoryItemDtoAndItemOption(findItem); } + @Override + public List getItemAndItemOptions(List itemIds) { + + List items = itemRepositoryCustom.getItemAndItemOptions(itemIds); + return items.stream() + .map(GetItemDto::new) + .collect(Collectors.toList()); + } + @Override public FetchItemDto fetchItem(Long itemId) { Item findItem = itemRepositoryCustom.fetchItem(itemId) 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 bf7cb5a..65f313b 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,6 +1,7 @@ package com.justpickup.storeservice.domain.item.web; 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.service.ItemService; import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto; @@ -22,9 +23,16 @@ public class ItemCustomerApiController { private final ItemService itemService; + @GetMapping("/items/{itemId}") + public ResponseEntity getItemAndItemOptions(@PathVariable("itemId") List itemId) { + List itemList = itemService.getItemAndItemOptions(itemId); + + return ResponseEntity.status(HttpStatus.OK) + .body(Result.createSuccessResult(itemList)); + } @GetMapping("/item/{itemId}") - public ResponseEntity getItem(@PathVariable("itemId") Long itemId) { + public ResponseEntity fetchItem(@PathVariable("itemId") Long itemId) { FetchItemDto fetchItem = itemService.fetchItem(itemId); GetItemResponse getItemResponse = new GetItemResponse(fetchItem); 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 9440a00..2e0fedb 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 @@ -19,7 +19,7 @@ import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; -@Component +//@Component @RequiredArgsConstructor public class SqlCommandLineRunner implements CommandLineRunner { diff --git a/store-service/src/main/resources/application.yml b/store-service/src/main/resources/application.yml index 677a294..aa4cc03 100644 --- a/store-service/src/main/resources/application.yml +++ b/store-service/src/main/resources/application.yml @@ -3,7 +3,7 @@ server: spring: application: - name: store-servcie + name: store-service config: import: optional:configserver:http://127.0.0.1:8888 cloud: @@ -18,6 +18,8 @@ spring: properties: hibernate: default_batch_fetch_size: 1000 + defer-datasource-initialization: true + datasource: driver-class-name: org.postgresql.Driver @@ -25,6 +27,11 @@ spring: username: postgres password: admin + sql: + init: + data-locations: classpath:data/data.sql + mode: always + eureka: client: @@ -42,7 +49,3 @@ logging: # jpa query, parameter 로그 (p6spy) decorator.datasource.p6spy: enable-logging: true - -#feign key -token: - feign: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmZWlnbiIsImV4cCI6MTE2NDY5NzY4NzAsImlhdCI6MTY0Njk3Njg3MH0.5x4Nx7oMnpF0_kZpbZsiB1u9eEbQ4IKIhJlEsa3D22cjZjvTHKz57GCz0sgXb_olhSNIVv9xF41A29-XYiFeBQ \ No newline at end of file diff --git a/store-service/src/main/resources/data/data.sql b/store-service/src/main/resources/data/data.sql new file mode 100644 index 0000000..e38faa8 --- /dev/null +++ b/store-service/src/main/resources/data/data.sql @@ -0,0 +1,77 @@ +-- store +INSERT INTO public.store( + store_id, created_at, created_by, last_modified_at, last_modified_by, city, street, zipcode, business_end_time, business_start_time, phone_number, photo_name, photo_path, user_id, map_id) +VALUES (1, now(), 1, now(), 1, '서울시', '광화문로', '123-456', to_timestamp('20:00:00', 'HH24:MI:SS'), to_timestamp('09:00:00', 'HH24:MI:SS'), '010-9418-1307', '사진명1', '/Users/sangbum/Desktop', 1, null); + + +-- category +INSERT INTO public.category( + category_id, created_at, created_by, last_modified_at, last_modified_by, name, orders, store_id) +VALUES (10, now(), 1, now(), 1, '카테고리1', 0, 1); + +INSERT INTO public.category( + category_id, created_at, created_by, last_modified_at, last_modified_by, name, orders, store_id) +VALUES (11, now(), 1, now(), 1, '카테고리2', 1, 1); + +-- item +INSERT INTO public.item( + item_id, created_at, created_by, last_modified_at, last_modified_by, name, photo_name, photo_path, price, sales_yn, category_id, store_id) +VALUES (100, now(), 1, now(), 1, '아이템1', '아이템_사진명', '/Users/sangbum/Desktop', 1000, 'Y', 10, 1); + +INSERT INTO public.item( + item_id, created_at, created_by, last_modified_at, last_modified_by, name, photo_name, photo_path, price, sales_yn, category_id, store_id) +VALUES (101, now(), 1, now(), 1, '아이템2', '아이템_사진명2', '/Users/sangbum/Desktop', 2000, 'Y', 10, 1); + +INSERT INTO public.item( + item_id, created_at, created_by, last_modified_at, last_modified_by, name, photo_name, photo_path, price, sales_yn, category_id, store_id) +VALUES (102, now(), 1, now(), 1, '아이템3', '아이템_사진명3', '/Users/sangbum/Desktop', 3000, 'Y', 11, 1); + + +-- item option +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1000, now(), 1, now(), 1, 'ICE', 'REQUIRED', 100); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1001, now(), 1, now(), 1, 'HOT', 'REQUIRED', 100); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1002, now(), 1, now(), 1, '샷 추가', 'OTHER', 100); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1003, now(), 1, now(), 1, '투샷 추카', 'OTHER', 100); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1004, now(), 1, now(), 1, 'ICE', 'REQUIRED', 101); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1005, now(), 1, now(), 1, 'HOT', 'REQUIRED', 101); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1006, now(), 1, now(), 1, '샷 추가', 'OTHER', 101); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1007, now(), 1, now(), 1, '투샷 추카', 'OTHER', 101); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1008, now(), 1, now(), 1, 'ICE', 'REQUIRED', 102); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1009, now(), 1, now(), 1, 'HOT', 'REQUIRED', 102); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1010, now(), 1, now(), 1, '샷 추가', 'OTHER', 102); + +INSERT INTO public.item_option( + item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id) +VALUES (1011, now(), 1, now(), 1, '투샷 추카', 'OTHER', 102); \ No newline at end of file diff --git a/user-service/src/main/resources/application.yml b/user-service/src/main/resources/application.yml index 3e51385..6290679 100644 --- a/user-service/src/main/resources/application.yml +++ b/user-service/src/main/resources/application.yml @@ -50,7 +50,6 @@ decorator.datasource.p6spy: token: access-expired-time: 3600000 refresh-expired-time: 604800000 - secret: my-secret + secret: $2a$10$q42lY7Y18xqrFt1qbODZIO4OMTeOxnrCe7tF3n9bazJinVE7VH5Pi refresh-token-name: refresh-token - access-token-name: access-token - fegin: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmZWlnbiIsImV4cCI6MTE2NDY5NzY4NzAsImlhdCI6MTY0Njk3Njg3MH0.5x4Nx7oMnpF0_kZpbZsiB1u9eEbQ4IKIhJlEsa3D22cjZjvTHKz57GCz0sgXb_olhSNIVv9xF41A29-XYiFeBQ \ No newline at end of file + access-token-name: access-token \ No newline at end of file From a811d122fc05d30f8e1bb8ec9f74333ba7bc7b91 Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Tue, 15 Mar 2022 11:40:08 +0900 Subject: [PATCH 02/10] refactor(order-service): order-service listener MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - save order시 jpa의 listener을 이용하여 kafka 전송 --- .../domain/order/entity/OrderListener.java | 10 ---- .../domain/order/service/OrderSender.java | 2 +- .../domain/order/service/OrderService.java | 6 +-- .../order/service/OrderServiceImpl.java | 54 +++++++++++++++---- .../client/store/GetStoreReseponse.java | 14 +++++ .../global/client/store/OptionType.java | 5 ++ .../global/client/store/StoreClient.java | 12 +++-- .../src/main/resources/application.yml | 6 +-- 8 files changed, 75 insertions(+), 34 deletions(-) create mode 100644 order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetStoreReseponse.java create mode 100644 order-service/src/main/java/com/justpickup/orderservice/global/client/store/OptionType.java diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java index 7876cff..2f58647 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java @@ -3,15 +3,10 @@ package com.justpickup.orderservice.domain.order.entity; import com.justpickup.orderservice.domain.order.exception.OrderException; import com.justpickup.orderservice.domain.order.service.OrderSender; import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; -import javax.persistence.EntityManager; import javax.persistence.PostUpdate; @Slf4j @@ -23,23 +18,18 @@ public class OrderListener { private OrderSender orderSender; @PostUpdate - @Transactional(propagation = Propagation.REQUIRES_NEW) void postUpdate(Order order) { OrderStatus orderStatus = order.getOrderStatus(); if (orderStatus == OrderStatus.ORDER) { // TODO: 2022/03/10 Kafka 알림 전송 log.info("[OrderListener] {}", OrderStatus.ORDER.name()); - try{ orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order)); }catch (Exception ex){ - order.fail(); - throw new OrderException(ex.getMessage()); } - } else if (orderStatus == OrderStatus.PLACED) { log.info("[OrderListener] {}", OrderStatus.PLACED.name()); } diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderSender.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderSender.java index cba4a71..2d55071 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderSender.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderSender.java @@ -31,7 +31,7 @@ public class OrderSender { @Data @AllArgsConstructor @Builder - static class KafkaSendOrderDto{ + public static class KafkaSendOrderDto{ private Long id; private Long 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 a2f0577..647f5ad 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 @@ -1,10 +1,6 @@ package com.justpickup.orderservice.domain.order.service; -import com.justpickup.orderservice.domain.order.dto.FetchOrderDto; -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.PrevOrderSearch; +import com.justpickup.orderservice.domain.order.dto.*; import com.justpickup.orderservice.domain.order.entity.OrderStatus; import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; import org.springframework.data.domain.Page; 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 7211c12..2bfd781 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,9 @@ 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.GetItemResponse; +import com.justpickup.orderservice.global.client.store.GetStoreReseponse; +import com.justpickup.orderservice.global.client.store.StoreClient; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -19,7 +22,10 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; 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; @@ -31,7 +37,8 @@ public class OrderServiceImpl implements OrderService { private final OrderRepository orderRepository; private final OrderRepositoryCustom orderRepositoryCustom; - private final OrderSender orderSender; + + private final StoreClient storeClient; @Override public OrderMainDto findOrderMain(OrderSearchCondition condition, Long storeId) { @@ -75,7 +82,7 @@ public class OrderServiceImpl implements OrderService { @Override @Transactional - public void addItemToBasket(OrderItemDto orderItemDto,Long storeId, Long userId) { + public void addItemToBasket(OrderItemDto orderItemDto, Long storeId, Long userId) { //orderItemOption Entity를 생성한다. List orderItemOptions = orderItemDto.getOrderItemOptionDtoList() @@ -105,21 +112,48 @@ public class OrderServiceImpl implements OrderService { public FetchOrderDto fetchOrder(Long userId) { Order order = orderRepositoryCustom.fetchOrder(userId) .orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다.")); + GetStoreReseponse store = storeClient.getStore(String.valueOf(order.getStoreId())).getData(); - return new FetchOrderDto(order); + Map itemMap = storeClient.getItemAndItemOptions(order.getOrderItems().stream() + .map(OrderItem::getItemId) + .filter(Objects::nonNull) + .collect(Collectors.toUnmodifiableList()) + ).getData() + .stream().collect( + Collectors.toMap( + GetItemResponse::getId + ,getItemResponse->getItemResponse + ,(t, t2) -> t + ) + ); + + List orderItemDtoList = order.getOrderItems() + .stream().map(orderItem -> + new FetchOrderDto.OrderItemDto( + itemMap.get(orderItem.getItemId()) + ,orderItem)) + .collect(Collectors.toList()); + + + FetchOrderDto fetchOrderDto = FetchOrderDto.builder() + .userId(order.getUserId()) + .orderPrice(order.getOrderPrice()) + .storeName(store.getName()) + .orderItemDtoList(orderItemDtoList) + .build(); + + return fetchOrderDto; } @Override @Transactional public void saveOrder(Long userId) { - Order order = orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING) + + orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING) .orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다.")) - .setOrderStatus(OrderStatus.PLACED); - try{ - orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order)); - }catch (Exception ex){ - throw new OrderException(ex.getMessage()); - } + .order(); + + } @Override diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetStoreReseponse.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetStoreReseponse.java new file mode 100644 index 0000000..3677001 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/GetStoreReseponse.java @@ -0,0 +1,14 @@ +package com.justpickup.orderservice.global.client.store; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GetStoreReseponse { + private Long id; + private String name; + private String phoneNumber; +} \ No newline at end of file diff --git a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/OptionType.java b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/OptionType.java new file mode 100644 index 0000000..018b6e0 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/OptionType.java @@ -0,0 +1,5 @@ +package com.justpickup.orderservice.global.client.store; + +public enum OptionType { + REQUIRED, OTHER +} 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 c2762bb..cbcb1ea 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 @@ -5,9 +5,15 @@ import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -@FeignClient(name = "STORE-SERVICE", url = "127.0.0.1:8001/store-service") +import java.util.List; + +@FeignClient("store-service") public interface StoreClient { - @GetMapping("/item/{itemId}") - Result getItem(@PathVariable("itemId") Long itemId); + @GetMapping("/store/{storeId}") + Result getStore(@PathVariable(value = "storeId") String storeId); + + @GetMapping("/api/customer/items/{itemId}") + Result> getItemAndItemOptions(@PathVariable(value = "itemId") List itemIds); + } diff --git a/order-service/src/main/resources/application.yml b/order-service/src/main/resources/application.yml index eccbfdf..e87c9d1 100644 --- a/order-service/src/main/resources/application.yml +++ b/order-service/src/main/resources/application.yml @@ -3,7 +3,7 @@ server: spring: application: - name: order-servcie + name: order-service config: import: optional:configserver:http://127.0.0.1:8888 cloud: @@ -46,7 +46,3 @@ decorator.datasource.p6spy: kafka: host: 127.0.0.1 port: 9092 - -#feign key -token: - feign: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmZWlnbiIsImV4cCI6MTE2NDY5NzY4NzAsImlhdCI6MTY0Njk3Njg3MH0.5x4Nx7oMnpF0_kZpbZsiB1u9eEbQ4IKIhJlEsa3D22cjZjvTHKz57GCz0sgXb_olhSNIVv9xF41A29-XYiFeBQ \ No newline at end of file From c59023a56f8acf08058920473c14cf1f74a8c371 Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Tue, 15 Mar 2022 11:41:43 +0900 Subject: [PATCH 03/10] =?UTF-8?q?feat(customer=20vue):=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=ED=99=94=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 매장 화면에서 주문화면으로 이동하는 기능 --- customer-vue/src/views/Layout/StoreLayout.vue | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/customer-vue/src/views/Layout/StoreLayout.vue b/customer-vue/src/views/Layout/StoreLayout.vue index 9dc2dea..e16c422 100644 --- a/customer-vue/src/views/Layout/StoreLayout.vue +++ b/customer-vue/src/views/Layout/StoreLayout.vue @@ -8,6 +8,17 @@ +
+ + mdi-basket + +
@@ -45,6 +56,11 @@ export default { const response = await storeApi.requestStore(this.store.id); this.store = response.data.data; + }, + toOrder(){ + if(confirm("주문화면으로 이동할까요?")){ + this.$router.replace("/order") + } } } } From 1c7f21964ac96d8bfae2e9adfefd3e55cfb4da98 Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Tue, 15 Mar 2022 17:48:53 +0900 Subject: [PATCH 04/10] =?UTF-8?q?test(store-service):=20getItem=20list=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getItemList 테스트 작성 --- .../web/OrderCustomerApiControllerTest.java | 32 ++++++++++++------- store-service/src/docs/asciidoc/api-docs.adoc | 3 ++ 2 files changed, 24 insertions(+), 11 deletions(-) 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 d05625a..6105adc 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 @@ -9,6 +9,8 @@ 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 com.justpickup.orderservice.global.client.store.GetItemResponse; +import com.justpickup.orderservice.global.client.store.OptionType; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; @@ -177,15 +179,15 @@ class OrderCustomerApiControllerTest { void fetchOrder() throws Exception{ //Given FetchOrderDto fetchOrderDto = - new FetchOrderDto(2L,2L,12000L,2L + new FetchOrderDto(2L,2L,12000L,"저스트카페" ,List.of( - OrderItemDto.of(1L,300L,3000L,2L, - List.of(new OrderItemOptionDto(2L) - ,new OrderItemOptionDto(3L)) + new FetchOrderDto.OrderItemDto(1L,1L,"카페라테", + List.of(new GetItemResponse.ItemOptionDto(2L, OptionType.REQUIRED,"Hot") + ,new GetItemResponse.ItemOptionDto(2L, OptionType.OTHER,"샷추카")),3000L,32L) ) - ) ); + given(orderService.fetchOrder(2L)).willReturn(fetchOrderDto); //When @@ -201,12 +203,20 @@ class OrderCustomerApiControllerTest { responseFields( fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), fieldWithPath("message").description("메시지"), - fieldWithPath("data.storeId").description("매장 고유번호"), - fieldWithPath("data.totalPrice").description("총 합계"), - fieldWithPath("data._orderItemDtos[*].itemId").description("상품 고유번호"), - fieldWithPath("data._orderItemDtos[*].price").description("상품 가격"), - fieldWithPath("data._orderItemDtos[*].count").description("상품 갯수"), - fieldWithPath("data._orderItemDtos[*].itemOptionIds[*]").description("아이템 옵션들") + fieldWithPath("data.id").description("주문 고유번호"), + fieldWithPath("data.userId").description("주문한 유저 고유번호"), + fieldWithPath("data.storeName").description("매장 명"), + fieldWithPath("data.orderPrice").description("총 합계"), + fieldWithPath("data.orderItemDtoList[*].id").description("orderItem 고유번호"), + fieldWithPath("data.orderItemDtoList[*].itemId").description("상품 고유번호"), + fieldWithPath("data.orderItemDtoList[*].itemName").description("상품 명"), + fieldWithPath("data.orderItemDtoList[*].orderItemOptionDtoList[*]").description("아이템 옵션들"), + fieldWithPath("data.orderItemDtoList[*].orderItemOptionDtoList[*].id").description("아이템 옵션 고유번호"), + fieldWithPath("data.orderItemDtoList[*].orderItemOptionDtoList[*].optionType").description("아이템 옵션 타입"), + fieldWithPath("data.orderItemDtoList[*].orderItemOptionDtoList[*].name").description("아이템 옵션명"), + fieldWithPath("data.orderItemDtoList[*].price").description("상품 가격"), + fieldWithPath("data.orderItemDtoList[*].count").description("상품 갯수") + ))); diff --git a/store-service/src/docs/asciidoc/api-docs.adoc b/store-service/src/docs/asciidoc/api-docs.adoc index cdb3467..bdba3b4 100644 --- a/store-service/src/docs/asciidoc/api-docs.adoc +++ b/store-service/src/docs/asciidoc/api-docs.adoc @@ -70,6 +70,9 @@ operation::item-get[snippets='curl-request,http-request,http-response,path-param === 상품 조회 (존재하지 않는 상품) operation::item-get-notExistItemException[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'] + === 상품 조회(판매자) operation::owner-item-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] From b7df4fb905860431f3fc49b3074ed7aff366436d Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Tue, 15 Mar 2022 17:52:16 +0900 Subject: [PATCH 05/10] =?UTF-8?q?refactor(order-service):=20save=20order?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - save order 수정 --- .../domain/order/entity/OrderListener.java | 10 ++++----- .../order/service/OrderServiceImpl.java | 21 ++++++++++--------- .../domain/item/dto/GetItemDto.java | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java index 2f58647..b5e0890 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/OrderListener.java @@ -2,31 +2,29 @@ package com.justpickup.orderservice.domain.order.entity; import com.justpickup.orderservice.domain.order.exception.OrderException; import com.justpickup.orderservice.domain.order.service.OrderSender; -import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; -import javax.persistence.PostUpdate; +import javax.persistence.*; @Slf4j -@NoArgsConstructor public class OrderListener { @Autowired @Lazy private OrderSender orderSender; + + // TODO: 2022/03/15 exception 발생시 order fail 처리 @PostUpdate - void postUpdate(Order order) { + public void postUpdate(Order order){ OrderStatus orderStatus = order.getOrderStatus(); if (orderStatus == OrderStatus.ORDER) { - // TODO: 2022/03/10 Kafka 알림 전송 log.info("[OrderListener] {}", OrderStatus.ORDER.name()); try{ orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order)); }catch (Exception ex){ - order.fail(); throw new OrderException(ex.getMessage()); } 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 2bfd781..0c15888 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 @@ -19,8 +19,11 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.SliceImpl; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; import java.util.List; import java.util.Map; import java.util.Objects; @@ -100,7 +103,7 @@ public class OrderServiceImpl implements OrderService { Optional optionalOrder = orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING); if(optionalOrder.isPresent()){ - if(optionalOrder.get().addOrderItem(orderItem) + if(!optionalOrder.get().addOrderItem(orderItem) .getStoreId().equals(storeId)) throw new OrderException("장바구니에 여러 카페의 메뉴를 담을수 없습니다."); }else{ @@ -114,16 +117,17 @@ public class OrderServiceImpl implements OrderService { .orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다.")); GetStoreReseponse store = storeClient.getStore(String.valueOf(order.getStoreId())).getData(); - Map itemMap = storeClient.getItemAndItemOptions(order.getOrderItems().stream() + List data = storeClient.getItemAndItemOptions(order.getOrderItems().stream() .map(OrderItem::getItemId) - .filter(Objects::nonNull) + .filter(Objects::nonNull) .collect(Collectors.toUnmodifiableList()) - ).getData() - .stream().collect( + ).getData(); + + Map itemMap = data.stream().collect( Collectors.toMap( GetItemResponse::getId - ,getItemResponse->getItemResponse - ,(t, t2) -> t + , getItemResponse -> getItemResponse + , (t, t2) -> t ) ); @@ -148,12 +152,9 @@ public class OrderServiceImpl implements OrderService { @Override @Transactional public void saveOrder(Long userId) { - orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING) .orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다.")) .order(); - - } @Override diff --git a/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/GetItemDto.java b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/GetItemDto.java index a669ad8..98666e0 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/GetItemDto.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/dto/GetItemDto.java @@ -41,7 +41,7 @@ public class GetItemDto { @AllArgsConstructor @NoArgsConstructor @Builder - static class ItemOptionDto{ + public static class ItemOptionDto{ private Long id; private OptionType optionType; From 170ddfa9f8c60b1f1883bac128e7a64b128d909a Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Tue, 15 Mar 2022 17:58:54 +0900 Subject: [PATCH 06/10] =?UTF-8?q?feat(customer-vue):=20=EA=B5=AC=EB=A7=A4?= =?UTF-8?q?=EC=9E=90=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 매장에서 장바구니로 이동하는 기능 --- customer-vue/src/main.js | 5 +- customer-vue/src/views/ItemDetail.vue | 6 +- customer-vue/src/views/Layout/StoreLayout.vue | 2 +- customer-vue/src/views/LoginPage.vue | 2 - customer-vue/src/views/OrderPage.vue | 11 +- .../web/ItemCustomerApiControllerTest.java | 134 ++++++++++++++++++ 6 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemCustomerApiControllerTest.java diff --git a/customer-vue/src/main.js b/customer-vue/src/main.js index bb202fc..9f625bf 100644 --- a/customer-vue/src/main.js +++ b/customer-vue/src/main.js @@ -19,7 +19,10 @@ axios.interceptors.request.use(function (config) { config.headers.Authorization = "Bearer " + jwt.getToken(); return config; }); - +Vue.filter('currency', function (value) { + var num = new Number(value); + return num.toFixed(0).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,") +}); axios.interceptors.response.use( (response) => { diff --git a/customer-vue/src/views/ItemDetail.vue b/customer-vue/src/views/ItemDetail.vue index 715ee43..440397c 100644 --- a/customer-vue/src/views/ItemDetail.vue +++ b/customer-vue/src/views/ItemDetail.vue @@ -133,7 +133,7 @@ export default { }) .catch(error=>{ console.log(error) - this.$router.replace("/") + this.$router.push("/") }) }, parseGroup: function (type){ @@ -151,10 +151,10 @@ export default { orderApi.addItemToBasket(this.setItem) .then(response=>{ console.log(response) - this.$router.replace("/store/"+this.storeId) + this.$router.push("/store/"+this.storeId) }) .catch(error=>{ - console.log(error) + console.log(error.response) }) } }, diff --git a/customer-vue/src/views/Layout/StoreLayout.vue b/customer-vue/src/views/Layout/StoreLayout.vue index e16c422..205f85c 100644 --- a/customer-vue/src/views/Layout/StoreLayout.vue +++ b/customer-vue/src/views/Layout/StoreLayout.vue @@ -59,7 +59,7 @@ export default { }, toOrder(){ if(confirm("주문화면으로 이동할까요?")){ - this.$router.replace("/order") + this.$router.push("/order") } } } diff --git a/customer-vue/src/views/LoginPage.vue b/customer-vue/src/views/LoginPage.vue index 74a76eb..38add22 100644 --- a/customer-vue/src/views/LoginPage.vue +++ b/customer-vue/src/views/LoginPage.vue @@ -14,8 +14,6 @@ justify="center" > - - - 수량 : {{ orderItem.count }} + 수량 : {{ orderItem.count| currency }}
{{ orderItem.orderItemOptionDtoList ? @@ -28,7 +28,7 @@ : null}}
- 합계 : {{ orderItem.count * orderItem.price }} 원 + 합계 : {{ orderItem.count * orderItem.price | currency}} 원
-
합계 : {{orderData.orderPrice}} 원
+
합계 : {{orderData.orderPrice | currency}} 원
{ alert('주문되었습니다.') - this.$router.replace("/") + this.$router.push("/history") }) .catch(error=>{ console.log(error) @@ -106,8 +106,7 @@ export default { }) .catch(error=>{ console.log(error.response) - - // this.$router.replace("/") + history.back(); }) }, } diff --git a/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemCustomerApiControllerTest.java b/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemCustomerApiControllerTest.java new file mode 100644 index 0000000..c3349ac --- /dev/null +++ b/store-service/src/test/java/com/justpickup/storeservice/domain/item/web/ItemCustomerApiControllerTest.java @@ -0,0 +1,134 @@ +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.GetItemDto; +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; +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 java.util.List; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +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(ItemCustomerApiController.class) +@Import(TestConfig.class) +@AutoConfigureRestDocs(uriHost = "just-pickup.com", uriPort = 8000) +class ItemCustomerApiControllerTest { + + @Autowired + ObjectMapper objectMapper; + + @Autowired + MockMvc mockMvc; + + @MockBean + ItemService itemService; + + @MockBean + private StoreRepository storeRepository; + + @MockBean + private FavoriteStoreRepository favoriteStoreRepository; + + @Test + @DisplayName("상품리스트 조회") + void getItem() throws Exception { + // GIVEN + List itemIds = List.of("1","2"); + List willReturnDtoList = + List.of( + GetItemDto.builder() + .id(1L) + .salesYn(Yn.Y) + .price(1500L) + .name("아메리카노") + .itemOptions(List.of( + GetItemDto.ItemOptionDto.builder() + .id(1L) + .name("Hot") + .optionType(OptionType.REQUIRED) + .build() + ,GetItemDto.ItemOptionDto.builder() + .id(2L) + .name("add shot") + .optionType(OptionType.OTHER) + .build() + )) + .build(), + GetItemDto.builder() + .id(2L) + .salesYn(Yn.Y) + .price(2500L) + .name("카페라테") + .itemOptions(List.of( + GetItemDto.ItemOptionDto.builder() + .id(1L) + .name("Hot") + .optionType(OptionType.REQUIRED) + .build() + ,GetItemDto.ItemOptionDto.builder() + .id(2L) + .name("add shot") + .optionType(OptionType.OTHER) + .build() + )) + .build() + ); + + + given(itemService.getItemAndItemOptions(any() )) + .willReturn(willReturnDtoList); + + String param = String.join(",", itemIds); + + // WHEN + ResultActions actions = mockMvc.perform(get("/api/customer/items/{itemIds}", param)); + + // THEN + actions.andExpect(status().isOk()) + .andDo(print()) + .andDo(document("customer-itemList-get", + pathParameters( + parameterWithName("itemIds").description("상품 고유 번호리스트") + ), + responseFields( + fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data[*].id").description("상품 고유 번호"), + fieldWithPath("data[*].name").description("상품 이름"), + fieldWithPath("data[*].salesYn").description("화면 표시 여부 Y/N"), + fieldWithPath("data[*].price").description("상품 가격"), + fieldWithPath("data[*].itemOptions[*].id").description("아이템 옵션 고유 번호"), + fieldWithPath("data[*].itemOptions[*].optionType").description("옵션 타입"), + fieldWithPath("data[*].itemOptions[*].name").description("옵션명") + ) + )); + } + +} \ No newline at end of file From 203f5c62f086244d69d3f76c464585d3ff49aab6 Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Tue, 15 Mar 2022 18:36:12 +0900 Subject: [PATCH 07/10] =?UTF-8?q?fix(customer-vue):=20login=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - login 페이지 수정 --- customer-vue/src/router/router.js | 12 +- customer-vue/src/views/LoginPage.vue | 176 +++++++++++++++------------ 2 files changed, 105 insertions(+), 83 deletions(-) diff --git a/customer-vue/src/router/router.js b/customer-vue/src/router/router.js index a3afd88..4b85163 100644 --- a/customer-vue/src/router/router.js +++ b/customer-vue/src/router/router.js @@ -23,7 +23,7 @@ const authCheck = async function (to, from, next) { await auth.requestCheckAccessToken(); } } catch (error) { - await router.replace("/login"); + await router.push("/login"); } next(); }; @@ -60,11 +60,6 @@ const routes = [ name: 'notification', component: () => import('../views/NotificationView') }, - { - path: '/login', - name: 'login', - component: () => import('../views/LoginPage') - }, { path: "/item/:itemId", name: 'itemDetail', @@ -77,6 +72,11 @@ const routes = [ }, ] }, + { + path: '/login', + component: () => import('../views/LoginPage'), + }, + { path: '/store', redirect: 'store', diff --git a/customer-vue/src/views/LoginPage.vue b/customer-vue/src/views/LoginPage.vue index 38add22..9f46eb6 100644 --- a/customer-vue/src/views/LoginPage.vue +++ b/customer-vue/src/views/LoginPage.vue @@ -1,77 +1,84 @@ @@ -79,29 +86,31 @@ import logo from '@/assets/justLogo.png' import logo_naver from '@/assets/logo_naver.svg' import logo_google from '@/assets/logo_google.png' +import jwt from "@/common/jwt"; +import router from "@/router/router"; export default { name: "LoginPage", - data (){ + data() { return { - logo : logo, + logo: logo, logo_naver: logo_naver, - logo_google : logo_google, + logo_google: logo_google, auth_popup: null, } }, watch: { - auth_popup : function () { - this.auth_popup.addEventListener('beforeunload', function() { - window.location.href=process.env.VUE_APP_BASEURL; + auth_popup: function () { + this.auth_popup.addEventListener('beforeunload', function () { + window.location.href = process.env.VUE_APP_BASEURL; }); } }, methods: { - login_auth: async function(target) { - const _url = process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+'/user-service/oauth2/authorization/'+target + login_auth: async function (target) { + const _url = process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL + '/user-service/oauth2/authorization/' + target this.auth_popup = window.open( _url, "", @@ -110,9 +119,22 @@ export default { }, }, + async mounted() { + + if (!jwt.isExpired()) + await router.push("/"); + + } } \ No newline at end of file From 58ffd2c7dc7b53e5617247c0c9c1ce08d9f6b08d Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Tue, 15 Mar 2022 19:34:02 +0900 Subject: [PATCH 08/10] =?UTF-8?q?fix(owner-vue):=20=EB=A9=94=EB=89=B4?= =?UTF-8?q?=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 메뉴관리 파라메터 잘못 넘어가는것 수정 --- owner-vue/src/api/store.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owner-vue/src/api/store.js b/owner-vue/src/api/store.js index fa9a734..5318ec1 100644 --- a/owner-vue/src/api/store.js +++ b/owner-vue/src/api/store.js @@ -34,6 +34,6 @@ export default { }) }, getMenu(searchParam){ - return axios.get(process.env.VUE_APP_OWNER_SERVICE_BASEURL+'/store-service/api/owner/item',searchParam); + return axios.get(process.env.VUE_APP_OWNER_SERVICE_BASEURL+'/store-service/api/owner/item',{params:searchParam}); }, } \ No newline at end of file From a3e0a3d6e95e79be452eacce928d02db7e2f4040 Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Wed, 16 Mar 2022 19:50:43 +0900 Subject: [PATCH 09/10] =?UTF-8?q?fix(customer-vue):=20mypage=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - customer mypage 개발 --- customer-vue/src/api/user.js | 3 + .../src/components/BottomNavigation.vue | 9 +- customer-vue/src/router/router.js | 15 ++++ customer-vue/src/views/MyPage.vue | 88 +++++++++++++++++++ .../userservice/domain/user/dto/UserDto.java | 1 + .../domain/user/web/UserController.java | 27 ++++++ 6 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 customer-vue/src/views/MyPage.vue diff --git a/customer-vue/src/api/user.js b/customer-vue/src/api/user.js index 7eb0b07..c366a01 100644 --- a/customer-vue/src/api/user.js +++ b/customer-vue/src/api/user.js @@ -5,6 +5,9 @@ export default { requestRegisterUser(user) { return axios.post(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+"/user-service/store-owner", user); }, + geUserData() { + return axios.get(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+"/user-service/customer/", ); + }, async requestLoginUser(email, password) { const user = { diff --git a/customer-vue/src/components/BottomNavigation.vue b/customer-vue/src/components/BottomNavigation.vue index b1fb176..f1b4432 100644 --- a/customer-vue/src/components/BottomNavigation.vue +++ b/customer-vue/src/components/BottomNavigation.vue @@ -24,7 +24,7 @@ export default { {name: "검색", url: "/search", icon: "mdi-magnify"}, {name: "즐겨찾기", url: "/favorite", icon: "mdi-cards-heart-outline"}, {name: "주문내역", url: "/history", icon: "mdi-clipboard-check-outline"}, - {name: "마이페이지", url: "/", icon: "mdi-account-outline"} + {name: "마이페이지", url: "/mypage", icon: "mdi-account-outline"} ] } }, @@ -33,6 +33,13 @@ export default { this.value = index; this.$router.push(url); } + },mounted() { + const path =this.$route.path + this.links.forEach((link, index) => { + if(link.url === path){ + this.value = index + } + }) } } diff --git a/customer-vue/src/router/router.js b/customer-vue/src/router/router.js index a3afd88..ba0585d 100644 --- a/customer-vue/src/router/router.js +++ b/customer-vue/src/router/router.js @@ -37,44 +37,58 @@ const routes = [ children: [ { path: "/home", + beforeEnter: authCheck, name: 'home', component: () => import('../views/HomeView') }, { path: "/search", + beforeEnter: authCheck, name: 'search-store', component: () => import('../views/SearchStore') }, { path: "/history", + beforeEnter: authCheck, name: 'order-history', component: () => import('../views/OrderHistory') }, { path: "/favorite", + beforeEnter: authCheck, name: 'favorite-store', component: () => import('../views/FavoriteStore') }, { path: "/notification", + beforeEnter: authCheck, name: 'notification', component: () => import('../views/NotificationView') }, { path: '/login', + beforeEnter: authCheck, name: 'login', component: () => import('../views/LoginPage') }, { path: "/item/:itemId", + beforeEnter: authCheck, name: 'itemDetail', component: () => import('../views/ItemDetail') }, { path: "/order", + beforeEnter: authCheck, name: 'orderPage', component: () => import('../views/OrderPage') }, + { + path: "/mypage", + beforeEnter: authCheck, + name: 'myPage', + component: () => import('../views/MyPage') + }, ] }, { @@ -86,6 +100,7 @@ const routes = [ { path: "/store/:storeId", name: "store", + beforeEnter: authCheck, component: () => import('../views/StoreView'), props: true }, diff --git a/customer-vue/src/views/MyPage.vue b/customer-vue/src/views/MyPage.vue new file mode 100644 index 0000000..268d115 --- /dev/null +++ b/customer-vue/src/views/MyPage.vue @@ -0,0 +1,88 @@ + + + + + \ No newline at end of file diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/UserDto.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/UserDto.java index f3aa62e..dbb65d9 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/UserDto.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/UserDto.java @@ -16,6 +16,7 @@ public abstract class UserDto { // == 생성 메소드 == // public UserDto(Customer customer) { this.id = customer.getId(); + this.email = customer.getEmail(); this.password = customer.getPassword(); this.name = customer.getName(); this.phoneNumber = customer.getPhoneNumber(); 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 377a1bb..1525635 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 @@ -24,6 +24,33 @@ public class UserController { private final UserService userService; + @GetMapping("/customer/") + public ResponseEntity getCustomerByToken(@Valid @RequestHeader(value = "user-id") String userId ) { + + CustomerDto customerDto = userService.findCustomerByUserId(Long.parseLong(userId)); + + GetCustomerByTokenResponse getCustomerByTokenResponse = new GetCustomerByTokenResponse(customerDto); + + return ResponseEntity.status(HttpStatus.OK) + .body(Result.createSuccessResult(getCustomerByTokenResponse)); + } + + @Data @NoArgsConstructor @AllArgsConstructor + static class GetCustomerByTokenResponse { + private Long userId; + private String email; + private String userName; + private String phoneNumber; + + public GetCustomerByTokenResponse(CustomerDto customerDto) { + this.userId = customerDto.getId(); + this.email = customerDto.getEmail(); + this.userName = customerDto.getName(); + this.phoneNumber = customerDto.getPhoneNumber(); + } + } + + @GetMapping("/customer/{userId}") public ResponseEntity getCustomer(@Valid @PathVariable("userId") Long userId) { From 5fc4bd434ee997d37d1f504882a33fe4e1f428c5 Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Wed, 16 Mar 2022 20:01:03 +0900 Subject: [PATCH 10/10] =?UTF-8?q?test(user-service):=20user-service=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - mypage 정보 가져오는 테스트코드 작성 --- user-service/src/docs/asciidoc/api-docs.adoc | 2 + .../domain/user/web/UserControllerTest.java | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/user-service/src/docs/asciidoc/api-docs.adoc b/user-service/src/docs/asciidoc/api-docs.adoc index 8bb36ad..9204d08 100644 --- a/user-service/src/docs/asciidoc/api-docs.adoc +++ b/user-service/src/docs/asciidoc/api-docs.adoc @@ -65,6 +65,8 @@ domain-httpRequestCode-etc == 유저 +=== 로그인 된 회원 조회 +operation::customer-get-mypage[snippets='curl-request,http-request,http-response,request-headers,response-fields'] === 회원 조회 operation::customer-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] === 회원 조회 (존재하지 않는 회원) 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 93c2c3d..7f7648a 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 @@ -21,12 +21,15 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; +import org.springframework.restdocs.headers.HeaderDocumentation; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.willThrow; +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.mockmvc.RestDocumentationRequestBuilders.post; @@ -58,6 +61,53 @@ class UserControllerTest { @SpyBean CookieProvider cookieProvider; + @Test + @DisplayName("로그인된 회원 조회") + void getCustomerByToken() throws Exception { + // GIVEN + long userId = 1L; + + CustomerDto willReturnDto = CustomerDto.builder() + .id(1L) + .name("이름") + .password("password!@#") + .email("hoonasdasd@naver.com") + .phoneNumber("010-1234-5678") + .build(); + + given(userService.findCustomerByUserId(userId)) + .willReturn(willReturnDto); + + // WHEN + ResultActions actions = mockMvc.perform(get("/customer/") + .header("user-id",userId)); + + // THEN + actions.andExpect(status().isOk()) + .andExpect(jsonPath("code").value(Code.SUCCESS.name())) + .andExpect(jsonPath("message").value("")) + .andExpect(jsonPath("data.userId").value(1)) + .andExpect(jsonPath("data.email").value("hoonasdasd@naver.com")) + .andExpect(jsonPath("data.userName").value("이름")) + .andExpect(jsonPath("data.phoneNumber").value("010-1234-5678")) + .andDo(print()) + .andDo(document("customer-get-mypage", + requestHeaders( + headerWithName("user-id").description("로그인한 유저 id") + ), + responseFields( + fieldWithPath("code").description("결과코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data.userId").description("회원 고유번호"), + fieldWithPath("data.userName").description("회원 이름"), + fieldWithPath("data.email").description("회원 이메일"), + fieldWithPath("data.phoneNumber").description("회원 휴대폰 번호") + )) + ) + ; + } + + @Test @DisplayName("회원 조회") void getCustomer() throws Exception {