platform orders: add renewal missing subscription governance card

This commit is contained in:
萝卜
2026-03-15 06:14:52 +00:00
parent ebc0bd8ce2
commit 2d67c167ed
3 changed files with 50 additions and 0 deletions

View File

@@ -255,6 +255,8 @@ class PlatformOrderController extends Controller
'bmpa_error_keyword' => trim((string) $request->query('bmpa_error_keyword', '')), 'bmpa_error_keyword' => trim((string) $request->query('bmpa_error_keyword', '')),
// 只看“可同步订阅”的订单:已支付 + 已生效 + 未同步(用于运营快速处理) // 只看“可同步订阅”的订单:已支付 + 已生效 + 未同步(用于运营快速处理)
'syncable_only' => (string) $request->query('syncable_only', ''), 'syncable_only' => (string) $request->query('syncable_only', ''),
// 只看“续费但未绑定订阅”的脏数据(可治理)
'renewal_missing_subscription' => (string) $request->query('renewal_missing_subscription', ''),
// 只看最近 24 小时批量同步过的订单(可治理追踪) // 只看最近 24 小时批量同步过的订单(可治理追踪)
'batch_synced_24h' => (string) $request->query('batch_synced_24h', ''), 'batch_synced_24h' => (string) $request->query('batch_synced_24h', ''),
// 只看最近 24 小时批量“标记支付并生效(BMPA)”过的订单(可治理追踪) // 只看最近 24 小时批量“标记支付并生效(BMPA)”过的订单(可治理追踪)
@@ -420,6 +422,10 @@ class PlatformOrderController extends Controller
->orWhereNotNull('site_subscription_id'); ->orWhereNotNull('site_subscription_id');
}) })
->count(), ->count(),
'renewal_missing_subscription_orders' => (clone $baseQuery)
->where('order_type', 'renewal')
->whereNull('site_subscription_id')
->count(),
'batch_synced_24h_orders' => (function () use ($baseQuery) { 'batch_synced_24h_orders' => (function () use ($baseQuery) {
$since = now()->subHours(24)->format('Y-m-d H:i:s'); $since = now()->subHours(24)->format('Y-m-d H:i:s');
@@ -2112,6 +2118,11 @@ class PlatformOrderController extends Controller
->orWhereNotNull('site_subscription_id'); ->orWhereNotNull('site_subscription_id');
}); });
}) })
->when(($filters['renewal_missing_subscription'] ?? '') !== '', function (Builder $builder) {
// 只看“续费但未绑定订阅”的脏数据(可治理)
$builder->where('order_type', 'renewal')
->whereNull('site_subscription_id');
})
->when(($filters['batch_synced_24h'] ?? '') !== '', function (Builder $builder) { ->when(($filters['batch_synced_24h'] ?? '') !== '', function (Builder $builder) {
// 只看最近 24 小时批量同步过的订单(基于 meta.batch_activation.at // 只看最近 24 小时批量同步过的订单(基于 meta.batch_activation.at
$since = now()->subHours(24)->format('Y-m-d H:i:s'); $since = now()->subHours(24)->format('Y-m-d H:i:s');

View File

@@ -419,6 +419,14 @@
</div> </div>
<div class="muted muted-xs">已支付 + 已生效 + 未同步(续费单需已绑定订阅)</div> <div class="muted muted-xs">已支付 + 已生效 + 未同步(续费单需已绑定订阅)</div>
</div> </div>
<div class="card">
<h3>续费缺订阅</h3>
<div class="metric-number">
<a class="link" href="{!! $safeFullUrlWithQuery(['renewal_missing_subscription' => '1', 'page' => null]) !!}">{{ $summaryStats['renewal_missing_subscription_orders'] ?? 0 }}</a>
</div>
<div class="muted muted-xs">renewal + site_subscription_id 为空(需治理)</div>
</div>
<div class="card"> <div class="card">
<h3>近24小时批量同步</h3> <h3>近24小时批量同步</h3>
<div class="metric-number"> <div class="metric-number">

View File

@@ -0,0 +1,31 @@
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AdminPlatformOrderRenewalMissingSubscriptionSummaryCardLinkTest 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_platform_orders_page_shows_renewal_missing_subscription_summary_card_link(): void
{
$this->loginAsPlatformAdmin();
$this->get('/admin/platform-orders')
->assertOk()
->assertSee('续费缺订阅')
->assertSee('renewal_missing_subscription=1');
}
}