From e57553c4476075e5976c7bc08af9d53811668523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=9D=E5=8D=9C?= Date: Wed, 11 Mar 2026 08:22:58 +0000 Subject: [PATCH] =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=90=8C=E6=AD=A5=E8=AE=A2?= =?UTF-8?q?=E9=98=85=EF=BC=9A=E6=B2=BB=E7=90=86=E7=AD=9B=E9=80=89=E4=B8=8B?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AE=89=E5=85=A8=E9=98=80=E9=98=BB=E6=96=AD?= =?UTF-8?q?=E5=B8=A6=E7=97=85=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Admin/PlatformOrderController.php | 7 ++ ...SubscriptionsGovernanceSafetyValveTest.php | 79 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 tests/Feature/AdminPlatformOrderBatchActivateSubscriptionsGovernanceSafetyValveTest.php diff --git a/app/Http/Controllers/Admin/PlatformOrderController.php b/app/Http/Controllers/Admin/PlatformOrderController.php index 8c0d3fc..ecafb2d 100644 --- a/app/Http/Controllers/Admin/PlatformOrderController.php +++ b/app/Http/Controllers/Admin/PlatformOrderController.php @@ -944,6 +944,13 @@ class PlatformOrderController extends Controller return redirect()->back()->with('warning', '为避免误操作,请先在筛选条件中勾选「只看可同步」,再执行批量同步订阅。'); } + // 防误操作(治理优先):当筛选集合同时命中“对账不一致/退款不一致”时,不允许直接批量同步,避免把“带病订单”同步到订阅 + if ($scope === 'filtered' + && ($filters['syncable_only'] ?? '') === '1' + && ((string) ($filters['reconcile_mismatch'] ?? '') === '1' || (string) ($filters['refund_inconsistent'] ?? '') === '1')) { + return redirect()->back()->with('warning', '当前筛选集合包含「对账不一致/退款不一致」订单,为避免带病同步,请先完成金额/状态治理(补回执/核对退款)后再批量同步订阅。'); + } + // 防误操作:scope=all 需要二次确认 if ($scope === 'all' && (string) $request->input('confirm', '') !== 'YES') { return redirect()->back()->with('warning', '为避免误操作,执行全量批量同步前请在确认框输入 YES。'); diff --git a/tests/Feature/AdminPlatformOrderBatchActivateSubscriptionsGovernanceSafetyValveTest.php b/tests/Feature/AdminPlatformOrderBatchActivateSubscriptionsGovernanceSafetyValveTest.php new file mode 100644 index 0000000..c63ad48 --- /dev/null +++ b/tests/Feature/AdminPlatformOrderBatchActivateSubscriptionsGovernanceSafetyValveTest.php @@ -0,0 +1,79 @@ +seed(); + + $this->post('/admin/login', [ + 'email' => 'platform.admin@demo.local', + 'password' => 'Platform@123456', + ])->assertRedirect('/admin'); + } + + public function test_batch_activate_subscriptions_blocked_when_syncable_only_and_reconcile_mismatch_present(): void + { + $this->loginAsPlatformAdmin(); + + $merchant = Merchant::query()->firstOrFail(); + $plan = Plan::query()->create([ + 'code' => 'batch_activate_gov_safety_valve_test', + 'name' => '批量同步治理安全阀测试套餐', + '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_BATCH_GOV_BLOCK_0001', + 'order_type' => 'new_purchase', + 'status' => 'activated', + 'payment_status' => 'paid', + 'plan_name' => $plan->name, + 'billing_cycle' => $plan->billing_cycle, + 'period_months' => 1, + 'quantity' => 1, + 'payable_amount' => 10, + 'paid_amount' => 10, + 'placed_at' => now(), + 'paid_at' => now(), + 'activated_at' => now(), + // 对账不一致:receipt_total 9.98 vs paid_amount 10 + 'meta' => [ + 'payment_summary' => [ + 'count' => 1, + 'total_amount' => 9.98, + ], + ], + ]); + + $res = $this->post('/admin/platform-orders/batch-activate-subscriptions', [ + 'scope' => 'filtered', + 'syncable_only' => '1', + 'reconcile_mismatch' => '1', + 'limit' => 50, + ]); + + $res->assertRedirect(); + $res->assertSessionHas('warning'); + + $order->refresh(); + $this->assertEmpty(data_get($order->meta, 'subscription_activation')); + } +}