Skip to content

代理折扣设计

目标

新增与会员等级完全独立的代理折扣体系。代理折扣是直接乘在商品原价上的付款系数,适用于新购、续费以及其他基于本地商品价格生成的可用付款账单。用户端展示代理组和折后价格,后台提供代理组、商品折扣分组、折扣矩阵、用户归属和优惠券兼容配置。

业务规则

  • 会员等级继续只负责分销返利,member_level_id 不参与代理折扣计算。
  • 用户最多绑定一个代理组,代理组由后台手动指定,不根据消费额自动升降级。
  • 商品最多绑定一个商品折扣分组;商品没有折扣分组、用户没有代理组或矩阵没有匹配项时,折扣系数为 100%
  • 商品折扣分组包含最低折扣率和成本系数。最低折扣率为允许保存的下限,成本系数用于成本价校验和后续利润统计。
  • 代理组与商品折扣分组之间通过唯一矩阵配置一个折扣率。折扣率必须大于等于商品折扣分组最低折扣率,且取值为 0-100
  • 计价顺序固定为:商品原价 → 代理折扣 → 优惠券折扣 → 最终应付金额。
  • 优惠券增加“允许代理使用”选项。代理用户仅可使用明确允许代理使用的优惠券;非代理用户不受此选项影响。
  • 代理折扣后的金额低于商品原价乘成本系数时,报价和创建账单均拒绝,不允许通过篡改报价令牌绕过。
  • 续费同样应用当前用户和商品的代理折扣。代理组变更后,下一次报价使用新代理组;已创建账单保留创建时的金额快照。
  • 外部上游直接返回价格的升级、流量包等旁路交易不强行套用本地代理折扣,除非其业务链路能够得到本地商品原价和成本基准。

数据模型

product_discount_groups

保存商品折扣分组:idnamecodemin_discount_ratecost_ratestatussort_orderremark、时间戳。code 唯一,费率为 decimal(5,2),范围为 0-100

agent_groups

保存代理组:idnamecodestatussort_orderremark、时间戳。code 唯一。删除被用户或矩阵引用的代理组时采用安全阻止或置空策略,不能留下无效折扣关系。

agent_group_discounts

保存代理组和商品折扣分组的矩阵关系:agent_group_idproduct_discount_group_iddiscount_rate、时间戳。建立二者联合唯一键和必要外键,删除任一侧时清理矩阵关系。

现有表扩展

  • products.product_discount_group_id:可空外键,删除分组时置空。
  • users.agent_group_id:可空外键,删除代理组时置空。
  • coupons.allow_agent:默认允许,控制代理用户是否可以使用该优惠券。

商品成本系数属于商品折扣分组,不重复写入商品价格 JSON。商品原价、代理折扣率、成本系数和实际金额在报价及账单快照中记录,保证后续利润统计具备数据基础。

后端计价

新增 AgentDiscountService 作为代理折扣领域服务,负责解析用户代理组、商品折扣分组、矩阵折扣率和成本系数,并提供统一的金额计算及成本校验方法。无匹配时返回 100%,不会改变普通用户和未配置数据的现有价格。

新购报价在 HandlesOrderCalculation 的统一报价链路中应用代理折扣,返回原始金额、代理折扣率、代理折扣金额、代理折后金额和成本基准。SiteProductQuoteService 将这些字段返回用户端,并将代理组身份、折扣配置和最终金额纳入报价令牌指纹。

创建新购账单时,服务端重新计算代理折扣并执行成本校验,再进行优惠券占用和最终应付金额计算。优惠券的可用性判断增加代理用户限制,优惠券折扣基于代理折后金额计算。账单、订单投影和配置快照保存原价、代理折扣、优惠券折扣、成本基准及代理组快照。

续费预览和续费建单在 ServiceRenewService 的周期价格生成和创建账单链路中应用相同规则。每个续费周期分别计算代理价,优惠券仍在代理价基础上计算。续费账单保存代理折扣快照,自动续费复用同一预览结果。

任何来自客户端的金额、代理组或折扣率字段都不作为可信输入;服务端只依据数据库当前关系重新解析。旧报价令牌在代理组、矩阵折扣或商品分组变更后必须失效。

API 与权限

新增后台接口:

  • 商品折扣分组列表、详情、创建、更新、删除。
  • 代理组列表、详情、创建、更新、删除。
  • 折扣矩阵查询和批量保存。
  • 商品绑定或解除商品折扣分组。
  • 用户绑定或解除代理组。

新增独立的代理折扣查看和管理权限,并接入后台权限目录、菜单和接口中间件。用户列表、用户详情、商品列表、商品详情、订单、账单和服务实例相关管理接口按需要补充代理组与折扣快照字段。

现有用户端商品报价、购买确认、续费预览、账单详情和个人中心接口增加代理组、原价、代理折扣率、代理折扣金额、优惠券折扣金额和最终应付金额字段。字段缺失时前端按普通用户价格兼容。

前端界面

后台新增代理折扣管理区域:

  • 商品折扣分组管理:名称、编码、最低折扣率、成本系数、状态和备注。
  • 代理组管理:名称、编码、状态、排序和备注。
  • 折扣矩阵编辑:行展示商品折扣分组,列展示代理组,编辑折扣率时即时校验最低折扣率。
  • 商品管理:选择商品折扣分组并展示成本系数及最低折扣率。
  • 用户列表和用户详情:展示代理组,支持后台手动绑定、解除和变更。
  • 优惠券管理:增加是否允许代理使用的开关。
  • 订单、账单、服务实例和用户相关页面:在可用数据存在时展示代理组、原价、代理折扣和最终金额。

用户端购买和续费页面展示原价划线、代理折后价、代理组名称和折扣说明;普通用户不显示空的代理信息。个人中心和用户主页展示当前代理组。

校验与错误处理

  • 所有费率统一按 0-100 校验,并使用金额工具类按两位小数计算。
  • 商品折扣分组最低折扣率不得高于矩阵折扣率。
  • 成本系数不得高于 100%,不能为负数。
  • 折后金额低于成本基准时返回明确业务错误,不创建账单,不占用优惠券,不扣余额。
  • 代理组或折扣矩阵被禁用、删除或变更时,新报价立即使用最新有效配置;已经创建的未支付账单不静默改价,按照账单快照处理。
  • 代理用户使用 allow_agent=0 的优惠券时,返回不可用,不泄露优惠券存在与否以外的敏感信息。
  • 所有计价分支记录必要的代理折扣上下文,禁止日志输出认证凭证和支付敏感信息。

验证范围

  • 代理组、商品折扣分组和矩阵的增删改查、权限和边界校验。
  • 普通用户、无匹配矩阵代理用户、有效矩阵代理用户的报价结果。
  • 新购和续费的代理折扣、优惠券叠加及成本价拒绝。
  • 报价令牌在代理组、商品分组和矩阵变更后的失效行为。
  • 自动续费与手动续费金额一致性。
  • 订单、账单、用户主页、购买页和续费页的代理信息展示。
  • 代理组删除、商品分组解绑、优惠券禁用代理使用等异常路径。

基于 AGPL-3.0-or-later 发布