feat(admin-dashboard): add rank coverage meta for merchant revenue top5

This commit is contained in:
萝卜
2026-03-16 22:01:06 +08:00
parent 6aa58d5369
commit 3f7ab0ed94
3 changed files with 62 additions and 1 deletions

View File

@@ -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' => [

View File

@@ -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
<div class="adm-mini-meta" data-role="merchant-revenue-rank-7d-meta">
<span class="adm-mini-meta-item">Top5合计已付<strong>¥{{ number_format($rankTotal, 2) }}</strong></span>
<span class="adm-mini-meta-sep"></span>
<span class="adm-mini-meta-item">Top5订单数<strong>{{ (int) $rankOrdersTotal }}</strong></span>
<span class="adm-mini-meta-sep"></span>
<span class="adm-mini-meta-item">覆盖率:<strong>{{ $rankCoveragePct }}%</strong></span>
<span class="adm-mini-meta-sep"></span>
<span class="adm-mini-meta-item">其它:<strong>{{ $rankOtherPct }}%</strong>(¥{{ number_format($rankOtherPaid, 2) }}</span>
<span class="adm-mini-meta-sep"></span>
<span class="adm-mini-meta-item">Top1金额<strong>¥{{ number_format($rankPaidMax, 2) }}</strong></span>
</div>

View File

@@ -0,0 +1,33 @@
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AdminDashboardMerchantRevenueRank7dMetaShouldIncludeCoverageTest extends TestCase
{
use RefreshDatabase;
protected function loginAsPlatformAdmin(): void
{
$this->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);
}
}