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

Laravel Collection返回空数组求助:无法正确返回用户订单总价

Laravel 返回用户订单统计数据为空集合的问题解决

你好,我看到你在Laravel中处理用户订单总价统计时遇到了返回结果为空的问题——虽然dd($data)能看到属性,但实际返回的是空数组。下面帮你梳理问题根源和具体解决方案:

你的需求

遍历包含2个用户名的数组,通过用户名查询用户ID,统计每个用户在指定时间范围内的所有订单总价,最终返回每个用户的{'username': 用户名, 'totalPrice': 总价}格式数据。

当前问题核心

你直接给Collection对象添加了username和price属性,但Laravel在返回Collection时,只会序列化其内部的$items数组,你额外添加的对象属性不会被包含在返回结果里,这就是为什么return $data只返回[],但dd($data)能看到属性的原因。

问题分析与解决方案

以下是针对代码的具体修改建议,分点说明优化方向:

1. 修正Collection的使用方式

应该把每个用户的统计结果作为独立元素添加到集合中,而不是给集合本身添加属性;同时要确保每次循环用户时重置总价,避免跨用户累加错误。

2. 优化用户ID查询逻辑

避免使用原生SQL拼接(存在SQL注入风险),改用Eloquent查询更安全且符合Laravel的开发规范。

3. 优化模型中的统计逻辑

直接使用Laravel的sum()方法计算总价,不用查询所有订单再手动遍历求和,既能提升效率又能减少内存消耗。


修改后的完整代码

模型代码(优化求和逻辑)

use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use App\Models\Order;

public static function getOrdersUserTotal($startDate, $endDate, $userId)
{
    return Order::whereBetween('created_at', [Carbon::parse($startDate), Carbon::parse($endDate)])
        ->where('user_id', $userId)
        // 过滤非报价订单
        ->where(function ($query) {
            $query->where('is_quotation', 0)->orWhereNull('is_quotation');
        })
        // 确保订单未被软删除
        ->whereNull('deleted_at')
        ->join('order_articles', 'orders.id', '=', 'order_articles.order_id')
        // 确保订单项未被软删除
        ->whereNull('order_articles.deleted_at')
        ->join('order_article_configurations', 'order_articles.id', '=', 'order_article_configurations.order_article_id')
        // 确保订单配置项未被软删除
        ->whereNull('order_article_configurations.deleted_at')
        // 计算单条订单总价并求和
        ->sum(DB::raw('COALESCE(NULLIF(order_article_configurations.special_price, 0), order_article_configurations.price) * order_article_configurations.quantity'));
}

控制器代码(修正集合使用与业务逻辑)

use Carbon\Carbon;
use App\Models\User;
use App\Models\Dashboard;
use Illuminate\Http\Request;

public static function getOrdersUser(Request $request = null)
{
    // 处理日期参数
    if ($request) {
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');
    } else {
        $startDate = Carbon::now()->subDays(30);
        $endDate = Carbon::now();
    }

    $users = ['merijn', 'stefan'];
    // 初始化空集合
    $data = collect();

    foreach ($users as $user) {
        // 用Eloquent查询用户ID,避免SQL注入风险
        $userId = User::where('username', $user)->value('id');
        
        // 如果用户不存在,跳过当前循环
        if (!$userId) {
            continue;
        }

        // 调用模型方法直接获取当前用户的订单总价
        $totalPrice = Dashboard::getOrdersUserTotal($startDate, $endDate, $userId);

        // 将当前用户的统计结果添加到集合中
        $data->push([
            'username' => $user,
            'totalPrice' => $totalPrice
        ]);
    }

    return $data;
}

修改后的返回结果

现在返回的结果会完全符合你的期望:

[
    {"username": "merijn", "totalPrice": 12345.67},
    {"username": "stefan", "totalPrice": 258090.16}
]

额外说明

  • 软删除条件修正:之前的orWhereNull会导致只要任意一个关联表未被软删除就会被查询,现在改为每个表都用whereNull,确保所有关联数据都未被软删除,统计结果更准确。
  • 日期处理:使用Carbon::parse()统一处理日期,避免因日期格式不一致导致的查询错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:03:05