跳至主要内容

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