fix(wle): 转仓代发(转x00005)不算转运异常 + 导出复用页面缓存 #84
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "yanhui-wle-transfer-cache-20261023"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景:两个业务反馈
① 崔桥工厂仓的单,快递却是「曹县韵达」,还是信誉订单
单号
351668937728(内部 9894520)。实查宽表只有一行:关键就是
转x00005—— 聚水潭「转仓」操作留在标签里的痕迹。记账仓是崔桥,货实际由目标仓(x00005 = 曹县)发出,承运账号也跟着换成曹县韵达小件。原仓的物流状态必然停在
「未揽收 / 无物流单」,报出来全是假异常。
顺带说明为什么没命中「信誉单」判据:这单在
jst_Orders里是status=Sent、type=普通订单、question_type=null,数仓里没有任何信誉单标记;而现有信誉单判据只认标签
转空包(真正的信誉单长那样:近 14 天转空包发货506 单全在「简尚-信誉订单仓」)。② 导出很卡
getLogisticsExceptionExportRows()用limit=5000,页面/list用limit=1000,而缓存键是
${核验日}|${limit}→ 导出永远命中不到页面那份缓存,每次点导出都整轮重算。但
limit只影响最后slice(0, limit)(异常实际才几十行),扫库成本完全一样。改动
1. 转仓代发不计异常
registry新增TRANSFER_WAREHOUSE_LABEL_PATTERN = /转\s*[xX]\s*\d{3,}/+matchTransferWarehouse()。不写死转x00005,后续出现 x00006 自动覆盖。service主循环在classify()之后、现场拦截之前判定。与「现场拦截」同类,这样异常率不会被错误放大)。
exclusions.transferPackages / transferOrders / transferReasons;前端页脚、钉钉正文各加一行说明。
2. 缓存键只按核验日
batch.verifyDate),limit 在出口finalizeDetail()截断。truncated按实际全量条数算,不再受调用方 limit 影响。数据支撑(近 30 天,12 仓)
转x00005转空包发货转x00005状态分布:已签收 371 / 无物流单 31 / 运输中 20 / 未揽收 15 —— 说明绝大多数正常,只有「记账仓看别仓货」这一小撮会误报。
验证
转空包反例)、转仓单不进异常但进分母、导出复用页面缓存不重查、小 limit 不污染缓存。
npm run check474 项 / 472 过,2 项为既有环境失败(Windows 权限位、负缓存需隧道故障态)。npm run build通过(含 router lazy 静态检查)。导出在页面加载后 3ms 返回 73 行(修复前同样操作要 317s)。
风险
两件事,都是 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 行