From a9f1185f84db5795e99720ca68aa7a779f4f43ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=9D=E5=8D=9C?= Date: Mon, 16 Mar 2026 13:49:56 +0800 Subject: [PATCH] feat(admin-dashboard): clarify plan share top5 meta with total and coverage --- .../Controllers/Admin/DashboardController.php | 9 +++++ resources/views/admin/dashboard.blade.php | 22 +++++++++--- ...ShareTop5MetaShouldIncludeCoverageTest.php | 34 +++++++++++++++++++ 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 tests/Feature/AdminDashboardPlanOrderShareTop5MetaShouldIncludeCoverageTest.php diff --git a/app/Http/Controllers/Admin/DashboardController.php b/app/Http/Controllers/Admin/DashboardController.php index 5b0e814..3309cb3 100644 --- a/app/Http/Controllers/Admin/DashboardController.php +++ b/app/Http/Controllers/Admin/DashboardController.php @@ -197,6 +197,14 @@ class DashboardController extends Controller ->get(); // 占比卡(最小可用):近 7 天按套餐统计平台订单数量 TopN + // 说明: + // - Top5 数据用于“对比/聚焦”(减少噪音) + // - total 用于计算“占比/覆盖率”,避免将 Top5 误当全量 + $planOrderShareTotal = PlatformOrder::query() + ->whereBetween('created_at', [$trendStart, $trendEnd]) + ->whereNotNull('plan_id') + ->count(); + $planOrderShare = PlatformOrder::query() ->selectRaw('plan_id, COUNT(*) as cnt') ->whereBetween('created_at', [$trendStart, $trendEnd]) @@ -243,6 +251,7 @@ class DashboardController extends Controller 'platformOrderTrend7d' => $platformOrderTrend7d, 'recentPlatformOrders' => $recentPlatformOrders, 'planOrderShare' => $planOrderShare, + 'planOrderShareTotal' => (int) $planOrderShareTotal, 'planIdToName' => $planIdToName, 'merchantRevenueRank7d' => $merchantRevenueRank7d, 'merchantIdToName' => $merchantIdToName, diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index 69696b5..12b4250 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -374,9 +374,14 @@ @php $shareRows = (array) ($planOrderShare ?? []); - $totalOrders = 0; + $top5Orders = 0; foreach ($shareRows as $r) { - $totalOrders += (int) ($r['count'] ?? 0); + $top5Orders += (int) ($r['count'] ?? 0); + } + $totalOrders = (int) ($planOrderShareTotal ?? 0); + if ($totalOrders <= 0) { + // 兜底:兼容旧数据(未传 total 时,至少不影响渲染) + $totalOrders = (int) $top5Orders; } @endphp @@ -401,9 +406,14 @@ $shareTop1Count = max($shareTop1Count, (int) ($r['count'] ?? 0)); } $shareTop1Pct = $totalOrders > 0 ? round(($shareTop1Count / $totalOrders) * 100, 1) : 0; + $shareCoveragePct = $totalOrders > 0 ? round(($top5Orders / $totalOrders) * 100, 1) : 0; @endphp
- Top5合计订单:{{ (int) $totalOrders }} + 全量订单:{{ (int) $totalOrders }} + + Top5合计:{{ (int) $top5Orders }} + + 覆盖率:{{ $shareCoveragePct }}% Top1占比:{{ $shareTop1Pct }}%
@@ -426,7 +436,11 @@ @endphp @php $planOrdersUrl = \App\Support\BackUrl::withBack( - '/admin/platform-orders?' . \Illuminate\Support\Arr::query(['plan_id' => $planId]), + '/admin/platform-orders?' . \Illuminate\Support\Arr::query([ + 'plan_id' => $planId, + 'created_from' => now()->subDays(6)->format('Y-m-d'), + 'created_to' => now()->format('Y-m-d'), + ]), $selfWithoutBack ); @endphp diff --git a/tests/Feature/AdminDashboardPlanOrderShareTop5MetaShouldIncludeCoverageTest.php b/tests/Feature/AdminDashboardPlanOrderShareTop5MetaShouldIncludeCoverageTest.php new file mode 100644 index 0000000..4eb3da6 --- /dev/null +++ b/tests/Feature/AdminDashboardPlanOrderShareTop5MetaShouldIncludeCoverageTest.php @@ -0,0 +1,34 @@ +seed(); + + $this->post('/admin/login', [ + 'email' => 'platform.admin@demo.local', + 'password' => 'Platform@123456', + ])->assertRedirect('/admin'); + } + + public function test_dashboard_plan_order_share_top5_meta_should_include_total_and_coverage(): void + { + $this->loginAsPlatformAdmin(); + + $res = $this->get('/admin'); + $res->assertOk(); + + // 护栏:Top5 摘要行应同时声明“全量口径”和“覆盖率”,避免运营误解 Top5=全部 + $res->assertSee('data-role="plan-order-share-top5-meta"', false); + $res->assertSee('全量订单', false); + $res->assertSee('覆盖率', false); + } +}