ui-design.md 9.2 KB

新 AI 助手:页面设计

状态:设计初稿,2026-10-24。新助手以独立的大页面展示(菜单路由),不放在顶栏右上角。需求见 requirements.md,前后端结构见 technical-design.md。对话组件来自 @agent-server/chat-ui(AgentServer packages/chat-ui)。

1. 路由与菜单

在 src/router/record.ts 增加一级菜单:

{
  path: 'ai-assistant',
  name: 'aiAssistant',
  icon: 'i-ph:sparkle',          // 与旧助手的 i-ph:chat-circle-dots 区分
  label: 'AI 助手',
  meta: {
    componentName: 'AiAssistant',
    showTab: true,
  },
  component: 'ai-assistant/index',
},
  • 单标签页(不设 enableMultiTab):一个页面同时只打开一个会话,避免多个标签各自维持 SSE 连接。
  • 当前会话写在查询参数 ?session=ses_xxx(切换会话时 router.replace):刷新页面、从浏览器历史返回都能回到同一个会话;链接发给别人时,对方打开会因归属校验失败而回到新会话。
  • 页面组件名为 AiAssistant,进入标签页的 KeepAlive:切换到其他标签时组件不销毁,进行中的回答继续接收;关闭标签时 dispose 订阅(运行本身不中断,下次打开从断点继续显示)。
  • 菜单可见性按现有菜单权限机制配置为 FR-03 允许的角色;AGENT_ENABLED=false 时不注册该菜单。
  • 旧助手顶栏按钮保持不变,两者并存。

2. 布局

宽屏(≥ 1280px)三栏,中间为对话主区:

┌───────────────┬──────────────────────────────────────────────┬─────────────────┐
│ + 新对话      │ 站点 XXXX 告警排查   ✎     [Sonnet 5.5 ▾]  ⋯ │ 本会话文件    ⇥ │
│ 🔍 搜索会话    ├──────────────────────────────────────────────┤ ─────────────── │
│               │                                              │ 上传            │
│ 今天          │        (对话时间线,最大宽度 880px 居中)      │  📄 sales.xlsx  │
│ ● 站点XXXX告警 │   用户:……                                    │  🖼 截图1.png   │
│   SIM 用量统计 │   助手:……                                    │ 产出            │
│ 昨天          │     ▸ 已调用 查询站点概况(0.8s)              │  📊 report.docx │
│   TOU 模版对比 │     ▸ 已调用 查询站点告警/事件记录(1.2s)     │  📈 trend.png   │
│ 最近 7 天      │     ┌ 审批:保存 TOU 模版(测试服)…  ┐        │                 │
│   …           │     └ [允许一次][本会话允许][拒绝]   ┘        │ ┌─────────────┐ │
│               │     📊 report.docx  2.1 MB  [下载]            │ │  文件预览    │ │
│               │                                              │ │ (图片/PDF/  │ │
│               ├──────────────────────────────────────────────┤ │  Markdown/   │ │
│ ⇤ 收起         │ [📎] 输入问题,Enter 发送,Shift+Enter 换行   ▶ │ │  CSV 前 200 行)│ │
│               │ 本轮 12.3k / 1.8k tokens · 排队中(第 2 位)    │ └─────────────┘ │
└───────────────┴──────────────────────────────────────────────┴─────────────────┘
   240px                       自适应                               320px
区域 内容 实现
左栏:会话 新对话按钮;按标题搜索;按“今天 / 昨天 / 最近 7 天 / 更早”分组;悬停显示改名、删除;当前会话高亮;可收起 NaiveUI(NInput、NScrollbar、NDropdown、NPopconfirm),数据来自 /agent/sessions
顶部栏 会话标题(点击改名);模型选择(Profile 允许的模型);更多菜单:删除会话、复制会话链接 NaiveUI;模型切换调用 PATCH /agent/v1/sessions/:id { model }
中间:对话 时间线、工具卡片、审批与提问卡片、文件卡片、输入框(附件、拖拽、粘贴截图)、中断、断线续传 <AgentChat :client :session @open-file>;#toolbar 插槽放用量与排队信息,#empty 插槽放欢迎页(第 3 节)
右栏:文件 本会话的上传与产出文件(按来源分组,最新在前);点击在下方预览;下载 client.sessions.files(id),收到 file.changed 事件时刷新;预览用 chat-ui 的 useFileObjectUrl、MarkdownView

对话主区的时间线限制最大宽度(880px)居中,宽屏下不至于一行过长;表格类回复允许横向滚动。

2.1 窄屏

宽度 布局
1024~1279px 右栏默认收起,顶部栏出现“文件”按钮,以右侧 NDrawer 打开
< 1024px 左栏也收起为顶部栏的“会话”按钮,以左侧 NDrawer 打开

左右栏的展开/收起状态记在 localStorage(读写包在 try/catch 中,失败时用默认值)。

3. 欢迎页(空会话)

新对话或空会话时,主区显示:

  • 一句说明:“可以查询站点、告警、停机、功率流、日志、录波、TOU 模版、SIM 卡数据,解答产品问题,分析上传的文件并生成报告。”
  • 示例问题卡片(2 × 3),点击即发送(session.send(text)):
    • 查一下站点 XXXX 最近 7 天的告警和事件
    • 统计昨天停机站点按国家分布
    • 分析站点 XXXX 本月的功率流,生成趋势图
    • 告警码 XXXX 是什么意思,通常怎么处理
    • 对比生产服和测试服的 TOU 模版 XXXX
    • 帮我把上传的 Excel 整理成一份 Word 报告

示例中的 SN、告警码等用占位符,点击后填入输入框而不直接发送,让用户补全(带占位符的卡片显示“填写后发送”)。

  • 底部提示:“数据来自 FWH 平台,结果仅供参考;涉及修改数据的操作会先请你确认。”

4. 交互细节

场景 行为
首次进入(无 ?session=) 打开最近活跃的会话;没有会话时显示欢迎页,发送第一条消息时才创建会话(避免产生空会话)
新对话 主区回到欢迎页,地址去掉 ?session=;左栏不出现新条目,直到发送第一条消息
发送第一条消息 POST /agent/sessions → 发送消息 → 用前 30 字改名 → 左栏插入并高亮
切换会话 当前会话 dispose,打开目标会话(拉取历史事件 + 订阅),右栏刷新文件列表
会话不存在 / 不属于本人 提示“会话不存在或无权访问”,回到欢迎页
运行中切换会话或离开页面 不中断运行;左栏该会话显示“进行中”小圆点(依据最近一次打开时的运行状态,回到该会话时以实际状态为准)
运行中再次发送 输入框保持可编辑,发送按钮置灰并提示“上一轮尚未结束,可先中断”
删除当前会话 二次确认 → 删除 → 回到欢迎页
审批 / 提问卡片待处理 页面标签显示提醒标记;离开页面期间到达的审批,回到页面时卡片仍在(来自 GET /v1/interactions)
AgentServer 或 fwh-agent-mcp 不可用 顶部栏下方显示横幅“AI 服务暂不可用”,输入框禁用;工具级别的不可用由工具卡片显示错误,不影响对话

5. 主题与样式

  • 引入 @agent-server/chat-ui/style.css;组件的原子类已在包内编译隔离,ToolBox 的 UnoCSS 不需要扫描 SDK。
  • 明暗模式:ToolBox 切换主题时同步设置 data-theme(组件读取 <html> 上的属性,需验证不影响 NaiveUI 的主题)。
  • 配色:在页面根元素上覆盖 --app-* 变量,使按钮、链接、选中色与 ToolBox 主色一致;完整变量见 @agent-server/ui-tokens 的 variables.css。
  • 左栏、顶部栏、右栏使用 NaiveUI 组件,与 ToolBox 其他页面一致;中间对话区保持 chat-ui 自身风格。

6. 代码结构

src/views/ai-assistant/
  index.vue                    页面:三栏布局、路由参数、窄屏抽屉
  components/
    SessionSidebar.vue         左栏:会话列表、搜索、分组、改名、删除
    ChatHeader.vue             顶部栏:标题、模型选择、更多菜单
    WelcomePanel.vue           欢迎页与示例问题
    FilePanel.vue              右栏:文件列表与预览
  composables/
    useAgentClient.ts          AgentClient 单例(baseUrl = /agent,令牌 = ToolBox 登录令牌)
    useAgentSessions.ts        会话列表、创建、改名、删除、当前会话与路由同步
    useSessionFiles.ts         文件列表与 file.changed 刷新
src/service/agent/index.ts     /agent/sessions/* 接口

不修改 src/layout/header/Actions/AiChat/、src/service/aiChat/。