From 73cdf5ac23b19a0e37c02b611105882e223579ee Mon Sep 17 00:00:00 2001 From: "shen893514322@126.com" Date: Thu, 19 Mar 2026 23:48:44 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=BB=E5=8F=96=E6=9C=AC=E5=9C=B0chatandrole?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=B9=B6=E4=BC=98=E5=8C=96=E6=8E=92=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/ToolBar/ToolBar.css | 581 ++++++++++++++---- .../src/components/ToolBar/ToolBar.jsx | 539 +++++++++++++--- 2 files changed, 908 insertions(+), 212 deletions(-) diff --git a/frontend-react/src/components/ToolBar/ToolBar.css b/frontend-react/src/components/ToolBar/ToolBar.css index d23497f..a24c855 100644 --- a/frontend-react/src/components/ToolBar/ToolBar.css +++ b/frontend-react/src/components/ToolBar/ToolBar.css @@ -12,16 +12,24 @@ display: flex; align-items: center; padding: 0 20px; - justify-content: flex-start; /* 确保内容从左到右排列 */ + justify-content: space-between; transition: all 0.3s ease; } +/* 工具栏主要部分容器 */ +.toolbar-section { + display: flex; + align-items: center; + gap: 15px; + flex: 1; +} + /* 工具栏图标容器 */ .toolbar-icons { display: flex; align-items: center; gap: 15px; - margin-right: auto; /* 添加这行,确保图标靠左 */ + flex: 1; } /* 工具栏图标 */ @@ -46,162 +54,485 @@ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } -/* ==================== 下拉框样式 ==================== */ - -/* 工具栏下拉框容器 */ -.toolbar-dropdown { - margin-bottom: 10px; +.toolbar-icon.active { + background-color: #1890ff; + color: #fff; } -.toolbar-dropdown label { - display: block; - margin-bottom: 5px; - font-size: 13px; - color: #333; - font-weight: 500; -} +/* ==================== 弹出面板样式 ==================== */ -/* 下拉框容器 */ -.dropdown-container { - position: relative; -} - -/* 下拉框触发器 */ -.dropdown-trigger { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 12px; - background-color: #fff; - border: 1px solid #e0e0e0; - border-radius: 6px; - cursor: pointer; - font-size: 13px; - transition: all 0.2s ease; - box-shadow: 0 1px 3px rgba(0,0,0,0.05); -} - -.dropdown-trigger:hover { - border-color: #1890ff; - box-shadow: 0 2px 6px rgba(0,0,0,0.1); -} - -.dropdown-arrow { - margin-left: 8px; - font-size: 10px; - transition: transform 0.2s ease; -} - -.dropdown-trigger.open .dropdown-arrow { - transform: rotate(180deg); -} - -/* 下拉菜单 */ -.dropdown-menu { - position: absolute; - top: 100%; +.panel-overlay { + position: fixed; + top: 50px; left: 0; - min-width: 180px; - background-color: white; - border: 1px solid #e0e0e0; - border-radius: 6px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); - z-index: 1001; - margin-top: 8px; - padding: 5px 0; - opacity: 0; - transform: translateY(-10px); - transition: opacity 0.2s ease, transform 0.2s ease; - pointer-events: none; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.3); + z-index: 999; + display: flex; + justify-content: center; + padding-top: 20px; + animation: fadeIn 0.2s ease; } -.dropdown-menu.visible { - opacity: 1; - transform: translateY(0); - pointer-events: auto; +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } } -/* 下拉菜单项 */ -.dropdown-item { - padding: 10px 15px; - cursor: pointer; - position: relative; - font-size: 14px; - transition: background-color 0.2s ease; +.panel-content { + background-color: #fff; + border-radius: 8px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); + width: 90%; + max-width: 1200px; + max-height: calc(100vh - 80px); + overflow: hidden; + display: flex; + flex-direction: column; + animation: slideDown 0.3s ease; +} + +@keyframes slideDown { + from { + transform: translateY(-20px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +.panel-header { + padding: 16px 20px; + border-bottom: 1px solid #e0e0e0; display: flex; justify-content: space-between; align-items: center; + background-color: #fafafa; } -.dropdown-item:hover { - background-color: #f5f5f5; -} - -.dropdown-item.selected { - background-color: #e6f7ff; - color: #1890ff; +.panel-header h3 { + margin: 0; + font-size: 16px; font-weight: 500; + color: #333; } -/* 嵌套下拉框 */ -.nested-dropdown { - position: absolute; - left: 100%; - top: 0; - min-width: 180px; - background-color: white; +.current-info { + display: flex; + gap: 20px; + font-size: 13px; + color: #666; +} + +.panel-body { + padding: 20px; + overflow-y: auto; + flex: 1; +} + +/* ==================== 角色面板样式 ==================== */ + +.role-panel { + max-width: 1200px; +} + +.panel-controls { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; +} + +.search-box { + flex: 1; + margin-right: 16px; +} + +.search-box input { + width: 100%; + padding: 10px 16px; border: 1px solid #e0e0e0; border-radius: 6px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); - z-index: 1002; - margin-left: 5px; - padding: 5px 0; - opacity: 0; - transform: translateX(-10px); - transition: opacity 0.2s ease, transform 0.2s ease; - pointer-events: none; - /* 移除滚动条相关设置,让下拉框根据内容自动扩展 */ + font-size: 14px; + transition: border-color 0.2s ease; } -.nested-dropdown.visible { - opacity: 1; - transform: translateX(0); - pointer-events: auto; +.search-box input:focus { + outline: none; + border-color: #1890ff; + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1); } -/* 添加指示箭头 */ -.dropdown-item.has-children::after { - content: '›'; - font-size: 18px; - color: #999; - margin-left: 8px; - font-weight: 300; -} - -.dropdown-item.selected.has-children::after { - color: #1890ff; -} - -/* 主内容区域 */ -.main-container { - margin-top: 50px; /* 为固定工具栏留出空间 */ - height: calc(100vh - 50px); +.add-button { display: flex; - overflow: hidden; + align-items: center; + gap: 6px; + padding: 10px 20px; + background-color: #1890ff; + color: white; + border: none; + border-radius: 6px; + cursor: pointer; + font-size: 14px; + transition: all 0.2s ease; +} + +.add-button:hover { + background-color: #40a9ff; + transform: translateY(-1px); + box-shadow: 0 2px 6px rgba(24, 144, 255, 0.2); +} + +.add-button .icon { + font-size: 16px; + font-weight: bold; +} + +.panel-list-container { + display: flex; + flex-direction: column; + height: calc(100% - 80px); +} + +.loading-container { + display: flex; + align-items: center; + justify-content: center; + padding: 40px; + gap: 12px; + color: #666; } -/* 加载动画 */ .loading-spinner { display: inline-block; - width: 16px; - height: 16px; + width: 20px; + height: 20px; border: 2px solid rgba(24, 144, 255, 0.2); border-radius: 50%; border-top-color: #1890ff; animation: spin 1s ease-in-out infinite; - margin-right: 8px; } @keyframes spin { to { transform: rotate(360deg); } } + +.empty-state { + display: flex; + align-items: center; + justify-content: center; + padding: 40px; + color: #999; +} + +/* ==================== 角色卡片网格布局 ==================== */ + +.role-cards-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; +} + +/* ==================== 角色卡片样式 ==================== */ + +.role-card { + border-radius: 8px; + cursor: pointer; + position: relative; + transition: all 0.2s ease; + background-color: #fff; + border: 1px solid #e0e0e0; + display: flex; + flex-direction: column; + overflow: hidden; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.role-card:hover { + background-color: #f5f5f5; + border-color: #1890ff; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + transform: translateY(-2px); +} + +.role-card.selected { + background-color: #e6f7ff; + border-color: #1890ff; + box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2); +} + +.role-card-header { + padding: 16px; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #f0f0f0; +} + +.role-name { + font-size: 15px; + color: #333; + font-weight: 500; +} + +.role-card.selected .role-name { + color: #1890ff; +} + +.role-chat-count { + font-size: 12px; + color: #999; + background-color: #f0f0f0; + padding: 4px 10px; + border-radius: 12px; +} + +.role-card-actions { + display: flex; + justify-content: flex-end; + padding: 8px 12px; + opacity: 0; + transition: opacity 0.2s ease; +} + +.role-card:hover .role-card-actions, +.role-card.clicked .role-card-actions { + opacity: 1; +} + +.action-button { + width: 28px; + height: 28px; + border-radius: 4px; + border: none; + background-color: #f5f5f5; + color: #666; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + transition: all 0.2s ease; +} + +.action-button:hover { + background-color: #e6f7ff; + color: #1890ff; +} + +.edit-button:hover { + background-color: #e6f7ff; + color: #1890ff; +} + +.delete-button:hover { + background-color: #fff1f0; + color: #ff4d4f; +} + +.role-card-header input { + padding: 6px 10px; + border: 1px solid #d9d9d9; + border-radius: 4px; + font-size: 14px; + width: 150px; +} + +.role-card-header input:focus { + outline: none; + border-color: #1890ff; + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1); +} + +/* ==================== 聊天列表样式 ==================== */ + +.chat-list { + margin-top: 0; + border-top: 1px solid #e0e0e0; + padding: 12px; + background-color: #fafafa; + animation: slideDown 0.2s ease; + max-height: 300px; + overflow-y: auto; +} + +.chat-list-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 0; + border-bottom: 1px solid #e0e0e0; + margin-bottom: 8px; +} + +.chat-list-header span { + font-size: 13px; + font-weight: 500; + color: #333; +} + +.add-chat-button { + display: flex; + align-items: center; + gap: 4px; + padding: 4px 10px; + background-color: #1890ff; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 12px; + transition: all 0.2s ease; +} + +.add-chat-button:hover { + background-color: #40a9ff; +} + +.add-chat-button .icon { + font-size: 14px; + font-weight: bold; +} + +.chat-item { + padding: 10px 12px; + cursor: pointer; + transition: background-color 0.2s ease; + display: flex; + justify-content: space-between; + align-items: center; + border-radius: 4px; + margin-bottom: 4px; +} + +.chat-item:hover { + background-color: #f0f0f0; +} + +.chat-item.selected { + background-color: #e6f7ff; + color: #1890ff; +} + +.chat-name { + font-size: 13px; + color: #333; +} + +.chat-item.selected .chat-name { + color: #1890ff; + font-weight: 500; +} + +.chat-actions { + display: flex; + gap: 6px; + opacity: 0; + transition: opacity 0.2s ease; +} + +.chat-item:hover .chat-actions { + opacity: 1; +} + +.chat-content input { + padding: 6px 10px; + border: 1px solid #d9d9d9; + border-radius: 4px; + font-size: 13px; + width: 180px; +} + +.chat-content input:focus { + outline: none; + border-color: #1890ff; + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1); +} + +/* ==================== 模态框样式 ==================== */ + +.modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + z-index: 2000; + display: flex; + align-items: center; + justify-content: center; + animation: fadeIn 0.2s ease; +} + +.modal-content { + background-color: #fff; + border-radius: 8px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); + width: 90%; + max-width: 400px; + padding: 24px; + animation: slideDown 0.3s ease; +} + +.modal-content h3 { + margin: 0 0 16px 0; + font-size: 16px; + font-weight: 500; + color: #333; +} + +.modal-content p { + margin: 0 0 24px 0; + font-size: 14px; + color: #666; +} + +.modal-actions { + display: flex; + justify-content: flex-end; + gap: 12px; +} + +.modal-button { + padding: 8px 16px; + border-radius: 4px; + font-size: 14px; + cursor: pointer; + transition: all 0.2s ease; + border: none; +} + +.cancel-button { + background-color: #f5f5f5; + color: #666; +} + +.cancel-button:hover { + background-color: #e6e6e6; + color: #333; +} + +.confirm-button { + background-color: #ff4d4f; + color: white; +} + +.confirm-button:hover { + background-color: #ff7875; +} + +/* 主内容区域 */ +.main-container { + margin-top: 50px; + height: calc(100vh - 50px); + display: flex; + overflow: hidden; +} diff --git a/frontend-react/src/components/ToolBar/ToolBar.jsx b/frontend-react/src/components/ToolBar/ToolBar.jsx index 7fae928..1d1eb8f 100644 --- a/frontend-react/src/components/ToolBar/ToolBar.jsx +++ b/frontend-react/src/components/ToolBar/ToolBar.jsx @@ -7,11 +7,17 @@ const Toolbar = ({ }) => { const [selectedRole, setSelectedRole] = useState(null); const [selectedChat, setSelectedChat] = useState(null); - const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const [activePanel, setActivePanel] = useState(null); const [roleData, setRoleData] = useState({}); const [hoveredRole, setHoveredRole] = useState(null); + const [clickedRole, setClickedRole] = useState(null); const [isLoading, setIsLoading] = useState(false); - const dropdownRef = useRef(null); + const [searchTerm, setSearchTerm] = useState(''); + const [editingRole, setEditingRole] = useState(null); + const [editingChat, setEditingChat] = useState(null); + const [showDeleteConfirm, setShowDeleteConfirm] = useState(null); + const [deleteType, setDeleteType] = useState(null); + const panelRef = useRef(null); // 获取角色和聊天数据 const fetchRoleData = async () => { @@ -37,12 +43,16 @@ const Toolbar = ({ } }; - // 点击外部关闭下拉菜单 + // 点击外部关闭面板 useEffect(() => { const handleClickOutside = (event) => { - if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { - setIsDropdownOpen(false); + if (panelRef.current && !panelRef.current.contains(event.target)) { + setActivePanel(null); setHoveredRole(null); + setClickedRole(null); + setEditingRole(null); + setEditingChat(null); + setShowDeleteConfirm(null); } }; @@ -52,11 +62,16 @@ const Toolbar = ({ }; }, []); - // 处理下拉框展开/收起 - const handleDropdownToggle = () => { - // 每次点击都重新获取数据 - fetchRoleData(); - setIsDropdownOpen(!isDropdownOpen); + // 处理面板切换 + const handlePanelToggle = (panelName) => { + if (activePanel === panelName) { + setActivePanel(null); + } else { + if (panelName === 'role') { + fetchRoleData(); + } + setActivePanel(panelName); + } }; // 处理角色选择 @@ -81,104 +96,454 @@ const Toolbar = ({ // 处理聊天选择 const handleChatSelect = (chat) => { setSelectedChat(chat); - setIsDropdownOpen(false); + setActivePanel(null); setHoveredRole(null); + setClickedRole(null); if (onChatChange) { onChatChange(selectedRole, chat); } }; - // 处理角色项悬停 - const handleRoleHover = (role) => { - setHoveredRole(role); + // 处理角色卡片点击 + const handleRoleCardClick = (role) => { + if (clickedRole === role) { + setClickedRole(null); + } else { + setClickedRole(role); + handleRoleSelect(role); + } }; - // 处理角色项离开 - const handleRoleLeave = () => { - // 不立即清除hoveredRole,以便用户可以移动到二级菜单 + // 处理搜索 + const handleSearchChange = (e) => { + setSearchTerm(e.target.value); }; - // 处理二级菜单进入 - const handleNestedMenuEnter = () => { - // 防止鼠标移动时菜单消失 + // 处理角色编辑 + const handleEditRole = (e, role) => { + e.stopPropagation(); + setEditingRole(role); }; - // 处理二级菜单离开 - const handleNestedMenuLeave = () => { - setHoveredRole(null); + // 处理角色重命名 + const handleRenameRole = (e, oldName) => { + e.stopPropagation(); + const newName = e.target.value; + if (newName && newName !== oldName) { + // 这里应该调用API更新角色名 + console.log('重命名角色:', oldName, '->', newName); + + // 更新本地状态 + const newRoleData = { ...roleData }; + const chats = newRoleData[oldName]; + delete newRoleData[oldName]; + newRoleData[newName] = chats; + setRoleData(newRoleData); + + // 如果当前选中的是被重命名的角色,更新选中状态 + if (selectedRole === oldName) { + setSelectedRole(newName); + if (onRoleChange) { + onRoleChange(newName); + } + } + } + setEditingRole(null); }; + // 处理聊天编辑 + const handleEditChat = (e, chat) => { + e.stopPropagation(); + setEditingChat(chat); + }; + + // 处理聊天重命名 + const handleRenameChat = (e, oldName) => { + e.stopPropagation(); + const newName = e.target.value; + if (newName && newName !== oldName) { + // 这里应该调用API更新聊天名 + console.log('重命名聊天:', oldName, '->', newName); + + // 更新本地状态 + const newRoleData = { ...roleData }; + const chatIndex = newRoleData[selectedRole].indexOf(oldName); + if (chatIndex !== -1) { + newRoleData[selectedRole][chatIndex] = newName; + setRoleData(newRoleData); + + // 如果当前选中的是被重命名的聊天,更新选中状态 + if (selectedChat === oldName) { + setSelectedChat(newName); + if (onChatChange) { + onChatChange(selectedRole, newName); + } + } + } + } + setEditingChat(null); + }; + + // 处理删除确认 + const handleDeleteClick = (e, type, name) => { + e.stopPropagation(); + setDeleteType(type); + setShowDeleteConfirm(name); + }; + + // 确认删除 + const confirmDelete = () => { + if (deleteType === 'role') { + // 这里应该调用API删除角色 + console.log('删除角色:', showDeleteConfirm); + + // 更新本地状态 + const newRoleData = { ...roleData }; + delete newRoleData[showDeleteConfirm]; + setRoleData(newRoleData); + + // 如果删除的是当前选中的角色,清空选中状态 + if (selectedRole === showDeleteConfirm) { + setSelectedRole(null); + setSelectedChat(null); + if (onRoleChange) { + onRoleChange(null); + } + } + } else if (deleteType === 'chat') { + // 这里应该调用API删除聊天 + console.log('删除聊天:', showDeleteConfirm); + + // 更新本地状态 + const newRoleData = { ...roleData }; + const chatIndex = newRoleData[selectedRole].indexOf(showDeleteConfirm); + if (chatIndex !== -1) { + newRoleData[selectedRole].splice(chatIndex, 1); + setRoleData(newRoleData); + + // 如果删除的是当前选中的聊天,清空选中状态 + if (selectedChat === showDeleteConfirm) { + setSelectedChat(null); + if (onChatChange) { + onChatChange(selectedRole, null); + } + } + } + } + setShowDeleteConfirm(null); + setDeleteType(null); + }; + + // 取消删除 + const cancelDelete = () => { + setShowDeleteConfirm(null); + setDeleteType(null); + }; + + // 处理新增角色 + const handleAddRole = () => { + // 这里应该调用API创建新角色 + const newRole = '新角色'; + console.log('创建新角色:', newRole); + + // 更新本地状态 + const newRoleData = { ...roleData }; + newRoleData[newRole] = []; + setRoleData(newRoleData); + + // 自动进入编辑模式 + setEditingRole(newRole); + }; + + // 处理新增聊天 + const handleAddChat = () => { + if (!selectedRole) return; + + // 这里应该调用API创建新聊天 + const newChat = '新聊天'; + console.log('创建新聊天:', newChat); + + // 更新本地状态 + const newRoleData = { ...roleData }; + newRoleData[selectedRole].push(newChat); + setRoleData(newRoleData); + + // 自动进入编辑模式 + setEditingChat(newChat); + }; + + // 过滤角色 + const filteredRoles = Object.keys(roleData).filter(role => + role.toLowerCase().includes(searchTerm.toLowerCase()) + ); + return ( -
-
- {/* Logo图标 */} -
- 🤖 -
- - {/* 角色选择下拉框 */} -
-
- 👤 -
- - {isDropdownOpen && ( -
- {isLoading ? ( -
- 加载中... -
- ) : ( - Object.keys(roleData).map(role => ( -
0 ? 'has-children' : ''}`} - onClick={() => handleRoleSelect(role)} - onMouseEnter={() => handleRoleHover(role)} - onMouseLeave={handleRoleLeave} - > - {role} - {/* 当悬停在角色上时显示二级菜单 */} - {hoveredRole === role && roleData[role] && roleData[role].length > 0 && ( -
- {roleData[role].map(chat => ( -
{ - e.stopPropagation(); - handleChatSelect(chat); - }} - > - {chat} -
- ))} -
- )} -
- )) - )} + <> +
+ {/* 左侧工具栏图标 */} +
+
+ {/* Logo图标 */} +
handlePanelToggle(null)} + > + 🤖
- )} +
- {/* 其他工具栏图标 */} -
- ⚙️ + {/* 中间操作图标 */} +
+
+ {/* 角色选择图标 */} +
handlePanelToggle('role')} + > + 👤 +
+
-
- ❓ + + {/* 右侧工具栏图标 */} +
+
+
handlePanelToggle('settings')} + > + ⚙️ +
+
handlePanelToggle('help')} + > + ❓ +
+
-
+ + {/* 角色管理面板 */} + {activePanel === 'role' && ( +
+
+
+

角色管理

+
+ 当前角色: {selectedRole || '未选择'} + 当前聊天: {selectedChat || '未选择'} +
+
+ +
+
+
+ +
+ +
+ +
+ {isLoading ? ( +
+
+ 加载中... +
+ ) : filteredRoles.length === 0 ? ( +
+

没有找到匹配的角色

+
+ ) : ( +
+ {filteredRoles.map(role => ( +
handleRoleCardClick(role)} + onMouseEnter={() => setHoveredRole(role)} + onMouseLeave={() => setHoveredRole(null)} + > +
+ {editingRole === role ? ( + handleRenameRole(e, role)} + onKeyDown={(e) => { + if (e.key === 'Enter') { + handleRenameRole(e, role); + } + }} + onClick={(e) => e.stopPropagation()} + /> + ) : ( +
{role}
+ )} + +
+ {roleData[role] ? roleData[role].length : 0} 个聊天 +
+
+ +
+ {editingRole !== role && ( + <> + + + + )} +
+ + {/* 聊天列表 */} + {(hoveredRole === role || clickedRole === role) && roleData[role] && roleData[role].length > 0 && ( +
+
+ 聊天记录 + +
+ + {roleData[role].map(chat => ( +
{ + e.stopPropagation(); + handleChatSelect(chat); + }} + > +
+ {editingChat === chat ? ( + handleRenameChat(e, chat)} + onKeyDown={(e) => { + if (e.key === 'Enter') { + handleRenameChat(e, chat); + } + }} + onClick={(e) => e.stopPropagation()} + /> + ) : ( +
{chat}
+ )} +
+ +
+ {editingChat !== chat && ( + <> + + + + )} +
+
+ ))} +
+ )} +
+ ))} +
+ )} +
+
+
+
+ )} + + {/* 删除确认对话框 */} + {showDeleteConfirm && ( +
+
+

确认删除

+

确定要删除{deleteType === 'role' ? '角色' : '聊天'} "{showDeleteConfirm}" 吗?

+
+ + +
+
+
+ )} + + {activePanel === 'settings' && ( +
+
+
+

设置

+
+
+

设置内容...

+
+
+
+ )} + + {activePanel === 'help' && ( +
+
+
+

帮助

+
+
+

帮助内容...

+
+
+
+ )} + ); };