From e53c1a0f7bf31c7fb3bdb05842e787dcc2b31177 Mon Sep 17 00:00:00 2001 From: xuhd Date: Fri, 5 Jun 2026 11:34:47 +0800 Subject: [PATCH] feat(notebook): pre-select notebook source when notebook_id is in URL --- .../components/ai-writing/AIWritingForm.tsx | 9 +++++++-- .../components/ai-writing/AIWritingPanel.tsx | 19 +++++++++++++++++-- .../src/open-canvas/pages/AIWritingPage.tsx | 2 ++ .../src/pages/NotebookAIWritingPage.tsx | 5 ++++- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/frontend-web/src/open-canvas/components/ai-writing/AIWritingForm.tsx b/frontend-web/src/open-canvas/components/ai-writing/AIWritingForm.tsx index 727f4e79..c53d386b 100644 --- a/frontend-web/src/open-canvas/components/ai-writing/AIWritingForm.tsx +++ b/frontend-web/src/open-canvas/components/ai-writing/AIWritingForm.tsx @@ -22,6 +22,8 @@ interface AIWritingFormProps { disabled?: boolean; /** workspace 入口:隐藏严格模式、目标读者 */ hideAdvancedFields?: boolean; + /** 预选笔记本 ID(传入时自动切换素材来源为「我的笔记」) */ + initialNotebookId?: number; } const INPUT_CLASS = @@ -50,6 +52,7 @@ export function AIWritingForm({ onSubmit, disabled, hideAdvancedFields = false, + initialNotebookId, }: AIWritingFormProps) { const { intent, setIntent, @@ -62,8 +65,10 @@ export function AIWritingForm({ materialSource, setMaterialSource, modelName, setModelName, } = useWritingForm(); - // 笔记来源:选中的 search_space_id 和多个 document_id(master 引入,useWritingForm 未含) - const [selectedNotebookId, setSelectedNotebookId] = useState(null); + // 笔记来源:选中的 search_space_id 和多个 document_id + const [selectedNotebookId, setSelectedNotebookId] = useState( + initialNotebookId ?? null, + ); const [selectedDocumentIds, setSelectedDocumentIds] = useState([]); const { models, isLoading: modelsLoading } = useModels(); diff --git a/frontend-web/src/open-canvas/components/ai-writing/AIWritingPanel.tsx b/frontend-web/src/open-canvas/components/ai-writing/AIWritingPanel.tsx index 003f8799..d0929596 100644 --- a/frontend-web/src/open-canvas/components/ai-writing/AIWritingPanel.tsx +++ b/frontend-web/src/open-canvas/components/ai-writing/AIWritingPanel.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useRef, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useSearchParams } from 'react-router-dom'; import { ChevronsDown, Play, Plus, RotateCcw, Settings2, Square, Trash2 } from 'lucide-react'; import { toast } from 'sonner'; @@ -16,7 +16,7 @@ import { useArticleTypes } from '../../hooks/useArticleTypes'; import { useAIWriting } from '../../contexts/AIWritingContext'; import { useAIWritingHistory } from '../../contexts/AIWritingHistoryContext'; import { useAIWritingSessions } from '../../hooks/useAIWritingSessions'; -import { adminCleanupAIWritingSessions } from '../../api/ai-writing-sessions'; +import { adminCleanupAIWritingSessions, getAIWritingSession } from '../../api/ai-writing-sessions'; /** * 暂停 / 继续功能开关(默认 false = 关)。 @@ -70,8 +70,10 @@ const STATUS_LABEL: Record = { export function AIWritingPanel({ hideAdvancedFields = false, + initialNotebookId, }: { hideAdvancedFields?: boolean; + initialNotebookId?: number; } = {}) { const navigate = useNavigate(); const { state, startWriting, submitIntervention, pauseWriting, resumeWriting, reset } = useAIWriting(); @@ -213,6 +215,18 @@ export function AIWritingPanel({ return () => window.removeEventListener('ai-writing:open-session', onOpenSession); }, []); + // 路径3:URL ?session=xxx 直接定位到指定会话 + useEffect(() => { + const sessionId = searchParams.get('session'); + if (!sessionId) return; + // 消费参数,避免刷新重复触发 + setSearchParams((prev) => { prev.delete('session'); return prev; }, { replace: true }); + getAIWritingSession(sessionId) + .then((session) => handleSelectHistoryRef.current(session)) + .catch(() => { /* session 不存在时静默忽略 */ }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); // 仅挂载时执行一次 + // ── ⚠️ 临时调试:admin 一键清理所有过期会话 ──────────────────────────────── // ai-writing-优化.md §阶段 7 删冗余代码时,本按钮 + 对应 api 一并删除。 // 仅 admin 能成功调用(后端 _require_admin),普通用户调会拿到 403。 @@ -339,6 +353,7 @@ export function AIWritingPanel({ )} diff --git a/frontend-web/src/open-canvas/pages/AIWritingPage.tsx b/frontend-web/src/open-canvas/pages/AIWritingPage.tsx index 09ebe1cf..de73ecb1 100644 --- a/frontend-web/src/open-canvas/pages/AIWritingPage.tsx +++ b/frontend-web/src/open-canvas/pages/AIWritingPage.tsx @@ -202,8 +202,10 @@ function AIWritingLayout({ hideAdvancedFields }: { hideAdvancedFields: boolean } export default function AIWritingPage({ hideAdvancedFields = false, + initialNotebookId, }: { hideAdvancedFields?: boolean; + initialNotebookId?: number; } = {}) { return ( diff --git a/frontend-web/src/pages/NotebookAIWritingPage.tsx b/frontend-web/src/pages/NotebookAIWritingPage.tsx index bc49e2af..8c083368 100644 --- a/frontend-web/src/pages/NotebookAIWritingPage.tsx +++ b/frontend-web/src/pages/NotebookAIWritingPage.tsx @@ -42,7 +42,10 @@ export default function NotebookAIWritingPage() { {/* 主体:AIWritingPage 完整组件,含 context providers */}
- +
);