本文目录导读:

我来详细解释Java订单状态流转的典型案例。
订单状态枚举定义
public enum OrderStatus {
// 正常流转状态
PENDING_PAYMENT(0, "待支付"),
PENDING_SHIPMENT(1, "待发货"),
SHIPPED(2, "已发货"),
DELIVERED(3, "已送达"),
COMPLETED(4, "已完成"),
// 异常状态
CANCELLED(-1, "已取消"),
REFUNDING(-2, "退款中"),
REFUNDED(-3, "已退款");
private int code;
private String desc;
// 构造方法、getter方法
OrderStatus(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() { return code; }
public String getDesc() { return desc; }
}
状态流转规则定义
@Component
public class OrderStateMachine {
// 定义状态流转映射
private static final Map<OrderStatus, List<OrderStatus>> TRANSITIONS = new HashMap<>();
static {
// 正常正向流转
TRANSITIONS.put(OrderStatus.PENDING_PAYMENT, Arrays.asList(
OrderStatus.PENDING_SHIPMENT, // 支付成功
OrderStatus.CANCELLED // 取消订单
));
TRANSITIONS.put(OrderStatus.PENDING_SHIPMENT, Arrays.asList(
OrderStatus.SHIPPED, // 发货
OrderStatus.CANCELLED // 取消订单(未发货前)
));
TRANSITIONS.put(OrderStatus.SHIPPED, Arrays.asList(
OrderStatus.DELIVERED, // 确认收货
OrderStatus.REFUNDING // 申请退款
));
TRANSITIONS.put(OrderStatus.DELIVERED, Arrays.asList(
OrderStatus.COMPLETED, // 自动/手动完成
OrderStatus.REFUNDING // 申请退款
));
TRANSITIONS.put(OrderStatus.COMPLETED, Arrays.asList(
OrderStatus.REFUNDING // 售后退款
));
// 退款状态流转
TRANSITIONS.put(OrderStatus.REFUNDING, Arrays.asList(
OrderStatus.REFUNDED, // 退款成功
OrderStatus.SHIPPED // 取消退款(恢复之前状态)
));
}
/**
* 检查状态是否可以流转
*/
public boolean canTransition(OrderStatus current, OrderStatus target) {
List<OrderStatus> allowed = TRANSITIONS.get(current);
return allowed != null && allowed.contains(target);
}
/**
* 获取允许的下一个状态
*/
public List<OrderStatus> getAllowedTransitions(OrderStatus current) {
return TRANSITIONS.getOrDefault(current, Collections.emptyList());
}
}
订单实体类
@Entity
@Table(name = "orders")
public class Order {
@Id
private Long orderId;
@Enumerated(EnumType.STRING)
private OrderStatus status;
private BigDecimal totalAmount;
private Long userId;
private String orderNo;
@Temporal(TemporalType.TIMESTAMP)
private Date createTime;
@Temporal(TemporalType.TIMESTAMP)
private Date updateTime;
// 状态变更记录
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderStatusLog> statusLogs;
// getter/setter方法
}
状态变更日志
@Entity
@Table(name = "order_status_log")
public class OrderStatusLog {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "order_id")
private Order order;
@Enumerated(EnumType.STRING)
private OrderStatus fromStatus;
@Enumerated(EnumType.STRING)
private OrderStatus toStatus;
private String operator; // 操作人
private String remark; // 备注
@Temporal(TemporalType.TIMESTAMP)
private Date operateTime;
// getter/setter方法
}
订单服务实现
@Service
@Slf4j
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private OrderStateMachine stateMachine;
@Autowired
private OrderStatusLogRepository logRepository;
@Transactional
public void updateOrderStatus(Long orderId, OrderStatus targetStatus,
String operator, String remark) {
// 1. 查询订单
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new RuntimeException("订单不存在"));
OrderStatus currentStatus = order.getStatus();
// 2. 检查状态是否允许流转
if (!stateMachine.canTransition(currentStatus, targetStatus)) {
throw new IllegalStateException(
String.format("不允许的状态流转: %s -> %s",
currentStatus.getDesc(), targetStatus.getDesc()));
}
// 3. 执行状态变更
OrderStatus previousStatus = order.getStatus();
order.setStatus(targetStatus);
order.setUpdateTime(new Date());
// 4. 保存订单
orderRepository.save(order);
// 5. 记录状态变更日志
OrderStatusLog log = new OrderStatusLog();
log.setOrder(order);
log.setFromStatus(previousStatus);
log.setToStatus(targetStatus);
log.setOperator(operator);
log.setRemark(remark);
log.setOperateTime(new Date());
logRepository.save(log);
log.info("订单 {} 状态变更: {} -> {}",
orderId, previousStatus.getDesc(), targetStatus.getDesc());
}
/**
* 支付成功处理
*/
@Transactional
public void handlePayment(Long orderId, String operator) {
updateOrderStatus(orderId, OrderStatus.PENDING_SHIPMENT,
operator, "支付成功");
// 其他业务逻辑:发送通知、更新库存等
}
/**
* 取消订单
*/
@Transactional
public void cancelOrder(Long orderId, String operator, String reason) {
updateOrderStatus(orderId, OrderStatus.CANCELLED,
operator, "取消订单:" + reason);
// 其他业务逻辑:退款处理、释放库存等
}
}
状态流转图(Mermaid)
stateDiagram-v2
[*] --> 待支付
待支付 --> 待发货 : 支付成功
待支付 --> 已取消 : 取消订单
待发货 --> 已发货 : 商家发货
待发货 --> 已取消 : 取消订单
已发货 --> 已送达 : 确认收货
已发货 --> 退款中 : 申请退款
已送达 --> 已完成 : 自动/手动完成
已送达 --> 退款中 : 申请退款
已完成 --> 退款中 : 售后申请
退款中 --> 已退款 : 退款成功
退款中 --> 已发货 : 取消退款
退款中 --> 已送达 : 取消退款
使用示例
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Autowired
private OrderService orderService;
/**
* 支付回调处理
*/
@PostMapping("/{orderId}/pay")
public Result<Void> handlePayment(@PathVariable Long orderId) {
orderService.handlePayment(orderId, "系统");
return Result.success();
}
/**
* 取消订单
*/
@PostMapping("/{orderId}/cancel")
public Result<Void> cancelOrder(@PathVariable Long orderId,
@RequestParam String reason) {
orderService.cancelOrder(orderId, "用户", reason);
return Result.success();
}
/**
* 查询订单状态
*/
@GetMapping("/{orderId}/status")
public Result<OrderStatusInfo> getStatus(@PathVariable Long orderId) {
Order order = orderService.findOrder(orderId);
OrderStatusInfo info = new OrderStatusInfo();
info.setCurrentStatus(order.getStatus());
info.setAllowedTransitions(
stateMachine.getAllowedTransitions(order.getStatus()));
return Result.success(info);
}
}
关键设计要点
- 状态不可逆:正常流转一般不允许回退(除了退款取消)
- 日志完整:每次状态变更需记录完整日志
- 事务控制:状态变更需在事务中执行
- 原子操作:状态变更和相关业务操作要一起成功或失败
- 幂等性:防止重复操作导致状态错误
这样的设计保证了订单状态的正确流转,同时便于追踪和审计。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播