diff --git a/src/components/platform-entry/PlatformEntryActiveFlowShell.test.tsx b/src/components/platform-entry/PlatformEntryActiveFlowShell.test.tsx
index 51cce4cfc..c3c556924 100644
--- a/src/components/platform-entry/PlatformEntryActiveFlowShell.test.tsx
+++ b/src/components/platform-entry/PlatformEntryActiveFlowShell.test.tsx
@@ -1674,6 +1674,71 @@ describe('共创顶层入口(只列支持共创的作品)', () => {
).toBeNull();
});
+ it('导航高亮认「入口来源」:从共创侧进的详情高亮共创,其余高亮游戏(用户报的 bug)', async () => {
+ gameDistributionMock.getGame.mockResolvedValue({
+ id: 'game-1',
+ title: '作品',
+ summary: '简介',
+ description: '',
+ category: '动作',
+ tags: [],
+ coverColor: '#d77a51',
+ icon: '✦',
+ author: { id: 'author-1', name: '测试作者' },
+ deviceSupport: { desktop: true, mobile: true, touch: true },
+ status: 'published',
+ currentVersion: null,
+ playCount: 0,
+ createdAt: '2026-09-18T00:00:00.000Z',
+ forkCount: 0,
+ });
+ const cases = [
+ {
+ expected: '共创',
+ title: '共创页点卡(带 from=co-creation)',
+ url: '/games/detail?id=game-1&from=co-creation',
+ },
+ {
+ expected: '游戏',
+ title: '游戏页点卡(无来源标记)',
+ url: '/games/detail?id=game-1',
+ },
+ {
+ expected: '共创',
+ title: '族谱页(共创侧才进得来)',
+ url: '/games/lineage?id=game-root',
+ },
+ {
+ expected: '共创',
+ title: '对比页(共创侧才进得来)',
+ url: '/games/compare?left=game-1&right=game-2',
+ },
+ ] as const;
+ for (const item of cases) {
+ window.history.replaceState(null, '', item.url);
+ const view = render(
+ ,
+ );
+ const rail = screen.getByRole('navigation', { name: '平台导航' });
+ expect(
+ within(rail)
+ .getAllByRole('button')
+ .filter((button) => button.getAttribute('aria-current') === 'page')
+ .map((button) => button.getAttribute('aria-label')),
+ ).toEqual([item.expected]);
+ view.unmount();
+ }
+ });
+
it('窄屏底部导航也有「共创」,点它同样直达共创页', async () => {
responsiveMock.isDesktopLayout = false;
window.history.replaceState(null, '', '/games');
diff --git a/src/components/platform-entry/PlatformEntryActiveFlowShell.tsx b/src/components/platform-entry/PlatformEntryActiveFlowShell.tsx
index d3a73ea97..bb0e89c15 100644
--- a/src/components/platform-entry/PlatformEntryActiveFlowShell.tsx
+++ b/src/components/platform-entry/PlatformEntryActiveFlowShell.tsx
@@ -47,6 +47,8 @@ import { ClientDownloadEntry } from '../creation-home/ClientDownloadEntry';
import { setCreatorViewer } from '../creator/creatorRelationshipState';
import {
CO_CREATION_DETAIL_SOURCE,
+ isCoCreator,
+ resolveGameViewerContext,
shouldCarryCoCreationSource,
} from '../game-distribution/gameViewerRole';
import { PaymentCheckoutView } from './PaymentCheckoutView';
@@ -830,10 +832,6 @@ export function PlatformEntryFlowShellImpl({
selectionStage === 'game-mine' ||
selectionStage === 'game-lineage' ||
selectionStage === 'game-publish';
- /** 侧边栏 / 底部导航的「共创」高亮(顶层入口,2026-10-07 从游戏页子页签升上来)。 */
- const isCoCreationStage = selectionStage === 'game-co-creation';
- /** 游戏区但不在共创页时,「游戏」这个导航项才是激活态——进共创时高亮共创、不再高亮游戏。 */
- const isGamesNavActive = isGamesStage && !isCoCreationStage;
/**
* 游玩页自己撑满剩余高度,面板不能再滚动,否则移动端会出现整页可滚的
* 半屏播放器;其余舞台继续沿用面板滚动。
@@ -842,8 +840,32 @@ export function PlatformEntryFlowShellImpl({
const gameSearchParams = new URLSearchParams(
typeof window === 'undefined' ? '' : window.location.search,
);
+ /**
+ * 本屏的**入口来源标记**:详情页上是「从哪一侧点进来」(`from=co-creation`),
+ * 族谱页上含义不同(`from=` = 高亮哪个作品)——所以只认 `co-creation` 这一个值
+ * (复用 `resolveGameViewerContext` 的白名单,不自己判字符串)。
+ */
+ const gameEntrySource = gameSearchParams.get('from');
+ /**
+ * 本屏是否属于「**共创侧**」上下文 —— **导航高亮(侧边栏 / 底部 dock)的唯一判据**。
+ *
+ * 用户报的 bug:共创页 → 点卡 → 详情后,侧边栏仍高亮「游戏」。根因是这里原先只看 `stage`,
+ * 而详情页的 stage 属于游戏区(`game-detail`),**来源被丢掉**。修法是复用详情页那套
+ * 已落地的来源判定(不新造参数、不新造标记):
+ * ① URL 的来源标记就是 `co-creation`(详情页,以及从它继续跳过去的页面);
+ * ② 或当前就在「共创侧才进得来的阶段」(共创页 / 族谱 / 对比,见 `shouldCarryCoCreationSource`)。
+ */
+ const isCoCreationContext =
+ isGamesStage &&
+ (isCoCreator(resolveGameViewerContext(gameEntrySource)) ||
+ shouldCarryCoCreationSource({
+ stage: selectionStage,
+ currentSource: gameEntrySource,
+ }));
+ /** 游戏区、且**不在共创侧上下文**时,「游戏」这个导航项才是激活态(两者互斥、不双亮)。 */
+ const isGamesNavActive = isGamesStage && !isCoCreationContext;
const gameId = gameSearchParams.get('id');
- const lineageHighlightGameId = gameSearchParams.get('from');
+ const lineageHighlightGameId = gameEntrySource;
const compareLeftGameId = gameSearchParams.get('left');
const compareRightGameId = gameSearchParams.get('right');
const creatorConnectionTab = gameSearchParams.get('tab');
@@ -912,12 +934,13 @@ export function PlatformEntryFlowShellImpl({
/>
{/*
「共创」:**顶层入口**(2026-10-07 用户口径:不该是游戏页里的子页签)。
- 指向 `scope="forkable"` 的那个列表页(`/games/co-creation`),
- 与「游戏」平级;在共创页时高亮的是这一项,不再是「游戏」。
+ 指向 `scope="forkable"` 的那个列表页(`/games/co-creation`),与「游戏」平级。
+ 高亮读 `isCoCreationContext`:共创页本身、以及**从共创侧点进去的详情/族谱/对比**
+ 都算共创侧(用户报的「共创 → 详情后仍高亮游戏」就是这里原先只看 stage 造成的)。
*/}
openCreator()}
onOpenProfile={openProfile}