254 lines
6.3 KiB
Vue
254 lines
6.3 KiB
Vue
<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>
|