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

5.4 KiB
Raw Permalink Blame History

首次扫描时间的使用范围说明

更新日期: 2026-05-16
主题: 首次扫描时间在SQL中的具体使用
状态: 验证无冲突


首次扫描时间的来源

定义位置

OverallScanStatus CTE第814-822行

OverallScanStatus AS (
    SELECT 
        s.NeutralWaybillNumber,
        MAX(CASE WHEN s.Result = 0 THEN 1 ELSE 0 END) AS 曾成功,
        MIN(CASE WHEN s.Result = 0 THEN DATE(...) ELSE NULL END) AS 首次成功日期,
        MIN(CASE WHEN s.Result = 0 THEN s.CreatedAt ELSE NULL END) AS 首次成功时间
    FROM label_scan_history s
    GROUP BY s.NeutralWaybillNumber
)

含义

  • 首次成功时间 = 该包裹首次扫描成功Result = 0的时刻
  • 来自 label_scan_history.CreatedAt 的最小值(第一次成功)

首次扫描时间的使用地点

1. DailyLowLabelRate24HCompleted CTE

位置第962-974行

使用方式

WHERE 
    oss.曾成功 = 1 
    AND oss.首次成功时间 IS NOT NULL
    AND ar.考核时间 IS NULL

作用

  • 判断该包裹是否曾经成功扫描
  • 配合"考核时间为NULL"(低标签率)来统计完成数

不影响的地方 冻结标签率计算

2. Daily24HCompletedOrders CTE

位置第976-996行

使用方式

WHERE 
    oss.曾成功 = 1 
    AND oss.首次成功时间 IS NOT NULL
    AND (
        -- 情况1标签率>=80%,有固定考核时间
        (ar.考核时间 IS NOT NULL AND CONVERT_TZ(oss.首次成功时间, '+00:00', '-05:00') <= ar.考核时间)
        OR
        -- 情况2标签率<80%,完成时间本身就是考核时间(即完成即达标)
        (ar.考核时间 IS NULL)
    )

作用

  • 首次成功时间考核时间 比较
  • 判断包裹是否在考核期限内完成

不影响的地方 冻结标签率计算

3. DailyBeforeNoonPassed CTE

位置第1000-1021行

使用方式

WHERE 
    oss.曾成功 = 1 
    AND oss.首次成功时间 IS NOT NULL
    AND CONVERT_TZ(oss.首次成功时间, '+00:00', '-05:00') <= ar.考核时间

作用

  • 统计16点前到仓且完成考核的包裹
  • 用首次成功时间来判断是否满足考核时间

不影响的地方 冻结标签率计算

4. DailyAfternoonPassed CTE

位置第1023-1044行

使用方式

WHERE 
    oss.曾成功 = 1 
    AND oss.首次成功时间 IS NOT NULL
    AND CONVERT_TZ(oss.首次成功时间, '+00:00', '-05:00') <= ar.考核时间

作用

  • 统计16点后到仓且完成考核的包裹
  • 用首次成功时间来判断是否满足考核时间

不影响的地方 冻结标签率计算

5. DailyLowLabelRatePassed CTE

位置第1050-1069行

使用方式

WHERE 
    oss.曾成功 = 1 
    AND oss.首次成功时间 IS NOT NULL
    AND ar.考核时间 IS NULL

作用

  • 统计低标签率(考核时间=NULL且成功的包裹
  • 完成即达标

不影响的地方 冻结标签率计算


与冻结标签率计算的关系

冻结标签率的计算

位置InterchangeUnitLabelRates CTE第734-763行

计算方式

label_rate_percent = COUNT(DISTINCT CASE 
                      WHEN l.Label IS NOT NULL AND l.Label != '' 
                      THEN l.Id 
                    END) * 100.0 / COUNT(DISTINCT l.Id)

特点

  • 只依赖 label_replace_requests 中的 Label 字段
  • 不涉及 首次成功时间
  • 不涉及 label_scan_history
  • 不涉及 时间比较

验证

首次扫描时间在冻结标签率计算中的使用

❌ 未使用
❌ 不需要使用
❌ 对计算没有影响

数据流整体分析

【冻结标签率的独立计算】
label_replace_requests有标签
    ↓
InterchangeUnitLabelRates只看是否有标签
    ↓
冻结标签率 >= 80% 或 < 80%
    ↓
DailyHighLabelRateShould / DailyLowLabelRateShould分类交接单

【考核完成情况的独立统计】
label_scan_history首次成功扫描
    ↓
OverallScanStatus首次成功时间
    ↓
各个考核CTEDailyBeforeNoonPassed 等)
    ↓
判断是否满足考核时间

【两条线的汇总】
冻结标签率 + 考核结果 = 最终报表

总结

首次扫描时间的用途

用途 位置 说明
判断是否曾成功 DailyLowLabelRate24HCompleted 等 用来过滤成功的包裹
比较考核时间 DailyBeforeNoonPassed、DailyAfternoonPassed 等 判断是否在考核期限内
统计历史数据 整体报表 多维度分析
计算冻结标签率 InterchangeUnitLabelRates 完全不使用

对现有逻辑的影响

❌ 不影响冻结标签率的计算
❌ 不影响高/低标签率的分类
✅ 只用于考核结果的判断(已有逻辑)
✅ 用于历史数据统计(补充信息)

结论

首次扫描时间的引入完全安全,不会影响现有逻辑。

  • 冻结标签率:基于标签属性(不依赖扫描时间)
  • 考核完成:基于成功时间与考核期限的比较(需要扫描时间)
  • 两部分逻辑独立,互不影响

编译状态

编译成功 (exit code 0)

  • 逻辑清晰,没有冲突
  • 首次扫描时间的使用范围明确
  • 与冻结标签率完全独立