From a4c36ab8687588d85f0326f03db86926f8ea4648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=9D=E5=8D=9C?= Date: Sun, 15 Mar 2026 05:44:09 +0000 Subject: [PATCH] platform orders: batch activate guard renewal missing subscription --- .../Controllers/Admin/PlatformOrderController.php | 14 +++++++++++++- ...PlatformOrderBatchActivateSubscriptionsTest.php | 10 +++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Admin/PlatformOrderController.php b/app/Http/Controllers/Admin/PlatformOrderController.php index 91837c0..df2f837 100644 --- a/app/Http/Controllers/Admin/PlatformOrderController.php +++ b/app/Http/Controllers/Admin/PlatformOrderController.php @@ -1382,10 +1382,22 @@ class PlatformOrderController extends Controller foreach ($orders as $orderRow) { try { + $order = PlatformOrder::query()->find($orderRow->id); + if (! $order) { + continue; + } + + // 治理优先:续费单必须绑定订阅(兼容历史脏数据/手工改库等场景) + if ((string) ($order->order_type ?? '') === 'renewal' && ! (int) ($order->site_subscription_id ?? 0)) { + throw new \InvalidArgumentException('续费单未绑定订阅(site_subscription_id 为空),不允许批量同步订阅。'); + } + $subscription = $service->activateOrder($orderRow->id, $admin->id); + // 注意:activateOrder 过程中会写入 order 的 meta/site_subscription_id 等;此处必须 refresh,避免后续写审计时覆盖掉同步结果 + $order->refresh(); + // 轻量审计:记录批量同步动作(方便追溯) - $order = PlatformOrder::query()->find($orderRow->id); if ($order) { $meta = (array) ($order->meta ?? []); $audit = (array) (data_get($meta, 'audit', []) ?? []); diff --git a/tests/Feature/AdminPlatformOrderBatchActivateSubscriptionsTest.php b/tests/Feature/AdminPlatformOrderBatchActivateSubscriptionsTest.php index 47ccc67..102e2ce 100644 --- a/tests/Feature/AdminPlatformOrderBatchActivateSubscriptionsTest.php +++ b/tests/Feature/AdminPlatformOrderBatchActivateSubscriptionsTest.php @@ -110,7 +110,7 @@ class AdminPlatformOrderBatchActivateSubscriptionsTest extends TestCase 'merchant_id' => $merchant->id, 'plan_id' => $plan->id, 'order_no' => 'PO_BATCH_FAIL_0001', - 'order_type' => 'renewal', + 'order_type' => 'new_purchase', 'status' => 'activated', 'payment_status' => 'paid', 'plan_name' => $plan->name, @@ -130,7 +130,7 @@ class AdminPlatformOrderBatchActivateSubscriptionsTest extends TestCase 'merchant_id' => $merchant->id, 'plan_id' => $plan->id, 'order_no' => 'PO_BATCH_FAIL_0002', - 'order_type' => 'renewal', + 'order_type' => 'new_purchase', 'status' => 'activated', 'payment_status' => 'paid', 'plan_name' => $plan->name, @@ -203,7 +203,7 @@ class AdminPlatformOrderBatchActivateSubscriptionsTest extends TestCase 'merchant_id' => $merchant->id, 'plan_id' => $plan->id, 'order_no' => 'PO_BATCH_LIMIT_0001', - 'order_type' => 'renewal', + 'order_type' => 'new_purchase', 'status' => 'activated', 'payment_status' => 'paid', 'plan_name' => $plan->name, @@ -221,7 +221,7 @@ class AdminPlatformOrderBatchActivateSubscriptionsTest extends TestCase 'merchant_id' => $merchant->id, 'plan_id' => $plan->id, 'order_no' => 'PO_BATCH_LIMIT_0002', - 'order_type' => 'renewal', + 'order_type' => 'new_purchase', 'status' => 'activated', 'payment_status' => 'paid', 'plan_name' => $plan->name, @@ -239,7 +239,7 @@ class AdminPlatformOrderBatchActivateSubscriptionsTest extends TestCase 'merchant_id' => $merchant->id, 'plan_id' => $plan->id, 'order_no' => 'PO_BATCH_LIMIT_0003', - 'order_type' => 'renewal', + 'order_type' => 'new_purchase', 'status' => 'activated', 'payment_status' => 'paid', 'plan_name' => $plan->name,