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

使用Carbon获取收入图表仅显示2个月数据,如何实现全月数据展示?

收入柱状图仅显示最近2个月数据的排查与修复方案

问题描述

现有一段用于展示收入柱状图的PHP代码,意图显示当前月份起往前11个月的累计收入数据,但实际仅能获取并展示最近2个月的数据,需要排查问题并实现12个月数据的完整展示。

问题根源分析

  1. 年份过滤限制过严:原代码使用whereYear('created_at', Carbon::now()->year)仅查询当前年份的数据,若当前月份是年初(比如1月、2月),往前11个月的范围会包含上一年的月份,这部分数据会被直接过滤,导致仅能显示当前年份已过的月份数据。
  2. 日期范围查询不匹配:代码生成了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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:13:16