后端必须重验并最终定价,否则用户篡改totalamount可绕过满减规则导致资损;前端仅用computed实时示意,finalamount须基于rawtotal和selectedcoupon计算,不信任任何前端输入,所有校验与决策由后端完成。

满减优惠不能只在前端算,后端必须重验并最终定价——否则用户改个 totalAmount 就能绕过规则,直接导致资损。
前端展示逻辑:用 computed 实时响应,但不信任输入
用户选商品、加减数量、切换优惠券时,界面要立刻反馈“当前满减后价格”,但这只是示意。关键点在于:
-
finalAmount必须基于原始总价(rawTotal)和用户选择的优惠项(如selectedCoupon)计算,不能直接修改totalAmount变量 - 满减条件判断要严格:比如“满100减20”,得写成
rawTotal >= 100 ? rawTotal - 20 : rawTotal,别用> 100漏掉等于边界 - 多个满减叠加?别在前端硬拼逻辑——美团系业务里,满减通常互斥或按规则优先级生效,前端只显示“当前生效的那一条”,具体哪条生效由后端决定并返回标识
- 显示文案要带条件原文,例如“已减 ¥20(满¥100可用)”,避免用户误以为是固定折扣
后端才是唯一可信的计算入口
用户点击“去结算”时,前端只传原始订单数据 + 所选优惠 ID(如 couponId: 123),不传任何计算结果。后端收到后做三件事:
- 校验优惠券状态:是否过期、是否已使用、是否满足商品范围、是否达门槛
- 重新计算满减:以数据库中配置的规则为准,比如“同一订单仅限使用一张满减券”,或“满减与折扣券不可同享”
- 返回完整支付信息:
payAmount(最终应付)、discountDetail(减免明细)、ruleId(命中哪条规则),前端只负责渲染,不参与决策
示例请求结构:uni.request({ url: '/api/order/create', method: 'POST', data: { items: [...], couponId: this.selectedCoupon?.id } })
容易踩的坑:金额精度、边界值、多端一致性
看似简单,实操中最常翻车的是这些细节:
- 金额全部用分单位(整数)传输和计算,前端展示时再除以 100;避免
0.1 + 0.2 !== 0.3导致满减门槛错判 - 满减门槛是“订单实付金额”还是“商品原价总和”?两者语义完全不同,必须和产品对齐,后端字段命名要明确,比如
minOrderAmountvsminOriginalAmount - 小程序真机上,iOS 微信有时会把
Number.toFixed(2)四舍五入逻辑和安卓不一致,建议统一用后端返回的字符串金额做展示,前端不做二次格式化 - 用户在购物车页面反复切换优惠,前端缓存了旧的
rawTotal(比如图片还没加载完,商品价格还是 placeholder 值),导致满减误触发——务必确保rawTotal是所有商品 price × quantity 的实时准确和
真正难的不是怎么写公式,而是怎么让前端“看起来实时”,又不让后端“被前端骗”。所有优惠逻辑的权威性必须收口到服务端,前端只做确定性渲染和用户引导。











