上传源代码版本
This commit is contained in:
241
.trae/documents/24h_rate_fix_completed_summary.md
Normal file
241
.trae/documents/24h_rate_fix_completed_summary.md
Normal 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
|
||||
```
|
||||
|
||||
**分子改为按到货日期分组**(第1047、1066行):
|
||||
```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)
|
||||
|
||||
Reference in New Issue
Block a user