From d2698cbb1d5f348539c923a3edfbaa5383f22d23 Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Mon, 5 Oct 2026 11:24:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E9=97=A8=E7=A6=81):=20=E8=A1=A5=20/games/l?= =?UTF-8?q?ineage=20=E7=9A=84=20Pingora=20=E7=99=BB=E8=AE=B0=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E4=BF=AE=E6=8E=89=E8=A2=AB=E6=8E=A9=E7=9B=96=E7=9A=84?= =?UTF-8?q?=20eslint=20=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `server-rs/crates/pingora-gateway/src/main.rs`(MAIN_SPA_PATHS,:64-79):插入 `"/games/lineage"`(放在 `"/games/detail"` 之后,保持既有字典序)。这是主站 SPA 深链在 Pingora 网关下的登记,漏一条就把该深链打成 404;与上一提交补的三份 nginx 模板属同一条「新 SPA 路由三处同批更新」规则 - 矩阵与文档无需改:`deploy/pingora/nginx-route-parity.matrix.json` 的既有 `games_spa_fallback` 用例仍前缀匹配同一行 `location`(本次只改交替项、未新增 `location`),Pingora 试点文档的取值表同理未受影响 - `src/components/game-distribution/GameLineagePage.tsx:146`:把 `lineage?.nodes ?? []` 用 `useMemo(..., [lineage])` 稳定下来,消掉两条 `react-hooks/exhaustive-deps`。取值仍是同一表达式的结果,identity 只在 `lineage` 变化时改变,因此两个下游 useMemo(代际分组、可见 ID 集合)取值不变、只少做无谓重算;未用 disable 注释压掉告警 - 6 处 `simple-import-sort/imports` 用 `eslint --fix` 机械修(`apps/.../view/home/PlatformGameForkSection.tsx`、`apps/.../view/home/index.tsx`、`src/components/game-distribution/GameDetailPage.tsx`、`MyGamesPage.test.tsx`、`MyGamesPage.tsx`、`src/services/gameDistributionClient.ts`):逐文件比对「剥掉 import 行后的正文」——5 个文件完全一致,`GameDetailPage.tsx` 仅多一个 import 分组空行 - 这批修的是「修 nginx 时被前一道红掩盖的第二、第三个失败」:CI run 3387 卡在 `check:nginx-spa-routes`,`check:pingora-route-parity` 与 `lint:eslint` 从未跑到 - 本地验证:`check:repository-ci` 的 15 个 lint 环节 + `appSurface` vitest + `npm run build` + `git diff --check 6c9566058...HEAD` 全绿,仅两个**本机不可执行**项(`check:git-hooks` 的 Windows EBUSY、`check:generated-bindings` 的 AGC `export_bindings` 本地构建);另跑 `cargo test -p pingora-gateway` 40 passed、`npx vitest run apps/ai-game-creator-shell/tests` 1957 passed / 17 skipped --- .../src/view/home/PlatformGameForkSection.tsx | 4 ++-- apps/ai-game-creator-shell/src/view/home/index.tsx | 2 +- server-rs/crates/pingora-gateway/src/main.rs | 1 + src/components/game-distribution/GameDetailPage.tsx | 1 + src/components/game-distribution/GameLineagePage.tsx | 5 ++++- src/components/game-distribution/MyGamesPage.test.tsx | 4 ++-- src/components/game-distribution/MyGamesPage.tsx | 4 ++-- src/services/gameDistributionClient.ts | 2 +- 8 files changed, 14 insertions(+), 9 deletions(-) diff --git a/apps/ai-game-creator-shell/src/view/home/PlatformGameForkSection.tsx b/apps/ai-game-creator-shell/src/view/home/PlatformGameForkSection.tsx index 8dfa54bf1..aad318466 100644 --- a/apps/ai-game-creator-shell/src/view/home/PlatformGameForkSection.tsx +++ b/apps/ai-game-creator-shell/src/view/home/PlatformGameForkSection.tsx @@ -10,11 +10,11 @@ * 渲染层只做输入解析、加载态与失败分类。 */ -import { useRef, useState } from 'react'; import type { FormEvent } from 'react'; +import { useRef, useState } from 'react'; -import type { InitLocalProjectResult } from '../../app/types'; import { resolveTauriInvoke } from '../../app/tauri'; +import type { InitLocalProjectResult } from '../../app/types'; import { classifyPlatformForkFailure, parsePlatformGameId, diff --git a/apps/ai-game-creator-shell/src/view/home/index.tsx b/apps/ai-game-creator-shell/src/view/home/index.tsx index e41681053..da902be9b 100644 --- a/apps/ai-game-creator-shell/src/view/home/index.tsx +++ b/apps/ai-game-creator-shell/src/view/home/index.tsx @@ -20,13 +20,13 @@ import { resolveHomeCreationFailureMessage } from '../../features/app-shell/home import { ConversationModelSelect } from '../../features/project-workspace/ConversationModelSelect'; import type { GameTemplateEntry } from '../../features/template-library/templateLibraryModel'; import type { ProjectOpenAnalytics } from '../../services/clientAnalytics'; -import PlatformGameForkSection from './PlatformGameForkSection'; import RichInputArea, { UploadButton } from './components/RichInputArea'; import { richTextToAttachments, richTextToPrompt, } from './components/RichInputArea/richTextToPrompt'; import { resolveHomeStartMode } from './homeStartMode'; +import PlatformGameForkSection from './PlatformGameForkSection'; import TemplateRecommendations from './TemplateRecommendations'; import { type HomeCreationType, diff --git a/server-rs/crates/pingora-gateway/src/main.rs b/server-rs/crates/pingora-gateway/src/main.rs index 51df31e98..3d3cffc11 100644 --- a/server-rs/crates/pingora-gateway/src/main.rs +++ b/server-rs/crates/pingora-gateway/src/main.rs @@ -69,6 +69,7 @@ const MAIN_SPA_PATHS: &[&str] = &[ "/editor/canvas", "/games", "/games/detail", + "/games/lineage", "/games/mine", "/games/play", "/games/publish", diff --git a/src/components/game-distribution/GameDetailPage.tsx b/src/components/game-distribution/GameDetailPage.tsx index 907dec1ef..a250f69d0 100644 --- a/src/components/game-distribution/GameDetailPage.tsx +++ b/src/components/game-distribution/GameDetailPage.tsx @@ -6,6 +6,7 @@ import { } from '@genarrative/shared/components'; import { ArrowLeft, Gamepad2, Maximize2 } from 'lucide-react'; import { useCallback, useEffect, useRef, useState } from 'react'; + import { GAME_DISTRIBUTION_FORK_AUTHORIZATION_LABELS, type GameDistributionRecoveryAction, diff --git a/src/components/game-distribution/GameLineagePage.tsx b/src/components/game-distribution/GameLineagePage.tsx index ee23259bb..b2af5a662 100644 --- a/src/components/game-distribution/GameLineagePage.tsx +++ b/src/components/game-distribution/GameLineagePage.tsx @@ -143,7 +143,10 @@ export function GameLineagePage({ void loadLineage(); }, [loadLineage]); - const nodes = lineage?.nodes ?? []; + // `lineage?.nodes ?? []` 在缺省分支每次渲染都会产生新数组,直接喂给下面的 useMemo 会让依赖 + // 每次渲染都变;这里把派生结果本身稳定下来:值仍是同一表达式的结果,identity 只在 `lineage` + // 变化时改变,因此两个下游 useMemo 的取值不变、只少做无谓重算。 + const nodes = useMemo(() => lineage?.nodes ?? [], [lineage]); const groups = useMemo(() => groupNodesByGeneration(nodes), [nodes]); const visibleIds = useMemo( () => new Set(nodes.map((node) => node.gameId)), diff --git a/src/components/game-distribution/MyGamesPage.test.tsx b/src/components/game-distribution/MyGamesPage.test.tsx index e935820bb..93e23939a 100644 --- a/src/components/game-distribution/MyGamesPage.test.tsx +++ b/src/components/game-distribution/MyGamesPage.test.tsx @@ -8,15 +8,15 @@ import { beforeEach, expect, test, vi } from 'vitest'; import { cancelGameVersion, deleteMyGame, - getDerivedGames, type GameDistributionMyGame, + getDerivedGames, getGameVersion, listMyGames, loadVersionRecoveryActions, submitGameVersion, unpublishGame, - updateMyGame, updateGameForkAuthorization, + updateMyGame, } from '../../services/gameDistributionClient'; import { AuthUiContext } from '../auth/AuthUiContext'; import { MyGamesPage } from './MyGamesPage'; diff --git a/src/components/game-distribution/MyGamesPage.tsx b/src/components/game-distribution/MyGamesPage.tsx index c64ba2dac..456c5fc51 100644 --- a/src/components/game-distribution/MyGamesPage.tsx +++ b/src/components/game-distribution/MyGamesPage.tsx @@ -6,20 +6,20 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import type { GameDistributionRecoveryAction } from '../../../packages/shared/src/contracts/gameDistribution'; import { canUpgradeGameForkAuthorization, - GAME_DISTRIBUTION_FORK_AUTHORIZATIONS, GAME_DISTRIBUTION_FORK_AUTHORIZATION_LABELS, GAME_DISTRIBUTION_FORK_AUTHORIZATION_SHORT_LABELS, + GAME_DISTRIBUTION_FORK_AUTHORIZATIONS, type GameDistributionForkAuthorization, resolveGameForkAuthorization, } from '../../../packages/shared/src/contracts/gameDistribution'; import { cancelGameVersion, deleteMyGame, - getDerivedGames, type GameDistributionLineageNode, type GameDistributionMyGame, type GameDistributionUpdateMyGameResponse, type GameDistributionVersionStatusEntry, + getDerivedGames, listMyGames, loadVersionRecoveryActions, submitGameVersion, diff --git a/src/services/gameDistributionClient.ts b/src/services/gameDistributionClient.ts index 2f3dd84ab..fffe2ba85 100644 --- a/src/services/gameDistributionClient.ts +++ b/src/services/gameDistributionClient.ts @@ -14,8 +14,8 @@ import type { GameDistributionReviewsResponse, GameDistributionSaveReviewRequest, GameDistributionSaveReviewResponse, - GameDistributionUpdateGameMetadataRequest, GameDistributionSetForkAuthorizationRequest, + GameDistributionUpdateGameMetadataRequest, GameDistributionVersionDetail, GameDistributionVersionStatus as GameDistributionVersionStatusValue, GameDistributionVersionSummary,