Authored by 张文文

添加跳转到卖家优惠券列表 review by lea.guo

... ... @@ -4,4 +4,9 @@ export default [
path: '/xianyu/home/coupon.html',
component: () => import(/* webpackChunkName: "home.coupon" */ './list'),
},
{
name: 'SalerCoupon',
path: '/xianyu/home/salerCoupon.html',
component: () => import(/* webpackChunkName: "home.coupon" */ './saler-list'),
},
];
... ...
... ... @@ -55,6 +55,10 @@
<div class="couponErrorPageImage"></div>
暂无优惠券
</div>
<div class="saler-wrapper" @click="jumpToSalerList">
<div class="saler-img"></div>
<div class="saler-text">卖家劵</div>
</div>
</LayoutApp>
</template>
... ... @@ -70,12 +74,12 @@ export default {
components: {EmptyList},
activated: function() {
this.type = 'unused';
this.fetchCouponList({type: 'unused', isReset: true}).then(r=>{
this.fetchCouponList({type: 'unused', userType: this.userType, isReset: true}).then(r=>{
this.list = r;
this.showEmpty = !(r && r.length);
});
this.fetchCouponList({type: 'used', isReset: true});
this.fetchCouponList({type: 'overtime', isReset: true});
this.fetchCouponList({type: 'used', userType: this.userType, isReset: true});
this.fetchCouponList({type: 'overtime', userType: this.userType, isReset: true});
},
data() {
return {
... ... @@ -87,6 +91,7 @@ export default {
pullDownRefresh: false
},
type: 'unused',
userType: 0, // 0:全部 1:买家 2:卖家
list: [],
showEmpty: false
};
... ... @@ -114,7 +119,7 @@ export default {
},
async onPullingUp() {
this.list = await this.fetchCouponList({type: this.type});
this.list = await this.fetchCouponList({type: this.type, userType: this.userType});
this.showEmpty = this[this.type].isEmpty;
},
... ... @@ -126,6 +131,12 @@ export default {
type: 8
}
});
},
jumpToSalerList() {
this.$router.push({
name: 'SalerCoupon',
});
}
},
computed: {
... ... @@ -342,6 +353,37 @@ export default {
}
}
.saler-wrapper {
background: #002B47;
width: 160px;
height: 60px;
border-top-left-radius: 45px;
border-bottom-left-radius: 45px;
position: absolute;
right: 0;
bottom: 80px;
display: flex;
flex-direction: row;
align-items: center;
.saler-img {
background: url(~statics/image/coupon/mjq_ic@3x.png) no-repeat;
background-size: contain;
width: 36px;
height: 24px;
margin-left: 26px;
}
.saler-text {
font-size: 24px;
line-height: 60px;
color: #FFFFFF;
letter-spacing: 0;
margin-left: 10px;
text-align: center;
}
}
.empty-wrapper {
width: 100%;
margin: auto 0;
... ...
<template>
<LayoutApp title="卖家优惠券">
<div class="tab">
<div class="item right-line" :class="type ==='unused' ? 'item-selected' : 'item-default'"
@click="onChangeList('unused')">未使用{{unused.total && '('+ unused.total + ')' || null}}
</div>
<div class="item right-line" :class="type ==='used' ? 'item-selected' : 'item-default'"
@click="onChangeList('used')">已使用{{used.total && '('+ used.total + ')' || null}}
</div>
<div class="item" :class="type ==='overtime' ? 'item-selected' : 'item-default'"
@click="onChangeList('overtime')">已失效{{overtime.total && '('+ overtime.total + ')' || null}}
</div>
</div>
<LayoutScroll ref="couponlist"
class="coupon-list"
:loading="loadingOptions"
@pulling-up="onPullingUp" v-show="!showEmpty">
<div class="item" v-for="(item,index) in list">
<div :class="type === 'unused' ? 'item-bg' : 'item-gray-bg'">
<div class="item-left">
<div class="item-price" :class="type !== 'unused' && 'gray'">{{item.coupon_value}}</div>
<div class="item-rule" v-if="item.use_rule" :class="type !== 'unused' && 'gray'">{{item.use_rule}}</div>
</div>
<div class="item-right">
<div class="item-name" :class="type !== 'unused' && 'gray'">
<span class="item-type" :class="type !== 'unused' && 'gray'">[{{item.coupon_type_name}}]</span>
{{item.coupon_name}}
</div>
<div class="item-time" :class="type !== 'unused' && 'gray'">{{item.coupon_validity}}</div>
<div class="item-desc-btn" :class="type !== 'unused' && 'gray'" @click="handleShowNotice(item,index)">
使用说明
<div class="down" :class="item.showNotice && 'up'"></div>
</div>
<div class="time-up" v-if="type ==='unused' && item.is_expired_soon === 'Y'"></div>
<div class="item-used-flag" v-if="type === 'used'"></div>
<div class="item-use" v-if="type === 'unused'" @click="goUseList(item.coupon_token)">
立即使用
</div>
<div class="item-overtime-flag" v-if="type === 'overtime'"></div>
</div>
</div>
<div class="notice" v-show="item.showNotice">
<div class="shadow"></div>
<div v-for="no in item.notes" class="row">
<div class="mr10">•</div>
<div class="no-text">{{no}}</div>
</div>
</div>
</div>
</LayoutScroll>
<div
class="empty-wrapper"
v-show="showEmpty"
>
<div class="couponErrorPageImage"></div>
暂无优惠券
</div>
</LayoutApp>
</template>
<script>
import {createNamespacedHelpers} from 'vuex';
import EmptyList from '../../../components/ufo-no-item';
const {mapState, mapActions} = createNamespacedHelpers('home/salerCoupon');
export default {
name: 'Coupon',
components: {EmptyList},
activated: function() {
this.type = 'unused';
this.fetchSalerCouponList({type: 'unused', userType: this.userType, isReset: true}).then(r=>{
this.list = r;
this.showEmpty = !(r && r.length);
});
this.fetchSalerCouponList({type: 'used', userType: this.userType, isReset: true});
this.fetchSalerCouponList({type: 'overtime', userType: this.userType, isReset: true});
},
data() {
return {
scrollOptions: {
bounce: {
top: false
},
pullUpLoad: true,
pullDownRefresh: false
},
type: 'unused',
userType: 2, // 0:全部 1:买家 2:卖家
list: [],
showEmpty: false
};
},
methods: {
...mapActions(['fetchSalerCouponList']),
onChangeList(type) {
// 切换tab
this.type = type;
// 切换list
this.list = this[type].list;
this.showEmpty = this[type].isEmpty;
this.$refs.couponlist.scrollTo(0, 0);
},
handleShowNotice(item, index) {
if (item.showNotice !== void(0)) {
item.showNotice = !item.showNotice;
} else {
item.showNotice = true;
}
this.$set(this.list, index, item);
},
async onPullingUp() {
this.list = await this.fetchSalerCouponList({type: this.type, userType: this.userType});
this.showEmpty = this[this.type].isEmpty;
},
goUseList(coupon_token) {
return this.$router.push({
name: 'List',
query: {
coupon_token,
type: 8
}
});
}
},
computed: {
...mapState(['unused', 'used', 'overtime']),
loadingOptions() {
let info = this[this.type];
return {
hide: !this.list || !this.list.length,
noMore: info && info.reachedEnd
}
}
},
};
</script>
<style lang="scss" scoped>
.tab {
position: relative;
display: flex;
width: 100%;
height: 88px;
padding: 14px 0;
align-items: center;
z-index: 9999;
background: #fff;
.item {
font-size: 28px;
flex: 1;
height: 60px;
text-align: center;
line-height: 60px;
}
.right-line {
border-right: 1px solid #E0E0E0;
}
.item-default {
color: #B0B0B0;
}
.item-selected {
color: #444444;
}
}
.coupon-list {
background: #f5f5f5;
.item {
width: 100%;
margin-top: 20px;
}
.item-bg {
background: url(~statics/image/coupon/bg@3x.png) no-repeat;
width: 710px;
height: 200px;
background-size: cover;
margin: 0 auto;
display: flex;
position: relative;
z-index: 10;
}
.down {
transform: rotate(0deg);
background: url(~statics/image/coupon/down@3x.png) no-repeat;
background-size: contain;
width: 20px;
height: 20px;
margin-left: 10px;
margin-top: 4px;
}
.up {
margin-top: -8px !important;
transform: rotate(180deg);
}
.shadow {
opacity: 0.7;
background: #fff;
position: absolute;
top: 0;
left: 0;
height: 2px;
width: 702px;
box-shadow: #ddd 0 1px 10px 10px;
}
.item-left {
width: 230px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.item-price {
font-size: 72px;
font-weight: bold;
color: #002B47;
}
.item-rule {
font-size: 24px;
margin-top: 4px;
color: #002B47;
}
}
.item-right {
margin-left: 6px;
.item-name {
font-size: 24px;
color: #222;
margin-top: 22px;
width: 320px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
height: 60px;
}
.item-type {
color: #002B47;
}
.item-time {
margin-top: 10px;
font-size: 22px;
color: #999;
}
.item-desc-btn {
margin-top: 26px;
font-size: 22px;
color: #999;
display: flex;
align-items: center;
}
.time-up {
background: url(~statics/image/coupon/time-up@3x.png) no-repeat;
background-size: cover;
position: absolute;
top: 0;
right: 0;
width: 80px;
height: 80px;
}
.item-used-flag {
background: url(~statics/image/coupon/used@3x.png) no-repeat;
background-size: cover;
position: absolute;
right: 30px;
width: 130px;
height: 130px;
top: 30px;
}
.item-overtime-flag {
background: url(~statics/image/coupon/overtime@3x.png) no-repeat;
background-size: cover;
position: absolute;
right: 30px;
width: 130px;
height: 130px;
top: 30px;
}
}
.gray {
color: #ccc !important;
}
.item-gray-bg {
background: url(~statics/image/coupon/bg-gray@3x.png) no-repeat;
width: 710px;
height: 200px;
background-size: cover;
margin: 0 auto;
display: flex;
position: relative;
z-index: 10;
}
.notice {
opacity: 0.7;
background: #fff;
margin: -10px 20px 0 20px;
padding: 36px 26px 26px 26px;
position: relative;
.mr10 {
margin-right: 10px;
}
.row {
display: flex;
margin-bottom: 8px;
}
.no-text {
font-size: 22px;
color: #444;
}
}
}
.empty-wrapper {
width: 100%;
margin: auto 0;
position: absolute;
top: 0;
bottom: 0;
background: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-size: 28px;
color: #b0b0b0;
}
.couponErrorPageImage {
background: url(~statics/image/coupon/no_coupon.png) no-repeat;
background-size: cover;
width: 208px;
height: 130px;
margin-bottom: 30px;
}
.item-use {
position: absolute;
right: 20px;
bottom: 20px;
width: 130px;
height: 50px;
border: 1px solid #444;
border-radius: 25px;
justify-content: center;
align-items: center;
font-size: 20px;
color: #444;
display: flex;
}
</style>
... ...
... ... @@ -56,6 +56,7 @@ export default function() {
page: couponData.page,
limit: couponData.limit,
type: couponData.type,
userType: param.userType
};
if (param.isReset) {
... ...
... ... @@ -3,6 +3,7 @@ import channel from './channel';
import favorite from './favorite';
import news from './news';
import coupon from './coupon';
import salerCoupon from './salerCoupon';
import bindAccount from './bindAccount';
export default function() {
return {
... ... @@ -24,6 +25,7 @@ export default function() {
favorite: favorite(),
news: news(),
coupon: coupon(),
salerCoupon: salerCoupon(),
bindAccount: bindAccount()
}
};
... ...
export default function() {
return {
namespaced: true,
state: {
unused: {
type: 'unused',
isFetching: false,
reachedEnd: false,
isEmpty: false,
list: [],
filter: 0,
page: 0,
limit: 10,
total: 0
},
used: {
type: 'used',
isFetching: false,
reachedEnd: false,
isEmpty: false,
list: [],
filter: 0,
page: 0,
limit: 10,
total: 0
},
overtime: {
type: 'overtime',
isFetching: false,
reachedEnd: false,
isEmpty: false,
list: [],
filter: 0,
page: 0,
limit: 10,
total: 0
},
},
mutations: {
addList(state, { data }) {
state[data.type] = data;
}
},
actions: {
async fetchSalerCouponList({ commit, state }, param) {
if (!param.type) {
return;
}
let couponData = {...state[param.type]};
if (!param.isReset && couponData.reachedEnd) {
return couponData.list;
}
let params = {
page: couponData.page,
limit: couponData.limit,
type: couponData.type,
userType: param.userType
};
if (param.isReset) {
params.page = 1;
} else {
params.page += 1;
}
params.filter = 0;
let result = await this.$api.get('/api/ufo/coupon/list', {...params});
if (result.code === 200) {
let data = result.data;
if (typeof data === 'object' && Object.keys(data).length) {
for (let key in data) {
if (key === 'coupons') {
couponData.list = data.page > 1 ? couponData.list.concat(data.coupons) : data.coupons;
} else {
couponData[key] = data[key];
}
}
if (data.page === data.totalPage) {
couponData.reachedEnd = true;
}
couponData.list.length ? couponData.isEmpty = false : couponData.isEmpty = true;
commit('addList', { data: couponData });
}
} else {
couponData.isEmpty = true;
commit('addList', { data: couponData });
}
return couponData.list || [];
}
},
};
}
... ...
... ... @@ -83,7 +83,7 @@ export default {
productId: productId,
}
const result = await this.$api.post('/api/ufo/product/couponTopList', params);
const result = await this.$api.get('/api/ufo/product/couponTopList', params);
if (result.code === 200) {
const couponTopList = result.data || [];
... ...