# 主应用:对话工作台 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/` | 深入任务详情 | 路由实测正常 | | 查看消息附件 | 点击图片或文件链接 | 图片新窗口打开;文件下载 | 获取 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 ```