一、需求分析
组合套餐销售是美团买菜提升客单价和用户购买体验的重要功能,主要需求包括:
1. 套餐创建与管理:支持商家自定义组合套餐
2. 价格计算:套餐总价与单品总价的优惠对比
3. 库存管理:套餐库存与单品库存的联动
4. 展示与推荐:在前端清晰展示套餐内容和优惠
5. 订单处理:正确拆分套餐为单品进行履约
二、系统架构设计
1. 核心模块设计
```
套餐服务(Package Service)
├── 套餐管理模块
├── 价格计算模块
├── 库存管理模块
└── 推荐引擎模块
商品服务(Commodity Service)
├── 商品信息管理
└── 库存管理
订单服务(Order Service)
├── 订单创建
└── 订单拆单处理
营销服务(Marketing Service)
├── 优惠规则引擎
└── 价格计算策略
```
2. 数据库设计
套餐主表(package)
```
id (主键)
name (套餐名称)
description (描述)
original_price (原价)
discount_price (优惠价)
start_time (开始时间)
end_time (结束时间)
status (状态)
```
套餐商品关联表(package_commodity)
```
id (主键)
package_id (套餐ID)
commodity_id (商品ID)
quantity (数量)
sort_order (排序)
```
套餐库存表(package_stock)
```
id (主键)
package_id (套餐ID)
total_stock (总库存)
locked_stock (锁定库存)
available_stock (可用库存)
```
三、核心功能实现
1. 套餐创建流程
```java
public Package createPackage(PackageCreateRequest request) {
// 1. 验证商品是否存在
List
commodities = commodityService.batchGet(request.getCommodityIds()); if (commodities.size() != request.getCommodityIds().size()) { throw new BusinessException("部分商品不存在"); } // 2. 计算原价 BigDecimal originalPrice = calculateOriginalPrice(request.getCommodityIds(), request.getQuantities()); // 3. 创建套餐 Package pkg = new Package(); pkg.setName(request.getName()); pkg.setDescription(request.getDescription()); pkg.setOriginalPrice(originalPrice); pkg.setDiscountPrice(request.getDiscountPrice()); // 其他字段设置... // 4. 保存套餐信息 packageRepository.save(pkg); // 5. 保存套餐商品关系 List relations = request.getCommodityIds().stream() .map(id -> { PackageCommodity pc = new PackageCommodity(); pc.setPackageId(pkg.getId()); pc.setCommodityId(id); pc.setQuantity(request.getQuantities().get(id)); return pc; }) .collect(Collectors.toList()); packageCommodityRepository.saveAll(relations); return pkg; } ``` 2. 价格计算策略 ```java public interface PriceCalculator { BigDecimal calculate(Package packageInfo); } public class DefaultPriceCalculator implements PriceCalculator { @Override public BigDecimal calculate(Package packageInfo) { // 获取套餐中所有商品及其数量 List commodities = packageCommodityRepository.findByPackageId(packageInfo.getId()); // 计算单品总价 BigDecimal originalPrice = commodities.stream() .map(pc -> { Commodity commodity = commodityService.getById(pc.getCommodityId()); return commodity.getPrice().multiply(new BigDecimal(pc.getQuantity())); }) .reduce(BigDecimal.ZERO, BigDecimal::add); // 返回套餐优惠价(如果未设置优惠价,返回原价) return packageInfo.getDiscountPrice() != null ? packageInfo.getDiscountPrice() : originalPrice; } } ``` 3. 库存管理实现 ```java public class PackageStockService { @Transactional public boolean reserveStock(Long packageId, int quantity) { Package packageInfo = packageRepository.findById(packageId) .orElseThrow(() -> new BusinessException("套餐不存在")); // 检查套餐库存 if (packageInfo.getAvailableStock() < quantity) { return false; } // 检查所有商品库存 List commodities = packageCommodityRepository.findByPackageId(packageId); for (PackageCommodity pc : commodities) { Commodity commodity = commodityService.getById(pc.getCommodityId()); if (commodity.getAvailableStock() < pc.getQuantity() * quantity) { return false; } } // 锁定套餐库存 packageRepository.decreaseStock(packageId, quantity); // 锁定商品库存(实际业务中可能需要) // ... return true; } } ``` 4. 订单处理流程 ```java public class OrderService { public Order createOrder(OrderCreateRequest request) { // 1. 验证套餐库存 if (request.getPackageId() != null) { boolean stockReserved = packageStockService.reserveStock( request.getPackageId(), request.getQuantity() ); if (!stockReserved) { throw new BusinessException("套餐库存不足"); } } // 2. 创建订单 Order order = new Order(); // 设置订单基本信息... // 3. 添加订单项 if (request.getPackageId() != null) { // 如果是套餐,拆分为多个商品项 Package pkg = packageRepository.findById(request.getPackageId()) .orElseThrow(() -> new BusinessException("套餐不存在")); List commodities = packageCommodityRepository.findByPackageId(request.getPackageId()); for (PackageCommodity pc : commodities) { OrderItem item = new OrderItem(); item.setCommodityId(pc.getCommodityId()); item.setQuantity(pc.getQuantity() * request.getQuantity()); item.setPrice(pc.getPrice()); // 使用套餐中设定的商品价格 order.addItem(item); } } else { // 单品订单处理... } // 4. 保存订单 orderRepository.save(order); return order; } } ``` 四、前端展示方案 1. 套餐卡片设计 ```html ``` 2. 套餐详情页 ```html 超值套餐
套餐内容 商品A ×2 单品总价: ¥108
套餐价: ¥88
立省: ¥20
立即购买 加入购物车
``` 五、关键技术点 1. 库存一致性保证: - 使用分布式锁保证套餐和单品库存操作的原子性 - 实现库存预扣机制,防止超卖 2. 价格计算优化: - 缓存套餐原价计算结果 - 使用计算器模式灵活支持各种优惠策略 3. 套餐推荐算法: - 基于用户购买历史的关联规则挖掘 - 实时计算套餐的性价比指标 4. 性能优化: - 套餐商品信息预加载 - 使用Redis缓存热门套餐数据 - 实现套餐的异步库存同步 六、测试要点 1. 功能测试: - 套餐创建、修改、删除 - 套餐价格计算准确性 - 库存联动更新 2. 并发测试: - 多用户同时购买同一套餐 - 库存扣减的线程安全 3. 边界测试: - 套餐中某个商品缺货时的处理 - 套餐价格低于单品总价时的验证 - 套餐有效期检查 七、部署与监控 1. 监控指标: - 套餐购买转化率 - 套餐库存预警 - 套餐价格计算耗时 2. 告警规则: - 套餐库存低于阈值 - 套餐价格计算异常 - 套餐购买量突增 通过以上方案,美团买菜系统可以实现高效、稳定的组合套餐销售功能,提升用户体验和平台收益。