lzh
a5f916c62a
fix(ops): 队列楼层权重修复——强楼层优先 + 闭环基准兜底 + N+1 优化
问题:楼层差在分数公式中本该主导同优先级排序,但有四个缺陷导致效果不稳:
1. 有 base 无 target 时给 +600 罚分,无 base 时则全免罚——同一工单在
保洁员忙/闲时排序不单调(B)。
2. 基准楼层只在 user 有 PROCESSING 时生效,空闲时完全无楼层信号(A)。
3. enqueue 瞬间 score 不含楼层,要等下一轮 rebuild 才补上(H)。
4. aging 上限 720 > floorDiff 上限 600,等满 4 小时可反超同优先级 10 层差
任务,削弱"强楼层优先"语义(G)。
5. rebuild 内 for 循环对每条 WAITING 单独 selectById(order)+selectById(area),
N+1 问题(F)。
修复:
1. QueueScoreCalculator(B + G)
- FLOOR_WEIGHT 60 → 100:上限 1000 > aging 上限 720,4 小时老化不再反超
同优先级的近楼层任务。
- 删除"有 base 无 target +600"分支:任一侧缺失即 score=0,语义对称。
2. OpsOrderMapper.selectLatestCompletedAreaIdByAssignee(A 二级兜底)
查最近 24h 内已完成工单的 area,用来推断空闲保洁员的物理位置。
超过 24h 视为跨班次、轨迹失效。
3. OrderQueueServiceEnhanced.resolveBaselineAreaId(A 三级兜底)
PROCESSING.area → 最近 24h COMPLETED.area → 调用方传的 fallbackAreaId。
4. OrderQueueServiceEnhanced.enqueue(H)
事务提交后 triggerQueueRebuildAfterCommit(userId, null),新入队工单
立即按楼层差参与排序,不依赖下一次 autoDispatchNext 触发。
5. OrderQueueServiceEnhanced.rebuildWaitingTasksByUserId(F)
批量 selectBatchIds(orders) + selectBatchIds(areas),100 条 WAITING
从 200 次 SELECT 降到 2 次。
权重直观对比(P2=priority×1500=3000):
旧分数 新分数
同层刚入队 3000 3000
差5层刚入队 3000+300=3300 3000+500=3500
差5层等2小时 3000+300-360=2940 3000+500-360=3140
同层等4小时 3000+0-720=2280 3000+0-720=2280
新权重下"差5层等2小时"仍大于"同层刚入队",楼层稳定主导排序;
极端 aging(>4h)仍能让同层任务被近楼层任务压制优先执行。
测试:QueueScoreCalculatorTest(3)、OrderQueueServiceEnhancedTest(1,
已按 selectBatchIds + selectActiveListByUserId 更新 mock)、QueueSyncServiceTest
全绿。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>