From 8df0a2bea7a912eaecb829a70a7d08a6015f4004 Mon Sep 17 00:00:00 2001 From: jacy <18049821889@163.com> Date: Wed, 5 Aug 2026 23:46:37 +0800 Subject: [PATCH] feat(trade): complete order on courier signed callback (v3.4.13) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When XFX route callback reports status=5 or statusName containing 签收, map to COMPLETED instead of PENDING_RECEIVE; document in v3.4.13 docs. Co-authored-by: Cursor --- .../src/callbacks/delivery-callback.service.ts | 5 ++++- .../src/integrations/courier/courier.service.ts | 4 ++-- .../src/integrations/courier/courier.types.ts | 2 +- .../courier/xiaofeixia/xiaofeixia.provider.ts | 8 +++++--- 杜康好客-v3-PRD.md | 2 +- 杜康好客-v3-现状对照.md | 2 +- 杜康好客-v3.4.13-体验优化开发文档.md | 14 ++++++++++++-- 7 files changed, 26 insertions(+), 11 deletions(-) diff --git a/server/dukang-api/src/callbacks/delivery-callback.service.ts b/server/dukang-api/src/callbacks/delivery-callback.service.ts index acfc6a1..fbeda27 100644 --- a/server/dukang-api/src/callbacks/delivery-callback.service.ts +++ b/server/dukang-api/src/callbacks/delivery-callback.service.ts @@ -73,7 +73,10 @@ export class DeliveryCallbackService { return this.courier.buildTrackCallbackResponse(false); } - const targetStatus = this.xiaofeixiaProvider.mapTrackStatus(payload.status); + const targetStatus = this.xiaofeixiaProvider.mapTrackStatus( + payload.status, + payload.statusName, + ); let applied = false; if (targetStatus && targetStatus !== order.status) { await this.tradeService.applyStatusTransition( diff --git a/server/dukang-api/src/integrations/courier/courier.service.ts b/server/dukang-api/src/integrations/courier/courier.service.ts index e5b440e..6714951 100644 --- a/server/dukang-api/src/integrations/courier/courier.service.ts +++ b/server/dukang-api/src/integrations/courier/courier.service.ts @@ -67,7 +67,7 @@ export class CourierService { return this.provider.parseTrackCallback(body); } - mapTrackStatus(status: string): CourierMappedOrderStatus | null { - return this.provider.mapTrackStatus(status); + mapTrackStatus(status: string, statusName?: string): CourierMappedOrderStatus | null { + return this.provider.mapTrackStatus(status, statusName); } } diff --git a/server/dukang-api/src/integrations/courier/courier.types.ts b/server/dukang-api/src/integrations/courier/courier.types.ts index 036f378..88416bb 100644 --- a/server/dukang-api/src/integrations/courier/courier.types.ts +++ b/server/dukang-api/src/integrations/courier/courier.types.ts @@ -128,6 +128,6 @@ export interface ICourierProvider { checkDeliveryCoverage(toAddress: string, options?: CourierCallOptions): Promise; estimateFreight(weight: number, options?: CourierCallOptions): Promise; parseTrackCallback(body: unknown): TrackCallbackPayload | null; - mapTrackStatus(status: string): CourierMappedOrderStatus | null; + mapTrackStatus(status: string, statusName?: string): CourierMappedOrderStatus | null; buildTrackCallbackResponse(success?: boolean): TrackCallbackResponse; } diff --git a/server/dukang-api/src/integrations/courier/xiaofeixia/xiaofeixia.provider.ts b/server/dukang-api/src/integrations/courier/xiaofeixia/xiaofeixia.provider.ts index e46ba70..5ae9c58 100644 --- a/server/dukang-api/src/integrations/courier/xiaofeixia/xiaofeixia.provider.ts +++ b/server/dukang-api/src/integrations/courier/xiaofeixia/xiaofeixia.provider.ts @@ -157,7 +157,11 @@ export class XiaofeixiaProvider implements ICourierProvider { }; } - mapTrackStatus(status: string): CourierMappedOrderStatus | null { + mapTrackStatus(status: string, statusName?: string): CourierMappedOrderStatus | null { + const name = (statusName || '').trim(); + if (status === '5' || /签收/.test(name)) { + return 'COMPLETED'; + } switch (String(status).trim()) { case '1': return 'OUT_WAREHOUSE'; @@ -165,8 +169,6 @@ export class XiaofeixiaProvider implements ICourierProvider { case '3': case '4': return 'SHIPPING'; - case '5': - return 'PENDING_RECEIVE'; case '7': return null; default: diff --git a/杜康好客-v3-PRD.md b/杜康好客-v3-PRD.md index 1db0a03..58cec30 100644 --- a/杜康好客-v3-PRD.md +++ b/杜康好客-v3-PRD.md @@ -48,7 +48,7 @@ | 版本 | 日期 | 说明 | |------|------|------| -| **3.4.13** | 2026-08-05 | 推广码归因统计、核销用户信息、技术支持工单优先级、mini-user 门店/商品/提货/版本/**物流增强(签收照/拨号/ETA/回调)**、H5 登录校验、合伙人微信暂停禁登、**OSS 图片超 10MB 客户端压缩**;开发设计见 [`杜康好客-v3.4.13-体验优化开发文档.md`](./杜康好客-v3.4.13-体验优化开发文档.md) | +| **3.4.13** | 2026-08-05 | 推广码归因统计、核销用户信息、技术支持工单优先级、mini-user 门店/商品/提货/版本/**物流增强(签收照/拨号/ETA/路由回调签收→已完成)**、H5 登录校验、合伙人微信暂停禁登、**OSS 图片超 10MB 客户端压缩**;开发设计见 [`杜康好客-v3.4.13-体验优化开发文档.md`](./杜康好客-v3.4.13-体验优化开发文档.md) | --- diff --git a/杜康好客-v3-现状对照.md b/杜康好客-v3-现状对照.md index c806696..3a88911 100644 --- a/杜康好客-v3-现状对照.md +++ b/杜康好客-v3-现状对照.md @@ -341,7 +341,7 @@ C2~C7、C14 见 §1.3。 | H5 登录前端校验 | ✅ | partner/shop LoginPage | | mini-user 门店体验 | ✅ | 电话脱敏/埋点、门头 aspectFit、套餐折叠 | | mini-user 商品/提货 | ✅ | 去分享、首图 preview、提货确认弹框 | -| mini-user 版本/物流 | ✅ | 摘要 + 签收照 + 拨号 + 时间线 + ETA + `/callbacks/courier/xfx/track` | +| mini-user 版本/物流 | ✅ | 摘要 + 签收照 + 拨号 + 时间线 + ETA;回调签收→**COMPLETED** | | OSS 大图压缩 | ✅ | shared-ui compressImage;四端 upload + mini 头像 | | 文档 | ✅ | PRD §0.5 + v3.4.13 开发文档 | diff --git a/杜康好客-v3.4.13-体验优化开发文档.md b/杜康好客-v3.4.13-体验优化开发文档.md index c953ad1..f4ee091 100644 --- a/杜康好客-v3.4.13-体验优化开发文档.md +++ b/杜康好客-v3.4.13-体验优化开发文档.md @@ -94,7 +94,17 @@ POST https://api-test.dukanghaoke.com/api/v1/callbacks/courier/xfx/track | 100102 | 路由查询 | `getTrack` | | 100108 | 签收照片 | `getSignPhotos` → OSS → `signPhotoUrls` | | 100301 | 预估送达 | `checkDeliveryCoverage` → `estimatedArrival` | -| 回调 | 路由推送 | `parseTrackCallback` + `mapTrackStatus` | +| 回调 | 路由推送 | `parseTrackCallback` + `mapTrackStatus`(**status=5 / statusName 含「签收」→ 订单 `COMPLETED`**) | + +**路由回调状态映射(小飞侠)** + +| 小飞侠 status / statusName | 系统订单状态 | +|---------------------------|--------------| +| 1 下单 | `OUT_WAREHOUSE` | +| 2 取件 / 3 中转 | `SHIPPING` | +| 4 派件 | `SHIPPING` | +| **5 签收** / statusName **已签收** | **`COMPLETED`(已完成)** | +| 7 取消 | 仅记录日志,不改订单 | ## 5. 数据表 @@ -112,6 +122,6 @@ POST https://api-test.dukanghaoke.com/api/v1/callbacks/courier/xfx/track - [ ] 合伙人/门店登录空字段前端提示;暂停合伙人微信登录被拒 - [ ] mini-user:电话脱敏、拨打埋点、提货确认、无分享按钮、首图 preview、门头/套餐正常 - [ ] mini-user:配送中物流摘要 + 签收照预览 + 电话拨号 + 时间线旧→新全点亮 + 预估送达 -- [ ] 小飞侠路由回调 `POST /callbacks/courier/xfx/track` 可推进订单状态且幂等 +- [ ] 小飞侠路由回调 `POST /callbacks/courier/xfx/track`:status=5 或 statusName 已签收 → 订单 **COMPLETED**;重复回调幂等 - [ ] 各端上传 >10MB 图片自动压缩后可上传;仍超限有明确报错 - [ ] `pnpm lint` 无新增错误