优惠卷选择显示

main
格调main 2026-03-25 09:40:53 +08:00
parent 35cc05448f
commit 801f4953ff
1 changed files with 174 additions and 6 deletions

View File

@ -102,8 +102,8 @@
<!-- 底部结算栏固定 -->
<view class="checkout-footer">
<view class="total-info">
<text class="total-label">总金额¥</text>
<text class="total-amount">{{ totalAmount.toFixed(2) }}</text>
<text class="total-label">应付¥</text>
<text class="total-amount">{{ payableAmountYuan.toFixed(2) }}</text>
<view class="member-benefit">
<image
class="crown-icon"
@ -113,6 +113,12 @@
<text class="benefit-text">{{ memberLevelName }}优惠</text>
</view>
</view>
<view class="coupon-brief" @click="openCouponSelect">
<image class="coupon-icon" src="/static/service/coupon-icon.png" mode="aspectFill"></image>
<text class="coupon-text">{{ selectedCoupon ? selectedCoupon.name : '选择优惠卷' }}</text>
<text class="coupon-deduction" v-if="selectedCoupon && couponDiscountFen > 0">-¥{{ (couponDiscountFen / 100).toFixed(2) }}</text>
<text class="coupon-arrow"></text>
</view>
<button
class="checkout-btn"
:class="{ disabled: totalAmount <= 0 }"
@ -131,7 +137,8 @@ import {
getGuildStoreDetail,
getGuildVoucher,
getPaySign,
appBuy
appBuy,
getLuCouponPage
} from "@/api/service";
import NavHeader from "@/components/NavHeader/NavHeader.vue";
@ -149,6 +156,10 @@ export default {
userInfo: {},
distance: null,
paying: false,
coupons: [],
selectedCoupon: null,
selectedCouponId: null,
couponLoading: false,
};
},
computed: {
@ -166,6 +177,36 @@ export default {
return total;
}, 0);
},
totalAmountFen() {
return Math.round(this.totalAmount * 100);
},
couponDiscountFen() {
if (!this.selectedCoupon) return 0;
const now = Date.now();
if ((this.selectedCoupon.validStartTime && now < this.selectedCoupon.validStartTime) ||
(this.selectedCoupon.validEndTime && now > this.selectedCoupon.validEndTime)) {
return 0;
}
if (!this.isCouponApplicable(this.selectedCoupon)) return 0;
const totalFen = this.totalAmountFen;
if (this.selectedCoupon.type === 2) {
const percent = this.selectedCoupon.discountPercent || 0;
const raw = Math.round(totalFen * (1 - percent / 100));
const limit = this.selectedCoupon.discountLimit || 0;
const val = limit > 0 ? Math.min(raw, limit) : raw;
return Math.max(0, val);
}
const amt = this.selectedCoupon.discountAmount || this.selectedCoupon.discountPrice || this.selectedCoupon.price || 0;
return Math.max(0, Math.min(amt, totalFen));
},
payableAmountFen() {
const val = this.totalAmountFen - this.couponDiscountFen;
if (val <= 0 && this.totalAmountFen > 0) return 1;
return Math.max(0, val);
},
payableAmountYuan() {
return this.payableAmountFen / 100;
},
//
hasMemberDiscount() {
return this.menuList.some((item) => item.selected && item.discount);
@ -295,6 +336,7 @@ export default {
// 0 1
item.quantity = 1;
}
this.autoSelectBestCoupon();
},
//
@ -310,6 +352,7 @@ export default {
}
//
item.quantity = (item.quantity || 0) + 1;
this.autoSelectBestCoupon();
},
//
@ -328,6 +371,7 @@ export default {
item.selected = false;
}
}
this.autoSelectBestCoupon();
},
// 100
@ -341,6 +385,94 @@ export default {
return yuan.toFixed(2);
},
async openCouponSelect() {
if (this.totalAmountFen <= 0) {
uni.showToast({ title: "请先选择商品", icon: "none" });
return;
}
await this.loadUserCoupons();
const eventChannelData = {
coupons: this.coupons,
selectedCouponId: this.selectedCouponId,
};
uni.navigateTo({
url: "/pages/detail/selectCoupon",
success: (res) => {
res.eventChannel.emit("acceptDataFromOpenerPage", eventChannelData);
res.eventChannel.on("acceptDataFromOpenedPage", ({ coupon }) => {
this.selectedCoupon = coupon;
this.selectedCouponId = coupon ? coupon.id : null;
});
},
});
},
async loadUserCoupons() {
if (this.couponLoading) return;
this.couponLoading = true;
try {
const res = await getLuCouponPage({ pageNo: 1, pageSize: 100, status: 0 });
const list = (res && res.list) || [];
const enhanced = list.map((c) => {
const copy = { ...c };
copy.isApplicable = this.isCouponApplicable(copy);
return copy;
});
this.coupons = enhanced;
if (!this.selectedCoupon && enhanced.length > 0) {
this.autoSelectBestCoupon();
}
} finally {
this.couponLoading = false;
}
},
isCouponApplicable(coupon) {
const now = Date.now();
if (coupon.status !== 0) return false;
if (coupon.validStartTime && now < coupon.validStartTime) return false;
if (coupon.validEndTime && now > coupon.validEndTime) return false;
const totalFen = this.totalAmountFen;
if (coupon.usePrice && totalFen < coupon.usePrice) return false;
const selectedIds = this.menuList.filter(i => i.selected && i.quantity > 0).map(i => i.id);
if (selectedIds.length === 0) return false;
if (coupon.productScope === 1) return true;
if (coupon.productScope === 2) {
const ids = Array.isArray(coupon.voucherIds)
? coupon.voucherIds
: (typeof coupon.voucherIds === "string" ? coupon.voucherIds.split(",").map(s => Number(s.trim())).filter(Boolean) : []);
return selectedIds.some(id => ids.includes(id));
}
return true;
},
autoSelectBestCoupon() {
if (!this.coupons || this.coupons.length === 0) return;
const applicable = this.coupons.filter(c => this.isCouponApplicable(c));
if (applicable.length === 0) {
this.selectedCoupon = null;
this.selectedCouponId = null;
return;
}
let best = null;
let maxDeduct = -1;
applicable.forEach(c => {
const deduct = (() => {
if (c.type === 2) {
const percent = c.discountPercent || 0;
const raw = Math.round(this.totalAmountFen * (1 - percent / 100));
const limit = c.discountLimit || 0;
return Math.max(0, limit > 0 ? Math.min(raw, limit) : raw);
}
return Math.max(0, Math.min(c.discountAmount || c.discountPrice || c.price || 0, this.totalAmountFen));
})();
if (deduct > maxDeduct) {
maxDeduct = deduct;
best = c;
}
});
this.selectedCoupon = best || null;
this.selectedCouponId = best ? best.id : null;
this.coupons = this.coupons.map(c => ({ ...c, isApplicable: this.isCouponApplicable(c) }));
},
//
async handleCheckout() {
if (this.totalAmount <= 0) {
@ -365,8 +497,8 @@ export default {
.map((item) => `${item.id}:${item.quantity}`)
.join(";");
// this.totalAmount ,
const trxamt = (this.totalAmount * 100).toFixed(0);
const trxamtFen = this.payableAmountFen;
const trxamt = String(trxamtFen);
console.log("购买信息: " + voucherStr);
console.log("金额:" + trxamt);
@ -374,6 +506,7 @@ export default {
shopId: this.shopId,
voucherData: voucherStr,
payableAmount: trxamt,
couponId: this.selectedCouponId || undefined,
});
console.log(res);
if (!res) {
@ -810,6 +943,41 @@ export default {
}
}
.coupon-brief {
position: absolute;
left: 20rpx;
top: -68rpx;
display: inline-flex;
align-items: center;
padding: 8rpx 12rpx;
background: #fff7f8;
border: 1rpx dashed #ffd4d8;
border-radius: 10rpx;
color: #d51c3c;
}
.coupon-icon {
width: 24rpx;
height: 24rpx;
margin-right: 8rpx;
}
.coupon-text {
font-size: 24rpx;
margin-right: 8rpx;
max-width: 280rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.coupon-deduction {
font-size: 24rpx;
color: #d51c3c;
margin-right: 8rpx;
}
.coupon-arrow {
font-size: 28rpx;
color: #d51c3c;
}
.checkout-btn {
color: #ffffff;
font-family: PingFang-SC, PingFang-SC;
@ -823,4 +991,4 @@ export default {
}
}
</style>