fix(wle): 转仓代发(转x00005)不算转运异常 + 导出复用页面缓存 #84

Merged
yanhui merged 1 commits from yanhui-wle-transfer-cache-20261023 into main 2026-10-23 16:03:16 +08:00

1 Commits

Author SHA1 Message Date
e02d1f6d66 fix(wle): 转仓代发(转x00005)不算转运异常 + 导出复用页面缓存
两件事,都是 2026-10-23 业务反馈直接引起的。

## 1. 转仓代发不再核对异常

业务反馈:崔桥工厂仓的单 351668937728 被判「未揽收」异常,快递却是「曹县韵达小件」,
而且这单在后台是信誉订单。

实查宽表:这单 `warehouse_name=简尚-崔桥工厂仓`,但 `order_labels` 里带一条
`转x00005` —— 聚水潭「转仓」操作留下的痕迹。记账仓还是崔桥,货却由目标仓
(x00005 = 曹县)实际发出,承运账号也跟着变成曹县韵达小件。结果就是原仓的
物流状态永远停在「未揽收 / 无物流单」,报出来全是假异常。

判据:`order_labels` 命中 `/转\s*[xX]\s*\d{3,}/`(不写死单个编码,后续可能出现
x00006)。实测近 30 天 12 仓:`转x00005` 438 单,报未揽收类 46 单(已签收 371 /
无物流单 31 / 运输中 20 / 未揽收 15);快递分布 曹县韵达小件 133、邮政快递包裹POSTB 124。

口径要点:
- 与「转空包」(信誉单,发空包)严格区分 —— 转仓是**真发货**,只是不从记账仓发;
- 所以**保留发货分母**,只从异常清单摘掉(与「现场拦截」同类,不稀释异常率);
- 新增 `exclusions.transferPackages/transferOrders/transferReasons`,
  前端页脚与钉钉正文各加一行说明。

## 2. 缓存键只按核验日(修导出卡顿)

原来键是 `${核验日}|${limit}`:页面传 1000、导出传 5000 → 两份缓存互不命中,
点一次导出就要把整轮重算一遍。可 `limit` 只影响最后 `slice(0, limit)`,
异常实际才几十行,扫库成本一模一样。

改为:缓存只存**全量明细**(键 = 核验日),limit 在出口 `finalizeDetail()` 里截断。
生产实测(修复前,容器内直调):页面冷启 189s、命中缓存 0ms、
**页面已缓存时点导出仍要 317s**;修复后导出复用页面结果 1~3ms。

## 验证

- 后端单测 50/50(新增:转仓标签识别 8 条断言、转仓单不进异常但进分母、
  导出复用页面缓存不重查、小 limit 不污染缓存)
- 全量 `npm run check` 474 项 / 472 过,2 项为既有环境失败(Windows 权限位、负缓存需隧道故障态)
- 前端 eslint 0、`npm run build` 通过(含 router lazy 静态检查)
- 真实库(10-23 批):异常 73 单,转仓剔除 1 单(正是 9894520),目标单已消失;
  导出在页面加载后 3ms 返回 73 行
2026-10-23 10:46:26 +08:00