diff --git a/app/Support/BackUrl.php b/app/Support/BackUrl.php
index c58fb50..f3219a6 100644
--- a/app/Support/BackUrl.php
+++ b/app/Support/BackUrl.php
@@ -74,6 +74,19 @@ class BackUrl
* 用途:列表页“全部/返回来源”等需要清空筛选但保留 back 的场景。
*/
public static function withBack(string $path, string $safeBackForLinks = ''): string
+ {
+ return self::appendBack($path, $safeBackForLinks, false);
+ }
+
+ /**
+ * withBack 的变体:将 back 放到 query 的最前面(用于少数对 query 顺序有严格断言的页面/测试)。
+ */
+ public static function withBackFirst(string $path, string $safeBackForLinks = ''): string
+ {
+ return self::appendBack($path, $safeBackForLinks, true);
+ }
+
+ private static function appendBack(string $path, string $safeBackForLinks = '', bool $preferFirst = false): string
{
$path = (string) $path;
@@ -86,10 +99,26 @@ class BackUrl
return $path;
}
- // 若 path 已带 query,则追加 &back=;否则追加 ?back=
- $sep = str_contains($path, '?') ? '&' : '?';
+ $backQuery = \Illuminate\Support\Arr::query(['back' => $safeBackForLinks]);
- return $path . $sep . \Illuminate\Support\Arr::query(['back' => $safeBackForLinks]);
+ if (!str_contains($path, '?')) {
+ return $path . '?' . $backQuery;
+ }
+
+ [$base, $qs] = explode('?', $path, 2);
+ $qs = trim((string) $qs);
+ $qs = trim($qs, "& ");
+
+ // 处理类似 "/xx?" 或 "/xx?&" 的情况:视为无 query
+ if ($qs === '') {
+ return $base . '?' . $backQuery;
+ }
+
+ if ($preferFirst) {
+ return $base . '?' . $backQuery . '&' . $qs;
+ }
+
+ return $base . '?' . $qs . '&' . $backQuery;
}
/**
@@ -114,6 +143,25 @@ class BackUrl
return $url . '#' . $fragment;
}
+ /**
+ * withBackFirst + fragment 的组合:用于少数对 query 顺序有严格断言的页面/测试。
+ */
+ public static function withBackFirstAndFragment(string $path, string $safeBackForLinks = '', string $fragment = ''): string
+ {
+ $url = self::withBackFirst($path, $safeBackForLinks);
+
+ $fragment = ltrim((string) $fragment, '#');
+ if ($fragment === '') {
+ return $url;
+ }
+
+ if (!preg_match('/^[A-Za-z0-9_-]+$/', $fragment)) {
+ return $url;
+ }
+
+ return $url . '#' . $fragment;
+ }
+
/**
* 当前路径下的“快捷筛选”链接构造器:
* - 仅保留指定上下文键(例如 merchant_id/plan_id/keyword/lead_id 等)
diff --git a/resources/views/admin/platform_orders/show.blade.php b/resources/views/admin/platform_orders/show.blade.php
index dae9109..9fab62f 100644
--- a/resources/views/admin/platform_orders/show.blade.php
+++ b/resources/views/admin/platform_orders/show.blade.php
@@ -327,7 +327,7 @@
打开订阅详情
|
@php
- $openSubSyncableUrl = \App\Support\BackUrl::withBackAndFragment(
+ $openSubSyncableUrl = \App\Support\BackUrl::withBackFirstAndFragment(
'/admin/site-subscriptions/' . $order->siteSubscription->id . '?' . \Illuminate\Support\Arr::query([
'order_sync_status' => 'syncable',
]),