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

Laravel展示客户月度消费数据遇阻,请求技术协助

客户月度消费数据表格渲染问题修复方案

核心问题分析

  • 日期匹配错误:原代码仅用月份英文缩写(M格式)查询,未关联年份,会导致跨年份同月份数据混淆;若数据库month字段存储数字,缩写格式完全无法匹配。
  • 查询结果类型错误:get()返回集合而非单个账单实例,前端无法直接解析单个值。
  • 数据结构冗余:未单独提取表头数据,前端渲染表格时无法复用统一表头。
  • 性能低下:循环客户+循环月份的查询方式触发大量N+1查询,效率极低。

修正后的控制器代码

public function indexannuel()
{
    // 预加载用户关联,避免N+1查询
    $clients = Client::with('user')->get();
    
    // 生成最近12个月的日期数据,包含数字月份、年份、显示格式
    $months = collect(range(1, 12))->map(function($i) {
        $date = Carbon::now()->subMonths($i)->startOfMonth();
        return [
            'month' => $date->month,
            'year' => $date->year,
            'display' => $date->format('Y-M')
        ];
    });

    // 批量查询目标时间范围内的所有账单,按客户+年+月分组
    $bills = Bill::whereIn('client_id', $clients->pluck('id'))
        ->where(function($query) use ($months) {
            foreach ($months as $month) {
                $query->orWhere(fn($q) => $q->where('year', $month['year'])->where('month', $month['month']));
            }
        })
        ->get()
        ->groupBy(fn($bill) => "{$bill->client_id}-{$bill->year}-{$bill->month}");

    // 构建前端可用的结构化数据
    $indexMensuel = [];
    foreach ($clients as $client) {
        $clientData = [
            'name' => $client->user->fullname,
            'months' => []
        ];
        
        foreach ($months as $month) {
            $key = "{$client->id}-{$month['year']}-{$month['month']}";
            // 无对应账单时填充0,可根据需求改为空字符串
            $clientData['months'][] = $bills->has($key) ? $bills[$key]->first()->final : 0;
        }
        
        $indexMensuel[] = $clientData;
    }

    return view('bills.indexannuel', compact('indexMensuel', 'months'));
}

Blade视图渲染示例

<table border="1">
    <thead>
        <tr>
            <th>客户姓名</th>
            @foreach($months as $month)
                <th>{{ $month['display'] }}</th>
            @endforeach
        </tr>
    </thead>
    <tbody>
        @foreach($indexMensuel as $client)
            <tr>
                <td>{{ $client['name'] }}</td>
                @foreach($client['months'] as $amount)
                    <td>{{ $amount }}</td>
                @endforeach
            </tr>
        @endforeach
    </tbody>
</table>

额外说明

  • 若数据库month字段存储的是英文缩写(如Jan),可将$date->month改为$date->format('M'),保持查询条件与存储格式一致。
  • 可根据需求调整表头显示格式(如Y年m月),修改format()参数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 13:32:50