From 2703acda84b92c120050500931ca1cb7e8f1ab38 Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Mon, 7 Sep 2026 14:50:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E9=80=89=E6=8B=A9=E5=A7=8B?= =?UTF-8?q?=E7=BB=88=E5=9B=9E=E9=80=80=E9=BB=98=E8=AE=A4=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E5=86=8D=E5=87=BA=E7=8E=B0=E8=AF=B7=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ConversationModelSelect 在已保存选择失效时回退到后台默认模型,只要默认模型可用就不会出现「选择模型」空态 首页模型选择器改为挂载即加载目录,触发按钮直接落在默认模型上(移除懒加载) 首页不再需要 lazy 路径,清理组件中已无调用方的懒加载逻辑 同步更新模型选择相关回归测试与首页/运行时配置用例 --- .../ConversationModelSelect.tsx | 31 +++++++++---------- .../src/view/home/index.tsx | 1 - .../tests/appSurface/home.suite.ts | 29 ++++++++++++----- .../appSurface/runtime-settings.suite.ts | 12 ++++++- .../tests/conversationModelSelect.test.tsx | 22 +++++++++---- 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx b/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx index 88ba4836b..eef2a3150 100644 --- a/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx +++ b/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx @@ -11,21 +11,18 @@ import { export function ConversationModelSelect({ className, disabled, - lazy = false, onReady, }: { className?: string; disabled: boolean; - lazy?: boolean; onReady?: (ready: boolean) => void; }) { const [models, setModels] = useState([]); const [selected, setSelected] = useState(''); const [defaultModelId, setDefaultModelId] = useState(''); - const [busy, setBusy] = useState(!lazy); + const [busy, setBusy] = useState(true); const [error, setError] = useState(''); const [open, setOpen] = useState(false); - const initializedRef = useRef(false); const containerRef = useRef(null); const refresh = useCallback(async () => { setBusy(true); @@ -40,16 +37,25 @@ export function ConversationModelSelect({ ]); setModels(catalog.models); setDefaultModelId(catalog.defaultModelId); - const id = config.config.selectedModelId || catalog.defaultModelId; + const savedSelection = config.config.selectedModelId; + // 优先沿用用户已选且仍可用的模型;已选模型被停用/移除时回退到默认模型, + // 避免下拉出现「请选择模型」的空态。默认模型由后台强制配置,缺失时才走错误提示。 + const savedAvailable = savedSelection + ? catalog.models.some((model) => model.id === savedSelection) + : false; + const id = + savedAvailable && savedSelection + ? savedSelection + : catalog.defaultModelId; setSelected(id); const available = catalog.models.some((model) => model.id === id); - if (available && !config.config.selectedModelId) { + if (available && savedSelection !== id) { const saved = await invoke( 'select_game_creator_model', { modelId: id }, ); if (saved.config.selectedModelId !== id) - throw new Error('Default selection was not saved'); + throw new Error('Model selection was not saved'); } onReady?.(available); if (!available) setError('请选择可用模型'); @@ -62,9 +68,8 @@ export function ConversationModelSelect({ }, [onReady]); useEffect(() => { - if (lazy) return; void refresh(); - }, [refresh, lazy]); + }, [refresh]); useEffect(() => { if (!open) return; @@ -126,13 +131,7 @@ export function ConversationModelSelect({ aria-haspopup="listbox" aria-expanded={open} disabled={disabled} - onClick={() => { - if (lazy && !initializedRef.current) { - initializedRef.current = true; - void refresh(); - } - setOpen((current) => !current); - }} + onClick={() => setOpen((current) => !current)} >