diff --git a/app/Http/Controllers/Admin/SiteSubscriptionController.php b/app/Http/Controllers/Admin/SiteSubscriptionController.php index a373993..7e2aeea 100644 --- a/app/Http/Controllers/Admin/SiteSubscriptionController.php +++ b/app/Http/Controllers/Admin/SiteSubscriptionController.php @@ -45,6 +45,62 @@ class SiteSubscriptionController extends Controller ->count(), ]; + // 可治理摘要:订阅维度的回执/退款汇总(口径与平台订单列表一致:优先 summary,缺省回退 receipts) + $metaOrders = (clone $baseOrdersQuery)->get(['id', 'paid_amount', 'meta']); + + $totalReceiptAmount = 0.0; + $receiptOrders = 0; + $noReceiptOrders = 0; + + $totalRefundedAmount = 0.0; + $refundOrders = 0; + $noRefundOrders = 0; + + foreach ($metaOrders as $o) { + $meta = $o->meta ?? []; + + $receiptTotal = (float) (data_get($meta, 'payment_summary.total_amount') ?? 0); + if ($receiptTotal <= 0) { + $receipts = (array) (data_get($meta, 'payment_receipts', []) ?? []); + foreach ($receipts as $r) { + $receiptTotal += (float) (data_get($r, 'amount') ?? 0); + } + } + + if ($receiptTotal > 0) { + $receiptOrders++; + $totalReceiptAmount += $receiptTotal; + } else { + $noReceiptOrders++; + } + + $refundTotal = (float) (data_get($meta, 'refund_summary.total_amount') ?? 0); + if ($refundTotal <= 0) { + $refunds = (array) (data_get($meta, 'refund_receipts', []) ?? []); + foreach ($refunds as $r) { + $refundTotal += (float) (data_get($r, 'amount') ?? 0); + } + } + + if ($refundTotal > 0) { + $refundOrders++; + $totalRefundedAmount += $refundTotal; + } else { + $noRefundOrders++; + } + } + + $summaryStats = $summaryStats + [ + 'receipt_orders' => $receiptOrders, + 'no_receipt_orders' => $noReceiptOrders, + 'total_receipt_amount' => (float) $totalReceiptAmount, + 'refund_orders' => $refundOrders, + 'no_refund_orders' => $noRefundOrders, + 'total_refunded_amount' => (float) $totalRefundedAmount, + // 对账差额:回执总额 - 已付总额(订阅维度) + 'reconciliation_delta' => (float) ($totalReceiptAmount - (float) $metaOrders->sum('paid_amount')), + ]; + // 同步失败原因聚合(Top3):订阅维度快速判断“常见失败原因” $failedReasonRows = (clone $baseOrdersQuery) ->whereRaw("JSON_EXTRACT(meta, '$.subscription_activation_error.message') IS NOT NULL") diff --git a/resources/views/admin/site_subscriptions/show.blade.php b/resources/views/admin/site_subscriptions/show.blade.php index 298aea2..eb82cbf 100644 --- a/resources/views/admin/site_subscriptions/show.blade.php +++ b/resources/views/admin/site_subscriptions/show.blade.php @@ -131,6 +131,35 @@
无 activation 且无 error
+
+

有回执订单 / 回执总额

+
+ {{ $summaryStats['receipt_orders'] ?? 0 }} + / ¥{{ number_format((float) ($summaryStats['total_receipt_amount'] ?? 0), 2) }} +
+
口径:payment_summary.total_amount 存在或 payment_receipts 有记录
+
+ +
+

有退款订单 / 退款总额

+
+ {{ $summaryStats['refund_orders'] ?? 0 }} + / ¥{{ number_format((float) ($summaryStats['total_refunded_amount'] ?? 0), 2) }} +
+
口径:refund_summary.total_amount 存在或 refund_receipts 有记录
+
+ +
+

对账差额(回执-已付)

+ @php $delta = (float) ($summaryStats['reconciliation_delta'] ?? 0); @endphp +
¥{{ number_format($delta, 2) }}
+ @if(abs($delta) >= 0.01) +
提示:差额非 0,可能存在回执金额与订单已付金额不一致。
+ @else +
差额为 0(当前订阅维度)
+ @endif +
+

失败原因Top3

@php $failedReasonStats = $failedReasonStats ?? []; @endphp diff --git a/tests/Feature/AdminSiteSubscriptionShowTest.php b/tests/Feature/AdminSiteSubscriptionShowTest.php index d9f8446..89d3166 100644 --- a/tests/Feature/AdminSiteSubscriptionShowTest.php +++ b/tests/Feature/AdminSiteSubscriptionShowTest.php @@ -80,6 +80,21 @@ class AdminSiteSubscriptionShowTest extends TestCase 'synced_at' => now()->subDay()->toDateTimeString(), 'admin_id' => 1, ], + // 订阅维度治理摘要:回执/退款汇总口径应可识别 summary + 'payment_summary' => [ + 'count' => 1, + 'total_amount' => 88, + 'last_at' => now()->subDay()->toDateTimeString(), + 'last_amount' => 88, + 'last_channel' => 'bank_transfer', + ], + 'refund_summary' => [ + 'count' => 1, + 'total_amount' => 10, + 'last_at' => now()->subHours(12)->toDateTimeString(), + 'last_amount' => 10, + 'last_channel' => 'bank_transfer', + ], ], ]); @@ -91,6 +106,9 @@ class AdminSiteSubscriptionShowTest extends TestCase ->assertSee('可同步(已支付+已生效+未同步)') ->assertSee('未同步(无记录)') ->assertSee('失败原因Top3') + ->assertSee('有回执订单 / 回执总额') + ->assertSee('有退款订单 / 退款总额') + ->assertSee('对账差额(回执-已付)') ->assertSee('关联平台订单') ->assertSee('PO_SUB_SHOW_0001') ->assertSee('同步时间')