diff --git a/frontend/src/components/DocumentEditor.tsx b/frontend/src/components/DocumentEditor.tsx index 7db9df7..b61b33a 100644 --- a/frontend/src/components/DocumentEditor.tsx +++ b/frontend/src/components/DocumentEditor.tsx @@ -1,8 +1,8 @@ -import { useEffect, useMemo, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import CodeMirror from '@uiw/react-codemirror'; import { markdown } from '@codemirror/lang-markdown'; import { html } from '@codemirror/lang-html'; -import { deleteDocument, getDocument, saveDocument } from '../api/client'; +import { deleteDocument, getDocument, saveDocument, uploadDocument } from '../api/client'; import MarkdownPreview from './MarkdownPreview'; interface DocumentEditorProps { @@ -18,9 +18,11 @@ export default function DocumentEditor({ documentKey, onDirtyChange, onDeleted } const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [deleting, setDeleting] = useState(false); + const [replacing, setReplacing] = useState(false); const [loadError, setLoadError] = useState(null); const [saveError, setSaveError] = useState(null); const [deleteError, setDeleteError] = useState(null); + const replaceInputRef = useRef(null); const [isPreview, setIsPreview] = useState(true); @@ -71,8 +73,25 @@ export default function DocumentEditor({ documentKey, onDirtyChange, onDeleted } }); } - function handleDelete() { - if (!window.confirm('确定要删除这篇文档吗?此操作无法撤销。')) { + async function handleReplaceFile(e: React.ChangeEvent) { + const file = e.target.files?.[0]; + e.target.value = ''; + if (!file) return; + setReplacing(true); + try { + await uploadDocument(file, '', documentKey); + const doc = await getDocument(documentKey); + setContent(doc.content); + setOriginalContent(doc.content); + setContentType(doc.contentType); + } catch { + setSaveError('替换失败,请重试'); + } finally { + setReplacing(false); + } + } + + function handleDelete() { if (!window.confirm('确定要删除这篇文档吗?此操作无法撤销。')) { return; } setDeleting(true); @@ -126,6 +145,10 @@ export default function DocumentEditor({ documentKey, onDirtyChange, onDeleted } + + {!isImage && !isHtml && ( <> -