You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
552 lines
12 KiB
552 lines
12 KiB
<template>
|
|
<view class="coupon-list-container">
|
|
<!-- 状态筛选 -->
|
|
<view class="filter-tabs">
|
|
<view
|
|
class="tab-item"
|
|
:class="[{ active: activeTab === 'all' }]"
|
|
@click="switchTab('all')"
|
|
>
|
|
全部
|
|
</view>
|
|
<view
|
|
class="tab-item"
|
|
:class="[{ active: activeTab === 'unused' }]"
|
|
@click="switchTab('unused')"
|
|
>
|
|
未使用
|
|
</view>
|
|
<view
|
|
class="tab-item"
|
|
:class="[{ active: activeTab === 'used' }]"
|
|
@click="switchTab('used')"
|
|
>
|
|
已使用
|
|
</view>
|
|
<view
|
|
class="tab-item"
|
|
:class="[{ active: activeTab === 'expired' }]"
|
|
@click="switchTab('expired')"
|
|
>
|
|
已过期
|
|
</view>
|
|
</view>
|
|
<!-- 优惠券列表 -->
|
|
<view class="coupon-list">
|
|
<view
|
|
v-for="(coupon, index) in filteredCoupons"
|
|
:key="index"
|
|
class="coupon-item"
|
|
:class="[
|
|
{
|
|
used: coupon.status === 1,
|
|
expired: coupon.status === 2,
|
|
},
|
|
]"
|
|
>
|
|
<!-- 优惠券主体 -->
|
|
<view class="coupon-main">
|
|
<!-- 左侧金额区域 -->
|
|
<view class="coupon-amount">
|
|
<view class="amount-value">
|
|
<text class="currency">¥</text>
|
|
<text class="value">{{ formatAmount(coupon) }}</text>
|
|
</view>
|
|
<view class="amount-desc" v-if="coupon.minAmount > 0">
|
|
满{{ coupon.minAmount }}可用
|
|
</view>
|
|
<view class="amount-desc" v-else> 无门槛 </view>
|
|
</view>
|
|
|
|
<!-- 右侧信息区域 -->
|
|
<view class="coupon-info">
|
|
<view class="coupon-type">{{
|
|
getCouponTypeName(coupon.type)
|
|
}}</view>
|
|
<view class="coupon-scope" v-if="coupon.scope === 0">
|
|
全场通用
|
|
</view>
|
|
<view class="coupon-scope" v-else>
|
|
<view class="scope-title" @click="toggleProductList(coupon.id)">
|
|
指定商品可用
|
|
<text
|
|
class="expand-icon"
|
|
:class="{ expanded: coupon.showProducts }"
|
|
>▼</text
|
|
>
|
|
</view>
|
|
<view class="product-list" v-if="coupon.showProducts">
|
|
<view
|
|
class="product-item"
|
|
v-for="product in coupon.products"
|
|
:key="product.id"
|
|
>
|
|
{{ product.name }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 状态标识 -->
|
|
<view class="coupon-status">
|
|
<view class="status-tag" :class="[getStatusClass(coupon.status)]">
|
|
{{ getStatusText(coupon.status) }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 有效期和使用按钮 -->
|
|
<view class="coupon-bottom">
|
|
<view class="coupon-validity">
|
|
<text class="validity-label">有效期:</text>
|
|
<text class="validity-date"
|
|
>{{ coupon.startDate }} - {{ coupon.endDate }}</text
|
|
>
|
|
</view>
|
|
<view class="coupon-action" v-if="coupon.status === 0">
|
|
<button class="use-btn" @click="useCoupon(coupon)">立即使用</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 空状态 -->
|
|
<view class="empty-state" v-if="filteredCoupons.length === 0">
|
|
<view class="empty-icon">📋</view>
|
|
<view class="empty-text">暂无优惠券</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
activeTab: "all",
|
|
coupons: [
|
|
{
|
|
id: 1,
|
|
type: 1, // 满减券
|
|
amount: 20,
|
|
minAmount: 100,
|
|
status: 0, // 0:未使用 1:已使用 2:已过期
|
|
startDate: "2024-01-01",
|
|
endDate: "2024-12-31",
|
|
scope: 0, // 0:不限商品 1:指定商品
|
|
showProducts: false,
|
|
},
|
|
{
|
|
id: 2,
|
|
type: 2, // 折扣券
|
|
discount: 8.5, // 8.5折
|
|
minAmount: 50,
|
|
status: 1,
|
|
startDate: "2024-01-01",
|
|
endDate: "2024-06-30",
|
|
scope: 1,
|
|
showProducts: false,
|
|
products: [
|
|
{ id: 1, name: "iPhone 15 Pro" },
|
|
{ id: 2, name: "MacBook Air M2" },
|
|
{ id: 3, name: "AirPods Pro" },
|
|
],
|
|
},
|
|
{
|
|
id: 3,
|
|
type: 3, // 立减券
|
|
amount: 10,
|
|
minAmount: 0,
|
|
status: 2,
|
|
startDate: "2023-12-01",
|
|
endDate: "2023-12-31",
|
|
scope: 0,
|
|
showProducts: false,
|
|
},
|
|
{
|
|
id: 4,
|
|
type: 4, // 兑换券
|
|
amount: 0,
|
|
minAmount: 0,
|
|
status: 0,
|
|
startDate: "2024-01-01",
|
|
endDate: "2024-12-31",
|
|
scope: 1,
|
|
showProducts: false,
|
|
products: [
|
|
{ id: 4, name: "星巴克咖啡券" },
|
|
{ id: 5, name: "肯德基套餐券" },
|
|
],
|
|
},
|
|
],
|
|
};
|
|
},
|
|
computed: {
|
|
filteredCoupons() {
|
|
if (this.activeTab === "all") {
|
|
return this.coupons;
|
|
}
|
|
if (this.activeTab === "unused") {
|
|
return this.coupons.filter((coupon) => coupon.status === 0);
|
|
}
|
|
if (this.activeTab === "used") {
|
|
return this.coupons.filter((coupon) => coupon.status === 1);
|
|
}
|
|
if (this.activeTab === "expired") {
|
|
return this.coupons.filter((coupon) => coupon.status === 2);
|
|
}
|
|
return [];
|
|
},
|
|
},
|
|
mounted() {
|
|
console.log("couponList mounted");
|
|
console.log("activeTab:", this.activeTab);
|
|
console.log("coupons:", this.coupons);
|
|
console.log("filteredCoupons:", this.filteredCoupons);
|
|
},
|
|
methods: {
|
|
switchTab(tab) {
|
|
this.activeTab = tab;
|
|
},
|
|
getCouponTypeName(type) {
|
|
const typeMap = {
|
|
1: "满减券",
|
|
2: "折扣券",
|
|
3: "立减券",
|
|
4: "兑换券",
|
|
};
|
|
return typeMap[type] || "未知类型";
|
|
},
|
|
formatAmount(coupon) {
|
|
if (coupon.type === 2) {
|
|
// 折扣券显示折扣
|
|
return coupon.discount + "折";
|
|
} else if (coupon.type === 4) {
|
|
// 兑换券
|
|
return "兑换";
|
|
} else {
|
|
// 满减券和立减券显示金额
|
|
return coupon.amount;
|
|
}
|
|
},
|
|
getStatusText(status) {
|
|
const statusMap = {
|
|
0: "未使用",
|
|
1: "已使用",
|
|
2: "已过期",
|
|
};
|
|
return statusMap[status] || "未知状态";
|
|
},
|
|
getStatusClass(status) {
|
|
const classMap = {
|
|
0: "unused",
|
|
1: "used",
|
|
2: "expired",
|
|
};
|
|
return classMap[status] || "";
|
|
},
|
|
useCoupon(coupon) {
|
|
// 跳转到商品页面或购物车
|
|
uni.showToast({
|
|
title: "跳转到商品页面",
|
|
icon: "none",
|
|
});
|
|
},
|
|
toggleProductList(couponId) {
|
|
console.log("toggleProductList called with couponId:", couponId);
|
|
const couponIndex = this.coupons.findIndex((c) => c.id === couponId);
|
|
console.log("found coupon index:", couponIndex);
|
|
if (couponIndex !== -1) {
|
|
const newShowProducts = !this.coupons[couponIndex].showProducts;
|
|
console.log(
|
|
"toggling showProducts from",
|
|
this.coupons[couponIndex].showProducts,
|
|
"to",
|
|
newShowProducts
|
|
);
|
|
// 使用 Vue.set 确保响应式更新
|
|
this.$set(this.coupons[couponIndex], "showProducts", newShowProducts);
|
|
console.log(
|
|
"after toggle, showProducts is:",
|
|
this.coupons[couponIndex].showProducts
|
|
);
|
|
}
|
|
},
|
|
},
|
|
onLoad() {
|
|
// 页面加载时获取优惠券数据
|
|
// this.loadCoupons();
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.coupon-list-container {
|
|
min-height: 100vh;
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
.header {
|
|
background: #fff;
|
|
padding: 20rpx 30rpx;
|
|
border-bottom: 1rpx solid #eee;
|
|
|
|
.header-title {
|
|
font-size: 36rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
text-align: center;
|
|
}
|
|
}
|
|
|
|
.filter-tabs {
|
|
display: flex;
|
|
background: #fff;
|
|
padding: 0 30rpx;
|
|
border-bottom: 1rpx solid #eee;
|
|
|
|
.tab-item {
|
|
flex: 1;
|
|
padding: 30rpx 0;
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
position: relative;
|
|
|
|
&.active {
|
|
color: #77f3f9;
|
|
font-weight: 600;
|
|
|
|
&::after {
|
|
content: "";
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 60rpx;
|
|
height: 4rpx;
|
|
background: #77f3f9;
|
|
border-radius: 2rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.coupon-list {
|
|
padding: 20rpx 30rpx;
|
|
}
|
|
|
|
.coupon-item {
|
|
background: #fff;
|
|
border-radius: 16rpx;
|
|
margin-bottom: 20rpx;
|
|
overflow: hidden;
|
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
position: relative;
|
|
|
|
&.used,
|
|
&.expired {
|
|
opacity: 0.6;
|
|
|
|
&::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.1);
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
.coupon-main {
|
|
display: flex;
|
|
padding: 30rpx;
|
|
position: relative;
|
|
|
|
&::after {
|
|
content: "";
|
|
position: absolute;
|
|
right: 200rpx;
|
|
top: 20rpx;
|
|
bottom: 20rpx;
|
|
width: 2rpx;
|
|
background: linear-gradient(
|
|
to bottom,
|
|
transparent 0%,
|
|
#ddd 20%,
|
|
#ddd 80%,
|
|
transparent 100%
|
|
);
|
|
}
|
|
}
|
|
|
|
.coupon-amount {
|
|
width: 200rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
.amount-value {
|
|
display: flex;
|
|
align-items: baseline;
|
|
margin-bottom: 10rpx;
|
|
|
|
.currency {
|
|
font-size: 24rpx;
|
|
color: #ff4d4f;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.value {
|
|
font-size: 48rpx;
|
|
color: #ff4d4f;
|
|
font-weight: 700;
|
|
margin-left: 4rpx;
|
|
}
|
|
}
|
|
|
|
.amount-desc {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
}
|
|
}
|
|
|
|
.coupon-info {
|
|
flex: 1;
|
|
padding-left: 30rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
|
|
.coupon-type {
|
|
font-size: 32rpx;
|
|
color: #333;
|
|
font-weight: 600;
|
|
margin-bottom: 12rpx;
|
|
}
|
|
|
|
.coupon-scope {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.coupon-scope {
|
|
.scope-title {
|
|
display: flex;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
|
|
.expand-icon {
|
|
margin-left: 8rpx;
|
|
font-size: 20rpx;
|
|
transition: transform 0.3s ease;
|
|
|
|
&.expanded {
|
|
transform: rotate(180deg);
|
|
}
|
|
}
|
|
}
|
|
|
|
.product-list {
|
|
margin-top: 8rpx;
|
|
padding: 8rpx 12rpx;
|
|
background: #f8f8f8;
|
|
border-radius: 8rpx;
|
|
|
|
.product-item {
|
|
font-size: 20rpx;
|
|
color: #666;
|
|
line-height: 1.5;
|
|
margin-bottom: 4rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.coupon-status {
|
|
position: absolute;
|
|
top: 20rpx;
|
|
right: 20rpx;
|
|
|
|
.status-tag {
|
|
padding: 8rpx 16rpx;
|
|
border-radius: 20rpx;
|
|
font-size: 20rpx;
|
|
color: #fff;
|
|
|
|
&.unused {
|
|
background: #52c41a;
|
|
}
|
|
|
|
&.used {
|
|
background: #999;
|
|
}
|
|
|
|
&.expired {
|
|
background: #ff4d4f;
|
|
}
|
|
}
|
|
}
|
|
|
|
.coupon-bottom {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 20rpx 30rpx;
|
|
border-top: 1rpx solid #f0f0f0;
|
|
|
|
.coupon-validity {
|
|
flex: 1;
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
|
|
.validity-label {
|
|
margin-right: 8rpx;
|
|
}
|
|
|
|
.validity-date {
|
|
line-height: 1.4;
|
|
}
|
|
}
|
|
|
|
.coupon-action {
|
|
.use-btn {
|
|
width: 160rpx;
|
|
height: 60rpx;
|
|
background: linear-gradient(135deg, #fffdb7 0%, #97fffa 100%);
|
|
color: #000;
|
|
border: none;
|
|
border-radius: 20rpx;
|
|
font-size: 24rpx;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
}
|
|
|
|
.empty-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 120rpx 0;
|
|
|
|
.empty-icon {
|
|
font-size: 120rpx;
|
|
margin-bottom: 30rpx;
|
|
opacity: 0.3;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
}
|
|
}
|
|
</style>
|
|
|