优惠卷选择显示
parent
35cc05448f
commit
801f4953ff
|
|
@ -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>
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue