Authored by 陈峰

Merge branch 'feature/ufo' into 'release/1.0'

Feature/ufo



See merge request !1
... ... @@ -542,7 +542,25 @@ const yoho = {
window.yohoInterface[name] = callback;
}
}, 500);
}
},
/**
* 跳转到 app 促销商品列表
* @param args
* @param success
* @param fail
*/
goCouponProductList(args, success, fail) {
if (this.isApp && window.yohoInterface) {
window.yohoInterface.triggerEvent(success || nullFun, fail || nullFun, {
method: 'go.couponProductList',
arguments: args
});
} else {
// tip(tipInfo);
}
},
};
... ...
... ... @@ -29,7 +29,7 @@
</template>
<template v-else>
<a :href="item.useNowLink" v-if="item.useNowLink" class="use-now">立即使用</a>
<div v-if="item.useNowLink" class="use-now" @click="onUseClick">立即使用</div>
<span class="top-tip" v-if="item.is_overdue_soon === 'Y'"></span>
</template>
</div>
... ... @@ -61,6 +61,14 @@ export default {
methods: {
onClickTip() {
this.show = !this.show;
},
onUseClick() {
this.$yoho.goCouponProductList({
coupon_code: this.item.coupon_code,
coupon_id: this.item.coupon_id,
title: '优惠活动商品',
coupon_title: `以下商品可使用【${this.item.coupon_name}】优惠券`
});
}
},
computed: {
... ... @@ -105,6 +113,7 @@ export default {
<style lang="scss" scoped>
.coupon-section {
margin-top: 20px;
margin-bottom: 20px;
}
... ... @@ -176,7 +185,7 @@ export default {
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
float: left;
padding: 22px;
padding: 20px;
font-size: 22px;
color: #b0b0b0;
position: relative;
... ... @@ -206,7 +215,7 @@ export default {
.title {
width: 370px;
font-size: 24px;
font-size: 22px;
color: #444;
display: -webkit-box;
-webkit-box-orient: vertical;
... ... @@ -216,13 +225,15 @@ export default {
.time {
position: absolute;
font-size: 20px;
top: 50%;
transform: translateY(-50%);
transform: translateY(-40%);
}
.use-intro {
font-size: 20px;
position: absolute;
bottom: 22px;
bottom: 18px;
}
.tip {
... ... @@ -233,7 +244,7 @@ export default {
}
.use-now {
font-size: 22px;
font-size: 20px;
position: absolute;
width: 130px;
height: 50px;
... ...
... ... @@ -43,7 +43,6 @@ export default {
height: 90px;
padding: 16px 20px;
background-color: #fff;
position: fixed;
top: 0;
left: 0;
z-index: 2;
... ...
... ... @@ -2,10 +2,10 @@
<LayoutApp>
<div :class="classes">
<div :class="[prefixCls + '-bar']">
<span class="back">
<span class="back" @click="onBackClick">
<i class="iconfont fontcls">&#xe763;</i>
</span>
<span class="help">
<span class="help" @click="onHelpClick">
<i class="iconfont fontcls">&#xe630;</i>
</span>
<div>
... ... @@ -19,6 +19,7 @@
</template>
<script>
export default {
name: 'Headers',
props: {
... ... @@ -78,18 +79,23 @@ export default {
['yoho-tab-active']: item.name === this.activeKey
}
];
},
onBackClick() {
this.$yoho.goBack({});
},
onHelpClick() {
this.$yoho.goNewPage({
url: window.location.protocol + '//m.yohobuy.com/service/qaDetail?keyword=%E4%BC%98%E6%83%A0%E5%88%B8&sonId=181'
});
}
},
watch: {
activeKey(val) {
activeKey() {
this.updateStatus();
},
value(val) {
this.activeKey = val;
}
},
created() {
// this.updateNav();
}
};
</script>
... ... @@ -126,12 +132,11 @@ export default {
background: #3a3a3a;
justify-content: center;
align-items: center;
position: fixed;
z-index: 4;
}
.#{$yoho-tab}-active {
color: #444444;
color: #444;
background-color: white;
}
... ... @@ -146,12 +151,22 @@ export default {
}
.back {
display: inline-block;
width: 90px;
height: 90px;
line-height: 90px;
position: absolute;
left: 20px;
left: 0;
text-align: center;
}
.help {
display: inline-block;
width: 90px;
height: 90px;
line-height: 90px;
position: absolute;
right: 20px;
right: 0;
text-align: center;
}
</style>
... ...
<template>
<Scroll ref="scroll" :options="options" @pulling-up="reachBottom" :data="data">
<div class="list-wrapper">
<Scroll ref="scroll" :options="options" @pulling-up="reachBottom" @pulling-down="pullRefresh" :data="data">
<slot></slot>
</Scroll>
</div>
</template>
<script>
... ... @@ -17,6 +19,12 @@ export default {
return {};
}
},
pullRefresh: {
type: Function,
default() {
return {};
}
},
reachBottom: {
type: Function,
default() {
... ... @@ -33,6 +41,9 @@ export default {
methods: {
forceUpdate() {
this.$refs.scroll.forceUpdate();
},
scrollTo(x, y) {
this.$refs.scroll.scrollTo(x, y, 1000);
}
},
components: {
... ... @@ -43,4 +54,10 @@ export default {
</script>
<style lang="scss" scoped>
.list-wrapper {
position: relative;
height: 100%;
overflow: hidden;
background-color: #f0f0f0;
}
</style>
... ...
... ... @@ -3,7 +3,7 @@ import Yoho from './yoho';
import Header from './components/header';
export default [{
path: '/coupon',
path: '/mapp/coupon',
component: Header,
children: [Ufo, Yoho]
}];
... ...
export default {
path: 'ufo',
path: 'ufo.html',
name: 'couponUfo',
component: () => import(/* webpackChunkName: "coupon" */ './list')
};
... ...
<template>
<div style="height: 100%;">
<div style="background-color: #f0f0f0;height: 100%;">
<div class="head"></div>
<ScrollView :data="ufoList" :options="scrollOptions" v-if="ufoList.length">
<ScrollView class="scroll-view" :data="ufoList" :options="scrollOptions" v-if="ufoList.length">
<CouponItem :item="item" v-for="(item, index) in ufoList" :key ="index"></CouponItem>
</ScrollView>
<Empty v-else></Empty>
</div>
</div>
</template>
... ... @@ -33,7 +30,7 @@ export default {
data() {
return {
scrollOptions: {
directionLockThreshold: 0
directionLockThreshold: 0,
}
};
},
... ... @@ -52,7 +49,7 @@ export default {
</script>
<style lang="scss" scoped>
.head {
height: 90px;
.scroll-view {
height: calc(100% - 90px);
}
</style>
... ...
export default {
path: 'yoho',
path: 'yoho.html',
name: 'couponYoho',
component: () => import(/* webpackChunkName: "coupon" */ './list')
};
... ...
<template>
<div style="height: 100%;">
<div class="head"></div>
<ClassicTabs ref="tabs" v-model="selectLabel" :data="tabLabels" @on-filter-change="onFilterChange"></ClassicTabs>
<div class="tab-slide-container">
... ... @@ -14,31 +13,29 @@
@scroll="scroll"
@change="changePage"
>
<SlideItem style="background-color: #f0f0f0;">
<ExchangeBox v-model="inputCouponCode" @click="onSubmitCode"></ExchangeBox>
<SlideItem>
<div class="filter-wrapper" v-if="showFilter">
<div class="filter-mask" @click="onMaskClick"></div>
<FilterBar :list="filterList" v-model="selectFilterId" class="filter"></FilterBar>
</div>
<div class="head"></div>
<ExchangeBox v-model="inputCouponCode" @click="onSubmitCode"></ExchangeBox>
<ScrollView ref="notuse" :data="getNotUseList" :options="scrollOptions" v-if="getNotUseList.length" :reach-bottom="reachBottom">
<ScrollView class="scroll-view1" ref="notuse" :data="getNotUseList" :options="scrollOptions" v-if="getNotUseList.length" :reach-bottom="reachBottom">
<CouponItem :item="item" v-for="(item, index) in getNotUseList" :key="index"></CouponItem>
</ScrollView>
<Empty v-else></Empty>
</SlideItem>
<SlideItem style="background-color: #f0f0f0;">
<ScrollView ref="use" :data="getUseList" :options="scrollOptions" v-if="getUseList.length" :reach-bottom="reachBottom">
<SlideItem>
<ScrollView class="scroll-view2" ref="use" :data="getUseList" :options="scrollOptions" v-if="getUseList.length" :reach-bottom="reachBottom">
<CouponItem :item="item" v-for="(item, index) in getUseList" :key="index"></CouponItem>
</ScrollView>
<Empty v-else></Empty>
</SlideItem>
<SlideItem style="background-color: #f0f0f0;">
<ScrollView ref="overtime" :data="getOvertimeList" options="scrollOptions" v-if="getOvertimeList.length" :reach-bottom="reachBottom">
<SlideItem>
<ScrollView class="scroll-view2" ref="overtime" :data="getOvertimeList" :options="scrollOptions" v-if="getOvertimeList.length" :reach-bottom="reachBottom">
<CouponItem :item="item" v-for="(item, index) in getOvertimeList" :key="index"></CouponItem>
</ScrollView>
<Empty v-else></Empty>
... ... @@ -69,18 +66,22 @@ export default {
asyncData({store}) {
return Promise.all([
store.dispatch('coupon/yoho/fetchYohoList', {
type: TYPE.notuse,
}),
type: TYPE.notuse,
refresh: true
}),
store.dispatch('coupon/yoho/fetchYohoList', {
type: TYPE.use,
}),
type: TYPE.use,
refresh: true
}),
store.dispatch('coupon/yoho/fetchYohoList', {
type: TYPE.overtime,
})
type: TYPE.overtime,
refresh: true
})
]);
},
data() {
return {
selectIndex: 0,
selectLabel: '未使用',
selectType: TYPE.notuse,
showFilter: false,
... ... @@ -112,7 +113,8 @@ export default {
more: '加载更多',
noMore: '以上是最新的内容'
}
}
},
bounce: true
},
slideOptions: {
listenScroll: true,
... ... @@ -140,6 +142,7 @@ export default {
methods: {
...mapActions(['getCouponCode', 'fetchYohoList', 'fetchYohoNum']),
changePage(current) {
this.selectIndex = current;
this.selectLabel = this.tabLabels[current].label;
this.selectType = this.tabLabels[current].type;
},
... ... @@ -169,15 +172,22 @@ export default {
}
});
},
reachBottom() {
this.fetchYohoList({type: this.selectType});
reachBottom(refresh = false) {
this.fetchYohoList({
type: this.selectType,
filter: this.tabLabels[this.selectIndex].selectFilterId,
refresh
}).then(() => {
this.$refs[this.selectType].forceUpdate();
});
}
},
watch: {
selectFilterId(val) {
this.tabLabels[0].selectFilterId = val;
this.$refs.notuse.scrollTo(0, 0);
this.onMaskClick();
return this.changePage(0);
this.reachBottom(true);
}
},
components: {
... ... @@ -194,8 +204,9 @@ export default {
</script>
<style lang="scss" scoped>
.head {
height: 90px;
.page-wrapper {
height: calc(100% - 90px);
}
.tab-slide-container {
... ... @@ -205,7 +216,8 @@ export default {
.filter-wrapper {
width: calc(100% / 3);
height: 100%;
position: fixed;
position: absolute;
top: 0;
z-index: 4;
}
... ... @@ -218,4 +230,12 @@ export default {
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}
.scroll-view1 {
height: calc(100% - 270px);
}
.scroll-view2 {
height: calc(100% - 180px);
}
</style>
... ...
... ... @@ -11,7 +11,13 @@ function _handleCoupon(item, type) {
item.usedOvertimeOrInValid = true;
}
item.useNowLink = 'fdsafdsa';
item.useNowLink = true;
// 线下店不可使用
if (item.is_online_avail) {
item.useNowLink = '';
}
return item;
}
... ... @@ -23,14 +29,24 @@ function _handleUfoCoupon(item) {
}
export default {
async fetchYohoList({commit, state}, {type, filter = 0}) {
async fetchYohoList({commit, state}, {type, filter = 0, refresh = false}) {
commit(Types.FETCH_YOHO_COUPON_REQUEST);
if (state.yohoList[type].page > state.yohoList[type].pageNum) {
return;
if (!refresh) {
if (state.yohoList[type].page > state.yohoList[type].pageNum) {
return false;
}
}
const result = await this.$api.get('/api/coupon/yoho/list', {type, filter, limit: 10, page: state.yohoList[type].page + 1});
const fetchPage = refresh ? 1 : state.yohoList[type].page + 1;
// 下一页的数据
const result = await this.$api.get('/api/coupon/yoho/list', {
type,
filter,
limit: 10,
page: fetchPage
});
if (result && result.code === 200) {
const data = {
... ... @@ -38,11 +54,12 @@ export default {
couponList: result.data.couponList.map((i) => _handleCoupon(i, type)),
pageNum: result.data.pageNum,
pageSize: result.data.pageSize,
total: result.data.total
total: result.data.total,
filterId: filter,
page: fetchPage,
refresh
};
console.log(data);
if (type === TYPE.notuse) {
data.filter = result.data.filters;
}
... ...
... ... @@ -17,6 +17,7 @@ export default function() {
pageSize: 10,
total: 0,
page: 0,
filterId: 0
},
use: {
couponList: [],
... ... @@ -24,13 +25,15 @@ export default function() {
pageSize: 10,
total: 0,
page: 0,
filterId: 0
},
overtime: {
couponList: [],
pageNum: 0,
pageSize: 10,
total: 0,
page: 0
page: 0,
filterId: 0
}
},
num: {
... ...
... ... @@ -4,16 +4,19 @@ export default {
[Types.FETCH_YOHO_COUPON_REQUEST](state) {
state.fetching = true;
},
[Types.FETCH_YOHO_COUPON_SUCCESS](state, {couponList, filter, type, pageNum, pageSize, total}) {
[Types.FETCH_YOHO_COUPON_SUCCESS](state, {couponList, filter, type, pageNum, pageSize, total, filterId, page, refresh}) {
state.fetching = false;
const list = state.yohoList[type].couponList;
const typeData = state.yohoList[type];
const list = typeData.couponList;
const newCouponList = refresh ? couponList : list.concat(couponList);
state.yohoList[type].couponList = list.concat(couponList);
state.yohoList[type].pageNum = pageNum;
state.yohoList[type].pageSize = pageSize;
state.yohoList[type].total = total;
state.yohoList[type].page += 1;
typeData.couponList = newCouponList;
typeData.pageNum = pageNum;
typeData.pageSize = pageSize;
typeData.total = total;
typeData.filterId = filterId;
typeData.page = page;
if (filter) {
state.filterList = filter;
... ...
... ... @@ -3,15 +3,9 @@ module.exports = [
route: /mapp\/order\/ufo\/\d+\.html/,
},
{
route: /coupon\/ufo/,
cache: true
route: /mapp\/coupon\/ufo/,
},
{
route: /coupon\/yoho/,
cache: true
},
{
route: /yoho\/coupon/,
cache: true
},
route: /mapp\/coupon\/yoho/,
}
];
... ...