Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -8,5 +8,21 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return axios.get(process.env.VUE_APP_ORDER_API_URL + "/order/history", options);
|
return axios.get(process.env.VUE_APP_ORDER_API_URL + "/order/history", options);
|
||||||
}
|
},
|
||||||
|
addItemToBasket(item) {
|
||||||
|
item.itemOptionIds =[];
|
||||||
|
for (const itemId of item.otherOptions) {
|
||||||
|
item.itemOptionIds.push(itemId)
|
||||||
|
}
|
||||||
|
item.itemOptionIds.push(item.requireOption)
|
||||||
|
return axios.post(process.env.VUE_APP_ORDER_API_URL+'/order/item', item);
|
||||||
|
},
|
||||||
|
saveOrder(order){
|
||||||
|
//만약 동시요청으로 장바구니가 두개 생겨버린다면?
|
||||||
|
return axios.post(process.env.VUE_APP_ORDER_API_URL + "/order/orders", order);
|
||||||
|
},
|
||||||
|
getOrder() {
|
||||||
|
return axios.get(process.env.VUE_APP_ORDER_API_URL + "/order/orders");
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -23,8 +23,14 @@ export default {
|
|||||||
longitude: longitude,
|
longitude: longitude,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return axios.get(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+'/store-service/api/customer/store/favorite',options)
|
return axios.get(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+'/store-service/api/customer/store/favorite',options)
|
||||||
},
|
},
|
||||||
|
getCategoryList(){
|
||||||
|
return axios.get(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+'/store-service/category/');
|
||||||
|
},
|
||||||
|
fetchItem(itemId){
|
||||||
|
return axios.get(process.env.VUE_APP_STORE_API_URL+'/item/'+itemId)
|
||||||
|
},
|
||||||
requestCategoriesWithItem(storeId) {
|
requestCategoriesWithItem(storeId) {
|
||||||
const options = {
|
const options = {
|
||||||
params: {
|
params: {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
dense
|
dense
|
||||||
color="white"
|
color="white"
|
||||||
elevation="1"
|
elevation="1"
|
||||||
|
|
||||||
>
|
>
|
||||||
<v-app-bar-nav-icon>
|
<v-app-bar-nav-icon>
|
||||||
<v-icon>mdi-arrow-left</v-icon>
|
<v-icon>mdi-arrow-left</v-icon>
|
||||||
|
|||||||
@@ -65,6 +65,16 @@ const routes = [
|
|||||||
name: 'login',
|
name: 'login',
|
||||||
component: () => import('../views/LoginPage')
|
component: () => import('../views/LoginPage')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/item/:itemId",
|
||||||
|
name: 'itemDetail',
|
||||||
|
component: () => import('../views/ItemDetail')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/order",
|
||||||
|
name: 'orderPage',
|
||||||
|
component: () => import('../views/OrderPage')
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container>
|
<v-container >
|
||||||
<v-row justify="center">
|
<v-row justify="center">
|
||||||
<v-col>
|
<v-col>
|
||||||
<div class="text-h5">
|
<div class="text-h5">
|
||||||
|
|||||||
165
customer-vue/src/views/ItemDetail.vue
Normal file
165
customer-vue/src/views/ItemDetail.vue
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
<template>
|
||||||
|
<div >
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-img :src="require('@/assets/store.jpeg')"
|
||||||
|
:aspect-ratio="16/9"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row class="mt-5" >
|
||||||
|
<v-col >
|
||||||
|
<div class="text-h3" >
|
||||||
|
{{itemData.name}}
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row class="mt-5" >
|
||||||
|
<v-col class="text-h5">
|
||||||
|
<span class="text-h5">가격</span>
|
||||||
|
</v-col>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-col >
|
||||||
|
<v-container>
|
||||||
|
<div class="text-h5">{{ itemData.price }}원</div>
|
||||||
|
</v-container>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-divider/>
|
||||||
|
<v-row class="mt-5">
|
||||||
|
<v-col>
|
||||||
|
<div class="text-h5">수량</div>
|
||||||
|
</v-col>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-col >
|
||||||
|
<v-container>
|
||||||
|
<v-text-field
|
||||||
|
v-model="setItem.count"
|
||||||
|
append-outer-icon="mdi-plus"
|
||||||
|
prepend-icon="mdi-minus"
|
||||||
|
filled
|
||||||
|
hide-details
|
||||||
|
@click:append-outer="addItemCount(1)"
|
||||||
|
@click:prepend="addItemCount(-1)"
|
||||||
|
/>
|
||||||
|
</v-container>
|
||||||
|
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-divider/>
|
||||||
|
<v-row class="mt-5">
|
||||||
|
<v-col>
|
||||||
|
<div class="text-h5"> 필수 옵션</div>
|
||||||
|
<v-radio-group v-model="setItem.requireOption">
|
||||||
|
<v-radio
|
||||||
|
v-for="itemOption in requireGroup"
|
||||||
|
:key="itemOption.id"
|
||||||
|
:label="itemOption.name"
|
||||||
|
:value="itemOption.id"
|
||||||
|
/>
|
||||||
|
</v-radio-group>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-divider/>
|
||||||
|
<v-row class="mt-5">
|
||||||
|
<v-col>
|
||||||
|
<div class="text-h5"> 추가 옵션</div>
|
||||||
|
<v-checkbox
|
||||||
|
class="shrink mr-2 mt-0"
|
||||||
|
v-model="setItem.otherOptions"
|
||||||
|
v-for="itemOption in otherGroup"
|
||||||
|
:key="itemOption.id"
|
||||||
|
:label="itemOption.name"
|
||||||
|
:value="itemOption.id"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-btn
|
||||||
|
block
|
||||||
|
@click="addItem"
|
||||||
|
>담기</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import storeApi from "@/api/store";
|
||||||
|
import orderApi from "@/api/order";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ItemDetail",
|
||||||
|
async beforeMount() {
|
||||||
|
console.log(this.$route.params)
|
||||||
|
this.itemId = this.$route.params.itemId
|
||||||
|
this.setItem.storeId = this.storeId;
|
||||||
|
await this.getItemData()
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
requireGroup:function(){
|
||||||
|
return this.parseGroup('REQUIRED')
|
||||||
|
},
|
||||||
|
otherGroup:function(){
|
||||||
|
return this.parseGroup('OTHER')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
storeId: -1,
|
||||||
|
itemId: -1,
|
||||||
|
itemData: {
|
||||||
|
itemOptions:[],
|
||||||
|
},
|
||||||
|
setItem:{
|
||||||
|
count:0,
|
||||||
|
storeId:-1,
|
||||||
|
itemId:-1,
|
||||||
|
price:0,
|
||||||
|
requireOption:{},
|
||||||
|
otherOptions:[],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getItemData: async function (){
|
||||||
|
storeApi.fetchItem(this.itemId)
|
||||||
|
.then(response=>{
|
||||||
|
console.log(response)
|
||||||
|
this.itemData = response.data.data
|
||||||
|
this.setItem.itemId = this.itemData.id
|
||||||
|
this.setItem.price = this.itemData.price
|
||||||
|
this.storeId = this.itemData.storeId
|
||||||
|
this.setItem.storeId = this.itemData.storeId
|
||||||
|
})
|
||||||
|
.catch(error=>{
|
||||||
|
console.log(error)
|
||||||
|
this.$router.replace("/")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
parseGroup: function (type){
|
||||||
|
let group= [];
|
||||||
|
for (const groupElement of this.itemData.itemOptions) {
|
||||||
|
if(groupElement.optionType===type) group.push(groupElement)
|
||||||
|
}
|
||||||
|
return group;
|
||||||
|
},
|
||||||
|
addItemCount: function (v){
|
||||||
|
this.setItem.count =
|
||||||
|
this.setItem.count+v >=0? this.setItem.count+v: 0;
|
||||||
|
},
|
||||||
|
addItem: function(){
|
||||||
|
orderApi.addItemToBasket(this.setItem)
|
||||||
|
.then(response=>{
|
||||||
|
console.log(response)
|
||||||
|
this.$router.replace("/store/"+this.storeId)
|
||||||
|
})
|
||||||
|
.catch(error=>{
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
122
customer-vue/src/views/OrderPage.vue
Normal file
122
customer-vue/src/views/OrderPage.vue
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<div class="text-h4" style="white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">{{ orderData.storeId }}</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col
|
||||||
|
v-for=" orderItem in orderData._orderItemDtos"
|
||||||
|
:key = "orderItem.itemId"
|
||||||
|
>
|
||||||
|
<v-card
|
||||||
|
class="mx-auto mb-5"
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<v-list-item three-line>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title class="text-h5 mb-3">
|
||||||
|
{{ orderItem.itemId }}
|
||||||
|
</v-list-item-title>
|
||||||
|
<v-list-item-subtitle class="mb-5">
|
||||||
|
수량 : {{ orderItem.count }}
|
||||||
|
</v-list-item-subtitle>
|
||||||
|
<div class="text-body-1 mb-5">
|
||||||
|
{{ orderItem.itemOptionIds.join(', ')}}
|
||||||
|
</div>
|
||||||
|
<div class="text--primary">
|
||||||
|
합계 : <b> {{ orderItem.count * orderItem.price }} 원</b>
|
||||||
|
</div>
|
||||||
|
</v-list-item-content>
|
||||||
|
<v-list-item-avatar
|
||||||
|
tile
|
||||||
|
size="100"
|
||||||
|
>
|
||||||
|
<v-img :src="require('@/assets/store.jpeg')"></v-img>
|
||||||
|
</v-list-item-avatar>
|
||||||
|
</v-list-item>
|
||||||
|
|
||||||
|
<v-card-actions class="pb-2">
|
||||||
|
<v-btn block color="warning">삭제하기</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<div> 합계 : {{orderData.totalPrice}} 원</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-btn
|
||||||
|
block
|
||||||
|
@click="saveOrder"
|
||||||
|
color="primary"
|
||||||
|
>주문하기</v-btn>
|
||||||
|
<!-- <v-btn-->
|
||||||
|
<!-- style="position: absolute; bottom: 0;transform: translateY(-100%); width: 100%"-->
|
||||||
|
<!-- @click="orderItems"-->
|
||||||
|
<!-- >주문하기</v-btn>-->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import orderApi from "@/api/order";
|
||||||
|
export default {
|
||||||
|
name: "OrderPage",
|
||||||
|
mounted() {
|
||||||
|
this.getOrder();
|
||||||
|
},
|
||||||
|
data: function(){
|
||||||
|
return {
|
||||||
|
orderData:{
|
||||||
|
storeId:Number,
|
||||||
|
_orderItemDtos:[{
|
||||||
|
itemId:Number,
|
||||||
|
itemOptionIds:Array,
|
||||||
|
price:Number,
|
||||||
|
count:Number,
|
||||||
|
}],
|
||||||
|
totalPrice:Number,
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
test:function (a){
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
saveOrder: function(){
|
||||||
|
|
||||||
|
orderApi.saveOrder()
|
||||||
|
.then(()=>{
|
||||||
|
alert('주문되었습니다.')
|
||||||
|
this.$router.replace("/")
|
||||||
|
})
|
||||||
|
.catch(error=>{
|
||||||
|
console.log(error)
|
||||||
|
//this.$router.replace("/")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getOrder: function(){
|
||||||
|
orderApi.getOrder()
|
||||||
|
.then(response=>{
|
||||||
|
this.orderData=response.data.data
|
||||||
|
})
|
||||||
|
.catch(error=>{
|
||||||
|
console.log(error)
|
||||||
|
this.$router.replace("/")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -35,7 +35,7 @@ dependencies {
|
|||||||
/*implementation 'org.springframework.boot:spring-boot-starter-amqp'*/
|
/*implementation 'org.springframework.boot:spring-boot-starter-amqp'*/
|
||||||
/*implementation 'org.springframework.boot:spring-boot-starter-security'*/
|
/*implementation 'org.springframework.boot:spring-boot-starter-security'*/
|
||||||
/*implementation 'org.springframework.cloud:spring-cloud-starter-config'*/
|
/*implementation 'org.springframework.cloud:spring-cloud-starter-config'*/
|
||||||
/*implementation 'org.springframework.kafka:spring-kafka'*/
|
implementation 'org.springframework.kafka:spring-kafka'
|
||||||
// https://mvnrepository.com/artifact/com.github.gavlyukovskiy/p6spy-spring-boot-starter
|
// https://mvnrepository.com/artifact/com.github.gavlyukovskiy/p6spy-spring-boot-starter
|
||||||
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.8.0'
|
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.8.0'
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ dependencies {
|
|||||||
annotationProcessor 'org.projectlombok:lombok'
|
annotationProcessor 'org.projectlombok:lombok'
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
// testImplementation 'org.springframework.amqp:spring-rabbit-test'
|
// testImplementation 'org.springframework.amqp:spring-rabbit-test'
|
||||||
// testImplementation 'org.springframework.kafka:spring-kafka-test'
|
testImplementation 'org.springframework.kafka:spring-kafka-test'
|
||||||
// testImplementation 'org.springframework.security:spring-security-test'
|
// testImplementation 'org.springframework.security:spring-security-test'
|
||||||
testImplementation 'com.h2database:h2'
|
testImplementation 'com.h2database:h2'
|
||||||
|
|
||||||
@@ -62,6 +62,9 @@ dependencies {
|
|||||||
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
|
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
|
||||||
// java.lang.NoClassDefFoundError(javax.annotation.Generated) 발생 대응
|
// java.lang.NoClassDefFoundError(javax.annotation.Generated) 발생 대응
|
||||||
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
|
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyManagement {
|
dependencyManagement {
|
||||||
|
|||||||
@@ -81,4 +81,13 @@ operation::prevOrder-get-BindException[snippets='curl-request,http-request,http-
|
|||||||
|
|
||||||
== Just Pick-up
|
== Just Pick-up
|
||||||
=== 주문 내역 페이지
|
=== 주문 내역 페이지
|
||||||
operation::api-customer-order-history[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields']
|
operation::api-customer-order-history[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields']
|
||||||
|
|
||||||
|
=== 장바구니 상품 추가
|
||||||
|
operation::add-item-to-basket[snippets='curl-request,http-request,http-response,request-headers,request-body,request-fields']
|
||||||
|
|
||||||
|
=== 장바구니 내역 가져오기
|
||||||
|
operation::fetch-order[snippets='curl-request,http-request,http-response,request-headers,response-fields']
|
||||||
|
|
||||||
|
=== 주문하기
|
||||||
|
operation::save-order[snippets='curl-request,http-request,http-response,request-headers']
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
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 java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class FetchOrderDto {
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
private Long orderPrice;
|
||||||
|
|
||||||
|
private Long storeId;
|
||||||
|
|
||||||
|
private List<OrderItemDto> orderItemDtoList;
|
||||||
|
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.justpickup.orderservice.domain.order.dto;
|
package com.justpickup.orderservice.domain.order.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||||
import com.justpickup.orderservice.domain.order.entity.Order;
|
import com.justpickup.orderservice.domain.order.entity.Order;
|
||||||
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||||
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
||||||
@@ -7,12 +9,14 @@ import com.justpickup.orderservice.domain.orderItem.entity.OrderItem;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Getter @NoArgsConstructor
|
@Getter @Setter
|
||||||
|
@NoArgsConstructor
|
||||||
public class OrderDto {
|
public class OrderDto {
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@@ -26,6 +30,7 @@ public class OrderDto {
|
|||||||
|
|
||||||
private Long storeId;
|
private Long storeId;
|
||||||
|
|
||||||
|
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
|
||||||
private LocalDateTime orderTime;
|
private LocalDateTime orderTime;
|
||||||
|
|
||||||
private Long usedPoint;
|
private Long usedPoint;
|
||||||
@@ -84,6 +89,8 @@ public class OrderDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// == 변수 변경 메소드 == //
|
// == 변수 변경 메소드 == //
|
||||||
public void setUserName(String userName) {
|
public void setUserName(String userName) {
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
|
|||||||
@@ -64,13 +64,36 @@ public class Order extends BaseEntity {
|
|||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Order of(Long userId, Long userCouponId, Long storeId, Long orderPrice,
|
||||||
|
OrderItem orderItem) {
|
||||||
|
Order order = new Order();
|
||||||
|
order.userId = userId;
|
||||||
|
order.userCouponId = userCouponId;
|
||||||
|
order.storeId = storeId;
|
||||||
|
order.orderPrice = orderPrice;
|
||||||
|
|
||||||
|
order.addOrderItem(orderItem);
|
||||||
|
|
||||||
|
order.usedPoint = 0L;
|
||||||
|
order.orderStatus = OrderStatus.PENDING;
|
||||||
|
order.orderTime = LocalDateTime.now();
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTransaction(Transaction transaction) {
|
public void setTransaction(Transaction transaction) {
|
||||||
this.transaction = transaction;
|
this.transaction = transaction;
|
||||||
transaction.setOrder(this);
|
transaction.setOrder(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addOrderItem(OrderItem orderItem) {
|
public Order addOrderItem(OrderItem orderItem) {
|
||||||
this.orderItems.add(orderItem);
|
this.orderItems.add(orderItem);
|
||||||
|
this.orderPrice += (orderItem.getPrice()*orderItem.getCount());
|
||||||
orderItem.setOrder(this);
|
orderItem.setOrder(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Order setOrderStatus(OrderStatus orderStatus){
|
||||||
|
this.orderStatus = orderStatus;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.justpickup.orderservice.domain.order.exception;
|
||||||
|
|
||||||
|
import com.justpickup.orderservice.global.exception.CustomException;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
public class OrderException extends CustomException {
|
||||||
|
|
||||||
|
public OrderException(String message) {
|
||||||
|
super(HttpStatus.CONFLICT, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.justpickup.orderservice.domain.order.repository;
|
package com.justpickup.orderservice.domain.order.repository;
|
||||||
|
|
||||||
import com.justpickup.orderservice.domain.order.entity.Order;
|
import com.justpickup.orderservice.domain.order.entity.Order;
|
||||||
|
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
public interface OrderRepository extends JpaRepository<Order, Long> {
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface OrderRepository extends JpaRepository<Order, Long> {
|
||||||
|
Optional<Order> findByUserIdAndOrderStatus(Long userId, OrderStatus orderStatus);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.justpickup.orderservice.domain.order.repository;
|
|||||||
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
||||||
import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch;
|
import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch;
|
||||||
import com.justpickup.orderservice.domain.order.entity.Order;
|
import com.justpickup.orderservice.domain.order.entity.Order;
|
||||||
|
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -14,8 +15,12 @@ import org.springframework.stereotype.Repository;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static com.justpickup.orderservice.domain.order.entity.QOrder.order;
|
import static com.justpickup.orderservice.domain.order.entity.QOrder.order;
|
||||||
|
import static com.justpickup.orderservice.domain.orderItem.entity.QOrderItem.orderItem;
|
||||||
|
import static com.justpickup.orderservice.domain.orderItemOption.entity.QOrderItemOption.orderItemOption;
|
||||||
|
import static com.justpickup.orderservice.domain.transaction.entity.QTransaction.transaction;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -104,4 +109,19 @@ public class OrderRepositoryCustom {
|
|||||||
|
|
||||||
return new SliceImpl<>(contents, pageable, hasNext);
|
return new SliceImpl<>(contents, pageable, hasNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<Order> fetchOrder(Long userId){
|
||||||
|
|
||||||
|
return Optional.ofNullable(queryFactory.selectFrom(order)
|
||||||
|
.leftJoin(order.orderItems, orderItem).fetchJoin()
|
||||||
|
.leftJoin(orderItem.orderItemOptions,orderItemOption)
|
||||||
|
.leftJoin(order.transaction,transaction)
|
||||||
|
.where(
|
||||||
|
order.userId.eq(userId),
|
||||||
|
order.orderStatus.eq(OrderStatus.PENDING)
|
||||||
|
)
|
||||||
|
.distinct()
|
||||||
|
.fetchOne());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.justpickup.orderservice.domain.order.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import com.justpickup.orderservice.domain.order.entity.Order;
|
||||||
|
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||||
|
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.kafka.core.KafkaTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class OrderSender {
|
||||||
|
|
||||||
|
private final KafkaTemplate<String, String> kafkaTemplate;
|
||||||
|
|
||||||
|
public void orderPlaced( KafkaSendOrderDto kafkaSendOrderDto) throws Exception{
|
||||||
|
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
|
||||||
|
String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto);
|
||||||
|
kafkaTemplate.send("orderPlaced", jsonInString);
|
||||||
|
log.info("kafka Producer sent data from the Order microservice: "+ kafkaSendOrderDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
static class KafkaSendOrderDto{
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
private Long userCouponId;
|
||||||
|
|
||||||
|
private Long orderPrice;
|
||||||
|
|
||||||
|
private Long storeId;
|
||||||
|
|
||||||
|
private LocalDateTime orderTime;
|
||||||
|
|
||||||
|
private Long usedPoint;
|
||||||
|
|
||||||
|
private OrderStatus orderStatus;
|
||||||
|
|
||||||
|
private List<OrderItemDto> orderItemDtoList;
|
||||||
|
|
||||||
|
// == 생성 메소드 == //
|
||||||
|
public static KafkaSendOrderDto createPrimitiveField(Order order) {
|
||||||
|
return KafkaSendOrderDto.builder()
|
||||||
|
.id(order.getId())
|
||||||
|
.userId(order.getUserId())
|
||||||
|
.userCouponId(order.getUserCouponId())
|
||||||
|
.orderPrice(order.getOrderPrice())
|
||||||
|
.orderTime(order.getOrderTime())
|
||||||
|
.storeId(order.getStoreId())
|
||||||
|
.usedPoint(order.getUsedPoint())
|
||||||
|
.orderStatus(order.getOrderStatus())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.justpickup.orderservice.domain.order.service;
|
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.OrderDto;
|
||||||
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
||||||
import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch;
|
import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch;
|
||||||
|
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.SliceImpl;
|
import org.springframework.data.domain.SliceImpl;
|
||||||
@@ -13,4 +15,7 @@ public interface OrderService {
|
|||||||
List<OrderDto> findOrderMain(OrderSearchCondition condition, Long storeId);
|
List<OrderDto> findOrderMain(OrderSearchCondition condition, Long storeId);
|
||||||
Page<OrderDto> findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long storeId);
|
Page<OrderDto> findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long storeId);
|
||||||
SliceImpl<OrderDto> findOrderHistory(Pageable pageable, Long userId);
|
SliceImpl<OrderDto> findOrderHistory(Pageable pageable, Long userId);
|
||||||
|
void addItemToBasket(OrderItemDto orderItemDto,Long storeId, Long userId);
|
||||||
|
FetchOrderDto fetchOrder(Long userId);
|
||||||
|
void saveOrder(Long userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,24 @@
|
|||||||
package com.justpickup.orderservice.domain.order.service;
|
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.OrderDto;
|
||||||
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
||||||
import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch;
|
import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch;
|
||||||
import com.justpickup.orderservice.domain.order.entity.Order;
|
import com.justpickup.orderservice.domain.order.entity.Order;
|
||||||
|
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||||
|
import com.justpickup.orderservice.domain.order.exception.OrderException;
|
||||||
import com.justpickup.orderservice.domain.order.repository.OrderRepository;
|
import com.justpickup.orderservice.domain.order.repository.OrderRepository;
|
||||||
import com.justpickup.orderservice.domain.order.repository.OrderRepositoryCustom;
|
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.orderItem.repository.OrderItemRepository;
|
||||||
|
import com.justpickup.orderservice.domain.orderItemOption.entity.OrderItemOption;
|
||||||
|
import com.justpickup.orderservice.domain.orderItemOption.repository.OrderItemOptionRepository;
|
||||||
import com.justpickup.orderservice.global.client.store.GetItemResponse;
|
import com.justpickup.orderservice.global.client.store.GetItemResponse;
|
||||||
import com.justpickup.orderservice.global.client.store.StoreClient;
|
import com.justpickup.orderservice.global.client.store.StoreClient;
|
||||||
import com.justpickup.orderservice.global.client.user.GetCustomerResponse;
|
import com.justpickup.orderservice.global.client.user.GetCustomerResponse;
|
||||||
import com.justpickup.orderservice.global.client.user.UserClient;
|
import com.justpickup.orderservice.global.client.user.UserClient;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.*;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@@ -20,6 +28,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -29,9 +38,14 @@ import java.util.stream.Collectors;
|
|||||||
public class OrderServiceImpl implements OrderService {
|
public class OrderServiceImpl implements OrderService {
|
||||||
|
|
||||||
private final OrderRepository orderRepository;
|
private final OrderRepository orderRepository;
|
||||||
|
private final OrderItemRepository orderItemRepository;
|
||||||
|
private final OrderItemOptionRepository orderItemOptionRepository;
|
||||||
private final OrderRepositoryCustom orderRepositoryCustom;
|
private final OrderRepositoryCustom orderRepositoryCustom;
|
||||||
private final StoreClient storeClient;
|
private final StoreClient storeClient;
|
||||||
private final UserClient userClient;
|
private final UserClient userClient;
|
||||||
|
private final OrderSender orderSender;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<OrderDto> findOrderMain(OrderSearchCondition condition, Long storeId) {
|
public List<OrderDto> findOrderMain(OrderSearchCondition condition, Long storeId) {
|
||||||
@@ -91,4 +105,57 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void addItemToBasket(OrderItemDto orderItemDto,Long storeId, Long userId) {
|
||||||
|
|
||||||
|
//orderItemOption Entity를 생성한다.
|
||||||
|
List<OrderItemOption> orderItemOptions = orderItemDto.getOrderItemOptionDtoList()
|
||||||
|
.stream().map(orderItemOptionDto -> OrderItemOption.of(orderItemDto.getId()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
//orderItem을 Entity를 생성한다.
|
||||||
|
OrderItem orderItem = OrderItem.of(orderItemDto.getItemId()
|
||||||
|
, orderItemDto.getPrice()
|
||||||
|
, orderItemDto.getCount()
|
||||||
|
,orderItemOptions);
|
||||||
|
|
||||||
|
//HARD_CODE
|
||||||
|
Long userCouponId=0L;
|
||||||
|
|
||||||
|
Optional<Order> optionalOrder = orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING);
|
||||||
|
if(optionalOrder.isPresent()){
|
||||||
|
if(optionalOrder.get().addOrderItem(orderItem)
|
||||||
|
.getStoreId().equals(storeId))
|
||||||
|
throw new OrderException("장바구니에 여러 카페의 메뉴를 담을수 없습니다.");
|
||||||
|
}else{
|
||||||
|
orderRepository.save(Order.of(userId,userCouponId,storeId,0L,orderItem));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FetchOrderDto fetchOrder(Long userId) {
|
||||||
|
Order order = orderRepositoryCustom.fetchOrder(userId)
|
||||||
|
.orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다."));
|
||||||
|
|
||||||
|
return new FetchOrderDto(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void saveOrder(Long userId) {
|
||||||
|
Order order = orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING)
|
||||||
|
.orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다."))
|
||||||
|
.setOrderStatus(OrderStatus.PLACED);
|
||||||
|
try{
|
||||||
|
orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order));
|
||||||
|
}catch (Exception ex){
|
||||||
|
throw new OrderException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
package com.justpickup.orderservice.domain.order.web;
|
package com.justpickup.orderservice.domain.order.web;
|
||||||
|
|
||||||
|
import com.justpickup.orderservice.domain.order.dto.FetchOrderDto;
|
||||||
import com.justpickup.orderservice.domain.order.dto.OrderDto;
|
import com.justpickup.orderservice.domain.order.dto.OrderDto;
|
||||||
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||||
import com.justpickup.orderservice.domain.order.service.OrderService;
|
import com.justpickup.orderservice.domain.order.service.OrderService;
|
||||||
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
||||||
|
import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto;
|
||||||
import com.justpickup.orderservice.global.dto.Result;
|
import com.justpickup.orderservice.global.dto.Result;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -14,10 +17,7 @@ import org.springframework.data.domain.SliceImpl;
|
|||||||
import org.springframework.data.web.PageableDefault;
|
import org.springframework.data.web.PageableDefault;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestHeader;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -89,4 +89,91 @@ public class OrderCustomerApiController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* order
|
||||||
|
*/
|
||||||
|
|
||||||
|
@PostMapping("item")
|
||||||
|
public ResponseEntity addItemToBasket( @RequestBody RequestItem requestItem,
|
||||||
|
@RequestHeader(value = "user-id") String userId){
|
||||||
|
OrderItemDto orderItemDto = OrderItemDto.of(-1L,
|
||||||
|
requestItem.getItemId(),
|
||||||
|
requestItem.getPrice(),
|
||||||
|
requestItem.getCount(),
|
||||||
|
requestItem.getItemOptionIds().stream().map(OrderItemOptionDto::new).collect(Collectors.toList()));
|
||||||
|
orderService.addItemToBasket(orderItemDto,requestItem.getStoreId() ,Long.parseLong(userId));
|
||||||
|
return ResponseEntity.status(HttpStatus.NO_CONTENT)
|
||||||
|
.body(Result.createSuccessResult(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class RequestItem{
|
||||||
|
private Long itemId;
|
||||||
|
private Long storeId;
|
||||||
|
private Long price;
|
||||||
|
private Long count;
|
||||||
|
private List<Long> 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<Long> 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();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/orders")
|
||||||
|
public ResponseEntity saveOrder(@RequestHeader(value = "user-id") String userId){
|
||||||
|
orderService.saveOrder(Long.parseLong(userId));
|
||||||
|
|
||||||
|
return ResponseEntity.status(HttpStatus.CREATED).body(Result.createSuccessResult(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package com.justpickup.orderservice.domain.orderItem.dto;
|
package com.justpickup.orderservice.domain.orderItem.dto;
|
||||||
|
|
||||||
import com.justpickup.orderservice.domain.orderItem.entity.OrderItem;
|
import com.justpickup.orderservice.domain.orderItem.entity.OrderItem;
|
||||||
|
import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Getter @NoArgsConstructor
|
@Getter @NoArgsConstructor
|
||||||
public class OrderItemDto {
|
public class OrderItemDto {
|
||||||
|
|
||||||
@@ -14,7 +18,7 @@ public class OrderItemDto {
|
|||||||
|
|
||||||
private String itemName;
|
private String itemName;
|
||||||
|
|
||||||
// private List<OrderItemOptionDto> orderItemOptionDtoList;
|
private List<OrderItemOptionDto> orderItemOptionDtoList;
|
||||||
|
|
||||||
private Long price;
|
private Long price;
|
||||||
|
|
||||||
@@ -38,6 +42,16 @@ public class OrderItemDto {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static OrderItemDto of(Long id, Long itemId, Long price, Long count, List<OrderItemOptionDto> orderItemOptions) {
|
||||||
|
OrderItemDto orderItemDto = new OrderItemDto();
|
||||||
|
orderItemDto.id = id;
|
||||||
|
orderItemDto.itemId = itemId;
|
||||||
|
orderItemDto.price = price;
|
||||||
|
orderItemDto.count = count;
|
||||||
|
orderItemDto.orderItemOptionDtoList = orderItemOptions;
|
||||||
|
|
||||||
|
return orderItemDto;
|
||||||
|
}
|
||||||
// == 변수 변경 메소드 == //
|
// == 변수 변경 메소드 == //
|
||||||
public void setItemName(String itemName) {
|
public void setItemName(String itemName) {
|
||||||
this.itemName = itemName;
|
this.itemName = itemName;
|
||||||
|
|||||||
@@ -54,4 +54,15 @@ public class OrderItem extends BaseEntity {
|
|||||||
}
|
}
|
||||||
return orderItem;
|
return orderItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static OrderItem of(Long itemId, Long price, Long count, List<OrderItemOption> orderItemOptions) {
|
||||||
|
OrderItem orderItem = new OrderItem();
|
||||||
|
orderItem.itemId = itemId;
|
||||||
|
orderItem.price = price;
|
||||||
|
orderItem.count = count;
|
||||||
|
for (OrderItemOption orderItemOption : orderItemOptions) {
|
||||||
|
orderItem.addOrderItemOption(orderItemOption);
|
||||||
|
}
|
||||||
|
return orderItem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.justpickup.orderservice.domain.orderItemOption.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class OrderItemOptionDto {
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
public OrderItemOptionDto(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,4 +32,11 @@ public class OrderItemOption extends BaseEntity {
|
|||||||
OrderItemOption orderItemOption = new OrderItemOption();
|
OrderItemOption orderItemOption = new OrderItemOption();
|
||||||
return orderItemOption;
|
return orderItemOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static OrderItemOption of(Long itemOptionId) {
|
||||||
|
OrderItemOption orderItemOption = new OrderItemOption();
|
||||||
|
orderItemOption.itemOptionId = itemOptionId;
|
||||||
|
return orderItemOption;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.justpickup.orderservice.domain.orderItemOption.repository;
|
||||||
|
|
||||||
|
|
||||||
|
import com.justpickup.orderservice.domain.orderItemOption.entity.OrderItemOption;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface OrderItemOptionRepository extends JpaRepository<OrderItemOption , Long> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.justpickup.orderservice.global.config;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.producer.ProducerConfig;
|
||||||
|
import org.apache.kafka.common.serialization.StringSerializer;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.kafka.annotation.EnableKafka;
|
||||||
|
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
|
||||||
|
import org.springframework.kafka.core.KafkaTemplate;
|
||||||
|
import org.springframework.kafka.core.ProducerFactory;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@EnableKafka
|
||||||
|
@Configuration
|
||||||
|
public class KafkaConfig {
|
||||||
|
|
||||||
|
public KafkaConfig(@Value("${kafka.host}") String kafkaServerHost,
|
||||||
|
@Value("${kafka.port}")String kafkaServerPort) {
|
||||||
|
this.kafkaServerHost = kafkaServerHost;
|
||||||
|
this.kafkaServerPort = kafkaServerPort;
|
||||||
|
}
|
||||||
|
private final String kafkaServerHost;
|
||||||
|
private final String kafkaServerPort;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ProducerFactory<String, String> producerFactory(){
|
||||||
|
Map<String, Object> properties = new HashMap<>();
|
||||||
|
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServerHost+":"+kafkaServerPort);
|
||||||
|
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||||
|
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||||
|
|
||||||
|
return new DefaultKafkaProducerFactory<>(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public KafkaTemplate<String, String> kafkaTemplate(){
|
||||||
|
return new KafkaTemplate<>(producerFactory());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
server:
|
server:
|
||||||
port: 0
|
port: 54329
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
@@ -7,7 +7,7 @@ spring:
|
|||||||
|
|
||||||
jpa:
|
jpa:
|
||||||
hibernate:
|
hibernate:
|
||||||
ddl-auto: validate
|
ddl-auto: create-drop
|
||||||
generate-ddl: true
|
generate-ddl: true
|
||||||
open-in-view: false
|
open-in-view: false
|
||||||
properties:
|
properties:
|
||||||
@@ -36,4 +36,8 @@ logging:
|
|||||||
|
|
||||||
# jpa query, parameter 로그 (p6spy)
|
# jpa query, parameter 로그 (p6spy)
|
||||||
decorator.datasource.p6spy:
|
decorator.datasource.p6spy:
|
||||||
enable-logging: true
|
enable-logging: true
|
||||||
|
|
||||||
|
kafka:
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 9092
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package com.justpickup.orderservice.domain.order.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||||
|
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
||||||
|
import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto;
|
||||||
|
import org.apache.kafka.clients.consumer.Consumer;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.kafka.annotation.EnableKafka;
|
||||||
|
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
|
||||||
|
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
|
||||||
|
import org.springframework.kafka.core.KafkaTemplate;
|
||||||
|
import org.springframework.kafka.support.SendResult;
|
||||||
|
import org.springframework.kafka.test.EmbeddedKafkaBroker;
|
||||||
|
import org.springframework.kafka.test.context.EmbeddedKafka;
|
||||||
|
import org.springframework.kafka.test.utils.KafkaTestUtils;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
import org.springframework.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@EnableKafka
|
||||||
|
@DirtiesContext
|
||||||
|
@EmbeddedKafka(topics = {"orderPlaced"})
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
class OrderSenderTest {
|
||||||
|
|
||||||
|
private final String TEST_TOPIC = "orderPlaced";
|
||||||
|
|
||||||
|
private Consumer<Integer, String> consumer;
|
||||||
|
private KafkaTemplate<String, String> producer;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmbeddedKafkaBroker embeddedKafkaBroker;
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
System.out.println("beforeAll");
|
||||||
|
producer = configureProducer();
|
||||||
|
consumer = configureConsumer();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Consumer<Integer, String> configureConsumer() {
|
||||||
|
Map<String, Object> consumerProps = KafkaTestUtils.consumerProps("testGroup", "true", embeddedKafkaBroker);
|
||||||
|
consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||||
|
Consumer<Integer, String> consumer = new DefaultKafkaConsumerFactory<Integer, String>(consumerProps)
|
||||||
|
.createConsumer();
|
||||||
|
consumer.subscribe(Collections.singleton(TEST_TOPIC));
|
||||||
|
return consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private KafkaTemplate<String, String> configureProducer() {
|
||||||
|
Map<String, Object> producerProps = new HashMap<>(KafkaTestUtils.producerProps(embeddedKafkaBroker));
|
||||||
|
return new KafkaTemplate <>( new DefaultKafkaProducerFactory<>(producerProps));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sendOrderPlaced() throws Exception{
|
||||||
|
//given
|
||||||
|
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
|
||||||
|
OrderSender.KafkaSendOrderDto kafkaSendOrderDto = new OrderSender.KafkaSendOrderDto(
|
||||||
|
1L,2L,"주문아이디",1L,12000L,2L, LocalDateTime.now(),3000L, OrderStatus.PLACED,
|
||||||
|
List.of(
|
||||||
|
OrderItemDto.of(1L,300L,3000L,2L,
|
||||||
|
List.of(new OrderItemOptionDto(2L)
|
||||||
|
,new OrderItemOptionDto(3L))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto);
|
||||||
|
|
||||||
|
//when
|
||||||
|
ListenableFuture<SendResult<String, String>> orderPlaced = producer.send("orderPlaced", jsonInString);
|
||||||
|
System.out.println(orderPlaced.get().toString());
|
||||||
|
//then
|
||||||
|
|
||||||
|
ConsumerRecord<Integer, String> singleRecord = KafkaTestUtils.getSingleRecord(consumer, TEST_TOPIC);
|
||||||
|
assertThat(singleRecord).isNotNull();
|
||||||
|
assertThat(singleRecord.value()).isEqualTo(jsonInString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,13 +2,16 @@ package com.justpickup.orderservice.domain.order.web;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.justpickup.orderservice.config.TestConfig;
|
import com.justpickup.orderservice.config.TestConfig;
|
||||||
|
import com.justpickup.orderservice.domain.order.dto.FetchOrderDto;
|
||||||
import com.justpickup.orderservice.domain.order.dto.OrderDto;
|
import com.justpickup.orderservice.domain.order.dto.OrderDto;
|
||||||
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||||
import com.justpickup.orderservice.domain.order.repository.OrderRepository;
|
import com.justpickup.orderservice.domain.order.repository.OrderRepository;
|
||||||
import com.justpickup.orderservice.domain.order.service.OrderService;
|
import com.justpickup.orderservice.domain.order.service.OrderService;
|
||||||
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
||||||
|
import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
@@ -17,20 +20,23 @@ import org.springframework.context.annotation.Import;
|
|||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.SliceImpl;
|
import org.springframework.data.domain.SliceImpl;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.ResultActions;
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
|
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
|
||||||
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
|
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
|
||||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
|
||||||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
|
||||||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
|
||||||
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
|
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
|
||||||
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
|
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
@@ -117,4 +123,113 @@ class OrderCustomerApiControllerTest {
|
|||||||
|
|
||||||
return new SliceImpl<>(contents, pageable, true);
|
return new SliceImpl<>(contents, pageable, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("장바구니 아이템 추가_성공")
|
||||||
|
void addItemToBasket() throws Exception {
|
||||||
|
//Given
|
||||||
|
OrderCustomerApiController.RequestItem requestItem;
|
||||||
|
// OrderItemDto orderItemDto;
|
||||||
|
// FetchOrderDto fetchOrderDto;
|
||||||
|
{
|
||||||
|
//givenData
|
||||||
|
requestItem = new OrderCustomerApiController.RequestItem(
|
||||||
|
102L, 1L, 3000L, 4L, List.of(1L, 2L, 3L, 4L, 5L)
|
||||||
|
);
|
||||||
|
|
||||||
|
// orderItemDto = OrderItemDto.of(-1L,
|
||||||
|
// requestItem.getItemId(),
|
||||||
|
// requestItem.getPrice(),
|
||||||
|
// requestItem.getCount(),
|
||||||
|
// requestItem.getItemOptionIds().stream().map(OrderItemOptionDto::new).collect(Collectors.toList()));
|
||||||
|
|
||||||
|
//willReturn data
|
||||||
|
|
||||||
|
}
|
||||||
|
//When
|
||||||
|
String body = objectMapper.writeValueAsString(requestItem);
|
||||||
|
|
||||||
|
ResultActions actions = mockMvc.perform(post(url + "/item")
|
||||||
|
.header("user-id", "2")
|
||||||
|
.content(body)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
|
);
|
||||||
|
|
||||||
|
//Then
|
||||||
|
|
||||||
|
actions.andExpect(status().isNoContent())
|
||||||
|
.andDo(print())
|
||||||
|
.andDo(document("add-item-to-basket",
|
||||||
|
requestHeaders(headerWithName("user-id").description("유저 고유번호")),
|
||||||
|
requestFields(
|
||||||
|
fieldWithPath("itemId").description("아이템 고유번호"),
|
||||||
|
fieldWithPath("storeId").description("매장 고유번호"),
|
||||||
|
fieldWithPath("price").description("아이템 가격"),
|
||||||
|
fieldWithPath("count").description("아이템 갯수"),
|
||||||
|
fieldWithPath("itemOptionIds").description("아이템 옵션들")
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("장바구니 정보 조회_성공")
|
||||||
|
void fetchOrder() throws Exception{
|
||||||
|
//Given
|
||||||
|
FetchOrderDto fetchOrderDto =
|
||||||
|
new FetchOrderDto(2L,2L,12000L,2L
|
||||||
|
,List.of(
|
||||||
|
OrderItemDto.of(1L,300L,3000L,2L,
|
||||||
|
List.of(new OrderItemOptionDto(2L)
|
||||||
|
,new OrderItemOptionDto(3L))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
given(orderService.fetchOrder(2L)).willReturn(fetchOrderDto);
|
||||||
|
//When
|
||||||
|
|
||||||
|
ResultActions actions = mockMvc.perform(get(url + "/orders")
|
||||||
|
.header("user-id", "2")
|
||||||
|
);
|
||||||
|
|
||||||
|
//Then
|
||||||
|
actions.andExpect(status().isOk())
|
||||||
|
.andDo(print())
|
||||||
|
.andDo(document("fetch-order",
|
||||||
|
requestHeaders(headerWithName("user-id").description("유저 고유번호")),
|
||||||
|
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("아이템 옵션들")
|
||||||
|
)));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("주문 및 mq produce_성공")
|
||||||
|
void saveOrder() throws Exception{
|
||||||
|
//Given
|
||||||
|
|
||||||
|
//When
|
||||||
|
ResultActions actions = mockMvc.perform(post(url + "/orders")
|
||||||
|
.header("user-id", "2")
|
||||||
|
);
|
||||||
|
//Then
|
||||||
|
actions.andExpect(status().isCreated())
|
||||||
|
.andDo(print())
|
||||||
|
.andDo(document("save-order",
|
||||||
|
requestHeaders(headerWithName("user-id").description("유저 고유번호"))
|
||||||
|
));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.justpickup.storeservice.domain.item.dto;
|
||||||
|
|
||||||
|
import com.justpickup.storeservice.domain.category.dto.CategoryDto;
|
||||||
|
import com.justpickup.storeservice.domain.item.entity.Item;
|
||||||
|
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
||||||
|
import com.justpickup.storeservice.domain.store.dto.StoreDto;
|
||||||
|
import com.justpickup.storeservice.global.entity.Yn;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class FetchItemDto {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Yn salesYn;
|
||||||
|
|
||||||
|
private Long price;
|
||||||
|
|
||||||
|
private CategoryDto categoryDto;
|
||||||
|
|
||||||
|
private List<ItemOptionDto> itemOptions;
|
||||||
|
|
||||||
|
private StoreDto storeDto;
|
||||||
|
|
||||||
|
public FetchItemDto(Item item) {
|
||||||
|
this.id = item.getId();
|
||||||
|
this.name = item.getName();
|
||||||
|
this.salesYn = item.getSalesYn();
|
||||||
|
this.price = item.getPrice();
|
||||||
|
this.categoryDto = new CategoryDto(item.getCategory());
|
||||||
|
this.itemOptions = item.getItemOptions().stream().map(ItemOptionDto::new).collect(Collectors.toList());
|
||||||
|
this.storeDto = new StoreDto(item.getStore().getId(), item.getStore().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,9 +3,7 @@ package com.justpickup.storeservice.domain.item.repository;
|
|||||||
import com.justpickup.storeservice.domain.category.entity.QCategory;
|
import com.justpickup.storeservice.domain.category.entity.QCategory;
|
||||||
import com.justpickup.storeservice.domain.item.entity.Item;
|
import com.justpickup.storeservice.domain.item.entity.Item;
|
||||||
import com.justpickup.storeservice.domain.item.entity.QItem;
|
import com.justpickup.storeservice.domain.item.entity.QItem;
|
||||||
import com.justpickup.storeservice.domain.itemoption.entity.ItemOption;
|
|
||||||
import com.justpickup.storeservice.domain.itemoption.entity.QItemOption;
|
import com.justpickup.storeservice.domain.itemoption.entity.QItemOption;
|
||||||
import com.justpickup.storeservice.domain.store.entity.QStore;
|
|
||||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -22,7 +20,7 @@ public class ItemRepositoryCustom {
|
|||||||
|
|
||||||
private final JPAQueryFactory queryFactory;
|
private final JPAQueryFactory queryFactory;
|
||||||
|
|
||||||
public Optional<Item> findById(Long itemId){
|
public Optional<Item> fetchItem(Long itemId){
|
||||||
Item item = queryFactory.selectFrom(QItem.item)
|
Item item = queryFactory.selectFrom(QItem.item)
|
||||||
.join(QItem.item.itemOptions, QItemOption.itemOption).fetchJoin()
|
.join(QItem.item.itemOptions, QItemOption.itemOption).fetchJoin()
|
||||||
.join(QItem.item.category,QCategory.category).fetchJoin()
|
.join(QItem.item.category,QCategory.category).fetchJoin()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.justpickup.storeservice.domain.item.service;
|
package com.justpickup.storeservice.domain.item.service;
|
||||||
|
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.FetchItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.web.ItemController;
|
|
||||||
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@@ -12,7 +12,7 @@ public interface ItemService {
|
|||||||
|
|
||||||
ItemDto findItemByItemId(Long itemId);
|
ItemDto findItemByItemId(Long itemId);
|
||||||
|
|
||||||
ItemDto findFullItemByItemId(Long itemId);
|
FetchItemDto fetchItem(Long itemId);
|
||||||
|
|
||||||
Page<ItemDto> findItemList(Long userId,String word, Pageable pageable);
|
Page<ItemDto> findItemList(Long userId,String word, Pageable pageable);
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ package com.justpickup.storeservice.domain.item.service;
|
|||||||
|
|
||||||
import com.justpickup.storeservice.domain.category.entity.Category;
|
import com.justpickup.storeservice.domain.category.entity.Category;
|
||||||
import com.justpickup.storeservice.domain.category.repository.CategoryRepository;
|
import com.justpickup.storeservice.domain.category.repository.CategoryRepository;
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.FetchItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.entity.Item;
|
import com.justpickup.storeservice.domain.item.entity.Item;
|
||||||
import com.justpickup.storeservice.domain.item.exception.NotExistItemException;
|
import com.justpickup.storeservice.domain.item.exception.NotExistItemException;
|
||||||
import com.justpickup.storeservice.domain.item.repository.ItemRepository;
|
import com.justpickup.storeservice.domain.item.repository.ItemRepository;
|
||||||
import com.justpickup.storeservice.domain.item.repository.ItemRepositoryCustom;
|
import com.justpickup.storeservice.domain.item.repository.ItemRepositoryCustom;
|
||||||
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
||||||
import com.justpickup.storeservice.domain.itemoption.entity.ItemOption;
|
|
||||||
import com.justpickup.storeservice.domain.itemoption.repository.ItemOptionRepository;
|
import com.justpickup.storeservice.domain.itemoption.repository.ItemOptionRepository;
|
||||||
import com.justpickup.storeservice.domain.store.entity.Store;
|
import com.justpickup.storeservice.domain.store.entity.Store;
|
||||||
import com.justpickup.storeservice.domain.store.repository.StoreRepository;
|
import com.justpickup.storeservice.domain.store.repository.StoreRepository;
|
||||||
@@ -46,11 +46,11 @@ public class ItemServiceImpl implements ItemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemDto findFullItemByItemId(Long itemId) {
|
public FetchItemDto fetchItem(Long itemId) {
|
||||||
Item findItem = itemRepositoryCustom.findById(itemId)
|
Item findItem = itemRepositoryCustom.fetchItem(itemId)
|
||||||
.orElseThrow(() -> new NotExistItemException("존재하지 않는 아이템 입니다."));
|
.orElseThrow(() -> new NotExistItemException("존재하지 않는 아이템 입니다."));
|
||||||
|
|
||||||
return ItemDto.createWithCategoryItemDtoAndItemOption(findItem);
|
return new FetchItemDto(findItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package com.justpickup.storeservice.domain.item.web;
|
||||||
|
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.FetchItemDto;
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
||||||
|
import com.justpickup.storeservice.domain.item.service.ItemService;
|
||||||
|
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
||||||
|
import com.justpickup.storeservice.domain.itemoption.entity.OptionType;
|
||||||
|
import com.justpickup.storeservice.global.dto.Result;
|
||||||
|
import com.justpickup.storeservice.global.entity.Yn;
|
||||||
|
import lombok.*;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/api/customer")
|
||||||
|
public class ItemCustomerApiController {
|
||||||
|
|
||||||
|
private final ItemService itemService;
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/item/{itemId}")
|
||||||
|
public ResponseEntity getItem(@PathVariable("itemId") Long itemId) {
|
||||||
|
FetchItemDto fetchItem = itemService.fetchItem(itemId);
|
||||||
|
|
||||||
|
GetItemResponse getItemResponse = new GetItemResponse(fetchItem);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
|
.body(Result.createSuccessResult(getItemResponse));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data @NoArgsConstructor @AllArgsConstructor
|
||||||
|
static class GetItemResponse {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private Yn salesYn;
|
||||||
|
private Long price;
|
||||||
|
private Long CategoryId;
|
||||||
|
private List<ItemOptionResponse> itemOptions;
|
||||||
|
private Long storeId;
|
||||||
|
|
||||||
|
public GetItemResponse(FetchItemDto fetchItemDto) {
|
||||||
|
this.id = fetchItemDto.getId();
|
||||||
|
this.name = fetchItemDto.getName();
|
||||||
|
this.salesYn = fetchItemDto.getSalesYn();
|
||||||
|
this.price = fetchItemDto.getPrice();
|
||||||
|
this.CategoryId = fetchItemDto.getCategoryDto().getId();
|
||||||
|
this.itemOptions = fetchItemDto.getItemOptions()
|
||||||
|
.stream().map(ItemOptionResponse::new)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
this.storeId = fetchItemDto.getStoreDto().getStoreId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
static class ItemOptionResponse{
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private OptionType optionType;
|
||||||
|
|
||||||
|
private Long price;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public ItemOptionResponse(ItemOptionDto itemOptionDto) {
|
||||||
|
|
||||||
|
this.id = itemOptionDto.getId();
|
||||||
|
this.optionType = itemOptionDto.getOptionType();
|
||||||
|
this.price = itemOptionDto.getPrice();
|
||||||
|
this.name = itemOptionDto.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.justpickup.storeservice.domain.item.web;
|
package com.justpickup.storeservice.domain.item.web;
|
||||||
|
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.FetchItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.service.ItemService;
|
import com.justpickup.storeservice.domain.item.service.ItemService;
|
||||||
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
||||||
@@ -90,9 +91,9 @@ public class ItemOwnerApiController {
|
|||||||
|
|
||||||
@GetMapping("/item/{itemId}")
|
@GetMapping("/item/{itemId}")
|
||||||
public ResponseEntity getItem(@PathVariable("itemId") Long itemId) {
|
public ResponseEntity getItem(@PathVariable("itemId") Long itemId) {
|
||||||
ItemDto itemByItemId = itemService.findFullItemByItemId(itemId);
|
FetchItemDto fetchItemDto = itemService.fetchItem(itemId);
|
||||||
|
|
||||||
GetItemResponse getItemResponse = new GetItemResponse(itemByItemId);
|
GetItemResponse getItemResponse = new GetItemResponse(fetchItemDto);
|
||||||
return ResponseEntity.status(HttpStatus.OK)
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
.body(Result.createSuccessResult(getItemResponse));
|
.body(Result.createSuccessResult(getItemResponse));
|
||||||
}
|
}
|
||||||
@@ -106,13 +107,13 @@ public class ItemOwnerApiController {
|
|||||||
private Long CategoryId;
|
private Long CategoryId;
|
||||||
private List<ItemOptionResponse> itemOptions;
|
private List<ItemOptionResponse> itemOptions;
|
||||||
|
|
||||||
public GetItemResponse(ItemDto itemDto) {
|
public GetItemResponse(FetchItemDto fetchItemDto) {
|
||||||
this.id = itemDto.getId();
|
this.id = fetchItemDto.getId();
|
||||||
this.name = itemDto.getName();
|
this.name = fetchItemDto.getName();
|
||||||
this.salesYn = itemDto.getSalesYn();
|
this.salesYn = fetchItemDto.getSalesYn();
|
||||||
this.price = itemDto.getPrice();
|
this.price = fetchItemDto.getPrice();
|
||||||
this.CategoryId = itemDto.getCategoryDto().getId();
|
this.CategoryId = fetchItemDto.getCategoryDto().getId();
|
||||||
this.itemOptions = itemDto.getItemOptions()
|
this.itemOptions = fetchItemDto.getItemOptions()
|
||||||
.stream().map(ItemOptionResponse::new)
|
.stream().map(ItemOptionResponse::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,5 +18,4 @@ public class StoreDto {
|
|||||||
this.name = store.getName();
|
this.name = store.getName();
|
||||||
this.phoneNumber = store.getPhoneNumber();
|
this.phoneNumber = store.getPhoneNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ spring:
|
|||||||
|
|
||||||
jpa:
|
jpa:
|
||||||
hibernate:
|
hibernate:
|
||||||
ddl-auto: validate
|
ddl-auto: create-drop
|
||||||
generate-ddl: true
|
generate-ddl: true
|
||||||
open-in-view: false
|
open-in-view: false
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import com.justpickup.storeservice.config.TestConfig;
|
import com.justpickup.storeservice.config.TestConfig;
|
||||||
import com.justpickup.storeservice.domain.category.dto.CategoryDto;
|
import com.justpickup.storeservice.domain.category.dto.CategoryDto;
|
||||||
import com.justpickup.storeservice.domain.favoritestore.repository.FavoriteStoreRepository;
|
import com.justpickup.storeservice.domain.favoritestore.repository.FavoriteStoreRepository;
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.FetchItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.exception.NotExistItemException;
|
|
||||||
import com.justpickup.storeservice.domain.item.service.ItemService;
|
import com.justpickup.storeservice.domain.item.service.ItemService;
|
||||||
import com.justpickup.storeservice.domain.itemoption.entity.OptionType;
|
import com.justpickup.storeservice.domain.itemoption.entity.OptionType;
|
||||||
import com.justpickup.storeservice.domain.store.repository.StoreRepository;
|
import com.justpickup.storeservice.domain.store.repository.StoreRepository;
|
||||||
@@ -21,15 +21,12 @@ import org.springframework.context.annotation.Import;
|
|||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.support.PageableExecutionUtils;
|
import org.springframework.data.support.PageableExecutionUtils;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.ResultActions;
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.LongSupplier;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
@@ -118,7 +115,7 @@ class ItemOwnerApiControllerTest {
|
|||||||
void getItem() throws Exception {
|
void getItem() throws Exception {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
long itemId = 1L;
|
long itemId = 1L;
|
||||||
ItemDto willReturnDto = ItemDto.builder()
|
FetchItemDto willReturnDto = FetchItemDto.builder()
|
||||||
.id(1L)
|
.id(1L)
|
||||||
.salesYn(Yn.Y)
|
.salesYn(Yn.Y)
|
||||||
.price(1500L)
|
.price(1500L)
|
||||||
@@ -126,7 +123,7 @@ class ItemOwnerApiControllerTest {
|
|||||||
.itemOptions(new ArrayList<>())
|
.itemOptions(new ArrayList<>())
|
||||||
.categoryDto(new CategoryDto())
|
.categoryDto(new CategoryDto())
|
||||||
.build();
|
.build();
|
||||||
given(itemService.findFullItemByItemId(itemId))
|
given(itemService.fetchItem(itemId))
|
||||||
.willReturn(willReturnDto);
|
.willReturn(willReturnDto);
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||||||
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
|
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableEurekaClient
|
@EnableEurekaClient
|
||||||
public class UserServiceApplication {
|
public class UserServiceApplication {
|
||||||
|
|||||||
Reference in New Issue
Block a user