SBE Scenario 3: 配送與簽收流轉(配送中 → 已簽收 → 已完成)
場景描述
送貨員上傳簽收照片後,訂單狀態從「配送中」變更為「已簽收」,系統檢查支付狀態後自動變更為「已完成」。
Given(前置條件)
系統狀態
- 當前日期: 2025-11-03
- 當前租戶:
ABC(ABC 花店) - 已登入用戶: 李配送 (ROLE_DELIVERY)
測試資料
現有訂單
{
"orderId": "ABC-20251101-0003",
"orderNumber": "ABC-20251101-0003",
"tenantId": "ABC",
"status": "out_for_delivery",
"customerId": "cust-003",
"assignedDelivery": {
"id": "user-003",
"name": "李配送",
"role": "ROLE_DELIVERY"
},
"paymentStatus": "paid",
"deliveryDate": "2025-11-03",
"createdAt": "2025-11-01T10:00:00Z"
}
When(執行操作)
步驟 1: 送貨員送達現場
- 送貨員「李配送」將商品送達客戶地址
- 客戶簽收商品
步驟 2: 上傳簽收照片
- 送貨員在訂單詳情頁點擊「上傳簽收照片」
- 選擇 2 張照片(signoff1.jpg, signoff2.jpg)
- 系統上傳照片至雲端儲存(S3)
- 照片包含 GPS 位置資訊與時間戳
步驟 3: 確認簽收
- 送貨員點擊「確認簽收」按鈕
- 系統顯示確認對話框: 「確定客戶已簽收嗎?」
- 送貨員點擊「確定」
Then(預期結果)
API 請求 1: 更新為已簽收
端點: PUT /api/v1/orders/ABC-20251101-0003/status
Request Body
{
"newStatus": "delivered",
"photoUrls": [
"https://s3.example.com/ABC/sign-offs/ABC-20251101-0003/signoff1.jpg",
"https://s3.example.com/ABC/sign-offs/ABC-20251101-0003/signoff2.jpg"
]
}
Response Body (200 OK)
{
"orderId": "ABC-20251101-0003",
"oldStatus": "out_for_delivery",
"newStatus": "delivered",
"updatedAt": "2025-11-03T14:00:00Z",
"updatedBy": {
"userId": "user-003",
"userName": "李配送",
"role": "ROLE_DELIVERY"
},
"message": "訂單狀態已更新為「已簽收」"
}
系統自動流轉: 已簽收 → 已完成
觸發條件:
- 訂單狀態 = 「已簽收」
- 支付狀態 = 「已支付」
自動執行(系統定期檢查,每 5 分鐘):
API 請求 2: 自動更新為已完成
端點: PUT /api/v1/orders/ABC-20251101-0003/status
Request Body (系統內部調用)
{
"newStatus": "completed"
}
Response Body (200 OK)
{
"orderId": "ABC-20251101-0003",
"oldStatus": "delivered",
"newStatus": "completed",
"updatedAt": "2025-11-03T14:05:00Z",
"updatedBy": {
"userId": "system",
"userName": "系統自動",
"role": "system"
},
"message": "訂單狀態已更新為「已完成」"
}
資料庫變更
1. 更新 orders 表(已簽收)
UPDATE orders
SET status = 'delivered',
signoff_photos = '["signoff1.jpg", "signoff2.jpg"]',
delivered_at = '2025-11-03T14:00:00Z',
updated_at = '2025-11-03T14:00:00Z'
WHERE order_id = 'ABC-20251101-0003';
2. 更新 orders 表(已完成)
UPDATE orders
SET status = 'completed',
completed_at = '2025-11-03T14:05:00Z',
updated_at = '2025-11-03T14:05:00Z'
WHERE order_id = 'ABC-20251101-0003';
3. 新增狀態歷史記錄(已簽收)
{
"id": "history-003",
"orderId": "ABC-20251101-0003",
"tenantId": "ABC",
"oldStatus": "out_for_delivery",
"newStatus": "delivered",
"timestamp": "2025-11-03T14:00:00Z",
"operatorId": "user-003",
"operatorName": "李配送",
"operatorRole": "ROLE_DELIVERY",
"description": "上傳簽收照片並確認簽收",
"metadata": {
"photoCount": 2,
"gpsLocation": "25.033,121.565"
}
}
4. 新增狀態歷史記錄(已完成)
{
"id": "history-004",
"orderId": "ABC-20251101-0003",
"tenantId": "ABC",
"oldStatus": "delivered",
"newStatus": "completed",
"timestamp": "2025-11-03T14:05:00Z",
"operatorId": "system",
"operatorName": "系統自動",
"operatorRole": "system",
"description": "支付狀態已完成,自動標記為已完成"
}
通知觸發
Email 通知(發送給客戶)
{
"to": "customer@example.com",
"subject": "ABC 花店 - 訂單已簽收 ABC-20251101-0003",
"body": "您的訂單已簽收,感謝您的訂購!點擊查看簽收照片。"
}
驗證檢查清單
狀態流轉
- 訂單狀態從「配送中」變更為「已簽收」
- 訂單狀態從「已簽收」自動變更為「已完成」
- 簽收照片 URL 正確儲存
- 簽收時間正確記錄
- GPS 位置資訊正確記錄
自動流轉邏輯
- 系統檢查支付狀態(已支付)
- 系統自動觸發狀態流轉(已簽收 → 已完成)
- 系統記錄操作者為「系統自動」
照片管理
- 照片上傳至雲端儲存成功
- 照片包含時間戳
- 照片包含 GPS 位置(可選)
通知系統
- 發送簽收通知給客戶
- 通知包含簽收照片連結
錯誤場景測試
錯誤場景 1: 未上傳簽收照片
- 操作: 點擊「確認簽收」但未上傳照片
- 預期結果:
- 前端驗證失敗
- 錯誤訊息: 「請先上傳至少 1 張簽收照片」
錯誤場景 2: 支付狀態為未支付
- 支付狀態: 「未支付」
- 預期結果:
- 訂單停留在「已簽收」狀態
- 不自動流轉至「已完成」
- 待客戶完成支付後才自動流轉
最後更新: 2025-11-03