# 冻结标签率设计核心逻辑修正 - v3.0 **更新日期**: 2026-05-16 **版本**: v3.0 - 关键考核规则澄清 **状态**: ✅ 编译通过,文档已更新 --- ## 核心修正点 ### ⚠️ 发现的误区 在 v2.0 中,对 `DailyHighLabelRateShould` 和 `DailyLowLabelRateShould` 两个 CTE 的理解有误。 **错误理解**(v2.0): - 这两个 CTE 是用来分别统计"标签推送时间与扫描时间关系"中的高/低标签率包裹数 - 高标签率包裹单独处理,低标签率包裹单独处理 **用户指正**: "如果冻结标签率是低于80%的,那么100个包裹都要按照完成即达标的规则处理,如果冻结标签率大于等于80%则按照到仓时间16点前后的规则处理" ### ✅ 正确理解(v3.0) **冻结标签率的真实作用**: - 冻结标签率是对**整个交接单**的标签率水平的评估 - 它决定了**这个交接单中的所有包裹**应该按什么规则处理 - **不是分别处理包裹,而是整体规则应用** **考核规则的应用逻辑**: ``` IF 冻结标签率 >= 80% THEN ├─ 所有包裹都按照"到仓时间16点前后分段"规则处理 └─ 高标签率应该换单数 += 这个交接单的全部包裹数 ELSE IF 冻结标签率 < 80% THEN ├─ 所有包裹都按照"完成即达标"规则处理 └─ 低标签率应该换单数 += 这个交接单的全部包裹数 ``` --- ## 代码修正 ### DailyHighLabelRateShould CTE 修正 **v2.0(错误)**: ```sql WHERE earliest_times.earliest_scan_time > lrr.LabelRetrievedAt -- 这样是在分别统计包裹,而不是统计交接单 ``` **v3.0(正确)**: ```sql FROM ArrivalRequests ar INNER JOIN ( SELECT DISTINCT BillOfLadingNumber, MasterPackageNumber FROM InterchangeUnitLabelRates WHERE label_rate_percent >= 80 ) high_label_units ON ... -- 统计所有冻结标签率 >= 80% 的交接单中的全部包裹数 ``` ### DailyLowLabelRateShould CTE 修正 **v2.0(错误)**: ```sql WHERE earliest_times.earliest_scan_time <= lrr.LabelRetrievedAt -- 这样是在分别统计包裹,而不是统计交接单 ``` **v3.0(正确)**: ```sql FROM ArrivalRequests ar INNER JOIN ( SELECT DISTINCT BillOfLadingNumber, MasterPackageNumber FROM InterchangeUnitLabelRates WHERE label_rate_percent < 80 ) low_label_units ON ... -- 统计所有冻结标签率 < 80% 的交接单中的全部包裹数 ``` --- ## 逻辑对比示例 ### 场景:100个订单在同一交接单 **标签分布**: - 30个订单:标签推送于09:00-10:00(早于作业开始) - 50个订单:标签推送于10:00-11:00(同时作业开始) - 20个订单:标签推送于11:00-12:00(晚于作业开始) **冻结标签率**:`30/100 = 30%` ### v2.0 的错误理解 ``` 高标签率应该换单数 = 30(推送时间 > 扫描时间的包裹) 低标签率应该换单数 = 70(推送时间 <= 扫描时间的包裹) 那么: - 30个包裹按高标签率规则处理(16点分段) - 70个包裹按低标签率规则处理(完成即达标) ❌ 这样导致同一个交接单的包裹按不同规则处理! ``` ### v3.0 的正确理解 ``` 冻结标签率 = 30% < 80% → 整个交接单(所有100个包裹)都按低标签率规则处理(完成即达标) 因此: 高标签率应该换单数 = 0(没有标签率≥80%的交接单) 低标签率应该换单数 = 100(整个交接单都按此规则处理) ✅ 这样才符合业务逻辑:同一个交接单的包裹按相同规则处理 ``` --- ## 关键原理 ### 为什么要用冻结标签率作为整体判断标准? 1. **交接单是最小的考核单位** - 每个交接单都有一个统一的标签率水平 - 不应该在同一个交接单内混合使用不同的考核规则 2. **标签率会随时间变化** - 某时刻的标签率可能低于80%,之后又升高 - 冻结标签率通过"最早扫描时间"这一关键时刻点来定位 - 代表"作业刚开始时的标签率情况" 3. **现场实际情况** - 作业人员在作业开始时面对的是一个固定的标签率 - 这个"时刻的标签率"决定了他们的考核规则 - 不会在作业过程中动态改变规则 ### InterchangeUnitLabelRates 的双重用途 | 用途 | 含义 | |------|------| | 计算 `label_rate_percent` | 判断该交接单属于高还是低标签率 | | 用于分类 | 通过 ≥80% 或 <80% 来分类全部交接单 | --- ## 文件变更 ### 代码修改 - ✅ `src/DAL/Repositories/LabelReplaceRepository.cs` - DailyHighLabelRateShould CTE(第1048-1066行) - DailyLowLabelRateShould CTE(第1069-1083行) - 逻辑:从"分别统计包裹"改为"统计交接单中的全部包裹" ### 文档更新 - ✅ `frozen_label_rate_design.md` - 设计逻辑第三步:完全重写,强调整体规则应用 - 验证场景:示例已更新 - 字段映射:说明已澄清 - ✅ `frozen_label_rate_implementation_summary.md` - DailyHighLabelRateShould 和 DailyLowLabelRateShould 功能说明 - 验证场景示例已更新 --- ## 编译状态 ✅ **编译成功** - 命令:`dotnet build src/DAL/DAL.csproj --no-restore -v quiet` - 结果:exit code 0 - 无编译错误 --- ## 重要总结 ### 冻结标签率的三层含义 | 层级 | 含义 | 用途 | |------|------|------| | 第1层 | 度量 | 测量特定时刻的标签率水平 | | 第2层 | 分类 | 将交接单分为两类(≥80% 或 <80%) | | 第3层 | 规则 | 决定整个交接单按什么考核规则处理 | ### 核心原则 ✅ **DO**: - 计算每个交接单的冻结标签率 - 根据冻结标签率对交接单分类 - 同一交接单内的所有包裹按相同规则处理 ❌ **DON'T**: - 在同一交接单内混合使用不同考核规则 - 对单个包裹分别应用高/低标签率规则 - 将包裹的"标签状态"与"整体考核规则"混淆 --- ## 后续验证 1. ✅ 编译成功 2. 在测试环境中验证新逻辑 3. 对比新旧数据结果 4. 验证"成功数 < 考核通过数"的矛盾是否消除