Merge pull request #58 from Development-team-1/owner_dashboard
Owner dashboard
This commit is contained in:
@@ -24,6 +24,9 @@ export default {
|
|||||||
getOrder() {
|
getOrder() {
|
||||||
return axios.get(process.env.VUE_APP_ORDER_API_URL + "/order/orders");
|
return axios.get(process.env.VUE_APP_ORDER_API_URL + "/order/orders");
|
||||||
},
|
},
|
||||||
|
deleteOrderItem(orderItemId){
|
||||||
|
return axios.delete(process.env.VUE_APP_ORDER_API_URL + "/orderItem/"+orderItemId);
|
||||||
|
},
|
||||||
getOrderDetail(orderId) {
|
getOrderDetail(orderId) {
|
||||||
return axios.get(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL + "/order-service/api/order-detail/" + orderId);
|
return axios.get(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL + "/order-service/api/order-detail/" + orderId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,9 @@
|
|||||||
<v-app-bar-nav-icon @click="$router.back()">
|
<v-app-bar-nav-icon @click="$router.back()">
|
||||||
<v-icon>mdi-arrow-left</v-icon>
|
<v-icon>mdi-arrow-left</v-icon>
|
||||||
</v-app-bar-nav-icon>
|
</v-app-bar-nav-icon>
|
||||||
|
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-toolbar-title>
|
<v-toolbar-title style="position: absolute; left: 50%; transform:translateX(-50%);">
|
||||||
<v-img :src="require('@/assets/just-logo.png')"></v-img>
|
<v-img :src="require('@/assets/just-logo.png')"></v-img>
|
||||||
</v-toolbar-title>
|
</v-toolbar-title>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<v-icon>mdi-arrow-left</v-icon>
|
<v-icon>mdi-arrow-left</v-icon>
|
||||||
</v-app-bar-nav-icon>
|
</v-app-bar-nav-icon>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-toolbar-title>
|
<v-toolbar-title style="position: absolute; left: 50%; transform:translateX(-50%);">
|
||||||
<b>{{store.name}}</b>
|
<b>{{store.name}}</b>
|
||||||
</v-toolbar-title>
|
</v-toolbar-title>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
@@ -23,11 +23,19 @@
|
|||||||
:color="favoriteStore.color"
|
:color="favoriteStore.color"
|
||||||
>{{ favoriteStore.icon }}</v-icon>
|
>{{ favoriteStore.icon }}</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
color="white"
|
||||||
|
elevation="0"
|
||||||
|
@click="logout"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-logout</v-icon>
|
||||||
|
</v-btn>
|
||||||
</v-app-bar>
|
</v-app-bar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import storeApi from "@/api/store";
|
import storeApi from "@/api/store";
|
||||||
|
import authApi from "@/api/auth";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "StoreNavigation",
|
name: "StoreNavigation",
|
||||||
@@ -71,7 +79,14 @@ export default {
|
|||||||
}
|
}
|
||||||
this.favoriteStore.status= !this.favoriteStore.status
|
this.favoriteStore.status= !this.favoriteStore.status
|
||||||
|
|
||||||
|
},
|
||||||
|
logout: function () {
|
||||||
|
if(confirm("로그아웃하시겠습니까?")){
|
||||||
|
authApi.logout();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
console.log(this.$route.params)
|
console.log(this.$route.params)
|
||||||
|
|||||||
@@ -64,12 +64,12 @@ const routes = [
|
|||||||
name: 'notification',
|
name: 'notification',
|
||||||
component: () => import('../views/NotificationView')
|
component: () => import('../views/NotificationView')
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
path: "/item/:itemId",
|
// path: "/item/:itemId",
|
||||||
beforeEnter: authCheck,
|
// beforeEnter: authCheck,
|
||||||
name: 'itemDetail',
|
// name: 'itemDetail',
|
||||||
component: () => import('../views/ItemDetail')
|
// component: () => import('../views/ItemDetail')
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: "/order",
|
path: "/order",
|
||||||
beforeEnter: authCheck,
|
beforeEnter: authCheck,
|
||||||
@@ -110,6 +110,19 @@ const routes = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/item',
|
||||||
|
redirect: 'item',
|
||||||
|
component: StoreLayout,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "/item/:itemId",
|
||||||
|
beforeEnter: authCheck,
|
||||||
|
name: 'itemDetail',
|
||||||
|
component: () => import('../views/ItemDetail')
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/auth',
|
path: '/auth',
|
||||||
name: 'auth',
|
name: 'auth',
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ export default {
|
|||||||
storeId:-1,
|
storeId:-1,
|
||||||
itemId:-1,
|
itemId:-1,
|
||||||
price:0,
|
price:0,
|
||||||
requireOption:{},
|
|
||||||
otherOptions:[],
|
otherOptions:[],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,17 +8,6 @@
|
|||||||
<router-view
|
<router-view
|
||||||
v-on:getStoreId="renderNavigation">
|
v-on:getStoreId="renderNavigation">
|
||||||
</router-view>
|
</router-view>
|
||||||
<div align="right" >
|
|
||||||
<v-btn
|
|
||||||
color="primary"
|
|
||||||
dark
|
|
||||||
right
|
|
||||||
fab
|
|
||||||
@click="toOrder"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-basket</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-main>
|
</v-main>
|
||||||
<bottom-navigation></bottom-navigation>
|
<bottom-navigation></bottom-navigation>
|
||||||
@@ -56,11 +45,6 @@ export default {
|
|||||||
|
|
||||||
const response = await storeApi.requestStore(this.store.id);
|
const response = await storeApi.requestStore(this.store.id);
|
||||||
this.store = response.data.data;
|
this.store = response.data.data;
|
||||||
},
|
|
||||||
toOrder(){
|
|
||||||
if(confirm("주문화면으로 이동할까요?")){
|
|
||||||
this.$router.push("/order")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,9 @@
|
|||||||
/>
|
/>
|
||||||
<v-btn
|
<v-btn
|
||||||
color="orange"
|
color="orange"
|
||||||
block>수정하기</v-btn>
|
block
|
||||||
|
@click="message('준비중입니다.')"
|
||||||
|
>수정하기</v-btn>
|
||||||
</v-form>
|
</v-form>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
@@ -76,6 +78,9 @@ export default {
|
|||||||
console.log(error.response)
|
console.log(error.response)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
message: function(message){
|
||||||
|
alert(message)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getUserData()
|
this.getUserData()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<v-row>
|
<v-row>
|
||||||
<v-col
|
<v-col
|
||||||
v-for=" orderItem in orderData.orderItemDtoList"
|
v-for=" orderItem in orderData.orderItemDtoList"
|
||||||
:key = "orderItem.itemId"
|
:key = "orderItem.id"
|
||||||
>
|
>
|
||||||
<v-card
|
<v-card
|
||||||
class="mx-auto mb-5"
|
class="mx-auto mb-5"
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<div class="text-body-1 mb-5" style="white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">
|
<div class="text-body-1 mb-5" style="white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">
|
||||||
{{ orderItem.orderItemOptionDtoList ?
|
{{ orderItem.orderItemOptionDtoList ?
|
||||||
orderItem.orderItemOptionDtoList.map(x=>x.name).join(', ')
|
orderItem.orderItemOptionDtoList.map(x=>x.name).join(', ')
|
||||||
: null}}
|
: null}}
|
||||||
</div>
|
</div>
|
||||||
<div class="text--primary">
|
<div class="text--primary">
|
||||||
합계 : <b> {{ orderItem.count * orderItem.price | currency}} 원</b>
|
합계 : <b> {{ orderItem.count * orderItem.price | currency}} 원</b>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
|
||||||
<v-card-actions class="pb-2">
|
<v-card-actions class="pb-2">
|
||||||
<v-btn block color="warning" @click="message('준비중입니다.')">삭제하기</v-btn>
|
<v-btn block color="warning" @click="deleteOrderItem(orderItem)">삭제하기</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
|
|
||||||
</v-card>
|
</v-card>
|
||||||
@@ -98,7 +98,6 @@ export default {
|
|||||||
getOrder: function(){
|
getOrder: function(){
|
||||||
orderApi.getOrder()
|
orderApi.getOrder()
|
||||||
.then(response=>{
|
.then(response=>{
|
||||||
console.log(response)
|
|
||||||
this.orderData=response.data.data
|
this.orderData=response.data.data
|
||||||
})
|
})
|
||||||
.catch(error=>{
|
.catch(error=>{
|
||||||
@@ -107,9 +106,27 @@ export default {
|
|||||||
console.log(error.response)
|
console.log(error.response)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
message: function(message){
|
deleteOrderItem: function(orderItem){
|
||||||
alert(message)
|
var vm = this
|
||||||
}
|
const deleteOrderItemId = orderItem.id
|
||||||
|
console.log(deleteOrderItemId)
|
||||||
|
orderApi.deleteOrderItem(deleteOrderItemId)
|
||||||
|
.then(response=>{
|
||||||
|
console.log(response)
|
||||||
|
alert(response.data.data+"삭제되었습니다.")
|
||||||
|
vm.orderData.orderPrice -=orderItem.price
|
||||||
|
vm.orderData.orderItemDtoList.splice(
|
||||||
|
vm.orderData.orderItemDtoList.indexOf(orderItem),1
|
||||||
|
)
|
||||||
|
if(vm.orderData.orderItemDtoList.length ==0)
|
||||||
|
this.$router.back()
|
||||||
|
})
|
||||||
|
.catch(error=>{
|
||||||
|
alert("문제가 발생하였습니다.")
|
||||||
|
console.log(error.response)
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -54,6 +54,17 @@
|
|||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div align="right" >
|
||||||
|
<v-btn
|
||||||
|
color="primary"
|
||||||
|
dark
|
||||||
|
right
|
||||||
|
fab
|
||||||
|
@click="toOrder"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-basket</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -94,6 +105,11 @@ export default {
|
|||||||
},
|
},
|
||||||
itemDetail: function (itemId) {
|
itemDetail: function (itemId) {
|
||||||
this.$router.push("/item/"+itemId)
|
this.$router.push("/item/"+itemId)
|
||||||
|
},
|
||||||
|
toOrder(){
|
||||||
|
if(confirm("주문화면으로 이동할까요?")){
|
||||||
|
this.$router.push("/order")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,9 @@ operation::prevOrder-get[snippets='curl-request,http-request,http-response,reque
|
|||||||
=== 점주 서비스 - 지난 주문 페이지 (잘못된 파라미터 형식)
|
=== 점주 서비스 - 지난 주문 페이지 (잘못된 파라미터 형식)
|
||||||
operation::prevOrder-get-BindException[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields']
|
operation::prevOrder-get-BindException[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields']
|
||||||
|
|
||||||
|
=== 점주 서비스 - 대쉬보드
|
||||||
|
operation::owner-findDashboard[snippets='curl-request,http-request,http-response,request-headers,response-fields']
|
||||||
|
|
||||||
== 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']
|
||||||
@@ -95,5 +98,9 @@ operation::add-item-to-basket[snippets='curl-request,http-request,http-response,
|
|||||||
=== 장바구니 내역 가져오기
|
=== 장바구니 내역 가져오기
|
||||||
operation::fetch-order[snippets='curl-request,http-request,http-response,request-headers,response-fields']
|
operation::fetch-order[snippets='curl-request,http-request,http-response,request-headers,response-fields']
|
||||||
|
|
||||||
|
=== 장바구니 상품 삭제
|
||||||
|
operation::delete-orderItem[snippets='curl-request,http-request,http-response,request-headers,path-parameters,response-fields']
|
||||||
|
|
||||||
|
|
||||||
=== 주문하기
|
=== 주문하기
|
||||||
operation::save-order[snippets='curl-request,http-request,http-response,request-headers']
|
operation::save-order[snippets='curl-request,http-request,http-response,request-headers']
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.justpickup.orderservice.domain.order.dto;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class DashBoardDto {
|
||||||
|
|
||||||
|
//일일 판매금액
|
||||||
|
private Long salesAmount=0L;
|
||||||
|
private BestSellItem bestSellItem;
|
||||||
|
List<SellAmountAWeek> sellAmountAWeeks;
|
||||||
|
|
||||||
|
public static DashBoardDto of(List<OrderPrice> orderPrices , DashBoardDto.BestSellItem bestSellItem , List<SellAmountAWeek> sellAmountAWeeks){
|
||||||
|
DashBoardDto dashBoardDto = new DashBoardDto();
|
||||||
|
orderPrices.forEach(orderPrice -> dashBoardDto.salesAmount+=orderPrice.getOrderPrice());
|
||||||
|
dashBoardDto.bestSellItem = bestSellItem;
|
||||||
|
dashBoardDto.sellAmountAWeeks = sellAmountAWeeks;
|
||||||
|
|
||||||
|
return dashBoardDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class OrderPrice{
|
||||||
|
Long orderPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class BestSellItem{
|
||||||
|
Long itemId;
|
||||||
|
String itemName;
|
||||||
|
Long sumCounts;
|
||||||
|
|
||||||
|
public void setItemName(String itemName) {
|
||||||
|
this.itemName = itemName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class SellAmountAWeek{
|
||||||
|
Object sellDate;
|
||||||
|
Long sellAmount;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
package com.justpickup.orderservice.domain.order.dto;
|
package com.justpickup.orderservice.domain.order.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 com.justpickup.orderservice.domain.orderItemOption.entity.OrderItemOption;
|
||||||
import com.justpickup.orderservice.global.client.store.GetItemResponse;
|
import com.justpickup.orderservice.global.client.store.GetItemResponse;
|
||||||
|
import com.justpickup.orderservice.global.client.store.OptionType;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@@ -33,7 +37,9 @@ public class FetchOrderDto {
|
|||||||
|
|
||||||
private String itemName;
|
private String itemName;
|
||||||
|
|
||||||
private List<GetItemResponse.ItemOptionDto> orderItemOptionDtoList;
|
private List<OrderItemOptionDto> orderItemOptionDtoList;
|
||||||
|
|
||||||
|
// private List<GetItemResponse.ItemOptionDto> orderItemOptionDtoList;
|
||||||
|
|
||||||
private Long price;
|
private Long price;
|
||||||
|
|
||||||
@@ -43,10 +49,35 @@ public class FetchOrderDto {
|
|||||||
this.id = orderItem.getId();
|
this.id = orderItem.getId();
|
||||||
this.itemId = getItemResponse.getId();
|
this.itemId = getItemResponse.getId();
|
||||||
this.itemName = getItemResponse.getName();
|
this.itemName = getItemResponse.getName();
|
||||||
this.orderItemOptionDtoList = getItemResponse.getItemOptions();
|
|
||||||
|
//getItemResponse에는 해당 item에 존재하는 itemOption들이 전부 들어있으므로, orderItem에서 orderItemOption에 있는값들을 가져와서 매칭해줌
|
||||||
|
this.orderItemOptionDtoList = orderItem.getOrderItemOptions().stream().map(orderItemOption -> {
|
||||||
|
OrderItemOptionDto orderItemOptionDto = new OrderItemOptionDto(orderItemOption.getId(), null, null);
|
||||||
|
for (GetItemResponse.ItemOptionDto responseItemOption : getItemResponse.getItemOptions()) {
|
||||||
|
|
||||||
|
if (responseItemOption.getId().equals(orderItemOption.getItemOptionId())) {
|
||||||
|
orderItemOptionDto = new OrderItemOptionDto(orderItemOption.getId(), responseItemOption.getOptionType(), responseItemOption.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orderItemOptionDto;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// this.orderItemOptionDtoList = getItemResponse.getItemOptions();
|
||||||
this.price = orderItem.getPrice();
|
this.price = orderItem.getPrice();
|
||||||
this.count = orderItem.getCount();
|
this.count = orderItem.getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class OrderItemOptionDto{
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private OptionType optionType;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class Order extends BaseEntity {
|
|||||||
private Transaction transaction;
|
private Transaction transaction;
|
||||||
|
|
||||||
@BatchSize(size = 100)
|
@BatchSize(size = 100)
|
||||||
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
|
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
private List<OrderItem> orderItems = new ArrayList<>();
|
private List<OrderItem> orderItems = new ArrayList<>();
|
||||||
|
|
||||||
public static Order of(Long userId, Long userCouponId, Long storeId, OrderItem orderItem) {
|
public static Order of(Long userId, Long userCouponId, Long storeId, OrderItem orderItem) {
|
||||||
@@ -83,6 +83,13 @@ public class Order extends BaseEntity {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Order deleteOrderItem(OrderItem orderItem) {
|
||||||
|
this.orderPrice -= orderItem.getTotalPrice();
|
||||||
|
this.orderItems.remove(orderItem);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public void setOrderStatus(OrderStatus orderStatus){
|
public void setOrderStatus(OrderStatus orderStatus){
|
||||||
this.orderStatus = orderStatus;
|
this.orderStatus = orderStatus;
|
||||||
}
|
}
|
||||||
@@ -105,8 +112,4 @@ public class Order extends BaseEntity {
|
|||||||
public void fail() {
|
public void fail() {
|
||||||
this.orderStatus = OrderStatus.FAILED;
|
this.orderStatus = OrderStatus.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changOrderTime(LocalDateTime orderTime) {
|
|
||||||
this.orderTime = orderTime;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface OrderRepository extends JpaRepository<Order, Long> {
|
public interface OrderRepository extends JpaRepository<Order, Long> {
|
||||||
|
Long countByUserIdAndOrderStatus(Long userId, OrderStatus orderStatus);
|
||||||
Optional<Order> findByUserIdAndOrderStatus(Long userId, OrderStatus orderStatus);
|
Optional<Order> findByUserIdAndOrderStatus(Long userId, OrderStatus orderStatus);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package com.justpickup.orderservice.domain.order.repository;
|
package com.justpickup.orderservice.domain.order.repository;
|
||||||
|
|
||||||
|
import com.justpickup.orderservice.domain.order.dto.DashBoardDto;
|
||||||
import com.justpickup.orderservice.domain.order.dto.OrderMainResult;
|
import com.justpickup.orderservice.domain.order.dto.OrderMainResult;
|
||||||
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.entity.OrderStatus;
|
||||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
import com.querydsl.core.types.ConstantImpl;
|
||||||
|
import com.querydsl.core.types.Projections;
|
||||||
|
import com.querydsl.core.types.dsl.*;
|
||||||
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;
|
||||||
@@ -139,4 +142,75 @@ public class OrderRepositoryCustom {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<DashBoardDto.OrderPrice> salesAmountBetweenADay(Long storeId){
|
||||||
|
LocalDateTime today = LocalDateTime.now();
|
||||||
|
LocalDateTime startTime = LocalDateTime.of(today.getYear(),today.getMonth(),today.getDayOfMonth(),0,0);
|
||||||
|
|
||||||
|
return queryFactory
|
||||||
|
.select(Projections.fields(DashBoardDto.OrderPrice.class,
|
||||||
|
order.orderPrice
|
||||||
|
))
|
||||||
|
.from(order)
|
||||||
|
.where(
|
||||||
|
order.storeId.eq(storeId)
|
||||||
|
.and( order.orderTime.between(startTime,today))
|
||||||
|
).fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashBoardDto.BestSellItem bestItemBetweenAWeek(Long storeId){
|
||||||
|
LocalDateTime today = LocalDateTime.now();
|
||||||
|
LocalDateTime startTime = LocalDateTime.of(today.getYear(),
|
||||||
|
today.getMonth(),
|
||||||
|
today.getDayOfMonth(),
|
||||||
|
0,0)
|
||||||
|
.minusDays(7);
|
||||||
|
|
||||||
|
return queryFactory.
|
||||||
|
select(
|
||||||
|
Projections.fields(DashBoardDto.BestSellItem.class,
|
||||||
|
orderItem.itemId.as("itemId"),
|
||||||
|
orderItem.count.sum().as("sumCounts")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(orderItem)
|
||||||
|
.join(orderItem.order, order)
|
||||||
|
.where(orderItem.order.storeId.eq(storeId)
|
||||||
|
.and(orderItem.order.orderTime.between(startTime,today)))
|
||||||
|
.groupBy(orderItem.itemId)
|
||||||
|
.orderBy(orderItem.count.sum().desc())
|
||||||
|
.limit(1L)
|
||||||
|
.fetchOne()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DashBoardDto.SellAmountAWeek> salesAmountBetweenAWeek(Long storeId){
|
||||||
|
LocalDateTime today = LocalDateTime.now();
|
||||||
|
LocalDateTime startTime = LocalDateTime.of(today.getYear(),
|
||||||
|
today.getMonth(),
|
||||||
|
today.getDayOfMonth(),
|
||||||
|
0,0)
|
||||||
|
.minusDays(7);
|
||||||
|
|
||||||
|
|
||||||
|
DateTimeTemplate formattedDate =
|
||||||
|
Expressions.dateTimeTemplate(LocalDateTime.class,
|
||||||
|
"CAST({0} AS date) ", orderItem.order.orderTime );
|
||||||
|
|
||||||
|
return queryFactory.
|
||||||
|
select(
|
||||||
|
Projections.fields(DashBoardDto.SellAmountAWeek.class,
|
||||||
|
formattedDate.as("sellDate"),
|
||||||
|
orderItem.price.sum().multiply(orderItem.count.sum()).as("sellAmount")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(orderItem)
|
||||||
|
.join(orderItem.order, order)
|
||||||
|
.where(orderItem.order.storeId.eq(storeId)
|
||||||
|
.and(orderItem.order.orderTime.between(startTime,today)))
|
||||||
|
.groupBy(formattedDate)
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.springframework.data.domain.SliceImpl;
|
|||||||
|
|
||||||
public interface OrderService {
|
public interface OrderService {
|
||||||
OrderMainDto findOrderMain(OrderSearchCondition condition, Long userId);
|
OrderMainDto findOrderMain(OrderSearchCondition condition, Long userId);
|
||||||
|
DashBoardDto findDashboard(Long userId);
|
||||||
Page<PrevOrderDto> findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long userId);
|
Page<PrevOrderDto> findPrevOrderMain(PrevOrderSearch search, Pageable pageable, Long userId);
|
||||||
SliceImpl<OrderHistoryDto> findOrderHistory(Pageable pageable, Long userId);
|
SliceImpl<OrderHistoryDto> findOrderHistory(Pageable pageable, Long userId);
|
||||||
void addItemToBasket(OrderItemDto orderItemDto,Long storeId, Long userId);
|
void addItemToBasket(OrderItemDto orderItemDto,Long storeId, Long userId);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.justpickup.orderservice.domain.orderItemOption.entity.OrderItemOption
|
|||||||
import com.justpickup.orderservice.global.client.store.*;
|
import com.justpickup.orderservice.global.client.store.*;
|
||||||
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 com.justpickup.orderservice.global.dto.Result;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -162,7 +163,9 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
|
|
||||||
//orderItemOption Entity를 생성한다.
|
//orderItemOption Entity를 생성한다.
|
||||||
List<OrderItemOption> orderItemOptions = orderItemDto.getOrderItemOptionDtoList()
|
List<OrderItemOption> orderItemOptions = orderItemDto.getOrderItemOptionDtoList()
|
||||||
.stream().map(orderItemOptionDto -> OrderItemOption.of(orderItemDto.getId()))
|
.stream()
|
||||||
|
.filter(orderItemOptionDto -> orderItemOptionDto.getId()!=null)
|
||||||
|
.map(orderItemOptionDto -> OrderItemOption.of(orderItemOptionDto.getId()))
|
||||||
.collect(toList());
|
.collect(toList());
|
||||||
|
|
||||||
//orderItem을 Entity를 생성한다.
|
//orderItem을 Entity를 생성한다.
|
||||||
@@ -174,29 +177,40 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
//HARD_CODE
|
//HARD_CODE
|
||||||
Long userCouponId=0L;
|
Long userCouponId=0L;
|
||||||
|
|
||||||
|
Long countByUserIdAndOrderStatus = orderRepository.countByUserIdAndOrderStatus(userId, OrderStatus.PENDING);
|
||||||
|
if(countByUserIdAndOrderStatus>=2) throw new OrderException("장바구니 데이터는 2건 이상 일 수 없습니다.");
|
||||||
|
|
||||||
Optional<Order> optionalOrder = orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING);
|
Optional<Order> optionalOrder = orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING);
|
||||||
if(optionalOrder.isPresent()){
|
if(optionalOrder.isPresent()){
|
||||||
if(!optionalOrder.get().addOrderItem(orderItem)
|
if(!optionalOrder.get().addOrderItem(orderItem)
|
||||||
.getStoreId().equals(storeId))
|
.getStoreId().equals(storeId))
|
||||||
throw new OrderException("장바구니에 여러 카페의 메뉴를 담을수 없습니다.");
|
throw new OrderException("장바구니에 여러 카페의 메뉴를 담을수 없습니다.");
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
orderRepository.save(Order.of(userId,userCouponId,storeId,orderItem));
|
orderRepository.save(Order.of(userId,userCouponId,storeId,orderItem));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FetchOrderDto fetchOrder(Long userId) {
|
public FetchOrderDto fetchOrder(Long userId) {
|
||||||
|
|
||||||
|
//장바구니
|
||||||
Order order = orderRepositoryCustom.fetchOrderBasket(userId)
|
Order order = orderRepositoryCustom.fetchOrderBasket(userId)
|
||||||
.orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다."));
|
.orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다."));
|
||||||
|
|
||||||
|
|
||||||
|
// feign 통신 -> store 정보 가져옴
|
||||||
GetStoreResponse store = storeClient.getStore(String.valueOf(order.getStoreId())).getData();
|
GetStoreResponse store = storeClient.getStore(String.valueOf(order.getStoreId())).getData();
|
||||||
|
|
||||||
|
// feign 통신 -> item, option 정보 가져옴
|
||||||
List<GetItemResponse> data = storeClient.getItemAndItemOptions(order.getOrderItems().stream()
|
List<GetItemResponse> data = storeClient.getItemAndItemOptions(order.getOrderItems().stream()
|
||||||
.map(OrderItem::getItemId)
|
.map(OrderItem::getItemId)
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.collect(Collectors.toUnmodifiableList())
|
.collect(Collectors.toUnmodifiableList())
|
||||||
).getData();
|
).getData();
|
||||||
|
|
||||||
Map<Long, GetItemResponse> itemMap = data.stream().collect(
|
//itemAndOptionMap
|
||||||
|
Map<Long, GetItemResponse> itemOptionMap = data.stream().collect(
|
||||||
Collectors.toMap(
|
Collectors.toMap(
|
||||||
GetItemResponse::getId
|
GetItemResponse::getId
|
||||||
, getItemResponse -> getItemResponse
|
, getItemResponse -> getItemResponse
|
||||||
@@ -207,7 +221,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
List<FetchOrderDto.OrderItemDto> orderItemDtoList = order.getOrderItems()
|
List<FetchOrderDto.OrderItemDto> orderItemDtoList = order.getOrderItems()
|
||||||
.stream().map(orderItem ->
|
.stream().map(orderItem ->
|
||||||
new FetchOrderDto.OrderItemDto(
|
new FetchOrderDto.OrderItemDto(
|
||||||
itemMap.get(orderItem.getItemId())
|
itemOptionMap.get(orderItem.getItemId())
|
||||||
,orderItem))
|
,orderItem))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
@@ -236,6 +250,25 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
order.setOrderStatus(orderStatus);
|
order.setOrderStatus(orderStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DashBoardDto findDashboard(Long userId) {
|
||||||
|
|
||||||
|
Result<StoreByUserIdResponse> storeByUserId = storeClient.getStoreByUserId(userId);
|
||||||
|
Long storeId = storeByUserId.getData().getId();
|
||||||
|
|
||||||
|
// 하루 판매금액
|
||||||
|
List<DashBoardDto.OrderPrice> orderPrices = orderRepositoryCustom.salesAmountBetweenADay(storeId);
|
||||||
|
|
||||||
|
// 일주일 판매 상위메뉴
|
||||||
|
DashBoardDto.BestSellItem bestSellItem = orderRepositoryCustom.bestItemBetweenAWeek(storeId);
|
||||||
|
bestSellItem.setItemName(storeClient.getItem(bestSellItem.getItemId()).getData().getName());
|
||||||
|
|
||||||
|
// 일주일 판매금액( 일별 )
|
||||||
|
List<DashBoardDto.SellAmountAWeek> sellAmountAWeeks = orderRepositoryCustom.salesAmountBetweenAWeek(storeId);
|
||||||
|
|
||||||
|
return DashBoardDto.of(orderPrices , bestSellItem, sellAmountAWeeks);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OrderDetailDto findOrderDetail(Long orderId) {
|
public OrderDetailDto findOrderDetail(Long orderId) {
|
||||||
Order order = orderRepository.findById(orderId)
|
Order order = orderRepository.findById(orderId)
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package com.justpickup.orderservice.domain.order.web;
|
package com.justpickup.orderservice.domain.order.web;
|
||||||
|
|
||||||
import com.justpickup.orderservice.domain.order.dto.OrderMainDto;
|
import com.justpickup.orderservice.domain.order.dto.*;
|
||||||
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
|
|
||||||
import com.justpickup.orderservice.domain.order.dto.PrevOrderDto;
|
|
||||||
import com.justpickup.orderservice.domain.order.dto.PrevOrderSearch;
|
|
||||||
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.order.validator.PrevOrderSearchValidator;
|
import com.justpickup.orderservice.domain.order.validator.PrevOrderSearchValidator;
|
||||||
@@ -40,6 +37,15 @@ public class OrderOwnerApiController {
|
|||||||
private final OrderService orderService;
|
private final OrderService orderService;
|
||||||
private final PrevOrderSearchValidator prevOrderSearchValidator;
|
private final PrevOrderSearchValidator prevOrderSearchValidator;
|
||||||
|
|
||||||
|
@GetMapping("/dashboard")
|
||||||
|
public ResponseEntity<Result> dashboard( @RequestHeader(value="user-id") String userId) {
|
||||||
|
|
||||||
|
DashBoardDto dashboardDto = orderService.findDashboard(Long.valueOf(userId));
|
||||||
|
|
||||||
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
|
.body(Result.createSuccessResult(dashboardDto));
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/order-main")
|
@GetMapping("/order-main")
|
||||||
public ResponseEntity<Result> orderMain(@Valid OrderSearchCondition condition,
|
public ResponseEntity<Result> orderMain(@Valid OrderSearchCondition condition,
|
||||||
@RequestHeader(value="user-id") String userHeader) {
|
@RequestHeader(value="user-id") String userHeader) {
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.justpickup.orderservice.domain.orderItem.service;
|
||||||
|
|
||||||
|
import com.justpickup.orderservice.domain.order.entity.Order;
|
||||||
|
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
|
||||||
|
import com.justpickup.orderservice.domain.order.exception.OrderException;
|
||||||
|
import com.justpickup.orderservice.domain.order.repository.OrderRepository;
|
||||||
|
import com.justpickup.orderservice.domain.order.repository.OrderRepositoryCustom;
|
||||||
|
import com.justpickup.orderservice.domain.orderItem.entity.OrderItem;
|
||||||
|
import com.justpickup.orderservice.domain.orderItem.repository.OrderItemRepository;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public class OrderItemService {
|
||||||
|
|
||||||
|
private final OrderItemRepository orderItemRepository;
|
||||||
|
private final OrderRepository orderRepository;
|
||||||
|
private final OrderRepositoryCustom orderRepositoryCustom;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteOrderItem(Long deleteOrderItemId, Long userId){
|
||||||
|
|
||||||
|
|
||||||
|
Order order = orderRepositoryCustom.fetchOrderBasket(userId)
|
||||||
|
.orElseThrow(() -> new OrderException("존재하지 않는 장바구니 아이템입니다."));
|
||||||
|
|
||||||
|
OrderItem orderItem = orderItemRepository.findById(deleteOrderItemId)
|
||||||
|
.orElseThrow(() -> new OrderException("존재하지 않는 장바구니 아이템입니다."));
|
||||||
|
|
||||||
|
order.deleteOrderItem(orderItem);
|
||||||
|
|
||||||
|
if(order.getOrderItems().size() ==0)
|
||||||
|
orderRepository.delete(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.justpickup.orderservice.domain.orderItem.web;
|
||||||
|
|
||||||
|
import com.justpickup.orderservice.domain.orderItem.service.OrderItemService;
|
||||||
|
import com.justpickup.orderservice.global.dto.Result;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/api/customer/orderItem")
|
||||||
|
public class OrderItemCustomerApiController {
|
||||||
|
|
||||||
|
private final OrderItemService orderItemService;
|
||||||
|
|
||||||
|
@DeleteMapping("/{orderItemId}")
|
||||||
|
public ResponseEntity deleteOrderItem(@PathVariable Long orderItemId,
|
||||||
|
@RequestHeader(value = "user-id") String userId){
|
||||||
|
orderItemService.deleteOrderItem(orderItemId,Long.parseLong(userId));
|
||||||
|
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).body(Result.createSuccessResult(orderItemId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -185,12 +185,15 @@ class OrderCustomerApiControllerTest {
|
|||||||
new FetchOrderDto(2L,2L,12000L,"저스트카페"
|
new FetchOrderDto(2L,2L,12000L,"저스트카페"
|
||||||
,List.of(
|
,List.of(
|
||||||
new FetchOrderDto.OrderItemDto(1L,1L,"카페라테",
|
new FetchOrderDto.OrderItemDto(1L,1L,"카페라테",
|
||||||
List.of(new GetItemResponse.ItemOptionDto(2L, OptionType.REQUIRED,"Hot")
|
List.of(new FetchOrderDto.OrderItemDto.OrderItemOptionDto(2L, OptionType.REQUIRED,"Hot")
|
||||||
,new GetItemResponse.ItemOptionDto(2L, OptionType.OTHER,"샷추카")),3000L,32L)
|
,new FetchOrderDto.OrderItemDto.OrderItemOptionDto(2L, OptionType.OTHER,"샷추카"))
|
||||||
|
,3000L
|
||||||
|
,32L)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
given(orderService.fetchOrder(2L)).willReturn(fetchOrderDto);
|
given(orderService.fetchOrder(2L)).willReturn(fetchOrderDto);
|
||||||
//When
|
//When
|
||||||
|
|
||||||
|
|||||||
@@ -320,4 +320,54 @@ class OrderOwnerApiControllerTest {
|
|||||||
))
|
))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("점주 서비스 - 대쉬보드")
|
||||||
|
void findDashboard() throws Exception {
|
||||||
|
// GIVEN
|
||||||
|
|
||||||
|
given(orderService.findDashboard(1L))
|
||||||
|
.willReturn(
|
||||||
|
DashBoardDto.builder()
|
||||||
|
.salesAmount(1237801239L)
|
||||||
|
.bestSellItem(new DashBoardDto.BestSellItem(40L,"까메리카노",3217L))
|
||||||
|
.sellAmountAWeeks(
|
||||||
|
List.of(new DashBoardDto.SellAmountAWeek("2022-03-22",1235L),
|
||||||
|
new DashBoardDto.SellAmountAWeek("2022-03-23",235L),
|
||||||
|
new DashBoardDto.SellAmountAWeek("2022-03-24",2235L),
|
||||||
|
new DashBoardDto.SellAmountAWeek("2022-03-25",1635L),
|
||||||
|
new DashBoardDto.SellAmountAWeek("2022-03-26",35L),
|
||||||
|
new DashBoardDto.SellAmountAWeek("2022-03-27",635L))
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
// THEN
|
||||||
|
ResultActions actions = mockMvc.perform(get(url + "/dashboard")
|
||||||
|
.header("user-id", "1")
|
||||||
|
);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
actions.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("code").value(Code.SUCCESS.name()))
|
||||||
|
.andDo(print())
|
||||||
|
.andDo(document("owner-findDashboard",
|
||||||
|
requestHeaders(
|
||||||
|
headerWithName("user-id").description("유저 고유번호")
|
||||||
|
),
|
||||||
|
responseFields(
|
||||||
|
fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"),
|
||||||
|
fieldWithPath("message").description("메시지"),
|
||||||
|
fieldWithPath("data").description("데이터"),
|
||||||
|
fieldWithPath("data.salesAmount").description("총 판매금약"),
|
||||||
|
fieldWithPath("data.bestSellItem").description("7일간 베스트 판매 상품"),
|
||||||
|
fieldWithPath("data.bestSellItem.itemId").description("7일간 베스트 판매 상품 고유번호"),
|
||||||
|
fieldWithPath("data.bestSellItem.itemName").description("7일간 베스트 판매 상품명"),
|
||||||
|
fieldWithPath("data.bestSellItem.sumCounts").description("7일간 베스트 판매 상품판매량"),
|
||||||
|
fieldWithPath("data.sellAmountAWeeks").description("7일간 판매 통계"),
|
||||||
|
fieldWithPath("data.sellAmountAWeeks[*].sellDate").description("7일간 판매 통계날짜"),
|
||||||
|
fieldWithPath("data.sellAmountAWeeks[*].sellAmount").description("7일간 판매 통계날짜별 판매량")
|
||||||
|
)
|
||||||
|
))
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package com.justpickup.orderservice.domain.orderItem.web;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.justpickup.orderservice.config.TestConfig;
|
||||||
|
import com.justpickup.orderservice.domain.order.service.OrderService;
|
||||||
|
import com.justpickup.orderservice.domain.order.web.OrderCustomerApiController;
|
||||||
|
import com.justpickup.orderservice.domain.orderItem.service.OrderItemService;
|
||||||
|
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.http.HttpStatus;
|
||||||
|
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
|
||||||
|
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
|
||||||
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
|
||||||
|
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
|
||||||
|
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
||||||
|
import static org.springframework.restdocs.request.RequestDocumentation.*;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@WebMvcTest(OrderItemCustomerApiController.class)
|
||||||
|
@Import(TestConfig.class)
|
||||||
|
@AutoConfigureRestDocs(uriHost = "http://just-pickup.com", uriPort = 8001)
|
||||||
|
class OrderItemCustomerApiControllerTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MockMvc mockMvc;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
OrderItemService orderItemService;
|
||||||
|
|
||||||
|
private final String url = "/api/customer/order";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("주문 아이템 삭제")
|
||||||
|
void deleteOrderItem() throws Exception{
|
||||||
|
|
||||||
|
//given
|
||||||
|
Long orderItemId = 2L;
|
||||||
|
|
||||||
|
//when
|
||||||
|
ResultActions resultActions = mockMvc.perform(
|
||||||
|
delete("/api/customer/orderItem/{orderItemId}",orderItemId)
|
||||||
|
.header("user-id", "2")
|
||||||
|
);
|
||||||
|
|
||||||
|
//then
|
||||||
|
|
||||||
|
resultActions
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andDo(print())
|
||||||
|
.andDo(MockMvcRestDocumentation.document("delete-orderItem",
|
||||||
|
pathParameters(
|
||||||
|
parameterWithName("orderItemId").description("orderItem 고유번호")
|
||||||
|
),
|
||||||
|
requestHeaders(
|
||||||
|
headerWithName("user-id").description("유저 고유번호")
|
||||||
|
),
|
||||||
|
responseFields(
|
||||||
|
fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"),
|
||||||
|
fieldWithPath("message").description("메시지"),
|
||||||
|
fieldWithPath("data").description("orderItem 고유번호")
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,9 +10,11 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/js": "^6.5.95",
|
"@mdi/js": "^6.5.95",
|
||||||
"axios": "^0.26.0",
|
"axios": "^0.26.0",
|
||||||
|
"chart.js": "^2.9.4",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
|
"vue-chartjs": "^3.5.1",
|
||||||
"vue-daum-postcode": "^0.10.0",
|
"vue-daum-postcode": "^0.10.0",
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vuedraggable": "^2.24.3",
|
"vuedraggable": "^2.24.3",
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ export default {
|
|||||||
}
|
}
|
||||||
return axios.patch(process.env.VUE_APP_OWNER_SERVICE_BASEURL + "/order-service/order/" + orderId, body);
|
return axios.patch(process.env.VUE_APP_OWNER_SERVICE_BASEURL + "/order-service/order/" + orderId, body);
|
||||||
},
|
},
|
||||||
|
findDashboard(){
|
||||||
|
return axios.get(process.env.VUE_APP_API_URL + "/order/dashboard");
|
||||||
|
},
|
||||||
getOrderDetail(orderId) {
|
getOrderDetail(orderId) {
|
||||||
return axios.get(process.env.VUE_APP_OWNER_SERVICE_BASEURL + "/order-service/api/order-detail/" + orderId);
|
return axios.get(process.env.VUE_APP_OWNER_SERVICE_BASEURL + "/order-service/api/order-detail/" + orderId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export default {
|
|||||||
addItemOption : function () {
|
addItemOption : function () {
|
||||||
if(!this.data) return;
|
if(!this.data) return;
|
||||||
|
|
||||||
this.dialog = false
|
this.dialog = !this.dialog
|
||||||
this.$emit('addItemOption',this.data,this.optionType)
|
this.$emit('addItemOption',this.data,this.optionType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
md="12"
|
md="12"
|
||||||
>
|
>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
|
type="number"
|
||||||
v-model="modalData.itemPrice"
|
v-model="modalData.itemPrice"
|
||||||
:rules="[() => !!modalData.itemPrice || 'This field is required']"
|
:rules="[() => !!modalData.itemPrice || 'This field is required']"
|
||||||
label="가격*"
|
label="가격*"
|
||||||
@@ -65,7 +66,7 @@
|
|||||||
>
|
>
|
||||||
<v-select
|
<v-select
|
||||||
v-model="modalData.requiredOption"
|
v-model="modalData.requiredOption"
|
||||||
:items="modalData.requiredOption"
|
:items="modalData.requiredOptionItems"
|
||||||
item-text="name"
|
item-text="name"
|
||||||
item-value="id"
|
item-value="id"
|
||||||
label="필수 옵션*"
|
label="필수 옵션*"
|
||||||
@@ -87,7 +88,7 @@
|
|||||||
>
|
>
|
||||||
<v-select
|
<v-select
|
||||||
v-model="modalData.otherOption"
|
v-model="modalData.otherOption"
|
||||||
:items="modalData.otherOption"
|
:items="modalData.otherOptionItems"
|
||||||
item-text="name"
|
item-text="name"
|
||||||
item-value="id"
|
item-value="id"
|
||||||
label="기타 옵션"
|
label="기타 옵션"
|
||||||
|
|||||||
11
owner-vue/src/js/CustomChart.js
Normal file
11
owner-vue/src/js/CustomChart.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// CustomChart.js
|
||||||
|
import { Line, mixins } from 'vue-chartjs'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extends: Line,
|
||||||
|
mixins: [mixins.reactiveProp],
|
||||||
|
props:['chartData', 'options'],
|
||||||
|
mounted () {
|
||||||
|
this.renderChart(this.chartData, this.options)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,10 +24,16 @@ const authCheck = async function (to, from, next) {
|
|||||||
};
|
};
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/order',
|
path: '/',
|
||||||
redirect: 'order',
|
redirect: 'dashboard',
|
||||||
component: DashboardLayout,
|
component: DashboardLayout,
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
path: '/dashboard',
|
||||||
|
name: 'dashboard',
|
||||||
|
beforeEnter: authCheck,
|
||||||
|
component: () => import('./../views/HomeDashBoard')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/category',
|
path: '/category',
|
||||||
name: 'category',
|
name: 'category',
|
||||||
@@ -61,7 +67,7 @@ const routes = [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/login',
|
||||||
redirect: 'login',
|
redirect: 'login',
|
||||||
component: AuthLayout,
|
component: AuthLayout,
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
171
owner-vue/src/views/HomeDashBoard.vue
Normal file
171
owner-vue/src/views/HomeDashBoard.vue
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<v-container fluid>
|
||||||
|
<v-row>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<v-card elevation="2" class="rounded-lg" style="border-left: 5px solid #f69653">
|
||||||
|
<v-card-title primary-title>
|
||||||
|
<div>
|
||||||
|
<div class="grey--text">{{ salesAmount.title }}</div>
|
||||||
|
</div>
|
||||||
|
<v-card-text class="d-flex justify-space-between align-center">
|
||||||
|
<h3 class="headline">{{salesAmount.data | currency}}원</h3>
|
||||||
|
<v-avatar size="60" >
|
||||||
|
<v-icon
|
||||||
|
:color="salesAmount.color"
|
||||||
|
size="64"
|
||||||
|
>
|
||||||
|
mdi-currency-usd
|
||||||
|
</v-icon>
|
||||||
|
</v-avatar>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card-title>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<v-card elevation="2" class="rounded-lg" style="border-left: 5px solid #ed6856">
|
||||||
|
<v-card-title primary-title>
|
||||||
|
<div>
|
||||||
|
<div class="grey--text">{{ bestSellItem.title }}</div>
|
||||||
|
</div>
|
||||||
|
<v-card-text class="d-flex justify-space-between align-center">
|
||||||
|
<h3 class="headline">{{bestSellItem.data.itemName}} {{ bestSellItem.data.sumCounts }}개</h3>
|
||||||
|
<v-avatar size="60" >
|
||||||
|
<v-icon
|
||||||
|
:color="bestSellItem.color"
|
||||||
|
size="64"
|
||||||
|
>
|
||||||
|
mdi-coffee
|
||||||
|
</v-icon>
|
||||||
|
</v-avatar>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card-title>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-card style="border-left: 5px solid #00a8e0">
|
||||||
|
<v-card-title>
|
||||||
|
<v-icon
|
||||||
|
:color="sellAmountAWeeks.color"
|
||||||
|
class="mr-12"
|
||||||
|
size="64"
|
||||||
|
>
|
||||||
|
mdi-currency-usd
|
||||||
|
</v-icon>
|
||||||
|
{{ sellAmountAWeeks.title }}
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-sheet color="transparent">
|
||||||
|
<CustomChart
|
||||||
|
v-if="sellAmountAWeeks.loaded"
|
||||||
|
:chart-data="sellAmountAWeeks.data"
|
||||||
|
:options="sellAmountAWeeks.options"/>
|
||||||
|
</v-sheet>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import orderApi from "@/api/order";
|
||||||
|
import CustomChart from "@/js/CustomChart";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "HomeDashBoard",
|
||||||
|
components:{
|
||||||
|
CustomChart
|
||||||
|
},
|
||||||
|
props: ['userInfo'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
salesAmount: {
|
||||||
|
title: "금일 판매금액",
|
||||||
|
color: "#f69653",
|
||||||
|
data: {}
|
||||||
|
},
|
||||||
|
bestSellItem: {
|
||||||
|
title: "주간베스트 판매상품",
|
||||||
|
color: "#ed6856",
|
||||||
|
data: {}
|
||||||
|
},
|
||||||
|
sellAmountAWeeks: {
|
||||||
|
title: "주간 판매금액 그래프",
|
||||||
|
color: "#00a8e0",
|
||||||
|
loaded:false,
|
||||||
|
options:{
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
|
||||||
|
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
ticks:{
|
||||||
|
fontColor : 'rgba(12, 13, 13, 1)',
|
||||||
|
fontSize : 14
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
ticks: {
|
||||||
|
fontColor : 'rgba(12, 13, 13, 1)',
|
||||||
|
fontSize : 14,
|
||||||
|
userCallback:function (ele) {
|
||||||
|
return Number(ele).toFixed(0).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,") + "원"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
labels: [],
|
||||||
|
datasets: [
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getDashboardData() {
|
||||||
|
const response = await orderApi.findDashboard()
|
||||||
|
this.salesAmount.data = response.data.data.salesAmount
|
||||||
|
this.bestSellItem.data = response.data.data.bestSellItem
|
||||||
|
|
||||||
|
var saleDataset={
|
||||||
|
label: '일별 판매 금액',
|
||||||
|
backgroundColor: '#00a8e0',
|
||||||
|
borderColor: 'rgb(75, 192, 192)',
|
||||||
|
fill: false,
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
|
for (const ele of response.data.data.sellAmountAWeeks) {
|
||||||
|
this.sellAmountAWeeks.data.labels.push(ele.sellDate)
|
||||||
|
saleDataset.data.push( ele.sellAmount)
|
||||||
|
}
|
||||||
|
this.sellAmountAWeeks.data.datasets.push(saleDataset)
|
||||||
|
|
||||||
|
this.sellAmountAWeeks.loaded = true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
this.getDashboardData()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-app id="inspire">
|
<v-app id="inspire">
|
||||||
<side-bar :drawer="drawer" @drawerEvent="drawer = !drawer"></side-bar>
|
<side-bar :drawer="drawer" @drawerEvent="drawer = !drawer" :userInfo="userInfo"/>
|
||||||
<top-bar @drawerEvent="drawer = !drawer"
|
<top-bar @drawerEvent="drawer = !drawer"
|
||||||
:notificationCounts="notificationCounts"/>
|
:notificationCounts="notificationCounts"
|
||||||
|
:userInfo="userInfo"
|
||||||
|
/>
|
||||||
<v-main style="background: #f5f5f540">
|
<v-main style="background: #f5f5f540">
|
||||||
<v-container class="py-8, px-6" fluid>
|
<v-container class="py-8, px-6" fluid>
|
||||||
<router-view
|
<router-view
|
||||||
v-on:plusCount="notificationCounts++"
|
v-on:plusCount="notificationCounts++"
|
||||||
v-on:minusCount="notificationCounts--"
|
v-on:minusCount="notificationCounts--"
|
||||||
|
:userInfo="userInfo"
|
||||||
></router-view>
|
></router-view>
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-main>
|
</v-main>
|
||||||
@@ -18,6 +21,7 @@
|
|||||||
import Sidebar from './Sidebar.vue'
|
import Sidebar from './Sidebar.vue'
|
||||||
import Topbar from "./Topbar.vue";
|
import Topbar from "./Topbar.vue";
|
||||||
import notificationApi from "@/api/notification";
|
import notificationApi from "@/api/notification";
|
||||||
|
import userApi from "@/api/user";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DashboardLayout",
|
name: "DashboardLayout",
|
||||||
@@ -25,20 +29,27 @@ export default {
|
|||||||
'side-bar': Sidebar,
|
'side-bar': Sidebar,
|
||||||
'top-bar': Topbar
|
'top-bar': Topbar
|
||||||
},
|
},
|
||||||
mounted() {
|
async mounted() {
|
||||||
this.searchNotificationCounts();
|
await this.searchNotificationCounts();
|
||||||
|
// 사용자 정보 가져오기
|
||||||
|
this.userInfo = await this.getUserInfo();
|
||||||
},
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
drawer: true,
|
drawer: true,
|
||||||
notificationCounts: 0
|
notificationCounts: 0,
|
||||||
|
userInfo: {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
searchNotificationCounts: async function() {
|
searchNotificationCounts: async function() {
|
||||||
const response = await notificationApi.countsNotification();
|
const response = await notificationApi.countsNotification();
|
||||||
this.notificationCounts = response.data.data;
|
this.notificationCounts = response.data.data;
|
||||||
}
|
},
|
||||||
|
getUserInfo: async function() {
|
||||||
|
const response = await userApi.requestUserInfo();
|
||||||
|
return response.data.data;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default {
|
|||||||
props: ["drawer"],
|
props: ["drawer"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
drawer_sidebar:false,
|
drawer_sidebar:null,
|
||||||
links: [
|
links: [
|
||||||
{name: "지난 주문", url: "/prev-order", icon: "mdi-clipboard-check-outline"},
|
{name: "지난 주문", url: "/prev-order", icon: "mdi-clipboard-check-outline"},
|
||||||
{name: "카테고리", url: "/category", icon: "mdi-shape-outline"},
|
{name: "카테고리", url: "/category", icon: "mdi-shape-outline"},
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
<v-icon>mdi-account-circle</v-icon>
|
<v-icon>mdi-account-circle</v-icon>
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
</v-badge>
|
</v-badge>
|
||||||
<span class="ml-3">{{ userName }}</span>
|
<span class="ml-3">{{ userInfo.name }}</span>
|
||||||
</v-chip>
|
</v-chip>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
</v-list-item-avatar>
|
</v-list-item-avatar>
|
||||||
|
|
||||||
<v-list-item-content>
|
<v-list-item-content>
|
||||||
<v-list-item-title>{{ userName }}</v-list-item-title>
|
<v-list-item-title>{{ userInfo.name }}</v-list-item-title>
|
||||||
<v-list-item-subtitle>Logged In</v-list-item-subtitle>
|
<v-list-item-subtitle>Logged In</v-list-item-subtitle>
|
||||||
</v-list-item-content>
|
</v-list-item-content>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
@@ -63,27 +63,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import userApi from "../../api/user";
|
|
||||||
import authApi from "../../api/auth";
|
import authApi from "../../api/auth";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Topbar",
|
name: "Topbar",
|
||||||
props: ["notificationCounts"],
|
props: ["notificationCounts","userInfo"],
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
userName: '',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
async mounted() {
|
|
||||||
// 사용자 정보 가져오기
|
|
||||||
const data = await this.getUserInfo();
|
|
||||||
this.userName = data.name;
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
getUserInfo: async function() {
|
|
||||||
const response = await userApi.requestUserInfo();
|
|
||||||
return response.data.data;
|
|
||||||
},
|
|
||||||
logout: async function() {
|
logout: async function() {
|
||||||
await authApi.logout();
|
await authApi.logout();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export default {
|
|||||||
name: "LoginUser",
|
name: "LoginUser",
|
||||||
mounted() {
|
mounted() {
|
||||||
if (false == jwt.isExpired()) {
|
if (false == jwt.isExpired()) {
|
||||||
this.$router.push('/order');
|
this.$router.push('/');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
@@ -62,7 +62,7 @@ export default {
|
|||||||
|
|
||||||
const flag = await userApi.requestLoginUser(this.email, this.password);
|
const flag = await userApi.requestLoginUser(this.email, this.password);
|
||||||
|
|
||||||
if (flag) await this.$router.push('/order');
|
if (flag) await this.$router.push('/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,7 +162,9 @@ export default {
|
|||||||
categoryId: 0,
|
categoryId: 0,
|
||||||
categoryList : [],
|
categoryList : [],
|
||||||
requiredOption : [],
|
requiredOption : [],
|
||||||
otherOption : []
|
requiredOptionItems : [],
|
||||||
|
otherOption : [],
|
||||||
|
otherOptionItems : []
|
||||||
}
|
}
|
||||||
|
|
||||||
store.getCategoryList()
|
store.getCategoryList()
|
||||||
@@ -184,10 +186,14 @@ export default {
|
|||||||
vm.modalData.itemPrice = item.price;
|
vm.modalData.itemPrice = item.price;
|
||||||
vm.modalData.categoryId = item.categoryId;
|
vm.modalData.categoryId = item.categoryId;
|
||||||
item.itemOptions.forEach(function(ele){
|
item.itemOptions.forEach(function(ele){
|
||||||
if(ele.optionType === "REQUIRED")
|
if(ele.optionType === "REQUIRED"){
|
||||||
vm.modalData.requiredOption.push(ele)
|
vm.modalData.requiredOption.push(ele)
|
||||||
else
|
vm.modalData.requiredOptionItems.push(ele)
|
||||||
|
}
|
||||||
|
else{
|
||||||
vm.modalData.otherOption.push(ele)
|
vm.modalData.otherOption.push(ele)
|
||||||
|
vm.modalData.otherOptionItems.push(ele)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -198,17 +204,46 @@ export default {
|
|||||||
method='put'
|
method='put'
|
||||||
else
|
else
|
||||||
method='post'
|
method='post'
|
||||||
store.saveItem(method,itemData);
|
|
||||||
|
|
||||||
|
var requiredOption = []
|
||||||
|
for (const ele of this.modalData.requiredOption) {
|
||||||
|
if(isNaN(ele)) {
|
||||||
|
requiredOption.push(ele)
|
||||||
|
}else{
|
||||||
|
const option = this.modalData.requiredOptionItems.find(value => value.id == ele)
|
||||||
|
requiredOption.push(option)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var otherOption = []
|
||||||
|
for (const ele of this.modalData.otherOption) {
|
||||||
|
if(isNaN(ele)) {
|
||||||
|
otherOption.push(ele)
|
||||||
|
}else{
|
||||||
|
const option = this.modalData.otherOptionItems.find(value => value.id == ele)
|
||||||
|
otherOption.push(option)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.modalData.requiredOption = requiredOption
|
||||||
|
this.modalData.otherOption = otherOption
|
||||||
|
store.saveItem(method,itemData)
|
||||||
},
|
},
|
||||||
addItemOption:function (itemOptionValue,type){
|
addItemOption:function (itemOptionValue,type){
|
||||||
var item = {
|
var item = {
|
||||||
name:itemOptionValue,
|
name:itemOptionValue,
|
||||||
optionType:type
|
optionType:type
|
||||||
}
|
}
|
||||||
if(type ==='REQUIRED')
|
if(type ==='REQUIRED'){
|
||||||
this.modalData.requiredOption.push(item)
|
this.modalData.requiredOption.push(item)
|
||||||
else
|
this.modalData.requiredOptionItems.push(item)
|
||||||
|
}
|
||||||
|
else{
|
||||||
this.modalData.otherOption.push(item)
|
this.modalData.otherOption.push(item)
|
||||||
|
this.modalData.otherOptionItems.push(item)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class ItemRepositoryCustom {
|
|||||||
|
|
||||||
public Optional<Item> fetchItem(Long itemId){
|
public Optional<Item> fetchItem(Long itemId){
|
||||||
Item fetchItem = queryFactory.selectFrom(item)
|
Item fetchItem = queryFactory.selectFrom(item)
|
||||||
.join(item.itemOptions, itemOption).fetchJoin()
|
.leftJoin(item.itemOptions, itemOption).fetchJoin()
|
||||||
.join(item.category,category).fetchJoin()
|
.join(item.category,category).fetchJoin()
|
||||||
.where(item.id.eq(itemId))
|
.where(item.id.eq(itemId))
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
|
|||||||
@@ -89,10 +89,23 @@ public class ItemServiceImpl implements ItemService {
|
|||||||
|
|
||||||
item.setItemNameAndPriceAndCategory(itemName,itemPrice,category);
|
item.setItemNameAndPriceAndCategory(itemName,itemPrice,category);
|
||||||
|
|
||||||
|
|
||||||
|
//item에 해당하는 itemoption 전부조회
|
||||||
|
List<ItemOption> byItem = itemOptionRepository.findByItem(item);
|
||||||
|
|
||||||
|
//itemOptionDtos 없는 itemOption 전부 삭제
|
||||||
|
byItem.forEach(itemOption -> {
|
||||||
|
boolean isDeleted = true;
|
||||||
|
for ( ItemOptionDto itemOptionDto: itemOptionDtos) {
|
||||||
|
if(itemOption.getId().equals(itemOptionDto.getId())) isDeleted = false;
|
||||||
|
}
|
||||||
|
if(isDeleted) itemOptionRepository.delete(itemOption);
|
||||||
|
});
|
||||||
|
|
||||||
|
//id가 없으면 저장
|
||||||
itemOptionDtos
|
itemOptionDtos
|
||||||
.forEach(itemOptionDto -> {
|
.forEach(itemOptionDto -> {
|
||||||
if(itemOptionDto.getId()!=null) return;
|
if(itemOptionDto.getId()==null)
|
||||||
if (itemOptionRepository.existsById(itemOptionDto.getId()))
|
|
||||||
itemOptionRepository.save(ItemOptionDto.createItemOption(itemOptionDto, item));
|
itemOptionRepository.save(ItemOptionDto.createItemOption(itemOptionDto, item));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ import java.util.List;
|
|||||||
|
|
||||||
public interface ItemOptionRepository extends JpaRepository<ItemOption,Long> {
|
public interface ItemOptionRepository extends JpaRepository<ItemOption,Long> {
|
||||||
|
|
||||||
|
List<ItemOption> findByItem(Item item);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user