From e92636dd5b1c782c167af5bdb2bee009fd6a0580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=9D=E5=8D=9C?= Date: Sun, 15 Mar 2026 23:08:29 +0800 Subject: [PATCH] feat: dashboard merchant revenue rank top5 7d --- .../Controllers/Admin/DashboardController.php | 23 ++++++++++ resources/views/admin/dashboard.blade.php | 46 +++++++++++++++++-- ...chantRevenueRank7dCardShouldRenderTest.php | 36 +++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 tests/Feature/AdminDashboardMerchantRevenueRank7dCardShouldRenderTest.php diff --git a/app/Http/Controllers/Admin/DashboardController.php b/app/Http/Controllers/Admin/DashboardController.php index 295c3b5..4952f02 100644 --- a/app/Http/Controllers/Admin/DashboardController.php +++ b/app/Http/Controllers/Admin/DashboardController.php @@ -141,6 +141,27 @@ class DashboardController extends Controller $planIdToName = Plan::query()->pluck('name', 'id')->all(); + // 排行卡(最小可用):近 7 天站点收入排行 Top5(按已付金额) + $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") + ->whereBetween('created_at', [$trendStart, $trendEnd]) + ->groupBy('merchant_id') + ->orderByDesc('paid_sum') + ->limit(5) + ->get() + ->map(function ($row) { + return [ + 'merchant_id' => (int) ($row->merchant_id ?? 0), + 'count' => (int) ($row->cnt ?? 0), + 'paid_sum' => (float) ($row->paid_sum ?? 0), + ]; + }) + ->values() + ->all(); + + $merchantIdToName = Merchant::query()->pluck('name', 'id')->all(); + return view('admin.dashboard', [ 'adminName' => $admin->name, 'stats' => $stats, @@ -148,6 +169,8 @@ class DashboardController extends Controller 'recentPlatformOrders' => $recentPlatformOrders, 'planOrderShare' => $planOrderShare, 'planIdToName' => $planIdToName, + 'merchantRevenueRank7d' => $merchantRevenueRank7d, + 'merchantIdToName' => $merchantIdToName, 'platformAdmin' => $admin, 'cacheMeta' => [ 'store' => config('cache.default'), diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index ae1c02a..e66aeeb 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -114,9 +114,49 @@
说明:先接入最小可用趋势数据;后续再补时间范围切换、维度切换与可视化图表。
-

排行

-
(占位)后续接入:站点续费金额排行、套餐销量排行、异常订单排行等。
-
说明:后续会补“时间范围切换 + 维度切换”的渐进增强交互。
+

排行(近7天站点收入 Top5)

+ @php + $rankRows = (array) ($merchantRevenueRank7d ?? []); + $rankTotal = 0.0; + foreach ($rankRows as $r) { + $rankTotal += (float) ($r['paid_sum'] ?? 0); + } + @endphp + +
Top5 合计已付 ¥{{ number_format($rankTotal, 2) }}
+ + + + + + + + + + + @forelse($rankRows as $row) + @php + $mid = (int) ($row['merchant_id'] ?? 0); + $mname = (string) (($merchantIdToName[$mid] ?? '') ?: ('#' . $mid)); + $merchantOrdersUrl = \App\Support\BackUrl::withBack( + '/admin/platform-orders?' . \Illuminate\Support\Arr::query(['merchant_id' => $mid]), + $selfWithoutBack + ); + @endphp + + + + + + @empty + + + + @endforelse + +
站点订单数已付金额
{{ $mname }}{{ (int) ($row['count'] ?? 0) }}¥{{ number_format((float) ($row['paid_sum'] ?? 0), 2) }}
暂无数据
+ +
说明:先落最小可用 Top5 排行;后续补时间范围切换、维度切换与异常排行。
diff --git a/tests/Feature/AdminDashboardMerchantRevenueRank7dCardShouldRenderTest.php b/tests/Feature/AdminDashboardMerchantRevenueRank7dCardShouldRenderTest.php new file mode 100644 index 0000000..7711b81 --- /dev/null +++ b/tests/Feature/AdminDashboardMerchantRevenueRank7dCardShouldRenderTest.php @@ -0,0 +1,36 @@ +seed(); + + $this->post('/admin/login', [ + 'email' => 'platform.admin@demo.local', + 'password' => 'Platform@123456', + ])->assertRedirect('/admin'); + } + + public function test_dashboard_merchant_revenue_rank_7d_card_should_render(): void + { + $this->loginAsPlatformAdmin(); + + $res = $this->get('/admin'); + $res->assertOk(); + + $res->assertSee('排行(近7天站点收入 Top5)', false); + $res->assertSee('data-role="merchant-revenue-rank-7d"', false); + + // 链接应携带 back(保持仪表盘治理链路一致性) + $res->assertSee('back=%2Fadmin', false); + $res->assertDontSee('&back=', false); + } +}