/** * 订单套餐自动定价 · 前端展示辅助(纯函数) * * 权威计算在后端:购物车/下单金额均由后端按 product_bundle_items 定价行重算, * 前端仅消费后端下发的 bundlePromo 做展示与总价扣减,杜绝前端篡改优惠。 */ /** * 安全读取套餐优惠金额(分):未命中/未激活/非法值一律返回 0。 * @param {Object|null} promo 后端下发的 bundlePromo * @returns {number} */ export function bundleDiscountOf(promo) { if (!promo || promo.active !== true) return 0 const d = promo.discount return typeof d === 'number' && d > 0 ? d : 0 } /** * 套餐命中明细 → 展示行(过滤脏数据、补齐默认值)。 * @param {Array|null} bundleList * @returns {Array<{name: string, times: number, saving: number}>} */ export function formatBundleLines(bundleList) { if (!Array.isArray(bundleList)) return [] return bundleList .filter(h => h && h.bundleName) .map(h => ({ name: h.bundleName, times: (typeof h.times === 'number' && h.times > 0) ? h.times : 1, saving: (typeof h.saving === 'number' && h.saving > 0) ? h.saving : 0 })) } /** * 对总价应用套餐优惠(安全扣减)。 * @param {number} total 总价(分) * @param {Object|null} promo * @returns {number} */ export function applyBundleDiscount(total, promo) { const base = typeof total === 'number' ? total : 0 return base - bundleDiscountOf(promo) }