Authored by TaoHuang

add buyer page

import createAPI from 'utils/create-api';
export default function addCouponList(Vue, CouponList) {
createAPI(Vue, CouponList, ['closeAction', 'payAction'], true);
}
... ...
<template>
<YohoActionSheet ref="actionSheet" @cancel="close">
<div class="pay-type-wrapper">
<div class="header">
<div class="title">选择优惠券</div>
<span><i class="iconfont iconweibiao45133 close" @click="close"></i></span>
</div>
<slot name="content">
<div class="pay-list-wrapper">
<div class="pay-list-item" v-for="item in data" :key="item.coupon_code">
<div class="pay-info">
<div class="price">{{item.coupon_value_str}}</div>
<div class="price-desc">{{item.use_rule_str}}</div>
</div>
<div class="coupon-info">
<div class="coupon-name">[{{item.coupon_type_name}}]{{item.coupon_name}}</div>
<div class="coupon-time">{{item.coupon_validity}}</div>
</div>
<Check class="check" :value="item.selected === 'Y'"></Check>
</div>
</div>
</slot>
<div name="footer">
<YohoButton txt="确定" class="footer" @click="pay"></YohoButton>
</div>
</div>
</YohoActionSheet>
</template>
<script>
import YohoActionSheet from '../action-sheet';
import Check from '../order-pay-type/check2';
import YohoButton from '../button';
export default {
name: 'OrderCouponList',
props: {
data: {
type: Array,
default() {
return [];
}
},
},
components: {
YohoButton,
YohoActionSheet,
Check
},
data() {
return {};
},
methods: {
show() {
this.$refs.actionSheet.show();
},
hide() {
this.$refs.actionSheet.hide();
},
close() {
this.hide();
this.$emit('closeAction');
},
pay() {
this.$emit('payAction');
}
}
};
</script>
<style lang="scss" scoped>
.pay-type-wrapper {
height: 960px;
background: white;
position: relative;
display: flex;
flex-direction: column;
}
.header {
display: flex;
justify-content: space-between;
padding: 40px;
}
.title {
font-weight: bold;
font-size: 32px;
color: #222;
}
.close {
font-size: 32px;
}
.pay-list-wrapper {
flex: 1;
overflow-y: auto;
background-color: #f5f5f5;
}
.pay-list-item {
height: 200px;
font-size: 28px;
margin: 20px 20px;
display: flex;
justify-content: space-between;
align-items: center;
background: url(~statics/image/order/bg@3x.png) no-repeat;
background-size: cover;
}
.check {
font-size: 48px;
margin-left: 40px;
margin-right: 40px;
}
.pay-info {
width: 210px;
}
.footer {
font-size: 32px;
}
.price-info {
margin-top: 40px;
margin-bottom: 60px;
}
.price {
font-size: 72px;
color: #002b47;
text-align: center;
font-weight: bolder;
}
.price-desc {
font-size: 24px;
color: #002b47;
text-align: center;
}
.coupon-info {
flex: 1;
height: 160px;
padding-left: 20px;
}
.coupon-name {
font-size: 24px;
color: #002b47;
margin-bottom: 40px;
}
.coupon-time {
font-size: 22px;
color: #999;
}
</style>
... ...
import CouponList from './coupon-list';
import addCouponList from './api';
CouponList.install = function(Vue) {
Vue.component(CouponList.name, CouponList);
addCouponList(Vue, CouponList);
};
export default CouponList;
... ...
... ... @@ -10,6 +10,7 @@ import Lazy from 'vue-lazyload';
import cookie from 'yoho-cookie';
import yoho from 'common/yoho';
import OrderPayType from 'components/order-pay-type';
import OrderCouponList from 'components/order-coupon-list';
import Bind from 'components/bind';
import sdk from 'yoho-activity-sdk';
... ... @@ -39,6 +40,7 @@ Vue.use(ImagePreview);
Vue.prop('api', api);
Vue.use(Lazy, { error: '' });
Vue.use(OrderPayType);
Vue.use(OrderCouponList);
Vue.use(Bind);
... ...
... ... @@ -2,13 +2,16 @@
<LayoutApp :show-back="true">
<div class="body">
<TitleComp txt="确认订单" class="title-class"></TitleComp>
<AddressInfo :data="orderDetail.userAddress" class="order-item" :show-tip="false"></AddressInfo>
<ProductInfo :data="orderDetail.goodsInfo" class="product-info order-item"></ProductInfo>
<BuyerFeeInfo :data="price" class="order-item"></BuyerFeeInfo>
<OrderInfo class="order-item"></OrderInfo>
<AddressInfo :data="address" class="order-item" :show-tip="false"></AddressInfo>
<ProductInfo :data="orderDetail.good" class="product-info order-item"></ProductInfo>
<Coupon class="order-item" :data="orderDetail.recommendedCouponInfo" @click="onCouponClick"></Coupon>
<BuyerFeeInfo :data="orderDetail.promotionFormulaList" class="order-item"></BuyerFeeInfo>
<div class="tip2 order-item">{{orderDetail.specialTips}}</div>
<div class="tip order-item" v-html="replaceBr(orderDetail.damagesDesc)"></div>
<OrderInfo class="order-item" :pay-way="orderDetail.paymentWay" :delivery-way="orderDetail.deliveryWay"></OrderInfo>
</div>
<OrderFooter class="footer"></OrderFooter>
<OrderFooter class="footer" :amount="orderDetail.amount"></OrderFooter>
</LayoutApp>
</template>
... ... @@ -20,23 +23,19 @@ import TitleComp from './components/confirm/title';
import BuyerFeeInfo from './components/confirm/buyer-fee';
import OrderInfo from './components/confirm/order-info';
import OrderFooter from './components/confirm/buyer-order-footer';
import Coupon from './components/confirm/coupon';
import { Types, UserType } from 'store/order/order-confirm';
import { get } from 'lodash';
import { createNamespacedHelpers } from 'vuex';
import { createNamespacedHelpers, mapState } from 'vuex';
const { mapState, mapActions, mapMutations } = createNamespacedHelpers('order/orderConfirm');
const { mapState: mapOrderState, mapActions: mapOrderAction, mapMutations: mapOrderMutations } = createNamespacedHelpers('order/orderConfirm');
export default {
name: 'OrderConfirm',
props: {
orderCode: {
type: String,
default: ''
}
},
props: ['productId', 'sizeId', 'tradeTypeId'],
data() {
return {
price: {}
};
return {};
},
components: {
ProductInfo,
... ... @@ -44,16 +43,39 @@ export default {
TitleComp,
BuyerFeeInfo,
OrderInfo,
OrderFooter
OrderFooter,
Coupon
},
mounted() {
this.fetchOrderDetail({ orderCode: this.orderCode });
async mounted() {
this.fetchUserStatus();
this.fetchOrderAddress({ tabType: UserType.buy });
await this.$store.dispatch('product/getSelectedTradeProduct', {
productId: this.productId,
sizeId: this.sizeId
});
this.fetchPayment({ skup: this.productDetail.skup });
},
computed: {
...mapState(['orderDetail'])
...mapOrderState(['address', 'orderDetail']),
...mapState({
productDetail: state => {
return {
skup: get(state.product.selectedProductInfo, 'size.skup', '')
};
}
})
},
methods: {
...mapActions(['fetchOrderDetail'])
...mapOrderAction(['fetchOrderAddress', 'fetchUserStatus', 'fetchPayList', 'fetchPayment']),
replaceBr(str) {
return str ? str.replace(/\n/g, '<br />') : '';
},
onCouponClick() {
this.$createOrderCouponList({
data: this.orderDetail.couponList
}).show();
}
}
};
</script>
... ... @@ -64,6 +86,8 @@ export default {
bottom: 0;
width: 100%;
z-index: 100;
background-color: white;
border-top: 1px solid #eee;
}
.body {
... ... @@ -87,4 +111,13 @@ export default {
height: 260px;
}
.tip {
font-size: 24px;
color: #999;
}
.tip2 {
font-size: 28px;
}
</style>
... ...
<template>
<div class="agree">
<span @click="onClick"><Check v-model="val"></Check> 我已阅读并同意</span> <span class="link"
@click="onLinkClick">有货卖家协议</span>
@click="onLinkClick">{{desc}}</span>
</div>
</template>
... ... @@ -15,6 +15,10 @@ export default {
value: {
type: Boolean,
default: true
},
desc: {
type: String,
default: ''
}
},
components: {
... ...
<template>
<div class="price-wrapper">
<div class="price-item">
<div>商品金额</div>
<div>-¥10.00</div>
<div class="price-item" v-for="(item, index) in data" :key="index">
<div>{{item.promotion}}</div>
<div :class="getClass(index)">{{item.promotionAmount}}</div>
</div>
<div class="price-item">
<div>运费</div>
<div>-¥10.00</div>
</div>
<div class="price-item">
<div>实付金额</div>
<div class="red">¥799.00</div>
</div>
<div class="tip">如卖家原因导致交易失败,您将获得赔偿金¥200</div>
</div>
</template>
... ... @@ -24,14 +12,25 @@ export default {
name: 'BuyerFee',
props: {
data: {
type: Object,
type: Array,
default() {
return {};
return [];
}
},
desc: {
type: String,
default: ''
}
},
data() {
return {};
},
methods: {
getClass(index) {
return {
red: index === (this.data.length - 1)
};
}
}
};
</script>
... ... @@ -47,12 +46,6 @@ export default {
margin-top: 20px;
}
.tip {
margin-top: 20px;
font-size: 24px;
color: #999;
}
.red {
font-size: 36px;
color: red;
... ...
<template>
<div class="order-footer-wrapper">
<div class="btn1">
<span>待支付:<span class="red">¥2149.00</span></span>
<span>待支付:<span class="red">¥{{amount}}</span></span>
</div>
<YohoButton class="btn2" txt="去支付" @click="onClick"></YohoButton>
</div>
... ... @@ -11,11 +11,7 @@
export default {
name: 'BuyerOrderFooter',
computed: {
txt() {
return '';
}
},
props: ['amount'],
methods: {
onClick() {
this.$createOrderPayType().show();
... ...
... ... @@ -3,8 +3,8 @@
<ImageFormat :src="data.goodImg" width="90" height="90"></ImageFormat>
<div class="product-price">
<div class="red">¥299.00</div>
<div class="product-name">Air Jordan 1 Retro High Off-whitetro High Off-white球鞋</div>
<div class="red">¥{{data.goodPrice}}</div>
<div class="product-name">{{data.productName}}</div>
<div class="price">{{data.colorName}},{{data.sizeName}}</div>
</div>
</div>
... ...
<template>
<div class="coupon-wrapper" @click="onClick">
<div class="title">优惠券<span class="desc">{{data.desc}}</span></div>
<div><span class="red">{{data.coupon_amount_str}}</span><i class="iconfont iconright"></i></div>
</div>
</template>
<script>
export default {
name: 'OrderCoupon',
props: {
data: {
type: Object,
default() {
return {};
}
}
},
methods: {
onClick() {
this.$emit('click');
}
}
};
</script>
<style lang="scss" scoped>
.coupon-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
}
.title {
font-size: 32px;
display: flex;
align-items: center;
}
.desc {
font-size: 24px;
color: #3f3f3f;
margin-left: 10px;
}
.red {
color: #d0021b;
font-size: 28px;
margin-right: 10px;
}
</style>
... ...
... ... @@ -2,12 +2,12 @@
<div>
<div class="info">
<span>支付方式:</span>
<span>在线支付</span>
<span>{{payWay.paymentTypeName}}</span>
</div>
<div class="info">
<span>配送方式:</span>
<span>顺丰速运</span>
<span>{{deliveryWay.deliveryWayName}}</span>
</div>
</div>
</template>
... ... @@ -15,6 +15,20 @@
<script>
export default {
name: 'OrderInfo',
props: {
payWay: {
type: Object,
default() {
return {};
}
},
deliveryWay: {
type: Object,
default() {
return {};
}
}
}
};
</script>
... ...
... ... @@ -5,12 +5,11 @@ import OrderDetail from './order-detail';
export default [
{
name: 'OrderSellConfirm',
path: '/xianyu/order/sellerconfirm.html',
path: '/xianyu/order/sellconfirm.html',
component: () => import(/* webpackChunkName: "order" */ './seller-confirm'),
props: (route) => ({
productId: route.query.productId,
sizeId: route.query.sizeId,
tradeTypeId: route.query.tradeTypeId
sizeId: route.query.sizeId
})
},
{
... ... @@ -24,12 +23,11 @@ export default [
},
{
name: 'OrderBuyConfirm',
path: '/xianyu/order/buyerconfirm.html',
path: '/xianyu/order/buyconfirm.html',
component: () => import(/* webpackChunkName: "order" */ './buyer-confirm'),
props: (route) => ({
productId: route.query.productId,
sizeId: route.query.sizeId,
tradeTypeId: route.query.tradeTypeId
sizeId: route.query.sizeId
})
},
{
... ...
... ... @@ -9,7 +9,12 @@
<script>
export default {
name: 'PayPage',
props: ['orderCode', 'payment']
props: ['orderCode', 'payment'],
mounted() {
},
methods: {
}
};
</script>
... ...
... ... @@ -9,7 +9,7 @@
<AddressInfo :data="address" class="order-item"></AddressInfo>
</div>
<div class="footer">
<OrderAgree :value="agree" @input="changeAgree" class="agree-wrapper"></OrderAgree>
<OrderAgree :value="agree" @input="changeAgree" class="agree-wrapper" :desc="agreeDesc"></OrderAgree>
<YohoButton :txt="txt" @click="onClick" :disable="!agree"></YohoButton>
</div>
</LayoutApp>
... ... @@ -24,18 +24,13 @@ import TitleComp from './components/confirm/title';
import OrderMargin from './components/confirm/order-margin';
import OrderFee from './components/confirm/order-fee';
import OrderAgree from './components/confirm/agree';
import { Types } from 'store/order/order-confirm';
import { Types, UserType } from 'store/order/order-confirm';
import { get } from 'lodash';
import { createNamespacedHelpers, mapState } from 'vuex';
const { mapState: mapOrderState, mapActions: mapOrderAction, mapMutations: mapOrderMutations } = createNamespacedHelpers('order/orderConfirm');
const UserType = {
sell: 'sell',
buy: 'buy'
};
export default {
name: 'OrderConfirm',
props: ['productId', 'sizeId', 'tradeTypeId'],
... ... @@ -52,7 +47,8 @@ export default {
return {
txt: '提交',
error: false,
num: 1
num: 1,
agreeDesc: '有货卖家协议'
};
},
mounted() {
... ... @@ -60,8 +56,7 @@ export default {
this.fetchOrderAddress({ tabType: UserType.sell });
this.$store.dispatch('product/getSelectedTradeProduct', {
productId: this.productId,
sizeId: this.sizeId,
tradeTypedId: this.tradeTypeId
sizeId: this.sizeId
});
},
computed: {
... ...
... ... @@ -5,7 +5,14 @@ export const Types = {
FETCH_ORDER_USER_STATUS: 'FETCH_ORDER_USER_STATUS',
FETCH_ORDER_FEE: 'FETCH_ORDER_FEE',
CHANGE_PRICE: 'CHANGE_PRICE',
CHANGE_AGREE: 'CHANGE_AGREE'
CHANGE_AGREE: 'CHANGE_AGREE',
FETCH_ORDER_BUY_ORDER: 'FETCH_ODER_BUY_ORDER',
FETCH_ORDER_COUPON_LIST: 'FETCH_ORDER_COUPON_LIST'
};
export const UserType = {
sell: 'sell',
buy: 'buy'
};
export default function() {
... ... @@ -28,7 +35,10 @@ export default function() {
alipayStatus: false,
userStatus: false,
price: '',
agree: false
agree: false,
orderDetail: {},
couponList: []
},
mutations: {
[Types.FETCH_ORDER_ADDRESS](state, data) {
... ... @@ -42,6 +52,12 @@ export default function() {
},
[Types.CHANGE_AGREE](state, data) {
state.agree = data;
},
[Types.FETCH_ORDER_BUY_ORDER](state, data) {
state.orderDetail = data;
},
[Types.FETCH_ORDER_COUPON_LIST](state, data) {
state.couponList = data;
}
},
actions: {
... ... @@ -81,7 +97,19 @@ export default function() {
async fetchPayList({ commit }, payload) {
return this.$api.post('/api/order/paytype', payload);
}
},
async fetchPayment({ commit }, { skup }) {
const orderInfo = await this.$api.post('/api/order/confirm/buypayment', { skup, api_version: 1 });
const couponList = await this.$api.get('/api/order/confirm/coupon', { skup, depositRequirement: 'N' });
if (orderInfo.code !== 200) {
return;
}
commit(Types.FETCH_ORDER_BUY_ORDER, orderInfo.data);
commit(Types.FETCH_ORDER_COUPON_LIST, couponList.data);
},
},
getters: {},
};
... ...
... ... @@ -138,7 +138,7 @@ module.exports = {
api: 'app.address.gethidden',
},
// 计算订单价格
// 卖家计算订单价格
'/api/order/confirm/compute': {
auth: true,
ufo: true,
... ... @@ -173,6 +173,38 @@ module.exports = {
api: 'ufo.payment.findPayListDetail',
},
// 买家计算订单价格
'/api/order/confirm/buycompute': {
ufo: true,
auth: true,
api: 'ufo.order.compute',
params: {
skup: { type: Number, require: true }
},
},
// 买家预定单订单价格
'/api/order/confirm/buypayment': {
ufo: true,
auth: true,
path: 'shopping',
api: 'ufo.order.payment',
params: {
skup: { type: Number, require: true }
},
},
// 买家获得优惠券
'/api/order/confirm/coupon': {
ufo: true,
auth: true,
path: 'shopping',
api: 'ufo.order.selectCoupon',
params: {
skup: { type: Number, require: true }
},
},
// 订单物流信息
'/api/order/express': {
ufo: true,
... ... @@ -182,5 +214,5 @@ module.exports = {
tabType: { type: String, require: true }, // 订单来源
orderCode: { type: Number, require: true }, // 订单编号
},
},
}
};
... ...