Files
LabelChange-server/.trae/documents/handling_no_scan_time_logic.md
2026-06-01 16:30:29 +08:00

5.9 KiB
Raw Blame History

没有首次扫描时间的包裹处理逻辑 - 说明文档

更新日期: 2026-05-16
主题: 边界情况处理 - 当包裹没有扫描记录时
状态: 编译通过


问题说明

场景如果一个交接单标签率达到了80%,但其中有些包裹从未被扫描过(即没有首次扫描时间),应该如何处理?

当前SQL逻辑

WHERE l.Label IS NOT NULL AND l.Label != '' 
  AND (
    SELECT MIN(ls.CreatedAt)
    FROM label_scan_history ls
    WHERE ls.NeutralWaybillNumber = l.NeutralWaybillNumber
  ) > l.LabelRetrievedAt

问题分析

  • label_scan_history 中没有记录时,MIN(ls.CreatedAt) 返回 NULL
  • NULL > l.LabelRetrievedAt 的比较结果是 NULL未知
  • 在 CASE WHEN 中NULL 被视为 FALSE
  • 这些包裹不被计入"高标签率"的分子
  • 导致整个交接单的冻结标签率会偏低

处理方案

方案选择

选择:当没有首次扫描时间时,按低标签率处理

原因

  1. 业务逻辑

    • 如果一个包裹从未被扫描,说明它还未开始作业
    • 标签的作用是在作业过程中发挥作用
    • 如果作业未开始,标签的可用性无法判断
    • 保守处理:默认认为标签在此时不可用
  2. 风险规避

    • 避免高估标签率
    • 确保考核时间的合理性
  3. 数据质量

    • 如果包裹从未被扫描,可能说明:
      • 包裹尚未送达仓库
      • 包裹信息不完整
      • 系统记录有缺失

SQL实现细节

当前逻辑

冻结标签率 = (最早扫描时间 > 标签推送时间的包裹数) / 总包裹数

处理规则:
IF 最早扫描时间 IS NOT NULL THEN
  IF 最早扫描时间 > 标签推送时间 THEN
     计入高标签率分子
  ELSE
     不计入高标签率分子
  END IF
ELSE
  -- 没有扫描时间
   默认不计入高标签率分子(按低标签率处理)
END IF

具体场景示例

场景1交接单中的所有包裹都没有扫描记录

交接单A
├─ 总包裹数100
├─ 有标签的包裹80
├─ 扫描过的包裹0全部未扫描
├─ 最早扫描时间NULL
└─ 冻结标签率计算:
   分子 = 0因为没有满足"最早扫描时间 > 标签推送时间"的包裹)
   分母 = 100
   冻结标签率 = 0%(低标签率)

考核规则:按低标签率处理(完成即达标)

场景2交接单中的部分包裹没有扫描记录

交接单B
├─ 总包裹数100
├─ 有标签的包裹90
├─ 扫描过的包裹70
│  ├─ 其中:标签推送时间 < 扫描时间的包裹60
│  └─ 其中:标签推送时间 >= 扫描时间的包裹10
└─ 未扫描的包裹30
   └─ 这30个包裹不计入高标签率分子

冻结标签率计算:
分子 = 60符合"最早扫描时间 > 标签推送时间"的包裹)
分母 = 100
冻结标签率 = 60%(低标签率)

考核规则:按低标签率处理(完成即达标)

场景3交接单中大部分包裹有扫描记录少数没有

交接单C
├─ 总包裹数100
├─ 有标签的包裹95
├─ 扫描过的包裹99
│  ├─ 其中:最早扫描时间 > 标签推送时间的包裹85
│  └─ 其中:最早扫描时间 <= 标签推送时间的包裹14
└─ 未扫描的包裹1
   └─ 这1个包裹不计入高标签率分子

冻结标签率计算:
分子 = 85满足条件的包裹
分母 = 100
冻结标签率 = 85%(高标签率)

考核规则按高标签率处理16点分段

对各个CTE的影响

InterchangeUnitLabelRates

计算逻辑

labeled_requests = COUNT(DISTINCT CASE 
                    WHEN l.Label IS NOT NULL 
                      AND MIN(ls.CreatedAt) > l.LabelRetrievedAt
                    THEN l.Id 
                  END)

对没有扫描时间的包裹

  • 自动不计入 labeled_requests
  • 因此不会虚高冻结标签率

DailyHighLabelRateShould

逻辑:根据 label_rate_percent >= 80 判断

对影响

  • 如果因为没有扫描记录导致冻结标签率 < 80%
  • 该交接单会被分类到"低标签率"
  • 所有包裹都按低标签率规则处理

DailyLowLabelRateShould

逻辑:根据 label_rate_percent < 80 判断

对影响

  • 包含没有扫描记录的交接单
  • 这些包裹按完成即达标处理
  • 符合保守处理的原则

数据质量检查建议

建议1监控未扫描的包裹

在报表中补充一个指标:

未扫描包裹数 = COUNT(DISTINCT 订单) WHERE 首次扫描时间 IS NULL
未扫描率 = 未扫描包裹数 / 总包裹数

建议2定期检查异常

IF 未扫描率 > 某个阈值例如5% THEN
  → 报警,检查系统是否有问题
  → 检查数据导入是否完整
END IF

建议3与现场对账

定期与现场对账,确认:

  • 是否真的有包裹未被扫描
  • 还是系统记录有缺失

总结

当前处理方式

没有首次扫描时间 
  ↓
不被计入高标签率分子
  ↓
冻结标签率偏低(或保持原来的水平)
  ↓
按低标签率规则处理(完成即达标)

优点

  1. 安全保守:避免高估标签率
  2. 符合业务逻辑:作业未开始时,标签不可用
  3. 自动处理无需特殊编码SQL逻辑自动应对
  4. 考核公平:低标签率的包裹按更宽松的规则考核

可能的改进

如果后续发现有频繁的未扫描现象,可以:

  1. 加强数据导入的完整性检查
  2. 增加数据质量监控指标
  3. 与现场沟通,了解根本原因
  4. 根据实际情况调整处理策略

编译状态

编译成功 (exit code 0)

  • SQL逻辑已加注释明确说明处理方式
  • 无编译错误
  • 业务逻辑清晰