Files
zn-ai/SidebarToggleMigrationPlan.md
2026-04-14 07:36:40 +08:00

127 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ChatHistory 侧边栏折叠功能迁移计划
## 参考来源
- **源文件**: `ClawX/src/components/layout/Sidebar.tsx:234-247`
- **目标文件**: `zn-ai/src/pages/home/ChatHistory.vue:6`
## 源实现思路分析
`Sidebar.tsx:234-247` 的核心实现逻辑:
1. **状态驱动**: 通过 `useSettingsStore` 获取 `sidebarCollapsed` 布尔值与 `setSidebarCollapsed` setter。
2. **图标切换**: 点击按钮时,根据当前状态切换图标:
- 展开状态 → 显示 `PanelLeftClose`(提示可收起)
- 收起状态 → 显示 `PanelLeft`(提示可展开)
3. **样式过渡**: 外层 `aside` 通过 `transition-all duration-300` 配合条件类名 `w-16` / `w-64` 实现宽度动画。
4. **内容显隐**: 内部文字/列表在收起时隐藏(`!sidebarCollapsed && ...`),只保留图标按钮可点。
## 迁移目标
将上述折叠/展开交互迁移到 `ChatHistory.vue`,使其第 6 行的 `RiSideBarLine` 图标具备切换侧边栏宽度的能力,并保持与现有 `zn-ai` 项目风格一致。
## 实现步骤
### 1. 状态定义ChatHistory.vue 本地状态)
`<script setup>` 中新增响应式状态,无需引入全局 store当前页面无对应 store本地 ref 足够):
```ts
const sidebarCollapsed = ref(false)
```
### 2. 图标点击交互(对应目标文件第 6 行)
将现有静态图标改造为可点击切换状态:
```html
<!-- 修改前 -->
<RiSideBarLine class="ml-auto cursor-pointer" />
<!-- 修改后 -->
<RiSideBarLine
v-if="!sidebarCollapsed"
class="ml-auto cursor-pointer hover:text-[#2B7FFF]"
@click="sidebarCollapsed = true"
/>
<RiArrowRightSLine
v-else
class="ml-auto cursor-pointer hover:text-[#2B7FFF]"
@click="sidebarCollapsed = false"
/>
```
> 说明:
> - 展开时显示 `RiSideBarLine`(或 `RiSideBarFoldLine` 若项目已有),点击后收起。
> - 收起时显示 `RiArrowRightSLine`(或 `RiSideBarLine`),点击后展开。
> - 与源实现保持一致:图标根据状态互斥显示。
### 3. 容器宽度过渡动画
`<aside>` 根元素添加动态类名与过渡:
```html
<aside
:class="[
'h-full box-border flex flex-col transition-all duration-300',
sidebarCollapsed ? 'w-16' : 'w-50'
]"
>
```
- 展开宽度保持原设计 `w-50``200px`)。
- 收起宽度收缩为 `w-16``64px`),仅保留 Logo 与切换按钮空间。
- `transition-all duration-300` 保证宽度变化平滑。
### 4. 内部内容显隐控制
`sidebarCollapsed = true` 时,以下区域应隐藏:
- **YINIAN Logo 文字**(保留图片,隐藏文字,避免换行)
- **"新对话" 按钮文字**(可保留图标 `RiAddLine`,或整体隐藏按钮)
- **历史会话列表**`groups` 循环区域整体隐藏,避免窄边栏内文字截断)
具体修改点:
```html
<!-- Logo 区域 -->
<div class="flex items-center m-2">
<img class="w-10 h-10 rounded-md" src="@assets/images/login/white_logo.png" />
<div v-if="!sidebarCollapsed" class="font-bold text-gray-80">YINIAN</div>
<!-- 图标切换按钮 -->
...
</div>
<!-- 新对话按钮 -->
<div
v-if="!sidebarCollapsed"
class="flex justify-center ..."
@click="addNewChat"
>
<RiAddLine /> 新对话
</div>
<!-- 历史会话列表 -->
<div v-if="!sidebarCollapsed" class="overflow-y-auto p-2">
...
</div>
```
### 5. 保持功能可用性
- **历史记录加载**:收起状态下仍可在后台通过 `onMounted` 正常加载列表数据,只是不渲染 DOM。
- **选中态同步**:展开后 `selectedConversationId``groups` 数据不丢失,用户可继续操作。
- **响应式恢复**:若窗口尺寸变化导致侧边栏过窄,可后续补充监听自动展开逻辑(本期非必须)。
## 涉及文件
| 文件 | 修改内容 |
|---|---|
| `zn-ai/src/pages/home/ChatHistory.vue` | 新增 `sidebarCollapsed` ref、改造第 6 行图标为状态切换按钮、为 `aside` 添加动态宽度与过渡、控制内部元素显隐 |
## 验收标准
- [ ] 点击 `RiSideBarLine` 后,侧边栏从 `w-50` 平滑过渡到 `w-16`
- [ ] 收起状态下只显示 Logo 图片与展开图标按钮,其余文字/列表隐藏。
- [ ] 再次点击展开图标,侧边栏平滑恢复 `w-50`,历史列表与选中态保持。
- [ ] 不影响现有的新建对话、选择会话、重命名、删除功能。