diff --git a/resources/views/admin/site_subscriptions/index.blade.php b/resources/views/admin/site_subscriptions/index.blade.php index 681bc06..ed63023 100644 --- a/resources/views/admin/site_subscriptions/index.blade.php +++ b/resources/views/admin/site_subscriptions/index.blade.php @@ -14,6 +14,25 @@ $selfWithoutBack .= '?' . \Illuminate\Support\Arr::query($currentQuery); } $back = $selfWithoutBack; + + // 用于构建“保留当前筛选上下文”的站内跳转链接(且不透传 back,避免嵌套/污染) + $buildSelfUrl = function (array $overrides = []) use ($currentQuery) { + $q = $currentQuery; + foreach ($overrides as $k => $v) { + if ($v === null) { + unset($q[$k]); + } else { + $q[$k] = $v; + } + } + + $url = '/' . ltrim(request()->path(), '/'); + if (count($q) > 0) { + $url .= '?' . \Illuminate\Support\Arr::query($q); + } + + return $url; + }; @endphp

这里是总台视角的订阅目录页,承接“套餐 -> 订阅 -> 平台订单”的收费主链中间层。

@@ -139,14 +158,14 @@ @if($subscription->merchant) - {{ $subscription->merchant->name }} + {{ $subscription->merchant->name }} @else 未关联站点 @endif @if($subscription->plan) - {{ $subscription->plan_name ?: $subscription->plan->name }} + {{ $subscription->plan_name ?: $subscription->plan->name }} @else {{ $subscription->plan_name ?: '未设置' }} @endif diff --git a/tests/Feature/AdminSiteSubscriptionIndexFilterLinksDoNotCarryBackOrPageTest.php b/tests/Feature/AdminSiteSubscriptionIndexFilterLinksDoNotCarryBackOrPageTest.php new file mode 100644 index 0000000..e3e1093 --- /dev/null +++ b/tests/Feature/AdminSiteSubscriptionIndexFilterLinksDoNotCarryBackOrPageTest.php @@ -0,0 +1,119 @@ +seed(); + + $this->post('/admin/login', [ + 'email' => 'platform.admin@demo.local', + 'password' => 'Platform@123456', + ])->assertRedirect('/admin'); + } + + public function test_merchant_and_plan_filter_links_should_not_carry_back_or_page(): void + { + $this->loginAsPlatformAdmin(); + + $merchant = Merchant::query()->firstOrFail(); + + $plan = Plan::query()->create([ + 'code' => 'sub_index_filter_links_no_back_page_plan', + 'name' => '订阅列表筛选链接不带 back/page 测试套餐', + 'billing_cycle' => 'monthly', + 'price' => 10, + 'list_price' => 10, + 'status' => 'active', + 'sort' => 10, + 'published_at' => now(), + ]); + + // 需要让 page=2 上仍有数据行(否则页面会显示“暂无订阅数据”,无法断言站点/套餐筛选链接) + // 列表按 id 倒序分页:page=1 是最新 10 条,page=2 是更早的记录。 + // 因此这里先创建“目标订阅”(让它落到 page=2),再补 10 条占满 page=1。 + $targetSub = SiteSubscription::query()->create([ + 'merchant_id' => $merchant->id, + 'plan_id' => $plan->id, + 'status' => 'activated', + 'source' => 'manual', + 'subscription_no' => 'SUB_INDEX_FILTER_LINKS_NO_BACK_PAGE_TARGET', + 'plan_name' => $plan->name, + 'billing_cycle' => $plan->billing_cycle, + 'period_months' => 1, + 'amount' => 10, + 'starts_at' => now()->subDay(), + 'ends_at' => now()->addMonth(), + 'activated_at' => now()->subDay(), + ]); + + for ($i = 1; $i <= 10; $i++) { + SiteSubscription::query()->create([ + 'merchant_id' => $merchant->id, + 'plan_id' => $plan->id, + 'status' => 'activated', + 'source' => 'manual', + 'subscription_no' => 'SUB_INDEX_FILTER_LINKS_NO_BACK_PAGE_FILL_' . str_pad((string) $i, 4, '0', STR_PAD_LEFT), + 'plan_name' => $plan->name, + 'billing_cycle' => $plan->billing_cycle, + 'period_months' => 1, + 'amount' => 10, + 'starts_at' => now()->subDay(), + 'ends_at' => now()->addMonth(), + 'activated_at' => now()->subDay(), + ]); + } + + $res = $this->get('/admin/site-subscriptions?status=activated&page=2&back=' . urlencode('/admin/platform-orders?status=pending')); + $res->assertOk(); + + $content = (string) $res->getContent(); + + preg_match_all('/href=["\']([^"\']+)["\']/', $content, $m); + $hrefs = $m[1] ?? []; + + // 若断言失败,方便快速排障(仅在测试失败时才会在输出中看到) + $this->assertTrue(count($hrefs) > 0, '页面中应存在 href'); + + $pickHref = function (callable $predicate) use ($hrefs): ?string { + foreach ($hrefs as $href) { + if ($predicate($href)) { + return $href; + } + } + return null; + }; + + $merchantHref = $pickHref(function (string $href) use ($merchant) { + return str_starts_with($href, '/admin/site-subscriptions?') + && str_contains($href, 'merchant_id=' . $merchant->id); + }); + + $planHref = $pickHref(function (string $href) use ($plan) { + return str_starts_with($href, '/admin/site-subscriptions?') + && str_contains($href, 'plan_id=' . $plan->id); + }); + + $this->assertNotNull($merchantHref, '站点筛选链接应存在'); + $this->assertNotNull($planHref, '套餐筛选链接应存在'); + + // 要求:保留 status,但不携带 back/page(避免筛选跳转污染与空页) + $this->assertStringContainsString('status=activated', $merchantHref); + $this->assertStringNotContainsString('back=', $merchantHref); + $this->assertStringNotContainsString('page=2', $merchantHref); + + $this->assertStringContainsString('status=activated', $planHref); + $this->assertStringNotContainsString('back=', $planHref); + $this->assertStringNotContainsString('page=2', $planHref); + } +}