@extends('admin.layouts.app') @section('title', '总台仪表盘') @section('page_title', '总台仪表盘') @section('content') @php // 用于构建“从仪表盘跳到其它治理页后可返回仪表盘”的 back $selfWithoutBack = \App\Support\BackUrl::selfWithoutBack(); // 重要:从仪表盘跳转到治理页时,应默认返回“仪表盘”本身(而不是沿用进入仪表盘时的 back)。 $billingEntryLinks = [ 'platform_orders' => \App\Support\BackUrl::withBack('/admin/platform-orders', $selfWithoutBack), 'site_subscriptions' => \App\Support\BackUrl::withBack('/admin/site-subscriptions', $selfWithoutBack), 'plans' => \App\Support\BackUrl::withBack('/admin/plans', $selfWithoutBack), ]; // 仪表盘内所有“近7天”口径统一从 Controller 注入(避免 Blade 内 now() 计算导致跨天漂移)。 $rangeFrom7d = (string) ($dashboardRangeFrom7d ?? now()->subDays(6)->format('Y-m-d')); $rangeTo7d = (string) ($dashboardRangeTo7d ?? now()->format('Y-m-d')); $platformOrdersQuickLinks = [ // 复用工作台入口(避免 /admin/platform-orders 入口口径分叉) 'platform_orders' => $billingEntryLinks['platform_orders'], // 时间范围集合:用于趋势/排行/占比跳转(避免各处散落拼接 query 导致口径漂移) 'platform_orders_range' => function (string $from, string $to) use ($selfWithoutBack): string { return \App\Support\BackUrl::withBack( '/admin/platform-orders?' . \Illuminate\Support\Arr::query([ 'created_from' => $from, 'created_to' => $to, ]), $selfWithoutBack ); }, // 站点收入排行:已付订单集合(merchant_id + payment_status=paid + 日期范围) 'merchant_paid_orders_range' => function (int $merchantId, string $from, string $to) use ($selfWithoutBack): string { return \App\Support\BackUrl::withBack( '/admin/platform-orders?' . \Illuminate\Support\Arr::query([ 'merchant_id' => $merchantId, 'payment_status' => 'paid', 'created_from' => $from, 'created_to' => $to, ]), $selfWithoutBack ); }, // 套餐订单占比:按套餐筛选 + 日期范围(用于 Top5 表格链接,同时被 JS 复用为 mini chart 点击入口) 'plan_orders_range' => function (int $planId, string $from, string $to) use ($selfWithoutBack): string { return \App\Support\BackUrl::withBack( '/admin/platform-orders?' . \Illuminate\Support\Arr::query([ 'plan_id' => $planId, 'created_from' => $from, 'created_to' => $to, ]), $selfWithoutBack ); }, // 平台订单(收费闭环)工作台入口: // 注意:仪表盘「可BMPA处理」统计口径已升级(排除退款轨迹/续费缺订阅)。 // 因此这里不再用简单 pending+unpaid,而是用 bmpa_processable_only=1 统一表达“真正可 BMPA 处理集合”。 'unpaid_pending' => \App\Support\BackUrl::withBack('/admin/platform-orders?bmpa_processable_only=1', $selfWithoutBack), // 待生效:paid + pending,并显式锁定 sync_status=unsynced(排除同步失败等异常单) 'paid_pending' => \App\Support\BackUrl::withBack('/admin/platform-orders?payment_status=paid&status=pending&sync_status=unsynced', $selfWithoutBack), // 可同步(工作台口径):只看可同步 + 未同步(排除同步失败等异常单),与工作台统计口径一致。 'syncable_only' => \App\Support\BackUrl::withBack('/admin/platform-orders?syncable_only=1&sync_status=unsynced', $selfWithoutBack), 'sync_failed' => \App\Support\BackUrl::withBack('/admin/platform-orders?sync_status=failed', $selfWithoutBack), 'renewal_missing_subscription' => \App\Support\BackUrl::withBack('/admin/platform-orders?renewal_missing_subscription=1', $selfWithoutBack), 'bmpa_failed' => \App\Support\BackUrl::withBack('/admin/platform-orders?bmpa_failed_only=1', $selfWithoutBack), 'bmpa_success' => \App\Support\BackUrl::withBack('/admin/platform-orders?bmpa_success_only=1', $selfWithoutBack), 'paid_no_receipt' => \App\Support\BackUrl::withBack('/admin/platform-orders?payment_status=paid&receipt_status=none', $selfWithoutBack), // 与平台订单列表快捷筛选“已付无回执”口径一致 'paid_no_receipt_strict' => \App\Support\BackUrl::withBack('/admin/platform-orders?payment_status=paid&receipt_status=none', $selfWithoutBack), 'reconcile_mismatch' => \App\Support\BackUrl::withBack('/admin/platform-orders?reconcile_mismatch=1', $selfWithoutBack), 'refund_inconsistent' => \App\Support\BackUrl::withBack('/admin/platform-orders?refund_inconsistent=1', $selfWithoutBack), ]; $subscriptionQuickLinks = [ // 复用工作台入口(避免 /admin/site-subscriptions 入口口径分叉) 'site_subscriptions' => $billingEntryLinks['site_subscriptions'], 'expiring_7d' => \App\Support\BackUrl::withBack('/admin/site-subscriptions?expiry=expiring_7d', $selfWithoutBack), 'expired' => \App\Support\BackUrl::withBack('/admin/site-subscriptions?expiry=expired', $selfWithoutBack), ]; @endphp
@php $kpiLinks = [ 'merchants' => \App\Support\BackUrl::withBack('/admin/merchants', $selfWithoutBack), 'plans' => $billingEntryLinks['plans'], 'site_subscriptions' => $billingEntryLinks['site_subscriptions'], 'platform_orders' => $billingEntryLinks['platform_orders'], ]; @endphp
站点
全站点数量(总台视角)
套餐
可售套餐目录
订阅
站点订阅总量(收费主链)
平台订单
平台收费订单总量

趋势

近7天|平台订单(按天)
@php $trendRows = (array) ($platformOrderTrend7d ?? []); // 用于前端渐进增强渲染迷你图表(JS 读取 data-points) $trendPoints = []; foreach ($trendRows as $r) { $trendPoints[] = [ 'date' => (string) ($r['date'] ?? ''), 'count' => (int) ($r['count'] ?? 0), 'paid_sum' => (float) ($r['paid_sum'] ?? 0), ]; } @endphp
@php $trendPaidTotal = 0.0; $trendOrdersTotal = 0; $trendPaidMax = 0.0; foreach ($trendRows as $r) { $trendPaidTotal += (float) ($r['paid_sum'] ?? 0); $trendOrdersTotal += (int) ($r['count'] ?? 0); $trendPaidMax = max($trendPaidMax, (float) ($r['paid_sum'] ?? 0)); } @endphp
7天合计已付:¥{{ number_format($trendPaidTotal, 2) }} 7天订单数:{{ (int) $trendOrdersTotal }} 峰值:¥{{ number_format($trendPaidMax, 2) }}
@forelse($trendRows as $row) @php $d = (string) ($row['date'] ?? ''); $dayOrdersUrl = ($platformOrdersQuickLinks['platform_orders_range'])($d, $d); @endphp @empty @endforelse
日期 订单数 已付金额
{{ $d }} {{ (int) ($row['count'] ?? 0) }} ¥{{ number_format((float) ($row['paid_sum'] ?? 0), 2) }}
暂无数据
说明:先接入最小可用趋势数据;后续再补时间范围切换、维度切换与可视化图表。

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

@php $rankRows = (array) ($merchantRevenueRank7d ?? []); $rankTotal = 0.0; foreach ($rankRows as $r) { $rankTotal += (float) ($r['paid_sum'] ?? 0); } @endphp
近7天|按已付金额统计
@php // 用于前端渐进增强渲染迷你排行(JS 读取 data-points) $rankPoints = []; foreach ($rankRows as $r) { $mid = (int) ($r['merchant_id'] ?? 0); $rankPoints[] = [ 'merchant_id' => $mid, 'name' => (string) (($merchantIdToName[$mid] ?? '') ?: ('#' . $mid)), 'count' => (int) ($r['count'] ?? 0), 'paid_sum' => (float) ($r['paid_sum'] ?? 0), ]; } @endphp
@php $rankPaidMax = 0.0; $rankOrdersTotal = 0; foreach ($rankRows as $r) { $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) }}
@forelse($rankRows as $row) @php $mid = (int) ($row['merchant_id'] ?? 0); $mname = (string) (($merchantIdToName[$mid] ?? '') ?: ('#' . $mid)); $merchantOrdersUrl = ($platformOrdersQuickLinks['merchant_paid_orders_range'])($mid, $rangeFrom7d, $rangeTo7d); @endphp @empty @endforelse
站点 订单数 已付金额
{{ $mname }} {{ (int) ($row['count'] ?? 0) }} ¥{{ number_format((float) ($row['paid_sum'] ?? 0), 2) }}
暂无数据
说明:先落最小可用 Top5 排行;后续补时间范围切换、维度切换与异常排行。

收费工作台(快捷治理)

聚焦收费闭环的日常治理入口:订单 → 订阅 → 套餐。
平台订单快捷筛选(只保留“点完能做事”的治理入口):
高级筛选(少用,默认收起)
@php $poTotal = (int) ($stats['platform_orders'] ?? 0); $poSyncFailed = (int) ($stats['platform_orders_sync_failed'] ?? 0); $poBmpaFailed = (int) ($stats['platform_orders_bmpa_failed'] ?? 0); $poNoReceipt = (int) ($stats['platform_orders_paid_no_receipt'] ?? 0); $poRenewalMissing = (int) ($stats['platform_orders_renewal_missing_subscription'] ?? 0); $poReconcileMismatch = (int) ($stats['platform_orders_reconcile_mismatch'] ?? 0); $poRefundInconsistent = (int) ($stats['platform_orders_refund_inconsistent'] ?? 0); $poSyncFailedPct = $poTotal > 0 ? min(100, max(0, round(($poSyncFailed / $poTotal) * 100, 1))) : 0; $poBmpaFailedPct = $poTotal > 0 ? min(100, max(0, round(($poBmpaFailed / $poTotal) * 100, 1))) : 0; $poNoReceiptPct = $poTotal > 0 ? min(100, max(0, round(($poNoReceipt / $poTotal) * 100, 1))) : 0; $poRenewalMissingPct = $poTotal > 0 ? min(100, max(0, round(($poRenewalMissing / $poTotal) * 100, 1))) : 0; $poReconcileMismatchPct = $poTotal > 0 ? min(100, max(0, round(($poReconcileMismatch / $poTotal) * 100, 1))) : 0; $poRefundInconsistentPct = $poTotal > 0 ? min(100, max(0, round(($poRefundInconsistent / $poTotal) * 100, 1))) : 0; @endphp @php $poUnpaidPending = (int) ($stats['platform_orders_unpaid_pending'] ?? 0); $poPaidPending = (int) ($stats['platform_orders_paid_pending'] ?? 0); $poSyncable = (int) ($stats['platform_orders_syncable'] ?? 0); $poUnpaidPendingPct = $poTotal > 0 ? min(100, max(0, round(($poUnpaidPending / $poTotal) * 100, 1))) : 0; $poPaidPendingPct = $poTotal > 0 ? min(100, max(0, round(($poPaidPending / $poTotal) * 100, 1))) : 0; $poSyncablePct = $poTotal > 0 ? min(100, max(0, round(($poSyncable / $poTotal) * 100, 1))) : 0; @endphp
收费主链漏斗(相对平台订单总量 {{ $poTotal }})
@include('admin.components.metric_explain', [ 'items' => [ '待支付=unpaid+pending', '待生效=paid+pending+unsynced', '可同步=paid+activated+unsynced+非失败(并排除续费缺订阅脏数据)', ], ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-po-unpaid-pending-row', 'barRole' => 'dashboard-po-unpaid-pending-bar', 'href' => $platformOrdersQuickLinks['unpaid_pending'], 'ariaLabel' => '进入待支付订单集合', 'label' => '待支付', 'pct' => $poUnpaidPendingPct, 'title' => $poUnpaidPending . ' / ' . $poTotal . '(' . $poUnpaidPendingPct . '%)', 'value' => $poUnpaidPendingPct . '%(' . $poUnpaidPending . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-po-paid-pending-row', 'barRole' => 'dashboard-po-paid-pending-bar', 'href' => $platformOrdersQuickLinks['paid_pending'], 'ariaLabel' => '进入待生效订单集合', 'label' => '待生效', 'pct' => $poPaidPendingPct, 'title' => $poPaidPending . ' / ' . $poTotal . '(' . $poPaidPendingPct . '%)', 'value' => $poPaidPendingPct . '%(' . $poPaidPending . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-po-syncable-row', 'barRole' => 'dashboard-po-syncable-bar', 'href' => $platformOrdersQuickLinks['syncable_only'], 'ariaLabel' => '进入可同步订单集合', 'label' => '可同步', 'pct' => $poSyncablePct, 'title' => $poSyncable . ' / ' . $poTotal . '(' . $poSyncablePct . '%)', 'value' => $poSyncablePct . '%(' . $poSyncable . ')', ])
治理风险占比(相对平台订单总量 {{ $poTotal }})
@include('admin.components.metric_explain', [ 'items' => [ '同步失败=meta.subscription_activation_error.message 存在', 'BMPA失败=meta.batch_mark_paid_and_activate_error.message 存在', '无回执=已支付但缺 payment_receipts', '对账不一致=回执汇总金额与 paid_amount 不一致', '退款不一致=退款汇总与退款状态不一致', '续费缺订阅=renewal 但 site_subscription_id 为空', ], ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-po-sync-failed-row', 'barRole' => 'dashboard-po-sync-failed-bar', 'href' => $platformOrdersQuickLinks['sync_failed'], 'ariaLabel' => '进入同步失败订单集合', 'label' => '同步失败', 'pct' => $poSyncFailedPct, 'title' => $poSyncFailed . ' / ' . $poTotal . '(' . $poSyncFailedPct . '%)', 'value' => $poSyncFailedPct . '%(' . $poSyncFailed . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-po-bmpa-failed-row', 'barRole' => 'dashboard-po-bmpa-failed-bar', 'href' => $platformOrdersQuickLinks['bmpa_failed'], 'ariaLabel' => '进入BMPA失败订单集合', 'label' => 'BMPA失败', 'pct' => $poBmpaFailedPct, 'title' => $poBmpaFailed . ' / ' . $poTotal . '(' . $poBmpaFailedPct . '%)', 'value' => $poBmpaFailedPct . '%(' . $poBmpaFailed . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-po-no-receipt-row', 'barRole' => 'dashboard-po-no-receipt-bar', 'href' => $platformOrdersQuickLinks['paid_no_receipt'], 'ariaLabel' => '进入无回执订单集合', 'label' => '无回执', 'pct' => $poNoReceiptPct, 'title' => $poNoReceipt . ' / ' . $poTotal . '(' . $poNoReceiptPct . '%)', 'value' => $poNoReceiptPct . '%(' . $poNoReceipt . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-po-renewal-missing-row', 'barRole' => 'dashboard-po-renewal-missing-bar', 'href' => $platformOrdersQuickLinks['renewal_missing_subscription'], 'ariaLabel' => '进入续费缺订阅订单集合', 'label' => '续费缺订阅', 'pct' => $poRenewalMissingPct, 'title' => $poRenewalMissing . ' / ' . $poTotal . '(' . $poRenewalMissingPct . '%)', 'value' => $poRenewalMissingPct . '%(' . $poRenewalMissing . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-po-reconcile-mismatch-row', 'barRole' => 'dashboard-po-reconcile-mismatch-bar', 'href' => $platformOrdersQuickLinks['reconcile_mismatch'], 'ariaLabel' => '进入对账不一致订单集合', 'label' => '对账不一致', 'pct' => $poReconcileMismatchPct, 'title' => $poReconcileMismatch . ' / ' . $poTotal . '(' . $poReconcileMismatchPct . '%)', 'value' => $poReconcileMismatchPct . '%(' . $poReconcileMismatch . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-po-refund-inconsistent-row', 'barRole' => 'dashboard-po-refund-inconsistent-bar', 'href' => $platformOrdersQuickLinks['refund_inconsistent'], 'ariaLabel' => '进入退款不一致订单集合', 'label' => '退款不一致', 'pct' => $poRefundInconsistentPct, 'title' => $poRefundInconsistent . ' / ' . $poTotal . '(' . $poRefundInconsistentPct . '%)', 'value' => $poRefundInconsistentPct . '%(' . $poRefundInconsistent . ')', ])
订阅到期治理:
@php $subTotal = (int) ($stats['site_subscriptions'] ?? 0); $subExpiring7d = (int) ($stats['site_subscriptions_expiring_7d'] ?? 0); $subExpired = (int) ($stats['site_subscriptions_expired'] ?? 0); $pctExpiring7d = $subTotal > 0 ? min(100, max(0, round(($subExpiring7d / $subTotal) * 100, 1))) : 0; $pctExpired = $subTotal > 0 ? min(100, max(0, round(($subExpired / $subTotal) * 100, 1))) : 0; @endphp
占比(相对订阅总量 {{ $subTotal }})
@include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-sub-expiring-7d-row', 'barRole' => 'dashboard-sub-expiring-7d-bar', 'href' => $subscriptionQuickLinks['expiring_7d'], 'ariaLabel' => '进入7天内到期订阅集合', 'label' => '7天内到期', 'pct' => $pctExpiring7d, 'title' => $subExpiring7d . ' / ' . $subTotal . '(' . $pctExpiring7d . '%)', 'value' => $pctExpiring7d . '%(' . $subExpiring7d . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'dashboard-sub-expired-row', 'barRole' => 'dashboard-sub-expired-bar', 'href' => $subscriptionQuickLinks['expired'], 'ariaLabel' => '进入已过期订阅集合', 'label' => '已过期', 'pct' => $pctExpired, 'title' => $subExpired . ' / ' . $subTotal . '(' . $pctExpired . '%)', 'value' => $pctExpired . '%(' . $subExpired . ')', ])
说明:这里先把收费主链的高频治理入口收敛到仪表盘;后续再补趋势/排行的真实聚合。

平台定位(运营版)

只保留“看完知道下一步做什么”的北极星指标与治理积压。
@php $ops = $platformOpsOverview ?? []; $opsLinks = (array) ($ops['links'] ?? []); $paidRevenue30d = (float) ($ops['paid_revenue_30d'] ?? 0); $activePaidMerchants = (int) ($ops['active_paid_merchants'] ?? 0); $renewalRate30d = (float) ($ops['renewal_success_rate_30d'] ?? 0); $renewalSuccess30d = (int) ($ops['renewal_success_30d'] ?? 0); $renewalCreated30d = (int) ($ops['renewal_created_30d'] ?? 0); $ordersTotal7d = (int) ($ops['orders_total_7d'] ?? 0); $funnelUnpaidPending7d = (int) ($ops['funnel_unpaid_pending_7d'] ?? 0); $funnelPaid7d = (int) ($ops['funnel_paid_7d'] ?? 0); $funnelPaidActivated7d = (int) ($ops['funnel_paid_activated_7d'] ?? 0); $goBmpa = (int) ($ops['govern_bmpa_processable'] ?? 0); $goSyncable = (int) ($ops['govern_syncable'] ?? 0); $goSyncFailed = (int) ($ops['govern_sync_failed'] ?? 0); @endphp @php // 北极星指标图形化:给运营“规模感/健康感”,但不引入额外分类维度。 $merchantsTotal = (int) ($stats['merchants'] ?? 0); $pctActivePaidMerchants = $merchantsTotal > 0 ? min(100, max(0, round(($activePaidMerchants / $merchantsTotal) * 100, 1))) : 0; @endphp
北极星指标 (点击展开口径说明)
@include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-northstar-active-paid-merchants-row', 'barRole' => 'ops-northstar-active-paid-merchants-bar', 'href' => (string) ($opsLinks['active_paid_merchants_subscriptions'] ?? $billingEntryLinks['site_subscriptions']), 'ariaLabel' => '进入活跃付费站点订阅集合', 'label' => '付费渗透', 'pct' => $pctActivePaidMerchants, 'title' => $activePaidMerchants . ' / ' . $merchantsTotal . '(' . $pctActivePaidMerchants . '%)', 'value' => $pctActivePaidMerchants . '%(' . $activePaidMerchants . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-northstar-renewal-rate-row', 'barRole' => 'ops-northstar-renewal-rate-bar', 'href' => (string) ($opsLinks['renewal_orders_30d'] ?? $billingEntryLinks['platform_orders']), 'ariaLabel' => '进入近30天续费订单集合', 'label' => '续费成功率', 'pct' => $renewalRate30d, 'title' => $renewalRate30d . '%(' . $renewalSuccess30d . ' / ' . $renewalCreated30d . ')', 'value' => $renewalRate30d . '%', ])
北极星指标口径说明
近30天已收款 ¥{{ number_format($paidRevenue30d, 2) }}
活跃付费站点 {{ $activePaidMerchants }} (以“已生效且未到期订阅”估算)
续费成功率(30天) {{ $renewalRate30d }}% ({{ $renewalSuccess30d }} / {{ $renewalCreated30d }})
说明:付费渗透 = 活跃付费站点 / 站点总数;续费成功率按近30天续费单计算。
@php $den = max(1, $ordersTotal7d); $pctUnpaidPending = $den > 0 ? min(100, max(0, round(($funnelUnpaidPending7d / $den) * 100, 1))) : 0; $pctPaid = $den > 0 ? min(100, max(0, round(($funnelPaid7d / $den) * 100, 1))) : 0; $pctPaidActivated = $den > 0 ? min(100, max(0, round(($funnelPaidActivated7d / $den) * 100, 1))) : 0; // 待处理治理:以平台订单总量作为分母,给一个“规模感”(不要求精确经营含义)。 $poTotalForOps = (int) ($stats['platform_orders'] ?? 0); $denOps = max(1, $poTotalForOps); $pctGoBmpa = $poTotalForOps > 0 ? min(100, max(0, round(($goBmpa / $denOps) * 100, 1))) : 0; $pctGoSyncable = $poTotalForOps > 0 ? min(100, max(0, round(($goSyncable / $denOps) * 100, 1))) : 0; $pctGoSyncFailed = $poTotalForOps > 0 ? min(100, max(0, round(($goSyncFailed / $denOps) * 100, 1))) : 0; @endphp
收款漏斗(近7天)
用于快速判断卡点:催付 / 治理生效 / 同步订阅。
@include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-funnel-unpaid-pending-row', 'barRole' => 'ops-funnel-unpaid-pending-bar', 'href' => (string) ($opsLinks['funnel_unpaid_pending_7d'] ?? $platformOrdersQuickLinks['unpaid_pending']), 'ariaLabel' => '进入近7天待支付订单集合', 'label' => '待支付', 'pct' => $pctUnpaidPending, 'title' => $funnelUnpaidPending7d . ' / ' . $ordersTotal7d . '(' . $pctUnpaidPending . '%)', 'value' => $pctUnpaidPending . '%(' . $funnelUnpaidPending7d . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-funnel-paid-row', 'barRole' => 'ops-funnel-paid-bar', 'href' => (string) ($opsLinks['funnel_paid_7d'] ?? $platformOrdersQuickLinks['platform_orders']), 'ariaLabel' => '进入近7天已支付订单集合', 'label' => '已支付', 'pct' => $pctPaid, 'title' => $funnelPaid7d . ' / ' . $ordersTotal7d . '(' . $pctPaid . '%)', 'value' => $pctPaid . '%(' . $funnelPaid7d . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-funnel-paid-activated-row', 'barRole' => 'ops-funnel-paid-activated-bar', 'href' => (string) ($opsLinks['funnel_paid_activated_7d'] ?? $platformOrdersQuickLinks['platform_orders']), 'ariaLabel' => '进入近7天已生效订单集合', 'label' => '已生效', 'pct' => $pctPaidActivated, 'title' => $funnelPaidActivated7d . ' / ' . $ordersTotal7d . '(' . $pctPaidActivated . '%)', 'value' => $pctPaidActivated . '%(' . $funnelPaidActivated7d . ')', ])
分母:近7天平台订单总数 {{ $ordersTotal7d }}(含未支付/已支付)。
待处理治理(Top3)
用于快速判断治理积压:优先清空“能直接处理”的集合。
@include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-govern-bmpa-row', 'barRole' => 'ops-govern-bmpa-bar', 'href' => $platformOrdersQuickLinks['unpaid_pending'], 'ariaLabel' => '进入可BMPA处理订单集合', 'label' => '可BMPA', 'pct' => $pctGoBmpa, 'title' => $goBmpa . ' / ' . $poTotalForOps . '(' . $pctGoBmpa . '%)', 'value' => $pctGoBmpa . '%(' . $goBmpa . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-govern-syncable-row', 'barRole' => 'ops-govern-syncable-bar', 'href' => $platformOrdersQuickLinks['syncable_only'], 'ariaLabel' => '进入可同步订单集合', 'label' => '可同步', 'pct' => $pctGoSyncable, 'title' => $goSyncable . ' / ' . $poTotalForOps . '(' . $pctGoSyncable . '%)', 'value' => $pctGoSyncable . '%(' . $goSyncable . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-govern-sync-failed-row', 'barRole' => 'ops-govern-sync-failed-bar', 'href' => $platformOrdersQuickLinks['sync_failed'], 'ariaLabel' => '进入同步失败订单集合', 'label' => '同步失败', 'pct' => $pctGoSyncFailed, 'title' => $goSyncFailed . ' / ' . $poTotalForOps . '(' . $pctGoSyncFailed . '%)', 'value' => $pctGoSyncFailed . '%(' . $goSyncFailed . ')', ])
分母:平台订单总量 {{ $poTotalForOps }}(用于规模感,不作为经营口径)。
@php // 平台健康预警:原因型风险(点进去有明确动作:补回执/对账/核对退款)。 $riskNoReceipt = (int) ($stats['platform_orders_paid_no_receipt'] ?? 0); $riskReconcileMismatch = (int) ($stats['platform_orders_reconcile_mismatch'] ?? 0); $riskRefundInconsistent = (int) ($stats['platform_orders_refund_inconsistent'] ?? 0); $pctRiskNoReceipt = $poTotalForOps > 0 ? min(100, max(0, round(($riskNoReceipt / $denOps) * 100, 1))) : 0; $pctRiskReconcileMismatch = $poTotalForOps > 0 ? min(100, max(0, round(($riskReconcileMismatch / $denOps) * 100, 1))) : 0; $pctRiskRefundInconsistent = $poTotalForOps > 0 ? min(100, max(0, round(($riskRefundInconsistent / $denOps) * 100, 1))) : 0; // 异常积压:点进去要做“治理修复/补关联/重试”。 $exBmpaFailed = (int) ($stats['platform_orders_bmpa_failed'] ?? 0); $exRenewalMissing = (int) ($stats['platform_orders_renewal_missing_subscription'] ?? 0); $pctExBmpaFailed = $poTotalForOps > 0 ? min(100, max(0, round(($exBmpaFailed / $denOps) * 100, 1))) : 0; $pctExRenewalMissing = $poTotalForOps > 0 ? min(100, max(0, round(($exRenewalMissing / $denOps) * 100, 1))) : 0; @endphp
平台健康预警(Top3)
原因型风险:补回执 / 对账 / 核对退款。
@include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-risk-no-receipt-row', 'barRole' => 'ops-risk-no-receipt-bar', 'href' => $platformOrdersQuickLinks['paid_no_receipt'], 'ariaLabel' => '进入无回执订单集合', 'label' => '无回执', 'pct' => $pctRiskNoReceipt, 'title' => $riskNoReceipt . ' / ' . $poTotalForOps . '(' . $pctRiskNoReceipt . '%)', 'value' => $pctRiskNoReceipt . '%(' . $riskNoReceipt . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-risk-reconcile-mismatch-row', 'barRole' => 'ops-risk-reconcile-mismatch-bar', 'href' => $platformOrdersQuickLinks['reconcile_mismatch'], 'ariaLabel' => '进入对账不一致订单集合', 'label' => '对账不一致', 'pct' => $pctRiskReconcileMismatch, 'title' => $riskReconcileMismatch . ' / ' . $poTotalForOps . '(' . $pctRiskReconcileMismatch . '%)', 'value' => $pctRiskReconcileMismatch . '%(' . $riskReconcileMismatch . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-risk-refund-inconsistent-row', 'barRole' => 'ops-risk-refund-inconsistent-bar', 'href' => $platformOrdersQuickLinks['refund_inconsistent'], 'ariaLabel' => '进入退款不一致订单集合', 'label' => '退款不一致', 'pct' => $pctRiskRefundInconsistent, 'title' => $riskRefundInconsistent . ' / ' . $poTotalForOps . '(' . $pctRiskRefundInconsistent . '%)', 'value' => $pctRiskRefundInconsistent . '%(' . $riskRefundInconsistent . ')', ])
更多异常积压(少用)
异常型治理:批量失败 / 续费缺订阅等。
@include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-exception-bmpa-failed-row', 'barRole' => 'ops-exception-bmpa-failed-bar', 'href' => $platformOrdersQuickLinks['bmpa_failed'], 'ariaLabel' => '进入BMPA失败订单集合', 'label' => 'BMPA失败', 'pct' => $pctExBmpaFailed, 'title' => $exBmpaFailed . ' / ' . $poTotalForOps . '(' . $pctExBmpaFailed . '%)', 'value' => $pctExBmpaFailed . '%(' . $exBmpaFailed . ')', ]) @include('admin.components.mini_bar_row', [ 'class' => 'mt-6', 'rowRole' => 'ops-exception-renewal-missing-row', 'barRole' => 'ops-exception-renewal-missing-bar', 'href' => $platformOrdersQuickLinks['renewal_missing_subscription'], 'ariaLabel' => '进入续费缺订阅订单集合', 'label' => '续费缺订阅', 'pct' => $pctExRenewalMissing, 'title' => $exRenewalMissing . ' / ' . $poTotalForOps . '(' . $pctExRenewalMissing . '%)', 'value' => $pctExRenewalMissing . '%(' . $exRenewalMissing . ')', ])

最近平台订单

查看全部
@php // 最近平台订单:概览 mini chart(渐进增强) // 目标:让“最近订单列表”也纳入数据图形化体系,但不牺牲明细扫描行。 // 注意:$recentPlatformOrders 是 Eloquent Collection,可直接 foreach;不要强转 (array) // 否则会变成对象属性数组,导致统计口径全部变 0。 $recentPos = $recentPlatformOrders ?? []; $recentTotal = is_countable($recentPos) ? count($recentPos) : 0; $recentCntBmpaSuccess = 0; $recentCntBmpaFailed = 0; $recentCntSyncSuccess = 0; $recentCntSyncFailed = 0; $recentCntRenewalMissing = 0; $recentCntRefundTrace = 0; $recentCntReconcileMismatch = 0; foreach ($recentPos as $rpo) { $orderType = (string) ($rpo->order_type ?? ''); $bmpaErr = (string) (data_get($rpo, 'meta.batch_mark_paid_and_activate_error.message') ?? ''); $bmpaRunId = (string) (data_get($rpo, 'meta.batch_mark_paid_and_activate.run_id') ?? ''); if ($bmpaErr !== '') { $recentCntBmpaFailed++; } elseif ($bmpaRunId !== '') { $recentCntBmpaSuccess++; } $syncErr = (string) (data_get($rpo, 'meta.subscription_activation_error.message') ?? ''); $syncSubId = (string) (data_get($rpo, 'meta.subscription_activation.subscription_id') ?? ''); if ($syncErr !== '') { $recentCntSyncFailed++; } elseif ($syncSubId !== '') { $recentCntSyncSuccess++; } if ($orderType === 'renewal' && ((int) ($rpo->site_subscription_id ?? 0) <= 0)) { $recentCntRenewalMissing++; } $refundTotal = (float) (data_get($rpo, 'refund_total') ?? 0); if ($refundTotal > 0) { $recentCntRefundTrace++; } if ((bool) (data_get($rpo, 'reconciliation_delta_row') ?? 0) != 0) { $recentCntReconcileMismatch++; } } // clickable links: 复用 $platformOrdersQuickLinks(保证口径不漂移) $recentMiniPoints = [ [ 'key' => 'bmpa_success', 'label' => 'BMPA成功', 'count' => $recentCntBmpaSuccess, 'href' => $platformOrdersQuickLinks['bmpa_success'] ?? $platformOrdersQuickLinks['platform_orders'], 'tone' => 'success', ], [ 'key' => 'bmpa_failed', 'label' => 'BMPA失败', 'count' => $recentCntBmpaFailed, 'href' => $platformOrdersQuickLinks['bmpa_failed'] ?? $platformOrdersQuickLinks['platform_orders'], 'tone' => 'danger', ], [ 'key' => 'sync_success', 'label' => '同步成功', 'count' => $recentCntSyncSuccess, 'href' => \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([ 'sync_status' => 'synced', ]), $selfWithoutBack), 'tone' => 'success', ], [ 'key' => 'sync_failed', 'label' => '同步失败', 'count' => $recentCntSyncFailed, 'href' => $platformOrdersQuickLinks['sync_failed'] ?? $platformOrdersQuickLinks['platform_orders'], 'tone' => 'danger', ], [ 'key' => 'renewal_missing_subscription', 'label' => '续费缺订阅', 'count' => $recentCntRenewalMissing, 'href' => $platformOrdersQuickLinks['renewal_missing_subscription'] ?? $platformOrdersQuickLinks['platform_orders'], 'tone' => 'warn', ], [ 'key' => 'refund_trace', 'label' => '有退款轨迹', 'count' => $recentCntRefundTrace, 'href' => \App\Support\BackUrl::withBack('/admin/platform-orders?refund_status=has', $selfWithoutBack), 'tone' => 'warn', ], [ 'key' => 'reconcile_mismatch', 'label' => '对账不一致', 'count' => $recentCntReconcileMismatch, 'href' => $platformOrdersQuickLinks['reconcile_mismatch'] ?? $platformOrdersQuickLinks['platform_orders'], 'tone' => 'danger', ], ]; @endphp
最近:{{ $recentTotal }} 说明:点击条目进入对应治理集合(用于快速 spot-check)
@forelse(($recentPlatformOrders ?? []) as $po) @php $poShowUrl = \App\Support\BackUrl::withBack('/admin/platform-orders/' . $po->id, $selfWithoutBack); $poShowGovernanceUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'order-governance-actions'); $hasReceiptEvidence = (data_get($po->meta, 'payment_summary.total_amount') !== null) || (data_get($po->meta, 'payment_receipts.0.amount') !== null); $fixReceiptUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'add-payment-receipt'); $fixRefundReceiptUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'add-refund-receipt'); $noReceiptListUrl = $platformOrdersQuickLinks['paid_no_receipt']; $syncErrMsg = (string) (data_get($po->meta, 'subscription_activation_error.message') ?? ''); $bmpaErrMsg = (string) (data_get($po->meta, 'batch_mark_paid_and_activate_error.message') ?? ''); $syncFailedListUrl = $platformOrdersQuickLinks['sync_failed']; $syncedListUrl = \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([ 'sync_status' => 'synced', ]), $selfWithoutBack); $bmpaFailedListUrl = $platformOrdersQuickLinks['bmpa_failed']; // 扫描行:直达治理锚点(与下方提示块的链接口径保持一致) // 最短治理路径:从仪表盘直接落到可执行动作面板,避免仅滚动到列表区后还要再找按钮。 $scanGoReconcileUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'add-payment-receipt'); $scanGoPaymentReceiptsUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'payment-receipts'); $scanGoRefundUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'add-refund-receipt'); $scanGoRefundReceiptsUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'refund-receipts'); $scanGoSyncFailedUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'sync-failed'); $scanGoBmpaFailedUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'bmpa-failed'); $bmpaSuccessListUrl = $platformOrdersQuickLinks['bmpa_success'] ?? ''; $scanGoBmpaSuccessUrl = $bmpaSuccessListUrl !== '' ? $bmpaSuccessListUrl : \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([ 'bmpa_success_only' => '1', ]), $selfWithoutBack); $scanGoRelationUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders/' . $po->id, $selfWithoutBack, 'relation-subscription'); // 订阅详情:当续费单已关联订阅时,扫描行提供直达订阅详情入口(便于 spot-check) $subscriptionShowUrl = ! empty($po->site_subscription_id) ? \App\Support\BackUrl::withBack('/admin/site-subscriptions/' . (int) $po->site_subscription_id, $selfWithoutBack) : ''; // 运营扫描用的“治理状态摘要”(不替代下方的治理提示入口,只用于快速判断) // 注意:为避免对“未支付订单”造成误导,回执/对账/退款在非 paid/refunded 时显示 "-"。 $paymentStatus = (string) ($po->payment_status ?? ''); $isPaid = ($paymentStatus === 'paid'); $isRefunded = ($paymentStatus === 'refunded'); // partially_refunded 属于“已支付但发生退款”的治理集合:扫描行应展示退款轨迹(避免显示 "-" 造成误判)。 $isPartiallyRefunded = ($paymentStatus === 'partially_refunded'); $receiptStatusText = $isPaid ? ($hasReceiptEvidence ? '有' : '无') : '-'; $reconcileStatusText = ($isPaid && $hasReceiptEvidence) ? ($po->isReconcileMismatch() ? '不一致' : '一致') : '-'; // 扫描行退款摘要口径(更贴近治理): // - 非 paid/refunded:显示 "-"(避免对未支付订单造成误导) // - paid/refunded: // - 有退款且不一致:"异常"(直达 #add-refund-receipt) // - 有退款且一致:"有"(直达 #add-refund-receipt,便于核对退款轨迹) // - 无退款:"无" $hasRefundTrace = ((float) $po->refundTotal()) > 0; $refundStatusText = ($isPaid || $isRefunded || $isPartiallyRefunded) ? ($po->isRefundInconsistent() ? '异常' : ($hasRefundTrace ? '有' : '无')) : '-'; // 同步摘要口径(更贴近治理/复核): // - 有 error.message:失败 // - 无 error 且有 subscription_activation.subscription_id:成功(已同步) // - 否则:无(尚未同步) $syncSubscriptionId = (string) (data_get($po->meta, 'subscription_activation.subscription_id') ?? ''); $syncStatusText = $syncErrMsg !== '' ? '失败' : ($syncSubscriptionId !== '' ? '成功' : '无'); // BMPA 摘要口径(更贴近治理/复核): // - 有 error.message:失败 // - 无 error 且有 run_id:成功(可用于抽样复核 spot-check) // - 否则:无(尚未发生 BMPA) $bmpaRunId = (string) (data_get($po->meta, 'batch_mark_paid_and_activate.run_id') ?? ''); $bmpaStatusText = $bmpaErrMsg !== '' ? '失败' : ($bmpaRunId !== '' ? '成功' : '无'); $subscriptionStatusText = ((string) $po->order_type === 'renewal') ? (empty($po->site_subscription_id) ? '缺' : '有') : '-'; // 运营提效:失败原因较短时,提供“一键进入同原因集合”链接(避免复制粘贴)。 // 与平台订单列表页的阈值保持一致(避免仪表盘能点、列表页却不支持/反之)。 $FAILED_REASON_KEYWORD_MAX_LEN = (int) config('saasshop.platform_orders.sync_error_keyword_link_max_len', 200); $syncReasonUrl = ''; if ($syncErrMsg !== '' && mb_strlen($syncErrMsg) <= $FAILED_REASON_KEYWORD_MAX_LEN) { $syncReasonUrl = \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([ 'sync_status' => 'failed', 'sync_error_keyword' => $syncErrMsg, ]), $selfWithoutBack); } $bmpaReasonUrl = ''; if ($bmpaErrMsg !== '' && mb_strlen($bmpaErrMsg) <= $FAILED_REASON_KEYWORD_MAX_LEN) { $bmpaReasonUrl = \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([ 'bmpa_failed_only' => '1', 'bmpa_error_keyword' => $bmpaErrMsg, ]), $selfWithoutBack); } @endphp @empty @endforelse
订单号 类型 金额 支付 状态
{{ $po->order_no }} {{ $po->orderTypeLabel() }}
{{ (string) (optional($po->merchant)->name ?: ('站点#' . (int) ($po->merchant_id ?? 0))) }} {{ (string) (optional($po->plan)->name ?: ((int) ($po->plan_id ?? 0) > 0 ? ('套餐#' . (int) $po->plan_id) : '-')) }}
回执: @if($receiptStatusText === '无') {{ $receiptStatusText }} @elseif($receiptStatusText === '有') {{ $receiptStatusText }} @else {{ $receiptStatusText }} @endif 对账: @if($reconcileStatusText !== '-' && $reconcileStatusText !== '一致') {{ $reconcileStatusText }} @elseif($reconcileStatusText === '一致') {{ $reconcileStatusText }} @else {{ $reconcileStatusText }} @endif 退款: @if($refundStatusText !== '-' && $refundStatusText !== '无') {{ $refundStatusText }} @elseif($refundStatusText === '无') {{ $refundStatusText }} @else {{ $refundStatusText }} @endif 同步: @if($syncStatusText === '失败') {{ $syncStatusText }} @elseif($syncStatusText === '成功') {{ $syncStatusText }} @else {{ $syncStatusText }} @endif BMPA: @if($bmpaStatusText === '失败') {{ $bmpaStatusText }} @elseif($bmpaStatusText === '成功' && $scanGoBmpaSuccessUrl !== '') {{ $bmpaStatusText }} @else {{ $bmpaStatusText }} @endif 订阅: @if($subscriptionStatusText === '缺') {{ $subscriptionStatusText }} @elseif($subscriptionStatusText === '有' && $subscriptionShowUrl !== '') {{ $subscriptionStatusText }} @else {{ $subscriptionStatusText }} @endif
¥{{ number_format((float) $po->payable_amount, 2) }} {{ $po->payment_status }} @if((string) $po->payment_status === 'paid' && ! $hasReceiptEvidence)
无回执 去补回执 进入集合
@endif
{{ $po->status }} @if($syncErrMsg !== '')
同步失败 进入集合 @if($syncReasonUrl !== '') 同原因集合 @elseif($syncErrMsg !== '') 原因过长 @endif 查看失败详情
@endif @if($bmpaErrMsg !== '')
BMPA失败 进入集合 @if($bmpaReasonUrl !== '') 同原因集合 @elseif($bmpaErrMsg !== '') 原因过长 @endif 查看失败详情
@endif @if((string) $po->status === 'pending' && (string) $po->payment_status === 'paid' && $po->isReconcileMismatch())
对账不一致 进入集合 去对账 去补回执
@endif @if($po->isRefundInconsistent())
退款不一致 进入集合 去核对退款 去补退款记录
@endif @if((string) $po->order_type === 'renewal' && empty($po->site_subscription_id))
续费缺订阅 进入集合 去关联订阅
@endif
暂无数据
说明:当前先接入最近订单列表;后续补“同步状态/站点/套餐/治理入口”。

套餐订单占比(Top5)

查看套餐
近7天|按订单数统计
@php $shareRows = (array) ($planOrderShare ?? []); $top5Orders = 0; foreach ($shareRows as $r) { $top5Orders += (int) ($r['count'] ?? 0); } $totalOrders = (int) ($planOrderShareTotal ?? 0); if ($totalOrders <= 0) { // 兜底:兼容旧数据(未传 total 时,至少不影响渲染) $totalOrders = (int) $top5Orders; } @endphp @php // 用于前端渐进增强渲染占比条形图(JS 读取 data-points) $sharePoints = []; foreach ($shareRows as $r) { $pid = (int) ($r['plan_id'] ?? 0); $sharePoints[] = [ 'plan_id' => $pid, 'name' => (string) (($planIdToName[$pid] ?? '') ?: ('#' . $pid)), 'count' => (int) ($r['count'] ?? 0), ]; } @endphp
@php $shareTop1Count = 0; foreach ($shareRows as $r) { $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; $shareOtherPct = max(0, round(100 - $shareCoveragePct, 1)); $shareOtherCount = max(0, (int) $totalOrders - (int) $top5Orders); @endphp
全量订单:{{ (int) $totalOrders }} Top5合计:{{ (int) $top5Orders }} 覆盖率:{{ $shareCoveragePct }}% 其它:{{ $shareOtherPct }}%({{ (int) $shareOtherCount }}单) Top1占比:{{ $shareTop1Pct }}%
@forelse($shareRows as $row) @php $planId = (int) ($row['plan_id'] ?? 0); $count = (int) ($row['count'] ?? 0); $pct = $totalOrders > 0 ? round(($count / $totalOrders) * 100, 1) : 0; $planName = (string) (($planIdToName[$planId] ?? '') ?: ('#' . $planId)); @endphp @php $planOrdersUrl = ($platformOrdersQuickLinks['plan_orders_range'])($planId, $rangeFrom7d, $rangeTo7d); @endphp @empty @endforelse
套餐 订单数 占比
{{ $planName }} {{ $count }} {{ $pct }}%
暂无数据
说明:当前口径为“平台订单按 plan_id 的数量占比(Top5)”;后续扩展到金额占比、渠道占比与时间范围切换。
@endsection