跨店满减通过按店铺id聚合金额并封装规则实体实现轻量级计算:用map分组累计各店消费额,再由crossshopfullminusrule实体按阈值独立应用满减,最终汇总减免。

在轻量级订单系统中,跨店满减不需要强依赖分布式事务或复杂规则引擎。核心思路是:把“店铺”作为聚合维度,用 Map
用 Map 按店铺 ID 聚合消费金额
用户购物车中商品可能来自不同店铺(如商品 A 来自 shop-001,商品 B 来自 shop-002),需先按店铺归集:
- 遍历购物车项,提取 shopId 和 discountedAmount(已扣券/折扣后的行小计)
- 用
Map.compute(shopId, (k, v) -> v == null ? amount : v.add(amount))累加,天然避免 null 判断和重复 get/put - 结果得到
Map<string bigdecimal> shopAmounts</string>,例如:{"shop-001": 285.50, "shop-002": 142.00}
用实体类封装满减规则与计算逻辑
定义 CrossShopFullMinusRule 实体,明确表达业务语义:
一款AI开发辅助工具,主要用于使用 OpenCLI 工具,可从各类网站及桌面应用中提取数据、下载媒体内容、控制外部 CLI 工具。支持 Bilibili、知乎、小红书、Twitter/X、Reddit、YouTube、Boss直聘、即刻、微博等 30+ 个平台,以及 Cursor、Codex、ChatGPT、Notion 等桌面应用。当用户需要:从社...,适合需要提升相关任务效率的用户。
- 字段包括
threshold: BigDecimal(满额)、discount: BigDecimal(减额)、scope: String(如 "per_shop") - 提供方法
applyTo(BigDecimal total):若total.compareTo(threshold) >= 0,返回total.subtract(discount);否则返回原值 - 支持多档规则(如满200减20、满500减60),可存为
List<crossshopfullminusrule></crossshopfullminusrule>并按阈值倒序匹配
组合 Map 与实体完成端到端计算
将聚合结果交由规则实体处理,输出各店铺实付与总减免:
- 对
shopAmounts.entrySet()流式处理,每个 entry 调用rule.applyTo(entry.getValue()) - 记录每店减免额:
BigDecimal reduction = entry.getValue().subtract(result) - 汇总总减免:
reductions.stream().reduce(BigDecimal.ZERO, BigDecimal::add) - 最终订单实付 = 原始总金额 − 总减免(注意:跨店满减通常不跨店叠加,即每店独立判断)
注意事项与边界处理
轻量级不等于忽略健壮性:
- 金额统一用
BigDecimal,避免浮点误差;构造时用字符串(如new BigDecimal("200.00")) - 店铺 ID 为空时默认归入“平台店”或直接抛异常,不静默吞掉
- 规则未命中时返回 0 减免,不中断流程;日志记录未达标店铺便于运营分析
- 若需支持“跨店累计满减”(如全店合并达 300 减 30),只需把 Map 聚合 key 改为固定字符串(如 "cross_shop_total")










