diff --git a/frontend/src/pages/Document/DocumentEditor.jsx b/frontend/src/pages/Document/DocumentEditor.jsx index 6321324..e5cbfb2 100644 --- a/frontend/src/pages/Document/DocumentEditor.jsx +++ b/frontend/src/pages/Document/DocumentEditor.jsx @@ -4,6 +4,7 @@ import { Layout, Menu, Button, Modal, Input, Space, Tooltip, Dropdown, Upload, S import { FileOutlined, FolderOutlined, + FolderOpenOutlined, PlusOutlined, DeleteOutlined, EditOutlined, @@ -923,11 +924,15 @@ function DocumentEditor() { ) if (!node.isLeaf) { + const isOpen = openKeys.includes(node.key) + const folderIconStyle = isSelected ? { color: '#1890ff' } : undefined // 目录 - 通过className和style控制选中样式 return { key: node.key, label: labelContent, - icon: , + icon: isOpen + ? + : , children: node.children ? convertTreeToMenuItems(node.children) : [], className: isSelected ? 'folder-selected' : '', onTitleClick: () => { diff --git a/frontend/src/pages/Document/DocumentPage.jsx b/frontend/src/pages/Document/DocumentPage.jsx index fdcb3cb..af1f4d8 100644 --- a/frontend/src/pages/Document/DocumentPage.jsx +++ b/frontend/src/pages/Document/DocumentPage.jsx @@ -1,7 +1,7 @@ import { useState, useEffect, useRef, useMemo } from 'react' import { useParams, useNavigate, useSearchParams } from 'react-router-dom' import { Layout, Menu, Spin, FloatButton, Button, Tooltip, message, Anchor, Modal, Input, Space, Dropdown, Empty, Switch } from 'antd' -import { VerticalAlignTopOutlined, ShareAltOutlined, MenuFoldOutlined, MenuUnfoldOutlined, FileTextOutlined, FolderOutlined, FilePdfOutlined, CopyOutlined, LockOutlined, CloudDownloadOutlined, CloudUploadOutlined, DownOutlined, SearchOutlined, ArrowLeftOutlined, MenuOutlined, ReloadOutlined } from '@ant-design/icons' +import { VerticalAlignTopOutlined, ShareAltOutlined, MenuFoldOutlined, MenuUnfoldOutlined, FileTextOutlined, FolderOutlined, FolderOpenOutlined, FilePdfOutlined, CopyOutlined, LockOutlined, CloudDownloadOutlined, CloudUploadOutlined, DownOutlined, SearchOutlined, ArrowLeftOutlined, MenuOutlined, ReloadOutlined } from '@ant-design/icons' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' import rehypeRaw from 'rehype-raw' @@ -306,11 +306,12 @@ function DocumentPage() { ) if (!node.isLeaf) { + const isOpen = openKeys.includes(node.key) // 目录 return { key: node.key, label: labelNode, - icon: , + icon: isOpen ? : , onTitleClick: () => setSelectedNodeKey(node.key), children: node.children ? convertTreeToMenuItems(node.children) : [], } diff --git a/frontend/src/pages/Preview/ProjectSharePage.jsx b/frontend/src/pages/Preview/ProjectSharePage.jsx index 9d7cc94..8c56a05 100644 --- a/frontend/src/pages/Preview/ProjectSharePage.jsx +++ b/frontend/src/pages/Preview/ProjectSharePage.jsx @@ -1,7 +1,7 @@ import { useState, useEffect, useRef, useMemo } from 'react' import { useParams, useSearchParams, useNavigate } from 'react-router-dom' import { Layout, Menu, Spin, Button, Modal, Input, Drawer, Anchor, Empty, Tooltip } from 'antd' -import { MenuFoldOutlined, MenuUnfoldOutlined, FileTextOutlined, FolderOutlined, FilePdfOutlined, LockOutlined, MenuOutlined, CloseOutlined } from '@ant-design/icons' +import { MenuFoldOutlined, MenuUnfoldOutlined, FileTextOutlined, FolderOutlined, FolderOpenOutlined, FilePdfOutlined, LockOutlined, MenuOutlined, CloseOutlined } from '@ant-design/icons' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' import rehypeHighlight from 'rehype-highlight' @@ -45,6 +45,7 @@ function ProjectSharePage() { const [projectInfo, setProjectInfo] = useState(null) const [fileTree, setFileTree] = useState([]) const [selectedFile, setSelectedFile] = useState('') + const [selectedNodeKey, setSelectedNodeKey] = useState('') const [markdownContent, setMarkdownContent] = useState('') const [loading, setLoading] = useState(false) const [openKeys, setOpenKeys] = useState([]) @@ -264,10 +265,12 @@ function ProjectSharePage() { ) if (!node.isLeaf) { + const isOpen = openKeys.includes(node.key) return { key: node.key, label: labelNode, - icon: , + icon: isOpen ? : , + onTitleClick: () => setSelectedNodeKey(node.key), children: node.children ? convertTreeToMenuItems(node.children) : [], } } @@ -296,6 +299,7 @@ function ProjectSharePage() { const openSharedFile = (key) => { setSelectedFile(key) + setSelectedNodeKey(key) const parts = key.split('/') const allParentPaths = [] @@ -346,7 +350,10 @@ function ProjectSharePage() { window.open(exportProjectSharePDF(shareCode, selectedFile), '_blank') } - const menuItems = useMemo(() => convertTreeToMenuItems(filteredTreeData), [filteredTreeData]) + const menuItems = useMemo( + () => convertTreeToMenuItems(filteredTreeData), + [filteredTreeData, openKeys] + ) return (
@@ -391,7 +398,7 @@ function ProjectSharePage() { {menuItems.length > 0 ? ( 0 ? ( handleOpenProject(project.id)} actions={type === 'my' ? [ - handleEdit(e, project)} />, + handleEdit(e, project)} />, handleGitSettings(e, project)} />, handleMembers(e, project)} />, ] : [