|
|
|
|
<template>
|
|
|
|
|
<view class="coupon-page">
|
|
|
|
|
<view class="title-wrap">
|
|
|
|
|
<view class="title-search">
|
|
|
|
|
<view class="back-btn" @tap="back"
|
|
|
|
|
:style="{'top': menuButtonInfo.top + 'px','width': menuButtonInfo.height + 'px','height': menuButtonInfo.height + 'px'}">
|
|
|
|
|
<uni-icons type="left" size="28" color="#08735d"></uni-icons>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="title-name" :style="{'padding-top': menuButtonInfo.top + 'px'}">
|
|
|
|
|
我的优惠券
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="hero-copy">
|
|
|
|
|
<view class="hero-title">可用优惠券</view>
|
|
|
|
|
<view class="hero-sub">仅展示当前校区未使用、未锁定且未过期的优惠券</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<view class="content">
|
|
|
|
|
<view class="summary-card">
|
|
|
|
|
<view class="summary-left">
|
|
|
|
|
<view class="summary-label">当前校区</view>
|
|
|
|
|
<view class="summary-name">{{regionName || '未选择校区'}}</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="summary-count">{{totalCount}} 张可用</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<view class="empty-card" v-if="couponList.length === 0 && loadStatus !== 'loading'">
|
|
|
|
|
<view class="empty-icon">券</view>
|
|
|
|
|
<view class="empty-title">暂无可用优惠券</view>
|
|
|
|
|
<view class="empty-sub">已使用、锁定和过期的优惠券不会显示在这里</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<view class="coupon-card" v-for="item in couponList" :key="item.id">
|
|
|
|
|
<view class="coupon-main">
|
|
|
|
|
<view class="amount-box">
|
|
|
|
|
<view class="amount"><text>¥</text>{{formatAmount(item.discountAmount)}}</view>
|
|
|
|
|
<view class="threshold">{{thresholdText(item.minAmount)}}</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="coupon-info">
|
|
|
|
|
<view class="coupon-title">{{sceneText(item.applyScene)}}优惠券</view>
|
|
|
|
|
<view class="tag-row">
|
|
|
|
|
<text>{{issuerText(item)}}</text>
|
|
|
|
|
<text>未使用</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="info-row">领取时间:{{formatDate(item.receiveTime)}}</view>
|
|
|
|
|
<view class="info-row">有效期至:{{formatDate(item.validEndTime)}}</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<uni-load-more :status="loadStatus" v-if="couponList.length > 0 || loadStatus === 'loading'" />
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
export default {
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
menuButtonInfo: {
|
|
|
|
|
top: 0,
|
|
|
|
|
height: 32
|
|
|
|
|
},
|
|
|
|
|
regionName: '',
|
|
|
|
|
totalCount: 0,
|
|
|
|
|
totalPages: 1,
|
|
|
|
|
loadStatus: 'more',
|
|
|
|
|
searchForm: {
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
userId: '',
|
|
|
|
|
regionId: ''
|
|
|
|
|
},
|
|
|
|
|
couponList: []
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
onReachBottom() {
|
|
|
|
|
if (this.loadStatus === 'loading' || this.searchForm.pageNum >= this.totalPages) return
|
|
|
|
|
this.searchForm.pageNum += 1
|
|
|
|
|
this.getCouponList()
|
|
|
|
|
},
|
|
|
|
|
onLoad(option) {
|
|
|
|
|
this.initQuery()
|
|
|
|
|
},
|
|
|
|
|
onShow() {
|
|
|
|
|
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
back() {
|
|
|
|
|
uni.navigateBack()
|
|
|
|
|
},
|
|
|
|
|
initQuery() {
|
|
|
|
|
const area = uni.getStorageSync('area')
|
|
|
|
|
this.searchForm.userId = uni.getStorageSync('id') || ''
|
|
|
|
|
if (area) {
|
|
|
|
|
try {
|
|
|
|
|
const areaInfo = typeof area === 'string' ? JSON.parse(area) : area
|
|
|
|
|
this.searchForm.regionId = areaInfo.id || ''
|
|
|
|
|
this.regionName = areaInfo.title || areaInfo.name || ''
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.searchForm.regionId = ''
|
|
|
|
|
this.regionName = ''
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!this.searchForm.userId) {
|
|
|
|
|
this.tui.toast('请先登录')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (!this.searchForm.regionId) {
|
|
|
|
|
this.tui.toast('请先选择校区')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
this.getCouponList()
|
|
|
|
|
},
|
|
|
|
|
getCouponList() {
|
|
|
|
|
this.loadStatus = 'loading'
|
|
|
|
|
this.tui.request('/mall/coupon/userList', 'POST', this.searchForm, false, false).then((res) => {
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
const result = res.result || {}
|
|
|
|
|
const records = Array.isArray(result.records) ? result.records : []
|
|
|
|
|
if (this.searchForm.pageNum == 1) {
|
|
|
|
|
this.couponList = records
|
|
|
|
|
} else {
|
|
|
|
|
this.couponList = [...this.couponList, ...records]
|
|
|
|
|
}
|
|
|
|
|
this.totalCount = result.total || this.couponList.length
|
|
|
|
|
this.totalPages = result.pages || 1
|
|
|
|
|
this.loadStatus = this.searchForm.pageNum >= this.totalPages ? 'nomore' : 'more'
|
|
|
|
|
} else {
|
|
|
|
|
this.loadStatus = 'nomore'
|
|
|
|
|
this.tui.toast(res.message)
|
|
|
|
|
}
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
this.loadStatus = 'nomore'
|
|
|
|
|
this.tui.toast('优惠券加载失败')
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
formatAmount(value) {
|
|
|
|
|
const num = Number(value || 0)
|
|
|
|
|
if (Number.isNaN(num)) return '0'
|
|
|
|
|
return num % 1 === 0 ? String(num) : num.toFixed(2)
|
|
|
|
|
},
|
|
|
|
|
thresholdText(value) {
|
|
|
|
|
const amount = Number(value || 0)
|
|
|
|
|
if (!amount) return '无门槛'
|
|
|
|
|
return '满' + this.formatAmount(amount) + '可用'
|
|
|
|
|
},
|
|
|
|
|
sceneText(value) {
|
|
|
|
|
const sceneMap = {
|
|
|
|
|
0: '通用',
|
|
|
|
|
1: '外卖/买饭',
|
|
|
|
|
2: '快递/跑腿',
|
|
|
|
|
3: '二手交易',
|
|
|
|
|
4: '团购'
|
|
|
|
|
}
|
|
|
|
|
return sceneMap[value] || '通用'
|
|
|
|
|
},
|
|
|
|
|
issuerText(item) {
|
|
|
|
|
if (item.issuerType == 1) return '平台发放'
|
|
|
|
|
if (item.issuerType == 2) return '商家:' + (item.issuerId || '-')
|
|
|
|
|
return '发放方:' + (item.issuerId || '-')
|
|
|
|
|
},
|
|
|
|
|
formatDate(value) {
|
|
|
|
|
if (!value) return '-'
|
|
|
|
|
const text = String(value)
|
|
|
|
|
const match = text.match(/^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}))?/)
|
|
|
|
|
if (match) {
|
|
|
|
|
return `${match[1]}-${match[2]}-${match[3]} ${match[4] || '00'}:${match[5] || '00'}`
|
|
|
|
|
}
|
|
|
|
|
const date = new Date(text)
|
|
|
|
|
if (Number.isNaN(date.getTime())) return text
|
|
|
|
|
const year = date.getFullYear()
|
|
|
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
|
|
|
const day = String(date.getDate()).padStart(2, '0')
|
|
|
|
|
const hour = String(date.getHours()).padStart(2, '0')
|
|
|
|
|
const minute = String(date.getMinutes()).padStart(2, '0')
|
|
|
|
|
return `${year}-${month}-${day} ${hour}:${minute}`
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
page {
|
|
|
|
|
width: 100%;
|
|
|
|
|
min-height: 100%;
|
|
|
|
|
background: #f4f8f5;
|
|
|
|
|
color: #00231C;
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.coupon-page {
|
|
|
|
|
width: 100%;
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
padding-bottom: 40rpx;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.title-wrap {
|
|
|
|
|
background: url('https://jewel-shop.oss-cn-beijing.aliyuncs.com/8bc15960c2dc40268e295d6dd23aecce.png') no-repeat;
|
|
|
|
|
background-size: 100%;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 390rpx;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.title-search {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 160rpx;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.back-btn {
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 18rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
z-index: 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.title-name {
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
text-align: center;
|
|
|
|
|
color: #063d32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-copy {
|
|
|
|
|
padding: 20rpx 48rpx 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-title {
|
|
|
|
|
font-size: 48rpx;
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
color: #063d32;
|
|
|
|
|
line-height: 1.3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-sub {
|
|
|
|
|
margin-top: 14rpx;
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
color: rgba(0, 35, 28, 0.62);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.content {
|
|
|
|
|
width: 92%;
|
|
|
|
|
margin: -48rpx auto 0;
|
|
|
|
|
position: relative;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.summary-card {
|
|
|
|
|
width: 100%;
|
|
|
|
|
min-height: 112rpx;
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
border-radius: 28rpx;
|
|
|
|
|
box-shadow: 0 18rpx 42rpx rgba(8, 115, 93, 0.08);
|
|
|
|
|
padding: 20rpx 28rpx;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
margin-bottom: 24rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.summary-label {
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
color: rgba(0, 35, 28, 0.48);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.summary-name {
|
|
|
|
|
margin-top: 4rpx;
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
color: #063d32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.summary-count {
|
|
|
|
|
padding: 12rpx 22rpx;
|
|
|
|
|
border-radius: 999rpx;
|
|
|
|
|
background: linear-gradient(90deg, #e3ff96, #a6ffea);
|
|
|
|
|
color: #063d32;
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.coupon-card {
|
|
|
|
|
width: 100%;
|
|
|
|
|
background: #fff;
|
|
|
|
|
border-radius: 24rpx;
|
|
|
|
|
margin-bottom: 18rpx;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
box-shadow: 0 12rpx 30rpx rgba(8, 115, 93, 0.06);
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.coupon-card::before,
|
|
|
|
|
.coupon-card::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 106rpx;
|
|
|
|
|
width: 24rpx;
|
|
|
|
|
height: 24rpx;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
background: #f4f8f5;
|
|
|
|
|
z-index: 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.coupon-card::before {
|
|
|
|
|
left: -12rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.coupon-card::after {
|
|
|
|
|
right: -12rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.coupon-main {
|
|
|
|
|
display: flex;
|
|
|
|
|
min-height: 168rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.amount-box {
|
|
|
|
|
width: 214rpx;
|
|
|
|
|
background: linear-gradient(160deg, #08735d, #0fb894);
|
|
|
|
|
color: #fff;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
padding: 20rpx 14rpx;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.amount {
|
|
|
|
|
font-size: 54rpx;
|
|
|
|
|
font-weight: 900;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.amount text {
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
margin-right: 4rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.threshold {
|
|
|
|
|
margin-top: 10rpx;
|
|
|
|
|
font-size: 23rpx;
|
|
|
|
|
color: rgba(255, 255, 255, 0.86);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.coupon-info {
|
|
|
|
|
flex: 1;
|
|
|
|
|
padding: 22rpx 24rpx 18rpx;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
min-width: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.coupon-title {
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
color: #063d32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tag-row {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
margin: 10rpx 0 8rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tag-row text {
|
|
|
|
|
margin-right: 12rpx;
|
|
|
|
|
margin-bottom: 6rpx;
|
|
|
|
|
padding: 4rpx 12rpx;
|
|
|
|
|
border-radius: 999rpx;
|
|
|
|
|
background: rgba(8, 115, 93, 0.08);
|
|
|
|
|
color: #08735d;
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.info-row {
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
line-height: 1.55;
|
|
|
|
|
color: rgba(0, 35, 28, 0.62);
|
|
|
|
|
word-break: break-all;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.empty-card {
|
|
|
|
|
width: 100%;
|
|
|
|
|
background: #fff;
|
|
|
|
|
border-radius: 28rpx;
|
|
|
|
|
padding: 70rpx 30rpx;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
text-align: center;
|
|
|
|
|
box-shadow: 0 12rpx 30rpx rgba(8, 115, 93, 0.06);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.empty-icon {
|
|
|
|
|
width: 96rpx;
|
|
|
|
|
height: 96rpx;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
margin: 0 auto 24rpx;
|
|
|
|
|
background: linear-gradient(160deg, #e3ff96, #a6ffea);
|
|
|
|
|
color: #08735d;
|
|
|
|
|
line-height: 96rpx;
|
|
|
|
|
font-size: 40rpx;
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.empty-title {
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
color: #063d32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.empty-sub {
|
|
|
|
|
margin-top: 12rpx;
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
color: rgba(0, 35, 28, 0.5);
|
|
|
|
|
}
|
|
|
|
|
</style>
|