苍穹外卖订单状态流转设计:从下单到完成的全链路解析

在餐饮外卖系统中,订单状态流转是核心业务逻辑之一。清晰的状态流转不仅能保证业务的正确性,还能提升用户体验和管理效率。本文将结合苍穹外卖项目的订单实体设计,详细解析订单状态的流转规则、对应接口及状态约束。


一、订单状态与支付状态定义

首先,我们明确订单实体中定义的核心状态常量,这是状态流转的基础。

1. 订单状态

状态值 常量名 描述
1 PENDING_PAYMENT 待付款
2 TO_BE_CONFIRMED 待接单
3 CONFIRMED 已接单
4 DELIVERY_IN_PROGRESS 派送中
5 COMPLETED 已完成
6 CANCELLED 已取消

2. 支付状态

状态值 常量名 描述
0 UN_PAID 未支付
1 PAID 已支付
2 REFUND 退款

二、订单状态流转图

为了更直观地展示状态流转,我们使用Mermaid流程图绘制全链路状态转换关系:

stateDiagram-v2[*] --> 待付款: 用户下单(POST)待付款 --> 待接单: 用户支付(PUT)<br/>支付状态→已支付待付款 --> 已取消: 用户取消<br/>支付状态→未支付待接单 --> 已接单: 管理端接单待接单 --> 已取消: 管理端拒单/用户取消<br/>支付状态→退款已接单 --> 派送中: 管理端派送派送中 --> 已完成: 管理端完成已取消 --> [*]已完成 --> [*]

三、详细状态流转说明

接下来,我们逐一解析每个状态的流转规则、对应接口及操作约束。

1. 初始状态:用户下单 → 待付款

  • 触发接口:用户端 POST /user/order/submit(下单接口)
  • 状态变更:订单状态 → 1 待付款,支付状态 → 0 未支付
  • 操作约束
    • 必须选择收货地址(关联address_book_id);
    • 购物车不能为空(需生成order_detail明细);
    • 订单号number需全局唯一(建议使用时间戳+随机数生成);
    • 下单时间order_time自动设置为当前时间。

2. 待付款状态流转

待付款是订单的第一个中间状态,用户可以选择支付或取消订单。

(1)用户支付 → 待接单

  • 触发接口:用户端 PUT /user/order/payment(支付接口)
  • 状态变更:订单状态 → 2 待接单,支付状态 → 1 已支付
  • 操作约束
    • 仅允许在待付款状态下操作:若订单已支付或取消,需抛出业务异常;
    • 支付成功后需更新checkout_time(结账时间)为当前时间;
    • 若对接微信/支付宝支付,需验证支付回调的签名和金额一致性。

(2)用户取消 → 已取消

  • 触发接口:用户端 PUT /user/order/cancel/{id}(取消订单接口)
  • 状态变更:订单状态 → 6 已取消,支付状态保持 0 未支付
  • 操作约束
    • 仅允许在待付款状态下操作:若用户已支付,需走“待接单状态下的取消”流程(涉及退款);
    • 需记录cancel_reason(取消原因)和cancel_time(取消时间)。

3. 待接单状态流转

待接单是用户支付成功后、商家接单前的状态,商家可以选择接单或拒单,用户也可以主动取消。

(1)管理端接单 → 已接单

  • 触发接口:管理端 PUT /admin/order/confirm/{id}(接单接口)
  • 状态变更:订单状态 → 3 已接单
  • 操作约束
    • 仅允许在待接单状态下操作:若订单已被接单、取消或完成,需抛出业务异常;
    • 接单后可设置estimated_delivery_time(预计送达时间)。

(2)管理端拒单 → 已取消

  • 触发接口:管理端 PUT /admin/order/rejection/{id}(拒单接口)
  • 状态变更:订单状态 → 6 已取消,支付状态 → 2 退款
  • 操作约束
    • 仅允许在待接单状态下操作
    • 必须填写拒单原因rejection_reason字段不能为空;
    • 需触发退款逻辑(若对接第三方支付,需调用退款接口)。

(3)用户取消 → 已取消

  • 触发接口:用户端 PUT /user/order/cancel/{id}(取消订单接口)
  • 状态变更:订单状态 → 6 已取消,支付状态 → 2 退款
  • 操作约束
    • 仅允许在待接单状态下操作:若商家已接单,用户无法直接取消,需联系商家处理;
    • 需记录cancel_reasoncancel_time
    • 需触发退款逻辑。

4. 已接单状态流转

已接单是商家确认订单后、开始派送前的状态,商家需点击“派送”推进状态。

  • 触发接口:管理端 PUT /admin/order/delivery/{id}(派送接口)
  • 状态变更:订单状态 → 4 派送中
  • 操作约束
    • 仅允许在已接单状态下操作
    • delivery_status(配送状态)为“选择具体时间”,需验证estimated_delivery_time是否已设置。

5. 派送中状态流转

派送中是订单配送的最后一个中间状态,送达后需点击“完成”结束订单。

  • 触发接口:管理端 PUT /admin/order/complete/{id}(完成订单接口)
  • 状态变更:订单状态 → 5 已完成
  • 操作约束
    • 仅允许在派送中状态下操作
    • 需更新delivery_time(送达时间)为当前时间;
    • 已完成状态为终态,不可再进行任何状态变更操作。

6. 已取消/已完成:终态

  • 已取消已完成均为订单的终态,不再允许任何状态变更操作;
  • 终态订单仅支持查询功能,不支持修改、取消、支付等操作。

四、总结

苍穹外卖的订单状态流转设计遵循了“单向流转、终态不可变”的原则,通过清晰的状态约束保证了业务的正确性:

  1. 用户端负责下单、支付、取消(待付款/待接单状态);
  2. 管理端负责接单、拒单、派送、完成;
  3. 支付状态与订单状态联动,待接单及之后的取消/拒单需触发退款。

这种设计既保证了用户体验(用户可在商家接单前自由取消),又规范了商家操作(状态约束避免误操作),是餐饮外卖系统的经典状态流转方案。