Files
iofficeai--aionui/docs/prds/teams/team-runtime-experience.md
2026-07-13 13:20:22 +08:00

233 lines
12 KiB
Markdown
Raw Permalink 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.
# 团队运行体验优化 · PRD
本次聚焦「创建团队之后、在团队详情页协作」的体验,不改团队的创建流程。目标是让用户在多成员并行协作时,能一眼分清谁是谁、清楚当前在跟谁对话、并在团队初始化期间得到明确的引导而非静默卡顿。
全部改动限定在渲染层(前端),不改动 aioncore 后端与团队数据结构。涉及的持久化一律走浏览器本地存储(`localStorage`),不落库。
---
## 写在前面
### 名词
- **成员实例(slot)**:团队里的一个成员位,以 `slot_id` 唯一标识。同一个助手可以被拉进团队多次,每次是一个独立的成员实例(不同 `slot_id`),各自拥有独立会话。
- **Leader**:团队里 `role === 'leader'` 的成员,恒为成员列表第一个,不可移除、不可拖拽。
- **身份色**:团队详情页里为区分成员而临时赋予的颜色,仅在团队详情页生效。
- **Warmup**:进入团队后,后端拉起各成员运行时 + 注入协作环境(MCP)的初始化阶段。
### 设计基调
- 配色取自 AionUi 既有 token(品牌色 `#7583b2` 及其低饱和邻近色系),冷静不扎眼。
- 颜色只作「身份标识」,不做整格彩底,保持界面灰白干净的基调。
---
## 1. 成员身份色系统
### 想解决的问题
多成员并行、且同一助手可被拉多次时,用户看着并排的多列会话 / 多条 teammate 消息,分不清「这条到底是哪一个成员实例发的」。
### 方案
为每个成员实例分配一个身份色,一致地用于三处:
- 顶部成员胶囊的**浅底色**
- 该成员消息气泡的**左侧色条 + 彩色发送者名**(不做整格彩底);
- 选中该成员时,其对话列的**四周色边 border + 列头淡底**。
**不作用于头像**——头像保持原样(整图圆形,不加描边、不换底色)。
### 分配与稳定性规则
- 身份色按一套固定顺序色板从左到右分配。
- 颜色**绑定成员实例(slot_id)**,一经分配即钉死:其他成员的新增 / 删除 / 重排都不改变一个成员已有的颜色。
- 新增成员:追加到列表末尾,取一个当前未被占用的颜色(优先复用被移除成员释放出的颜色)。
- 移除成员:释放其颜色,不影响其余成员。
- 色板准备较多的舒适色,尽量覆盖常见团队规模;成员数超出色板时循环复用。
### 边界
- 身份色是纯展示辅助,不是业务数据;仅团队详情页使用,团队之外(左侧列表、设置里的助手等)不受影响。
---
## 2. 顶部成员列表
### 想解决的问题
现有顶部 tab 形态区分度弱、操作隐蔽;成员多到超出时用户不易发现可以横向查看更多,也就找不到末尾的添加入口。
### 方案
- 成员呈现为**横向单行胶囊**(省纵向空间,把高度留给对话面板):头像 + 名称 + 状态点 + 身份色浅底。
- **选中态明显**:选中胶囊身份色底加深 + 一圈身份色 border;对应对话列四周色边 + 列头淡底;未选中的列降饱和以聚焦当前对话。
- **成员操作 hover 才出现**:hover 胶囊时显示重命名 / 移除的小图标,平时不占位、不杂乱。
- **点击胶囊 = 切换到该成员**(选中态,见第 3 节)。
- **横向滚动**:成员超出宽度时列表横向滚动,两侧以渐隐提示「还有更多」。
- **添加成员入口固定可见**:见第 5 节。
---
## 3. 选中与高亮
### 想解决的问题
当前选中态只有一条细线,太弱,一眼看不出「现在选中的是谁、正在跟谁对话」。
### 方案
- **选中态载体**:成员胶囊高亮(身份色底加深 + border)+ 对应对话列四周身份色 border + 列头身份色淡底;其余列降饱和。
- **默认选中**:进入团队默认选中 Leader(列表第一个)。
- **选中态共享**:并行视图与单聊视图共用同一份选中状态(当前成员),两视图切换时保持连贯。
- **选中成员被移除**:自动回退到 Leader。
---
## 4. 协作视图:并行 / 单聊
### 想解决的问题
成员多时并排列会被压窄;用户有时只想专注跟某一个成员(尤其 Leader)对话、有时想纵览全员。
### 方案
提供两个可切换的视图,切换控件位于**标题行右侧**:
- **并行视图**(默认):所有成员对话列并排。
- **单聊视图**:全屏显示当前选中的成员对话。单聊 + 切换成员 = 切换全屏对象。
### 持久化与边界
- 视图是**团队整体**的属性 → 按团队记忆:key `team-view-mode-${team_id}`,各团队各自记住上次视图;默认并行。
- 单聊视图下当前成员被移除 → 回退到 Leader,仍留在单聊视图。
- Warmup 期间**允许切换视图**(纯前端布局变化,不改团队状态)。
---
## 5. 添加成员入口与「找 Leader 拉人」引导
### 想解决的问题
- 添加入口藏在滚动列表末尾,成员多时用户不知道右滑能看到它。
- 一个显眼的「添加成员」按钮会隐性传递「加人只有 GUI 这一条路」,而实际上更强的能力是:直接让 Leader 帮忙安排,尤其当现有助手都不合适时。
### 方案
- **添加入口固定在成员栏最右侧**(虚线胶囊样式,与实心成员胶囊形成「实=已有 / 虚=可加」对照),不随成员列表滚动,永远可见。
- 点击展开助手选择下拉(复用现有的助手选择器:搜索 + 列表,选中即关,助手随即出现在成员列表——即「加成功」反馈)。
- **下拉底部常驻一句引导**
> 没有合适的?也可以直接让 Leader 帮你安排。**告诉 Leader →**
- 点击「告诉 Leader →」:切换到 Leader 会话(单聊全屏 Leader),并在输入框**预填**「帮我在团队里加一个擅长 \_\_\_ 的成员」,**不自动发送**,光标定位让用户补全后自行发出。
- 不做空状态——用户一定有可添加的助手。
---
## 6. Leader 问候语
### 想解决的问题
新建团队进入 Leader 会话时,空状态没有明确的自我介绍,用户不清楚 Leader 是什么、能做什么。
### 方案
改现有 Leader 空状态:把问候语显示为
> 你好,我是 Leader,负责理解你的目标并协调团队。描述你想做的事,我来安排。
替换现有的 subtitle 文案,保留下方已有的 3 个提示词快捷卡片。纯前端文案改动(走 i18n)。
---
## 7. Warmup 初始化状态
### 想解决的问题
进入团队时后端在拉起成员运行时、注入协作环境,这段时间现在是**静默禁用**若干操作,没有任何反馈,用户只觉得「卡了一下」,还可能去做无效操作(发消息、加成员)。
### 方案
**进度表现**:整界面磨砂遮罩 + 成员头像从左到右逐个「点亮」(Leader 先亮)+「唤醒中 N/M」文案 + 品牌色进度条,呼应 App 既有的柔和光晕元素。
**结束闸门 = Leader ready**
- 遮罩在 **Leader 运行时就绪时即撤除**,不等全体成员——用户进团队第一件事是跟 Leader 说目标,Leader 一好就能开工。
- 这也从根本上规避「一个成员起不来就卡死整个团队」:某个 teammate 还在初始化或失败,不阻塞用户开始使用。
**遮罩期间禁止的行为**:添加成员、移除成员、重命名成员、发消息(遮罩盖住输入区,天然禁用)。
**遮罩期间允许的行为**:切换视图、切换 / 浏览成员、滚动。
**失败与超时兜底**
- 某 teammate 失败:遮罩早已撤除(Leader 已好),该成员在自己的胶囊 / 列上显示「启动失败 · 可重试」,不影响其他成员。
- Leader 失败:遮罩转为错误态(重试 / 返回),不无限转圈。
- **超时兜底**:Leader 在超时时限内仍未就绪,遮罩转为错误态(准备超时,重试 / 返回),防止后端未发事件等极端情况下无限等待。
### 技术前置确认
本方案依赖「前端能单独判断 Leader 的运行时就绪信号」(而非只有当前的全员聚合忙碌标志)。实现前需在代码中确认该信号可从现有运行时状态事件(带 `slot_id`)中取到;确认后方案成立,仍为纯前端。
---
## 8. 后续单独专题(不在本次范围)
- **全 App 头像容器统一**:现状各处头像的容器形状 / 尺寸 / 背景不一致,期望统一为左侧对话列表那种圆形头像。本次团队优化不做,后续单独拉专题梳理全 App 头像现状后统一。
- **确认型弹窗轻量统一**:删除助手 / 删除技能 / 工作区重命名删除 / 粘贴确认 / 关闭预览等确认弹窗保持轻量,作为独立线后续处理。
---
## 附录 A:前端技术方案
### A.1 存储与状态归属
| 状态 | 归属 | 存储位置 |
| --------------------- | -------- | ------------------------------------------------------------------------------- |
| 视图模式(并行/单聊) | 团队整体 | `localStorage: team-view-mode-${team_id}` |
| 成员身份色映射 | 成员实例 | `localStorage: team-member-colors-${team_id}`,内容为 `{ slot_id: colorIndex }` |
| 当前选中成员 | 团队整体 | 复用现有 `team-active-slot-${team_id}` |
| 成员排序 | 团队整体 | 复用现有 `team-assistant-order-${team_id}` |
身份色映射与视图模式均复用现有 `TeamTabsProvider`(已是每团队一实例,已有按 `team_id` 分键的 localStorage 先例:active-slot、assistant-order)。
### A.2 身份色分配逻辑
- 维护 `{ slot_id → colorIndex }` 映射(内存 + localStorage 持久化)。
- 渲染成员时:已有映射的直接取色;新出现的 slot 取「当前未占用的最小色号」(优先复用被移除释放的色号),写入映射。
- 移除成员:从映射删除该 slot,释放色号。
- 超出色板容量:色号对色板长度取模循环。
- 色板取 AionUi 品牌 slate 邻近的低饱和色,Leader 固定用品牌主色。
### A.3 视图切换
- 复用现有 `fullscreenSlotId` 的单列全屏能力,升级为显式、按团队持久化的 `viewMode` 状态。
- 单聊显示当前 `activeSlotId` 对应成员;两视图共享 `activeSlotId`
### A.4 Warmup 状态机
- 现有 `membershipMutationBusy` 是「是否有成员 runtime pending 或 MCP 注入中」的聚合布尔值,不区分 Leader。
- 新增:从运行时状态事件(`agentRuntimeStatusChanged`,带 `slot_id`)中单独取 Leader 的就绪状态,作为撤遮罩闸门(实现前先确认该粒度可取)。
- teammate 级失败状态映射到各自胶囊 / 列的表现;不参与撤遮罩判断。
- 超时兜底:进入团队后启动计时,Leader 超时未就绪则进入错误态。
### A.5 「告诉 Leader」
- 切换 `activeSlotId` 到 Leader + 视图切单聊 + 向 Leader 会话的输入框预填提示词(复用现有 send box 预填能力,不自动发送)。
### A.6 i18n
本次新增 / 改动的文案(多语言):视图切换标签、warmup 各态文案(唤醒中 / 准备超时 / 启动失败 · 重试)、「找 Leader 拉人」引导句、Leader 问候语。均新增 key 并覆盖各 locale。
---
## 附录 B:实施阶段建议
| 阶段 | 内容 | 独立验收点 |
| ---- | --------------------------------------------------------- | -------------------------------------------------- |
| 1 | 身份色系统 + 胶囊成员栏 + 气泡区分 + 选中态高亮 | 多成员下颜色区分清晰、选中态明显、增删成员颜色稳定 |
| 2 | 并行 / 单聊视图切换(按团队记忆) | 两视图切换连贯、按团队记忆、选中态共享 |
| 3 | Warmup loading 态 + 禁用清单 + 失败/超时兜底 | Leader 就绪即可用、失败不卡死、超时有兜底 |
| 4 | 添加成员虚线胶囊 + 「找 Leader 拉人」引导 + Leader 问候语 | 入口常驻可见、引导可切 Leader 预填、问候语到位 |
每阶段完成后起 dev 自测(白盒 + 黑盒 + 类型 + lint 全绿)并交产品验收,验收通过后按聚焦提交。