You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Eloquent外部对同优先级的自行车维修工单按日期排序?

问题分析

原代码存在三个核心问题:

  • urgency_level是字符串枚举(如Emergency、Very urgent),用$b->urgency_level - $a->urgency_level数值减法完全无效,字符串相减会被转成0,等于未做有效比较。
  • sort()方法返回新集合,但未重新赋值给$queue_maintenance,原分页对象未被修改,排序结果不生效。
  • 分页后再做内存排序会打乱分页逻辑,且性能远不如数据库层面排序。
正确实现方案

方案一:数据库层面排序(推荐)

通过SQL的CASE语句给不同紧急程度分配权重,直接在数据库完成排序,分页逻辑完全正确:

$queue_maintenance = QueueMaintenance::selectRaw('*, 
    CASE urgency_level
        WHEN "Emergency" THEN 3
        WHEN "Very urgent" THEN 2
        WHEN "Urgent" THEN 1
        ELSE 0
    END AS urgency_weight')
    ->where('type_solicitation', 'First solicitation')
    ->where('status', 'Waiting for request')
    ->orderBy('urgency_weight', 'desc')
    ->orderBy('date_solicitation', 'asc')
    ->paginate(10);

说明

  1. 用CASE为紧急程度定义数值权重,数值越高优先级越高,确保排序逻辑符合预期。
  2. 先按紧急权重降序,再按请求日期升序(最早工单在前)。
  3. 数据库层面排序性能更优,分页结果完全匹配排序规则。

方案二:集合层面排序(仅特殊场景使用)

若无法修改SQL,可在集合中处理,但需注意重新赋值和正确的比较逻辑:

// 定义紧急程度优先级映射
$urgencyPriority = [
    'Emergency' => 3,
    'Very urgent' => 2,
    'Urgent' => 1,
];

$queue_maintenance = QueueMaintenance::where('type_solicitation', 'First solicitation')
    ->where('status', 'Waiting for request')
    ->get()
    ->sort(function($a, $b) use ($urgencyPriority) {
        // 先比较紧急程度优先级
        $urgencyDiff = $urgencyPriority[$b->urgency_level] <=> $urgencyPriority[$a->urgency_level];
        if ($urgencyDiff !== 0) {
            return $urgencyDiff;
        }
        // 同优先级用Carbon日期比较(需确保date_solicitation是Carbon实例)
        return $a->date_solicitation->compare($b->date_solicitation);
    })
    ->paginate(10);

注意

集合分页仅适用于数据量较小的场景,大数据量下性能远低于数据库分页。

原代码修正要点
  1. 字符串类型的紧急程度必须用优先级映射表做比较,不能用数值减法。
  2. 调用sort()后需重新赋值:$queue_maintenance = $queue_maintenance->sort(...)。
  3. 日期比较优先用Carbon的compare()方法,避免strcmp处理日期字符串的潜在问题。

内容的提问来源于stack exchange,提问作者user20338917

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 08:15:33