一、功能概述
订单状态追踪是生鲜电商系统中的核心功能之一,它允许用户实时查看订单从下单到配送完成的整个生命周期状态,提升用户体验和信任度。
二、系统架构设计
1. 前端实现
- 订单详情页:展示订单当前状态和历史状态变更记录
- 状态时间轴:可视化展示订单流程(下单→支付→拣货→打包→配送→完成)
- 实时推送:通过WebSocket或长轮询实现状态变更实时通知
- 地图追踪:集成地图API展示配送员实时位置(可选)
2. 后端实现
- 状态机设计:定义订单状态流转规则
- 状态变更服务:处理状态变更逻辑和通知
- API接口:提供订单状态查询能力
- 消息队列:异步处理状态变更相关操作
三、核心功能实现
1. 订单状态定义
```java
public enum OrderStatus {
PENDING_PAYMENT("待支付"),
PAID("已支付"),
PROCESSING("处理中"),
PICKING("拣货中"),
PACKING("打包中"),
SHIPPED("已发货"),
DELIVERING("配送中"),
DELIVERED("已送达"),
COMPLETED("已完成"),
CANCELLED("已取消"),
REFUNDED("已退款");
private String description;
// 构造函数和getter
}
```
2. 状态流转规则
- 待支付 → 已支付(支付成功)
- 已支付 → 处理中(开始处理订单)
- 处理中 → 拣货中(开始拣货)
- 拣货中 → 打包中(拣货完成)
- 打包中 → 已发货(打包完成)
- 已发货 → 配送中(分配配送员)
- 配送中 → 已送达(配送完成)
- 已送达 → 已完成(用户确认收货)
3. 状态变更服务实现
```java
@Service
public class OrderStatusService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private OrderStatusHistoryRepository historyRepository;
@Autowired
private NotificationService notificationService;
@Transactional
public void updateOrderStatus(Long orderId, OrderStatus newStatus, String operator) {
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new RuntimeException("订单不存在"));
// 验证状态流转是否合法
validateStatusTransition(order.getStatus(), newStatus);
// 更新订单状态
order.setStatus(newStatus);
order.setUpdateTime(LocalDateTime.now());
orderRepository.save(order);
// 记录状态变更历史
OrderStatusHistory history = new OrderStatusHistory();
history.setOrderId(orderId);
history.setBeforeStatus(order.getStatus());
history.setAfterStatus(newStatus);
history.setOperator(operator);
history.setCreateTime(LocalDateTime.now());
historyRepository.save(history);
// 发送通知
notificationService.sendStatusChangeNotification(order, newStatus);
}
private void validateStatusTransition(OrderStatus current, OrderStatus newStatus) {
// 实现状态流转验证逻辑
// 例如:已完成的订单不能再次变更状态
if (current == OrderStatus.COMPLETED && newStatus != OrderStatus.COMPLETED) {
throw new IllegalStateException("已完成订单不能变更状态");
}
// 其他验证规则...
}
}
```
4. 状态历史记录查询
```java
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Autowired
private OrderStatusHistoryRepository historyRepository;
@GetMapping("/{orderId}/status-history")
public List getStatusHistory(@PathVariable Long orderId) {
return historyRepository.findByOrderIdOrderByCreateTimeDesc(orderId)
.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
}
private OrderStatusHistoryDTO convertToDTO(OrderStatusHistory history) {
// 转换逻辑
}
}
```
四、实时通知实现
1. WebSocket实现方案
```java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}
@Service
public class NotificationService {
@Autowired
private SimpMessagingTemplate messagingTemplate;
public void sendStatusChangeNotification(Long orderId, OrderStatus newStatus) {
OrderStatusNotification notification = new OrderStatusNotification(
orderId,
newStatus,
LocalDateTime.now()
);
messagingTemplate.convertAndSend(
"/topic/orders/" + orderId + "/status",
notification
);
}
}
```
2. 前端WebSocket连接
```javascript
const socket = new SockJS(/ws);
const stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
const orderId = 12345; // 实际从页面获取
stompClient.subscribe(`/topic/orders/${orderId}/status`, function(message) {
const notification = JSON.parse(message.body);
updateOrderStatusUI(notification);
});
});
```
五、数据库设计
1. 订单表(orders)
```sql
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(32) NOT NULL UNIQUE,
user_id BIGINT NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time DATETIME NOT NULL,
update_time DATETIME NOT NULL,
-- 其他字段...
);
```
2. 订单状态历史表(order_status_history)
```sql
CREATE TABLE order_status_history (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_id BIGINT NOT NULL,
before_status VARCHAR(20) NOT NULL,
after_status VARCHAR(20) NOT NULL,
operator VARCHAR(50), -- 操作人(系统/用户/配送员)
create_time DATETIME NOT NULL,
FOREIGN KEY (order_id) REFERENCES orders(id)
);
```
六、扩展功能考虑
1. 异常状态处理:
- 超时未支付自动取消
- 配送异常状态处理
- 用户主动取消流程
2. 多端同步:
- 确保APP、小程序、H5等各端状态同步
3. 性能优化:
- 状态变更频繁时的缓存策略
- 高并发场景下的数据库优化
4. 国际化:
- 多语言状态描述支持
七、测试要点
1. 正常状态流转测试
2. 异常状态处理测试
3. 并发状态变更测试
4. 通知机制可靠性测试
5. 历史记录完整性测试
通过以上实现,叮咚买菜系统可以为用户提供清晰、实时的订单状态追踪体验,增强用户对平台的信任度和满意度。