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

242 lines
6.7 KiB
Markdown
Raw Permalink 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.

# 24小时换单率修复 - 完成总结
**修复完成日期**2026-05-16
**编译状态**:✅ 成功exit code: 0
---
## 修复概述
根据用户的最终业务逻辑澄清已完成24小时换单率的根本性修复。核心改进**使用作业时标签率(基于最早扫描时间)替代现在标签率**,确保分子分母维度一致。
---
## 核心问题与解决方案
### 问题为什么超过100%
**根本原因**
1. **分子按完成日期分组**:某天完成的包裹(可能来自多天到货)
2. **分母按到货日期分组**:某天到货的应该完成的包裹
3. **导致分子 >> 分母**:例如分子=130分母=50 → 260%
**更深层问题**
- 用的是"现在的标签率"判断,而不是"作业时的标签率"
- 作业决策在最早扫描时刻做的,此时的标签率是固定的
- 用错误的标签率判断导致错误的包裹被纳入24H统计
---
## 实施的三大关键修改
### 修改1创建"作业时标签率" CTE
**新增CTE**`InterchangeUnitLabelRatesAtFirstScan`第760-791行
```sql
作业时标签率 = 最早扫描时间之前推送的标签数 / 总包裹数
```
**原理**
- 最早扫描时间 = 任何Result值的最早扫描记录
- 在这个时刻,标签率是"冻结"的
- 这个标签率决定了包裹是否纳入24H考核
---
### 修改2修改考核时间逻辑
**位置**ArrivalRequests CTE第802-843行
**改变**
```sql
原来:用现在的标签率判断 (label_rate_percent)
现在:用作业时标签率判断 (label_rate_at_first_scan)
```
**含义**
- 作业时标签率≥80% → 设定考核时间16点前后不同
- 作业时标签率<80% 无考核时间完成即达标
**结果**每个包裹的考核方式由其作业时的标签率决定而不是最终标签率
---
### 修改3分子分母维度对齐
**分母改为使用作业时标签率**第1113-1115行
```sql
FROM InterchangeUnitLabelRatesAtFirstScan
WHERE label_rate_at_first_scan >= 80
```
**分子改为按到货日期分组**第10471066行
```sql
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步查询某一天的统计数据
```sql
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
---
## 后续行动
1. **部署到测试环境**:运行修复后的查询
2. **数据验证**确认24H换单率 ≤ 100%
3. **手工抽查**选择3-5个日期手工验证分子分母
4. **监控**:上线后监测是否有异常数据
---
## 文档参考
- 修复计划:[fix_24h_rate_based_on_first_scan_plan.md](fix_24h_rate_based_on_first_scan_plan.md)
- 之前诊断:[24h_rate_numerator_denominator_diagnosis.md](24h_rate_numerator_denominator_diagnosis.md)
- 代码位置:[LabelReplaceRepository.cs](file:///d:\EPproject\LabelReplaceServer\src\DAL\Repositories\LabelReplaceRepository.cs#L709)