6.7 KiB
6.7 KiB
24小时换单率修复 - 完成总结
修复完成日期:2026-05-16
编译状态:✅ 成功(exit code: 0)
修复概述
根据用户的最终业务逻辑澄清,已完成24小时换单率的根本性修复。核心改进:使用作业时标签率(基于最早扫描时间)替代现在标签率,确保分子分母维度一致。
核心问题与解决方案
问题:为什么超过100%?
根本原因:
- 分子按完成日期分组:某天完成的包裹(可能来自多天到货)
- 分母按到货日期分组:某天到货的应该完成的包裹
- 导致分子 >> 分母:例如分子=130,分母=50 → 260%
更深层问题:
- 用的是"现在的标签率"判断,而不是"作业时的标签率"
- 作业决策在最早扫描时刻做的,此时的标签率是固定的
- 用错误的标签率判断导致错误的包裹被纳入24H统计
实施的三大关键修改
修改1:创建"作业时标签率" CTE
新增CTE:InterchangeUnitLabelRatesAtFirstScan(第760-791行)
作业时标签率 = 最早扫描时间之前推送的标签数 / 总包裹数
原理:
- 最早扫描时间 = 任何Result值的最早扫描记录
- 在这个时刻,标签率是"冻结"的
- 这个标签率决定了包裹是否纳入24H考核
修改2:修改考核时间逻辑
位置:ArrivalRequests CTE(第802-843行)
改变:
原来:用现在的标签率判断 (label_rate_percent)
现在:用作业时标签率判断 (label_rate_at_first_scan)
含义:
- 作业时标签率≥80% → 设定考核时间(16点前后不同)
- 作业时标签率<80% → 无考核时间(完成即达标)
结果:每个包裹的考核方式由其作业时的标签率决定,而不是最终标签率
修改3:分子分母维度对齐
分母改为使用作业时标签率(第1113-1115行):
FROM InterchangeUnitLabelRatesAtFirstScan
WHERE label_rate_at_first_scan >= 80
分子改为按到货日期分组(第1047、1066行):
GROUP BY DATE(CONVERT_TZ(ar.到货时间, '+00:00', '-05:00'))
结果:
- 分子:某天到货、作业时标签率≥80%、已完成的包裹
- 分母:某天到货、作业时标签率≥80%的全部包裹
- 维度一致,分子 ≤ 分母
修复前后对比
修复前(有问题)
DailyBeforeNoonPassed(分子):
└─ GROUP BY 首次成功日期
DailyAfternoonPassed(分子):
└─ GROUP BY 首次成功日期
DailyHighLabelRateShould(分母):
└─ GROUP BY 到货日期
结果:日期维度不同,导致分子 >> 分母 → 超过100%
修复后(正确)
DailyBeforeNoonPassed(分子):
├─ GROUP BY 到货日期 ✓
├─ WHERE 作业时标签率≥80% ✓
└─ AND 完成时间 <= 考核时间 ✓
DailyAfternoonPassed(分子):
├─ GROUP BY 到货日期 ✓
├─ WHERE 作业时标签率≥80% ✓
└─ AND 完成时间 <= 考核时间 ✓
DailyHighLabelRateShould(分母):
├─ GROUP BY 到货日期 ✓
├─ FROM InterchangeUnitLabelRatesAtFirstScan
└─ WHERE 作业时标签率≥80% ✓
结果:日期维度一致,分子 ≤ 分母 → 0-100%
修改的具体代码位置
| 操作 | 文件 | 行号 | 内容 |
|---|---|---|---|
| 新增CTE | LabelReplaceRepository.cs | 760-791 | InterchangeUnitLabelRatesAtFirstScan |
| 修改ArrivalRequests | LabelReplaceRepository.cs | 802-843 | 新增作业时标签率字段,修改考核时间逻辑 |
| 修改DailyHighLabelRateShould | LabelReplaceRepository.cs | 1100-1117 | 改用作业时标签率判断 |
| 修改DailyBeforeNoonPassed | LabelReplaceRepository.cs | 1033-1050 | 改按到货日期分组 |
| 修改DailyAfternoonPassed | LabelReplaceRepository.cs | 1052-1069 | 改按到货日期分组 |
预期效果
修复后24H换单率应该表现为:
24H换单率 = (该天到货、作业时标签率≥80%、已完成的包裹)
/ (该天到货、作业时标签率≥80%的全部包裹) × 100%
特性:
✅ 0% ≤ 24H换单率 ≤ 100%
✅ 分子 ≤ 分母(数学上正确)
✅ 可以手工验证(选一天数据验证)
✅ 符合业务含义(该天到货订单24小时内完成率)
测试建议
第1步:查询某一天的统计数据
SELECT
日期,
高标签率应该换单数 AS 分母,
16点前考核通过包裹数 + 16点后考核通过包裹数 AS 分子,
24H换单率
FROM 日级报表
WHERE 日期 = '2026-05-15'
验证:分子 ≤ 分母,24H换单率 ≤ 100%
第2步:检查作业时标签率vs现在标签率
某些订单的标签率会在作业时间之后继续增加,导致:
- 作业时标签率 < 80% → 按完成即达标处理
- 现在标签率 ≥ 80% → 但不会被纳入24H考核(因为作业时没有达到80%)
这是正确行为,因为决策是在作业开始时做的。
第3步:验证边界情况
测试以下场景:
- 某天到货100个订单,作业时79% → 应该2-48小时内完成
- 某天到货100个订单,作业时80% → 应该按16点前后分别设定考核时间
关键设计理念
"冻结"的标签率
时间线:
┌─ 标签推送 → 标签率: 50%
│
├─ 最早扫描 ← 作业时标签率冻结在这个时刻
│ (标签率: 60%)
│
├─ 继续扫描和标签推送 → 标签率: 70% → 85%
│ (但不影响作业策略,已经确定要按60%处理)
│
└─ 首次成功 → 完成时间确定
决策依据:作业时标签率(60%)而不是最终标签率(85%)
两种场景的处理
场景A:作业时标签率≥80%
- 需要在规定时间内完成
- 完成时间 ≤ 考核时间 → 考核通过
- 完成时间 > 考核时间 → 考核不通过
场景B:作业时标签率<80%
- 无需在特定时间内完成
- 完成即达标,不需要考核时间
编译验证
✅ 编译成功
- 命令:
dotnet build src/DAL/DAL.csproj - 结果:exit code 0
- 时间:2026-05-16
后续行动
- 部署到测试环境:运行修复后的查询
- 数据验证:确认24H换单率 ≤ 100%
- 手工抽查:选择3-5个日期,手工验证分子分母
- 监控:上线后监测是否有异常数据