Laravel 8 实现每日数据统计图表需按日期分组聚合并补全缺失日期,返回标准 JSON 格式供前端渲染;核心步骤包括时区对齐、DATE(created_at) 分组、mapWithKeys 转换、循环补零及 created_at 字段加索引优化。

在 Laravel 8 中实现每日数据统计图表,核心是「按日期分组聚合」+「前端图表渲染」。后端重点在于准确查出每天的数据量(如订单数、用户注册数等),并返回标准格式的 JSON 数据供 ECharts / Chart.js 等前端库使用。
1. 数据库表结构与时间字段要求
确保目标表(如 orders、users)中存在可用来按天分组的时间字段,推荐使用 created_at(Laravel 默认时间戳字段),且该字段类型为 datetime 或 timestamp。
若需统计“当天新增”,务必确认时区一致(Laravel 默认用应用时区,数据库也建议设为相同,如 Asia/Shanghai)。
2. 后端查询:按天聚合统计(支持最近 N 天)
以下代码以「统计最近 7 天订单数量」为例,放在 Controller 中:
use Illuminate\Http\Request;
use App\Models\Order;
use Carbon\Carbon;
<p>public function dailyOrders(Request $request)
{
$days = (int) $request->input('days', 7); // 可动态传参,默认7天</p><pre class='brush:php;toolbar:false;'>// 获取从今天起往前推 $days 天的日期范围(含今天)
$startDate = Carbon::now()->subDays($days - 1)->startOfDay();
$endDate = Carbon::now()->endOfDay();
// 查询并按日期分组统计(注意:MySQL 用 DATE(),PostgreSQL 用 DATE_TRUNC)
$data = Order::whereBetween('created_at', [$startDate, $endDate])
->selectRaw('DATE(created_at) as date')
->selectRaw('COUNT(*) as count')
->groupBy('date')
->orderBy('date')
->get()
->mapWithKeys(function ($item) {
return [$item->date => (int) $item->count];
})
->all();
// 补全缺失日期(如某天无订单,则补 0)
$fullData = [];
for ($i = 0; $i < $days; $i++) {
$day = Carbon::now()->subDays($days - 1 - $i)->format('Y-m-d');
$fullData[$day] = $data[$day] ?? 0;
}
return response()->json([
'labels' => array_keys($fullData),
'values' => array_values($fullData),
]);}
说明:
- 使用 selectRaw + GROUP BY DATE(created_at) 实现按天聚合;
- 用 mapWithKeys 快速转成「日期 → 数量」关联数组;
- 手动补全日期避免图表出现断点(关键!);
- 返回结构适配常见图表库:
{ "labels": [...], "values": [...] }。
3. 路由与 API 接入
在 routes/api.php 中添加:
Route::get('/stats/daily-orders', [StatsController::class, 'dailyOrders'])->name('api.stats.daily-orders');
前端可通过 /api/stats/daily-orders?days=30 获取最近 30 天数据。
4. 前端简单示例(ECharts)
在 Blade 模板或 Vue 组件中调用:
fetch('/api/stats/daily-orders?days=7')
.then(res => res.json())
.then(data => {
const chart = echarts.init(document.getElementById('chart'));
chart.setOption({
xAxis: { type: 'category', data: data.labels },
yAxis: { type: 'value' },
series: [{
name: '订单数',
type: 'line',
data: data.values,
smooth: true
}],
tooltip: {}
});
});
不复杂但容易忽略:日期补全、时区对齐、数据库索引(给 created_at 加索引可大幅提升查询速度)。


















