feat(notebook): pre-select notebook source when notebook_id is in URL

This commit is contained in:
xuhd committed 2026-06-05 13:35:35 +08:00
1 parent e689493723
commit e53c1a0f7b
4 files changed
+30 -5

No files matched your search

@@ -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<number | null>(null);
// 笔记来源:选中的 search_space_id 和多个 document_id
const [selectedNotebookId, setSelectedNotebookId] = useState<number | null>(
initialNotebookId ?? null,
);
const [selectedDocumentIds, setSelectedDocumentIds] = useState<number[]>([]);
const { models, isLoading: modelsLoading } = useModels();
@@ -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<string, string> = {
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({
<AIWritingForm
onSubmit={startWriting}
hideAdvancedFields={hideAdvancedFields}
initialNotebookId={initialNotebookId}
/>
)}
@@ -202,8 +202,10 @@ function AIWritingLayout({ hideAdvancedFields }: { hideAdvancedFields: boolean }
export default function AIWritingPage({
hideAdvancedFields = false,
initialNotebookId,
}: {
hideAdvancedFields?: boolean;
initialNotebookId?: number;
} = {}) {
return (
<CanvasThreadProvider>
@@ -42,7 +42,10 @@ export default function NotebookAIWritingPage() {
{/* 主体:AIWritingPage 完整组件,含 context providers */}
<div className="flex-1 min-h-0 overflow-hidden">
<AIWritingPage hideAdvancedFields />
<AIWritingPage
hideAdvancedFields
initialNotebookId={notebookId ? Number(notebookId) : undefined}
/>
</div>
</div>
);