Merge branch 'master' into feign_클라이언트_연동
This commit is contained in:
@@ -5,6 +5,9 @@ export default {
|
|||||||
requestRegisterUser(user) {
|
requestRegisterUser(user) {
|
||||||
return axios.post(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+"/user-service/store-owner", user);
|
return axios.post(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+"/user-service/store-owner", user);
|
||||||
},
|
},
|
||||||
|
geUserData() {
|
||||||
|
return axios.get(process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+"/user-service/customer/", );
|
||||||
|
},
|
||||||
|
|
||||||
async requestLoginUser(email, password) {
|
async requestLoginUser(email, password) {
|
||||||
const user = {
|
const user = {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default {
|
|||||||
{name: "검색", url: "/search", icon: "mdi-magnify"},
|
{name: "검색", url: "/search", icon: "mdi-magnify"},
|
||||||
{name: "즐겨찾기", url: "/favorite", icon: "mdi-cards-heart-outline"},
|
{name: "즐겨찾기", url: "/favorite", icon: "mdi-cards-heart-outline"},
|
||||||
{name: "주문내역", url: "/history", icon: "mdi-clipboard-check-outline"},
|
{name: "주문내역", url: "/history", icon: "mdi-clipboard-check-outline"},
|
||||||
{name: "마이페이지", url: "/", icon: "mdi-account-outline"}
|
{name: "마이페이지", url: "/mypage", icon: "mdi-account-outline"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -33,6 +33,13 @@ export default {
|
|||||||
this.value = index;
|
this.value = index;
|
||||||
this.$router.push(url);
|
this.$router.push(url);
|
||||||
}
|
}
|
||||||
|
},mounted() {
|
||||||
|
const path =this.$route.path
|
||||||
|
this.links.forEach((link, index) => {
|
||||||
|
if(link.url === path){
|
||||||
|
this.value = index
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ axios.interceptors.request.use(function (config) {
|
|||||||
config.headers.Authorization = "Bearer " + jwt.getToken();
|
config.headers.Authorization = "Bearer " + jwt.getToken();
|
||||||
return config;
|
return config;
|
||||||
});
|
});
|
||||||
|
Vue.filter('currency', function (value) {
|
||||||
|
var num = new Number(value);
|
||||||
|
return num.toFixed(0).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")
|
||||||
|
});
|
||||||
|
|
||||||
axios.interceptors.response.use(
|
axios.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const authCheck = async function (to, from, next) {
|
|||||||
await auth.requestCheckAccessToken();
|
await auth.requestCheckAccessToken();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await router.replace("/login");
|
await router.push("/login");
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
@@ -60,11 +60,6 @@ const routes = [
|
|||||||
name: 'notification',
|
name: 'notification',
|
||||||
component: () => import('../views/NotificationView')
|
component: () => import('../views/NotificationView')
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/login',
|
|
||||||
name: 'login',
|
|
||||||
component: () => import('../views/LoginPage')
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/item/:itemId",
|
path: "/item/:itemId",
|
||||||
name: 'itemDetail',
|
name: 'itemDetail',
|
||||||
@@ -77,6 +72,11 @@ const routes = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
component: () => import('../views/LoginPage'),
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: '/store',
|
path: '/store',
|
||||||
redirect: 'store',
|
redirect: 'store',
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch(error=>{
|
.catch(error=>{
|
||||||
console.log(error)
|
console.log(error)
|
||||||
this.$router.replace("/")
|
this.$router.push("/")
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
parseGroup: function (type){
|
parseGroup: function (type){
|
||||||
@@ -151,10 +151,10 @@ export default {
|
|||||||
orderApi.addItemToBasket(this.setItem)
|
orderApi.addItemToBasket(this.setItem)
|
||||||
.then(response=>{
|
.then(response=>{
|
||||||
console.log(response)
|
console.log(response)
|
||||||
this.$router.replace("/store/"+this.storeId)
|
this.$router.push("/store/"+this.storeId)
|
||||||
})
|
})
|
||||||
.catch(error=>{
|
.catch(error=>{
|
||||||
console.log(error)
|
console.log(error.response)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,6 +8,17 @@
|
|||||||
<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>
|
||||||
@@ -45,6 +56,11 @@ 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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,79 +1,84 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container
|
<v-app>
|
||||||
fill-height
|
<v-main>
|
||||||
>
|
<v-container class="px-8 py-8">
|
||||||
<v-row>
|
<v-container
|
||||||
<v-col>
|
fill-height
|
||||||
<div align="center" ><v-img
|
>
|
||||||
max-height="150"
|
<v-row>
|
||||||
max-width="250"
|
<v-col>
|
||||||
:src="logo"></v-img></div>
|
<div align="center" ><v-img
|
||||||
</v-col>
|
max-height="150"
|
||||||
</v-row>
|
max-width="250"
|
||||||
<v-row
|
:src="logo"></v-img></div>
|
||||||
justify="center"
|
</v-col>
|
||||||
>
|
</v-row>
|
||||||
<v-col class="align-content-center">
|
<v-row
|
||||||
|
justify="center"
|
||||||
|
>
|
||||||
<v-form ref="form" lazy-validation>
|
<v-col class="align-content-center">
|
||||||
<v-text-field
|
<v-form ref="form" lazy-validation>
|
||||||
:rules="[v => /.+@.+\..+/.test(v) || 'E-mail must be valid', v => !!v || '이메일은 필수 값입니다']"
|
<v-text-field
|
||||||
label="이메일"
|
:rules="[v => /.+@.+\..+/.test(v) || 'E-mail must be valid', v => !!v || '이메일은 필수 값입니다']"
|
||||||
prepend-icon="mdi-account-circle"
|
label="이메일"
|
||||||
></v-text-field>
|
prepend-icon="mdi-account-circle"
|
||||||
<v-text-field
|
></v-text-field>
|
||||||
:rules="[v => !!v || '비밀번호는 필수 값입니다']"
|
<v-text-field
|
||||||
label="비밀번호"
|
:rules="[v => !!v || '비밀번호는 필수 값입니다']"
|
||||||
type="Password"
|
label="비밀번호"
|
||||||
prepend-icon="mdi-lock"
|
type="Password"
|
||||||
append-icon="mdi-eye-off"
|
prepend-icon="mdi-lock"
|
||||||
></v-text-field>
|
append-icon="mdi-eye-off"
|
||||||
<v-btn
|
></v-text-field>
|
||||||
block
|
|
||||||
>
|
|
||||||
Login
|
|
||||||
</v-btn>
|
|
||||||
<div class="d-block my-7" align="center">
|
|
||||||
<v-subheader class="d-inline" >소셜 아이디로 로그인해보세요!</v-subheader>
|
|
||||||
</div>
|
|
||||||
<div class="d-block " align="center">
|
|
||||||
<v-btn
|
<v-btn
|
||||||
class="mx-2"
|
block
|
||||||
fab
|
|
||||||
small
|
|
||||||
>
|
>
|
||||||
<v-img
|
Login
|
||||||
class="d-inline-block align-lg-center mx-5"
|
|
||||||
style=""
|
|
||||||
max-width="38"
|
|
||||||
max-height="38"
|
|
||||||
:src="logo_naver"
|
|
||||||
@click="login_auth('naver')"
|
|
||||||
/>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
class="mx-2"
|
|
||||||
fab
|
|
||||||
small
|
|
||||||
>
|
|
||||||
<v-img
|
|
||||||
class="d-inline-block mx-5"
|
|
||||||
max-width="38"
|
|
||||||
max-height="38"
|
|
||||||
min-width="38"
|
|
||||||
min-height="38"
|
|
||||||
:src="logo_google"
|
|
||||||
@click="login_auth('google')"
|
|
||||||
/>
|
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
<div class="d-block my-7" align="center">
|
||||||
|
<v-subheader class="d-inline" >소셜 아이디로 로그인해보세요!</v-subheader>
|
||||||
|
</div>
|
||||||
|
<div class="d-block " align="center">
|
||||||
|
<v-btn
|
||||||
|
class="mx-2"
|
||||||
|
fab
|
||||||
|
small
|
||||||
|
>
|
||||||
|
<v-img
|
||||||
|
class="d-inline-block align-lg-center mx-5"
|
||||||
|
style=""
|
||||||
|
max-width="38"
|
||||||
|
max-height="38"
|
||||||
|
:src="logo_naver"
|
||||||
|
@click="login_auth('naver')"
|
||||||
|
/>
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
class="mx-2"
|
||||||
|
fab
|
||||||
|
small
|
||||||
|
>
|
||||||
|
<v-img
|
||||||
|
class="d-inline-block mx-5"
|
||||||
|
max-width="38"
|
||||||
|
max-height="38"
|
||||||
|
min-width="38"
|
||||||
|
min-height="38"
|
||||||
|
:src="logo_google"
|
||||||
|
@click="login_auth('google')"
|
||||||
|
/>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</v-form>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
</v-container>
|
||||||
|
</v-main>
|
||||||
|
</v-app>
|
||||||
|
|
||||||
</v-form>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-container>
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -81,29 +86,31 @@
|
|||||||
import logo from '@/assets/justLogo.png'
|
import logo from '@/assets/justLogo.png'
|
||||||
import logo_naver from '@/assets/logo_naver.svg'
|
import logo_naver from '@/assets/logo_naver.svg'
|
||||||
import logo_google from '@/assets/logo_google.png'
|
import logo_google from '@/assets/logo_google.png'
|
||||||
|
import jwt from "@/common/jwt";
|
||||||
|
import router from "@/router/router";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "LoginPage",
|
name: "LoginPage",
|
||||||
data (){
|
data() {
|
||||||
return {
|
return {
|
||||||
logo : logo,
|
logo: logo,
|
||||||
logo_naver: logo_naver,
|
logo_naver: logo_naver,
|
||||||
logo_google : logo_google,
|
logo_google: logo_google,
|
||||||
auth_popup: null,
|
auth_popup: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
auth_popup : function () {
|
auth_popup: function () {
|
||||||
this.auth_popup.addEventListener('beforeunload', function() {
|
this.auth_popup.addEventListener('beforeunload', function () {
|
||||||
window.location.href=process.env.VUE_APP_BASEURL;
|
window.location.href = process.env.VUE_APP_BASEURL;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
login_auth: async function(target) {
|
login_auth: async function (target) {
|
||||||
const _url = process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL+'/user-service/oauth2/authorization/'+target
|
const _url = process.env.VUE_APP_CUSTOMER_SERVICE_BASEURL + '/user-service/oauth2/authorization/' + target
|
||||||
this.auth_popup = window.open(
|
this.auth_popup = window.open(
|
||||||
_url,
|
_url,
|
||||||
"",
|
"",
|
||||||
@@ -112,9 +119,22 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
async mounted() {
|
||||||
|
|
||||||
|
if (!jwt.isExpired())
|
||||||
|
await router.push("/");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
max-width: 768px;
|
||||||
|
background-color: white;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
background-color: #f2f2f2!important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
88
customer-vue/src/views/MyPage.vue
Normal file
88
customer-vue/src/views/MyPage.vue
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<v-container
|
||||||
|
fill-height
|
||||||
|
>
|
||||||
|
<v-row >
|
||||||
|
<v-col >
|
||||||
|
<v-card
|
||||||
|
class="mx-auto mb-5 v-alert--border"
|
||||||
|
outlined
|
||||||
|
|
||||||
|
elevation="9"
|
||||||
|
|
||||||
|
>
|
||||||
|
<v-card-title>내 정보 관리</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<v-form
|
||||||
|
ref="form"
|
||||||
|
v-model="userData.valid"
|
||||||
|
lazy-validation
|
||||||
|
readonly
|
||||||
|
>
|
||||||
|
<v-text-field
|
||||||
|
v-model="userData.userId"
|
||||||
|
label="id"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<v-text-field
|
||||||
|
v-model="userData.email"
|
||||||
|
label="E-mail"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<v-text-field
|
||||||
|
v-model="userData.userName"
|
||||||
|
label="Name"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<v-text-field
|
||||||
|
v-model="userData.phoneNumber"
|
||||||
|
label="phoneNumber"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<v-btn
|
||||||
|
color="orange"
|
||||||
|
block>수정하기</v-btn>
|
||||||
|
</v-form>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import userApi from "@/api/user";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MyPage",
|
||||||
|
data (){
|
||||||
|
return {
|
||||||
|
userData:{
|
||||||
|
userId:'',
|
||||||
|
email:'',
|
||||||
|
userName:'',
|
||||||
|
phoneNumber:'',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
getUserData(){
|
||||||
|
userApi.geUserData().then(response =>{
|
||||||
|
this.userData = response.data.data
|
||||||
|
}).catch(error =>{
|
||||||
|
console.log(error.response)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getUserData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -2,12 +2,12 @@
|
|||||||
<div>
|
<div>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<div class="text-h4" style="white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">{{ orderData.storeId }}</div>
|
<div class="text-h4" style="white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">{{ orderData.storeName }}</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col
|
<v-col
|
||||||
v-for=" orderItem in orderData._orderItemDtos"
|
v-for=" orderItem in orderData.orderItemDtoList"
|
||||||
:key = "orderItem.itemId"
|
:key = "orderItem.itemId"
|
||||||
>
|
>
|
||||||
<v-card
|
<v-card
|
||||||
@@ -17,16 +17,18 @@
|
|||||||
<v-list-item three-line>
|
<v-list-item three-line>
|
||||||
<v-list-item-content>
|
<v-list-item-content>
|
||||||
<v-list-item-title class="text-h5 mb-3">
|
<v-list-item-title class="text-h5 mb-3">
|
||||||
{{ orderItem.itemId }}
|
{{ orderItem.itemName }}
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
<v-list-item-subtitle class="mb-5">
|
<v-list-item-subtitle class="mb-5">
|
||||||
수량 : {{ orderItem.count }}
|
수량 : {{ orderItem.count| currency }}
|
||||||
</v-list-item-subtitle>
|
</v-list-item-subtitle>
|
||||||
<div class="text-body-1 mb-5">
|
<div class="text-body-1 mb-5" style="white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">
|
||||||
{{ orderItem.itemOptionIds.join(', ')}}
|
{{ orderItem.orderItemOptionDtoList ?
|
||||||
|
orderItem.orderItemOptionDtoList.map(x=>x.name).join(', ')
|
||||||
|
: null}}
|
||||||
</div>
|
</div>
|
||||||
<div class="text--primary">
|
<div class="text--primary">
|
||||||
합계 : <b> {{ orderItem.count * orderItem.price }} 원</b>
|
합계 : <b> {{ orderItem.count * orderItem.price | currency}} 원</b>
|
||||||
</div>
|
</div>
|
||||||
</v-list-item-content>
|
</v-list-item-content>
|
||||||
<v-list-item-avatar
|
<v-list-item-avatar
|
||||||
@@ -46,7 +48,7 @@
|
|||||||
</v-row>
|
</v-row>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<div> 합계 : {{orderData.totalPrice}} 원</div>
|
<div> 합계 : {{orderData.orderPrice | currency}} 원</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-btn
|
<v-btn
|
||||||
@@ -72,31 +74,24 @@ export default {
|
|||||||
data: function(){
|
data: function(){
|
||||||
return {
|
return {
|
||||||
orderData:{
|
orderData:{
|
||||||
storeId:Number,
|
// storeName:Number,
|
||||||
_orderItemDtos:[{
|
// orderItemDtoList:[{
|
||||||
itemId:Number,
|
// name:Number,
|
||||||
itemOptionIds:Array,
|
// itemOptionIds:Array,
|
||||||
price:Number,
|
// price:Number,
|
||||||
count:Number,
|
// count:Number,
|
||||||
}],
|
// }],
|
||||||
totalPrice:Number,
|
// orderPrice:Number,
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed:{
|
|
||||||
test:function (a){
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods:{
|
methods:{
|
||||||
saveOrder: function(){
|
saveOrder: function(){
|
||||||
|
|
||||||
orderApi.saveOrder()
|
orderApi.saveOrder()
|
||||||
.then(()=>{
|
.then(()=>{
|
||||||
alert('주문되었습니다.')
|
alert('주문되었습니다.')
|
||||||
this.$router.replace("/")
|
this.$router.push("/history")
|
||||||
})
|
})
|
||||||
.catch(error=>{
|
.catch(error=>{
|
||||||
console.log(error)
|
console.log(error)
|
||||||
@@ -106,11 +101,12 @@ 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=>{
|
||||||
console.log(error)
|
console.log(error.response)
|
||||||
this.$router.replace("/")
|
history.back();
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,3 @@ logging:
|
|||||||
# jpa query, parameter 로그 (p6spy)
|
# jpa query, parameter 로그 (p6spy)
|
||||||
decorator.datasource.p6spy:
|
decorator.datasource.p6spy:
|
||||||
enable-logging: true
|
enable-logging: true
|
||||||
|
|
||||||
#feign key
|
|
||||||
token:
|
|
||||||
feign: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmZWlnbiIsImV4cCI6MTE2NDY5NzY4NzAsImlhdCI6MTY0Njk3Njg3MH0.5x4Nx7oMnpF0_kZpbZsiB1u9eEbQ4IKIhJlEsa3D22cjZjvTHKz57GCz0sgXb_olhSNIVv9xF41A29-XYiFeBQ
|
|
||||||
@@ -1,18 +1,15 @@
|
|||||||
package com.justpickup.orderservice.domain.order.dto;
|
package com.justpickup.orderservice.domain.order.dto;
|
||||||
|
|
||||||
import com.justpickup.orderservice.domain.order.entity.Order;
|
import com.justpickup.orderservice.domain.orderItem.entity.OrderItem;
|
||||||
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
|
import com.justpickup.orderservice.global.client.store.GetItemResponse;
|
||||||
import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto;
|
import lombok.*;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
public class FetchOrderDto {
|
public class FetchOrderDto {
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@@ -20,19 +17,36 @@ public class FetchOrderDto {
|
|||||||
|
|
||||||
private Long orderPrice;
|
private Long orderPrice;
|
||||||
|
|
||||||
private Long storeId;
|
private String storeName;
|
||||||
|
|
||||||
private List<OrderItemDto> orderItemDtoList;
|
private List<OrderItemDto> orderItemDtoList;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class OrderItemDto{
|
||||||
|
|
||||||
public FetchOrderDto(Order order) {
|
private Long id;
|
||||||
this.id = order.getId();
|
|
||||||
this.userId = order.getUserId();
|
private Long itemId;
|
||||||
this.orderPrice = order.getOrderPrice();
|
|
||||||
this.storeId = order.getStoreId();
|
private String itemName;
|
||||||
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())))
|
private List<GetItemResponse.ItemOptionDto> orderItemOptionDtoList;
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
private Long price;
|
||||||
|
|
||||||
|
private Long count;
|
||||||
|
|
||||||
|
public OrderItemDto(GetItemResponse getItemResponse, OrderItem orderItem) {
|
||||||
|
this.id = orderItem.getId();
|
||||||
|
this.itemId = getItemResponse.getId();
|
||||||
|
this.itemName = getItemResponse.getName();
|
||||||
|
this.orderItemOptionDtoList = getItemResponse.getItemOptions();
|
||||||
|
this.price = orderItem.getPrice();
|
||||||
|
this.count = orderItem.getCount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import java.util.List;
|
|||||||
@Entity
|
@Entity
|
||||||
@Table(name = "orders")
|
@Table(name = "orders")
|
||||||
@Getter
|
@Getter
|
||||||
|
@EntityListeners(value = {OrderListener.class})
|
||||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
public class Order extends BaseEntity {
|
public class Order extends BaseEntity {
|
||||||
|
|
||||||
@@ -101,4 +102,8 @@ public class Order extends BaseEntity {
|
|||||||
}
|
}
|
||||||
return totalPrice;
|
return totalPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fail() {
|
||||||
|
this.orderStatus = OrderStatus.FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,33 @@
|
|||||||
package com.justpickup.orderservice.domain.order.entity;
|
package com.justpickup.orderservice.domain.order.entity;
|
||||||
|
|
||||||
|
import com.justpickup.orderservice.domain.order.exception.OrderException;
|
||||||
|
import com.justpickup.orderservice.domain.order.service.OrderSender;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
|
||||||
import javax.persistence.PostUpdate;
|
import javax.persistence.*;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class OrderListener {
|
public class OrderListener {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private OrderSender orderSender;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: 2022/03/15 exception 발생시 order fail 처리
|
||||||
@PostUpdate
|
@PostUpdate
|
||||||
private void postUpdate(Order order) {
|
public void postUpdate(Order order){
|
||||||
OrderStatus orderStatus = order.getOrderStatus();
|
OrderStatus orderStatus = order.getOrderStatus();
|
||||||
if (orderStatus == OrderStatus.ORDER) {
|
if (orderStatus == OrderStatus.ORDER) {
|
||||||
// TODO: 2022/03/10 Kafka 알림 전송
|
|
||||||
log.info("[OrderListener] {}", OrderStatus.ORDER.name());
|
log.info("[OrderListener] {}", OrderStatus.ORDER.name());
|
||||||
|
try{
|
||||||
|
orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order));
|
||||||
|
}catch (Exception ex){
|
||||||
|
throw new OrderException(ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
} else if (orderStatus == OrderStatus.PLACED) {
|
} else if (orderStatus == OrderStatus.PLACED) {
|
||||||
log.info("[OrderListener] {}", OrderStatus.PLACED.name());
|
log.info("[OrderListener] {}", OrderStatus.PLACED.name());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class OrderSender {
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Builder
|
@Builder
|
||||||
static class KafkaSendOrderDto{
|
public static class KafkaSendOrderDto{
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ import com.justpickup.orderservice.global.client.store.StoreByUserIdResponse;
|
|||||||
import com.justpickup.orderservice.global.client.store.StoreClient;
|
import com.justpickup.orderservice.global.client.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 com.justpickup.orderservice.global.client.store.GetItemResponse;
|
||||||
|
import com.justpickup.orderservice.global.client.store.GetStoreReseponse;
|
||||||
|
import com.justpickup.orderservice.global.client.store.StoreClient;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -22,9 +25,12 @@ import org.springframework.data.domain.Pageable;
|
|||||||
import org.springframework.data.domain.SliceImpl;
|
import org.springframework.data.domain.SliceImpl;
|
||||||
import org.springframework.data.support.PageableExecutionUtils;
|
import org.springframework.data.support.PageableExecutionUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static java.util.stream.Collectors.toMap;
|
import static java.util.stream.Collectors.toMap;
|
||||||
@@ -40,7 +46,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
private final OrderSender orderSender;
|
private final OrderSender orderSender;
|
||||||
private final StoreClient storeClient;
|
private final StoreClient storeClient;
|
||||||
private final UserClient userClient;
|
private final UserClient userClient;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OrderMainDto findOrderMain(OrderSearchCondition condition, Long userId) {
|
public OrderMainDto findOrderMain(OrderSearchCondition condition, Long userId) {
|
||||||
// storeId 가져오기
|
// storeId 가져오기
|
||||||
@@ -183,7 +189,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void addItemToBasket(OrderItemDto orderItemDto,Long storeId, Long userId) {
|
public void addItemToBasket(OrderItemDto orderItemDto, Long storeId, Long userId) {
|
||||||
|
|
||||||
//orderItemOption Entity를 생성한다.
|
//orderItemOption Entity를 생성한다.
|
||||||
List<OrderItemOption> orderItemOptions = orderItemDto.getOrderItemOptionDtoList()
|
List<OrderItemOption> orderItemOptions = orderItemDto.getOrderItemOptionDtoList()
|
||||||
@@ -201,7 +207,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
|
|
||||||
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{
|
||||||
@@ -213,21 +219,46 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
public FetchOrderDto fetchOrder(Long userId) {
|
public FetchOrderDto fetchOrder(Long userId) {
|
||||||
Order order = orderRepositoryCustom.fetchOrder(userId)
|
Order order = orderRepositoryCustom.fetchOrder(userId)
|
||||||
.orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다."));
|
.orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다."));
|
||||||
|
GetStoreReseponse store = storeClient.getStore(String.valueOf(order.getStoreId())).getData();
|
||||||
|
|
||||||
return new FetchOrderDto(order);
|
List<GetItemResponse> data = storeClient.getItemAndItemOptions(order.getOrderItems().stream()
|
||||||
|
.map(OrderItem::getItemId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toUnmodifiableList())
|
||||||
|
).getData();
|
||||||
|
|
||||||
|
Map<Long, GetItemResponse> itemMap = data.stream().collect(
|
||||||
|
Collectors.toMap(
|
||||||
|
GetItemResponse::getId
|
||||||
|
, getItemResponse -> getItemResponse
|
||||||
|
, (t, t2) -> t
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
List<FetchOrderDto.OrderItemDto> orderItemDtoList = order.getOrderItems()
|
||||||
|
.stream().map(orderItem ->
|
||||||
|
new FetchOrderDto.OrderItemDto(
|
||||||
|
itemMap.get(orderItem.getItemId())
|
||||||
|
,orderItem))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|
||||||
|
FetchOrderDto fetchOrderDto = FetchOrderDto.builder()
|
||||||
|
.userId(order.getUserId())
|
||||||
|
.orderPrice(order.getOrderPrice())
|
||||||
|
.storeName(store.getName())
|
||||||
|
.orderItemDtoList(orderItemDtoList)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return fetchOrderDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void saveOrder(Long userId) {
|
public void saveOrder(Long userId) {
|
||||||
Order order = orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING)
|
orderRepository.findByUserIdAndOrderStatus(userId, OrderStatus.PENDING)
|
||||||
.orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다."))
|
.orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다."))
|
||||||
.setOrderStatus(OrderStatus.PLACED);
|
.order();
|
||||||
try{
|
|
||||||
orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order));
|
|
||||||
}catch (Exception ex){
|
|
||||||
throw new OrderException(ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -116,55 +116,12 @@ public class OrderCustomerApiController {
|
|||||||
private Long price;
|
private Long price;
|
||||||
private Long count;
|
private Long count;
|
||||||
private List<Long> itemOptionIds ;
|
private List<Long> itemOptionIds ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/orders")
|
@GetMapping("/orders")
|
||||||
public ResponseEntity fetchOrder(@RequestHeader(value = "user-id") String userId){
|
public ResponseEntity fetchOrder(@RequestHeader(value = "user-id") String userId){
|
||||||
FetchOrderDto fetchOrderDto = orderService.fetchOrder(Long.parseLong(userId));
|
FetchOrderDto fetchOrderDto = orderService.fetchOrder(Long.parseLong(userId));
|
||||||
FetchOrderResponse fetchOrderResponse = new FetchOrderResponse(fetchOrderDto);
|
return ResponseEntity.ok(Result.createSuccessResult(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")
|
@PostMapping("/orders")
|
||||||
|
|||||||
@@ -1,12 +1,34 @@
|
|||||||
package com.justpickup.orderservice.global.client.store;
|
package com.justpickup.orderservice.global.client.store;
|
||||||
|
|
||||||
import com.justpickup.orderservice.global.entity.Yn;
|
import com.justpickup.orderservice.global.entity.Yn;
|
||||||
import lombok.Data;
|
import lombok.*;
|
||||||
|
|
||||||
@Data
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
public class GetItemResponse {
|
public class GetItemResponse {
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private Yn salesYn;
|
private Yn salesYn;
|
||||||
|
|
||||||
private Long price;
|
private Long price;
|
||||||
|
|
||||||
|
private List<ItemOptionDto> itemOptions;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public static class ItemOptionDto{
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private OptionType optionType;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.justpickup.orderservice.global.client.store;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class GetStoreReseponse {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private String phoneNumber;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.justpickup.orderservice.global.client.store;
|
||||||
|
|
||||||
|
public enum OptionType {
|
||||||
|
REQUIRED, OTHER
|
||||||
|
}
|
||||||
@@ -22,4 +22,11 @@ public interface StoreClient {
|
|||||||
|
|
||||||
@GetMapping("/stores/{storeId}")
|
@GetMapping("/stores/{storeId}")
|
||||||
Result<List<GetStoreResponse>> getStoreAllById(@PathVariable("storeId") Iterable<Long> storeIds);
|
Result<List<GetStoreResponse>> getStoreAllById(@PathVariable("storeId") Iterable<Long> storeIds);
|
||||||
|
|
||||||
|
@GetMapping("/store/{storeId}")
|
||||||
|
Result<GetStoreReseponse> getStore(@PathVariable(value = "storeId") String storeId);
|
||||||
|
|
||||||
|
@GetMapping("/api/customer/items/{itemId}")
|
||||||
|
Result<List<GetItemResponse>> getItemAndItemOptions(@PathVariable(value = "itemId") List<Long> itemIds);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ public class KafkaConfig {
|
|||||||
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServerHost+":"+kafkaServerPort);
|
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServerHost+":"+kafkaServerPort);
|
||||||
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||||
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||||
|
// properties.put(ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, 5000);
|
||||||
|
|
||||||
return new DefaultKafkaProducerFactory<>(properties);
|
return new DefaultKafkaProducerFactory<>(properties);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,3 @@ decorator.datasource.p6spy:
|
|||||||
kafka:
|
kafka:
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 9092
|
port: 9092
|
||||||
|
|
||||||
#feign key
|
|
||||||
token:
|
|
||||||
feign: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmZWlnbiIsImV4cCI6MTE2NDY5NzY4NzAsImlhdCI6MTY0Njk3Njg3MH0.5x4Nx7oMnpF0_kZpbZsiB1u9eEbQ4IKIhJlEsa3D22cjZjvTHKz57GCz0sgXb_olhSNIVv9xF41A29-XYiFeBQ
|
|
||||||
@@ -10,6 +10,8 @@ import com.justpickup.orderservice.domain.order.repository.OrderRepository;
|
|||||||
import com.justpickup.orderservice.domain.order.service.OrderService;
|
import com.justpickup.orderservice.domain.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.domain.orderItemOption.dto.OrderItemOptionDto;
|
||||||
|
import com.justpickup.orderservice.global.client.store.GetItemResponse;
|
||||||
|
import com.justpickup.orderservice.global.client.store.OptionType;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
@@ -179,15 +181,15 @@ class OrderCustomerApiControllerTest {
|
|||||||
void fetchOrder() throws Exception{
|
void fetchOrder() throws Exception{
|
||||||
//Given
|
//Given
|
||||||
FetchOrderDto fetchOrderDto =
|
FetchOrderDto fetchOrderDto =
|
||||||
new FetchOrderDto(2L,2L,12000L,2L
|
new FetchOrderDto(2L,2L,12000L,"저스트카페"
|
||||||
,List.of(
|
,List.of(
|
||||||
OrderItemDto.of(1L,300L,3000L,2L,
|
new FetchOrderDto.OrderItemDto(1L,1L,"카페라테",
|
||||||
List.of(new OrderItemOptionDto(2L)
|
List.of(new GetItemResponse.ItemOptionDto(2L, OptionType.REQUIRED,"Hot")
|
||||||
,new OrderItemOptionDto(3L))
|
,new GetItemResponse.ItemOptionDto(2L, OptionType.OTHER,"샷추카")),3000L,32L)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
given(orderService.fetchOrder(2L)).willReturn(fetchOrderDto);
|
given(orderService.fetchOrder(2L)).willReturn(fetchOrderDto);
|
||||||
//When
|
//When
|
||||||
|
|
||||||
@@ -203,12 +205,20 @@ class OrderCustomerApiControllerTest {
|
|||||||
responseFields(
|
responseFields(
|
||||||
fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"),
|
fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"),
|
||||||
fieldWithPath("message").description("메시지"),
|
fieldWithPath("message").description("메시지"),
|
||||||
fieldWithPath("data.storeId").description("매장 고유번호"),
|
fieldWithPath("data.id").description("주문 고유번호"),
|
||||||
fieldWithPath("data.totalPrice").description("총 합계"),
|
fieldWithPath("data.userId").description("주문한 유저 고유번호"),
|
||||||
fieldWithPath("data._orderItemDtos[*].itemId").description("상품 고유번호"),
|
fieldWithPath("data.storeName").description("매장 명"),
|
||||||
fieldWithPath("data._orderItemDtos[*].price").description("상품 가격"),
|
fieldWithPath("data.orderPrice").description("총 합계"),
|
||||||
fieldWithPath("data._orderItemDtos[*].count").description("상품 갯수"),
|
fieldWithPath("data.orderItemDtoList[*].id").description("orderItem 고유번호"),
|
||||||
fieldWithPath("data._orderItemDtos[*].itemOptionIds[*]").description("아이템 옵션들")
|
fieldWithPath("data.orderItemDtoList[*].itemId").description("상품 고유번호"),
|
||||||
|
fieldWithPath("data.orderItemDtoList[*].itemName").description("상품 명"),
|
||||||
|
fieldWithPath("data.orderItemDtoList[*].orderItemOptionDtoList[*]").description("아이템 옵션들"),
|
||||||
|
fieldWithPath("data.orderItemDtoList[*].orderItemOptionDtoList[*].id").description("아이템 옵션 고유번호"),
|
||||||
|
fieldWithPath("data.orderItemDtoList[*].orderItemOptionDtoList[*].optionType").description("아이템 옵션 타입"),
|
||||||
|
fieldWithPath("data.orderItemDtoList[*].orderItemOptionDtoList[*].name").description("아이템 옵션명"),
|
||||||
|
fieldWithPath("data.orderItemDtoList[*].price").description("상품 가격"),
|
||||||
|
fieldWithPath("data.orderItemDtoList[*].count").description("상품 갯수")
|
||||||
|
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,6 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
getMenu(searchParam){
|
getMenu(searchParam){
|
||||||
return axios.get(process.env.VUE_APP_OWNER_SERVICE_BASEURL+'/store-service/api/owner/item',searchParam);
|
return axios.get(process.env.VUE_APP_OWNER_SERVICE_BASEURL+'/store-service/api/owner/item',{params:searchParam});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -72,8 +72,15 @@ operation::item-get-notExistItemException[snippets='curl-request,http-request,ht
|
|||||||
=== 상품 리스트 조회
|
=== 상품 리스트 조회
|
||||||
operation::items-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
operation::items-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
||||||
|
|
||||||
|
|
||||||
== 상품 (판매자)
|
== 상품 (판매자)
|
||||||
=== 상품 조회
|
=== 상품 조회
|
||||||
|
=======
|
||||||
|
=== 상품 리스트 조회(구매자)
|
||||||
|
operation::customer-itemList-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
||||||
|
|
||||||
|
|
||||||
|
=== 상품 조회(판매자)
|
||||||
operation::owner-item-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
operation::owner-item-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
||||||
=== 상품 리스트 조회
|
=== 상품 리스트 조회
|
||||||
operation::owner-itemList-get[snippets='curl-request,http-request,http-response,response-fields']
|
operation::owner-itemList-get[snippets='curl-request,http-request,http-response,response-fields']
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.justpickup.storeservice.domain.item.dto;
|
||||||
|
|
||||||
|
import com.justpickup.storeservice.domain.category.dto.CategoryDto;
|
||||||
|
import com.justpickup.storeservice.domain.item.entity.Item;
|
||||||
|
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
||||||
|
import com.justpickup.storeservice.domain.itemoption.entity.ItemOption;
|
||||||
|
import com.justpickup.storeservice.domain.itemoption.entity.OptionType;
|
||||||
|
import com.justpickup.storeservice.global.entity.Yn;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class GetItemDto {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Yn salesYn;
|
||||||
|
|
||||||
|
private Long price;
|
||||||
|
|
||||||
|
private List<ItemOptionDto> itemOptions;
|
||||||
|
|
||||||
|
public GetItemDto(Item item) {
|
||||||
|
this.id = item.getId();
|
||||||
|
this.name = item.getName();
|
||||||
|
this.salesYn = item.getSalesYn();
|
||||||
|
this.price = item.getPrice();
|
||||||
|
this.itemOptions = item.getItemOptions().stream().
|
||||||
|
map(ItemOptionDto::new)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public static class ItemOptionDto{
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private OptionType optionType;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public ItemOptionDto (ItemOption itemOption){
|
||||||
|
this.id = itemOption.getId();
|
||||||
|
this.optionType = itemOption.getOptionType();
|
||||||
|
this.name = itemOption.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
package com.justpickup.storeservice.domain.item.repository;
|
package com.justpickup.storeservice.domain.item.repository;
|
||||||
|
|
||||||
import com.justpickup.storeservice.domain.category.entity.QCategory;
|
|
||||||
import com.justpickup.storeservice.domain.item.entity.Item;
|
import com.justpickup.storeservice.domain.item.entity.Item;
|
||||||
import com.justpickup.storeservice.domain.item.entity.QItem;
|
import com.justpickup.storeservice.domain.item.entity.QItem;
|
||||||
import com.justpickup.storeservice.domain.itemoption.entity.QItemOption;
|
|
||||||
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;
|
||||||
@@ -14,6 +12,10 @@ import org.springframework.stereotype.Repository;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static com.justpickup.storeservice.domain.category.entity.QCategory.category;
|
||||||
|
import static com.justpickup.storeservice.domain.item.entity.QItem.item;
|
||||||
|
import static com.justpickup.storeservice.domain.itemoption.entity.QItemOption.itemOption;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ItemRepositoryCustom {
|
public class ItemRepositoryCustom {
|
||||||
@@ -21,15 +23,25 @@ public class ItemRepositoryCustom {
|
|||||||
private final JPAQueryFactory queryFactory;
|
private final JPAQueryFactory queryFactory;
|
||||||
|
|
||||||
public Optional<Item> fetchItem(Long itemId){
|
public Optional<Item> fetchItem(Long itemId){
|
||||||
Item item = queryFactory.selectFrom(QItem.item)
|
Item fetchItem = queryFactory.selectFrom(item)
|
||||||
.join(QItem.item.itemOptions, QItemOption.itemOption).fetchJoin()
|
.join(item.itemOptions, itemOption).fetchJoin()
|
||||||
.join(QItem.item.category,QCategory.category).fetchJoin()
|
.join(item.category,category).fetchJoin()
|
||||||
.where(QItem.item.id.eq(itemId))
|
.where(item.id.eq(itemId))
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
|
|
||||||
return Optional.ofNullable(item);
|
return Optional.ofNullable(fetchItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Item> getItemAndItemOptions(List<Long> itemIds){
|
||||||
|
|
||||||
|
return queryFactory.selectFrom(item)
|
||||||
|
.join(item.itemOptions,itemOption).fetchJoin()
|
||||||
|
.where(item.id.in(itemIds))
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Page<Item> findItem(Long userId,String word, Pageable pageable){
|
public Page<Item> findItem(Long userId,String word, Pageable pageable){
|
||||||
|
|
||||||
//count 가져오기
|
//count 가져오기
|
||||||
|
|||||||
@@ -1,6 +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.FetchItemDto;
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.GetItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.dto.ItemsDto;
|
import com.justpickup.storeservice.domain.item.dto.ItemsDto;
|
||||||
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
import com.justpickup.storeservice.domain.itemoption.dto.ItemOptionDto;
|
||||||
@@ -13,6 +14,7 @@ public interface ItemService {
|
|||||||
|
|
||||||
ItemDto findItemByItemId(Long itemId);
|
ItemDto findItemByItemId(Long itemId);
|
||||||
|
|
||||||
|
List<GetItemDto> getItemAndItemOptions(List<Long> itemIds);
|
||||||
FetchItemDto fetchItem(Long itemId);
|
FetchItemDto fetchItem(Long itemId);
|
||||||
|
|
||||||
Page<ItemDto> findMenuItemList(Long userId, String word, Pageable pageable);
|
Page<ItemDto> findMenuItemList(Long userId, String word, Pageable pageable);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.justpickup.storeservice.domain.item.service;
|
|||||||
import com.justpickup.storeservice.domain.category.entity.Category;
|
import com.justpickup.storeservice.domain.category.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.FetchItemDto;
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.GetItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
||||||
import com.justpickup.storeservice.domain.item.dto.ItemsDto;
|
import com.justpickup.storeservice.domain.item.dto.ItemsDto;
|
||||||
import com.justpickup.storeservice.domain.item.entity.Item;
|
import com.justpickup.storeservice.domain.item.entity.Item;
|
||||||
@@ -45,6 +46,15 @@ public class ItemServiceImpl implements ItemService {
|
|||||||
return ItemDto.createWithCategoryItemDtoAndItemOption(findItem);
|
return ItemDto.createWithCategoryItemDtoAndItemOption(findItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GetItemDto> getItemAndItemOptions(List<Long> itemIds) {
|
||||||
|
|
||||||
|
List<Item> items = itemRepositoryCustom.getItemAndItemOptions(itemIds);
|
||||||
|
return items.stream()
|
||||||
|
.map(GetItemDto::new)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FetchItemDto fetchItem(Long itemId) {
|
public FetchItemDto fetchItem(Long itemId) {
|
||||||
Item findItem = itemRepositoryCustom.fetchItem(itemId)
|
Item findItem = itemRepositoryCustom.fetchItem(itemId)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
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.FetchItemDto;
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.GetItemDto;
|
||||||
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;
|
||||||
@@ -22,9 +23,16 @@ public class ItemCustomerApiController {
|
|||||||
|
|
||||||
private final ItemService itemService;
|
private final ItemService itemService;
|
||||||
|
|
||||||
|
@GetMapping("/items/{itemId}")
|
||||||
|
public ResponseEntity getItemAndItemOptions(@PathVariable("itemId") List<Long> itemId) {
|
||||||
|
List<GetItemDto> itemList = itemService.getItemAndItemOptions(itemId);
|
||||||
|
|
||||||
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
|
.body(Result.createSuccessResult(itemList));
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/item/{itemId}")
|
@GetMapping("/item/{itemId}")
|
||||||
public ResponseEntity getItem(@PathVariable("itemId") Long itemId) {
|
public ResponseEntity fetchItem(@PathVariable("itemId") Long itemId) {
|
||||||
FetchItemDto fetchItem = itemService.fetchItem(itemId);
|
FetchItemDto fetchItem = itemService.fetchItem(itemId);
|
||||||
|
|
||||||
GetItemResponse getItemResponse = new GetItemResponse(fetchItem);
|
GetItemResponse getItemResponse = new GetItemResponse(fetchItem);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Component
|
//@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SqlCommandLineRunner implements CommandLineRunner {
|
public class SqlCommandLineRunner implements CommandLineRunner {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ spring:
|
|||||||
properties:
|
properties:
|
||||||
hibernate:
|
hibernate:
|
||||||
default_batch_fetch_size: 1000
|
default_batch_fetch_size: 1000
|
||||||
|
defer-datasource-initialization: true
|
||||||
|
|
||||||
|
|
||||||
datasource:
|
datasource:
|
||||||
driver-class-name: org.postgresql.Driver
|
driver-class-name: org.postgresql.Driver
|
||||||
@@ -25,6 +27,13 @@ spring:
|
|||||||
username: postgres
|
username: postgres
|
||||||
password: admin
|
password: admin
|
||||||
|
|
||||||
|
|
||||||
|
# sql:
|
||||||
|
# init:
|
||||||
|
# data-locations: classpath:data/data.sql
|
||||||
|
# mode: always
|
||||||
|
|
||||||
|
|
||||||
eureka:
|
eureka:
|
||||||
client:
|
client:
|
||||||
service-url:
|
service-url:
|
||||||
@@ -41,7 +50,3 @@ logging:
|
|||||||
# jpa query, parameter 로그 (p6spy)
|
# jpa query, parameter 로그 (p6spy)
|
||||||
decorator.datasource.p6spy:
|
decorator.datasource.p6spy:
|
||||||
enable-logging: true
|
enable-logging: true
|
||||||
|
|
||||||
#feign key
|
|
||||||
token:
|
|
||||||
feign: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmZWlnbiIsImV4cCI6MTE2NDY5NzY4NzAsImlhdCI6MTY0Njk3Njg3MH0.5x4Nx7oMnpF0_kZpbZsiB1u9eEbQ4IKIhJlEsa3D22cjZjvTHKz57GCz0sgXb_olhSNIVv9xF41A29-XYiFeBQ
|
|
||||||
77
store-service/src/main/resources/data/data.sql
Normal file
77
store-service/src/main/resources/data/data.sql
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
-- store
|
||||||
|
INSERT INTO public.store(
|
||||||
|
store_id, created_at, created_by, last_modified_at, last_modified_by, city, street, zipcode, business_end_time, business_start_time, phone_number, photo_name, photo_path, user_id, map_id)
|
||||||
|
VALUES (1, now(), 1, now(), 1, '서울시', '광화문로', '123-456', to_timestamp('20:00:00', 'HH24:MI:SS'), to_timestamp('09:00:00', 'HH24:MI:SS'), '010-9418-1307', '사진명1', '/Users/sangbum/Desktop', 1, null);
|
||||||
|
|
||||||
|
|
||||||
|
-- category
|
||||||
|
INSERT INTO public.category(
|
||||||
|
category_id, created_at, created_by, last_modified_at, last_modified_by, name, orders, store_id)
|
||||||
|
VALUES (10, now(), 1, now(), 1, '카테고리1', 0, 1);
|
||||||
|
|
||||||
|
INSERT INTO public.category(
|
||||||
|
category_id, created_at, created_by, last_modified_at, last_modified_by, name, orders, store_id)
|
||||||
|
VALUES (11, now(), 1, now(), 1, '카테고리2', 1, 1);
|
||||||
|
|
||||||
|
-- item
|
||||||
|
INSERT INTO public.item(
|
||||||
|
item_id, created_at, created_by, last_modified_at, last_modified_by, name, photo_name, photo_path, price, sales_yn, category_id, store_id)
|
||||||
|
VALUES (100, now(), 1, now(), 1, '아이템1', '아이템_사진명', '/Users/sangbum/Desktop', 1000, 'Y', 10, 1);
|
||||||
|
|
||||||
|
INSERT INTO public.item(
|
||||||
|
item_id, created_at, created_by, last_modified_at, last_modified_by, name, photo_name, photo_path, price, sales_yn, category_id, store_id)
|
||||||
|
VALUES (101, now(), 1, now(), 1, '아이템2', '아이템_사진명2', '/Users/sangbum/Desktop', 2000, 'Y', 10, 1);
|
||||||
|
|
||||||
|
INSERT INTO public.item(
|
||||||
|
item_id, created_at, created_by, last_modified_at, last_modified_by, name, photo_name, photo_path, price, sales_yn, category_id, store_id)
|
||||||
|
VALUES (102, now(), 1, now(), 1, '아이템3', '아이템_사진명3', '/Users/sangbum/Desktop', 3000, 'Y', 11, 1);
|
||||||
|
|
||||||
|
|
||||||
|
-- item option
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1000, now(), 1, now(), 1, 'ICE', 'REQUIRED', 100);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1001, now(), 1, now(), 1, 'HOT', 'REQUIRED', 100);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1002, now(), 1, now(), 1, '샷 추가', 'OTHER', 100);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1003, now(), 1, now(), 1, '투샷 추카', 'OTHER', 100);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1004, now(), 1, now(), 1, 'ICE', 'REQUIRED', 101);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1005, now(), 1, now(), 1, 'HOT', 'REQUIRED', 101);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1006, now(), 1, now(), 1, '샷 추가', 'OTHER', 101);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1007, now(), 1, now(), 1, '투샷 추카', 'OTHER', 101);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1008, now(), 1, now(), 1, 'ICE', 'REQUIRED', 102);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1009, now(), 1, now(), 1, 'HOT', 'REQUIRED', 102);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1010, now(), 1, now(), 1, '샷 추가', 'OTHER', 102);
|
||||||
|
|
||||||
|
INSERT INTO public.item_option(
|
||||||
|
item_option_id, created_at, created_by, last_modified_at, last_modified_by, name, option_type, item_id)
|
||||||
|
VALUES (1011, now(), 1, now(), 1, '투샷 추카', 'OTHER', 102);
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
package com.justpickup.storeservice.domain.item.web;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.justpickup.storeservice.config.TestConfig;
|
||||||
|
import com.justpickup.storeservice.domain.favoritestore.repository.FavoriteStoreRepository;
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.GetItemDto;
|
||||||
|
import com.justpickup.storeservice.domain.item.dto.ItemDto;
|
||||||
|
import com.justpickup.storeservice.domain.item.service.ItemService;
|
||||||
|
import com.justpickup.storeservice.domain.itemoption.entity.OptionType;
|
||||||
|
import com.justpickup.storeservice.domain.store.repository.StoreRepository;
|
||||||
|
import com.justpickup.storeservice.global.dto.Code;
|
||||||
|
import com.justpickup.storeservice.global.entity.Yn;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||||
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
|
||||||
|
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
|
||||||
|
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
||||||
|
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
|
||||||
|
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@WebMvcTest(ItemCustomerApiController.class)
|
||||||
|
@Import(TestConfig.class)
|
||||||
|
@AutoConfigureRestDocs(uriHost = "just-pickup.com", uriPort = 8000)
|
||||||
|
class ItemCustomerApiControllerTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MockMvc mockMvc;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
ItemService itemService;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private StoreRepository storeRepository;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private FavoriteStoreRepository favoriteStoreRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("상품리스트 조회")
|
||||||
|
void getItem() throws Exception {
|
||||||
|
// GIVEN
|
||||||
|
List<String> itemIds = List.of("1","2");
|
||||||
|
List<GetItemDto> willReturnDtoList =
|
||||||
|
List.of(
|
||||||
|
GetItemDto.builder()
|
||||||
|
.id(1L)
|
||||||
|
.salesYn(Yn.Y)
|
||||||
|
.price(1500L)
|
||||||
|
.name("아메리카노")
|
||||||
|
.itemOptions(List.of(
|
||||||
|
GetItemDto.ItemOptionDto.builder()
|
||||||
|
.id(1L)
|
||||||
|
.name("Hot")
|
||||||
|
.optionType(OptionType.REQUIRED)
|
||||||
|
.build()
|
||||||
|
,GetItemDto.ItemOptionDto.builder()
|
||||||
|
.id(2L)
|
||||||
|
.name("add shot")
|
||||||
|
.optionType(OptionType.OTHER)
|
||||||
|
.build()
|
||||||
|
))
|
||||||
|
.build(),
|
||||||
|
GetItemDto.builder()
|
||||||
|
.id(2L)
|
||||||
|
.salesYn(Yn.Y)
|
||||||
|
.price(2500L)
|
||||||
|
.name("카페라테")
|
||||||
|
.itemOptions(List.of(
|
||||||
|
GetItemDto.ItemOptionDto.builder()
|
||||||
|
.id(1L)
|
||||||
|
.name("Hot")
|
||||||
|
.optionType(OptionType.REQUIRED)
|
||||||
|
.build()
|
||||||
|
,GetItemDto.ItemOptionDto.builder()
|
||||||
|
.id(2L)
|
||||||
|
.name("add shot")
|
||||||
|
.optionType(OptionType.OTHER)
|
||||||
|
.build()
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
given(itemService.getItemAndItemOptions(any() ))
|
||||||
|
.willReturn(willReturnDtoList);
|
||||||
|
|
||||||
|
String param = String.join(",", itemIds);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
ResultActions actions = mockMvc.perform(get("/api/customer/items/{itemIds}", param));
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
actions.andExpect(status().isOk())
|
||||||
|
.andDo(print())
|
||||||
|
.andDo(document("customer-itemList-get",
|
||||||
|
pathParameters(
|
||||||
|
parameterWithName("itemIds").description("상품 고유 번호리스트")
|
||||||
|
),
|
||||||
|
responseFields(
|
||||||
|
fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"),
|
||||||
|
fieldWithPath("message").description("메시지"),
|
||||||
|
fieldWithPath("data[*].id").description("상품 고유 번호"),
|
||||||
|
fieldWithPath("data[*].name").description("상품 이름"),
|
||||||
|
fieldWithPath("data[*].salesYn").description("화면 표시 여부 Y/N"),
|
||||||
|
fieldWithPath("data[*].price").description("상품 가격"),
|
||||||
|
fieldWithPath("data[*].itemOptions[*].id").description("아이템 옵션 고유 번호"),
|
||||||
|
fieldWithPath("data[*].itemOptions[*].optionType").description("옵션 타입"),
|
||||||
|
fieldWithPath("data[*].itemOptions[*].name").description("옵션명")
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -65,6 +65,8 @@
|
|||||||
domain-httpRequestCode-etc
|
domain-httpRequestCode-etc
|
||||||
|
|
||||||
== 유저
|
== 유저
|
||||||
|
=== 로그인 된 회원 조회
|
||||||
|
operation::customer-get-mypage[snippets='curl-request,http-request,http-response,request-headers,response-fields']
|
||||||
=== 회원 조회
|
=== 회원 조회
|
||||||
operation::customer-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
operation::customer-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
||||||
=== 회원 조회 (존재하지 않는 회원)
|
=== 회원 조회 (존재하지 않는 회원)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public abstract class UserDto {
|
|||||||
// == 생성 메소드 == //
|
// == 생성 메소드 == //
|
||||||
public UserDto(Customer customer) {
|
public UserDto(Customer customer) {
|
||||||
this.id = customer.getId();
|
this.id = customer.getId();
|
||||||
|
this.email = customer.getEmail();
|
||||||
this.password = customer.getPassword();
|
this.password = customer.getPassword();
|
||||||
this.name = customer.getName();
|
this.name = customer.getName();
|
||||||
this.phoneNumber = customer.getPhoneNumber();
|
this.phoneNumber = customer.getPhoneNumber();
|
||||||
|
|||||||
@@ -26,6 +26,33 @@ public class UserController {
|
|||||||
|
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
|
@GetMapping("/customer/")
|
||||||
|
public ResponseEntity getCustomerByToken(@Valid @RequestHeader(value = "user-id") String userId ) {
|
||||||
|
|
||||||
|
CustomerDto customerDto = userService.findCustomerByUserId(Long.parseLong(userId));
|
||||||
|
|
||||||
|
GetCustomerByTokenResponse getCustomerByTokenResponse = new GetCustomerByTokenResponse(customerDto);
|
||||||
|
|
||||||
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
|
.body(Result.createSuccessResult(getCustomerByTokenResponse));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data @NoArgsConstructor @AllArgsConstructor
|
||||||
|
static class GetCustomerByTokenResponse {
|
||||||
|
private Long userId;
|
||||||
|
private String email;
|
||||||
|
private String userName;
|
||||||
|
private String phoneNumber;
|
||||||
|
|
||||||
|
public GetCustomerByTokenResponse(CustomerDto customerDto) {
|
||||||
|
this.userId = customerDto.getId();
|
||||||
|
this.email = customerDto.getEmail();
|
||||||
|
this.userName = customerDto.getName();
|
||||||
|
this.phoneNumber = customerDto.getPhoneNumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/customer/{userId}")
|
@GetMapping("/customer/{userId}")
|
||||||
public ResponseEntity getCustomer(@PathVariable("userId") Long userId) {
|
public ResponseEntity getCustomer(@PathVariable("userId") Long userId) {
|
||||||
|
|
||||||
|
|||||||
@@ -53,5 +53,4 @@ token:
|
|||||||
refresh-expired-time: 604800000
|
refresh-expired-time: 604800000
|
||||||
secret: $2a$10$q42lY7Y18xqrFt1qbODZIO4OMTeOxnrCe7tF3n9bazJinVE7VH5Pi
|
secret: $2a$10$q42lY7Y18xqrFt1qbODZIO4OMTeOxnrCe7tF3n9bazJinVE7VH5Pi
|
||||||
refresh-token-name: refresh-token
|
refresh-token-name: refresh-token
|
||||||
access-token-name: access-token
|
access-token-name: access-token
|
||||||
fegin: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmZWlnbiIsImV4cCI6MTE2NDY5NzY4NzAsImlhdCI6MTY0Njk3Njg3MH0.5x4Nx7oMnpF0_kZpbZsiB1u9eEbQ4IKIhJlEsa3D22cjZjvTHKz57GCz0sgXb_olhSNIVv9xF41A29-XYiFeBQ
|
|
||||||
@@ -21,6 +21,7 @@ import org.springframework.context.annotation.ComponentScan;
|
|||||||
import org.springframework.context.annotation.FilterType;
|
import org.springframework.context.annotation.FilterType;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.restdocs.headers.HeaderDocumentation;
|
||||||
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;
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ import java.util.stream.Collectors;
|
|||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
import static org.mockito.BDDMockito.willThrow;
|
import static org.mockito.BDDMockito.willThrow;
|
||||||
|
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
|
||||||
|
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
|
||||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
|
||||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
|
||||||
@@ -62,6 +65,53 @@ class UserControllerTest {
|
|||||||
@SpyBean
|
@SpyBean
|
||||||
CookieProvider cookieProvider;
|
CookieProvider cookieProvider;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("로그인된 회원 조회")
|
||||||
|
void getCustomerByToken() throws Exception {
|
||||||
|
// GIVEN
|
||||||
|
long userId = 1L;
|
||||||
|
|
||||||
|
CustomerDto willReturnDto = CustomerDto.builder()
|
||||||
|
.id(1L)
|
||||||
|
.name("이름")
|
||||||
|
.password("password!@#")
|
||||||
|
.email("hoonasdasd@naver.com")
|
||||||
|
.phoneNumber("010-1234-5678")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
given(userService.findCustomerByUserId(userId))
|
||||||
|
.willReturn(willReturnDto);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
ResultActions actions = mockMvc.perform(get("/customer/")
|
||||||
|
.header("user-id",userId));
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
actions.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("code").value(Code.SUCCESS.name()))
|
||||||
|
.andExpect(jsonPath("message").value(""))
|
||||||
|
.andExpect(jsonPath("data.userId").value(1))
|
||||||
|
.andExpect(jsonPath("data.email").value("hoonasdasd@naver.com"))
|
||||||
|
.andExpect(jsonPath("data.userName").value("이름"))
|
||||||
|
.andExpect(jsonPath("data.phoneNumber").value("010-1234-5678"))
|
||||||
|
.andDo(print())
|
||||||
|
.andDo(document("customer-get-mypage",
|
||||||
|
requestHeaders(
|
||||||
|
headerWithName("user-id").description("로그인한 유저 id")
|
||||||
|
),
|
||||||
|
responseFields(
|
||||||
|
fieldWithPath("code").description("결과코드 SUCCESS/ERROR"),
|
||||||
|
fieldWithPath("message").description("메시지"),
|
||||||
|
fieldWithPath("data.userId").description("회원 고유번호"),
|
||||||
|
fieldWithPath("data.userName").description("회원 이름"),
|
||||||
|
fieldWithPath("data.email").description("회원 이메일"),
|
||||||
|
fieldWithPath("data.phoneNumber").description("회원 휴대폰 번호")
|
||||||
|
))
|
||||||
|
)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("회원 조회")
|
@DisplayName("회원 조회")
|
||||||
void getCustomer() throws Exception {
|
void getCustomer() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user