电商订单功能设计和实现
订单模块采用分层架构设计,通过状态机管理订单生命周期(待付款、待发货、已发货等)。核心流程包括:订单生成前组装确认单信息、创建时校验库存并锁定、支付成功后更新状态扣减库存。系统通过RabbitMQ延迟队列处理超时订单自动取消,释放库存并返还优惠券。数据库设计包含订单主表(记录基本信息和状态)、订单商品表(记录商品明细)和操作历史表。关键点包括:订单号生成策略、事务一致性保障、库存先锁定后扣减机制。
·
订单模块设计思路
1. 核心设计理念
- 分层架构:采用Controller-Service-DAO分层架构,职责分离清晰
- 状态驱动:通过订单状态(0-待付款、1-待发货、2-已发货、3-已完成、4-已关闭)管理订单生命周期
- 事务一致性:关键操作使用@Transactional确保数据一致性
- 异步处理:通过RabbitMQ延迟队列处理超时订单
2. 订单生命周期管理
具体实现
1. 核心类结构
2. 订单生成流程实现
2.1 确认单生成
// 核心逻辑:组装购物车、地址、优惠券、积分等信息
public ConfirmOrderResult generateConfirmOrder(List<Long> cartIds) {
ConfirmOrderResult result = new ConfirmOrderResult();
// 获取购物车促销信息
List<CartPromotionItem> cartPromotionItemList = cartItemService.listPromotion(currentMember.getId(), cartIds);
// 获取收货地址
List<UmsMemberReceiveAddress> memberReceiveAddressList = memberReceiveAddressService.list();
// 获取可用优惠券
List<SmsCouponHistoryDetail> couponHistoryDetailList = memberCouponService.listCart(cartPromotionItemList, 1);
// 计算金额
ConfirmOrderResult.CalcAmount calcAmount = calcCartAmount(cartPromotionItemList);
return result;
}
2.2 订单创建
public Map<String, Object> generateOrder(OrderParam orderParam) {
// 1. 校验收货地址和库存
if (!hasStock(cartPromotionItemList)) {
Asserts.fail("库存不足,无法下单");
}
// 2. 处理优惠券和积分
handleCouponAmount(orderItemList, couponHistoryDetail);
handleRealAmount(orderItemList);
// 3. 锁定库存
lockStock(cartPromotionItemList);
// 4. 生成订单号(日期+类型+Redis自增)
String orderSn = generateOrderSn(order);
// 5. 保存订单和订单项
orderMapper.insert(order);
orderItemDao.insertList(orderItemList);
// 6. 发送延迟取消消息
sendDelayMessageCancelOrder(order.getId());
}
3. 支付回调处理
public Integer paySuccess(Long orderId, Integer payType) {
// 1. 更新订单状态(只更新未付款订单)
OmsOrderExample example = new OmsOrderExample();
example.createCriteria()
.andIdEqualTo(order.getId())
.andDeleteStatusEqualTo(0)
.andStatusEqualTo(0);
int updateCount = orderMapper.updateByExampleSelective(order, example);
// 2. 扣减真实库存,释放锁定库存
OmsOrderDetail orderDetail = portalOrderDao.getDetail(orderId);
for (OmsOrderItem orderItem : orderDetail.getOrderItemList()) {
portalOrderDao.reduceSkuStock(orderItem.getProductSkuId(), orderItem.getProductQuantity());
}
}
4. 超时订单处理
4.1 延迟队列配置
@Configuration
public class RabbitMqConfig {
// 订单延迟队列(死信队列)
@Bean
public Queue orderTtlQueue() {
return QueueBuilder.durable(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getName())
.withArgument("x-dead-letter-exchange", QueueEnum.QUEUE_ORDER_CANCEL.getExchange())
.withArgument("x-dead-letter-routing-key", QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey())
.build();
}
}
4.2 自动取消逻辑
public Integer cancelTimeOutOrder() {
// 1. 查询超时未支付订单
List<OmsOrderDetail> timeOutOrders = portalOrderDao.getTimeOutOrders(orderSetting.getNormalOrderOvertime());
// 2. 批量更新状态为已关闭
portalOrderDao.updateOrderStatus(ids, 4);
// 3. 释放库存锁定,返还优惠券和积分
portalOrderDao.releaseSkuStockLock(timeOutOrder.getOrderItemList());
updateCouponStatus(timeOutOrder.getCouponId(), timeOutOrder.getMemberId(), 0);
}
5. 数据库设计
5.1 核心表结构
-- 订单主表
CREATE TABLE `oms_order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_sn` varchar(64) COMMENT '订单编号',
`member_id` bigint(20) COMMENT '用户ID',
`status` int(1) COMMENT '订单状态',
`total_amount` decimal(10,2) COMMENT '订单总金额',
`pay_amount` decimal(10,2) COMMENT '应付金额',
`create_time` datetime COMMENT '提交时间',
`payment_time` datetime COMMENT '支付时间',
PRIMARY KEY (`id`)
);
-- 订单商品表
CREATE TABLE `oms_order_item` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_id` bigint(20) COMMENT '订单ID',
`product_name` varchar(500) COMMENT '商品名称',
`product_price` decimal(10,2) COMMENT '销售价格',
`product_quantity` int(11) COMMENT '购买数量',
PRIMARY KEY (`id`)
);
-- 订单操作历史表
CREATE TABLE `oms_order_operate_history` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_id` bigint(20) COMMENT '订单id',
`operate_man` varchar(100) COMMENT '操作人',
`order_status` int(1) COMMENT '订单状态',
`note` varchar(500) COMMENT '备注',
PRIMARY KEY (`id`)
);
6. 关键技术特性
6.1 订单号生成策略
private String generateOrderSn(OmsOrder order) {
// 8位日期+2位平台+2位支付方式+6位自增
String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
String key = REDIS_DATABASE + ":" + REDIS_KEY_ORDER_ID + date;
Long increment = redisService.incr(key, 1);
return date + String.format("%02d", order.getSourceType()) +
String.format("%02d", order.getPayType()) +
String.format("%06d", increment);
}
6.2 库存管理机制
- 预占库存:下单时锁定库存(lock_stock)
- 真实扣减:支付成功后扣减真实库存(stock)
- 库存释放:订单取消时释放锁定库存
6.3 优惠计算策略
- 促销优惠:单品促销、打折优惠、满减优惠
- 优惠券分摊:按商品价格比例分摊优惠金额
- 积分抵扣:根据积分规则计算抵扣金额
7. 异常处理机制
// 统一异常处理
public static void fail(String message) {
throw new ApiException(message);
}
// 业务校验示例
if (!hasStock(cartPromotionItemList)) {
Asserts.fail("库存不足,无法下单");
}
if (updateCount == 0) {
Asserts.fail("订单不存在或订单状态不是未支付!");
}
设计亮点
- 完整的订单生命周期管理:从生成到完成的全流程覆盖
- 灵活的促销体系:支持多种促销方式和优惠券类型
- 可靠的库存控制:预占机制防止超卖
- 高效的批量操作:支持批量发货、关闭等管理功能
- 完善的日志记录:操作历史便于追踪和审计
- 良好的扩展性:通过配置化支持不同的业务场景
这套订单系统设计考虑了电商场景的典型需求,通过状态机、事务控制、异步处理等技术手段,确保了订单处理的可靠性、一致性和性能。
更多推荐




所有评论(0)