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

239 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 没有首次扫描时间的包裹处理逻辑 - 说明文档
**更新日期**: 2026-05-16
**主题**: 边界情况处理 - 当包裹没有扫描记录时
**状态**: ✅ 编译通过
---
## 问题说明
**场景**如果一个交接单标签率达到了80%,但其中有些包裹**从未被扫描过**(即没有首次扫描时间),应该如何处理?
**当前SQL逻辑**
```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实现细节
**当前逻辑**
```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
**计算逻辑**
```sql
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逻辑已加注释明确说明处理方式
- 无编译错误
- 业务逻辑清晰