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

Laravel中实现父数据与子数据同表展示问题求助

解决方案:实现父Task与子UserTask表格并排展示

1. 优化数据查询(解决N+1性能问题)

首先在Task模型中定义与UserTask的关联关系,再通过预加载一次性获取所有关联数据,替代原循环内的重复查询:

Task模型添加关联

// app/Models/Task.php
public function userTasks()
{
    return $this->hasMany(UserTask::class, 'task_id');
}

控制器代码优化

$task = Task::where('type', $this->type)
    ->where('domain', $this->domain)
    ->where('category', $this->category)
    ->with(['userTasks' => function($query) {
        $query->whereDate('created_at', '>=', $this->firstDate)
              ->whereDate('created_at', '<=', $this->lastDate);
    }])
    ->get();

return view('export.task', ['task' => $task]);

2. 修改HTML表格结构(利用rowspan实现单元格合并)

核心逻辑:父Task的信息通过rowspan属性垂直合并单元格,对应所有子UserTask的行;每个子UserTask生成一行,仅在第一个子任务行展示父Task信息,后续行跳过父单元格列,直接渲染子任务数据。

完整HTML表格代码

<table>
    <thead>
        <tr>
            <th>Domain</th>
            <th>Category</th>
            <th>Detail</th>
            <th>Scope</th>
            <th>Activity</th>
            <th>Technician</th>
            <th>Photo</th>
            <th>Date</th>
        </tr>
    </thead>
    <tbody>
        @foreach ($task as $item)
            @php
                $userTaskCount = $item->userTasks->count();
                $rowSpan = $userTaskCount > 0 ? $userTaskCount : 1;
            @endphp

            @foreach ($item->userTasks as $index => $userTask)
                <tr>
                    @if ($index === 0)
                        <td rowspan="{{ $rowSpan }}">{{ $item->domain }}</td>
                        <td rowspan="{{ $rowSpan }}">{{ $item->category }}</td>
                        <td rowspan="{{ $rowSpan }}">{{ $item->desc }}</td>
                        <td rowspan="{{ $rowSpan }}">{{ $item->scope }}</td>
                        <td rowspan="{{ $rowSpan }}">{{ $item->activity }}</td>
                    @endif
                    <td>{{ $userTask->technician ?? '-' }}</td>
                    <td>
                        @if ($userTask->photo)
                            <img src="{{ asset('storage/' . $userTask->photo) }}" alt="Task Photo" style="max-width: 80px;">
                        @else
                            -
                        @endif
                    </td>
                    <td>{{ $userTask->created_at->format('Y-m-d') }}</td>
                </tr>
            @endforeach

            @if ($userTaskCount === 0)
                <tr>
                    <td>{{ $item->domain }}</td>
                    <td>{{ $item->category }}</td>
                    <td>{{ $item->desc }}</td>
                    <td>{{ $item->scope }}</td>
                    <td>{{ $item->activity }}</td>
                    <td>-</td>
                    <td>-</td>
                    <td>-</td>
                </tr>
            @endif
        @endforeach
    </tbody>
</table>

原方法无效的原因

你之前在单个<td>内循环userTask,会导致该单元格内堆叠所有子任务数据,无法生成独立行对应每个子任务。通过rowspan合并父单元格+遍历子任务生成对应行,才能实现父/子数据的并排对齐展示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:20:23