consumer-app/pages/detail/selectCoupon.vue

254 lines
6.3 KiB
Vue
Raw Normal View History

2026-03-21 11:16:08 +00:00
<template>
<view class="select-coupon-page">
<view class="header-fixed-wrapper" :style="{ height: headerHeight + 'px' }">
<NavHeader title="选择优惠卷" />
</view>
<view class="main-wrap" :style="{ paddingTop: headerHeight + 'px' }">
<scroll-view class="coupon-list" scroll-y="true">
<view
class="coupon-item"
v-for="(item, index) in coupons"
:key="index"
:class="{ disabled: !item.isApplicable }"
@click="selectCoupon(item)"
>
<view class="coupon-left">
<!-- 折扣类 -->
<view class="coupon-price" v-if="item.type === 2">
<text class="amount">{{ (item.discountPercent / 10).toFixed(1).replace(/\.0$/, '') }}</text>
<text class="symbol" style="font-size: 24rpx; margin-left: 4rpx;"></text>
</view>
<!-- 金额类 -->
<view class="coupon-price" v-else>
<text class="symbol">¥</text>
<!-- 检查返回的字段是 discountPrice, discountAmount 还是抵扣金额相关字段如果是金额类应该有值 -->
<text class="amount">{{ formatAmount(item.discountAmount || item.discountPrice || item.price || 0) }}</text>
</view>
<view class="coupon-condition" v-if="item.usePrice">
{{ formatAmount(item.usePrice) }}可用
</view>
<view class="coupon-condition" v-else>
无门槛
</view>
</view>
<view class="coupon-right">
<view class="coupon-name">{{ item.name }}</view>
<view class="coupon-time" v-if="item.type === 2 && item.discountLimit > 0" style="margin-bottom: 6rpx;">: ¥{{ formatAmount(item.discountLimit) }}</view>
<view class="coupon-time" v-if="item.validEndTime">: {{ formatTimeStr(item.validEndTime) }}</view>
</view>
<view class="coupon-radio">
<radio :checked="selectedCouponId === item.id" :disabled="!item.isApplicable" color="#d51c3c" style="transform:scale(0.8)" />
</view>
</view>
<view v-if="coupons.length === 0" class="empty-tip"></view>
</scroll-view>
<!-- 不使用优惠卷按钮 -->
<view class="bottom-bar">
<button class="no-coupon-btn" @click="selectNone">使</button>
</view>
</view>
</view>
</template>
<script>
import NavHeader from "@/components/NavHeader/NavHeader.vue";
import { formatTime } from "@/utils/date.js";
export default {
components: {
NavHeader,
},
data() {
return {
statusBarHeight: 0,
coupons: [],
selectedCouponId: null,
};
},
computed: {
headerHeight() {
return this.statusBarHeight + 44;
},
},
onLoad() {
const systemInfo = uni.getSystemInfoSync();
this.statusBarHeight = systemInfo.statusBarHeight || 0;
// 获取传递过来的数据
const eventChannel = this.getOpenerEventChannel();
if (eventChannel && eventChannel.on) {
eventChannel.on('acceptDataFromOpenerPage', (data) => {
this.coupons = data.coupons || [];
this.selectedCouponId = data.selectedCouponId || null;
});
}
},
methods: {
selectCoupon(item) {
if (!item.isApplicable) {
return;
}
this.selectedCouponId = item.id;
this.confirmSelection(item);
},
selectNone() {
this.selectedCouponId = null;
this.confirmSelection(null);
},
confirmSelection(coupon) {
const eventChannel = this.getOpenerEventChannel();
if (eventChannel && eventChannel.emit) {
eventChannel.emit('acceptDataFromOpenedPage', { coupon });
}
uni.navigateBack();
},
formatTimeStr(timestamp) {
if (!timestamp) return '';
return formatTime(timestamp, 'YYYY-MM-DD HH:mm:ss');
},
// 将分转换为元,并处理小数显示
formatAmount(amount) {
if (!amount) return '0';
const yuan = amount / 100;
// 如果是整数直接显示整数如果有小数保留两位小数但去掉末尾的0
return Number.isInteger(yuan) ? yuan.toString() : yuan.toFixed(2).replace(/\.?0+$/, '');
}
}
}
</script>
<style lang="scss" scoped>
.select-coupon-page {
min-height: 100vh;
background-color: #f5f5f5;
}
.header-fixed-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 100;
background-color: #fff;
}
.main-wrap {
display: flex;
flex-direction: column;
height: 100vh;
box-sizing: border-box;
}
.coupon-list {
flex: 1;
padding: 20rpx;
box-sizing: border-box;
}
.coupon-item {
display: flex;
background-color: #fff;
border-radius: 16rpx;
margin-bottom: 20rpx;
padding: 30rpx;
align-items: center;
&.disabled {
opacity: 0.6;
background-color: #fafafa;
.coupon-price {
color: #999 !important;
}
.coupon-name {
color: #999 !important;
}
}
.coupon-left {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 160rpx;
border-right: 2rpx dashed #eee;
padding-right: 20rpx;
.coupon-price {
color: #d51c3c;
.symbol {
font-size: 24rpx;
font-weight: bold;
}
.amount {
font-size: 48rpx;
font-weight: bold;
}
}
.coupon-condition {
font-size: 20rpx;
color: #666;
margin-top: 10rpx;
}
}
.coupon-right {
flex: 1;
padding-left: 30rpx;
display: flex;
flex-direction: column;
justify-content: center;
.coupon-name {
font-size: 28rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.coupon-time {
font-size: 22rpx;
color: #999;
}
}
.coupon-radio {
margin-left: 20rpx;
}
}
.empty-tip {
text-align: center;
padding: 60rpx 0;
color: #999;
font-size: 28rpx;
}
.bottom-bar {
padding: 20rpx 40rpx calc(20rpx + env(safe-area-inset-bottom));
background-color: #fff;
border-top: 1rpx solid #eee;
.no-coupon-btn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
text-align: center;
background-color: #f5f5f5;
color: #333;
font-size: 32rpx;
border-radius: 44rpx;
border: none;
&::after {
border: none;
}
}
}
</style>