一、系统架构设计 订单状态追踪是生鲜电商系统的核心功能之一,需要实现从下单到配送完成的全程可视化。以下是实现方案: 1.微服务架构 -订单服务:处理订单创建、状态变更 -仓储服务:管理商品出库、分拣 -配送服务:调度骑手、跟踪配送进度 -通知服务:推送状态变更消息 -A
一、系统架构设计
订单状态追踪是生鲜电商系统的核心功能之一,需要实现从下单到配送完成的全程可视化。以下是实现方案:
1. 微服务架构
- 订单服务:处理订单创建、状态变更
- 仓储服务:管理商品出库、分拣
- 配送服务:调度骑手、跟踪配送进度
- 通知服务:推送状态变更消息
- API网关:统一对外提供接口
2. 数据库设计
```sql
-- 订单主表
CREATE TABLE orders (
order_id VARCHAR(32) PRIMARY KEY,
user_id VARCHAR(32) NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT pending,
create_time DATETIME NOT NULL,
update_time DATETIME NOT NULL,
delivery_address TEXT NOT NULL,
delivery_time_slot VARCHAR(50) NOT NULL
);
-- 订单状态变更历史表
CREATE TABLE order_status_history (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
order_id VARCHAR(32) NOT NULL,
status VARCHAR(20) NOT NULL,
status_desc VARCHAR(100),
operator VARCHAR(50),
operator_type VARCHAR(20) COMMENT user/system/courier,
create_time DATETIME NOT NULL,
FOREIGN KEY (order_id) REFERENCES orders(order_id)
);
-- 配送位置表
CREATE TABLE delivery_locations (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
order_id VARCHAR(32) NOT NULL,
longitude DECIMAL(10,6) NOT NULL,
latitude DECIMAL(10,6) NOT NULL,
address VARCHAR(200),
event_type VARCHAR(20) COMMENT pickup/enroute/arrived/completed,
create_time DATETIME NOT NULL,
FOREIGN KEY (order_id) REFERENCES orders(order_id)
);
```
二、核心功能实现
1. 订单状态定义与流转
```java
public enum OrderStatus {
PENDING("待支付"),
PAID("已支付"),
PROCESSING("处理中"),
PACKING("打包中"),
DELIVERING("配送中"),
COMPLETED("已完成"),
CANCELLED("已取消"),
REFUNDED("已退款");
private String description;
// 状态流转规则
public static boolean canTransition(OrderStatus from, OrderStatus to) {
switch (from) {
case PENDING:
return to == PAID || to == CANCELLED;
case PAID:
return to == PROCESSING || to == CANCELLED;
case PROCESSING:
return to == PACKING || to == CANCELLED;
case PACKING:
return to == DELIVERING || to == CANCELLED;
case DELIVERING:
return to == COMPLETED || to == CANCELLED;
default:
return false;
}
}
}
```
2. 状态变更服务实现
```java
@Service
public class OrderStatusService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private OrderStatusHistoryRepository historyRepository;
@Transactional
public boolean updateOrderStatus(String orderId, OrderStatus newStatus, String operator) {
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new RuntimeException("Order not found"));
if (!OrderStatus.canTransition(order.getStatus(), newStatus)) {
throw new IllegalStateException("Invalid status transition");
}
// 更新订单状态
order.setStatus(newStatus);
order.setUpdateTime(LocalDateTime.now());
orderRepository.save(order);
// 记录状态变更历史
OrderStatusHistory history = new OrderStatusHistory();
history.setOrderId(orderId);
history.setStatus(newStatus);
history.setStatusDesc(getStatusDescription(newStatus));
history.setOperator(operator);
history.setOperatorType(operator.startsWith("user_") ? "user" : "system");
history.setCreateTime(LocalDateTime.now());
historyRepository.save(history);
// 触发相应事件
publishStatusChangeEvent(order, newStatus);
return true;
}
private void publishStatusChangeEvent(Order order, OrderStatus newStatus) {
// 根据状态变更发布不同事件
switch (newStatus) {
case PAID:
// 触发库存预留
break;
case DELIVERING:
// 分配骑手并开始追踪
startDeliveryTracking(order);
break;
case COMPLETED:
// 完成订单处理
break;
}
}
private void startDeliveryTracking(Order order) {
// 调用配送服务API分配骑手
// 启动定时任务更新骑手位置
}
}
```
3. 实时位置追踪实现
```java
@Service
public class DeliveryTrackingService {
@Autowired
private DeliveryLocationRepository locationRepository;
@Autowired
private WebSocketHandler webSocketHandler;
// 骑手APP调用此接口更新位置
public void updateCourierLocation(String orderId, double longitude, double latitude, String eventType) {
DeliveryLocation location = new DeliveryLocation();
location.setOrderId(orderId);
location.setLongitude(longitude);
location.setLatitude(latitude);
location.setEventType(eventType);
location.setCreateTime(LocalDateTime.now());
// 保存位置信息
locationRepository.save(location);
// 通过WebSocket推送位置更新
webSocketHandler.sendLocationUpdate(orderId, location);
}
// 获取订单最新位置
public DeliveryLocation getLatestLocation(String orderId) {
return locationRepository.findTopByOrderIdOrderByCreateTimeDesc(orderId)
.orElse(null);
}
}
```
4. 前端实现要点
```javascript
// 订单状态追踪组件
class OrderTracker extends React.Component {
state = {
order: null,
statusHistory: [],
currentLocation: null,
estimatedTime: null
};
componentDidMount() {
this.loadOrderData();
this.setupWebSocket();
}
loadOrderData = async () => {
const orderId = this.props.orderId;
const [orderRes, historyRes] = await Promise.all([
api.getOrder(orderId),
api.getOrderStatusHistory(orderId)
]);
this.setState({
order: orderRes.data,
statusHistory: historyRes.data
});
if (orderRes.data.status === DELIVERING) {
this.loadCurrentLocation();
}
};
loadCurrentLocation = async () => {
const location = await api.getOrderLocation(this.props.orderId);
this.setState({ currentLocation: location.data });
};
setupWebSocket = () => {
const socket = new WebSocket(wss://api.dingdong.com/ws/orders);
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.orderId === this.props.orderId && data.type === location_update) {
this.setState({ currentLocation: data.location });
}
};
this.socket = socket;
};
renderStatusTimeline() {
return this.state.statusHistory.map((item, index) => (
{formatTime(item.createTime)}
{item.statusDesc}
{item.operator &&
{item.operator}
}
));
}
renderMap() {
if (!this.state.currentLocation) return null;
return (
预计送达时间: {this.state.estimatedTime || 计算中...}
);
}
render() {
if (!this.state.order) return
;
return (
订单号: {this.state.order.orderId}
当前状态:
{getStatusDescription(this.state.order.status)}
{this.renderMap()}
订单进度
{this.renderStatusTimeline()}
);
}
}
```
三、关键技术点
1. 实时位置追踪:
- 使用WebSocket实现骑手位置实时推送
- 结合GPS定位和地理围栏技术
- 前端使用地图API(如高德、Google Maps)展示位置
2. 状态机管理:
- 定义严格的状态流转规则
- 使用状态模式处理不同状态下的业务逻辑
3. 事件驱动架构:
- 使用Spring Event或消息队列(如RabbitMQ)解耦状态变更与后续处理
- 例如:订单支付后触发库存预留、配送分配等事件
4. 数据一致性保证:
- 使用数据库事务确保状态变更和历史记录的原子性
- 考虑最终一致性方案处理分布式环境下的数据同步
5. 通知系统:
- 短信/APP推送/站内信多渠道通知
- 关键节点(如配送出发、到达)自动触发通知
四、性能优化
1. 位置数据存储优化:
- 对历史位置数据进行分表或冷热分离
- 使用时空索引优化位置查询
2. 状态查询缓存:
- 对频繁查询的订单状态使用Redis缓存
- 设置合理的缓存过期策略
3. WebSocket连接管理:
- 实现连接心跳检测
- 连接断开时自动重连机制
4. 批量处理:
- 对位置更新等高频操作实现批量写入
五、扩展功能
1. 预计送达时间预测:
- 基于历史数据和实时交通状况的机器学习模型
- 动态调整ETA(Estimated Time of Arrival)
2. 异常状态处理:
- 配送延迟自动预警
- 客户可发起紧急联系骑手功能
3. 多端同步:
- 微信小程序、APP、Web多端状态实时同步
- 离线状态下的本地缓存与同步机制
4. 数据分析:
- 订单履约率分析
- 各环节耗时统计
- 状态变更热点分析
通过以上实现方案,叮咚买菜系统可以提供从下单到配送的全程可视化追踪,提升用户体验和运营效率。