fix(wst): 发货时效剔除「已作废」单 —— 问题单 / 发货前售后 / 售后已作废三条兜底 #82

Merged
yanhui merged 1 commits from yanhui-wst-void-fix-20261022 into main 2026-10-22 17:55:35 +08:00
Collaborator

目的与范围

业务反馈 3 单在聚水潭后台都已作废,却仍出现在「仓储中心 24 小时发货时效」的超时明细里:

线上单号 so_id 内部单号 状态表 order_status_name 订单表 status 订单表 labels 出库单
3655421011854634 9823980 发货中 / send_time 空 Question 含**「发货前售后」** 5943740=Delete(作废) + 5943874=待确认
3658479011191285 9880810 发货中 / send_time 空 Question 无 5975373=待确认
110215007857459363 9889575 发货中 / send_time 空 Delivering 「品牌直发」 无记录

实测这三单在 13:00 轮就是页面上的全部超时单(overdueUnshipped=3)。

根因:页面只认状态表 jst_order_express_details,这三单在上游仍是「发货中」+ send_time 空、售后「暂无售后」——作废状态没同步过来。而代码里唯一的作废兜底只认订单表 status ∈ Merged/Split/Cancelled 与 is_merge/is_split,覆盖不到 Question 和「发货前售后」标签。

改动(仅 3 个文件)

  • warehouseShipTimelinessRegistry.js:新增 VOID_QUESTION_STATUS='Question'、VOID_ORDER_LABEL_KEYWORDS=['发货前售后']、AFTERSALE_VOID_STATUS='已作废';
  • warehouseShipTimelinessService.js:
    • 状态表主查询多投一列 aftersale_status_name;
    • 回订单表补事实时多投一个 CASE WHEN labels LIKE N'%发货前售后%' THEN 1 ELSE 0 END AS presaleVoid
      (不传 labels 原文,避免宽列回表:历史实测同一 WHERE 取多列会从 0.7s 拖到 54s);
    • 主循环在「发货中」分支之后判这三种作废证据,命中则计入 voidCount、不进考核。

⚠️ 一个必须说明的实现细节

Question 不能直接塞进 VOID_ORDER_STATUS:那个数组在状态分类之前判定,而订单表 Question 的单有一大批在状态表是「异常」。实测直接加进去会让 heldCount 从 472 → 10(462 单「异常待处理」被从清单里吞掉)。

所以单独放在 state === '发货中' 之后判 —— 异常/待审核清单完全不受影响。

同步与兼容性

  • 不改表结构、不改接口字段、不改前端;summary.voidCount 语义不变(作废+已发剔除数)。
  • 只收紧「发货中」分支的作废判定,不回退任何既有判据。
  • 数据源仍是 rpt.jst_order_express_details,无新增查询次数(backfill 仍是 1 趟,只多 1 个布尔列)。

验证

单测:node --test backend/test/warehouseShipTimeliness.test.js → 19/19 通过
(新增 38/39/40 三条作废形态用例;15 号用例额外锁定 heldCount 不被 Question 判据影响)

真实库(13:00 轮,force:true):

指标 改前 改后
overdueUnshipped 3 1
heldCount 472 472(未被吞)
voidCount 4442 4444(恰好 +2)
9823980 超时 已剔除
9880810 超时 已剔除
9889575 超时 仍在(见下)

耗时:冷查 42.6s(改前生产同轮 40~80s 区间),labels 的 CASE WHEN ... LIKE 未带来可感知开销。

⚠️ 待业务确认:9889575 未剔除

110215007857459363(内部 9889575,得物-米客米家,睢宁仓)在库里查不到任何作废痕迹:

  • 状态表:发货中 + send_time 空 + 售后「暂无售后」;
  • ���单表:Delivering(发货中),labels「品牌直发/商家指定物流/平台分配仓库」,无「发货前售后」;
  • 出库单:jst_salesOutboundInfo / jst_qmcust_salesoutbound 都没有记录,也没有运单号。

代码里对 Delivering 有明确注释:「Delivering 是已审核待出库,正是本页要考核的对象,算成已发整页就空了」,所以本次没有动它。

若业务确认这单同样不该考核,需要业务给一个可判据的特征(例如「品牌直发」标签不考核本仓),再单独提一次改动。

风险与回退

  • 影响面:近 30 天「状态表发货中+未发」里 Question 6 单、「发货前售后」20 单,量级小;
  • 若业务认为 Question 单仍需考核 → 把 VOID_QUESTION_STATUS 置空即可恢复;
  • 回退:直接 revert 本 PR,无数据迁移、无配置变更。
## 目的与范围 业务反馈 3 单在聚水潭后台**都已作废**,却仍出现在「仓储中心 24 小时发货时效」的超时明细里: | 线上单号 so_id | 内部单号 | 状态表 `order_status_name` | 订单表 `status` | 订单表 labels | 出库单 | |---|---|---|---|---|---| | 3655421011854634 | 9823980 | 发货中 / send_time 空 | **Question** | 含**「发货前售后」** | 5943740=**Delete**(作废) + 5943874=待确认 | | 3658479011191285 | 9880810 | 发货中 / send_time 空 | **Question** | 无 | 5975373=待确认 | | 110215007857459363 | 9889575 | 发货中 / send_time 空 | **Delivering** | 「品牌直发」 | **无记录** | 实测这三单在 13:00 轮就是页面上的**全部**超时单(`overdueUnshipped=3`)。 **根因**:页面只认状态表 `jst_order_express_details`,这三单在上游仍是「发货中」+ `send_time` 空、售后「暂无售后」——作废状态没同步过来。而代码里唯一的作废兜底只认订单表 `status ∈ Merged/Split/Cancelled` 与 `is_merge/is_split`,覆盖不到 `Question` 和「发货前售后」标签。 **改动(仅 3 个文件)** - `warehouseShipTimelinessRegistry.js`:新增 `VOID_QUESTION_STATUS='Question'`、`VOID_ORDER_LABEL_KEYWORDS=['发货前售后']`、`AFTERSALE_VOID_STATUS='已作废'`; - `warehouseShipTimelinessService.js`: - 状态表主查询多投一列 `aftersale_status_name`; - 回订单表补事实时多投一个 `CASE WHEN labels LIKE N'%发货前售后%' THEN 1 ELSE 0 END AS presaleVoid` (**不传 labels 原文**,避免宽列回表:历史实测同一 WHERE 取多列会从 0.7s 拖到 54s); - 主循环在「发货中」分支**之后**判这三种作废证据,命中则计入 `voidCount`、不进考核。 ## ⚠️ 一个必须说明的实现细节 `Question` **不能**直接塞进 `VOID_ORDER_STATUS`:那个数组在状态分类**之前**判定,而订单表 `Question` 的单有一大批在状态表是「异常」。实测直接加进去会让 `heldCount` 从 **472 → 10**(462 单「异常待处理」被从清单里吞掉)。 所以单独放在 `state === '发货中'` 之后判 —— 异常/待审核清单完全不受影响。 ## 同步与兼容性 - 不改表结构、不改接口字段、不改前端;`summary.voidCount` 语义不变(作废+已发剔除数)。 - 只**收紧**「发货中」分支的作废判定,不回退任何既有判据。 - 数据源仍是 `rpt.jst_order_express_details`,无新增查询次数(backfill 仍是 1 趟,只多 1 个布尔列)。 ## 验证 **单测**:`node --test backend/test/warehouseShipTimeliness.test.js` → **19/19 通过** (新增 38/39/40 三条作废形态用例;15 号用例额外锁定 `heldCount` 不被 Question 判据影响) **真实库**(13:00 轮,`force:true`): | 指标 | 改前 | 改后 | |---|---|---| | `overdueUnshipped` | 3 | **1** | | `heldCount` | 472 | **472**(未被吞) | | `voidCount` | 4442 | **4444**(恰好 +2) | | 9823980 | 超时 | **已剔除** | | 9880810 | 超时 | **已剔除** | | 9889575 | 超时 | 仍在(见下) | **耗时**:冷查 42.6s(改前生产同轮 40~80s 区间),`labels` 的 `CASE WHEN ... LIKE` 未带来可感知开销。 ## ⚠️ 待业务确认:9889575 未剔除 `110215007857459363`(内部 9889575,得物-米客米家,睢宁仓)在库里**查不到任何作废痕迹**: - 状态表:`发货中` + `send_time` 空 + 售后「暂无售后」; - ���单表:`Delivering`(发货中),labels「品牌直发/商家指定物流/平台分配仓库」,无「发货前售后」; - 出库单:`jst_salesOutboundInfo` / `jst_qmcust_salesoutbound` **都没有记录**,也没有运单号。 代码里对 `Delivering` 有明确注释:**「Delivering 是已审核待出库,正是本页要考核的对象,算成已发整页就空了」**,所以本次**没有**动它。 若业务确认这单同样不该考核,需要业务给一个可判据的特征(例如「品牌直发」标签不考核本仓),再单独提一次改动。 ## 风险与回退 - 影响面:近 30 天「状态表发货中+未发」里 `Question` 6 单、「发货前售后」20 单,量级小; - 若业务认为 `Question` 单仍需考核 → 把 `VOID_QUESTION_STATUS` 置空即可恢复; - 回退:直接 revert 本 PR,无数据迁移、无配置变更。
yanhui added 1 commit 2026-10-22 17:55:16 +08:00
业务反馈 3 单(so_id 3655421011854634 / 3658479011191285 / 110215007857459363)
在聚水潭后台都已作废,却仍出现在「仓储中心 24 小时发货时效」的超时明细里。

根因:
- 页面只认状态表 jst_order_express_details,这三单 order_status_name 仍是「发货中」
  + send_time 为空;售后状态是「暂无售后」—— 上游没把作废同步过来;
- 现有的作废兜底只认订单表 status ∈ Merged/Split/Cancelled 以及 is_merge/is_split,
  覆盖不到 status=Question(聚水潭后台显示「已作废/问题单」)和 labels 含「发货前售后」。

改动:
- registry 新增 VOID_QUESTION_STATUS='Question'、VOID_ORDER_LABEL_KEYWORDS=['发货前售后']、
  AFTERSALE_VOID_STATUS='已作废';
- 回订单表补事实时增投一个 `CASE WHEN labels LIKE N'%发货前售后%' THEN 1 ELSE 0 END`
  布尔列(不传 labels 原文,避免宽列回表;实测冷查 42.6s,与改前同量级);
- 状态表主查询增投一列 aftersale_status_name;
- 主循环在「发货中」分支之后判这三种作废证据,命中则并入 voidCount、不进考核。

⚠️ Question 不能直接塞进 VOID_ORDER_STATUS:那个数组在状态分类之前判定,
订单表 Question 的单有一大批在状态表是「异常」,会被从「异常待处理」清单里一起吞掉
(实测 heldCount 472 → 10,少掉 462 单)。故单独放在 SHIPPING_STATUS 之后判。

验证:
- 单测 19/19 通过(新增 38/39/40 三条作废形态用例,锁定 heldCount 不被影响);
- 真实库 13:00 轮:超时 3 单 → 1 单(9823980 / 9880810 已剔除),
  heldCount 保持 472,voidCount 4442 → 4444(恰好 +2);
- 剩余 9889575 未剔除:订单表 Delivering、无出库单、无任何作废标记(见 PR 正文说明)。

风险与回退:
- 仅收紧「发货中」分支的作废判定,不回退任何既有判据;
- 若业务认为 Question 单仍需考核,改 VOID_QUESTION_STATUS 一处即可恢复。
yanhui merged commit db1185c19f into main 2026-10-22 17:55:35 +08:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: lunanting/cangku#82
No description provided.