<template>
|
<view class="coupon-page">
|
<view class="coupon-tabs">
|
<view
|
v-for="tab in tabs"
|
:key="tab.value"
|
class="coupon-tab"
|
:class="{ active: currentTab === tab.value }"
|
@tap="currentTab = tab.value"
|
>
|
<text>{{ tab.label }}</text>
|
<view class="tab-line"></view>
|
</view>
|
</view>
|
|
<view class="coupon-list">
|
<view
|
v-for="item in coupons"
|
:key="item.id"
|
class="coupon-card"
|
>
|
<view class="coupon-main">
|
<view class="coupon-info">
|
<view class="coupon-title">{{ item.name }}</view>
|
<view class="coupon-time">有效期{{ item.startDate }}~{{ item.endDate }}</view>
|
</view>
|
<view class="coupon-price" :class="item.status">
|
<text class="price-value">{{ ((item.price || 0) / 100).toFixed(2) }}</text>
|
<text class="price-desc">{{ item.couponType === 0 ? '满减' : '' }}</text>
|
</view>
|
</view>
|
|
<view class="coupon-divider"></view>
|
|
<view class="coupon-footer">
|
<view class="coupon-meta" @tap="toggleRule(item.id)">
|
<text class="meta-text">本优惠券不可转让</text>
|
<u-icon
|
class="meta-arrow"
|
:name="item.expanded ? 'arrow-up' : 'arrow-down'"
|
size="12"
|
color="#9d9d9d"
|
></u-icon>
|
</view>
|
<view
|
class="receive-btn"
|
:class="{ 'receive-btn-disabled': [2, 99].includes(currentTab) }"
|
@click="handleReceive(item)"
|
>
|
{{ currentTab === 1 ? '去使用' : '立即领取' }}
|
</view>
|
</view>
|
|
<view v-if="item.info" class="coupon-rule">
|
{{ item.info }}
|
</view>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
export default {
|
data() {
|
return {
|
currentTab: 0,
|
tabs: [
|
{ label: '待领取', value: 0 },
|
{ label: '已领取', value: 1 },
|
{ label: '已使用', value: 2 },
|
{ label: '已失效', value: 99 }
|
],
|
coupons: [],
|
page: 1,
|
capacity: 10,
|
isRequest: true
|
}
|
},
|
watch: {
|
currentTab() {
|
this.page = 1
|
this.coupons = []
|
this.isRequest = true
|
this.getCouponList()
|
}
|
},
|
onLoad() {
|
this.getCouponList()
|
},
|
onReachBottom() {
|
this.getCouponList()
|
},
|
methods: {
|
async getCouponList() {
|
if (!this.isRequest) return
|
const res = await this.$u.api.findPage({
|
capacity: this.capacity,
|
page: this.page,
|
model: {
|
status: this.currentTab
|
}
|
})
|
if (res.code === 200) {
|
const list = res.records || []
|
this.coupons = [...this.coupons, ...list]
|
this.page++
|
if (res.total <= this.coupons.length) {
|
this.isRequest = false
|
}
|
}
|
},
|
async handleReceive(item) {
|
uni.showModal({
|
title: '提示',
|
content: '确定要领取该优惠券吗?',
|
success: async (res) => {
|
if (res.confirm) {
|
const result = await this.$u.api.claimCoupon({ couponId: item.id })
|
if (result.code === 200) {
|
uni.showToast({ title: '领取成功', icon: 'success' })
|
this.page = 1
|
this.coupons = []
|
this.isRequest = true
|
this.getCouponList()
|
}
|
}
|
}
|
})
|
},
|
toggleRule(id) {
|
this.coupons = this.coupons.map((item) => {
|
if (item.id === id) {
|
return {
|
...item,
|
expanded: !item.expanded
|
};
|
}
|
|
return item;
|
});
|
}
|
}
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.coupon-page {
|
min-height: 100vh;
|
background: #f6f7fb;
|
}
|
|
.coupon-tabs {
|
position: sticky;
|
top: 0;
|
z-index: 10;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 0 18rpx;
|
height: 88rpx;
|
background: rgba(255, 255, 255, 0.98);
|
box-shadow: 0 2rpx 12rpx rgba(27, 39, 94, 0.05);
|
}
|
|
.coupon-tab {
|
position: relative;
|
display: flex;
|
flex: 1;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
height: 100%;
|
font-size: 34rpx;
|
font-weight: 500;
|
color: #666666;
|
}
|
|
.coupon-tab.active {
|
color: #222222;
|
font-weight: 700;
|
}
|
|
.tab-line {
|
position: absolute;
|
left: 50%;
|
bottom: 10rpx;
|
width: 44rpx;
|
height: 6rpx;
|
border-radius: 999rpx;
|
background: transparent;
|
transform: translateX(-50%);
|
}
|
|
.coupon-tab.active .tab-line {
|
background: #18b7ff;
|
}
|
|
.coupon-list {
|
padding: 22rpx 20rpx 40rpx;
|
}
|
|
.coupon-card {
|
padding: 30rpx;
|
margin-bottom: 22rpx;
|
background: #ffffff;
|
border-radius: 24rpx;
|
box-shadow: 0 10rpx 28rpx rgba(30, 42, 64, 0.04);
|
}
|
|
.coupon-main {
|
display: flex;
|
align-items: flex-start;
|
justify-content: space-between;
|
gap: 24rpx;
|
}
|
|
.coupon-info {
|
flex: 1;
|
min-width: 0;
|
}
|
|
.coupon-title {
|
font-size: 36rpx;
|
font-weight: 700;
|
line-height: 50rpx;
|
color: #222222;
|
}
|
|
.coupon-time {
|
margin-top: 18rpx;
|
font-size: 28rpx;
|
line-height: 40rpx;
|
color: #8b8b8b;
|
}
|
|
.coupon-price {
|
display: flex;
|
flex-direction: column;
|
align-items: flex-end;
|
min-width: 150rpx;
|
color: #ff2442;
|
}
|
|
.coupon-price.used,
|
.coupon-price.expired {
|
color: #c0c4cc;
|
}
|
|
.price-value {
|
position: relative;
|
padding-left: 24rpx;
|
font-size: 60rpx;
|
font-weight: 700;
|
line-height: 1.05;
|
}
|
|
.price-value::before {
|
content: '¥';
|
position: absolute;
|
left: 0;
|
top: 8rpx;
|
font-size: 34rpx;
|
line-height: 1;
|
}
|
|
.price-desc {
|
margin-top: 10rpx;
|
font-size: 30rpx;
|
line-height: 42rpx;
|
}
|
|
.coupon-divider {
|
height: 1rpx;
|
margin: 24rpx 0;
|
background: repeating-linear-gradient(to right, #ececf1 0, #ececf1 8rpx, transparent 8rpx, transparent 16rpx);
|
}
|
|
.coupon-footer {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 20rpx;
|
}
|
|
.coupon-meta {
|
display: flex;
|
align-items: center;
|
gap: 10rpx;
|
font-size: 30rpx;
|
line-height: 42rpx;
|
color: #ababab;
|
}
|
|
.meta-text {
|
max-width: 360rpx;
|
}
|
|
.meta-arrow {
|
font-size: 24rpx;
|
color: #9d9d9d;
|
}
|
|
.receive-btn {
|
flex-shrink: 0;
|
padding: 0 28rpx;
|
height: 62rpx;
|
line-height: 62rpx;
|
border-radius: 999rpx;
|
background: linear-gradient(135deg, #ff8b14 0%, #ff4d0a 100%);
|
font-size: 30rpx;
|
font-weight: 500;
|
color: #ffffff;
|
}
|
|
.receive-btn-disabled {
|
background: #d1d1d1;
|
color: #ffffff;
|
}
|
|
.coupon-rule {
|
margin-top: 16rpx;
|
font-size: 28rpx;
|
line-height: 42rpx;
|
color: #9f9f9f;
|
}
|
</style>
|