From b4f1e194f6b7cbc901f4ccb7fd4957e590305bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=9D=E5=8D=9C?= Date: Wed, 11 Mar 2026 06:41:36 +0000 Subject: [PATCH] refactor: centralize receipt total logic on PlatformOrder --- .../Admin/PlatformOrderController.php | 16 +---- .../Admin/SiteSubscriptionController.php | 8 +-- app/Models/PlatformOrder.php | 18 ++++++ tests/Unit/PlatformOrderReceiptTotalTest.php | 58 +++++++++++++++++++ 4 files changed, 79 insertions(+), 21 deletions(-) create mode 100644 tests/Unit/PlatformOrderReceiptTotalTest.php diff --git a/app/Http/Controllers/Admin/PlatformOrderController.php b/app/Http/Controllers/Admin/PlatformOrderController.php index ebaeb71..879f57d 100644 --- a/app/Http/Controllers/Admin/PlatformOrderController.php +++ b/app/Http/Controllers/Admin/PlatformOrderController.php @@ -1470,20 +1470,8 @@ class PlatformOrderController extends Controller private function receiptTotalForOrder(PlatformOrder $order): float { - // 优先读扁平字段 payment_summary.total_amount(更稳定、避免遍历 receipts) - $total = (float) (data_get($order->meta, 'payment_summary.total_amount') ?? 0); - if ($total > 0) { - return $total; - } - - // 回退:遍历 payment_receipts[].amount - $receipts = (array) (data_get($order->meta, 'payment_receipts', []) ?? []); - $sum = 0.0; - foreach ($receipts as $r) { - $sum += (float) (data_get($r, 'amount') ?? 0); - } - - return $sum; + // 口径统一:集中到模型方法,避免多处复制导致漂移 + return (float) $order->receiptTotal(); } private function refundTotalForOrder(PlatformOrder $order): float diff --git a/app/Http/Controllers/Admin/SiteSubscriptionController.php b/app/Http/Controllers/Admin/SiteSubscriptionController.php index 80c405e..8028459 100644 --- a/app/Http/Controllers/Admin/SiteSubscriptionController.php +++ b/app/Http/Controllers/Admin/SiteSubscriptionController.php @@ -62,13 +62,7 @@ class SiteSubscriptionController extends Controller 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); - } - } + $receiptTotal = (float) $o->receiptTotal(); if ($receiptTotal > 0) { $receiptOrders++; diff --git a/app/Models/PlatformOrder.php b/app/Models/PlatformOrder.php index d199b45..e0a5cbe 100644 --- a/app/Models/PlatformOrder.php +++ b/app/Models/PlatformOrder.php @@ -10,6 +10,24 @@ class PlatformOrder extends Model { use HasFactory; + public function receiptTotal(): float + { + // 优先读扁平字段 payment_summary.total_amount(更稳定、避免遍历 receipts) + $total = (float) (data_get($this->meta, 'payment_summary.total_amount') ?? 0); + if ($total > 0) { + return $total; + } + + // 回退:遍历 payment_receipts[].amount + $receipts = (array) (data_get($this->meta, 'payment_receipts', []) ?? []); + $sum = 0.0; + foreach ($receipts as $r) { + $sum += (float) (data_get($r, 'amount') ?? 0); + } + + return $sum; + } + public function refundTotal(): float { // 优先读扁平字段 refund_summary.total_amount diff --git a/tests/Unit/PlatformOrderReceiptTotalTest.php b/tests/Unit/PlatformOrderReceiptTotalTest.php new file mode 100644 index 0000000..5ea4942 --- /dev/null +++ b/tests/Unit/PlatformOrderReceiptTotalTest.php @@ -0,0 +1,58 @@ +create([ + 'name' => '单测站点_receipt', + 'slug' => 'unit-test-merchant-receipt', + 'status' => 'active', + ]); + + $plan = Plan::query()->create([ + 'code' => 'unit_test_plan_receipt_total', + 'name' => '单测套餐_receipt', + 'billing_cycle' => 'monthly', + 'price' => 10, + 'list_price' => 10, + 'status' => 'active', + 'sort' => 10, + 'published_at' => now(), + ]); + + $order = PlatformOrder::query()->create([ + 'merchant_id' => $merchant->id, + 'plan_id' => $plan->id, + 'order_no' => 'PO_UNIT_RECEIPT_TOTAL_0001', + 'order_type' => 'subscription', + 'status' => 'activated', + 'payment_status' => 'paid', + 'plan_name' => 'Unit Test Plan', + 'billing_cycle' => 'monthly', + 'period_months' => 1, + 'quantity' => 1, + 'payable_amount' => 10, + 'paid_amount' => 10, + 'placed_at' => now(), + 'meta' => [ + 'payment_receipts' => [ + ['amount' => 3.25], + ['amount' => 1.15], + ], + ], + ]); + + $this->assertEquals(4.40, $order->receiptTotal()); + } +}