fix(notebook): default material source to notebook when studioToken or initialNotebookId is set

Replace useEffect-based approach with synchronous effectiveMaterialSource
derived value to avoid first-render flash and timing issues.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
xuhdandClaude Sonnet 4.6 committed 2026-06-05 13:53:10 +08:00
1 parent d57bcd9aa2
commit c577833e7c
1 file changed
+25 -35
@@ -97,13 +97,10 @@ export function AIWritingForm({
[models, modelName], [models, modelName],
); );
// initialNotebookId 存在时自动切换素材来源为「我的笔记」 // studioToken / initialNotebookId 存在时强制使用「我的笔记」
useEffect(() => { const effectiveMaterialSource: MaterialSource = studioToken ?? initialNotebookId != null
if (initialNotebookId != null) { ? 'notebook'
setMaterialSource('notebook'); : materialSource;
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// 初始化时加载文章类型 // 初始化时加载文章类型
useEffect(() => { useEffect(() => {
@@ -172,11 +169,11 @@ export function AIWritingForm({
wordCountTarget: wordCount, wordCountTarget: wordCount,
keywordCount: DEFAULT_KEYWORD_COUNT, keywordCount: DEFAULT_KEYWORD_COUNT,
writingMode: hideAdvancedFields ? 'loose' : strictMode ? 'strict' : 'loose', writingMode: hideAdvancedFields ? 'loose' : strictMode ? 'strict' : 'loose',
materialSource, materialSource: effectiveMaterialSource,
modelName: selectedModel?.name || modelName || undefined, modelName: selectedModel?.name || modelName || undefined,
// 只有选了"我的笔记"才传笔记参数 // 只有选了"我的笔记"才传笔记参数
noteSearchSpaceId: materialSource === 'notebook' ? (selectedNotebookId ?? undefined) : undefined, noteSearchSpaceId: effectiveMaterialSource === 'notebook' ? (selectedNotebookId ?? undefined) : undefined,
noteSourceIds: materialSource === 'notebook' && selectedNotebookId != null ? selectedDocumentIds : undefined, noteSourceIds: effectiveMaterialSource === 'notebook' && selectedNotebookId != null ? selectedDocumentIds : undefined,
}); });
} }
@@ -284,33 +281,26 @@ export function AIWritingForm({
<div className="mt-4 space-y-2"> <div className="mt-4 space-y-2">
<label className={FIELD_LABEL_CLASS}>素材来源</label> <label className={FIELD_LABEL_CLASS}>素材来源</label>
{/* studioToken 模式:素材来源已锁定为「我的笔记」,不可切换 */} <Select
{studioToken ? ( value={effectiveMaterialSource}
<div className={`${FIELD_TRIGGER_CLASS} flex items-center px-3 border rounded-xl bg-white text-sm text-muted-foreground`}> onValueChange={(v) => handleMaterialSourceChange(v as MaterialSource)}
我的笔记 disabled={disabled}
</div> >
) : ( <SelectTrigger className={FIELD_TRIGGER_CLASS}>
<Select <SelectValue placeholder="选择素材来源" />
value={materialSource} </SelectTrigger>
onValueChange={(v) => handleMaterialSourceChange(v as MaterialSource)} <SelectContent>
disabled={disabled} {MATERIAL_SOURCE_OPTIONS.map((opt) => (
> <SelectItem key={opt.value} value={opt.value} className="text-sm">
<SelectTrigger className={FIELD_TRIGGER_CLASS}> {opt.label}
<SelectValue placeholder="选择素材来源" /> <span className="ml-1 text-xs text-muted-foreground">— {opt.desc}</span>
</SelectTrigger> </SelectItem>
<SelectContent> ))}
{MATERIAL_SOURCE_OPTIONS.map((opt) => ( </SelectContent>
<SelectItem key={opt.value} value={opt.value} className="text-sm"> </Select>
{opt.label}
<span className="ml-1 text-xs text-muted-foreground">— {opt.desc}</span>
</SelectItem>
))}
</SelectContent>
</Select>
)}
{/* 选了"我的笔记"才展示笔记本 / 文档选择器 */} {/* 选了"我的笔记"才展示笔记本 / 文档选择器 */}
{materialSource === 'notebook' && ( {effectiveMaterialSource === 'notebook' && (
<div className="mt-2 space-y-2"> <div className="mt-2 space-y-2">
{/* studioToken 模式:笔记本已锁定,不展示选择器 */} {/* studioToken 模式:笔记本已锁定,不展示选择器 */}
{!studioToken && ( {!studioToken && (