010-53388338

美团买菜组合套餐系统设计:从架构到实现,提升客单价与用户体验

分类:IT频道 时间:2026-02-01 10:35 浏览:36
概述
    一、功能概述    组合套餐销售是美团买菜系统中重要的营销功能,允许商家将多个商品打包销售,提供价格优惠,提升客单价和用户购买体验。    二、系统架构设计    1.数据库设计    套餐表(combo_package)  ```  id(主键)  name(套餐名称)  descript
内容
  
   一、功能概述
  
  组合套餐销售是美团买菜系统中重要的营销功能,允许商家将多个商品打包销售,提供价格优惠,提升客单价和用户购买体验。
  
   二、系统架构设计
  
   1. 数据库设计
  
  套餐表(combo_package)
  ```
  id (主键)
  name (套餐名称)
  description (描述)
  image_url (图片)
  original_price (原价)
  discount_price (折扣价)
  start_time (开始时间)
  end_time (结束时间)
  status (状态:上架/下架)
  create_time (创建时间)
  update_time (更新时间)
  ```
  
  套餐商品关联表(combo_package_items)
  ```
  id (主键)
  combo_id (套餐ID)
  product_id (商品ID)
  quantity (数量)
  sort_order (排序)
  ```
  
  套餐购买记录表(combo_order_records)
  ```
  id (主键)
  order_id (订单ID)
  combo_id (套餐ID)
  user_id (用户ID)
  create_time (购买时间)
  ```
  
   2. 后端服务设计
  
  核心API接口
  - 创建/编辑套餐:`POST /api/combos`
  - 获取套餐列表:`GET /api/combos`
  - 获取套餐详情:`GET /api/combos/{id}`
  - 购买套餐:`POST /api/orders/combos`
  - 获取用户购买的套餐记录:`GET /api/users/{id}/combos`
  
  业务逻辑层
  - 套餐有效性验证(时间、库存等)
  - 价格计算逻辑(原价 vs 折扣价)
  - 库存预占与释放
  - 订单生成与支付处理
  
   3. 前端展示设计
  
  - 套餐专区页面
  - 套餐详情页(包含商品列表)
  - 购物车中的套餐展示
  - 订单确认页的套餐展示
  
   三、核心功能实现
  
   1. 套餐创建与管理
  
  ```java
  // 示例:创建套餐的Service层代码
  public ComboPackage createComboPackage(ComboCreateRequest request) {
   // 验证商品是否存在
   List productIds = request.getItems().stream()
   .map(ComboItemRequest::getProductId)
   .collect(Collectors.toList());
   List products = productRepository.findAllById(productIds);
   if (products.size() != productIds.size()) {
   throw new BusinessException("部分商品不存在");
   }
  
   // 计算原价
   BigDecimal originalPrice = request.getItems().stream()
   .map(item -> {
   Product p = products.stream()
   .filter(prod -> prod.getId().equals(item.getProductId()))
   .findFirst()
   .orElseThrow();
   return p.getPrice().multiply(BigDecimal.valueOf(item.getQuantity()));
   })
   .reduce(BigDecimal.ZERO, BigDecimal::add);
  
   // 创建套餐
   ComboPackage combo = new ComboPackage();
   combo.setName(request.getName());
   combo.setDescription(request.getDescription());
   combo.setOriginalPrice(originalPrice);
   combo.setDiscountPrice(request.getDiscountPrice());
   // 其他字段设置...
  
   // 保存套餐
   ComboPackage savedCombo = comboRepository.save(combo);
  
   // 保存套餐商品关联
   List items = request.getItems().stream()
   .map(item -> {
   ComboPackageItem comboItem = new ComboPackageItem();
   comboItem.setComboId(savedCombo.getId());
   comboItem.setProductId(item.getProductId());
   comboItem.setQuantity(item.getQuantity());
   // 其他字段设置...
   return comboItem;
   })
   .collect(Collectors.toList());
   comboItemRepository.saveAll(items);
  
   return savedCombo;
  }
  ```
  
   2. 套餐购买流程
  
  ```java
  // 示例:购买套餐的Service层代码
  public Order createComboOrder(Long userId, Long comboId, Integer quantity) {
   // 获取套餐信息
   ComboPackage combo = comboRepository.findById(comboId)
   .orElseThrow(() -> new BusinessException("套餐不存在"));
  
   if (!combo.getStatus().equals(ComboStatus.ACTIVE)) {
   throw new BusinessException("套餐已下架");
   }
  
   // 检查时间有效性
   LocalDateTime now = LocalDateTime.now();
   if (now.isBefore(combo.getStartTime()) || now.isAfter(combo.getEndTime())) {
   throw new BusinessException("套餐不在销售期内");
   }
  
   // 获取套餐商品
   List items = comboItemRepository.findByComboId(comboId);
  
   // 检查库存
   for (ComboPackageItem item : items) {
   Product product = productRepository.findById(item.getProductId())
   .orElseThrow(() -> new BusinessException("商品不存在"));
  
   if (product.getStock() < item.getQuantity() * quantity) {
   throw new BusinessException(product.getName() + "库存不足");
   }
   }
  
   // 预占库存(事务中操作)
   for (ComboPackageItem item : items) {
   productRepository.updateStock(
   item.getProductId(),
   item.getQuantity() * quantity * -1
   );
   }
  
   // 创建订单
   Order order = new Order();
   order.setUserId(userId);
   order.setTotalAmount(combo.getDiscountPrice().multiply(BigDecimal.valueOf(quantity)));
   order.setOriginalAmount(combo.getOriginalPrice().multiply(BigDecimal.valueOf(quantity)));
   order.setDiscountAmount(
   combo.getOriginalPrice().subtract(combo.getDiscountPrice()).multiply(BigDecimal.valueOf(quantity))
   );
   // 其他订单字段设置...
  
   // 保存订单
   Order savedOrder = orderRepository.save(order);
  
   // 保存订单商品(套餐中的商品)
   List orderItems = items.stream()
   .map(item -> {
   Product product = productRepository.findById(item.getProductId())
   .orElseThrow();
  
   OrderItem orderItem = new OrderItem();
   orderItem.setOrderId(savedOrder.getId());
   orderItem.setProductId(item.getProductId());
   orderItem.setProductName(product.getName());
   orderItem.setPrice(product.getPrice()); // 实际按单品价格记录,便于售后
   orderItem.setQuantity(item.getQuantity() * quantity);
   // 其他字段设置...
   return orderItem;
   })
   .collect(Collectors.toList());
   orderItemRepository.saveAll(orderItems);
  
   // 记录套餐购买
   ComboOrderRecord record = new ComboOrderRecord();
   record.setOrderId(savedOrder.getId());
   record.setComboId(comboId);
   record.setUserId(userId);
   comboOrderRecordRepository.save(record);
  
   return savedOrder;
  }
  ```
  
   3. 前端展示逻辑
  
  ```javascript
  // 示例:Vue组件中的套餐展示逻辑
  export default {
   data() {
   return {
   combos: [],
   loading: false,
   error: null
   }
   },
   created() {
   this.fetchCombos();
   },
   methods: {
   async fetchCombos() {
   this.loading = true;
   this.error = null;
   try {
   const response = await axios.get(/api/combos);
   this.combos = response.data.map(combo => ({
   ...combo,
   savedAmount: combo.originalPrice.subtract(combo.discountPrice),
   items: [] // 初始化商品列表
   }));
  
   // 加载每个套餐的商品详情
   for (const combo of this.combos) {
   const itemsResponse = await axios.get(`/api/combos/${combo.id}/items`);
   combo.items = itemsResponse.data;
   }
   } catch (err) {
   this.error = 获取套餐信息失败;
   console.error(err);
   } finally {
   this.loading = false;
   }
   },
   addToCart(combo) {
   // 添加套餐到购物车逻辑
   const cartItem = {
   type: combo,
   comboId: combo.id,
   name: combo.name,
   image: combo.imageUrl,
   price: combo.discountPrice,
   quantity: 1,
   items: combo.items // 包含套餐内商品信息
   };
  
   // 调用购物车服务添加商品
   this.$store.dispatch(cart/addItem, cartItem);
   this.$toast.success(已添加到购物车);
   }
   }
  }
  ```
  
   四、关键技术点
  
  1. 事务管理:确保库存预占、订单创建等操作的原子性
  2. 并发控制:防止超卖,可使用分布式锁或数据库乐观锁
  3. 价格计算:精确处理BigDecimal运算,避免浮点数精度问题
  4. 缓存策略:对热门套餐进行缓存,减少数据库压力
  5. 搜索优化:为套餐建立专门的索引,支持按分类、价格等筛选
  
   五、测试用例
  
  1. 正常流程测试
   - 创建有效套餐
   - 用户购买套餐
   - 检查订单和库存是否正确更新
  
  2. 异常流程测试
   - 购买已下架套餐
   - 购买库存不足的套餐
   - 购买不在销售期的套餐
  
  3. 边界条件测试
   - 套餐包含0件商品
   - 购买数量为0或负数
   - 折扣价为0或负数
  
  4. 性能测试
   - 高并发下购买套餐
   - 大量套餐数据下的查询性能
  
   六、部署与监控
  
  1. 部署方案
   - 套餐服务作为独立微服务部署
   - 使用容器化技术(Docker)便于扩展
  
  2. 监控指标
   - 套餐创建成功率
   - 套餐购买成功率
   - 库存预占失败率
   - 套餐服务响应时间
  
  3. 告警机制
   - 库存不足告警
   - 套餐购买异常告警
   - 服务不可用告警
  
  通过以上设计实现,美团买菜系统可以高效地支持组合套餐销售功能,提升用户体验和平台营收能力。
评论
  • 下一篇

  • Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 8192 bytes) in /www/wwwroot/www.sjwxsc.com/config/function.php on line 274