Skip to content

团购 / 拼团 / 套餐 商品业务流程说明文档 ​

版本提示(2026-09-21):本文保留历史流程说明,部分价格模式、固定套餐分摊方式及代码路径已过时。平台运营商品的现行价格规则请参阅《平台运营商品价格逻辑》,不要将下文历史描述直接作为当前实现依据。

本文档用于详细阐述系统中团购(Groupbuy)、**拼团(Pintuan)以及套餐(Package)**商品的整体业务逻辑设计、数据库表结构关系、价格模式规则以及交易结算与下单预约的流转过程,供开发、测试及业务运营人员参考。


一、 核心概念与数据库表设计 ​

在系统设计中,商品的“基础信息”与“营销/价格活动”采用解耦设计,使得同一件商品可以参与不同的营销类型。

1. 核心数据表 ​

  • 商品基础表 (xl_product): 记录商品标题、分类、城市、图片、详情、限购规则、退款类型、扩展属性等基础静态信息。
  • 商品活动配置表 (xl_product_activity): 记录该商品参与的具体活动信息,包括活动类型(团购/拼团/套餐/租赁等)、定价模式(自主定价/底价模式)、平台售价、商户底价、抽成比例、平台加价等。
  • 套餐表 (xl_package): 由平台创建 and 维护的“组合套餐”主表,记录套餐名称、套餐总售价、城市、行程时长、行程介绍等。
  • 套餐商品关联表 (xl_package_item): 将 xl_package 与商户在 xl_product_activity 中发布的套餐底价商品进行关联绑定,属于套餐的子项。

2. 实体关联图 (ER Diagram) ​


二、 价格模式与约束规则 ​

系统中的营销商品区分两种价格模式:

  1. 自主定价模式 (self):商户拥有定价权,自己设定销售价,平台按预设的比例对交易额进行扣点抽成。
  2. 底价模式 (floor):商户填写结算底价,平台设定最终售价(销售价),底价归商户,溢价部分归平台所有。

1. 不同业务的价格模式限制 ​

活动类型 (activity_type)支持的价格模式 (price_mode)核心规则约束
团购 (groupbuy)自主定价 (self) / 底价模式 (floor)商户可自由选择定价权归属。
拼团 (pintuan)仅支持底价模式 (floor)强制约束,非底价模式保存时会抛出异常。
套餐 (package)仅支持底价模式 (floor)商户发布为底价套餐商品,仅代表结算底价;最终总售价由平台套餐决定。

2. 自主定价模式 of 默认抽成比例 ​

在自主定价模式下,若商户未配置抽成比例,系统会采用默认扣点比例:20%。

  • 核心代码位置:[XlProductActivityServiceImpl.java](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/XlProductActivityServiceImpl.java)
  • 业务公式: $$\text{平台抽成 (platformMargin)} = \text{活动售价 (activityPrice)} \times \text{抽成比例 (commissionRate)}$$ 注:若未填抽成比例,系统底层自动在新增时将 commissionRate 设为 20.00。

3. 微信支付手续费 (0.6%) 共同分摊机制 ​

在所有业务模式下,交易产生的微信支付通道手续费(系统内已从错误的 0.06% 修正为微信支付官方标准的 0.6%)由商户和平台按各自的应得款项比例共同承担,具体结算公式如下:

  • 微信支付总手续费: $$\text{总手续费 (totalActualFee)} = \text{用户实际支付售价} \times 0.6%$$
  • 商户与平台共同分摊:
    • 商户分摊: $$\text{商户手续费分摊} = \text{总手续费} \times \frac{\text{商户应分账金额}}{\text{商品活动售价}}$$ $$\text{商户实际入账可用余额} = \text{商户应分账金额} - \text{商户手续费分摊}$$
    • 平台分摊: $$\text{平台手续费分摊} = \text{总手续费} \times \frac{\text{平台应分账金额}}{\text{商品活动售价}}$$ $$\text{平台实际利润所得} = \text{平台应分账金额} - \text{平台手续费分摊}$$
    • 注:系统内钱包结算服务底层以“分”为最小计算单元。在计算分摊时,手续费均向分单位进行取整(Math.floor),以规避微小的分账小数差错。

三、 用户下单与预约逻辑详解 (特有规则) ​

针对酒店类型商品(businessType = "hotel"),系统在下单和发券核销上设计了特殊的机制。

1. 团购模式下的下单与预约 (囤券预约制) ​

  • 酒店团购商品:
    1. 下单与支付:用户调用 /groupbuy 接口下单支付时,不需要提交入住人或预约日期等信息。
    2. 囤券发码:支付成功回调中,系统判定为酒店团购后,[XlOrderServiceImpl.java:L723](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/XlOrderServiceImpl.java#L723) 规定不立即触发预约,仅为用户生成处于待预约状态(status = 0)的券码(囤券)。
    3. 二次预约:用户后续在订单详情页手工点击预约,调用 POST /api/app/hotel/appointments 接口提交预约日期和入住人信息,由 XdHotelAppointmentServiceImpl#createFromVoucherRequest 处理预约申请。
  • 其它普通团购商品:
    • 支付成功后立即发券,生成可直接到店扫码使用的券码,不经过任何二次预约流程。

2. 拼团与套餐模式下的下单与预约 (下单即预约) ​

与团购“先囤券后预约”不同,拼团与套餐在遇到酒店商品时,采用下单时同步提交预约的模式:

  • 拼团商品遇到酒店:
    • 下单(开团 /createPintuanGroup 或参团 /joinPintuanGroup)时,[XlOrderServiceImpl.java:L1843](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/XlOrderServiceImpl.java#L1843) 会强制校验预约参数:
      java
      if ("hotel".equals(prod.getBusinessType())) {
          if (fi.getCheckInDate() == null || fi.getCheckInDate().isEmpty()) {
              throw new ServiceException("酒店商品请选择入离日期");
          }
      }
    • 用户填写的入离日期(checkInDate/checkOutDate)和入住人信息(guestName/guestPhone)会在下单阶段同步写入订单明细的快照字段 snapshotJson 中。
  • 套餐商品遇到酒店:
    • 用户调用 /package 接口下单时,在参数中会同步包含套餐内酒店子项的入离日期及入住人信息。系统在保存子单时,直接将预约日期打包写入 snapshotJson 快照暂存。
    • 支付成功后,[XlOrderServiceImpl.java:L710-L721](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/XlOrderServiceImpl.java#L710-L721) 会检测当前子单是否为 "package" 且含酒店商品。若满足,系统会自动调用预约服务创建预约申请,跳过用户在前端二次重复预约的动作,实现一步到位。

四、 团购 / 拼团 业务流程 ​

团购与拼团的底价模式业务流转如下:

1. 创建活动商品 ​

  • 商户在商家后台发布团购或拼团商品,选择 floor 定价模式,填写 settlementPrice(结算底价)。
  • 校验规则:底价必填且不可为零或负数。

2. 平台定价与审核 ​

  • 平台管理员在平台管理后台对商户提交 of 活动进行审核,通过接口 setActivityPrice 设置商品的最终前端售价 activityPrice。
  • 溢价计算:系统在此阶段自动计算平台加价(即溢价归平台): $$\text{platformMargin} = \text{activityPrice} - \text{settlementPrice}$$

3. 交易支付与资金冻结 ​

  • 用户在前台下单支付。
  • 订单支付回调成功时,系统将子单的 settlementAmountFen(底价 $\times$ 数量)计算出来。
  • 钱包服务 MerchantWalletServiceImpl.creditForOrder 会生成一条业务类型为 ORDER_FROZEN 的记录,同时将底价收益冻结在商户钱包中。

五、 套餐 业务流程 ​

套餐采用“商户提供子件底价,平台组装销售”的模式:

1. 商户发布底价套餐商品 ​

  • 商户在商户端发布商品,选择活动类型为 package,定价模式为 floor,并设置其愿意接受的结算底价 settlementPrice。该商品通过审核后,自动进入“套餐商品池”。

2. 平台组装套餐 ​

  • 平台管理员在平台后台创建套餐(xl_package),设置对用户的套餐售价 packagePrice。
  • 从“套餐商品池”中挑选已入池的商品,添加到当前套餐下,生成 xl_package_item 记录。

3. 套餐下单及拆单分摊机制 ​

  • 分摊算法(位于 [XlOrderServiceImpl.java:splitPackageAmount](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/XlOrderServiceImpl.java#L2827)): 如果为固定套餐(fixed),系统会收集该套餐内所有关联商品的底价 settlementPrice,计算各自所占的比例,然后将用户支付的套餐总价(packagePrice)按比例分摊到每一个子商品的订单上,作为该子单的销售额;最后一单使用减法收余。 $$\text{子单分摊销售价} = \text{套餐总售价} \times \frac{\text{当前商品底价}}{\text{套餐内所有商品底价总和}}$$

六、 核心类与方法索引 ​

开发人员在进行代码调整或维护时,可参考以下核心文件:

  1. 商户端商品提交与校验:
    • 接口层:[MerchantProductController.java](file:///d:/XieLi/Api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/merchant/MerchantProductController.java)
    • 校验核心:validateDto(MerchantProductDto dto)(校验底价和售价是否填妥)
  2. 活动管理与默认比例配置:
    • 服务层:[XlProductActivityServiceImpl.java](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/XlProductActivityServiceImpl.java)
    • 核心方法:insertActivity、updateActivity、setActivityPrice(设置最终售价并计算平台利润)
  3. 平台端套餐管理:
    • 接口层:[AdminPackageController.java](file:///d:/XieLi/Api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/platform/AdminPackageController.java)
    • 核心服务:[XlPackageServiceImpl.java](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/XlPackageServiceImpl.java)
  4. 套餐下单与拆单:
    • 订单类型处理器:[PackageOrderHandler.java](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/order/handler/PackageOrderHandler.java)
    • 分摊算法:[XlOrderServiceImpl.java](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/XlOrderServiceImpl.java#L2827-L2875) 的 splitPackageAmount 方法
  5. 酒店预约提交流程:
    • 下单拦截与自动预约:[XlOrderServiceImpl.java](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/XlOrderServiceImpl.java#L710) 的 doPaySuccess 方法
    • 手动预约处理:XdHotelAppointmentServiceImpl#createFromVoucherRequest
  6. 钱包与财务结算:
    • 钱包服务:[MerchantWalletServiceImpl.java](file:///d:/XieLi/Api/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/MerchantWalletServiceImpl.java)
    • 核心方法:creditForOrder(支付成功冻结资金及收益)、unfreezeForOrder(核销完成底价解冻入账)

携岛 XieDao · 内部文档