@@ -10,7 +10,7 @@ import "katex/dist/katex.min.css";
1010import "@uiw/react-md-editor/markdown-editor.css" ;
1111import "@uiw/react-markdown-preview/markdown.css" ;
1212
13- import { createNote , updateNote , fetchNotes , type NoteDTO } from "@/lib/api-client" ;
13+ import { createNote , updateNote , fetchNotes , type NoteDTO , type UploadedPaperDTO } from "@/lib/api-client" ;
1414import { getAccessToken } from "@/lib/auth" ;
1515import type { MinerUParseResult } from "@/types/pdf-reader" ;
1616
@@ -20,16 +20,23 @@ const MDEditor = dynamic(
2020 { ssr : false }
2121) ;
2222
23+ function formatLibraryTitle ( filename : string ) : string {
24+ const withoutExt = filename . replace ( / \. [ ^ / . ] + $ / , "" ) ;
25+ const cleaned = withoutExt . replace ( / [ _ - ] + / g, " " ) . trim ( ) ;
26+ return cleaned || filename ;
27+ }
28+
2329interface NoteEditorPanelProps {
2430 paperId ?: number ;
31+ paper ?: UploadedPaperDTO | null ;
2532 mineruResult ?: MinerUParseResult | null ;
2633 onExtractText ?: ( text : string ) => void ;
2734}
2835
2936const NoteEditorPanel = forwardRef <
3037 { appendContent : ( text : string ) => void ; resetEditor : ( ) => void } ,
3138 NoteEditorPanelProps
32- > ( ( { paperId, mineruResult } , ref ) => {
39+ > ( ( { paperId, paper , mineruResult } , ref ) => {
3340 const [ title , setTitle ] = useState ( "" ) ;
3441 const [ content , setContent ] = useState ( "" ) ;
3542 const [ saving , setSaving ] = useState ( false ) ;
@@ -108,15 +115,6 @@ const NoteEditorPanel = forwardRef<
108115 // eslint-disable-next-line react-hooks/exhaustive-deps
109116 } , [ paperId ] ) ; // 只依赖paperId
110117
111- // 自动填充标题(仅首次,且在新建笔记时)
112- useEffect ( ( ) => {
113- if ( mineruResult && ! hasAutoFilledTitle && ! noteId && ! title ) {
114- const pdfTitle = mineruResult . metadata . title || "未命名文档" ;
115- setTitle ( `关于《${ pdfTitle } 》的笔记` ) ;
116- setHasAutoFilledTitle ( true ) ;
117- }
118- } , [ mineruResult , hasAutoFilledTitle , noteId , title ] ) ;
119-
120118 // 自动保存(debounce 3秒)
121119 const triggerAutoSave = useCallback ( ( ) => {
122120 if ( autoSaveTimerRef . current ) {
@@ -248,6 +246,26 @@ const NoteEditorPanel = forwardRef<
248246 setHasAutoFilledTitle ( true ) ;
249247 } ;
250248
249+ const resolveNoteTitleSource = useCallback ( ( ) : string => {
250+ if ( paper ?. original_filename ) {
251+ return formatLibraryTitle ( paper . original_filename ) ;
252+ }
253+
254+ const mineruTitle = ( mineruResult ?. metadata ?. title ?? "" ) . trim ( ) ;
255+ if ( mineruTitle ) return mineruTitle ;
256+
257+ return "" ;
258+ } , [ paper ?. original_filename , mineruResult ?. metadata ?. title ] ) ;
259+
260+ useEffect ( ( ) => {
261+ if ( hasAutoFilledTitle || noteId || title ) return ;
262+ const sourceTitle = resolveNoteTitleSource ( ) ;
263+ if ( ! sourceTitle ) return ;
264+
265+ setTitle ( `关于《${ sourceTitle } 》的笔记` ) ;
266+ setHasAutoFilledTitle ( true ) ;
267+ } , [ resolveNoteTitleSource , hasAutoFilledTitle , noteId , title ] ) ;
268+
251269 return (
252270 < aside
253271 className = "flex h-full min-h-0 w-full flex-col overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-slate-700 dark:bg-slate-900"
0 commit comments