admin: 列表行级仅标记生效对齐治理安全阀(续费缺订阅禁用并引导)

This commit is contained in:
萝卜
2026-03-18 00:10:40 +08:00
parent ba7f43fef8
commit decd653ad8
2 changed files with 87 additions and 2 deletions

View File

@@ -1831,11 +1831,21 @@
@php
$canMarkActivatedOnly = ($order->payment_status === 'paid') && ($order->status !== 'activated');
// 安全阀对齐后端:续费单未绑定订阅时,不允许“仅标记为已生效”(后端 markActivated 也会阻断)
$markActivatedBlockedByMissingSubscriptionOnRenewalRow = ((string) ($order->order_type ?? '') === 'renewal')
&& ((int) ($order->site_subscription_id ?? 0) <= 0);
@endphp
<form method="post" action="/admin/platform-orders/{{ $order->id }}/mark-activated" data-action="disable-on-submit" onsubmit="return confirm('确认将该订单标记为已生效?(不修改支付状态,不自动同步订阅)');" class="mb-6">
@csrf
<button class="btn btn-secondary btn-sm" type="submit" @disabled(! $canMarkActivatedOnly)>仅标记为已生效</button>
<button class="btn btn-secondary btn-sm" type="submit" @disabled(! $canMarkActivatedOnly || $markActivatedBlockedByMissingSubscriptionOnRenewalRow)>仅标记为已生效</button>
</form>
@if($markActivatedBlockedByMissingSubscriptionOnRenewalRow)
<div class="muted text-danger mt-6">
续费缺订阅不可直接标记生效
<span class="muted"></span>
<a class="link" href="{!! $relationFixUrlCompactForBmpa !!}">去关联订阅</a>
</div>
@endif
@php
$syncBlockedByGovernanceRow = (bool) ($order->isReconcileMismatch() || $order->isRefundInconsistent());
@@ -1861,7 +1871,7 @@
需先完成治理后再同步
@if($syncBlockedByMissingSubscriptionOnRenewalRow)
<span class="muted"></span>
<a class="link" href="{!! $relationFixUrlCompact !!}">去关联订阅</a>
<a class="link" href="{!! $relationFixUrlCompactForBmpa !!}">去关联订阅</a>
@endif
</div>
@endif

View File

@@ -0,0 +1,75 @@
<?php
namespace Tests\Feature;
use App\Models\Merchant;
use App\Models\Plan;
use App\Models\PlatformOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AdminPlatformOrderIndexRowMarkActivatedButtonShouldDisableWhenRenewalMissingSubscriptionTest extends TestCase
{
use RefreshDatabase;
protected function loginAsPlatformAdmin(): void
{
$this->seed();
$this->post('/admin/login', [
'email' => 'platform.admin@demo.local',
'password' => 'Platform@123456',
])->assertRedirect('/admin');
}
public function test_row_mark_activated_button_should_be_disabled_when_renewal_missing_subscription(): void
{
$this->loginAsPlatformAdmin();
$merchant = Merchant::query()->firstOrFail();
$plan = Plan::query()->create([
'code' => 'po_index_row_mark_activated_disable_renewal_missing_sub_plan',
'name' => '平台订单列表行级仅标记生效禁用(续费缺订阅)测试套餐',
'billing_cycle' => 'monthly',
'price' => 30,
'list_price' => 30,
'status' => 'active',
'sort' => 10,
'published_at' => now(),
]);
// 构造:已支付 + 待处理,但续费缺订阅;该场景后端 markActivated 会阻断,列表页也应禁用。
$order = PlatformOrder::query()->create([
'merchant_id' => $merchant->id,
'plan_id' => $plan->id,
'order_no' => 'PO_INDEX_ROW_MARK_ACTIVATED_DISABLE_RENEW_MISS_SUB_0001',
'order_type' => 'renewal',
'site_subscription_id' => null,
'status' => 'pending',
'payment_status' => 'paid',
'plan_name' => $plan->name,
'billing_cycle' => $plan->billing_cycle,
'period_months' => 1,
'quantity' => 1,
'payable_amount' => 30,
'paid_amount' => 30,
'placed_at' => now(),
'paid_at' => now(),
'meta' => [],
]);
$res = $this->get('/admin/platform-orders');
$res->assertOk();
$html = (string) $res->getContent();
$this->assertStringContainsString($order->order_no, $html);
// 断言:该订单所在行的“仅标记为已生效”按钮应被禁用
$pattern = '#/admin/platform-orders/' . $order->id . '/mark-activated.*?<button[^>]*disabled#s';
$this->assertMatchesRegularExpression($pattern, $html);
// 并且应给出最短治理入口(去关联订阅)
$this->assertStringContainsString('去关联订阅', $html);
$this->assertStringContainsString('#relation-subscription', $html);
}
}