# 供应商订单审核功能设计文档
**优先级**: P1
**预计工时**: 后端 1.5h + 前端 2h
**创建日期**: 2026-09-12
---
## 用户故事
- 作为**商品供应商**,我希望在用户提交待支付订单后进行审核,可以修改价格、配送方式、添加优惠券和赠品,以便优化订单体验并促成成交。
- 作为**买家**,我希望在供应商修改订单后看到新的金额和优惠信息,以便知晓变动原因后确认支付。
---
## 验收标准
- [ ] 供应商在订单列表页可以查看待支付订单,并点击进入审核模式
- [ ] 待支付订单(status=pending)允许修改价格、配送方式、优惠券、赠品
- [ ] 已支付及之后状态的订单不可修改
- [ ] 修改价格后自动重新计算 totalAmount / moneyAmount
- [ ] 配送方式修改仅限商品配置允许的方式
- [ ] 添加优惠券时自动创建一次性临时优惠券并关联订单
- [ ] 添加赠品直接写入 product_order_gifts,无需校验库存
- [ ] 用户端订单详情页显示供应商修改记录
- [ ] 修改后订单状态保持 pending,用户按新金额支付
---
## 技术方案
### 一、后端 API 设计
#### 1. 新增接口:供应商审核更新
| 端点 | 说明 |
|------|------|
| `POST /api/product/order/review/update` | 供应商审核修改订单(统一入口) |
**请求体:**
```json
{
"orderNo": "PO20260912001",
"unitPrice": 29900, // 新单价(分),null=不修改
"deliveryMethod": 2, // 新配送方式,null=不修改
"couponId": null, // 供应商创建的临时优惠券ID
"couponType": "ONE_TIME", // 临时券类型: ONE_TIME/VENDOR_SPECIAL
"couponValue": 500, // 临时券金额(分)
"giftItems": [ // 新增赠品列表
{
"giftType": "product",
"giftProductId": 123,
"giftProductName": "赠品名称",
"giftProductImage": "https://...",
"quantity": 1
}
],
"remark": "供应商备注:已为用户申请了优惠券和赠品"
}
```
**响应:**
```json
{
"code": 200,
"message": "订单已更新",
"data": {
"orderNo": "PO20260912001",
"totalAmount": 24900,
"moneyAmount": 24900,
"pointsCost": 0,
"deliveryMethod": 2,
"giftItems": [...],
"reviewHistory": [
{
"reviewerId": 456,
"reviewerName": "供应商名称",
"reviewedAt": "2026-09-12T10:30:00",
"changes": {
"price": {"before": 39900, "after": 29900},
"delivery": {"before": 1, "after": 2},
"gifts": [{"added": "赠品名称", "quantity": 1}]
}
}
]
}
}
```
#### 2. 权限校验逻辑
```
1. 查询订单,确认 status == "pending"
2. 确认供应商是该订单商品的 vendorId(或 supplierId 匹配当前userId)
3. 执行修改(见下方各字段处理逻辑)
4. 重新计算金额
5. 记录修改历史
6. 返回更新后订单信息
```
#### 3. 各字段修改逻辑
**单价/总价修改**
- 如果 `unitPrice` 不为 null:
- `totalAmount = unitPrice * quantity`
- `moneyAmount = totalAmount - pointsCost`(如果 pointsUsed > 0,积分抵扣不变)
- 校验 unitPrice >= 0
**配送方式修改**
- 如果 `deliveryMethod` 不为 null:
- 查询商品,确认新 deliveryMethod 在商品允许的范围内
- 如果新方式为自提(2/3):校验 `pickupLocationId` 和 `timeSlotId` 非空
- 如果新方式为线上服务(4/5):校验 `servicePersonId` 和 `timeSlotId` 非空
- 更新对应快照字段(pickupLocationSnapshot / timeSlotSnapshot / servicePersonSnapshot)
**优惠券添加**
- 如果 `couponType == "ONE_TIME"` 或 `couponValue` 不为 null:
- 在 `coupon` 表创建一条一次性优惠券记录(name="供应商临时券" + 订单号,type="ONE_TIME",value=couponValue,minSpend=0,discountRate=null,status="ACTIVE",validFrom=当前,validUntil=订单取消时间后7天)
- 在 `user_coupon` 表创建一条用户可用记录(couponId=新券id,userId=order.buyerId,status="AVAILABLE",orderId=order.id)
- 更新订单的 `couponId` 指向新券
- 重新计算 `discountAmount`:根据优惠券的 value 或 discountRate 计算
- `moneyAmount = totalAmount - discountAmount`
**赠品添加**
- 如果 `giftItems` 不为空:
- 遍历每个赠品项,在 `product_order_gifts` 表插入新记录
- giftType 默认 "product",quantity 默认 1
- 不需要校验库存或会员等级
**修改历史**
- 使用 `order.remark` 字段记录供应商备注(已有字段)
- 在订单详情返回时附加 `reviewHistory` 数组(基于 remark 解析或新建审计表)
> **简化方案**:先通过 `remark` 字段记录变更信息,不新建审计表。后续如需完整变更日志再补充。
### 二、前端设计
#### 1. 订单列表页增强(`pages/vendor/orders/orders.vue`)
在 `pending` 状态的订单卡片上增加「审核」按钮:
```vue
```
跳转路径:`/pages/vendor/order-review/order-review?orderNo={orderNo}`
#### 2. 新增审核页面(`pages/vendor/order-review/order-review.vue`)
**页面结构:**
```
┌─────────────────────────────────┐
│ 订单号:PO20260912001 │
│ 订单状态:待支付 │
├─────────────────────────────────┤
│ 商品信息 │
│ [图片] 商品名称 x1 │
│ 原价:¥299.00 │
├─────────────────────────────────┤
│ 修改价格 【修改】 │
│ 修改配送方式 【修改】 │
│ 添加优惠券 【添加】 │
│ 添加赠品 【添加】 │
├─────────────────────────────────┤
│ 修改记录(若有) │
│ 2026-09-12 10:30 供应商修改价格 │
│ 299 → 249,新增赠品×1 │
├─────────────────────────────────┤
│ [保存修改] │
└─────────────────────────────────┘
```
**各模块交互:**
- **修改价格**:弹出 modal,输入新单价,实时预览新总价
- **修改配送方式**:选择配送方式(1快递/2自提),切换后根据方式显示对应表单(地址选择/自取地点选择)
- **添加优惠券**:弹出 modal,输入优惠券名称和金额,确认后创建临时券并关联
- **添加赠品**:弹出 modal,从商品库选择赠品商品,确认后写入
- **保存修改**:调用 `/api/product/order/review/update`,成功后返回列表并 Toast 提示
#### 3. 订单详情页增强(`order-detail.vue`)
当当前用户为订单商品的供应商时,在详情页底部增加「审核操作」入口(仅 pending 状态):
- 跳转到 `order-review` 页面传入 orderNo
在费用明细区块下方增加「供应商修改记录」区块(从 remark 解析显示):
```
供应商备注:已为用户申请优惠券减免50元并赠送定制笔记本
```
### 三、数据模型变更
#### 3.1 需新增的字段
**ProductOrder 实体(无需新增列,复用现有字段):**
- `remark` 字段用于记录供应商修改备注(已存在)
**无需新增实体**,所有功能复用现有表:
- 临时优惠券 → 写入 `coupon` + `user_coupon` 表
- 赠品 → 写入 `product_order_gifts` 表
- 配送方式 → 写入 `deliveryMethod` + 对应快照字段
#### 3.2 数据库迁移
```java
// 迁移48: product_orders 添加 review_remark 字段(供应商审核备注)
ensureColumn("product_orders", "review_remark", "TEXT COMMENT '供应商审核修改备注'");
```
(如果复用 remark 字段则无需迁移,remark 字段已存在)
### 四、新增文件清单
#### 后端
- `ProductOrderService.reviewAndUpdate()` — 审核修改核心逻辑
- `ProductOrderController.reviewUpdate()` — 审核修改接口
#### 前端
- `pages/vendor/order-review/order-review.vue` — 审核页面
- `utils/api.js` — 新增 `productOrderReviewUpdate()` 封装
### 五、状态流转
```
pending (待支付)
├── 供应商审核修改 ──→ pending (待支付,金额已变)
├── 用户支付 ──→ paid (已支付)
└── 取消/超时 ──→ cancelled (已取消)
```
**关键约束**:供应商审核只能在 `pending` 状态下执行。已支付后不可修改。
### 六、边界情况处理
| 场景 | 处理 |
|------|------|
| 供应商修改了配送方式,但原订单的自提地点/服务者已失效 | 重新选择时校验有效性,无效则拒绝 |
| 修改后价格比原价低 | 允许,提示"已降价" |
| 修改后价格比原价高 | 允许,提示"已加价" |
| 用户已支付后才看到修改通知 | 用户已在原金额支付,修改不生效(pending 状态下才修改) |
| 同一订单多次审核修改 | 每次修改都记录,remark 追加备注 |
### 七、后端实现细节
**Controller 新增:**
```java
@PostMapping("/review/update")
public Result