订单状态流转 — 测试指南
本文档面向测试人员和项目经理,描述订单系统在状态重构后的全部业务行为。
如有疑问请对照 specs/006-orderstate/spec.md 原始需求文档。
一、背景
系统支持三种订单类型,每种类型有不同的参与角色和完成方式:
| 订单类型 |
谁送餐 |
谁付钱 |
谁完成订单 |
| 外送 (type=0) |
骑手配送 |
在线支付 / 到付 |
骑手点"已送达" |
| 自取 (type=1) |
用户到店取 |
现金(线下收款) |
商家点"完成" 或 用户确认取餐 |
| 堂食 (type=2) |
商家端上 |
现金(线下收款) |
商家点"完成" |
二、状态字段说明
订单有 4 个独立的状态字段,各自跟踪不同的关注点:
2.1 订单状态 (state) — 订单的生命周期
| 值 |
状态名 |
含义 |
| 0 |
待处理 |
订单刚创建,等待商家接单 |
| 1 |
已接单 |
商家已接单,正在备餐 |
| 2 |
已出餐 |
商家备餐完成 |
| 3 |
已完成 |
订单结束(外送=骑手送达,自取=用户取餐,堂食=备餐完成) |
| 4 |
已取消 |
订单被取消 |
2.2 支付状态 (payStatus)
| 值 |
状态名 |
含义 |
| 0 |
未支付 |
等待付款 |
| 1 |
已支付 |
付款完成 |
| 2 |
已退款 |
退款完成 |
关键规则:
- 外送到付订单:下单时直接标记为"已支付"(1),骑手送货时收现金
- 自取/堂食现金订单:下单时为"未支付"(0),商家收款+点完成时才改为"已支付"(1)
- 在线支付订单:下单时为"未支付"(0),支付成功后改为"已支付"(1)
2.3 配送状态 (deliveryStatus) — 仅外送订单
| 值 |
状态名 |
含义 |
| null |
不适用 |
自取/堂食订单没有配送状态 |
| 0 |
待接单 |
等待骑手接单 |
| 1 |
骑手已接单 |
骑手已接单,还没取餐 |
| 2 |
配送中 |
骑手已取餐,正在送 |
| 3 |
已送达 |
骑手已送到 |
2.4 售后状态 (afterSaleStatus)
| 值 |
状态名 |
含义 |
| 0 |
无售后 |
正常订单 |
| 1 |
申请中 |
用户申请退款,等商家处理 |
| 2 |
退款中 |
商家同意,退款正在处理 |
| 3 |
已退款 |
退款完成 |
| 4 |
退款拒绝 |
商家拒绝退款 |
| 5 |
客服介入 |
客服正在处理 |
| 6 |
售后完成 |
售后流程结束 |
本次不实现售后/退款流程。afterSaleStatus 字段已预留,但退款相关操作(申请退款、同意退款、拒绝退款、客服介入等)暂未开发。
三、状态流转场景
3.1 外送 — 在线支付
用户下单 → 用户付款 → 商家接单 → 商家出餐 → 骑手接单 → 骑手取餐 → 骑手送达
state: 0 0 1 2 2 2 3
pay: 0 → 1 1 1 1 1 1
delivery: null null null 0 1 2 3
| 步骤 |
操作者 |
操作 |
state |
payStatus |
deliveryStatus |
| 1 |
系统 |
创建订单 |
0 |
0 |
null |
| 2 |
用户 |
在线支付 |
0 |
0→1 |
null |
| 3 |
商家 |
接单 |
0→1 |
1 |
null |
| 4 |
商家 |
出餐 |
1→2 |
1 |
0 |
| 5 |
骑手 |
接单 |
2 |
1 |
0→1 |
| 6 |
骑手 |
取餐出发 |
2 |
1 |
1→2 |
| 7 |
骑手 |
送达 |
2→3 |
1 |
2→3 |
3.2 外送 — 到付
与在线支付基本相同,唯一区别:下单时 payStatus 直接设为 1(已支付)
| 步骤 |
操作者 |
操作 |
state |
payStatus |
deliveryStatus |
| 1 |
系统 |
创建订单 |
0 |
1(直接已支付) |
null |
| 2 |
商家 |
接单 |
0→1 |
1 |
null |
| 3 |
商家 |
出餐 |
1→2 |
1 |
0 |
| 4 |
骑手 |
接单→取餐→送达 |
2→2→3 |
1 |
0→1→2→3 |
3.3 自取 — 现金
用户下单 → 商家接单 → 商家出餐 → 商家收款+完成(或用户确认取餐)
state: 0 1 2 3
pay: 0 0 0 1(商家收款时设为1)
delivery: 无 无 无 无
| 步骤 |
操作者 |
操作 |
state |
payStatus |
| 1 |
系统 |
创建订单 |
0 |
0 |
| 2 |
商家 |
接单 |
0→1 |
0 |
| 3 |
商家 |
出餐 |
1→2 |
0 |
| 4a |
商家 |
完成(收款+完成) |
2→3 |
0→1 |
| 4b |
用户 |
确认取餐(仅已支付时可用) |
2→3 |
1(不变) |
重要规则:用户"确认取餐"仅对已支付(payStatus=1)的自取订单有效。现金订单(payStatus=0)的用户无法自己确认取餐,只能等商家点"完成"。
3.4 堂食 — 现金
与自取流程完全一致,只是 type=2。
四、取消订单场景
4.1 用户取消
| 条件 |
state |
结果 |
| 商家未接单 |
state=0 |
state→4(已取消) |
| 商家已接单 |
state=1 或更高 |
不允许取消(需走退款流程) |
测试步骤:
- 用户下单(state=0)
- 用户点击"取消订单"
- 预期:订单变为"已取消"(state=4)
4.2 商家取消
| 条件 |
state |
结果 |
| 待处理或已接单 |
state=0 或 1 |
state→4(已取消) |
| 已出餐或之后 |
state=2 或更高 |
不允许取消 |
4.3 系统自动取消
| 场景 |
条件 |
结果 |
| 超时未接单 |
商家在规定时间内未接单 |
state→4 |
| 超时未完成 |
商家出餐后长时间未完成 |
state→3(自动完成) |
五、各端订单列表测试
5.1 用户端
接口:GET /system/userOrder/orderList
| Tab 名称 |
tab 参数 |
应出现的订单 |
不应出现的订单 |
| 待付款 |
unpaid |
外送未支付订单(payStatus=0, type=0) |
自取/堂食的未支付订单、已支付的外送订单 |
| 进行中 |
active |
所有正在进行的订单 |
已完成、已取消、有售后的订单 |
| 已完成 |
completed |
state=3 的订单 |
其他状态的订单 |
| 已取消 |
cancelled |
state=4 且无售后的订单 |
有售后的已取消订单 |
| 退款/售后 |
refund |
afterSaleStatus>0 的订单 |
正常订单 |
重点测试用例:
| # |
场景 |
预期结果 |
| 1 |
自取订单(type=1)刚创建,payStatus=0 |
应出现在"进行中"Tab,不应出现在"待付款"Tab |
| 2 |
堂食订单(type=2)刚创建,payStatus=0 |
同上,出现在"进行中",不在"待付款" |
| 3 |
外送订单(type=0)未支付 |
应出现在"待付款"Tab |
| 4 |
外送到付订单刚创建,payStatus=1 |
应出现在"进行中"Tab |
| 5 |
传入 type=1 筛选 |
只显示自取订单 |
| 6 |
不传 type |
显示所有类型的订单 |
5.2 商家端
接口:GET /system/orderShOprate/orderList
| Tab 名称 |
tab 参数 |
应出现的订单 |
| 待受理 |
pending |
state=0 且(已支付 OR 自取/堂食) |
| 待出餐 |
preparing |
state=1 |
| 已出餐 |
ready |
state=2 且无售后 |
| 已完成 |
completed |
state=3 且无售后 |
| 已取消 |
cancelled |
state=4 且无售后 |
| 退款/售后 |
refund |
有售后记录的订单 |
重点测试用例:
| # |
场景 |
预期结果 |
| 1 |
外送未支付订单(state=0, payStatus=0) |
不应出现在"待受理"(用户还没付款) |
| 2 |
自取订单刚创建(state=0, payStatus=0) |
应出现在"待受理"(现金线下收) |
| 3 |
外送到付订单(state=0, payStatus=1) |
应出现在"待受理" |
| 4 |
外送在线支付成功(state=0, payStatus=1) |
应出现在"待受理" |
| 5 |
商家接单后 |
订单从"待受理"移到"待出餐" |
| 6 |
商家出餐后 |
订单从"待出餐"移到"已出餐" |
5.3 骑手端
接口:GET /system/orderQsOprate/orderList
| Tab 名称 |
tab 参数 |
应出现的订单 |
| 新任务 |
newTask |
外送订单(type=0)、已出餐(state=2)、等待骑手(deliveryStatus=0)、无售后 |
| 待取货 |
toPickup |
当前骑手已接单(deliveryStatus=1)、无售后 |
| 配送中 |
delivering |
当前骑手正在配送(deliveryStatus=2)、无售后 |
| 已完成 |
completed |
当前骑手已完成的订单 |
| 已取消 |
cancelled |
当前骑手关联的已取消订单 |
| 退款/售后 |
refund |
当前骑手关联的有售后的订单 |
重点测试用例:
| # |
场景 |
预期结果 |
| 1 |
商家还没出餐(state=1)的外送订单 |
不应出现在"新任务"Tab |
| 2 |
自取订单(type=1) |
不应出现在骑手端任何Tab |
| 3 |
新任务列表排序 |
按距离从近到远排列(需要传入经纬度参数) |
| 4 |
其他骑手已接单的订单 |
不应出现在当前骑手的"新任务"中 |
六、用户端操作测试
6.1 确认取餐
接口:POST /system/userOrder/confirmPickup
| # |
前置条件 |
操作 |
预期结果 |
| 1 |
自取订单、已出餐(state=2)、已支付(payStatus=1) |
点击确认取餐 |
成功,state→3 |
| 2 |
自取订单、已出餐(state=2)、未支付(payStatus=0) |
点击确认取餐 |
失败,提示"订单未支付" |
| 3 |
外送订单(type=0) |
点击确认取餐 |
失败,提示"仅自取订单可确认取餐" |
| 4 |
堂食订单(type=2) |
点击确认取餐 |
失败,提示"仅自取订单可确认取餐" |
| 5 |
自取订单、待处理(state=0) |
点击确认取餐 |
失败,提示"当前订单状态不可确认取餐" |
| 6 |
自取订单、已接单(state=1) |
点击确认取餐 |
失败,提示"当前订单状态不可确认取餐" |
| 7 |
自取订单、已完成(state=3) |
点击确认取餐 |
失败,提示"当前订单状态不可确认取餐" |
| 8 |
别人的订单 |
点击确认取餐 |
失败,提示"订单不存在" |
6.2 取消订单
接口:POST /system/userOrder/cancelOrder
| # |
前置条件 |
操作 |
预期结果 |
| 1 |
任何类型、待处理(state=0) |
点击取消订单 |
成功,state→4 |
| 2 |
任何类型、已接单(state=1) |
点击取消订单 |
失败,提示"仅待处理状态的订单可取消" |
| 3 |
任何类型、已出餐(state=2) |
点击取消订单 |
失败,同上 |
| 4 |
别人的订单 |
点击取消订单 |
失败,提示"订单不存在" |
| 5 |
自取订单(state=0) |
点击取消 |
成功 |
| 6 |
堂食订单(state=0) |
点击取消 |
成功 |
| 7 |
外送订单(state=0) |
点击取消 |
成功 |
七、商家端操作测试
| 操作 |
接口 |
前置条件 |
预期结果 |
| 接单 |
POST /system/orderShOprate/acceptOrder |
state=0 |
state→1 |
| 出餐 |
GET /system/orderShOprate/dispatchOrder |
state=1 |
state→2;外送额外设 deliveryStatus=0 |
| 完成(自取/堂食) |
POST /system/orderShOprate/completeOrder |
type=1或2,state=2 |
state→3,payStatus→1 |
| 取消 |
POST /system/orderShOprate/cancelOrder |
state=0或1 |
state→4 |
重点测试用例:
| # |
场景 |
预期结果 |
| 1 |
商家对外送订单出餐 |
state→2,同时 deliveryStatus=0(等待骑手) |
| 2 |
商家对自取订单出餐 |
state→2,deliveryStatus 保持 null |
| 3 |
商家对自取订单点"完成" |
state→3,payStatus→1(收款+完成一步到位) |
| 4 |
商家对外送订单点"完成" |
不允许(外送订单由骑手完成) |
| 5 |
商家对已出餐(state=2)的订单接单 |
不允许(只能对 state=0 的订单接单) |
八、骑手端操作测试
| 操作 |
接口 |
前置条件 |
预期结果 |
| 接单 |
POST /system/orderQsOprate/acceptOrder |
type=0, deliveryStatus=0, afterSaleStatus=0 |
deliveryStatus→1,绑定骑手ID |
| 取餐出发 |
POST /system/orderQsOprate/pickupOrder |
deliveryStatus=1, afterSaleStatus=0 |
deliveryStatus→2 |
| 送达 |
POST /system/orderQsOprate/deliverOrder |
deliveryStatus=2 |
deliveryStatus→3,state→3 |
重点测试用例:
| # |
场景 |
预期结果 |
| 1 |
骑手对自取订单(type=1)接单 |
不允许(只有外送订单需要骑手) |
| 2 |
骑手对已有人接的订单接单 |
不允许(防止重复接单) |
| 3 |
骑手送达后 |
state=3, deliveryStatus=3,订单在骑手端移到"已完成"Tab |
| 4 |
骑手接单时有活跃退款(afterSaleStatus>0) |
允许操作但需提示 |
九、用户看到的文字
用户端页面不直接显示 state 数字,而是根据状态组合显示中文文字。
9.1 外送订单 (type=0) 用户看到的
| 用户看到 |
对应的订单状态 |
| 待支付 |
还没付款(payStatus=0) |
| 商家已接单 |
已付款,等商家处理(state=0或1) |
| 配送中 |
商家出餐,骑手在送(state=2, deliveryStatus=0/1/2) |
| 已送达 |
骑手送到(state=2, deliveryStatus=3) |
| 已完成 |
订单结束(state=3) |
| 已取消 |
订单取消(state=4) |
| 退款中/已退款 |
有退款处理(afterSaleStatus>0) |
9.2 自取订单 (type=1) 用户看到的
| 用户看到 |
对应的订单状态 |
| 待支付 |
还没付款(payStatus=0) |
| 商家已接单 |
等商家处理(state=0或1) |
| 待取餐 |
商家出餐了,等用户去取(state=2) |
| 已完成 |
订单结束(state=3) |
| 已取消 |
订单取消(state=4) |
9.3 堂食订单 (type=2) 用户看到的
| 用户看到 |
对应的订单状态 |
| 待支付 |
还没付款(payStatus=0) |
| 商家已接单 |
等商家处理(state=0或1) |
| 备餐完成 |
商家出餐了(state=2) |
| 已完成 |
订单结束(state=3) |
| 已取消 |
订单取消(state=4) |
9.4 商家端订单卡片显示
外送订单:
| 条件 |
显示 |
颜色建议 |
| state=0, payStatus=0 |
待支付 |
灰色 |
| state=0, payStatus=1 |
待接单 |
橙色 |
| state=1 |
制作中 |
蓝色 |
| state=2, deliveryStatus=0/1 |
待骑手取餐 |
蓝色 |
| state=2, deliveryStatus=2 |
配送中 |
蓝色 |
| state=2, deliveryStatus=3 |
已送达 |
绿色 |
| state=3 |
已完成 |
灰色 |
| state=4 |
已取消 |
红色 |
自取/堂食订单:
| 条件 |
显示 |
颜色建议 |
| state=0 |
待接单 |
橙色 |
| state=1 |
制作中 |
蓝色 |
| state=2 |
备餐完成 |
橙色 |
| state=3 |
已完成 |
灰色 |
| state=4 |
已取消 |
红色 |
售后状态覆盖规则:当 afterSaleStatus>0 时,不管上面的规则,统一显示售后状态文字(退款申请中/退款中/已退款/退款已拒绝),优先级最高。
十、边界场景和注意事项
| # |
场景 |
说明 |
| 1 |
已取消的订单应出现在哪个Tab |
三个端都有独立的"已取消"Tab 承接 |
| 2 |
自取/堂食订单的 deliveryStatus |
始终为 null,不应出现在骑手端 |
| 3 |
外送订单商家出餐后 |
deliveryStatus 应自动设为 0(等待骑手),不是 null |
| 4 |
现金自取订单的支付 |
下单时 payStatus=0,只有商家点"完成"时才变为 1 |
| 5 |
到付外送订单的支付 |
下单时 payStatus=1(直接确认支付方式) |
| 6 |
用户确认取餐前提 |
必须是自取(type=1) + 已支付(payStatus=1) + 已出餐(state=2) |
| 7 |
退款流程 |
本次不实现,afterSaleStatus 字段已预留但无操作入口 |
| 8 |
旧接口 |
旧的订单列表接口保留不删,但不再维护,前端应切换到新接口 |
| 9 |
平台管理端 |
订单列表页需从单状态下拉改为四个独立下拉筛选(state/payStatus/deliveryStatus/afterSaleStatus) |
| 10 |
定时任务 |
商家出餐后超时未完成的订单,系统自动设为已完成(state=3) |
十一、实现状态总览
| 功能 |
状态 |
说明 |
| 订单创建(四字段初始化) |
✅ 已实现 |
UserOrderController.createOrder |
| 用户端订单列表 |
✅ 已实现 |
UserOrderController.orderList |
| 商家端订单列表 |
✅ 已实现 |
PosOrderShOprateController.orderList |
| 骑手端订单列表 |
✅ 已实现 |
PosOrderQsOprateController.orderList |
| 用户确认取餐 |
✅ 已实现 |
UserOrderController.confirmPickup |
| 用户取消订单(新) |
✅ 已实现 |
UserOrderController.cancelOrder |
| 用户取消订单(旧) |
⚠️ 已废弃 |
OrderAppealController.userCancelpOrder 已注释 |
| 商家接单/出餐/完成/取消 |
✅ 已实现 |
PosOrderShOprateController |
| 骑手接单/取餐/送达 |
✅ 已实现 |
PosOrderQsOprateController |
| 支付回调更新 payStatus |
✅ 已实现 |
PayController |
| 定时任务自动完成 |
待确认 |
TestTask.java |
| 用户申请退款 |
❌ 未实现 |
留待接入在线支付后开发 |
| 商家同意/拒绝退款 |
❌ 未实现 |
留待接入在线支付后开发 |
| 客服介入 |
❌ 未实现 |
留待接入在线支付后开发 |
| 平台管理端四字段筛选 |
❌ 未实现 |
foodie-admin-vue 待改造 |