fix: 对对碰默认不使用优惠券

对对碰支付弹窗新增不使用优惠券选项,并关闭默认使用次数卡,避免优惠券选择器被禁用。
This commit is contained in:
Zuncle 2026-05-25 02:17:33 +08:00
parent d530ec11e7
commit c785ead9d7
2 changed files with 59 additions and 18 deletions

View File

@ -65,21 +65,22 @@
<picker <picker
class="picker-full" class="picker-full"
mode="selector" mode="selector"
:range="coupons" :range="couponOptions"
range-key="name" range-key="name"
@change="onCouponChange" @change="onCouponChange"
:value="couponIndex" :value="couponIndex"
:disabled="(!coupons || coupons.length === 0) || useGamePass" :disabled="couponPickerDisabled"
> >
<view class="picker-display" :class="{ 'picker-disabled': useGamePass }"> <view class="picker-display" :class="{ 'picker-disabled': useGamePass }">
<text v-if="useGamePass" class="placeholder" style="color: #666;"> <text v-if="useGamePass" class="placeholder" style="color: #666;">
多次卡不可与优惠券同享 多次卡不可与优惠券同享
</text> </text>
<text v-if="selectedCoupon" class="selected-text"> <text v-else-if="selectedCoupon" class="selected-text">
{{ selectedCoupon.name }} (-¥{{ effectiveCouponDiscount.toFixed(2) }}) {{ selectedCoupon.name }} (-¥{{ effectiveCouponDiscount.toFixed(2) }})
<text v-if="selectedCoupon.amount > maxDeductible" style="font-size: 20rpx; color: #FF9800;">(最高抵扣50%)</text> <text v-if="selectedCoupon.amount > maxDeductible" style="font-size: 20rpx; color: #FF9800;">(最高抵扣50%)</text>
</text> </text>
<text v-else-if="!coupons || coupons.length === 0" class="placeholder">暂无优惠券可用</text> <text v-else-if="!hasUsableCoupons" class="placeholder">暂无优惠券可用</text>
<text v-else-if="couponOptionalSelected" class="placeholder">不使用优惠券</text>
<text v-else class="placeholder">请选择优惠券</text> <text v-else class="placeholder">请选择优惠券</text>
<text class="arrow"></text> <text class="arrow"></text>
</view> </view>
@ -129,7 +130,10 @@ const props = defineProps({
coupons: { type: Array, default: () => [] }, coupons: { type: Array, default: () => [] },
propCards: { type: Array, default: () => [] }, propCards: { type: Array, default: () => [] },
showCards: { type: Boolean, default: true }, showCards: { type: Boolean, default: true },
gamePasses: { type: Object, default: () => null } // { total_remaining, passes } gamePasses: { type: Object, default: () => null }, // { total_remaining, passes }
couponOptional: { type: Boolean, default: false },
defaultUseCoupon: { type: Boolean, default: true },
defaultUseGamePass: { type: Boolean, default: true }
}) })
const emit = defineEmits(['update:visible', 'confirm', 'cancel']) const emit = defineEmits(['update:visible', 'confirm', 'cancel'])
@ -203,6 +207,20 @@ const couponIndex = ref(-1)
const cardIndex = ref(-1) const cardIndex = ref(-1)
const useGamePass = ref(false) const useGamePass = ref(false)
const hasUsableCoupons = computed(() => Array.isArray(props.coupons) && props.coupons.length > 0)
const couponOptions = computed(() => {
const list = Array.isArray(props.coupons) ? props.coupons : []
if (!props.couponOptional) return list
return [{ id: 0, name: '不使用优惠券', amount: 0, noCoupon: true }, ...list]
})
const couponOptionalSelected = computed(() => props.couponOptional && Number(couponIndex.value) === 0)
const couponPickerDisabled = computed(() => {
return useGamePass.value || !hasUsableCoupons.value
})
// //
const gamePassRemaining = computed(() => { const gamePassRemaining = computed(() => {
return props.gamePasses?.total_remaining || 0 return props.gamePasses?.total_remaining || 0
@ -211,8 +229,7 @@ const gamePassRemaining = computed(() => {
// //
watch(() => props.visible, (newVal) => { watch(() => props.visible, (newVal) => {
if (newVal) { if (newVal) {
// useGamePass.value = props.defaultUseGamePass && gamePassRemaining.value > 0
useGamePass.value = gamePassRemaining.value > 0
} }
}) })
@ -221,12 +238,20 @@ function toggleGamePass() {
// Mutually Exclusive: If Game Pass is ON, clear Coupon. // Mutually Exclusive: If Game Pass is ON, clear Coupon.
if (useGamePass.value) { if (useGamePass.value) {
couponIndex.value = -1 couponIndex.value = -1
} else {
resetCouponSelection()
} }
} }
const selectedCoupon = computed(() => { const selectedCoupon = computed(() => {
if (couponIndex.value >= 0 && props.coupons[couponIndex.value]) { const index = Number(couponIndex.value)
return props.coupons[couponIndex.value] if (Number.isNaN(index)) return null
if (props.couponOptional) {
if (index <= 0) return null
return props.coupons[index - 1] || null
}
if (index >= 0 && props.coupons[index]) {
return props.coupons[index]
} }
return null return null
}) })
@ -262,24 +287,37 @@ const finalPayAmount = computed(() => {
return Math.max(0, amt - effectiveCouponDiscount.value).toFixed(2) return Math.max(0, amt - effectiveCouponDiscount.value).toFixed(2)
}) })
function resetCouponSelection() {
if (useGamePass.value) {
couponIndex.value = -1
return
}
if (!hasUsableCoupons.value) {
couponIndex.value = props.couponOptional ? 0 : -1
return
}
if (props.couponOptional) {
couponIndex.value = props.defaultUseCoupon ? 1 : 0
return
}
if (props.defaultUseCoupon && couponIndex.value < 0) {
couponIndex.value = 0
}
}
watch( watch(
[() => props.visible, () => (Array.isArray(props.coupons) ? props.coupons.length : 0)], [() => props.visible, () => (Array.isArray(props.coupons) ? props.coupons.length : 0)],
([vis, len]) => { ([vis]) => {
if (!vis) return if (!vis) return
cardIndex.value = -1 cardIndex.value = -1
if (len <= 0) { resetCouponSelection()
couponIndex.value = -1
return
}
if (couponIndex.value < 0) {
couponIndex.value = 0
}
}, },
{ immediate: true } { immediate: true }
) )
function onCouponChange(e) { function onCouponChange(e) {
couponIndex.value = e.detail.value const index = Number(e.detail.value)
couponIndex.value = Number.isNaN(index) ? -1 : index
} }
function onCardChange(e) { function onCardChange(e) {

View File

@ -180,6 +180,9 @@
:propCards="propCards" :propCards="propCards"
:showCards="true" :showCards="true"
:gamePasses="gamePasses" :gamePasses="gamePasses"
:couponOptional="true"
:defaultUseCoupon="false"
:defaultUseGamePass="false"
@confirm="onPaymentConfirm" @confirm="onPaymentConfirm"
/> />