导航与组织(中文译文)
原始 DeepWiki 页面:https://deepwiki.com/open-webui/open-webui/8-navigation-and-organization
翻译时间:2026-06-09T16:09:30.515Z
翻译模型:deepseek-chat
原文字符数:12099
项目:Open WebUI (open-webui)
--- T2f46,
导航与组织
相关源文件
以下文件被用作生成此 wiki 页面的上下文:
src/lib/components/chat/Tags.sveltesrc/lib/components/common/ConfirmDialog.sveltesrc/lib/components/common/DragGhost.sveltesrc/lib/components/common/Dropdown.sveltesrc/lib/components/common/Folder.sveltesrc/lib/components/layout/Navbar/Menu.sveltesrc/lib/components/layout/Sidebar.sveltesrc/lib/components/layout/Sidebar/ChatItem.sveltesrc/lib/components/layout/Sidebar/ChatMenu.sveltesrc/lib/components/layout/Sidebar/Folders.sveltesrc/lib/components/layout/Sidebar/Folders/FolderMenu.sveltesrc/lib/components/layout/Sidebar/RecursiveFolder.svelte
本文档介绍 Open WebUI 的导航与组织系统。该系统通过层级化侧边栏,让用户将聊天记录整理到文件夹中、置顶重要对话以及访问频道。系统支持无限层级的文件夹嵌套、拖放式组织以及持久化的展开状态。
关于聊天界面本身,请参阅聊天系统。关于侧边栏内的搜索功能,请参阅聊天组件架构。关于与他人共享聊天记录,请参阅用户菜单与个人资料。
目的与范围
导航与组织系统包含以下部分:
- 侧边栏组件:主导航容器,包含可折叠区域
src/lib/components/layout/Sidebar.svelte:1-137。 - 文件夹系统:支持拖放的递归文件夹层级结构
src/lib/components/layout/Sidebar/RecursiveFolder.svelte:1-62。 - 聊天项:单个聊天条目,带有上下文菜单和操作
src/lib/components/layout/Sidebar/ChatItem.svelte:1-106。 - 置顶项:用于置顶对话、笔记和模型的特殊区域
src/lib/components/layout/Sidebar.svelte:19-20。 - 频道:用于群组和直接消息的团队协作空间
src/lib/components/layout/Sidebar.svelte:64-66。 - 拖放:通过浏览器原生拖放事件组织聊天和文件夹
src/lib/components/layout/Sidebar/ChatItem.svelte:245-257。 - 用户菜单:个人资料管理和设置访问
src/lib/components/layout/Sidebar/UserMenu.svelte:1-325。
该系统主要在前端使用 Svelte 组件实现,并通过文件夹和聊天 API 进行持久化。
组件层级
侧边栏导航遵循清晰的父子关系层级化组件结构:
侧边栏组件层级
graph TB
Sidebar["Sidebar.svelte<br/>(主容器)"]
subgraph "顶部区域"
NewChat["新建聊天按钮"]
Search["Search.svelte<br/>(图标/按钮)"]
Notes["Note.svelte<br/>(图标/链接)"]
end
subgraph "内容区域"
PinnedModels["PinnedModelList.svelte<br/>(如果有置顶模型)"]
Channels["Folder.svelte<br/>(频道容器)"]
ChannelItem["ChannelItem.svelte"]
FoldersSection["Folder.svelte<br/>(文件夹容器)"]
ChatsSection["Folder.svelte<br/>(聊天容器)"]
end
subgraph "文件夹区域详情"
Folders["Folders.svelte<br/>(逻辑容器)"]
RecursiveFolder["RecursiveFolder.svelte<br/>(自引用)"]
FolderChats["ChatItem.svelte<br/>(嵌套)"]
end
subgraph "底部区域"
UserMenu["UserMenu.svelte<br/>(个人资料/设置)"]
end
Sidebar --> NewChat
Sidebar --> Search
Sidebar --> Notes
Sidebar --> PinnedModels
Sidebar --> Channels
Channels --> ChannelItem
Sidebar --> FoldersSection
Sidebar --> ChatsSection
Sidebar --> UserMenu
FoldersSection --> Folders
Folders --> RecursiveFolder
RecursiveFolder --> RecursiveFolder
RecursiveFolder --> FolderChats
来源:src/lib/components/layout/Sidebar.svelte:56-75、src/lib/components/layout/Sidebar/Folders.svelte:1-63、src/lib/components/layout/Sidebar/RecursiveFolder.svelte:1-45
文件夹初始化算法
文件夹系统在 initFolders 中使用两遍初始化算法,从通过 getFolders 从后端获取的扁平列表构建层级结构 src/lib/apis/folders:49。
文件夹初始化数据流
graph TD
Start["initFolders()"]
Fetch["getFolders()<br/>API 调用"]
Sort["按 updated_at 排序"]
subgraph "第一遍:扁平注册表"
CreateEntry["folders[id] = folder_data"]
MarkNew["标记 .new = true<br/>(如果刚创建)"]
end
subgraph "第二遍:树结构构建"
HasParent["有 parent_id?"]
LinkChild["parent.childrenIds.push(id)"]
SortChildren["按 updated_at 排序 childrenIds"]
end
Done["folders 对象已填充"]
Start --> Fetch
Fetch --> Sort
Sort --> CreateEntry
CreateEntry --> MarkNew
MarkNew --> HasParent
HasParent -->|是| LinkChild
LinkChild --> SortChildren
SortChildren --> Done
HasParent -->|否| Done
该实现确保子文件夹在本地 folders 状态对象中正确嵌套在其父文件夹下 src/lib/components/layout/Sidebar.svelte:175-217。
来源:src/lib/components/layout/Sidebar.svelte:175-217、src/lib/apis/folders:49
文件夹注册表模式
系统使用 folderRegistry 模式,允许主 Sidebar 与深层嵌套的 RecursiveFolder 组件之间进行通信,而无需过度传递 props。
文件夹注册表通信
graph LR
Sidebar["Sidebar.svelte<br/>{folderRegistry}"]
Folders["Folders.svelte"]
RecFolder["RecursiveFolder.svelte"]
subgraph "注册"
Mount["onMount()"]
Register["folderRegistry[id] = { setFolderItems }"]
end
subgraph "更新触发"
Move["聊天移动事件"]
Call["folderRegistry[id].setFolderItems()"]
end
Sidebar -->|bind| Folders
Folders -->|bind| RecFolder
RecFolder --> Mount
Mount --> Register
Move --> Call
每个 RecursiveFolder 在注册表中注册一个 setFolderItems 方法 src/lib/components/layout/Sidebar/RecursiveFolder.svelte:257-261。当聊天被移动或导入时,Sidebar 或父文件夹组件可以触发特定文件夹的刷新 src/lib/components/layout/Sidebar/Folders.svelte:26-30。
来源:src/lib/components/layout/Sidebar/RecursiveFolder.svelte:257-261、src/lib/components/layout/Sidebar/Folders.svelte:8-36
拖放系统
Open WebUI 实现了原生 HTML5 拖放系统,用于组织聊天和文件夹。
拖放实体映射
| UI 操作 | 代码实体 | 逻辑 |
|---|---|---|
| 开始拖拽聊天 | ChatItem.svelte | onDragStart 设置 text/plain 为 JSON {type: 'chat', id: id} src/lib/components/layout/Sidebar/ChatItem.svelte:245-257。 |
| 开始拖拽文件夹 | RecursiveFolder.svelte | onDragStart 设置 text/plain 为 JSON {type: 'folder', id: id} src/lib/components/layout/Sidebar/RecursiveFolder.svelte:224-239。 |
| 拖放到文件夹 | RecursiveFolder.svelte | onDrop 解析数据。调用 updateChatFolderIdById 或 updateFolderParentIdById src/lib/components/layout/Sidebar/RecursiveFolder.svelte:87-206。 |
| 拖放文件 (JSON) | RecursiveFolder.svelte | onDrop 通过 FileReader 读取 application/json 文件,并调用 importChats src/lib/components/layout/Sidebar/RecursiveFolder.svelte:101-127。 |
为了提供干净的 UI,系统使用一个透明的 1x1 像素占位符 invisibleDragImage 来抑制浏览器默认的拖拽图像 src/lib/components/layout/Sidebar/ChatItem.svelte:3-5,并使用自定义的 DragGhost.svelte 组件提供视觉反馈 src/lib/components/common/DragGhost.svelte:1-38。
来源:src/lib/components/layout/Sidebar/ChatItem.svelte:3-5、src/lib/components/layout/Sidebar/ChatItem.svelte:245-257、src/lib/components/layout/Sidebar/RecursiveFolder.svelte:87-206、src/lib/components/layout/Sidebar/RecursiveFolder.svelte:224-239、src/lib/components/common/DragGhost.svelte:1-38
聊天管理
ChatItem 组件处理单个对话条目,通过 ChatMenu.svelte 提供丰富的上下文菜单进行管理。
聊天操作管道
graph TD
User["用户交互"]
Menu["ChatMenu.svelte"]
Item["ChatItem.svelte"]
subgraph "操作"
Rename["editChatTitle()"]
Clone["cloneChatHandler()"]
Archive["archiveChatHandler()"]
Delete["deleteChatHandler()"]
Pin["pinHandler()"]
end
subgraph "API"
ChatAPI["chats.ts API"]
end
User -->|点击| Menu
User -->|双击| Item
Menu --> Pin
Menu --> Clone
Item --> Rename
Pin --> ChatAPI
Clone --> ChatAPI
Archive --> ChatAPI
Delete --> ChatAPI
主要功能包括:
- 标题生成:使用
generateTitleAPI 根据内容自动命名聊天src/lib/components/layout/Sidebar/ChatItem.svelte:53。 - 克隆:使用
cloneChatById创建聊天的副本src/lib/components/layout/Sidebar/ChatItem.svelte:140-159。 - 标签:与
Tags.svelte集成,实现语义化组织src/lib/components/chat/Tags.svelte:1-86。 - 未读状态:通过比较
updatedAt与effectiveReadAt来跟踪未读消息src/lib/components/layout/Sidebar/ChatItem.svelte:102-105。
来源:src/lib/components/layout/Sidebar/ChatItem.svelte:53、src/lib/components/layout/Sidebar/ChatItem.svelte:140-159、src/lib/components/layout/Sidebar/ChatItem.svelte:163-185、src/lib/components/layout/Sidebar/ChatItem.svelte:189-209、src/lib/components/layout/Sidebar/ChatMenu.svelte:51-54、src/lib/components/chat/Tags.svelte:1-86
用户菜单与个人资料
位于侧边栏底部的 UserMenu 组件,是执行账户级操作和访问设置的入口。
- 状态管理:用户可以设置自定义状态消息和表情符号
src/lib/components/layout/Sidebar/UserMenu.svelte:1-325。 - 设置访问:触发全局
showSettingsstore 以打开设置模态框src/lib/components/layout/Sidebar.svelte:11。 - 导航项:根据用户权限和功能标志动态显示/隐藏“笔记”、“工作区”、“自动化”和“日历”等项
src/lib/components/layout/Sidebar.svelte:109-139。 - 菜单自定义:支持通过
SortableJS重新排序置顶菜单项src/lib/components/layout/Sidebar.svelte:152-169。
来源:src/lib/components/layout/Sidebar.svelte:109-169、src/lib/components/layout/Sidebar/UserMenu.svelte:1-325
子页面
有关特定导航子系统的详细技术文档,请参阅以下页面: