diff --git a/app/Http/Controllers/Admin/DashboardController.php b/app/Http/Controllers/Admin/DashboardController.php index abb6d13..f5011c7 100644 --- a/app/Http/Controllers/Admin/DashboardController.php +++ b/app/Http/Controllers/Admin/DashboardController.php @@ -227,10 +227,12 @@ class DashboardController extends Controller $planIdToName = Plan::query()->pluck('name', 'id')->all(); // 排行卡(最小可用):近 7 天站点收入排行 Top5(按已付金额) + // 说明:只统计 payment_status=paid,避免“未支付订单=0金额”混入排行造成噪音。 $merchantRevenueRank7d = PlatformOrder::query() ->selectRaw('merchant_id, COUNT(*) as cnt') - ->selectRaw("SUM(CASE WHEN payment_status = 'paid' THEN paid_amount ELSE 0 END) as paid_sum") + ->selectRaw('SUM(paid_amount) as paid_sum') ->whereBetween('created_at', [$trendStart, $trendEnd]) + ->where('payment_status', 'paid') ->groupBy('merchant_id') ->orderByDesc('paid_sum') ->limit(5) @@ -245,6 +247,17 @@ class DashboardController extends Controller ->values() ->all(); + // 用于计算“Top5覆盖率/其它”的全量分母(近 7 天全站点已付总额/总订单数) + $merchantRevenueTotalPaid7d = (float) PlatformOrder::query() + ->whereBetween('created_at', [$trendStart, $trendEnd]) + ->where('payment_status', 'paid') + ->sum('paid_amount'); + + $merchantRevenueTotalOrders7d = (int) PlatformOrder::query() + ->whereBetween('created_at', [$trendStart, $trendEnd]) + ->where('payment_status', 'paid') + ->count(); + $merchantIdToName = Merchant::query()->pluck('name', 'id')->all(); return view('admin.dashboard', [ @@ -256,6 +269,8 @@ class DashboardController extends Controller 'planOrderShareTotal' => (int) $planOrderShareTotal, 'planIdToName' => $planIdToName, 'merchantRevenueRank7d' => $merchantRevenueRank7d, + 'merchantRevenueTotalPaid7d' => (float) $merchantRevenueTotalPaid7d, + 'merchantRevenueTotalOrders7d' => (int) $merchantRevenueTotalOrders7d, 'merchantIdToName' => $merchantIdToName, 'platformAdmin' => $admin, 'cacheMeta' => [ diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index 441a979..77cad45 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -185,12 +185,25 @@ $rankPaidMax = max($rankPaidMax, (float) ($r['paid_sum'] ?? 0)); $rankOrdersTotal += (int) ($r['count'] ?? 0); } + + $rankTotalPaidAll = (float) ($merchantRevenueTotalPaid7d ?? 0); + if ($rankTotalPaidAll <= 0) { + $rankTotalPaidAll = (float) $rankTotal; + } + + $rankCoveragePct = $rankTotalPaidAll > 0 ? round(((float) $rankTotal / $rankTotalPaidAll) * 100, 1) : 0; + $rankOtherPaid = max(0.0, $rankTotalPaidAll - (float) $rankTotal); + $rankOtherPct = max(0.0, round(100 - $rankCoveragePct, 1)); @endphp
Top5合计已付:¥{{ number_format($rankTotal, 2) }} Top5订单数:{{ (int) $rankOrdersTotal }} + 覆盖率:{{ $rankCoveragePct }}% + + 其它:{{ $rankOtherPct }}%(¥{{ number_format($rankOtherPaid, 2) }}) + Top1金额:¥{{ number_format($rankPaidMax, 2) }}
diff --git a/tests/Feature/AdminDashboardMerchantRevenueRank7dMetaShouldIncludeCoverageTest.php b/tests/Feature/AdminDashboardMerchantRevenueRank7dMetaShouldIncludeCoverageTest.php new file mode 100644 index 0000000..f8e4a73 --- /dev/null +++ b/tests/Feature/AdminDashboardMerchantRevenueRank7dMetaShouldIncludeCoverageTest.php @@ -0,0 +1,33 @@ +seed(); + + $this->post('/admin/login', [ + 'email' => 'platform.admin@demo.local', + 'password' => 'Platform@123456', + ])->assertRedirect('/admin'); + } + + public function test_dashboard_merchant_revenue_rank_7d_meta_should_include_coverage_and_other(): void + { + $this->loginAsPlatformAdmin(); + + $res = $this->get('/admin'); + $res->assertOk(); + + $res->assertSee('data-role="merchant-revenue-rank-7d-meta"', false); + $res->assertSee('覆盖率:', false); + $res->assertSee('其它:', false); + } +}