上传源代码版本

This commit is contained in:
Im-Jenisson
2026-06-01 16:30:29 +08:00
commit b2a9b7d3c2
462 changed files with 104365 additions and 0 deletions

View File

@@ -0,0 +1,241 @@
# 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)