# 主应用：对话工作台 UI/UX

## 1. 页面定义

| 项目 | 内容 |
| --- | --- |
| 页面名称 | 对话工作台 |
| 路由 | `/` |
| 页面实现 | `app-instance/frontend/app/(app)/page.tsx` |
| 全局外壳 | `components/AppShell.tsx`、`components/Header.tsx`、`components/AuthGuard.tsx`、`components/AppRuntimeBridge.tsx` |
| 消息区 | `components/chat-workbench/ChatWorkbench.tsx`、`MessageList.tsx`、`AgentTeamBlock.tsx` |
| 进度区 | `components/chat-workbench/CurrentSessionProgressSidebar.tsx` |
| 核心任务 | 选择或创建会话，发送文本或附件，与 Assistant 协作并处理任务验收 |
| 测试状态 | 已完成修复并复测通过；所有实测视口无页面横向越界、无小点击目标，核心交互可用 |

本页是主应用默认工作区。它同时承载全局导航、会话管理、消息时间线、Agent 运行过程、任务验收、附件上传、消息输入和当前任务进度。

## 2. 信息架构与组件层级

```text
AppShell
├── Header                                      固定头部，z-index: 50，高 64px
│   ├── Beaver 品牌入口
│   ├── 桌面主导航：对话、Task、通知、技能、文件、工具、智能体、Outlook、市场、配置
│   ├── 窄屏菜单按钮与移动导航面板
│   ├── 连接状态
│   ├── LanguageSwitcher
│   └── 账号按钮
│       └── Account Popover                     浮层，含账号信息和退出登录
└── main.pt-16
    └── AuthGuard
        ├── AppRuntimeBridge                    会话列表、WebSocket 与运行状态同步
        └── ChatPage                            高度 calc(100vh - 4rem)
            ├── Desktop Session Sidebar         md 及以上左侧固定 280px
            │   ├── 新对话按钮
            │   └── 最近对话滚动列表
            │       └── 会话选择按钮 + 44px 归档按钮
            ├── Mobile Session Drawer           手机最近对话抽屉
            ├── Conversation Column             中央弹性宽度
            │   ├── ChatWorkbench
            │   │   └── MessageList
            │   │       ├── 空状态
            │   │       ├── 用户消息
            │   │       ├── Assistant Markdown 消息
            │   │       ├── 消息附件
            │   │       ├── 任务卡与查看任务链接
            │   │       ├── 验收操作与内联反馈面板
            │   │       ├── Agent Team / Subtask 卡片
            │   │       └── 思考中状态
            │   └── Composer
            │       ├── 当前任务或修改任务状态胶囊
            │       ├── 待上传附件列表
            │       └── 输入器
            │           ├── textarea
            │           ├── 添加附件
            │           ├── 思考模式
            │           └── 发送
            └── Current Session Progress
                ├── >= xl：右侧固定 380px 侧栏
                └── < xl：右上角浮动按钮 + 右侧抽屉
```

## 3. 布局、位置与层级

### 全局头部

- 固定在视口顶部，高度 `64px`，页面主体使用 `pt-16` 避免被遮挡。
- 桌面宽屏显示品牌、完整主导航、连接状态、语言和账号。
- `2xl` 以下收起完整导航，显示菜单按钮；点击后从左侧滑入独立导航抽屉。
- 移动导航抽屉使用完全不透明的应用背景色、右侧阴影和独立滚动；抽屉外显示深色遮罩，底层页面不可交互且不会透过抽屉显示。
- “对话、通知、技能”等导航项区域和每个导航项均显式使用不透明应用表面背景，不依赖底层页面或透明父容器。
- 抽屉最大宽度为 `320px`，不会在平板或窄屏桌面退化为横向铺满的双列透明菜单。
- 层级顺序为页面内容 < 遮罩 < 导航抽屉 < 固定头部；打开时锁定页面滚动。
- 账号和语言入口在 `320px` 到宽屏范围内始终可达。

### 工作台主体

- 主体为横向 `flex`，高度 `calc(100vh - 4rem)`。
- 左侧会话栏在 `md` 及以上显示；手机默认隐藏，使用“最近对话”按钮打开抽屉。
- 中央对话列使用 `flex-1 min-w-0`，消息区占剩余高度，输入器固定在对话列底部。
- 输入器外层在手机使用较小左右边距，`md` 及以上恢复桌面边距；textarea 高度范围为 `72px` 到 `200px`。
- 当存在运行中任务时：
  - `xl` 及以上显示右侧固定 `380px` 进度栏。
  - 小于 `xl` 时显示右上角 `44×44px` 浮动按钮，点击后打开右侧抽屉。

### 消息与运行过程

- 消息时间线使用独立滚动区域，中央内容最大宽度 `5xl`。
- 用户消息右对齐、深色圆角气泡；Assistant 消息左对齐、透明背景。
- Assistant 创建任务后显示任务卡；待验收消息下方显示接受、需要修改、放弃。
- Agent Team 作为较大的运行过程区块插入消息时间线，内部 Subtask 卡片可横向排列并点击选中。
- 当前任务状态胶囊位于输入器上方，点击可前往任务详情。

### 弹层与覆盖层

| 层 | 触发入口 | 当前行为 |
| --- | --- | --- |
| 账号 Popover | 头部账号按钮 | 右对齐浮层；点击按钮打开；`Escape` 关闭；退出登录后跳往认证门户 |
| 移动导航抽屉 | `2xl` 以下的汉堡菜单 | 左侧滑入不透明面板；显示背景遮罩；点击遮罩、导航项或按 `Escape` 关闭 |
| 进度抽屉 | `< xl` 的右上角进度按钮 | 背景遮罩 + 右侧抽屉；点击遮罩或关闭按钮可关闭 |
| 接受反馈面板 | 待验收消息的“接受” | 在消息下方内联展开，不遮挡页面 |
| 修改任务状态 | 待验收消息的“需要修改” | 不打开弹窗；聚焦底部输入器并切换提示文案 |
| 放弃确认弹窗 | 待验收消息的“放弃” | 先说明后果，确认后才提交 `abandon` |
| 归档确认弹窗 | 会话行归档按钮 | 先说明会话将从最近对话移除，确认后归档 |

## 4. 页面状态

| 状态 | 当前表现 | UX 目的 | 测试结论 |
| --- | --- | --- | --- |
| 认证加载 | `AuthGuard` 显示加载中 | 避免未认证内容闪现 | 本轮未单独注入慢认证 |
| 空会话 | 中央显示 Beaver 和“发送消息开始对话” | 给出明确起点 | 通过 |
| 已加载会话 | 显示消息、任务卡和运行过程 | 恢复历史上下文 | 通过 |
| 切换会话 | 更新消息、进度、当前任务和输入草稿 | 快速在多任务间切换 | 通过，逐会话草稿正常保留 |
| 思考模式关闭或开启 | 按钮使用 `aria-pressed`，状态写入 localStorage | 让用户控制推理深度并保持偏好 | 通过 |
| 输入与换行 | `Enter` 发送，`Shift+Enter` 换行 | 提高聊天输入效率 | 通过 |
| 空输入 | 发送按钮禁用 | 防止无效提交 | 通过 |
| 发送中或思考中 | 禁用发送，并显示思考中状态 | 防止重复发送并提供过程反馈 | HTTP 模拟流程通过；真实 WebSocket 流未测 |
| 附件上传中 | 显示文件名、大小和进度条 | 表达上传进度 | 模拟上传通过 |
| 附件就绪 | 显示“就绪”，可移除 | 发送前确认附件 | 通过，但移除按钮可访问性不合格 |
| 待验收 | 显示接受、需要修改、放弃 | 让用户决定任务后续 | 三类操作均通过 |
| 接受反馈展开 | 显示可选备注、取消和提交 | 支持带上下文验收 | 通过 |
| 修改任务 | 输入器切换为修改要求并自动聚焦 | 降低修改路径成本 | 通过 |
| 放弃任务 | 点击后打开确认弹窗，确认后提交并显示已放弃 | 防止误终止任务 | 通过 |
| 进度侧栏或抽屉 | 显示整体进度、步骤和产物 | 在不离开对话的情况下理解执行状态 | 通过 |
| 账号弹层 | 显示账号信息和退出按钮 | 提供会话级账号入口 | 打开、Escape 关闭、退出登录均通过 |

## 5. 操作与 UX 逻辑

### 全局头部

| 操作 | 触发方式 | 状态变化与反馈 | UX 目的 | 当前结果 |
| --- | --- | --- | --- | --- |
| 返回对话页 | 点击 Beaver 或“对话” | 导航到 `/` | 提供稳定主页入口 | 正常 |
| 主导航切换 | 桌面点击导航项；窄屏点击菜单后选择导航项 | 前往对应主应用页面，当前项高亮 | 在产品模块间切换 | 正常 |
| 切换 ZH/EN | 点击语言按钮 | 页面文案立即变化并持久化 | 支持中英文用户 | 正常 |
| 打开账号弹层 | 点击账号按钮 | 显示账号信息与退出登录 | 集中账号操作 | 宽屏和移动端均正常 |
| 关闭账号弹层 | 按 `Escape` 或点击外部 | 浮层关闭并返回原页面 | 提供清晰退出路径 | `Escape` 实测正常 |
| 退出登录 | 点击退出登录 | 清除 access/refresh token，跳往认证门户 `/login?next=/` | 安全退出并保留返回路径 | 正常 |

### 会话栏

| 操作 | 触发方式 | 状态变化与反馈 | UX 目的 | 当前结果 |
| --- | --- | --- | --- | --- |
| 新对话 | 点击顶部主按钮 | 创建新 session、清空消息和输入、显示空状态 | 快速开始新任务 | 正常 |
| 选择会话 | 点击会话按钮，或键盘聚焦后 Enter/Space | 切换消息、当前任务、运行进度和草稿 | 支持并行工作 | 正常 |
| 保留草稿 | 在不同会话输入后切换 | 每个 session 恢复各自草稿 | 防止上下文切换丢失输入 | 正常 |
| 归档会话 | 点击会话行右侧 44px 归档按钮并确认 | 归档后从列表移除；失败时插入 Assistant 错误消息 | 清理历史会话并降低误操作 | 正常 |

### 消息、任务与 Agent 过程

| 操作 | 触发方式 | 状态变化与反馈 | UX 目的 | 当前结果 |
| --- | --- | --- | --- | --- |
| 查看任务 | 点击消息任务卡或当前任务胶囊 | 前往 `/tasks/<taskId>` | 深入任务详情 | 路由实测正常 |
| 查看消息附件 | 点击图片或文件链接 | 图片新窗口打开；文件下载 | 获取 Assistant 或用户提供的内容 | 本轮未连接真实文件服务 |
| 选择 Agent 卡片 | 点击 Subtask 卡片 | 卡片出现选中 ring | 明确当前关注的运行单元 | 正常 |
| 接受任务 | 点击“接受” | 展开可选备注面板 | 在提交前允许补充验收上下文 | 正常 |
| 取消接受 | 点击反馈面板“取消” | 关闭面板并清空备注 | 避免误提交 | 正常 |
| 提交接受 | 输入可选备注后点击“提交” | 提交 `accept`，显示“已接受” | 完成任务验收 | 正常 |
| 请求修改 | 点击“需要修改” | 输入器自动聚焦并切换修改提示；发送后提交 `revise` | 让修改请求复用主输入器 | 正常 |
| 放弃任务 | 点击“放弃”后确认 | 确认后提交 `abandon`，显示已放弃 | 终止不再需要的任务并降低误操作 | 正常 |

### 输入器与附件

| 操作 | 触发方式 | 状态变化与反馈 | UX 目的 | 当前结果 |
| --- | --- | --- | --- | --- |
| 输入消息 | 点击 textarea 并输入 | 自动增长，最大高度 `200px`；写入当前会话草稿 | 支持多行消息并防止输入丢失 | 正常 |
| 换行 | `Shift+Enter` | 插入换行，不发送 | 支持结构化输入 | 正常 |
| 键盘发送 | `Enter` | 清空输入、显示用户消息、等待回复 | 提高高频对话效率 | 正常 |
| 点击发送 | 点击发送按钮 | 与键盘发送相同 | 为鼠标和触控提供明确入口 | 正常 |
| 空输入发送 | 空输入时点击或按 Enter | 发送按钮禁用，无请求 | 防止无效提交 | 正常 |
| 添加附件 | 点击加号并选择文件 | 上传并显示进度、错误或就绪状态 | 在对话中补充文件上下文 | 模拟上传正常 |
| 超过 50MB 文件 | 选择过大文件 | 前端显示“最大 50MB”错误 | 及早阻止无效上传 | 代码路径确认；本轮未真实构造 50MB 文件 |
| 移除待发送附件 | 点击附件行右侧 X | 从待发送列表移除 | 发送前修正附件选择 | 正常，按钮有文件名相关可访问名称 |
| 切换思考模式 | 点击“思考” | `aria-pressed` 切换并持久化 | 让用户控制回答方式 | 正常 |

### 进度面板

| 操作 | 触发方式 | 状态变化与反馈 | UX 目的 | 当前结果 |
| --- | --- | --- | --- | --- |
| 查看桌面进度 | `xl` 及以上自动显示 | 右侧固定展示进度、步骤和产物 | 保持过程透明 | 正常 |
| 打开进度抽屉 | `< xl` 点击右上角浮动按钮 | 打开遮罩和右侧抽屉 | 在较窄空间按需查看进度 | 正常 |
| 关闭进度抽屉 | 点击 X 或遮罩 | 返回对话页 | 避免抽屉阻塞主任务 | 正常 |
| 打开产物链接 | 点击产物行 | 有 URL 时新窗口打开 | 快速访问结果 | 本轮未访问外部 URL |

## 6. 响应式测试矩阵

测试日期：2026-06-04。浏览器：Playwright Chromium。页面使用模拟 API 数据，所有布局渲染、点击、键盘操作和截图均在真实浏览器中执行。

| 视口 | 页面横向越界 | textarea 实测宽度 | 会话栏 | 进度展示 | 结论 |
| --- | --- | --- | --- | --- | --- |
| `320×568` | 无 | `262px` | 移动抽屉 | 抽屉可打开 | 通过 |
| `375×667` | 无 | `317px` | 移动抽屉 | 抽屉可打开 | 通过 |
| `390×844` | 无 | `332px` | 移动抽屉 | 抽屉可打开 | 通过 |
| `844×390` 横屏 | 无 | `466px` | 固定 `280px` | 抽屉可打开 | 通过 |
| `768×1024` | 无 | `390px` | 固定 `280px` | 抽屉可打开 | 通过 |
| `1024×768` | 无 | `646px` | 固定 `280px` | 抽屉可打开 | 通过 |
| `1365×900` | 无 | `607px` | 固定 `280px` | 固定右栏 `380px` | 通过 |
| `1920×1080` | 无 | `990px` | 固定 `280px` | 固定右栏 `380px` | 通过 |

### 关键量化证据

- `320px`、`375px`、`390px` 手机竖屏均无页面横向越界。
- 手机竖屏 textarea 实测宽度分别为 `262px`、`317px`、`332px`。
- `390px` 手机宽度下，账号入口 `44×44px` 且完整位于视口内。
- `1365px` 宽度下，账号入口完整位于视口内，完整导航收起为菜单入口。
- 最终复测中抽样视口可见小目标数为 `0`。

## 7. 可访问性与触控检查

### 已通过

- 发送按钮具有本地化 `aria-label`。
- 思考模式使用 `aria-pressed` 表达开关状态。
- 归档按钮、进度按钮和进度关闭按钮具有可访问名称。
- 账号 Popover 可使用 `Escape` 关闭。
- 修改任务后焦点自动移动到主输入器。
- 空输入时发送按钮使用原生 `disabled`。
- 长连续文本在桌面消息气泡中正常换行，未引发页面横向越界。
- 会话选择使用语义按钮，并通过 `aria-current` 表达当前会话。
- 附件移除按钮具有包含文件名的可访问名称。
- 主输入器和反馈输入器均有 label 关联。
- 所有最终抽样视口中，可见可交互控件命中区域均不小于 `44×44px`。

### 已修复

| 等级 | 问题 | 证据与影响 | 建议验收标准 |
| --- | --- | --- | --- |
| P1 | 会话行不可键盘操作 | 已改为语义按钮 | 支持 Enter/Space，当前会话使用 `aria-current` |
| P2 | 归档入口依赖悬停且目标过小 | 已改为 44px 归档按钮，并支持键盘焦点显示 | 触控环境可操作，目标至少 `44×44px` |
| P2 | 待发送附件移除按钮无名称且过小 | 已添加“移除附件 <文件名>”名称并扩大到 44px | 屏幕阅读器和触控均可用 |
| P2 | 多个关键操作小于 `44px` | 已扩大导航、语言、账号、任务链接、反馈、附件、思考模式等控件 | 最终抽样视口小目标数为 `0` |
| P2 | 主输入器和反馈输入器仅使用 placeholder | 已补充 label | 输入后仍有稳定字段语义 |
| P2 | 归档与放弃缺少确认或撤销 | 已补充站内确认弹窗 | 操作需确认后执行 |

## 8. 已修复问题与仍需观察项

### 已修复：手机竖屏下对话核心流程不可用

- 复现：使用 `320×568`、`375×667` 或 `390×844` 访问 `/`。
- 用户看到：左侧 `280px` 会话栏占据绝大部分视口，中央消息与输入器被压缩到右侧细条；需要横向滚动。
- 实测证据：文档宽度为 `549px`；textarea 可见宽度仅 `16px`。
- 影响：用户无法正常阅读消息、输入内容或使用发送与反馈操作。
- 相关实现：
  - `app/(app)/page.tsx` 的会话栏始终为 `w-[280px] shrink-0`。
  - 输入器始终保留 `px-8`。
- 复测结论：
  - 手机竖屏无页面横向滚动。
  - 会话列表改为抽屉，默认优先显示对话内容。
  - 输入器在 `320px` 宽度仍可完整输入和发送。

### 已修复：全局头部缺少响应式策略

- 复现：在 `1365px` 及以下查看头部。
- 用户看到：
  - `1365px` 时连接状态、语言和账号区域相互挤压，账号入口右侧被裁切。
  - `1024px`、`768px`、`390px` 时大量导航与账号入口位于视口外。
- 实测证据：
  - `1365px` 时账号入口右边界 `1392px`。
  - `390px` 时账号入口起点 `x=1302px`。
- 相关实现：`components/Header.tsx` 始终渲染 10 个完整文字导航项，并使用固定三列网格。
- 复测结论：在 `320px` 到 `1365px` 提供可操作的移动或紧凑导航，账号、语言和当前模块入口始终可达。

### 已修复：会话选择不支持键盘

- 复现：使用 Tab 键尝试选择最近对话。
- 当前结果：会话行是带 `onClick` 的 `div`，无 `role`、无 `tabIndex`，不会进入键盘焦点顺序。
- 用户影响：键盘和部分辅助技术用户无法切换会话。
- 相关实现：`app/(app)/page.tsx` 会话列表行。
- 复测结论：会话项使用语义按钮，支持键盘操作，当前项具有 `aria-current`。

### 已修复：放弃任务立即执行，无确认或撤销

- 复现：点击待验收消息的“放弃”。
- 当前结果：点击后先打开确认弹窗，确认后才提交 `abandon` 请求。
- 用户影响：误触会直接终止任务，恢复路径不明确。
- 相关实现：`MessageList.tsx` 的放弃按钮直接调用 `onFeedback(..., 'abandon')`。
- 复测结论：放弃前明确说明后果并要求确认。

### 已修复：会话归档入口可发现性和误操作保护不足

- 归档按钮默认 `opacity-0`，只有悬停会话行才显示。
- 按钮实测约 `18×18px`，触控设备不易发现和点击。
- 点击后先打开确认弹窗，确认后归档。
- 复测结论：触控环境可操作；命中区域至少 `44×44px`；归档前要求确认。

### 已修复：关键触控目标普遍偏小

- 影响范围：头部导航、语言切换、归档、查看任务、接受/修改/放弃、反馈取消/提交、附件、思考模式。
- 用户影响：手机、平板和运动能力受限用户更容易误触或漏触。
- 复测结论：最终抽样视口可见小目标数为 `0`。

### 已修复：待发送附件移除按钮缺少可访问名称

- 复现：添加附件并等待“就绪”。
- 当前结果：右侧 X 为无文本、无 `aria-label`、无 `title` 的按钮，尺寸约 `14×14px`。
- 复测结论：名称包含操作和文件名，命中区域至少 `44×44px`。

### 已修复：移动视口高度使用 `100vh`

- 工作台使用 `h-[calc(100vh-4rem)]`，没有使用动态视口单位。
- 用户影响：iOS Safari 等动态地址栏环境中，底部输入器可能被浏览器 UI 遮挡或发生高度跳变。
- 复测结论：工作台主体改用 `100dvh`。仍建议在移动真机验证输入法与地址栏变化。

## 9. 当前实现的正向 UX

- 新对话、会话切换、发送、修改、验收和进度查看形成完整工作流。
- 每个会话独立保留输入草稿，切换后可恢复。
- `Enter` 发送和 `Shift+Enter` 换行符合聊天产品惯例。
- 空输入时禁用发送；异步发送时避免重复提交。
- 修改任务会自动聚焦输入器并切换提示文案，路径清晰。
- 接受任务先展开可选备注，允许取消后再提交。
- 任务卡和当前任务胶囊均可直接进入任务详情。
- 进度面板同时表达总体进度、步骤和产物；小于 `xl` 时抽屉打开与关闭正常。
- 账号 Popover 支持 `Escape`，退出登录正确清除 token 并返回认证门户。
- 本轮所有实测交互均未产生控制台错误或框架错误覆盖层。

## 10. 后续验收清单

- [x] 为手机和窄屏设计会话抽屉、紧凑头部和主对话优先布局。
- [x] 修复 `320px`、`375px`、`390px` 横向越界并确保输入器完整可用。
- [x] 修复 `1365px` 及以下头部挤压和账号入口越界。
- [x] 将会话行改为完整的键盘与辅助技术可操作元素。
- [x] 为放弃任务和归档会话增加确认。
- [x] 扩大所有关键触控目标到至少 `44×44px`。
- [x] 为附件移除按钮添加本地化可访问名称。
- [x] 为主输入器和反馈输入器补充明确 label。
- [ ] 使用真实 WebSocket、真实上传、网络失败和超时状态复测。
- [ ] 测试 50MB 边界、上传失败、发送失败和反馈失败恢复路径。
- [ ] 在 iOS Safari、Android Chrome 和桌面 Safari 复测动态视口与输入法。
- [ ] 使用屏幕阅读器完成发送、切换会话和任务验收流程。

## 11. 本轮测试证据

- 自动化结果：`/tmp/beaver-chat-qa-results.json`
- 截图目录：`/tmp/beaver-chat-qa-shots`
- 临时测试脚本：`/tmp/beaver-ui-qa-tests/chat-page-qa.spec.js`
- API 环境：使用确定性模拟数据；真实浏览器负责页面渲染、点击、键盘、路由、响应式测量与截图。
- 自动化结果：`4 passed`。
- 测试命令：

```bash
/tmp/beaver-ui-qa-tests/node_modules/.bin/playwright test \
  /tmp/beaver-ui-qa-tests/chat-page-qa.spec.js \
  --config=/tmp/beaver-ui-qa-tests/pw.config.js \
  --workers=1
```
