bundle-pricing.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. /**
  2. * 订单套餐自动定价 · 前端展示辅助(纯函数)
  3. *
  4. * 权威计算在后端:购物车/下单金额均由后端按 product_bundle_items 定价行重算,
  5. * 前端仅消费后端下发的 bundlePromo 做展示与总价扣减,杜绝前端篡改优惠。
  6. */
  7. /**
  8. * 安全读取套餐优惠金额(分):未命中/未激活/非法值一律返回 0。
  9. * @param {Object|null} promo 后端下发的 bundlePromo
  10. * @returns {number}
  11. */
  12. export function bundleDiscountOf(promo) {
  13. if (!promo || promo.active !== true) return 0
  14. const d = promo.discount
  15. return typeof d === 'number' && d > 0 ? d : 0
  16. }
  17. /**
  18. * 套餐命中明细 → 展示行(过滤脏数据、补齐默认值)。
  19. * @param {Array|null} bundleList
  20. * @returns {Array<{name: string, times: number, saving: number}>}
  21. */
  22. export function formatBundleLines(bundleList) {
  23. if (!Array.isArray(bundleList)) return []
  24. return bundleList
  25. .filter(h => h && h.bundleName)
  26. .map(h => ({
  27. name: h.bundleName,
  28. times: (typeof h.times === 'number' && h.times > 0) ? h.times : 1,
  29. saving: (typeof h.saving === 'number' && h.saving > 0) ? h.saving : 0
  30. }))
  31. }
  32. /**
  33. * 对总价应用套餐优惠(安全扣减)。
  34. * @param {number} total 总价(分)
  35. * @param {Object|null} promo
  36. * @returns {number}
  37. */
  38. export function applyBundleDiscount(total, promo) {
  39. const base = typeof total === 'number' ? total : 0
  40. return base - bundleDiscountOf(promo)
  41. }