diff --git a/src/components/payCard/payCard.vue b/src/components/payCard/payCard.vue index 67f26a3..8c752f4 100644 --- a/src/components/payCard/payCard.vue +++ b/src/components/payCard/payCard.vue @@ -206,7 +206,7 @@
@@ -214,10 +214,11 @@ 清除
-
- 注意:订单金额不足¥{{ - formatDecimal(+pointOptions.minPaymentAmount) }},无法使用积分抵扣 +
+ 注意:{{ pointOptions.unusableReason || (`订单金额不足¥${formatDecimal(+pointOptions.minPaymentAmount)},无法使用积分抵扣`) }} +
+
+ 说明:订单已满足使用门槛,当前积分可抵扣最多¥{{ pointOptions.potentialAmount }}(当前积分 {{ couponFormUser.accountPoints || 0 }})
@@ -666,6 +667,7 @@ const pointOptions = ref({ usable: true, unusableReason: '', amount: 0, // 抵扣金额(元) + potentialAmount: 0, // 用户当前积分可抵扣的最大金额(元,供展示) loading: false }) @@ -775,7 +777,8 @@ const pointInput = _.debounce(function (e) { // 未登录用户或无可用积分时直接归0并返回 const userAvailablePoints = Number(couponFormUser.value && couponFormUser.value.accountPoints ? couponFormUser.value.accountPoints : 0) - if (!couponFormUser.value || !couponFormUser.value.id || userAvailablePoints <= 0) { + // 如果未登录、无可用积分或积分抵扣不可用(不满足门槛或商家未开启),直接归0并返回 + if (!couponFormUser.value || !couponFormUser.value.id || userAvailablePoints <= 0 || !pointOptions.value.usable) { couponForm.value.pointsNum = 0 pointOptions.value.amount = 0 updateCartCalc() @@ -788,12 +791,11 @@ const pointInput = _.debounce(function (e) { } // 边界限制:不得超过最大/小于最小 - if (couponForm.value.pointsNum > pointOptions.value.maxPoints) { + if (pointOptions.value.maxPoints && couponForm.value.pointsNum > pointOptions.value.maxPoints) { couponForm.value.pointsNum = pointOptions.value.maxPoints } - if (couponForm.value.pointsNum < pointOptions.value.minPoints) { - couponForm.value.pointsNum = pointOptions.value.minPoints - } + // 允许输入少于 minPoints 的积分(前端做友好展示),实际抵扣金额由 calcPointMoney 和后端规则决定 + // 如果希望严格按照 minPoints 阈值生效,可在此恢复置0逻辑 if (!e) { couponForm.value.pointsNum = 0 @@ -806,7 +808,7 @@ const pointInput = _.debounce(function (e) { // 满足条件式开始计算抵扣金额,由后端返回 - if (couponForm.value.pointsNum >= pointOptions.value.minPoints && couponForm.value.pointsNum <= pointOptions.value.maxPoints) { + if (couponForm.value.pointsNum > 0 && (!pointOptions.value.maxPoints || couponForm.value.pointsNum <= pointOptions.value.maxPoints)) { pointOptions.value.loading = true calcPointMoney() } @@ -822,25 +824,30 @@ const calcPointMoney = async () => { const points = Number(couponForm.value.pointsNum || 0) const orderAmount = Number(goodsStore.cartInfo.costSummary.finalPayAmount || 0) - if (!pointsPerYuan || points <= 0) { + // 若不满足计算条件,则直接退出并复位 + if (!pointOptions.value.usable || !pointsPerYuan || points <= 0) { pointOptions.value.amount = 0 - // 若未初始化 couponForm.value.amount,则用订单原价 couponForm.value.amount = couponForm.value.amount || originOrderAmount.value || orderAmount updateCartCalc() + pointOptions.value.loading = false return } // 积分可抵扣的金额(元) => 积分 / (积分数/元) - let deductionFromPoints = points / pointsPerYuan + const deductionFromPoints = points / pointsPerYuan - // 最大可抵扣金额基于订单金额和最大抵扣比例 + // 最大可抵扣金额基于订单金额和最大抵扣比例(后端规则) const maxDeductionAmount = orderAmount * (pointOptions.value.maxDeductionRatio || 0) - // 最终抵扣为积分抵扣金额与最大比例的较小者,且不超过订单可支付金额 - const baseAmount = Number(couponForm.value.amount || originOrderAmount.value || orderAmount) + // 基数为当前可用于抵扣的订单金额(可能已经包含其他优惠),不能小于0 + const baseAmount = Math.max(0, Number(couponForm.value.amount || originOrderAmount.value || orderAmount)) + + // 最终抵扣为:积分折算金额、最大可抵扣金额、当前可抵扣金额三者的最小值 let deduction = Math.min(deductionFromPoints, maxDeductionAmount, baseAmount) - pointOptions.value.amount = formatDecimal(deduction) + deduction = Number(formatDecimal(deduction)) + + pointOptions.value.amount = deduction couponForm.value.amount = formatDecimal(baseAmount - deduction) updateCartCalc() @@ -977,19 +984,46 @@ async function pointOptionsAjax() { // 后端的 equivalentPoints 表示 积分数/元(例如 20 表示 20 积分 = 1 元) pointOptions.value.pointsPerYuan = pointOptions.value.equivalentPoints + // 规范化 maxDeductionRatio:后端可能以百分比(如50)返回,若大于1则认为是百分比并除以100 + if (pointOptions.value.maxDeductionRatio > 1) { + pointOptions.value.maxDeductionRatio = pointOptions.value.maxDeductionRatio / 100 + } + // 计算页面需要的最小/最大可用积分(按接口返回的金额阈值与比例换算为积分) const pointsPerYuan = pointOptions.value.pointsPerYuan || 0 const orderAmount = Number(goodsStore.cartInfo.costSummary.finalPayAmount || 0) // 最少使用积分:基于最小抵扣金额换算(若无则为0),minPaymentAmount 单位为元 - pointOptions.value.minPoints = pointOptions.value.minPaymentAmount && pointsPerYuan ? Math.ceil(pointOptions.value.minPaymentAmount * pointsPerYuan) : 0 + pointOptions.value.minPoints = (pointOptions.value.minPaymentAmount && pointsPerYuan) ? Math.ceil(pointOptions.value.minPaymentAmount * pointsPerYuan) : 0 - // 最大可用积分:基于订单金额与最大抵扣比例换算 - pointOptions.value.maxPoints = (pointOptions.value.maxDeductionRatio && pointsPerYuan) ? Math.floor(orderAmount * pointOptions.value.maxDeductionRatio * pointsPerYuan) : 0 + // 最大可用积分:基于订单金额与最大抵扣比例换算。后端返回的 maxDeductionRatio 表示可抵扣的最大金额占比,需换算为积分 + const maxDeductionAmount = orderAmount * (pointOptions.value.maxDeductionRatio || 0) + pointOptions.value.maxPoints = (pointOptions.value.maxDeductionRatio && pointsPerYuan) ? Math.floor(maxDeductionAmount * pointsPerYuan) : 0 - // 可用性 - pointOptions.value.usable = pointOptions.value.enableRewards === 1 && pointOptions.value.maxPoints > 0 - pointOptions.value.unusableReason = pointOptions.value.usable ? '' : (pointOptions.value.enableRewards !== 1 ? '商家未开启积分抵扣' : '订单不可抵扣积分') + // 可用性:必须开启、订单满足最小支付金额门槛且最大可用积分>0 + pointOptions.value.usable = (pointOptions.value.enableRewards === 1) && (orderAmount >= (pointOptions.value.minPaymentAmount || 0)) && pointOptions.value.maxPoints > 0 + + if (!pointOptions.value.usable) { + if (pointOptions.value.enableRewards !== 1) { + pointOptions.value.unusableReason = '商家未开启积分抵扣' + } else if (orderAmount < (pointOptions.value.minPaymentAmount || 0)) { + pointOptions.value.unusableReason = `订单金额不足¥${formatDecimal(+pointOptions.value.minPaymentAmount)},无法使用积分抵扣` + } else { + pointOptions.value.unusableReason = '订单不可抵扣积分' + } + } else { + pointOptions.value.unusableReason = '' + } + + // 计算当前用户积分在当前订单下的潜在最大抵扣金额(仅供展示) + let potential = 0 + const userPoints = Number(couponFormUser.value && couponFormUser.value.accountPoints ? couponFormUser.value.accountPoints : 0) + if (pointsPerYuan && userPoints > 0) { + potential = Math.min(userPoints / pointsPerYuan, maxDeductionAmount, orderAmount) + } + pointOptions.value.potentialAmount = formatDecimal(potential) + + console.log('pointOptions after calc:', JSON.parse(JSON.stringify(pointOptions.value)), 'couponFormUser:', JSON.parse(JSON.stringify(couponFormUser.value)), 'orderAmount:', orderAmount) } catch (error) { console.log(error); }