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/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/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/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 9dc2dea..205f85c 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.push("/order") + } } } } diff --git a/customer-vue/src/views/LoginPage.vue b/customer-vue/src/views/LoginPage.vue index 74a76eb..9f46eb6 100644 --- a/customer-vue/src/views/LoginPage.vue +++ b/customer-vue/src/views/LoginPage.vue @@ -1,79 +1,84 @@ @@ -81,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, "", @@ -112,9 +119,22 @@ export default { }, }, + async mounted() { + + if (!jwt.isExpired()) + await router.push("/"); + + } } \ No newline at end of file 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/customer-vue/src/views/OrderPage.vue b/customer-vue/src/views/OrderPage.vue index df1c272..64a79f4 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.count| currency }} -
- {{ orderItem.itemOptionIds.join(', ')}} +
+ {{ orderItem.orderItemOptionDtoList ? + orderItem.orderItemOptionDtoList.map(x=>x.name).join(', ') + : null}}
- 합계 : {{ orderItem.count * orderItem.price }} 원 + 합계 : {{ orderItem.count * orderItem.price | currency}} 원
-
합계 : {{orderData.totalPrice}} 원
+
합계 : {{orderData.orderPrice | currency}} 원
{ alert('주문되었습니다.') - this.$router.replace("/") + this.$router.push("/history") }) .catch(error=>{ console.log(error) @@ -106,11 +101,12 @@ export default { getOrder: function(){ orderApi.getOrder() .then(response=>{ + console.log(response) this.orderData=response.data.data }) .catch(error=>{ - console.log(error) - this.$router.replace("/") + console.log(error.response) + history.back(); }) }, } 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 9e6737f..09465ea 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/Order.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/entity/Order.java @@ -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 { @@ -101,4 +102,8 @@ public class Order extends BaseEntity { } return totalPrice; } + + 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..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 @@ -1,18 +1,33 @@ 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.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; -import javax.persistence.PostUpdate; +import javax.persistence.*; @Slf4j public class OrderListener { + @Autowired + @Lazy + private OrderSender orderSender; + + + // TODO: 2022/03/15 exception 발생시 order fail 처리 @PostUpdate - private 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){ + 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/OrderServiceImpl.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java index 1467e63..5ba1aa3 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java @@ -15,6 +15,9 @@ import com.justpickup.orderservice.global.client.store.StoreByUserIdResponse; import com.justpickup.orderservice.global.client.store.StoreClient; import com.justpickup.orderservice.global.client.user.GetCustomerResponse; import com.justpickup.orderservice.global.client.user.UserClient; +import com.justpickup.orderservice.global.client.store.GetItemResponse; +import com.justpickup.orderservice.global.client.store.GetStoreReseponse; +import com.justpickup.orderservice.global.client.store.StoreClient; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -22,9 +25,12 @@ 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 java.util.*; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; @@ -40,7 +46,7 @@ public class OrderServiceImpl implements OrderService { private final OrderSender orderSender; private final StoreClient storeClient; private final UserClient userClient; - + @Override public OrderMainDto findOrderMain(OrderSearchCondition condition, Long userId) { // storeId 가져오기 @@ -183,7 +189,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() @@ -201,7 +207,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{ @@ -213,21 +219,46 @@ 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); + List data = storeClient.getItemAndItemOptions(order.getOrderItems().stream() + .map(OrderItem::getItemId) + .filter(Objects::nonNull) + .collect(Collectors.toUnmodifiableList()) + ).getData(); + + Map itemMap = data.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/domain/order/web/OrderCustomerApiController.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiController.java index 1cbd256..a915d27 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiController.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiController.java @@ -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/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 2679ea1..8581c8e 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/global/client/store/StoreClient.java +++ b/order-service/src/main/java/com/justpickup/orderservice/global/client/store/StoreClient.java @@ -22,4 +22,11 @@ public interface StoreClient { @GetMapping("/stores/{storeId}") Result> getStoreAllById(@PathVariable("storeId") Iterable storeIds); + + @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/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/order-service/src/main/resources/application.yml b/order-service/src/main/resources/application.yml index ba95b52..e87c9d1 100644 --- a/order-service/src/main/resources/application.yml +++ b/order-service/src/main/resources/application.yml @@ -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 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 fce27c4..8c9dbf8 100644 --- a/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java +++ b/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java @@ -10,6 +10,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; @@ -179,15 +181,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 @@ -203,12 +205,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/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 diff --git a/store-service/src/docs/asciidoc/api-docs.adoc b/store-service/src/docs/asciidoc/api-docs.adoc index 071904a..f080c60 100644 --- a/store-service/src/docs/asciidoc/api-docs.adoc +++ b/store-service/src/docs/asciidoc/api-docs.adoc @@ -72,8 +72,15 @@ operation::item-get-notExistItemException[snippets='curl-request,http-request,ht === 상품 리스트 조회 operation::items-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] + == 상품 (판매자) === 상품 조회 +======= +=== 상품 리스트 조회(구매자) +operation::customer-itemList-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] + + +=== 상품 조회(판매자) operation::owner-item-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] === 상품 리스트 조회 operation::owner-itemList-get[snippets='curl-request,http-request,http-response,response-fields'] 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..98666e0 --- /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 + public 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 c5633f0..2ca0050 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemService.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemService.java @@ -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.item.dto.ItemsDto; import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto; @@ -13,6 +14,7 @@ public interface ItemService { ItemDto findItemByItemId(Long itemId); + List getItemAndItemOptions(List itemIds); FetchItemDto fetchItem(Long itemId); Page findMenuItemList(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 46ca011..98db5a1 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemServiceImpl.java +++ b/store-service/src/main/java/com/justpickup/storeservice/domain/item/service/ItemServiceImpl.java @@ -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.dto.ItemsDto; import com.justpickup.storeservice.domain.item.entity.Item; @@ -45,6 +46,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 c044f4a..f2c51fe 100644 --- a/store-service/src/main/java/com/justpickup/storeservice/global/SqlCommandLineRunner.java +++ b/store-service/src/main/java/com/justpickup/storeservice/global/SqlCommandLineRunner.java @@ -26,7 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; -@Component +//@Component @RequiredArgsConstructor @Slf4j public class SqlCommandLineRunner implements CommandLineRunner { diff --git a/store-service/src/main/resources/application.yml b/store-service/src/main/resources/application.yml index 15d5314..c66a93b 100644 --- a/store-service/src/main/resources/application.yml +++ b/store-service/src/main/resources/application.yml @@ -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,13 @@ spring: username: postgres password: admin + +# sql: +# init: +# data-locations: classpath:data/data.sql +# mode: always + + eureka: client: service-url: @@ -41,7 +50,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/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 diff --git a/user-service/src/docs/asciidoc/api-docs.adoc b/user-service/src/docs/asciidoc/api-docs.adoc index 9a7faea..cae79a5 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/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 c1eee47..9a7cfe3 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java @@ -26,6 +26,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(@PathVariable("userId") Long userId) { diff --git a/user-service/src/main/resources/application.yml b/user-service/src/main/resources/application.yml index 76d0d52..a156c8a 100644 --- a/user-service/src/main/resources/application.yml +++ b/user-service/src/main/resources/application.yml @@ -53,5 +53,4 @@ token: refresh-expired-time: 604800000 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 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 9b244bc..0575454 100644 --- a/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java +++ b/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java @@ -21,6 +21,7 @@ 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; @@ -31,6 +32,8 @@ import java.util.stream.Collectors; 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; @@ -62,6 +65,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 {