上传源代码版本
This commit is contained in:
238
.trae/documents/handling_no_scan_time_logic.md
Normal file
238
.trae/documents/handling_no_scan_time_logic.md
Normal file
@@ -0,0 +1,238 @@
|
||||
# 没有首次扫描时间的包裹处理逻辑 - 说明文档
|
||||
|
||||
**更新日期**: 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逻辑已加注释,明确说明处理方式
|
||||
- 无编译错误
|
||||
- 业务逻辑清晰
|
||||
|
||||
Reference in New Issue
Block a user