From 5d41339c4a69fae69598f722ec17823a6a2d20a7 Mon Sep 17 00:00:00 2001 From: "mula.liu" Date: Mon, 31 Aug 2026 18:32:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MainLayout/MainLayout.jsx | 16 ++++++++++- frontend/src/pages/Document/DocumentPage.css | 27 ------------------- frontend/src/pages/Document/DocumentPage.jsx | 20 ++------------ .../src/pages/ProjectList/ProjectList.jsx | 14 ++++++---- 4 files changed, 26 insertions(+), 51 deletions(-) diff --git a/frontend/src/components/MainLayout/MainLayout.jsx b/frontend/src/components/MainLayout/MainLayout.jsx index 1d26601..1685edd 100644 --- a/frontend/src/components/MainLayout/MainLayout.jsx +++ b/frontend/src/components/MainLayout/MainLayout.jsx @@ -1,13 +1,27 @@ -import { useState } from 'react' +import { useState, useEffect } from 'react' import { Layout } from 'antd' +import { useLocation } from 'react-router-dom' import AppSider from './AppSider' import AppHeader from './AppHeader' import './MainLayout.css' const { Content } = Layout +// 项目详情页路由(浏览 / 编辑) +const isProjectDetailPath = (pathname) => { + return /^\/projects\/[^/]+\/(docs|editor)(\/|$)/.test(pathname) +} + function MainLayout({ children }) { const [collapsed, setCollapsed] = useState(true) + const location = useLocation() + + // 进入项目详情页时,若左侧主菜单栏处于展开状态则自动收起 + useEffect(() => { + if (isProjectDetailPath(location.pathname)) { + setCollapsed(true) + } + }, [location.pathname]) const toggleCollapsed = () => { setCollapsed(!collapsed) diff --git a/frontend/src/pages/Document/DocumentPage.css b/frontend/src/pages/Document/DocumentPage.css index 67098af..f39f45c 100644 --- a/frontend/src/pages/Document/DocumentPage.css +++ b/frontend/src/pages/Document/DocumentPage.css @@ -28,33 +28,6 @@ height: 100%; } -/* 侧栏收起时:左侧悬浮展开按钮 */ -.docs-sider-expand-btn { - position: fixed; - left: 12px; - top: 50%; - transform: translateY(-50%); - z-index: 30; - width: 32px; - height: 48px; - border-radius: 8px; - border: 1px solid var(--border-color); - background: var(--header-bg); - color: var(--text-color-secondary); - font-size: 16px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); - transition: color 0.2s ease, border-color 0.2s ease; -} - -.docs-sider-expand-btn:hover { - color: var(--link-color); - border-color: var(--link-color); -} - .docs-sider-header { padding: 12px 10px 12px; border-bottom: 1px solid var(--border-color); diff --git a/frontend/src/pages/Document/DocumentPage.jsx b/frontend/src/pages/Document/DocumentPage.jsx index 4e2bf77..7202e08 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, Spin, Button, Tooltip, Modal, Input, Space, Dropdown, Empty, Switch, Select, TreeSelect, Radio, Alert } from 'antd' -import { ShareAltOutlined, FileTextOutlined, FolderOutlined, FolderOpenOutlined, FilePdfOutlined, CopyOutlined, CloudDownloadOutlined, CloudUploadOutlined, ArrowLeftOutlined, ReloadOutlined, VerticalAlignTopOutlined, MenuUnfoldOutlined } from '@ant-design/icons' +import { ShareAltOutlined, FileTextOutlined, FolderOutlined, FolderOpenOutlined, FilePdfOutlined, CopyOutlined, CloudDownloadOutlined, CloudUploadOutlined, ArrowLeftOutlined, ReloadOutlined, VerticalAlignTopOutlined } from '@ant-design/icons' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' import rehypeRaw from 'rehype-raw' @@ -61,7 +61,6 @@ function DocumentPage() { const [pdfUrl, setPdfUrl] = useState('') const [pdfFilename, setPdfFilename] = useState('') const [viewMode, setViewMode] = useState('markdown') - const [siderCollapsed, setSiderCollapsed] = useState(false) const [gitRepos, setGitRepos] = useState([]) // Git 同步范围弹窗状态 const [gitSyncModalVisible, setGitSyncModalVisible] = useState(false) @@ -132,7 +131,6 @@ function DocumentPage() { setMarkdownContent('') setTocItems([]) setViewMode('folder') - setSiderCollapsed(true) expandParentFolders(`${folderPath}/placeholder`) // 从内容区点击进入子文件夹时,同时展开自身,保证与左侧文件树同步 @@ -151,7 +149,6 @@ function DocumentPage() { setMarkdownContent('') setTocItems([]) setViewMode('folder') - setSiderCollapsed(true) setOpenKeys([]) if (syncUrl) { @@ -1262,7 +1259,7 @@ function DocumentPage() {
{/* 左侧目录 */} - +
- )} - {/* 右侧内容区 */} diff --git a/frontend/src/pages/ProjectList/ProjectList.jsx b/frontend/src/pages/ProjectList/ProjectList.jsx index b2b3434..81d47e9 100644 --- a/frontend/src/pages/ProjectList/ProjectList.jsx +++ b/frontend/src/pages/ProjectList/ProjectList.jsx @@ -44,10 +44,13 @@ function ProjectList({ type = 'my' }) { const [unreadByProject, setUnreadByProject] = useState({}) const pageSize = 8 + // 角色字段统一小写(兼容历史数据中的大小写差异) + const normalizeRole = (role) => String(role || '').trim().toLowerCase() + // 参与项目角色 -> 显示名称 const projectRoleLabel = (role) => { const roleMap = { admin: '管理员', editor: '编辑者', viewer: '查看者' } - return roleMap[role] || role || '查看者' + return roleMap[normalizeRole(role)] || role || '查看者' } // 成员管理弹窗角色显示名 @@ -112,13 +115,14 @@ function ProjectList({ type = 'my' }) { const cardRoleClass = (project) => { if (type === 'my') return 'role-owner' const roleMap = { admin: 'role-admin', editor: 'role-editor', viewer: 'role-viewer' } - return roleMap[project.user_role] || 'role-viewer' + return roleMap[normalizeRole(project.user_role)] || 'role-viewer' } // 卡片角色徽章图标 const cardRoleIcon = (project) => { - if (type === 'my' || project.user_role === 'admin') return - if (project.user_role === 'editor') return + const role = normalizeRole(project.user_role) + if (type === 'my' || role === 'admin') return + if (role === 'editor') return return } @@ -1183,7 +1187,7 @@ function ProjectList({ type = 'my' }) { return (