使用Carbon获取收入图表仅显示2个月数据,如何实现全月数据展示?
收入柱状图仅显示最近2个月数据的排查与修复方案
问题描述
现有一段用于展示收入柱状图的PHP代码,意图显示当前月份起往前11个月的累计收入数据,但实际仅能获取并展示最近2个月的数据,需要排查问题并实现12个月数据的完整展示。
问题根源分析
- 年份过滤限制过严:原代码使用
whereYear('created_at', Carbon::now()->year)仅查询当前年份的数据,若当前月份是年初(比如1月、2月),往前11个月的范围会包含上一年的月份,这部分数据会被直接过滤,导致仅能显示当前年份已过的月份数据。 - 日期范围查询不匹配:代码生成了12个月份的标签,但查询逻辑没有覆盖这12个月的完整时间范围,导致非当前年份的月份没有数据返回。
修复方案与代码调整
核心修改点
- 替换
whereYear为日期范围查询,覆盖从11个月前到当前的完整区间 - 保持月份标签的展示格式不变,同时确保所有12个月份都能获取对应数据(无数据时显示0)
修复后的完整代码
public function incomeChartData(): array { // 计算时间范围:当前月份往前推11个月的月初 到 当前时间 $startDate = now()->startOfMonth()->subMonths(11); $endDate = now(); // 查询该时间范围内的手动付款记录,按月份缩写分组 $manualPayment = Subscription::wherePaymentType('paid') ->whereBetween('created_at', [$startDate, $endDate]) ->get() ->groupBy(function ($q) { return Carbon::parse($q->created_at)->isoFormat('MMM'); }); // 查询该时间范围内的交易记录,按月份缩写分组 $transactions = Transaction::whereStatus(1) ->whereBetween('created_at', [$startDate, $endDate]) ->get() ->groupBy(function ($q) { return Carbon::parse($q->created_at)->isoFormat('MMM'); }); $data = []; // 生成从11个月前到现在的所有月份 $periods = $startDate->monthsUntil($endDate); $labels = []; $dataset = []; $colors = []; $borderColors = []; foreach ($periods as $key => $period) { $month = $period->isoFormat('MMM'); $labels[] = $month; $colors[] = getBGColors($key) . ')'; $borderColors[] = getBGColors($key) . ', 0.75)'; // 初始化当月金额为0 $amounts = [0]; // 合并交易记录金额 if (isset($transactions[$month])) { $amounts = array_merge($amounts, $transactions[$month]->pluck('amount')->toArray()); } // 合并手动付款金额 if (isset($manualPayment[$month])) { $amounts = array_merge($amounts, $manualPayment[$month]->pluck('payable_amount')->toArray()); } $dataset[] = removeCommaFromNumbers(number_format(array_sum($amounts), 2)); } $data['labels'] = $labels; $data['breakDown'][] = [ 'label' => __('messages.common.total_amount'), 'data' => $dataset, 'backgroundColor' => $colors, 'borderColor' => $borderColors, 'lineTension' => 0.5, 'radius' => 4, ]; return $data; }
额外说明
- 如果需要区分不同年份的同月份(比如去年12月和今年12月),可以将分组键改为
Carbon::parse($q->created_at)->isoFormat('YYYY-MMM'),同时标签也对应调整,避免数据混淆。 - 若部分月份确实没有收入数据,代码会自动填充0,保证12个月份的标签和数据一一对应,图表能完整展示12个月的内容。
内容的提问来源于stack exchange,提问作者Komal Shree
相关产品推荐
相关产品推荐

