From 502c397ec25163502fc14f6d67568dbfd9006e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=9D=E5=8D=9C?= Date: Mon, 16 Mar 2026 22:37:46 +0800 Subject: [PATCH] fix(governance-ui): align clear error tool guards with backend --- app/Support/PlatformOrderToolsGuard.php | 23 ++++++++- ...sShouldDisableWhenNotInFailedScopeTest.php | 50 +++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/app/Support/PlatformOrderToolsGuard.php b/app/Support/PlatformOrderToolsGuard.php index ed4cc71..db86863 100644 --- a/app/Support/PlatformOrderToolsGuard.php +++ b/app/Support/PlatformOrderToolsGuard.php @@ -120,10 +120,20 @@ class PlatformOrderToolsGuard */ public static function clearSyncErrorsReason(array $filters): string { + // 口径对齐后端安全阀:清理「同步失败」标记必须在失败治理集合内执行,且不得叠加与失败集合互斥的筛选。 if ((string) ($filters['sync_status'] ?? '') !== 'failed' && (string) ($filters['fail_only'] ?? '') === '') { return '建议先筛选「同步失败」集合(sync_status=failed)后再执行清理,避免误清理。'; } + if ((string) ($filters['syncable_only'] ?? '') === '1') { + return '当前已勾选「只看可同步」:该集合与「同步失败」互斥。请先取消只看可同步或切到失败集合后再清理。'; + } + + $syncStatus = (string) ($filters['sync_status'] ?? ''); + if ($syncStatus !== '' && $syncStatus !== 'failed') { + return '当前为「清理同步失败标记」动作:若需要筛选同步状态,请使用 sync_status=failed(或清空该筛选)后再执行。'; + } + return ''; } @@ -132,10 +142,19 @@ class PlatformOrderToolsGuard */ public static function clearBmpaErrorsReason(array $filters): string { + // 口径对齐后端安全阀:清理 BMPA 失败标记必须先锁定 BMPA 治理集合,且不得叠加与 BMPA 治理无关/互斥的筛选。 + if ((string) ($filters['syncable_only'] ?? '') === '1') { + return '当前已勾选「只看可同步」:该集合与「BMPA失败」治理集合无关。请先取消只看可同步或切到 BMPA 失败集合后再清理。'; + } + + if ((string) ($filters['fail_only'] ?? '') === '1' || trim((string) ($filters['sync_error_keyword'] ?? '')) !== '') { + return '当前筛选包含「同步失败/失败原因」:该集合用于订阅同步治理,请切到 BMPA 失败集合后再清理 BMPA 失败标记。'; + } + if ((string) ($filters['bmpa_failed_only'] ?? '') === '' - && (string) ($filters['bmpa_error_keyword'] ?? '') === '' + && trim((string) ($filters['bmpa_error_keyword'] ?? '')) === '' && (string) ($filters['batch_mark_paid_and_activate_24h'] ?? '') === '') { - return '建议先筛选「BMPA失败」集合(bmpa_failed_only=1 或失败原因关键词)后再执行清理,避免误清理。'; + return '建议先筛选「BMPA失败」集合(bmpa_failed_only=1 或失败原因关键词,或勾选 batch_mark_paid_and_activate_24h)后再执行清理,避免误清理。'; } return ''; diff --git a/tests/Feature/AdminPlatformOrderIndexClearErrorButtonsShouldDisableWhenNotInFailedScopeTest.php b/tests/Feature/AdminPlatformOrderIndexClearErrorButtonsShouldDisableWhenNotInFailedScopeTest.php index 4285bbf..dee6633 100644 --- a/tests/Feature/AdminPlatformOrderIndexClearErrorButtonsShouldDisableWhenNotInFailedScopeTest.php +++ b/tests/Feature/AdminPlatformOrderIndexClearErrorButtonsShouldDisableWhenNotInFailedScopeTest.php @@ -40,4 +40,54 @@ class AdminPlatformOrderIndexClearErrorButtonsShouldDisableWhenNotInFailedScopeT // 按钮 disabled(宽松断言) $this->assertTrue(str_contains($html, 'type="submit" disabled') || str_contains($html, 'disabled="disabled"')); } + + public function test_clear_sync_errors_button_should_disable_when_syncable_only_checked_even_if_in_failed_scope(): void + { + $this->loginAsPlatformAdmin(); + + $res = $this->get('/admin/platform-orders?sync_status=failed&syncable_only=1'); + $res->assertOk(); + + $html = (string) $res->getContent(); + + $this->assertStringContainsString('清除同步失败标记(当前筛选范围)', $html); + $this->assertStringContainsString('data-role="clear-sync-errors-blocked-hint"', $html); + $this->assertStringContainsString('只看可同步', $html); + + // 仍应禁用 + $this->assertTrue(str_contains($html, 'type="submit" disabled') || str_contains($html, 'disabled="disabled"')); + } + + public function test_clear_bmpa_errors_button_should_disable_when_syncable_only_checked_even_if_in_bmpa_failed_scope(): void + { + $this->loginAsPlatformAdmin(); + + $res = $this->get('/admin/platform-orders?bmpa_failed_only=1&syncable_only=1'); + $res->assertOk(); + + $html = (string) $res->getContent(); + + $this->assertStringContainsString('清除批量标记支付失败标记(当前筛选范围)', $html); + $this->assertStringContainsString('data-role="clear-bmpa-errors-blocked-hint"', $html); + $this->assertStringContainsString('只看可同步', $html); + + $this->assertTrue(str_contains($html, 'type="submit" disabled') || str_contains($html, 'disabled="disabled"')); + } + + public function test_clear_bmpa_errors_button_should_disable_when_sync_failed_filters_present(): void + { + $this->loginAsPlatformAdmin(); + + // 即使 bmpa_failed_only=1,但叠加了 sync_error_keyword/fail_only,也应禁用(避免误清理)。 + $res = $this->get('/admin/platform-orders?bmpa_failed_only=1&fail_only=1&sync_error_keyword=timeout'); + $res->assertOk(); + + $html = (string) $res->getContent(); + + $this->assertStringContainsString('清除批量标记支付失败标记(当前筛选范围)', $html); + $this->assertStringContainsString('data-role="clear-bmpa-errors-blocked-hint"', $html); + $this->assertStringContainsString('同步失败', $html); + + $this->assertTrue(str_contains($html, 'type="submit" disabled') || str_contains($html, 'disabled="disabled"')); + } }