fix(wst): 用聚水潭状态终态 + 销售出库单判作废/已发 #93

Merged
yanhui merged 2 commits from yanhui-wst-void-1029 into main 2026-10-29 15:38:52 +08:00
Collaborator

fix(wst): 用聚水潭状态终态 + 销售出库单判作废/已发

业务 2026-10-29 连续两次报同一件事:「作废的订单、已发货的订单还在考核之内」。
第一次给了 9 个内部单号(洛宁仓 16 单),并指明「在聚水潭的销售出库单里面找一下这个作废单据」。

一、13:19 第一轮:状态表终态(commit 1139e4c)

13:00 轮 159 单全部来自停更的 qmcust(停 07:25),订单表里:
status 全 Delivering、send_date 全空、labels 里一个「发货前售后」都没有
→ 老的 presaleVoid 判据(只看订单表 labels)0 命中。

状态镜像表虽也停(11:52),但比订单表新鲜 4 小时,其中 11 单 order_status_name='已取消'。

判据 处理
order_status_name = '已取消' 作废,剔除
order_status_name = '已发货' 已发,剔除
物流状态 ∈ 已揽收/运输中/派送中/已签收/拒收 已发,剔除
send_time 有值 已发,剔除

两个必须避的坑(已写进注释和测试):

  • 售后 aftersale_status_name='已作废' 不是作废单 —— 那是售后单被撤销、订单照常发货(近 2 天 1387 单),当剔会把该考核的全放跑
  • 未揽收 / 无物流单 不算已发 —— 前者只是打了单快递没来取,后者连快递单都没录

二、14:34 第二轮:销售出库单(commit 54518ab)

查出来的事实

9 个点名单在库里三处全部显示「还在发货」:

9992097  订单表=Delivering  出库单=WaitConfirm  状态表=发货中  物流=无物流单

不是判据漏了,是三条数据源全停在作废动作之前(2026-10-29 15:13 实测):

数据源 最后灌库 滞后
jst_Orders 14:45 正常
jst_qmcust_orderlist 13:25 1.8h
状态镜像表 11:52 3.4h
出库单(聚水潭/奇门) 03:10 12.0h ← 作废就落在这张表

聚水潭的作废落在出库单 status='Delete' 上,而这张表今天凌晨 3 点后零写入。

改动

  1. 新增 loadOrderIoStatus():按 o_id 批量取出库单状态(两表、分批 500 / 并发 3)
    判据 = 「该 o_id 下没有任何非 Delete 的出库单」
    • 只对「发货中」生效:全库「出库单全 Delete」的候选单里 127/131 状态表是「异常」,那批还挂着待处理,删出库单更可能是重开单;当成作废剔会让业务在「不计考核」里也看不到 → 丢可见性比漏剔更糟
    • 拆包/重开的单有多张出库单,删一张不算作废(实测 51 单里 7 单是这种)
    • 「没有出库单」绝不判作废:近 3 天未发单 82%(1467/1790)本来就没出库单
  2. 两张出库单表纳入 loadSourceFreshness()。用 local_updated / updateTime(灌库时刻),不能用 modified —— 没单据变更时它天然是旧的,拿它判停更会天天误报
  3. 新增 freshness.voidJudgeReliable,hint 明说「作废单 / 取消单可能判不出来」,并告诉业务去聚水潭「销售出库单」核对
  4. 明细加「销售出库单」列(已作废 / 待出库 / 已出库 / 未建单),导出同步加列

验证

项 结果
WST 单测 27/27(新增:出库单全删必剔 / 拆包重开不剔 / 异常单不剔 / 无出库单不剔 / 停更时提示判据失效 / 源正常时不误报)
后端全量 498/500(2 个既���失败:负缓存 TTL、Windows 文件权限)
前端 lint 干净
真实数据 stateVoidSkipped=195、stateShippedSkipped=17、ioVoidSkipped=11、overdue=16
本地真渲染 表头有「销售出库单」、首行「待出库」、红条列出 5 个数据源停更状态、pageerror 0、console.error 仅 2 条 antd 弃用警告

没解决(不掩盖)

这 9 单今天仍然判不出作废 —— 数据没进来,判据再准也没用。
根子在 ETL:出库单表停 12 小时、状态表停 3.4 小时、qmcust 停 1.8 小时。
ETL 恢复后判据立即生效;但那 9 单是否作废,仍需 IT 修同步或业务在聚水潭复核。

顺带说明:出库单 Delete 只能覆盖一部分作废(近 7 天 2209 单 Delete vs 订单表 7742 单 Cancelled),
大部分作废仍要等订单表同步。所以停更告警比判据更重要。

# fix(wst): 用聚水潭状态终态 + 销售出库单判作废/已发 业务 2026-10-29 连续两次报同一件事:「作废的订单、已发货的订单还在考核之内」。 第一次给了 9 个内部单号(洛宁仓 16 单),并指明「在聚水潭的**销售出库单**里面找一下这个作废单据」。 ## 一、13:19 第一轮:状态表终态(commit `1139e4c`) 13:00 轮 159 单**全部**来自停更的 qmcust(停 07:25),订单表里: `status` 全 Delivering、`send_date` 全空、`labels` 里**一个**「发货前售后」都没有 → 老的 `presaleVoid` 判据(只看订单表 labels)**0 命中**。 状态镜像表虽也停(11:52),但比订单表新鲜 4 小时,其中 11 单 `order_status_name='已取消'`。 | 判据 | 处理 | |---|---| | `order_status_name = '已取消'` | 作废,剔除 | | `order_status_name = '已发货'` | 已发,剔除 | | 物流状态 ∈ 已揽收/运输中/派送中/已签收/拒收 | 已发,剔除 | | `send_time` 有值 | 已发,剔除 | **两个必须避的坑**(已写进注释和测试): - 售后 `aftersale_status_name='已作废'` **不是**作废单 —— 那是售后单被撤销、订单照常发货(近 2 天 1387 单),当剔会把该考核的全放跑 - `未揽收` / `无物流单` **不算**已发 —— 前者只是打了单快递没来取,后者连快递单都没录 ## 二、14:34 第二轮:销售出库单(commit `54518ab`) ### 查出来的事实 9 个点名单在库里**三处全部显示「还在发货」**: ``` 9992097 订单表=Delivering 出库单=WaitConfirm 状态表=发货中 物流=无物流单 ``` **不是判据漏了,是三条数据源全停在作废动作之前**(2026-10-29 15:13 实测): | 数据源 | 最后灌库 | 滞后 | |---|---|---| | `jst_Orders` | 14:45 | 正常 | | `jst_qmcust_orderlist` | 13:25 | 1.8h | | 状态镜像表 | 11:52 | 3.4h | | **出库单(聚水潭/奇门)** | **03:10** | **12.0h** ← 作废就落在这张表 | 聚水潭的作废落在出库单 `status='Delete'` 上,而这张表今天凌晨 3 点后零写入。 ### 改动 1. **新增 `loadOrderIoStatus()`**:按 o_id 批量取出库单状态(两表、分批 500 / 并发 3) 判据 = **「该 o_id 下没有任何非 Delete 的出库单」** - **只对「发货中」生效**:全库「出库单全 Delete」的候选单里 **127/131 状态表是「异常」**,那批还挂着待处理,删出库单更可能是重开单;当成作废剔会让业务在「不计考核」里也看不到 → **丢可见性比漏剔更糟** - **拆包/重开**的单有多张出库单,删一张不算作废(实测 51 单里 7 单是这种) - **「没有出库单」绝不判作废**:近 3 天未发单 **82%(1467/1790)本来就没出库单** 2. 两张出库单表纳入 `loadSourceFreshness()`。用 `local_updated / updateTime`(灌库时刻),**不能用 `modified`** —— 没单据变更时它天然是旧的,拿它判停更会天天误报 3. 新增 `freshness.voidJudgeReliable`,hint 明说「作废单 / 取消单可能判不出来」,并告诉业务去聚水潭「销售出库单」核对 4. 明细加「销售出库单」列(已作废 / 待出库 / 已出库 / 未建单),导出同步加列 ## 验证 | 项 | 结果 | |---|---| | WST 单测 | **27/27**(新增:出库单全删必剔 / 拆包重开不剔 / 异常单不剔 / 无出库单不剔 / 停更时提示判据失效 / 源正常时不误报) | | 后端全量 | 498/500(2 个既���失败:负缓存 TTL、Windows 文件权限) | | 前端 lint | 干净 | | 真实数据 | `stateVoidSkipped=195`、`stateShippedSkipped=17`、`ioVoidSkipped=11`、`overdue=16` | | 本地真渲染 | 表头有「销售出库单」、首行「待出库」、红条列出 5 个数据源停更状态、**pageerror 0**、console.error 仅 2 条 antd 弃用警告 | ## 没解决(不掩盖) **这 9 单今天仍然判不出作废** —— 数据没进来,判据再准也没用。 根子在 ETL:出库单表停 12 小时、状态表停 3.4 小时、qmcust 停 1.8 小时。 ETL 恢复后判据立即生效;但那 9 单是否作废,仍需 IT 修同步或业务在聚水潭复核。 顺带说明:出库单 `Delete` 只能覆盖一部分作废(近 7 天 2209 单 Delete vs 订单表 7742 单 Cancelled), **大部分作废仍要等订单表同步**。所以停更告警比判据更重要。
yanhui added 1 commit 2026-10-29 13:46:41 +08:00
业务 2026-10-29 第三次报同一件事:13:00 轮里作废的单、已经发货的单还在考核。
根因不是判定写错,而是**订单两表各自停更**,停更期间聚水潭做的「取消 / 发货」
订单表完全看不到 —— status 仍是 Delivering、send_date 仍是空。

## 现场证据(2026-10-29 13:00 轮)

- 当天 qmcust 停在 07:25(6 小时),13:00 轮 159 单**全部**来自它
- 订单表侧:159 单 status 全 Delivering、send_date 全空、labels 里**没有**
  「发货前售后」⟹ 原来的 `presaleVoid` 判据(订单表 labels 含关键词)完全失效
- 状态镜像表(停在 11:52,比订单表新鲜 4 小时):
  `order_status_name='已取消'` **11 单**,`order_labels` 里才有「发货前售后」
  「已打印被取消」;其余 145 单「发货中」

qmcust 13:25 补数后重算,误判量比想象大得多:
**overdue 159 → 16,作废剔除 195 单、已发剔除 17 单。**

## 改动

判据(新增,排在窗口判断与「不计考核」之前):

| 判据 | 处理 |
|---|---|
| `order_status_name='已取消'` | 作废,剔除(计 `stateVoidSkipped`) |
| `send_time` 有值 | 已发,剔除 |
| `order_status_name='已发货'` | 已发,剔除 |
| `logistic_status_name` ∈ 已揽收/运输中/派送中/已签收/拒收 | 已发,剔除 |

- `loadOaConfirmInfo` → `loadStateInfo`,同一次 IN 多取 4 个语义列,**不增加往返**
- ⚠️ **判据只用 `order_status_name`**:`aftersale_status_name='已作废'` 是「售后单被撤销、
  订单照常发货」,近 2 天 1387 单全是这种,混为一谈会把该考核的单全放跑
- ⚠️ `未揽收` / `无物流单` **不算已发**(后者是连快递单都没录,当天 39/159 单是这种)
- 状态镜像表纳入 `dataSources` 停更监控(它停了,「取消了吗」的依据就过期了)
- 明细/导出新增「聚水潭状态」「物流状态(聚水潭)」「状态表抓取时间」;
  页面「发货状态」列改优先显示聚水潭终态,与订单表不一致时打 ⚠

## 验证

- 后端 `npm run check` 496/498(2 个失败是老问题:负缓存 TTL、Windows 文件权限)
- WST 单测 **25/25**,新增两组:终态剔除(含「售后已作废不能误剔」的反向保护)、
  状态表纳入新鲜度监控
- 真实数据(本地直连生产 MSSQL,2026-10-29 13:00 轮):
  `overdue=16 / stateVoidSkipped=195 / stateShippedSkipped=17`,
  明细里「已取消」残留 **0**;剩余 16 单全是河南洛宁仓「发货中 + 无物流单」的真积压
- 作废证据交叉核对:状态表近 2 天「已取消」59263 单,94% 带「发货前售后」标签,
  与业务口径一致
yanhui added 1 commit 2026-10-29 15:16:41 +08:00
业务 14:34 点名 9992097 / 9992098 / 9992924 / 9992925 / 9992926 /
9993284 / 9993285 / 9995464 / 9995465「洛宁仓 16 单都是作废订单,为啥还在
考核之内」,并指明「在聚水潭的销售出库单里面找一下这个作废单据」。

## 查出来的事实

这 9 单在库里**三处全部显示「还在发货」**:

  订单表 qmcust      status=Delivering、send_date 空
  销售出库单         status=WaitConfirm(待出库)
  状态镜像表         order_status_name=发货中、logistics=无物流单

不是判据漏了,是**三条数据源全停在作废动作之前**(2026-10-29 15:13 实测):

  jst_Orders             14:45  正常
  qmcust                 13:25  滞后 1.8h
  状态镜像表              11:52  滞后 3.4h
  出库单(聚水潭/奇门)      03:10  滞后 12.0h  ← 作废就落在这张表上

聚水潭的作废落在**出库单** `status='Delete'` 上,而这张表今天凌晨 3 点后
零写入,所以上午作的废一条都没进来

## 改动

1. 新增 `loadOrderIoStatus()`:按 o_id 批量取出库单状态(两表、
   分批 500 / 并发 3),判据是 **「该 o_id 下没有任何非 Delete 的出库单」**。
   - 只对「发货中」生效:全库「出库单全 Delete」的候选单里 127/131
     状态表是「异常」,那批还挂着待处理,删出库单更可能是重开单,
     当成作废剔会让业务在「不计考核」里也看不到 → 丢可见性比漏剔更糟
   - 拆包/重开的单有多张出库单,删一张不算作废(实测 51 单里 7 单是这种)
   - **「没有出库单」绝不判作废**:近 3 天未发单 82%(1467/1790)本来就没出库单
2. 两张出库单表纳入 `loadSourceFreshness()`(用 local_updated / updateTime
   灌库时刻,**不能用 modified**,否则没变更时天天误报)
3. 新增 `freshness.voidJudgeReliable` + hint 明说「作废单/取消单可能判不出来」,
   告诉业务去聚水潭「销售出库单」核对
4. 明细加「销售出库单」列(已作废/待出库/已出库/未建单),导出同步加列

## 验证

- WST 单测 27/27(新增:出库单全删必剔 / 拆包重开不剔 / 异常单不剔 /
  无出库单不剔 / 停更时提示作废判不出来 / 源正常时不误报)
- 后端全量 498/500(2 个既有失败:负缓存 TTL、Windows 文件权限)
- 真实数据:ioVoidSkipped=11(发货中 + 出库单全删),overdue 仍 16 单
- 本地真渲染:表头有「销售出库单」、首行显示「待出库」、
  红条列出 5 个数据源停更状态、**pageerror 0**

## 没解决(已在页面明说,不掩盖)

这 9 单今天仍然判不出作废 —— 数据没进来,判据再准也没用。
根子在 ETL:出库单表停 12 小时。ETL 恢复后判据立即生效,
但那 9 单是否作废仍需 IT 修同步或业务在聚水潭复核。
yanhui changed title from fix(wst): 用聚水潭状态终态判作废/已发,修「作废单已发单还在考核里」 to fix(wst): 用聚水潭状态终态 + 销售出库单判作废/已发 2026-10-29 15:17:10 +08:00
yanhui merged commit b955e78ba2 into main 2026-10-29 15:38:52 +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#93
No description provided.