From 7c7b9ea1c637843db12de024d6e4638b25fb405e Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Thu, 19 Mar 2026 12:46:46 +0800 Subject: [PATCH] fix: persist docs config to localStorage - Save docsPath, externalDocs, and selectedPath to localStorage - Restore state when component mounts - Fix data loss when switching pages --- src/components/ApiDocViewer.tsx | 58 +++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/src/components/ApiDocViewer.tsx b/src/components/ApiDocViewer.tsx index 09788d0..b6b2cab 100644 --- a/src/components/ApiDocViewer.tsx +++ b/src/components/ApiDocViewer.tsx @@ -18,13 +18,32 @@ interface ApiDocViewerProps { onCloseAddModal?: () => void; } +const STORAGE_KEY = 'xc-docs-config'; + +function loadStoredConfig() { + try { + const stored = localStorage.getItem(STORAGE_KEY); + if (stored) { + return JSON.parse(stored); + } + } catch {} + return { docsPath: '', externalDocs: [] as ExternalDoc[], selectedPath: undefined }; +} + +function saveStoredConfig(docsPath: string, externalDocs: ExternalDoc[], selectedPath?: string) { + try { + localStorage.setItem(STORAGE_KEY, JSON.stringify({ docsPath, externalDocs, selectedPath })); + } catch {} +} + export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }: ApiDocViewerProps) => { + const stored = loadStoredConfig(); const [fileTree, setFileTree] = useState([]) - const [selectedPath, setSelectedPath] = useState() + const [selectedPath, setSelectedPath] = useState(stored.selectedPath) const [currentContent, setCurrentContent] = useState('') const [showModal, setShowModal] = useState(false) - const [docsPath, setDocsPath] = useState('') - const [externalDocs, setExternalDocs] = useState([]) + const [docsPath, setDocsPath] = useState(stored.docsPath) + const [externalDocs, setExternalDocs] = useState(stored.externalDocs) const [isLoading, setIsLoading] = useState(false) const [errorMsg, setErrorMsg] = useState(null) @@ -35,6 +54,35 @@ export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal } } }, [showAddModal]) + useEffect(() => { + if (externalDocs.length > 0 && fileTree.length > 0 && !selectedPath) { + const fileList = externalDocs + .filter(doc => { + const parts = doc.relativePath.split('/') + if (parts.length < 2) return true + const filename = parts[parts.length - 1].replace(/\.md$/, '') + const parentFolder = parts[parts.length - 2] + return filename !== parentFolder + }) + .map(d => d.relativePath) + + const targetPath = stored.selectedPath && externalDocs.find(d => d.relativePath === stored.selectedPath) + ? stored.selectedPath + : fileList[0] + + if (targetPath) { + setSelectedPath(targetPath) + setCurrentContent(externalDocs.find(d => d.relativePath === targetPath)?.content || '') + } + } + }, [externalDocs, fileTree, selectedPath]) + + useEffect(() => { + if (docsPath && externalDocs.length > 0) { + saveStoredConfig(docsPath, externalDocs, selectedPath) + } + }, [docsPath, externalDocs, selectedPath]) + const loadDocsFromPath = async (basePath: string): Promise => { if (!basePath) { setErrorMsg('请输入文档路径') @@ -70,6 +118,7 @@ export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal } } setExternalDocs(docs) + saveStoredConfig(basePath, docs) const fileList = docs .filter(doc => { @@ -86,6 +135,9 @@ export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal } if (fileList.length > 0) { setSelectedPath(fileList[0]) setCurrentContent(docs[0].content) + saveStoredConfig(basePath, docs, fileList[0]) + } else { + saveStoredConfig(basePath, docs, undefined) } return true } catch (err) {