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 @@