From 6aa58d5369c1d0b78274df8a28c42c2bd5ef012d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=9D=E5=8D=9C?= Date: Mon, 16 Mar 2026 21:51:29 +0800 Subject: [PATCH] chore(seed): add demo merchants for dashboard rank; tighten batch mark activated UI guard --- app/Support/PlatformOrderToolsGuard.php | 11 +++ ...onShouldDisableWhenConflictFiltersTest.php | 68 +++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 tests/Feature/AdminPlatformOrderIndexBatchMarkActivatedButtonShouldDisableWhenConflictFiltersTest.php diff --git a/app/Support/PlatformOrderToolsGuard.php b/app/Support/PlatformOrderToolsGuard.php index 66fc1dd..ed4cc71 100644 --- a/app/Support/PlatformOrderToolsGuard.php +++ b/app/Support/PlatformOrderToolsGuard.php @@ -101,6 +101,17 @@ class PlatformOrderToolsGuard return '为避免把同步失败等异常单混入,请先锁定「同步状态=未同步(sync_status=unsynced)」(建议用快捷筛选「待生效」)再执行批量生效。'; } + // 互斥筛选阻断:避免运营在其它治理集合上误触“批量生效”导致误解。 + if ((string) ($filters['fail_only'] ?? '') === '1' || trim((string) ($filters['sync_error_keyword'] ?? '')) !== '') { + return '当前筛选包含「同步失败/失败原因」治理集合:与“待生效(unsynced)”互斥。请先切回待生效集合后再执行批量生效。'; + } + if ((string) ($filters['synced_only'] ?? '') === '1') { + return '当前已勾选「只看已同步」:该集合与“待生效(unsynced)”互斥。请先取消该筛选后再执行批量生效。'; + } + if ((string) ($filters['syncable_only'] ?? '') === '1') { + return '当前已勾选「只看可同步」:该集合语义为“已生效(activated)+未同步”,与本动作处理的“待处理(pending)”互斥。请先取消只看可同步后再执行。'; + } + return ''; } diff --git a/tests/Feature/AdminPlatformOrderIndexBatchMarkActivatedButtonShouldDisableWhenConflictFiltersTest.php b/tests/Feature/AdminPlatformOrderIndexBatchMarkActivatedButtonShouldDisableWhenConflictFiltersTest.php new file mode 100644 index 0000000..959a3d4 --- /dev/null +++ b/tests/Feature/AdminPlatformOrderIndexBatchMarkActivatedButtonShouldDisableWhenConflictFiltersTest.php @@ -0,0 +1,68 @@ +seed(); + + $this->post('/admin/login', [ + 'email' => 'platform.admin@demo.local', + 'password' => 'Platform@123456', + ])->assertRedirect('/admin'); + } + + public function test_batch_mark_activated_button_should_disable_when_conflict_filters_present(): void + { + $this->loginAsPlatformAdmin(); + + $merchant = Merchant::query()->firstOrFail(); + $plan = Plan::query()->create([ + 'code' => 'po_index_batch_mark_activated_btn_disable_conflict_plan', + 'name' => '批量生效按钮冲突筛选禁用测试套餐', + 'billing_cycle' => 'monthly', + 'price' => 10, + 'list_price' => 10, + 'status' => 'active', + 'sort' => 10, + 'published_at' => now(), + ]); + + PlatformOrder::query()->create([ + 'merchant_id' => $merchant->id, + 'plan_id' => $plan->id, + 'order_no' => 'PO_IDX_BATCH_ACT_BTN_DISABLE_CONFLICT_0001', + 'order_type' => 'new_purchase', + 'status' => 'pending', + '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(), + 'meta' => [], + ]); + + // 与“待生效(unsynced)”互斥:fail_only=1 + $res = $this->get('/admin/platform-orders?payment_status=paid&status=pending&sync_status=unsynced&fail_only=1'); + $res->assertOk(); + $html = (string) $res->getContent(); + + $this->assertStringContainsString('批量仅标记为已生效(当前筛选范围)', $html); + $this->assertStringContainsString('data-role="batch-mark-activated-blocked-hint"', $html); + $this->assertStringContainsString('同步失败', $html); + $this->assertTrue(str_contains($html, 'type="submit" disabled') || str_contains($html, 'disabled="disabled"')); + } +}