592 lines
12 KiB
Vue
592 lines
12 KiB
Vue
|
<template>
|
|||
|
<view class="my-coupon">
|
|||
|
<view>
|
|||
|
<!--顶部导航栏-->
|
|||
|
<view class="tabr" :style="{ top: headerTop }">
|
|||
|
<view :class="typeClass == 'valid' ? `text-${themeColor.name} on` : ''" @tap="switchType('valid', 1)"
|
|||
|
>可用
|
|||
|
<text v-if="state === 1">({{ couponList.length }})</text>
|
|||
|
</view>
|
|||
|
<view :class="typeClass == 'used' ? `text-${themeColor.name} on` : ''" @tap="switchType('used', 2)"
|
|||
|
>已使用
|
|||
|
<text v-if="state === 2">({{ couponList.length }})</text>
|
|||
|
</view>
|
|||
|
<view
|
|||
|
:class="typeClass == 'invalid' ? `text-${themeColor.name} on` : ''"
|
|||
|
@tap="switchType('invalid', 3)"
|
|||
|
>已失效
|
|||
|
<text v-if="state === 3">({{ couponList.length }})</text>
|
|||
|
</view>
|
|||
|
<view class="border" :class="[typeClass, 'bg-' + themeColor.name]"></view>
|
|||
|
</view>
|
|||
|
<!--占位符-->
|
|||
|
<view class="place"></view>
|
|||
|
<!--优惠券列表-->
|
|||
|
<view class="coupon-list">
|
|||
|
<view
|
|||
|
v-if="state === 3 && couponList.length > 0 && !loading"
|
|||
|
class="empty-invalid"
|
|||
|
:class="'text-' + themeColor.name"
|
|||
|
@tap.stop="emptyInvalidCoupon"
|
|||
|
>
|
|||
|
清空失效优惠券
|
|||
|
</view>
|
|||
|
<!-- 优惠券列表 -->
|
|||
|
<view
|
|||
|
class="sub-list valid"
|
|||
|
:style="{ marginTop: state === 3 ? '50upx' : 0 }"
|
|||
|
>
|
|||
|
<view class="row" v-for="(row, index) in couponList" :key="index">
|
|||
|
<!-- content -->
|
|||
|
<view class="carrier">
|
|||
|
<view class="left">
|
|||
|
<view class="in1line title">
|
|||
|
<text class="cell-icon" :class="'bg-' + themeColor.name">{{
|
|||
|
parseInt(row.type, 10) === 1 ? '满减' : '直降'
|
|||
|
}}</text>
|
|||
|
{{ row.name }}
|
|||
|
</view>
|
|||
|
<view class="term" v-if="state !== 2">
|
|||
|
{{ row.startTime }} ~ {{ row.endTime }}
|
|||
|
</view>
|
|||
|
<view class="term" v-else>
|
|||
|
使用时间:{{ row.userTime }}
|
|||
|
</view>
|
|||
|
<view class="overdue" v-if="state === 3">
|
|||
|
<text class="iconfont iconyiguoqi2" :class="'text-' + themeColor.name"></text>
|
|||
|
</view>
|
|||
|
<view class="overdue" v-if="state === 2">
|
|||
|
<text class="iconfont iconyishiyong"></text>
|
|||
|
</view>
|
|||
|
<view class="usage">
|
|||
|
{{
|
|||
|
`每人限领${row.price}`
|
|||
|
}}
|
|||
|
已领{{ row.price }}
|
|||
|
总数 {{ row.num }}
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="right" :class="state !== 1 ? 'invalid' : 'bg-' + themeColor.name">
|
|||
|
<view class="ticket">
|
|||
|
<view class="num">
|
|||
|
{{ row.fallPrice ? moneySymbol +'直降'+ row.fallPrice : '减'+moneySymbol +row.price }}
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="criteria" v-if="parseInt(row.type, 10) === 1"> 满{{ row.fullPrice }}使用 </view>
|
|||
|
<view
|
|||
|
class="use view"
|
|||
|
:class="'text-' + themeColor.name"
|
|||
|
@tap="show(row)"
|
|||
|
|
|||
|
>
|
|||
|
商品
|
|||
|
</view>
|
|||
|
<view
|
|||
|
class="use"
|
|||
|
:class="'text-' + themeColor.name"
|
|||
|
v-if="state == 1"
|
|||
|
@tap="navTo('/pages/product/list')"
|
|||
|
>
|
|||
|
去使用
|
|||
|
</view>
|
|||
|
<view
|
|||
|
class="use"
|
|||
|
:class="'text-' + themeColor.name"
|
|||
|
v-if="state == 2"
|
|||
|
@tap="navTo(`/pages/order/detail?id=${row.orderId}`)"
|
|||
|
>
|
|||
|
去查看
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<rf-load-more
|
|||
|
:status="loadingType"
|
|||
|
v-if="couponList.length > 0"
|
|||
|
></rf-load-more>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<rf-empty
|
|||
|
class="empty"
|
|||
|
info="暂无优惠券"
|
|||
|
v-if="couponList.length === 0 && !loading"
|
|||
|
></rf-empty>
|
|||
|
<!--显示部分商品的抽屉-->
|
|||
|
<uni-drawer
|
|||
|
class="rf-drawer"
|
|||
|
:visible="showRight"
|
|||
|
mode="right"
|
|||
|
@close="closeDrawer()"
|
|||
|
>
|
|||
|
<view class="rf-drawer-title" :class="'text-' + themeColor.name">可用商品列表</view>
|
|||
|
<view class="rf-drawer-list">
|
|||
|
<view
|
|||
|
class="rf-drawer-item"
|
|||
|
@tap="navTo(`/pages/product/product?id=${item.id}`)"
|
|||
|
v-for="item in currentCoupon.usableProduct"
|
|||
|
:key="item.id"
|
|||
|
>
|
|||
|
<view class="left">
|
|||
|
<view class="title">{{
|
|||
|
item.name
|
|||
|
.split('】')[0]
|
|||
|
.split('【')
|
|||
|
.join('')
|
|||
|
}}</view>
|
|||
|
<view class="desc in2line">{{ item.name.split('】')[1] }}</view>
|
|||
|
</view>
|
|||
|
<text class="iconfont iconyou"></text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="close">
|
|||
|
<view
|
|||
|
class="btn"
|
|||
|
:class="'bg-' + themeColor.name"
|
|||
|
plain="true"
|
|||
|
size="small"
|
|||
|
type="primary"
|
|||
|
@tap="hide"
|
|||
|
>
|
|||
|
关闭
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</uni-drawer>
|
|||
|
<rfLoading isFullScreen :active="loading"></rfLoading>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
<script>
|
|||
|
/**
|
|||
|
* @des 优惠券管理
|
|||
|
*
|
|||
|
* @author 237524947@qq.com
|
|||
|
* @date 2019-12-09 10:13
|
|||
|
* @copyright 2019
|
|||
|
*/
|
|||
|
import { couponClear, myCouponList } from '@/api/userInfo';
|
|||
|
import rfLoadMore from '@/components/rf-load-more/rf-load-more';
|
|||
|
import moment from '@/common/moment';
|
|||
|
import uniDrawer from '@/components/uni-drawer/uni-drawer';
|
|||
|
export default {
|
|||
|
components: {
|
|||
|
rfLoadMore,
|
|||
|
uniDrawer
|
|||
|
},
|
|||
|
data() {
|
|||
|
return {
|
|||
|
headerTop: 0,
|
|||
|
// 控制滑动效果
|
|||
|
typeClass: 'valid',
|
|||
|
theIndex: null,
|
|||
|
oldIndex: null,
|
|||
|
state: 1,
|
|||
|
isStop: false,
|
|||
|
couponList: [],
|
|||
|
loadingType: 'more',
|
|||
|
token: null,
|
|||
|
pageNum :0,
|
|||
|
showRight: false,
|
|||
|
moneySymbol: this.moneySymbol,
|
|||
|
currentCoupon: {},
|
|||
|
loading: true
|
|||
|
};
|
|||
|
},
|
|||
|
filters: {
|
|||
|
// 格式化时间
|
|||
|
time(val) {
|
|||
|
return moment(val * 1000).format('YYYY-MM-DD');
|
|||
|
},
|
|||
|
// 格式化时间
|
|||
|
timeFull(val) {
|
|||
|
return moment(val * 1000).format('YYYY-MM-DD HH:mm:ss');
|
|||
|
}
|
|||
|
},
|
|||
|
// 下拉刷新,需要自己在page.json文件中配置开启页面下拉刷新 "enablePullDownRefresh": true
|
|||
|
onPullDownRefresh() {
|
|||
|
this.pageNum = 0;
|
|||
|
this.couponList = [];
|
|||
|
this.getMyCouponList('refresh');
|
|||
|
},
|
|||
|
// 加载更多
|
|||
|
onReachBottom() {
|
|||
|
if (this.loadingType === 'nomore') return;
|
|||
|
this.pageNum++
|
|||
|
this.getMyCouponList();
|
|||
|
},
|
|||
|
onLoad() {
|
|||
|
// 数据初始化
|
|||
|
this.initData();
|
|||
|
// 兼容H5下排序栏位置
|
|||
|
// #ifdef H5
|
|||
|
// 定时器方式循环获取高度为止,这么写的原因是onLoad中head未必已经渲染出来。
|
|||
|
let Timer = setInterval(() => {
|
|||
|
let uniHead = document.getElementsByTagName('uni-page-head');
|
|||
|
if (uniHead.length > 0) {
|
|||
|
this.headerTop = uniHead[0].offsetHeight + 'px';
|
|||
|
clearInterval(Timer); // 清除定时器
|
|||
|
}
|
|||
|
}, 1);
|
|||
|
// #endif
|
|||
|
},
|
|||
|
methods: {
|
|||
|
// 显示抽屉(可使用商品)
|
|||
|
show(item) {
|
|||
|
if (item.usableProduct.length === 0) return;
|
|||
|
this.currentCoupon = item;
|
|||
|
this.showRight = true;
|
|||
|
},
|
|||
|
// 隐藏抽屉
|
|||
|
hide() {
|
|||
|
this.showRight = false;
|
|||
|
},
|
|||
|
// 关闭抽屉
|
|||
|
closeDrawer() {
|
|||
|
this.showRight = false;
|
|||
|
},
|
|||
|
// 切换顶部优惠券类型
|
|||
|
switchType(type, state) {
|
|||
|
if (this.typeClass === type) {
|
|||
|
return;
|
|||
|
}
|
|||
|
uni.pageScrollTo({
|
|||
|
scrollTop: 0,
|
|||
|
duration: 0
|
|||
|
});
|
|||
|
this.typeClass = type;
|
|||
|
this.state = state;
|
|||
|
this.pageNum = 0;
|
|||
|
this.couponList = [];
|
|||
|
this.loading = true;
|
|||
|
this.getMyCouponList();
|
|||
|
},
|
|||
|
// 清空失效优惠券
|
|||
|
async emptyInvalidCoupon() {
|
|||
|
await this.$http.get(`${couponClear}`).then(() => {
|
|||
|
this.getMyCouponList();
|
|||
|
});
|
|||
|
},
|
|||
|
// 占位方法
|
|||
|
discard() {
|
|||
|
// 丢弃
|
|||
|
},
|
|||
|
// 初始化数据
|
|||
|
initData() {
|
|||
|
this.pageNum = 0;
|
|||
|
this.couponList = [];
|
|||
|
this.getMyCouponList();
|
|||
|
},
|
|||
|
// 统一跳转接口
|
|||
|
navTo(route, type) {
|
|||
|
if (type) {
|
|||
|
this.$mRouter.switchTab({ route });
|
|||
|
} else {
|
|||
|
this.$mRouter.push({ route });
|
|||
|
}
|
|||
|
},
|
|||
|
// 获取我的优惠券列表
|
|||
|
async getMyCouponList(type) {
|
|||
|
await this.$http
|
|||
|
.get(`${myCouponList}`, {
|
|||
|
pageNum: this.pageNum,
|
|||
|
status: this.state
|
|||
|
})
|
|||
|
.then(r => {
|
|||
|
this.loading = false;
|
|||
|
if (type === 'refresh') {
|
|||
|
uni.stopPullDownRefresh();
|
|||
|
}
|
|||
|
if(r.list){
|
|||
|
this.loadingType = r.list.length === 10 ? 'more' : 'nomore';
|
|||
|
this.couponList = [...this.couponList, ...r.list];
|
|||
|
}
|
|||
|
})
|
|||
|
.catch(() => {
|
|||
|
this.loading = false;
|
|||
|
if (type === 'refresh') {
|
|||
|
uni.stopPullDownRefresh();
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
</script>
|
|||
|
<style lang="scss">
|
|||
|
view {
|
|||
|
display: flex;
|
|||
|
flex-wrap: wrap;
|
|||
|
}
|
|||
|
page {
|
|||
|
position: relative;
|
|||
|
background-color: $page-color-base;
|
|||
|
}
|
|||
|
|
|||
|
.my-coupon {
|
|||
|
.place {
|
|||
|
width: 100%;
|
|||
|
height: 95upx;
|
|||
|
}
|
|||
|
.tabr {
|
|||
|
background-color: #fff;
|
|||
|
width: 100%;
|
|||
|
height: 95upx;
|
|||
|
padding: 0 3%;
|
|||
|
border-bottom: solid 1upx #dedede;
|
|||
|
position: fixed;
|
|||
|
top: 0;
|
|||
|
z-index: 10;
|
|||
|
view {
|
|||
|
width: 33.3%;
|
|||
|
height: 90upx;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
font-size: 32upx;
|
|||
|
}
|
|||
|
.border {
|
|||
|
height: 4upx;
|
|||
|
&.used {
|
|||
|
transform: translate3d(100%, 0, 0);
|
|||
|
}
|
|||
|
&.invalid {
|
|||
|
transform: translate3d(200%, 0, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.coupon-list {
|
|||
|
width: 100%;
|
|||
|
display: block;
|
|||
|
position: relative;
|
|||
|
.empty-invalid {
|
|||
|
position: absolute;
|
|||
|
right: 20upx;
|
|||
|
top: 10upx;
|
|||
|
font-size: $font-base;
|
|||
|
}
|
|||
|
}
|
|||
|
@keyframes showValid {
|
|||
|
0% {
|
|||
|
transform: translateX(-100%);
|
|||
|
}
|
|||
|
100% {
|
|||
|
transform: translateX(0);
|
|||
|
}
|
|||
|
}
|
|||
|
@keyframes showInvalid {
|
|||
|
0% {
|
|||
|
transform: translateX(0);
|
|||
|
}
|
|||
|
100% {
|
|||
|
transform: translateX(-100%);
|
|||
|
}
|
|||
|
}
|
|||
|
.sub-list {
|
|||
|
width: 100%;
|
|||
|
&.invalid {
|
|||
|
position: absolute;
|
|||
|
top: 0;
|
|||
|
left: 100%;
|
|||
|
display: none;
|
|||
|
}
|
|||
|
|
|||
|
&.showvalid {
|
|||
|
display: flex;
|
|||
|
animation: showValid 0.2s linear both;
|
|||
|
}
|
|||
|
|
|||
|
&.showinvalid {
|
|||
|
display: flex;
|
|||
|
animation: showInvalid 0.2s linear both;
|
|||
|
}
|
|||
|
|
|||
|
.tis {
|
|||
|
width: 100%;
|
|||
|
height: 60upx;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
font-size: 32upx;
|
|||
|
}
|
|||
|
|
|||
|
.row {
|
|||
|
width: 92%;
|
|||
|
height: 27vw;
|
|||
|
margin: 20upx auto 10upx auto;
|
|||
|
border-radius: 8upx;
|
|||
|
// box-shadow: 0upx 0 10upx rgba(0,0,0,0.1);
|
|||
|
align-items: center;
|
|||
|
position: relative;
|
|||
|
overflow: hidden;
|
|||
|
z-index: 4;
|
|||
|
border: 0;
|
|||
|
.carrier {
|
|||
|
@keyframes showMenu {
|
|||
|
0% {
|
|||
|
transform: translateX(0);
|
|||
|
}
|
|||
|
100% {
|
|||
|
transform: translateX(-28%);
|
|||
|
}
|
|||
|
}
|
|||
|
@keyframes closeMenu {
|
|||
|
0% {
|
|||
|
transform: translateX(-28%);
|
|||
|
}
|
|||
|
100% {
|
|||
|
transform: translateX(0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
&.open {
|
|||
|
animation: showMenu 0.25s linear both;
|
|||
|
}
|
|||
|
|
|||
|
&.close {
|
|||
|
animation: closeMenu 0.15s linear both;
|
|||
|
}
|
|||
|
|
|||
|
background-color: #fff;
|
|||
|
position: absolute;
|
|||
|
width: 100%;
|
|||
|
padding: 0 0;
|
|||
|
height: 100%;
|
|||
|
z-index: 3;
|
|||
|
flex-wrap: nowrap;
|
|||
|
|
|||
|
.left {
|
|||
|
width: 100%;
|
|||
|
position: relative;
|
|||
|
|
|||
|
.title {
|
|||
|
padding-top: 3vw;
|
|||
|
width: 90%;
|
|||
|
margin: 0 5%;
|
|||
|
font-size: 36upx;
|
|||
|
|
|||
|
.cell-icon {
|
|||
|
display: inline-block;
|
|||
|
height: 32upx;
|
|||
|
margin-top: 15upx;
|
|||
|
width: 32upx;
|
|||
|
font-size: 22upx;
|
|||
|
text-align: center;
|
|||
|
line-height: 32upx;
|
|||
|
border-radius: 4upx;
|
|||
|
margin-right: 12upx;
|
|||
|
&.hb {
|
|||
|
background: #ffaa0e;
|
|||
|
}
|
|||
|
&.lpk {
|
|||
|
background: #3ab54a;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.term {
|
|||
|
width: 90%;
|
|||
|
margin: 0 5%;
|
|||
|
font-size: 26upx;
|
|||
|
color: #999;
|
|||
|
}
|
|||
|
|
|||
|
.usage {
|
|||
|
width: 90%;
|
|||
|
margin: 0 5%;
|
|||
|
font-size: 26upx;
|
|||
|
color: $font-color-light;
|
|||
|
}
|
|||
|
|
|||
|
.gap-top,
|
|||
|
.gap-bottom {
|
|||
|
position: absolute;
|
|||
|
width: 20upx;
|
|||
|
height: 20upx;
|
|||
|
right: -10upx;
|
|||
|
border-radius: 100%;
|
|||
|
background-color: #f5f5f5;
|
|||
|
}
|
|||
|
|
|||
|
.gap-top {
|
|||
|
top: -10upx;
|
|||
|
}
|
|||
|
|
|||
|
.gap-bottom {
|
|||
|
bottom: -10upx;
|
|||
|
}
|
|||
|
|
|||
|
.overdue {
|
|||
|
position: absolute;
|
|||
|
right: 10upx;
|
|||
|
top: 0;
|
|||
|
|
|||
|
.iconyiguoqi2 {
|
|||
|
font-size: $font-lg + 40upx;
|
|||
|
}
|
|||
|
|
|||
|
.iconyishiyong {
|
|||
|
font-size: $font-lg + 40upx;
|
|||
|
color: $font-color-base;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.right {
|
|||
|
flex-shrink: 0;
|
|||
|
width: 28%;
|
|||
|
color: #fff;
|
|||
|
&.invalid {
|
|||
|
background: linear-gradient(to right, #aaa, #999);
|
|||
|
.use {
|
|||
|
color: #aaa;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
justify-content: center;
|
|||
|
|
|||
|
.ticket,
|
|||
|
.criteria {
|
|||
|
width: 100%;
|
|||
|
}
|
|||
|
|
|||
|
.ticket {
|
|||
|
padding-top: 1vw;
|
|||
|
justify-content: center;
|
|||
|
align-items: baseline;
|
|||
|
height: 6vw;
|
|||
|
|
|||
|
.num {
|
|||
|
font-size: 42upx;
|
|||
|
font-weight: 600;
|
|||
|
}
|
|||
|
|
|||
|
.unit {
|
|||
|
font-size: 24upx;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.criteria {
|
|||
|
justify-content: center;
|
|||
|
|
|||
|
font-size: 28upx;
|
|||
|
}
|
|||
|
|
|||
|
.use {
|
|||
|
width: 45%;
|
|||
|
margin: 0 2.5%;
|
|||
|
height: 40upx;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
font-size: 24upx;
|
|||
|
background-color: #fff;
|
|||
|
border-radius: 40upx;
|
|||
|
padding: 0 4upx;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
.empty {
|
|||
|
width: 100vw;
|
|||
|
display: block;
|
|||
|
}
|
|||
|
</style>
|