美团买菜组合套餐系统设计:从架构到实现,提升客单价与用户体验
分类: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. 告警机制
- 库存不足告警
- 套餐购买异常告警
- 服务不可用告警
通过以上设计实现,美团买菜系统可以高效地支持组合套餐销售功能,提升用户体验和平台营收能力。
评论