|
|
@@ -0,0 +1,684 @@
|
|
|
+# 006 - 订单状态流转设计(美团方案)
|
|
|
+
|
|
|
+## 背景
|
|
|
+
|
|
|
+系统新增自取订单(type=1)和堂食订单(type=2)后,订单不再需要骑手参与。现有 `state` 字段将支付状态、订单状态、配送状态、退款状态全部混在一起,导致自取/堂食订单无法直接复用。
|
|
|
+
|
|
|
+### 旧状态定义(待废弃)
|
|
|
+
|
|
|
+| 旧 state | 含义 | 类别 |
|
|
|
+|----------|------|------|
|
|
|
+| 0 | 未支付 | 支付 |
|
|
|
+| 1 | 已付款 | 支付 |
|
|
|
+| 2 | 已接单 | 订单 |
|
|
|
+| 3 | 骑手接单 | 配送 |
|
|
|
+| 4 | 配送中 | 配送 |
|
|
|
+| 5 | 已完成 | 订单 |
|
|
|
+| 6 | 申请退款 | 退款 |
|
|
|
+| 7 | 同意退款 | 退款 |
|
|
|
+| 8 | 拒绝退款 | 退款 |
|
|
|
+| 9 | 客服接入 | 退款 |
|
|
|
+| 10 | 作废 | 订单 |
|
|
|
+| 11 | 售后完成 | 退款 |
|
|
|
+| 12 | 送达 | 配送 |
|
|
|
+| 13 | 退款处理中 | 退款 |
|
|
|
+
|
|
|
+## 选定方案:全面重新设计,四字段分离
|
|
|
+
|
|
|
+参考美团做法,将原来混在 `state` 中的四种关注点拆成四个独立字段:
|
|
|
+
|
|
|
+- **state**:订单生命周期(所有类型共用)
|
|
|
+- **deliveryStatus**:配送追踪(仅外送订单使用)
|
|
|
+- **payStatus**:支付状态(所有类型共用)
|
|
|
+- **afterSaleStatus**:售后/退款状态(独立于订单状态,参考美团做法)
|
|
|
+
|
|
|
+同时废弃 `diningStatus` 字段,出餐动作由 `state` 状态变更表示。
|
|
|
+
|
|
|
+## 新字段定义
|
|
|
+
|
|
|
+### state(订单状态)— 重新编号
|
|
|
+
|
|
|
+| 新 state | 含义 | 谁触发 | 说明 |
|
|
|
+|----------|------|--------|------|
|
|
|
+| 0 | 待处理 | 系统创建 | 订单已创建,等待商家接单 |
|
|
|
+| 1 | 已接单 | 商家 | 商家已接单,备餐中 |
|
|
|
+| 2 | 已出餐 | 商家 | 商家出餐完成 |
|
|
|
+| 3 | 已完成 | 系统 | 外送:骑手送达;自取:用户确认取餐;堂食:备餐完成 |
|
|
|
+| 4 | 已取消 | 系统/商家 | 作废/取消(全额退款、商家取消、系统超时取消) |
|
|
|
+
|
|
|
+state 只有 5 个值,只跟踪订单的核心生命周期。
|
|
|
+
|
|
|
+### deliveryStatus(配送状态)— 仅 type=0 外送订单
|
|
|
+
|
|
|
+| deliveryStatus | 含义 | 谁触发 |
|
|
|
+|----------------|------|--------|
|
|
|
+| 0 | 待接单 | 系统(商家出餐后设为0,等待骑手) |
|
|
|
+| 1 | 骑手已接单 | 骑手 |
|
|
|
+| 2 | 配送中 | 骑手(取餐出发) |
|
|
|
+| 3 | 已送达 | 骑手 |
|
|
|
+
|
|
|
+自取(type=1)和堂食(type=2)订单 `deliveryStatus` 为 NULL。
|
|
|
+
|
|
|
+### payStatus(支付状态)— 新增字段
|
|
|
+
|
|
|
+| payStatus | 含义 | 说明 |
|
|
|
+|-----------|------|------|
|
|
|
+| 0 | 未支付 | 订单刚创建,等待付款 |
|
|
|
+| 1 | 已支付 | 在线支付成功,或到付外送订单创建时直接设为1 |
|
|
|
+| 2 | 已退款 | 订单退款完成 |
|
|
|
+
|
|
|
+- **外送到付**(type=0, payType=1):创建时直接设为 `payStatus=1`(不需要等在线支付)
|
|
|
+- **自取/堂食现金**(type=1或2):创建时 `payStatus=0`,商家收款并完成订单时同步设为 `1`
|
|
|
+- **在线支付**(vnpay/zalopay/银行卡):创建时 `payStatus=0`,支付回调成功后改为 `1`
|
|
|
+- **退款完成**:`afterSaleStatus=3`(已退款)时,同步把 `payStatus` 改为 `2`
|
|
|
+
|
|
|
+> **设计决策**:自取/堂食现金订单 payStatus 在下单时为 0,商家收款+完成时才设为 1。原因:商家需要明确知道"现金是否已收到",收钱和完成是同一个动作。外送订单则不同,到付意味着骑手送货时收钱,所以创建时就确认支付方式。
|
|
|
+
|
|
|
+### afterSaleStatus(售后状态)— 新增字段,独立于订单状态
|
|
|
+
|
|
|
+参考美团做法:退款申请本身不改变订单状态,只有全额退款成功才将订单设为已取消。
|
|
|
+
|
|
|
+| afterSaleStatus | 含义 | 谁触发 | 说明 |
|
|
|
+|-----------------|------|--------|------|
|
|
|
+| 0 | 无售后 | - | 订单正常,无退款申请 |
|
|
|
+| 1 | 申请中 | 用户 | 用户发起退款申请,等待商家处理 |
|
|
|
+| 2 | 退款中 | 系统/商家 | 商家同意退款,退款正在处理 |
|
|
|
+| 3 | 已退款 | 系统 | 退款完成,全额退款时同步设 state=4 |
|
|
|
+| 4 | 退款拒绝 | 商家 | 商家拒绝退款,订单继续正常流转 |
|
|
|
+| 5 | 客服介入 | 客服 | 客服正在处理争议 |
|
|
|
+| 6 | 售后完成 | 系统 | 售后流程结束 |
|
|
|
+
|
|
|
+### 废弃字段
|
|
|
+
|
|
|
+- **diningStatus**:不再使用。"出餐"动作由 `state` 从 1 变为 2 表示。
|
|
|
+
|
|
|
+## 各类型状态流转
|
|
|
+
|
|
|
+```
|
|
|
+外送-在线支付 (type=0):
|
|
|
+ state: 0 → 1 → 2 → 3
|
|
|
+ deliveryStatus: 0 → 1 → 2 → 3
|
|
|
+ payStatus: 0 → 1(支付回调)
|
|
|
+ afterSaleStatus: 0(无售后时始终为0)
|
|
|
+ 骑手参与: 是(state 和 deliveryStatus 独立推进)
|
|
|
+ 完成触发: 骑手点"已送达"
|
|
|
+
|
|
|
+外送-到付 (type=0, payType=1):
|
|
|
+ state: 0 → 1 → 2 → 3
|
|
|
+ deliveryStatus: 0 → 1 → 2 → 3
|
|
|
+ payStatus: 1(创建时即确认,骑手送货时收现金)
|
|
|
+ afterSaleStatus: 0
|
|
|
+ 骑手参与: 是
|
|
|
+ 完成触发: 骑手点"已送达"
|
|
|
+
|
|
|
+自取-现金 (type=1):
|
|
|
+ state: 0 → 1 → 2 → 3
|
|
|
+ payStatus: 0 ──────────→ 1(商家收款+完成,同一操作)
|
|
|
+ afterSaleStatus: 0
|
|
|
+ 骑手参与: 否(用户到店自取)
|
|
|
+ deliveryStatus: 无
|
|
|
+ 完成触发: 商家点"完成"(收款+出餐)
|
|
|
+
|
|
|
+堂食-现金 (type=2):
|
|
|
+ state: 0 → 1 → 2 → 3
|
|
|
+ payStatus: 0 ──────────→ 1(商家收款+完成,同一操作)
|
|
|
+ afterSaleStatus: 0
|
|
|
+ 骑手参与: 否
|
|
|
+ deliveryStatus: 无
|
|
|
+ 完成触发: 商家点"完成"(收款+出餐)
|
|
|
+```
|
|
|
+
|
|
|
+## 售后/退款流转(所有类型,独立状态机)
|
|
|
+
|
|
|
+```
|
|
|
+afterSaleStatus: 0(无售后) → 1(申请中) → 2(退款中) → 3(已退款)
|
|
|
+ → 4(退款拒绝) → 5(客服介入) → 6(售后完成)
|
|
|
+```
|
|
|
+
|
|
|
+### 售后与订单状态的联动规则(参考美团)
|
|
|
+
|
|
|
+| 售后动作 | afterSaleStatus | state | payStatus | deliveryStatus | 骑手行为 |
|
|
|
+|---------|-----------------|-------|-----------|----------------|---------|
|
|
|
+| 用户申请退款 | → 1(申请中) | **不变** | 不变 | 不变 | **继续配送** |
|
|
|
+| 商家同意退款(全额) | → 2(退款中) | **→ 4(已取消)** | → 2(已退款) | 废弃 | **停止配送** |
|
|
|
+| 商家同意退款(部分) | → 3(已退款) | **不变** | 视金额调整 | 不变 | **继续配送** |
|
|
|
+| 商家拒绝退款 | → 4(退款拒绝) | **不变** | 不变 | 不变 | **继续配送** |
|
|
|
+| 客服介入 | → 5(客服介入) | 不变 | 不变 | 不变 | 视客服裁决 |
|
|
|
+| 用户撤销退款 | → 0(无售后) | 不变 | 不变 | 不变 | **继续配送** |
|
|
|
+
|
|
|
+核心原则:退款申请本身不影响订单状态和配送,只有全额退款成功才取消订单。
|
|
|
+
|
|
|
+### state=4(已取消)的触发场景
|
|
|
+
|
|
|
+| 场景 | state | afterSaleStatus | 说明 |
|
|
|
+|------|-------|-----------------|------|
|
|
|
+| 商家主动取消 | → 4 | 0 | 未付款或刚接单时商家取消 |
|
|
|
+| 系统超时自动取消 | → 4 | 0 | 商家超时未接单 |
|
|
|
+| 全额退款成功 | → 4 | 3(已退款) | 退款完成后订单取消 |
|
|
|
+| 用户未支付取消 | → 4 | 0 | 订单超时未支付 |
|
|
|
+
|
|
|
+## 旧值 → 新值 数据迁移映射
|
|
|
+
|
|
|
+| 旧 state | 旧含义 | 新 state | 新 payStatus | 新 deliveryStatus | 新 afterSaleStatus |
|
|
|
+|----------|--------|----------|-------------|------------------|-------------------|
|
|
|
+| 0 | 未支付 | 0 | 0 | NULL | 0 |
|
|
|
+| 1 | 已付款 | 0 | 1 | NULL | 0 |
|
|
|
+| 2 | 已接单 | 1 | 1 | NULL | 0 |
|
|
|
+| 3 | 骑手接单 | 1 | 1 | 1 | 0 |
|
|
|
+| 4 | 配送中 | 1 | 1 | 2 | 0 |
|
|
|
+| 5 | 已完成 | 3 | 1 | 3(外送) | 0 |
|
|
|
+| 6 | 申请退款 | 1 | 1 | NULL | 1 |
|
|
|
+| 7 | 同意退款 | 4 | 2 | NULL | 3 |
|
|
|
+| 8 | 拒绝退款 | 1 | 1 | NULL | 4 |
|
|
|
+| 9 | 客服接入 | 1 | 1 | NULL | 5 |
|
|
|
+| 10 | 作废 | 4 | 0 | NULL | 0 |
|
|
|
+| 11 | 售后完成 | 4 | 2 | NULL | 6 |
|
|
|
+| 12 | 送达 | 2 | 1 | 3 | 0 |
|
|
|
+| 13 | 退款处理中 | 1 | 1 | NULL | 2 |
|
|
|
+
|
|
|
+> 注:旧退款状态(6,8,9)迁移时新 state 推算为 1(已接单),因为退款前订单大概率在已接单阶段。历史数据够用即可。
|
|
|
+
|
|
|
+## 前端展示逻辑
|
|
|
+
|
|
|
+### 商家端订单列表 Tab
|
|
|
+
|
|
|
+| 商家端 Tab | 筛选条件 |
|
|
|
+|-----------|---------|
|
|
|
+| 待受理 | state=0 AND (payStatus=1 OR type IN (1,2)) |
|
|
|
+| 待出餐 | state=1 |
|
|
|
+| 已出餐 | state=2 + afterSaleStatus=0 |
|
|
|
+| 已完成 | state=3 + afterSaleStatus=0 |
|
|
|
+| 已取消 | state=4 + afterSaleStatus=0 |
|
|
|
+| 退款/售后 | afterSaleStatus > 0 |
|
|
|
+
|
|
|
+> **设计决策**:待受理条件区分了外送和自取/堂食。外送订单必须 payStatus=1(已付款/到付确认)才出现在待受理;自取/堂食订单下单即可见(因为现金是线下收取的,不需要等在线支付)。
|
|
|
+
|
|
|
+### 用户端订单列表 Tab
|
|
|
+
|
|
|
+| 用户端 Tab | 筛选条件 |
|
|
|
+|-----------|---------|
|
|
|
+| 待付款 | payStatus=0 AND type=0(仅外送在线支付订单) |
|
|
|
+| 进行中 | state IN (0,1,2) AND afterSaleStatus=0 AND (payStatus=1 OR type IN (1,2)) |
|
|
|
+| 已完成 | state=3 + afterSaleStatus=0 |
|
|
|
+| 已取消 | state=4 + afterSaleStatus=0 |
|
|
|
+| 退款/售后 | afterSaleStatus > 0 |
|
|
|
+
|
|
|
+> **设计决策**:待付款仅显示外送未支付订单。自取/堂食现金订单的 payStatus=0 但不显示在"待付款"(用户无需在线付款),直接进入"进行中"Tab。用户端 Tab 名从"待收货"改为"进行中",因为自取/堂食不存在"收货"概念。
|
|
|
+
|
|
|
+### 骑手端订单列表 Tab
|
|
|
+
|
|
|
+| 骑手端 Tab | 筛选条件 |
|
|
|
+|-----------|---------|
|
|
|
+| 新任务 | type=0 + deliveryStatus=0 + state=2 + afterSaleStatus=0 |
|
|
|
+| 待取货 | deliveryStatus=1 + qsId=当前骑手 + afterSaleStatus=0 |
|
|
|
+| 配送中 | deliveryStatus=2 + qsId=当前骑手 + afterSaleStatus=0 |
|
|
|
+| 已完成 | state=3 + afterSaleStatus=0 + qsId=当前骑手 |
|
|
|
+| 已取消 | state=4 + qsId=当前骑手 + afterSaleStatus=0 |
|
|
|
+| 退款/售后 | afterSaleStatus > 0 + qsId=当前骑手 |
|
|
|
+
|
|
|
+### 前端展示给用户的文字
|
|
|
+
|
|
|
+| type | state | deliveryStatus | payStatus | afterSaleStatus | 展示给用户 |
|
|
|
+|------|-------|----------------|-----------|-----------------|-----------|
|
|
|
+| 0(外送) | 0 | - | 0 | 0 | 待付款 |
|
|
|
+| 0(外送) | 0 | - | 1 | 0 | 待商家确认 |
|
|
|
+| 0(外送) | 1 | - | 1 | 0 | 商家备餐中 |
|
|
|
+| 0(外送) | 2 | 0 | 1 | 0 | 待骑手配送 |
|
|
|
+| 0(外送) | 2 | 1 | 1 | 0 | 骑手已接单 |
|
|
|
+| 0(外送) | 2 | 2 | 1 | 0 | 配送中 |
|
|
|
+| 0(外送) | 2 | 3 | 1 | 0 | 已送达 |
|
|
|
+| 0(外送) | 3 | - | 1 | 0 | 已完成 |
|
|
|
+| 0(外送) | * | * | * | 1 | 退款申请中 |
|
|
|
+| 0(外送) | * | * | * | 2 | 退款中 |
|
|
|
+| 0(外送) | 4 | - | 2 | 3 | 已退款 |
|
|
|
+| 0(外送) | 4 | - | 0 | 0 | 已取消 |
|
|
|
+| 0(外送) | 4 | - | 1 | 0 | 已取消 |
|
|
|
+| 0(外送) | * | * | * | 4 | 退款已拒绝 |
|
|
|
+| 0(外送) | * | * | * | 5 | 客服介入中 |
|
|
|
+| 0(外送) | * | * | * | 6 | 售后完成 |
|
|
|
+| 1(自取) | 0 | - | 0 | 0 | 待商家确认 |
|
|
|
+| 1(自取) | 0 | - | 1 | 0 | 待商家确认 |
|
|
|
+| 1(自取) | 1 | - | 1 | 0 | 商家备餐中 |
|
|
|
+| 1(自取) | 2 | - | 1 | 0 | 待取餐(请到店取餐) |
|
|
|
+| 1(自取) | 3 | - | 1 | 0 | 已完成 |
|
|
|
+| 1(自取) | * | - | * | 1 | 退款申请中 |
|
|
|
+| 1(自取) | 4 | - | 0 | 0 | 已取消 |
|
|
|
+| 1(自取) | 4 | - | 1 | 0 | 已取消 |
|
|
|
+| 1(自取) | * | - | * | 2 | 退款中 |
|
|
|
+| 1(自取) | * | - | * | 4 | 退款已拒绝 |
|
|
|
+| 1(自取) | * | - | * | 5 | 客服介入中 |
|
|
|
+| 1(自取) | * | - | * | 6 | 售后完成 |
|
|
|
+| 2(堂食) | 0 | - | 0 | 0 | 待商家确认 |
|
|
|
+| 2(堂食) | 0 | - | 1 | 0 | 待商家确认 |
|
|
|
+| 2(堂食) | 1 | - | 1 | 0 | 商家备餐中 |
|
|
|
+| 2(堂食) | 2 | - | 1 | 0 | 备餐完成 |
|
|
|
+| 2(堂食) | 3 | - | 1 | 0 | 已完成 |
|
|
|
+| 2(堂食) | * | - | * | 1 | 退款申请中 |
|
|
|
+| 2(堂食) | 4 | - | 0 | 0 | 已取消 |
|
|
|
+| 2(堂食) | 4 | - | 1 | 0 | 已取消 |
|
|
|
+| 2(堂食) | * | - | * | 2 | 退款中 |
|
|
|
+| 2(堂食) | * | - | * | 4 | 退款已拒绝 |
|
|
|
+| 2(堂食) | * | - | * | 5 | 客服介入中 |
|
|
|
+| 2(堂食) | * | - | * | 6 | 售后完成 |
|
|
|
+
|
|
|
+## 需要修改的代码
|
|
|
+
|
|
|
+### 1. 数据库变更
|
|
|
+
|
|
|
+```sql
|
|
|
+-- 新增 delivery_status 字段
|
|
|
+ALTER TABLE pos_order ADD COLUMN delivery_status BIGINT DEFAULT NULL COMMENT '配送状态:0待接单,1骑手已接单,2配送中,3已送达';
|
|
|
+
|
|
|
+-- 新增 pay_status 字段
|
|
|
+ALTER TABLE pos_order ADD COLUMN pay_status BIGINT DEFAULT 0 COMMENT '支付状态:0未支付,1已支付,2已退款';
|
|
|
+
|
|
|
+-- 新增 after_sale_status 字段
|
|
|
+ALTER TABLE pos_order ADD COLUMN after_sale_status BIGINT DEFAULT 0 COMMENT '售后状态:0无售后,1申请中,2退款中,3已退款,4退款拒绝,5客服介入,6售后完成';
|
|
|
+
|
|
|
+-- 废弃 dining_status 字段
|
|
|
+-- ALTER TABLE pos_order DROP COLUMN dining_status; -- 视情况是否删除
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 数据迁移
|
|
|
+
|
|
|
+**不需要数据迁移**。系统未正式使用,历史订单数据由开发者手动清空。新字段(delivery_status, pay_status, after_sale_status)通过 ALTER TABLE 添加后,所有新订单直接使用新值。
|
|
|
+
|
|
|
+> **注意**:如果将来需要迁移历史数据,不能用逐步 UPDATE 的方式(会有值冲突 bug),必须用单条 CASE WHEN 语句原子更新。
|
|
|
+
|
|
|
+### 3. PosOrder 实体类
|
|
|
+
|
|
|
+- 新增字段:`deliveryStatus`(Long)、`payStatus`(Long)、`afterSaleStatus`(Long)
|
|
|
+- **废弃但保留的字段**:`diningStatus`、`isAccepted`、`kefuState`、`kefuContent`、`kefuRepeat`、`repeatDdId` — 新逻辑不再使用,保留在实体中避免序列化问题
|
|
|
+ - `diningStatus` 由 `state` 值变更替代(state=2 即出餐)
|
|
|
+ - `isAccepted` 由 `state=1`(已接单)替代
|
|
|
+ - `kefuState` 等由 `afterSaleStatus` 替代(客服介入 = afterSaleStatus=5)
|
|
|
+
|
|
|
+### 4. MyBatis Mapper(PosOrderMapper.xml)
|
|
|
+
|
|
|
+- resultMap 新增 `delivery_status`、`pay_status`、`after_sale_status` 映射
|
|
|
+- insert/update 新增对应字段
|
|
|
+
|
|
|
+### 5. PosOrderShOprateController(商家操作)
|
|
|
+
|
|
|
+- **接单**:`state` 从 0 改为 1
|
|
|
+- **出餐**:`state` 从 1 改为 2
|
|
|
+ - 外送订单:额外设置 `deliveryStatus=0`(等待骑手接单)
|
|
|
+ - 自取/堂食订单:只改 `state=2`
|
|
|
+- **完成(自取/堂食)**:`state` 从 2 改为 3,同时 `payStatus` 从 0 改为 1(收现金+完成,一个操作)
|
|
|
+ - 仅限 type=1(自取)或 type=2(堂食)订单
|
|
|
+
|
|
|
+### 6. PosOrderQsOprateController(骑手操作)
|
|
|
+
|
|
|
+- `acceptOrder`:校验 type=0 且 afterSaleStatus=0,设置 `deliveryStatus=1`
|
|
|
+- `pickupOrder`:校验 type=0 且 afterSaleStatus=0,设置 `deliveryStatus=2`
|
|
|
+- `deliverOrder`:校验 type=0,设置 `deliveryStatus=3`,同时设置 `state=3`
|
|
|
+- 所有骑手操作需检查 afterSaleStatus,有活跃退款申请时允许操作但需提示
|
|
|
+
|
|
|
+### 7. 订单完成机制
|
|
|
+
|
|
|
+参考美团做法:商家/骑手操作是主触发器,用户确认是可选的,自动完成是兜底。
|
|
|
+
|
|
|
+| 类型 | 完成触发者 | 操作 | 自动完成兜底 |
|
|
|
+|------|-----------|------|-------------|
|
|
|
+| 外送 | 骑手 | 骑手点"已送达" → state=3, deliveryStatus=3 | 送达后 N 小时自动完成 |
|
|
|
+| 自取 | 商家 | 商家点"完成" → state=3, payStatus=1 | 出餐后 N 小时自动完成 |
|
|
|
+| 堂食 | 商家 | 商家点"完成" → state=3, payStatus=1 | 出餐后 N 小时自动完成 |
|
|
|
+
|
|
|
+- **用户确认**:可提供可选的"确认取餐"按钮,用户点了也设 `state=3`,但不点也不影响
|
|
|
+- **定时任务兜底**:商家出餐(state=2)后超时未完成,系统自动设为 `state=3`
|
|
|
+
|
|
|
+### 8. 订单创建(UserOrderController)
|
|
|
+
|
|
|
+- 创建订单时设置 `state=0`、`afterSaleStatus=0`、`deliveryStatus=NULL`(所有类型),根据类型和支付方式设置 `payStatus`
|
|
|
+ - 外送到付(type=0, payType=1):`payStatus=1`
|
|
|
+ - 自取/堂食现金(type=1或2):`payStatus=0`(商家收款时设为1)
|
|
|
+ - 在线支付:`payStatus=0`
|
|
|
+
|
|
|
+### 9. 支付回调
|
|
|
+
|
|
|
+- 支付成功后:`payStatus` 从 0 改为 1
|
|
|
+
|
|
|
+### 10. 售后/退款操作(OrderAppealController 等)
|
|
|
+
|
|
|
+> **本次不实现完整退款流程**。系统尚未接入在线支付,暂无退款场景。afterSaleStatus 字段预留,但只实现以下两个操作:
|
|
|
+> - 用户取消订单(未接单前):`state` → 4,`afterSaleStatus` 保持 0
|
|
|
+> - 商家取消订单:`state` → 4,`afterSaleStatus` 保持 0
|
|
|
+>
|
|
|
+> 以下完整退款流程留待接入在线支付后实现:
|
|
|
+
|
|
|
+- 用户申请退款:`afterSaleStatus` → 1,`state` 不变
|
|
|
+- 商家同意退款(全额):`afterSaleStatus` → 2 → 3,`state` → 4,`payStatus` → 2
|
|
|
+- 商家同意退款(部分):`afterSaleStatus` → 3,`state` 不变
|
|
|
+- 商家拒绝退款:`afterSaleStatus` → 4,`state` 不变
|
|
|
+- 客服介入:`afterSaleStatus` → 5
|
|
|
+- 售后完成:`afterSaleStatus` → 6
|
|
|
+- 用户撤销退款:`afterSaleStatus` → 0
|
|
|
+
|
|
|
+### 11. 旧订单列表查询方法(废弃)
|
|
|
+
|
|
|
+以下旧方法在数据迁移后自然废弃,不再修改。新方法见第 15 节。
|
|
|
+
|
|
|
+- `PosOrderController.getstoreorderlist()` — 商家端订单列表(废弃,由 PosOrderShOprateController.orderList 替代)
|
|
|
+- `PosOrderController.getorderlist()` — 用户端订单列表(废弃,由 UserOrderController.orderList 替代)
|
|
|
+- `PosOrderController.getqsorderlist()` — 骑手端订单列表(废弃,由 PosOrderQsOprateController.orderList 替代)
|
|
|
+- `PosOrderController.getqishouorderlist()` — 骑手抢单列表(废弃,由 PosOrderQsOprateController.orderList 的 newTask Tab 替代)
|
|
|
+- `ShindexController` — 商家首页(废弃)
|
|
|
+- `TableQrcodeController` — 堂食二维码订单(废弃)
|
|
|
+- `PosOrderMapper` — 旧 SQL 中的 state 条件不再维护
|
|
|
+
|
|
|
+### 12. 定时任务(TestTask.java)
|
|
|
+
|
|
|
+- ~~旧自动完成逻辑(state=12→5)不再需要~~:骑手"已送达"操作直接设 `state=3 + deliveryStatus=3`,不存在需要从"送达"自动转为"已完成"的中间状态
|
|
|
+- **新增自动完成兜底**:查 `state=2 AND afterSaleStatus=0` 且超时未完成,自动设 `state=3`(外送同时设 `deliveryStatus=3`,自取/堂食同时设 `payStatus=1`)
|
|
|
+- 退款处理逻辑:原来查 `state=13` 改为查 `afterSaleStatus=2`(本次不实现)
|
|
|
+- 作废逻辑:原来设 `state=10` 改为设 `state=4`
|
|
|
+
|
|
|
+### 13. 骑手约束逻辑
|
|
|
+
|
|
|
+- 防止骑手同时接多单:原来查 `state IN (3,4)` 改为查 `deliveryStatus IN (1,2)`
|
|
|
+- `RiderPositionMapper` 排除有活跃订单的骑手:条件同步更新
|
|
|
+- 有退款申请的订单(afterSaleStatus>0)仍允许骑手操作,直到全额退款成功
|
|
|
+
|
|
|
+### 14. 推送通知
|
|
|
+
|
|
|
+- 推送消息中的 state 值需对应新值
|
|
|
+- 根据 `type + state + deliveryStatus + afterSaleStatus` 组合发送不同内容
|
|
|
+- 退款相关推送应基于 afterSaleStatus 而非 state
|
|
|
+
|
|
|
+## 15. 新订单列表接口设计
|
|
|
+
|
|
|
+### 设计原则
|
|
|
+
|
|
|
+- **旧方法不动**:PosOrderController 中旧的 getstoreorderlist/getorderlist/getqsorderlist/getqishouorderlist 等方法保留代码不删,数据迁移后自然废弃
|
|
|
+- **新方法写在三个 Controller 中**:用户端写 UserOrderController,骑手端写 PosOrderQsOprateController,商家端写 PosOrderShOprateController
|
|
|
+- **使用 LambdaQueryWrapper**:三个端统一用 LambdaQueryWrapper 拼查询条件
|
|
|
+- **Tab 参数**:前端传 `tab` 字符串参数(如 `pending`、`active`、`completed`),后端映射到四字段查询条件
|
|
|
+- **状态展示文字由前端计算**:后端只返回 state/deliveryStatus/payStatus/afterSaleStatus/type 字段,前端根据这些字段组合自行决定显示文案
|
|
|
+- **分页返回 total**:新接口统一返回 `{ records, total, page, size }` 格式
|
|
|
+
|
|
|
+### 前置条件
|
|
|
+
|
|
|
+以下变更必须在列表接口开发前完成:
|
|
|
+1. PosOrder 实体添加 `deliveryStatus`、`payStatus`、`afterSaleStatus` 字段
|
|
|
+2. PosOrderMapper.xml resultMap 添加三个新字段映射,insert/update 语句同步更新
|
|
|
+3. 数据库执行 ALTER TABLE 添加三个新列(第1节 SQL 脚本)
|
|
|
+4. 历史订单数据手动清空(第2节:不需要迁移脚本)
|
|
|
+5. PosOrder 已有 `longitude`(经度)和 `latitude`(纬度)字段,骑手距离排序可直接使用
|
|
|
+
|
|
|
+### 15.1 用户端订单列表
|
|
|
+
|
|
|
+**位置**:`UserOrderController.java`(路径前缀 `/system/userOrder`)
|
|
|
+**接口**:`GET /system/userOrder/orderList`
|
|
|
+
|
|
|
+**参数**:
|
|
|
+
|
|
|
+| 参数 | 类型 | 必填 | 说明 |
|
|
|
+|------|------|------|------|
|
|
|
+| token | Header | 是 | 用户身份 |
|
|
|
+| page | int | 是 | 页码,从1开始 |
|
|
|
+| size | int | 是 | 每页条数 |
|
|
|
+| tab | String | 是 | Tab 标识 |
|
|
|
+| type | String | 否 | 订单类型筛选:0 外送 / 1 自取 / 2 堂食,不传则查所有类型 |
|
|
|
+
|
|
|
+**Tab 映射**:
|
|
|
+
|
|
|
+| tab 值 | 查询条件 | 说明 |
|
|
|
+|--------|---------|------|
|
|
|
+| `unpaid` | `payStatus=0 AND type=0` | 待付款(仅外送在线支付订单) |
|
|
|
+| `active` | `state IN (0,1,2) AND afterSaleStatus=0 AND (payStatus=1 OR type IN (1,2))` | 进行中 |
|
|
|
+| `completed` | `state=3 AND afterSaleStatus=0` | 已完成 |
|
|
|
+| `cancelled` | `state=4 AND afterSaleStatus=0` | 已取消 |
|
|
|
+| `refund` | `afterSaleStatus > 0` | 退款/售后 |
|
|
|
+
|
|
|
+**返回格式**:复用旧接口 `getorderlist()` 的返回格式。PosOrder 全字段自动序列化(含 `deliveryStatus`、`payStatus`、`afterSaleStatus` 新字段),额外附加以下关联数据:
|
|
|
+
|
|
|
+| 附加字段 | 来源 | 说明 |
|
|
|
+|---------|------|------|
|
|
|
+| `ddId` | PosOrder.ddId | 转为字符串 |
|
|
|
+| `shanghu` | InfoUser(shId) | 商家用户信息 |
|
|
|
+| `store` | PosStore(mdId) | 门店信息 |
|
|
|
+| `shaddress` | InfoAddress(shdzId) 或 JSON解析 | 收货地址 |
|
|
|
+| `user` | InfoUser(userId) | 用户信息 |
|
|
|
+| `food` | PosOrder.food | JSON 解析为商品列表 |
|
|
|
+| `parentRemarks` | OrderParent | 父订单备注 |
|
|
|
+
|
|
|
+骑手信息只返回 PosOrder 自带的 `qsId` 和 `qsImg`,不做额外 InfoUser 查询。
|
|
|
+
|
|
|
+**返回示例**:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": 200,
|
|
|
+ "msg": "操作成功",
|
|
|
+ "data": {
|
|
|
+ "records": [
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "ddId": "202605150001",
|
|
|
+ "type": 0,
|
|
|
+ "state": 1,
|
|
|
+ "deliveryStatus": null,
|
|
|
+ "payStatus": 1,
|
|
|
+ "afterSaleStatus": 0,
|
|
|
+ "qsId": null,
|
|
|
+ "qsImg": null,
|
|
|
+ "mdId": 100,
|
|
|
+ "amount": 50000,
|
|
|
+ "cretim": "2026-05-15 12:00:00",
|
|
|
+ "shanghu": { "userId": 50, "nickName": "商家A" },
|
|
|
+ "store": { "id": 100, "mdName": "测试门店" },
|
|
|
+ "shaddress": { "id": 1, "address": "..." },
|
|
|
+ "user": { "userId": 1, "nickName": "用户A" },
|
|
|
+ "food": [{ "foodName": "菜品1", "num": 2 }],
|
|
|
+ "parentRemarks": ""
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "total": 100,
|
|
|
+ "page": 1,
|
|
|
+ "size": 10
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 15.2 商家端订单列表
|
|
|
+
|
|
|
+**位置**:`PosOrderShOprateController.java`(路径前缀 `/system/orderShOprate`)
|
|
|
+**接口**:`GET /system/orderShOprate/orderList`
|
|
|
+
|
|
|
+**参数**:
|
|
|
+
|
|
|
+| 参数 | 类型 | 必填 | 说明 |
|
|
|
+|------|------|------|------|
|
|
|
+| token | Header | 是 | 商家身份 |
|
|
|
+| page | int | 是 | 页码,从1开始 |
|
|
|
+| size | int | 是 | 每页条数 |
|
|
|
+| tab | String | 是 | Tab 标识 |
|
|
|
+| mdId | String | 是 | 门店ID |
|
|
|
+| type | String | 否 | 订单类型筛选:0 外送 / 1 自取 / 2 堂食,不传则显示全部类型 |
|
|
|
+
|
|
|
+**Tab 映射**:
|
|
|
+
|
|
|
+| tab 值 | 查询条件 | 说明 |
|
|
|
+|--------|---------|------|
|
|
|
+| `pending` | `state=0 AND (payStatus=1 OR type IN (1,2)) AND mdId=?` | 待受理 |
|
|
|
+| `preparing` | `state=1 AND mdId=?` | 待出餐 |
|
|
|
+| `ready` | `state=2 AND afterSaleStatus=0 AND mdId=?` | 已出餐 |
|
|
|
+| `completed` | `state=3 AND afterSaleStatus=0 AND mdId=?` | 已完成 |
|
|
|
+| `cancelled` | `state=4 AND afterSaleStatus=0 AND mdId=?` | 已取消 |
|
|
|
+| `refund` | `afterSaleStatus > 0 AND mdId=?` | 退款/售后 |
|
|
|
+
|
|
|
+**返回格式**:PosOrder 全字段序列化 + 新字段自动包含。返回 `{ records, total, page, size }` 格式。
|
|
|
+
|
|
|
+### 15.3 骑手端订单列表
|
|
|
+
|
|
|
+**位置**:`PosOrderQsOprateController.java`(路径前缀 `/system/orderQsOprate`)
|
|
|
+**接口**:`GET /system/orderQsOprate/orderList`
|
|
|
+
|
|
|
+**参数**:
|
|
|
+
|
|
|
+| 参数 | 类型 | 必填 | 说明 |
|
|
|
+|------|------|------|------|
|
|
|
+| token | Header | 是 | 骑手身份(JwtUtil.getusid(token) 即为 qsId) |
|
|
|
+| page | int | 是 | 页码,从1开始 |
|
|
|
+| size | int | 是 | 每页条数 |
|
|
|
+| tab | String | 是 | Tab 标识 |
|
|
|
+| longitude | BigDecimal | 条件必填 | 骑手当前经度(newTask Tab 必填) |
|
|
|
+| latitude | BigDecimal | 条件必填 | 骑手当前纬度(newTask Tab 必填) |
|
|
|
+
|
|
|
+**Tab 映射**:
|
|
|
+
|
|
|
+| tab 值 | 查询条件 | 排序 |
|
|
|
+|--------|---------|------|
|
|
|
+| `newTask` | `type=0 AND deliveryStatus=0 AND state=2 AND afterSaleStatus=0` | 距离 ASC(使用 PosOrder.longitude/latitude 计算到骑手的距离) |
|
|
|
+| `toPickup` | `deliveryStatus=1 AND qsId=当前骑手ID AND afterSaleStatus=0` | 时间 ASC |
|
|
|
+| `delivering` | `deliveryStatus=2 AND qsId=当前骑手ID AND afterSaleStatus=0` | 时间 ASC |
|
|
|
+| `completed` | `state=3 AND afterSaleStatus=0 AND qsId=当前骑手ID` | 时间 DESC |
|
|
|
+| `cancelled` | `state=4 AND qsId=当前骑手ID AND afterSaleStatus=0` | 时间 DESC |
|
|
|
+| `refund` | `afterSaleStatus > 0 AND qsId=当前骑手ID` | 时间 DESC |
|
|
|
+
|
|
|
+**距离排序实现**:
|
|
|
+
|
|
|
+```java
|
|
|
+wrapper.last("ORDER BY ST_Distance_Sphere(point(longitude, latitude), " +
|
|
|
+ "point(" + lng + ", " + lat + ")) ASC");
|
|
|
+```
|
|
|
+
|
|
|
+**返回格式**:PosOrder 全字段序列化 + 新字段自动包含。返回 `{ records, total, page, size }` 格式。
|
|
|
+
|
|
|
+### 15.4 设计决策记录
|
|
|
+
|
|
|
+以下问题在需求讨论中确认,记录备查:
|
|
|
+
|
|
|
+| # | 问题 | 决策 | 原因 |
|
|
|
+|---|------|------|------|
|
|
|
+| 1 | 旧方法如何处理 | 保留代码不删,数据迁移后自然废弃 | 系统未正式使用,旧方法不再维护 |
|
|
|
+| 2 | Tab 参数格式 | 用有意义的字符串(pending/active 等) | 参考美团做法,语义清晰,与旧接口 z01 模式完全独立 |
|
|
|
+| 3 | 用户端返回格式 | 复用旧接口格式 + 新字段自动包含 | 前端切换成本低,新字段通过 PosOrder 序列化自动包含 |
|
|
|
+| 4 | 骑手信息 | 只返回 qsId + qsImg | 和旧接口一致,不做额外 InfoUser 查询 |
|
|
|
+| 5 | 已取消订单归属 | 三个端都新增 `cancelled` Tab | 参考美团做法,已取消订单(state=4, afterSaleStatus=0)需要独立 Tab 承接,否则无任何 Tab 显示 |
|
|
|
+| 6 | 商家端 Tab 数量 | 从 4 个扩充到 6 个(加 completed + cancelled) | 参考美团商家端有"已完成"和"已取消"分类 |
|
|
|
+| 7 | 骑手距离排序 | 用 LambdaQueryWrapper.last() 追加原始 SQL | PosOrder 已有 longitude/latitude 字段,无需 JOIN PosStore |
|
|
|
+| 8 | 状态展示文字 | 前端根据 type+state+deliveryStatus+afterSaleStatus 组合自行计算 | 后端只返回数据,不返回 statusText |
|
|
|
+| 9 | 分页格式 | 返回 { records, total, page, size } | 前端需要 total 做分页控件 |
|
|
|
+| 10 | 类型筛选 | 用户端和商家端都支持可选的 type 参数 | 商家可能需要区分外送/自取/堂食订单 |
|
|
|
+| 11 | 数据迁移策略 | 四步骤一次性执行(加字段+填充+迁移state) | 系统未正式使用,无需分步兼容 |
|
|
|
+| 12 | 自取/堂食现金 payStatus | 创建时 payStatus=0,商家收款+完成时设为1 | 商家需要明确知道现金是否已收到,收钱和完成是同一动作 |
|
|
|
+| 13 | 待受理 Tab 条件 | state=0 AND (payStatus=1 OR type IN (1,2)) | 自取/堂食下单即可见,外送需先付款 |
|
|
|
+| 14 | 用户端"待付款"Tab | payStatus=0 AND type=0 | 自取/堂食现金无需在线付款,不显示在待付款 |
|
|
|
+| 15 | 订单完成机制 | 商家/骑手操作为主触发,用户确认为可选,定时任务兜底 | 参考美团:不依赖用户点确认 |
|
|
|
+| 16 | 数据迁移 | 不需要,历史数据手动清空 | 系统未正式使用 |
|
|
|
+| 17 | 退款流程 | 本次不实现,afterSaleStatus 字段预留 | 尚未接入在线支付,无退款场景 |
|
|
|
+| 18 | 旧字段处理 | diningStatus/isAccepted/kefuState 等保留但废弃 | 新逻辑不再使用,避免序列化问题 |
|
|
|
+| 19 | 商家操作步骤 | 接单(state 0→1)和出餐(state 1→2)分两步 | 参考美团商家端流程 |
|
|
|
+
|
|
|
+## 16. 平台管理端(foodie-admin-vue)调整
|
|
|
+
|
|
|
+### 16.1 订单列表页(src/views/system/order/index.vue)
|
|
|
+
|
|
|
+**位置**:`E:\QtwCode\foodie\foodie-admin-vue\src\views\system\order\index.vue`
|
|
|
+**后端接口**:`/system/order/list`(保留现有接口,后端需支持新的筛选参数)
|
|
|
+
|
|
|
+#### 筛选条件变更
|
|
|
+
|
|
|
+原来用单个下拉框筛选旧 state(0-12),改为四个独立下拉框:
|
|
|
+
|
|
|
+| 筛选字段 | 下拉选项 | 默认 |
|
|
|
+|---------|---------|------|
|
|
|
+| state | 全部 / 待处理(0) / 已接单(1) / 已出餐(2) / 已完成(3) / 已取消(4) | 全部 |
|
|
|
+| payStatus | 全部 / 未支付(0) / 已支付(1) / 已退款(2) | 全部 |
|
|
|
+| deliveryStatus | 全部 / 待接单(0) / 骑手已接单(1) / 配送中(2) / 已送达(3) / 不适用(NULL) | 全部 |
|
|
|
+| afterSaleStatus | 全部 / 无售后(0) / 申请中(1) / 退款中(2) / 已退款(3) / 退款拒绝(4) / 客服介入(5) / 售后完成(6) | 全部 |
|
|
|
+
|
|
|
+保留现有的订单号、用户ID、订单类型、创建时间筛选条件不变。
|
|
|
+
|
|
|
+#### 状态列变更
|
|
|
+
|
|
|
+原来单个 `el-tag` 显示旧 state,改为两个 tag 组合显示——主状态 + 副状态:
|
|
|
+
|
|
|
+```
|
|
|
+| 订单状态列 |
|
|
|
+|-----------|
|
|
|
+| [待处理] [已支付] ← state=0, payStatus=1 |
|
|
|
+| [已接单] ← state=1 |
|
|
|
+| [已出餐] [配送中] ← state=2, deliveryStatus=2 |
|
|
|
+| [已出餐] [待骑手] ← state=2, deliveryStatus=0 |
|
|
|
+| [已完成] ← state=3 |
|
|
|
+| [已取消] ← state=4, afterSaleStatus=0 |
|
|
|
+| [已取消] [已退款] ← state=4, afterSaleStatus=3 |
|
|
|
+| [已接单] [退款申请中] ← state=1, afterSaleStatus=1 |
|
|
|
+```
|
|
|
+
|
|
|
+规则:
|
|
|
+- **主 tag**:根据 state 显示(待处理/已接单/已出餐/已完成/已取消)
|
|
|
+- **副 tag**:根据订单类型和附加状态显示
|
|
|
+ - 外送(type=0):显示 deliveryStatus(待骑手/骑手已接单/配送中/已送达)
|
|
|
+ - 所有类型:显示 payStatus(仅未支付/已退款时显示,已支付不显示避免冗余)
|
|
|
+ - 所有类型:显示 afterSaleStatus(仅 >0 时显示)
|
|
|
+- 已取消的订单主 tag 用红色(`type="danger"`)
|
|
|
+
|
|
|
+#### 修改订单弹窗
|
|
|
+
|
|
|
+原来用 `sys_order_type` 字典的 radio 选择旧 state 值。改为:
|
|
|
+- 只能修改 `state` 字段(0-4 的下拉选择)
|
|
|
+- 平台管理员通常不应该直接改状态,如确需保留此功能,下拉选项为:待处理(0) / 已接单(1) / 已出餐(2) / 已完成(3) / 已取消(4)
|
|
|
+
|
|
|
+### 16.2 订单详情弹窗
|
|
|
+
|
|
|
+#### 进度条变更
|
|
|
+
|
|
|
+原来7步进度条(未支付→已付款→已接单→取餐中→配送中→已完成→异常),改为4步:
|
|
|
+
|
|
|
+```
|
|
|
+待处理(0) → 已接单(1) → 已出餐(2) → 已完成(3)
|
|
|
+```
|
|
|
+
|
|
|
+- 已取消(state=4)的订单不显示进度条,改为显示红色 `已取消` 标签
|
|
|
+- `:active` 绑定 `orxiangq.state`(0-3 直接对应步骤索引)
|
|
|
+
|
|
|
+#### 新增状态信息区域
|
|
|
+
|
|
|
+在进度条下方,增加三个状态信息行(仅在对应值非默认时显示):
|
|
|
+
|
|
|
+| 显示条件 | 内容 |
|
|
|
+|---------|------|
|
|
|
+| payStatus != 1 | 支付状态:未支付(payStatus=0) / 已退款(payStatus=2) |
|
|
|
+| type == 0 且 deliveryStatus != null | 配送状态:待接单(0) / 骑手已接单(1) / 配送中(2) / 已送达(3) |
|
|
|
+| afterSaleStatus > 0 | 售后状态:申请中(1) / 退款中(2) / 已退款(3) / 退款拒绝(4) / 客服介入(5) / 售后完成(6) |
|
|
|
+
|
|
|
+### 16.3 后端接口调整
|
|
|
+
|
|
|
+现有 `/system/order/list` 接口需支持新的筛选参数:
|
|
|
+- 新增 `state`、`payStatus`、`deliveryStatus`、`afterSaleStatus` 查询参数
|
|
|
+- 多个筛选条件同时传入时为 AND 关系
|
|
|
+- `deliveryStatus` 需支持 NULL 筛选(自取/堂食订单)
|
|
|
+- 旧 `sys_order_type` 字典可废弃
|
|
|
+
|
|
|
+### 16.4 字典数据
|
|
|
+
|
|
|
+新增以下字典或在前端硬编码(推荐前端硬编码,因为值固定不变):
|
|
|
+
|
|
|
+| 字段 | 选项 |
|
|
|
+|------|------|
|
|
|
+| state | [{value:0, label:'待处理'}, {value:1, label:'已接单'}, {value:2, label:'已出餐'}, {value:3, label:'已完成'}, {value:4, label:'已取消'}] |
|
|
|
+| payStatus | [{value:0, label:'未支付'}, {value:1, label:'已支付'}, {value:2, label:'已退款'}] |
|
|
|
+| deliveryStatus | [{value:0, label:'待接单'}, {value:1, label:'骑手已接单'}, {value:2, label:'配送中'}, {value:3, label:'已送达'}] |
|
|
|
+| afterSaleStatus | [{value:0, label:'无售后'}, {value:1, label:'申请中'}, {value:2, label:'退款中'}, {value:3, label:'已退款'}, {value:4, label:'退款拒绝'}, {value:5, label:'客服介入'}, {value:6, label:'售后完成'}] |
|
|
|
+
|
|
|
+推荐前端硬编码而非字典表,因为这些值由代码逻辑定义,不会由运营人员修改。
|
|
|
+
|
|
|
+## 美团订单完成机制参考
|
|
|
+
|
|
|
+美团各类型订单的完成机制:
|
|
|
+
|
|
|
+- **外送**:骑手点"已送达"后启动自动完成倒计时(通常24小时),到期自动标记已完成。用户可提前手动确认收货,但不点确认不影响完成。
|
|
|
+- **自取**:商家点"出餐完成"后启动倒计时,到期自动完成。用户到店取餐可在 App 中扫码确认,但非必须。
|
|
|
+- **堂食**:商家出餐后自动倒计时完成。无需用户额外操作。
|
|
|
+
|
|
|
+核心原则:**商家/骑手操作是主触发器,用户确认是可选的,自动完成是兜底。** 用户不确认不会导致订单永远"挂着"。
|
|
|
+
|
|
|
+## 参考资源
|
|
|
+
|
|
|
+- [美团外卖开放平台 — 订单状态](https://developer.waimai.meituan.com/home/doc/market/100)
|
|
|
+- [美团外卖开放平台 — 订单退款与取消](https://developer.waimai.meituan.com/home/questionDetail/6295)
|
|
|
+- [美团外卖开放平台 — 订单确认退款请求](https://developer.waimai.meituan.com/home/docDetail/122)
|
|
|
+- [美团外卖订单中心演进](https://tech.meituan.com/2016/09/09/mt-waimai-order-evolution.html)
|