Files
wecom_it_smart_desk/docs/02-技术文档/技术架构/增量设计-布局优化v2-20260711.md
T

1006 lines
43 KiB
Markdown
Raw Normal View History

# 增量设计:坐席端布局优化 v2.0
> **文档版本**v2.0
> **创建日期**2026-07-11
> **文档类型**:增量架构设计(前端重构)
> **技术栈**Vue 3 + Element Plus + TypeScript + Pinia + CSS Variables
> **代码位置**`frontend-agent/`
> **预估工期**7 天(5 个 Phase
---
## 目录
1. [实现方案概述](#1-实现方案概述)
2. [文件列表](#2-文件列表)
3. [数据结构和接口](#3-数据结构和接口)
4. [程序调用流程](#4-程序调用流程)
5. [任务列表](#5-任务列表)
6. [依赖包列表](#6-依赖包列表)
7. [共享知识](#7-共享知识)
8. [待明确事项](#8-待明确事项)
---
## 1. 实现方案概述
### 1.1 背景与核心矛盾
坐席端当前三栏布局(左栏 280px 会话列表 + 中栏 flex-1 聊天区 + 右栏 320px AI 面板)存在四个核心矛盾:
| 编号 | 矛盾 | 现状 | 影响 |
|------|------|------|------|
| P1 | ReplyBox 工具栏拥挤 | 单行 6 按钮,新增 4 个 AI 按钮后达 10 个 | 按钮无层次,操作效率低 |
| P2 | 右栏信息密度过载 | 320px 承载 5 个功能区(Wingman/AI推荐/标注/快速回复/草稿) | 坐席视线频繁切换 |
| P3 | 中栏可用高度不足 | 固定高度层过多,1080p 屏幕消息区仅剩 ~400px | 消息浏览体验差 |
| P4 | AI 交互入口分散 | 9+ 个入口分布在 3 个位置 | 认知负担重 |
### 1.2 重构策略:功能重新分类 + 布局精简
本次重构采用 **"先清理后建设"** 的增量策略,分两条主线推进:
**主线 A — 功能重新分类(解决 P2/P4)**
将 AI 功能按使用时机分为两类,分别归入中栏和右栏:
```
┌─────────────────────────────────────────────────────────────────┐
│ 回复前用(放中栏) │ 回复后用/训练用(放右栏) │
├───────────────────────────────┼─────────────────────────────────┤
│ · AI 草稿生成/展示 │ · 智能标注(原"排查流程"重命名) │
│ · 知识库引用 │ · 质量反馈(AI回复有用/无用) │
│ · AI 推荐回复 │ · 知识贡献(提交知识建议) │
│ · 快速回复 │ · 使用统计 │
│ · 排查导航 │ │
│ · 自动补齐/语气/润色/改写 │ │
└───────────────────────────────┴─────────────────────────────────┘
```
**主线 B — 布局精简(解决 P1/P3)**
- 左栏 280px → 260px(释放 20px 给中栏)
- 右栏 320px → 260px(正常)/ 560px(放大模式,新增开关)
- UserInfoBar 详情默认折叠(节省 ~150px 高度)
- TroubleshootBar 默认收起为图标条(节省 ~36px 高度)
- ReplyBox 工具栏重构为左右分区(常规工具 | AI 工具)
### 1.3 功能重复清理(5 处)
| 编号 | 重复问题 | 清理方案 |
|------|---------|---------|
| R1 | AI 草稿双展示(中栏气泡 + 右栏 Wingman | 统一到中栏 ReplySuggestArea |
| R2 | AI 推荐回复三处展示(右栏卡片 + 内联 + 草稿气泡) | 合并到 AiRecommendBar.vue |
| R3 | 排查流程命名混淆 | 右栏按钮重命名为"智能标注" |
| R4 | 标签建议双入口 | 合并为单一"智能标注"面板 |
| R5 | 孤儿组件 AiRecommendInline.vue | 删除 |
### 1.4 风险控制
| 风险 | 等级 | 控制措施 |
|------|------|---------|
| 功能迁移期间出现入口缺失 | 高 | T02 先完成清理并验证无残留引用,再进入 T03/T04 建设 |
| 右栏放大模式挤压中栏 | 中 | 放大模式设置 560px 上限,中栏 min-width: 400px 保底 |
| CSS 变量改动影响暗色主题 | 中 | 新增变量同步在 `[data-theme="dark"]` 中定义对应值 |
| 拖拽手柄与新宽度冲突 | 低 | 拖拽范围下限从 220px 调整为 200px,上限保持 500px |
| 删除组件导致其他模块编译错误 | 中 | T02 中执行全局 Grep 搜索引用,确保无残留 import |
### 1.5 框架选型
本项目不引入新框架,完全基于现有技术栈实现:
| 技术 | 用途 | 选型理由 |
|------|------|---------|
| Vue 3 Composition API | 组件逻辑组织 | 现有项目统一使用 `<script setup>` |
| Element Plus | UI 组件库 | 现有项目已深度集成 |
| Pinia | 状态管理 | 现有 conversation store 扩展 panelMode 状态 |
| CSS Variables | 布局尺寸/配色管理 | 现有 global.css 已建立完整变量体系,本次扩展 |
---
## 2. 文件列表
### 2.1 新增文件(8 个组件)
| 序号 | 文件路径 | 说明 |
|------|---------|------|
| 1 | `src/components/chat/ReplySuggestArea.vue` | 回复建议区容器:位于消息列表与 ReplyBox 之间,承载 AiRecommendBar + QuickReplyBar |
| 2 | `src/components/chat/AiRecommendBar.vue` | AI 推荐条:合并原 AiSuggestReply + AiRecommendInline 功能,横向展示 1-3 条推荐 |
| 3 | `src/components/chat/QuickReplyBar.vue` | 快速回复条:横向 2 层布局(L1 分类 chip + L2 条目预览),替代右栏 QuickReplyPanel |
| 4 | `src/components/assistant/AiTrainingPanel.vue` | 右栏 AI 训练区主体:Tab 切换智能标注/质量反馈/知识贡献 |
| 5 | `src/components/assistant/PanelModeToggle.vue` | 右栏放大/缩小模式切换开关 |
| 6 | `src/components/assistant/SmartTagEditor.vue` | 智能标注编辑面板(从 AiAssistantPanel 迁出并增强) |
| 7 | `src/components/assistant/QualityFeedback.vue` | 质量反馈面板:对 AI 回复进行有用/无用标注 |
| 8 | `src/components/assistant/KnowledgeContribute.vue` | 知识贡献面板:提交知识建议 |
### 2.2 修改文件(7 个组件 + 1 个样式)
| 序号 | 文件路径 | 修改内容 |
|------|---------|---------|
| 1 | `src/styles/global.css` | 新增 CSS 变量(`--assistant-panel-expanded``--suggest-*-bg``--toolbar-*-bg`);调整 `--sidebar-width` 280→260、`--assistant-panel-width` 320→260 |
| 2 | `src/views/Workspace.vue` | 左右栏宽度调整;新增 `panelMode` 状态控制右栏放大/缩小;右栏拖拽范围调整 |
| 3 | `src/components/chat/ChatArea.vue` | 新增 ReplySuggestArea 层(消息列表与 ReplyBox 之间);移除 AiRecommendInline 引用 |
| 4 | `src/components/chat/UserInfoBar.vue` | 确保详情默认折叠(`isExpanded` 初始值 `false`);优化折叠态高度 |
| 5 | `src/components/chat/TroubleshootBar.vue` | 新增"图标条"折叠态(比当前 header 更紧凑,仅显示🔧图标 + 当前步骤号) |
| 6 | `src/components/chat/ReplyBox.vue` | 工具栏重构为左右分区:左侧常规工具(截图/拍照/表情/文件/邀请)、右侧 AI 工具(自动补齐/语气/润色/改写) |
| 7 | `src/components/assistant/AiAssistantPanel.vue` | 全面重构:移除 Wingman 触发组、AI 推荐区、快速回复区(已迁移到中栏);改为承载 AiTrainingPanel + PanelModeToggle 的容器 |
### 2.3 删除文件(2 个组件)
| 序号 | 文件路径 | 删除原因 |
|------|---------|---------|
| 1 | `src/components/chat/AiRecommendInline.vue` | R5 孤儿组件,功能已被 AiRecommendBar 替代 |
| 2 | `src/components/assistant/AiSuggestReply.vue` | R2 功能合并到 AiRecommendBar,不再独立使用 |
### 2.4 文件变更全景图
```
frontend-agent/src/
├── styles/
│ └── global.css [修改] CSS变量调整
├── views/
│ └── Workspace.vue [修改] 栏宽+模式切换
├── components/
│ ├── chat/
│ │ ├── ChatArea.vue [修改] +ReplySuggestArea -AiRecommendInline
│ │ ├── UserInfoBar.vue [修改] 确保默认折叠
│ │ ├── TroubleshootBar.vue [修改] +图标条折叠态
│ │ ├── ReplyBox.vue [修改] 工具栏左右分区
│ │ ├── AiRecommendInline.vue [删除] 孤儿组件
│ │ ├── ReplySuggestArea.vue [新增] 回复建议区容器
│ │ ├── AiRecommendBar.vue [新增] AI推荐条
│ │ └── QuickReplyBar.vue [新增] 快速回复条
│ └── assistant/
│ ├── AiAssistantPanel.vue [修改] 重构为训练区容器
│ ├── AiSuggestReply.vue [删除] 功能合并
│ ├── AiTrainingPanel.vue [新增] 训练区主体
│ ├── PanelModeToggle.vue [新增] 模式切换开关
│ ├── SmartTagEditor.vue [新增] 智能标注编辑
│ ├── QualityFeedback.vue [新增] 质量反馈面板
│ └── KnowledgeContribute.vue [新增] 知识贡献面板
```
---
## 3. 数据结构和接口
### 3.1 类图
> 完整 Mermaid 类图见:`docs/02-技术文档/技术架构/增量设计-布局优化v2-类图.mermaid`
```mermaid
classDiagram
class Workspace {
+Ref~boolean~ assistantVisible
+Ref~PanelMode~ panelMode
+startLeftResize() void
+startRightResize() void
}
class ChatArea {
+Ref~Message~ replyToMessage
+handleSend(content: string) void
}
class ReplySuggestArea {
+Props: conversationId: string
+Emits: select(content: string)
+activeTab: Ref~string~
}
class AiRecommendBar {
+Props: recommendations: AiRecommendation[]
+Props: loading: boolean
+Emits: select(content: string)
+Emits: refresh()
}
class QuickReplyBar {
+Props: templates: QuickReply[]
+Emits: select(content: string)
+navState: Ref~QuickReplyNav~
}
class ReplyBox {
+Props: replyToMessage: Message
+Emits: send(content: string)
+inputText: Ref~string~
+toolbarMode: Ref~ToolbarMode~
}
class AiAssistantPanel {
+Props: mode: PanelMode
+Emits: toggleMode()
}
class AiTrainingPanel {
+Props: conversationId: string
+activeTab: Ref~TrainingTab~
}
class PanelModeToggle {
+Props: mode: PanelMode
+Emits: toggle()
}
class SmartTagEditor {
+Props: conversationId: string
+currentTags: Ref~ConversationTags~
+suggestedTags: Ref~string[]
+handleSuggestTags() void
+handleAddTag(tag: string) void
+handleRemoveTag(key: string) void
}
class QualityFeedback {
+Props: conversationId: string
+feedbackList: Ref~Annotation[]
+handleSubmit(msgId: string, feedback: string) void
}
class KnowledgeContribute {
+Props: conversationId: string
+contributeForm: Ref~ContributeForm~
+handleSubmit() void
}
class ConversationStore {
+pendingReplyText: string
+aiDrafts: Map~string, Set~DraftResult~~
+panelMode: Ref~PanelMode~
+setPanelMode(mode: PanelMode) void
}
class UserInfoBar {
+Props: conversation: Conversation
+isExpanded: Ref~boolean~
+toggleExpand() void
}
class TroubleshootBar {
+isFlowchartExpanded: Ref~boolean~
+isIconBarCollapsed: Ref~boolean~
+toggleCollapse() void
}
%% 组合关系
Workspace *-- ChatArea : renders
Workspace *-- AiAssistantPanel : renders
ChatArea *-- UserInfoBar : contains
ChatArea *-- TroubleshootBar : contains
ChatArea *-- ReplySuggestArea : contains (新增)
ChatArea *-- ReplyBox : contains
ReplySuggestArea *-- AiRecommendBar : contains
ReplySuggestArea *-- QuickReplyBar : contains
AiAssistantPanel *-- AiTrainingPanel : contains
AiAssistantPanel *-- PanelModeToggle : contains
AiTrainingPanel *-- SmartTagEditor : tab
AiTrainingPanel *-- QualityFeedback : tab
AiTrainingPanel *-- KnowledgeContribute : tab
%% 依赖关系
AiRecommendBar ..> ConversationStore : pendingReplyText
QuickReplyBar ..> ConversationStore : pendingReplyText
ReplyBox ..> ConversationStore : pendingReplyText
SmartTagEditor ..> ConversationStore : currentConversation
```
### 3.2 新增组件 Props/Emits 定义
#### ReplySuggestArea.vue
```typescript
interface Props {
/** 当前会话 ID */
conversationId: string
}
interface Emits {
/** 选中某条建议/回复,填入输入框 */
(e: 'select', content: string): void
}
```
#### AiRecommendBar.vue
```typescript
/** AI 推荐项类型(与原 AiSuggestReply 保持一致) */
interface AiRecommendation {
title: string
content: string
confidence: number
}
interface Props {
/** 推荐列表 */
recommendations: AiRecommendation[]
/** 是否加载中 */
loading: boolean
}
interface Emits {
/** 选中推荐 → 填入输入框 */
(e: 'select', content: string): void
/** 刷新推荐列表 */
(e: 'refresh'): void
}
```
#### QuickReplyBar.vue
```typescript
/** 快速回复导航状态 */
interface QuickReplyNav {
l1Index: number // 一级分类索引,-1 表示未选择
l2Index: number // 二级子分类索引,-1 表示未选择
}
interface Props {
/** 快速回复模板列表 */
templates: QuickReply[]
}
interface Emits {
/** 选中模板 → 填入输入框 */
(e: 'select', content: string): void
}
```
#### AiTrainingPanel.vue
```typescript
/** 训练区 Tab 类型 */
type TrainingTab = 'smart-tag' | 'quality-feedback' | 'knowledge-contribute'
interface Props {
/** 当前会话 ID */
conversationId: string
}
```
#### PanelModeToggle.vue
```typescript
/** 右栏面板模式 */
type PanelMode = 'normal' | 'expanded'
interface Props {
/** 当前模式 */
mode: PanelMode
}
interface Emits {
/** 切换模式 */
(e: 'toggle'): void
}
```
#### SmartTagEditor.vue
```typescript
type ConversationTags = Record<string, any>
interface Props {
/** 当前会话 ID */
conversationId: string
}
```
#### QualityFeedback.vue
```typescript
interface Props {
/** 当前会话 ID */
conversationId: string
}
```
#### KnowledgeContribute.vue
```typescript
/** 知识贡献表单 */
interface ContributeForm {
title: string
problem: string
solution: string
category: string
}
interface Props {
/** 当前会话 ID */
conversationId: string
}
```
### 3.3 Store 变化
#### ConversationStore 新增字段
```typescript
// 在 useConversationStore 中新增:
import type { Ref } from 'vue'
/** 右栏面板模式:normal(260px) | expanded(560px) */
const panelMode = ref<PanelMode>('normal')
/** 设置面板模式 */
function setPanelMode(mode: PanelMode): void {
panelMode.value = mode
}
```
#### PanelMode 类型定义
```typescript
// 新增到 src/types/ 或内联在 store 中
/** 右栏面板模式 */
type PanelMode = 'normal' | 'expanded'
```
### 3.4 修改组件接口变化
#### ReplyBox.vue 工具栏重构
```typescript
/** 工具栏模式 */
type ToolbarMode = 'conventional' | 'ai'
// 工具栏分区结构(template 中):
// <div class="chat-toolbar">
// <div class="toolbar-left"> ← 常规工具(截图/拍照/表情/文件/邀请)
// <div class="toolbar-right"> ← AI 工具(自动补齐/语气/润色/改写)
// </div>
// 新增 AI 工具按钮处理函数:
function handleAiTool(action: 'autocomplete' | 'tone' | 'polish' | 'rewrite'): void {
// 根据 action 调用对应 wingman API 或本地处理
}
```
#### TroubleshootBar.vue 新增图标条折叠态
```typescript
/** 是否收起为图标条(比当前 header 更紧凑) */
const isIconBarCollapsed = ref(true) // 默认收起
/** 切换图标条/完整栏 */
function toggleCollapse(): void {
isIconBarCollapsed.value = !isIconBarCollapsed.value
if (isIconBarCollapsed.value) {
isFlowchartExpanded.value = false // 收起时同步收起流程图
}
}
```
#### AiAssistantPanel.vue 重构后结构
```typescript
// 重构后仅作为容器,不再包含 Wingman/AI推荐/快速回复逻辑
interface Props {
/** 面板模式 */
mode: PanelMode
}
interface Emits {
/** 切换模式 */
(e: 'toggle'): void
}
// template 结构:
// <div class="ai-assistant-panel">
// <PanelModeToggle :mode="mode" @toggle="$emit('toggle')" />
// <AiTrainingPanel :conversation-id="conversationId" />
// </div>
```
---
## 4. 程序调用流程
### 4.1 时序图
> 完整 Mermaid 时序图见:`docs/02-技术文档/技术架构/增量设计-布局优化v2-时序图.mermaid`
#### 4.1.1 回复建议区交互流程
```mermaid
sequenceDiagram
participant User as 坐席
participant ChatArea as ChatArea
participant RSA as ReplySuggestArea
participant ARB as AiRecommendBar
participant QRB as QuickReplyBar
participant CS as ConversationStore
participant RB as ReplyBox
participant API as Wingman API
User->>ChatArea: 选中会话
ChatArea->>CS: selectConversation(id)
CS->>API: generateDraft(convId)
API-->>CS: DraftResult {content, confidence}
CS-->>ChatArea: aiDrafts 更新
ChatArea->>RSA: render(conversationId)
RSA->>ARB: :recommendations = loadFromDrafts()
ARB-->>User: 展示 AI 推荐条(1-3条)
User->>ARB: 点击推荐卡片
ARB->>CS: pendingReplyText = content
ARB->>RSA: emit('select', content)
RSA->>ChatArea: emit('select', content)
CS-->>RB: watch(pendingReplyText) 触发
RB->>RB: inputText = pendingReplyText
RB->>RB: 清空 pendingReplyText
RB-->>User: 输入框显示推荐内容
User->>QRB: 点击快速回复分类
QRB->>QRB: navState.l1Index = index
QRB-->>User: 展示 L2 条目列表
User->>QRB: 点击条目
QRB->>CS: pendingReplyText = template.content
CS-->>RB: watch 触发,填入输入框
```
#### 4.1.2 右栏模式切换流程
```mermaid
sequenceDiagram
participant User as 坐席
participant PMT as PanelModeToggle
participant AAP as AiAssistantPanel
participant WS as Workspace
participant CS as ConversationStore
participant DOM as DOM/CSS
User->>PMT: 点击放大/缩小开关
PMT->>AAP: emit('toggle')
AAP->>WS: emit('toggle')
alt 当前为 normal 模式
WS->>CS: setPanelMode('expanded')
CS-->>WS: panelMode = 'expanded'
WS->>DOM: assistantPanel style.width = var(--assistant-panel-expanded)
DOM-->>User: 右栏宽度 260px → 560pxCSS transition 0.3s
else 当前为 expanded 模式
WS->>CS: setPanelMode('normal')
CS-->>WS: panelMode = 'normal'
WS->>DOM: assistantPanel style.width = var(--assistant-panel-width)
DOM-->>User: 右栏宽度 560px → 260px
end
Note over WS,DOM: 中栏 flex:1 自动伸缩,min-width: 400px 保底
```
#### 4.1.3 功能迁移流程(清理 → 建设)
```mermaid
sequenceDiagram
participant Dev as 开发过程
participant Old as 旧组件
participant New as 新组件
participant ChatArea as ChatArea
participant AAP as AiAssistantPanel
Note over Dev: Phase 1 — 清理重复
Dev->>Old: 删除 AiRecommendInline.vue
Dev->>ChatArea: 移除 import AiRecommendInline
Dev->>Old: 删除 AiSuggestReply.vue
Dev->>AAP: 移除 import AiSuggestReply
Note over Dev: Phase 1 — 移除右栏已迁移功能
Dev->>AAP: 移除 Wingman 触发组(生成回复/知识库/排查流程)
Dev->>AAP: 移除 AI 推荐区
Dev->>AAP: 移除快速回复区
Note over AAP: AiAssistantPanel 仅保留容器骨架
Note over Dev: Phase 3 — 中栏建设
Dev->>New: 创建 ReplySuggestArea.vue
Dev->>New: 创建 AiRecommendBar.vue(合并推荐功能)
Dev->>New: 创建 QuickReplyBar.vue(横向2层快速回复)
Dev->>ChatArea: 在消息列表与 ReplyBox 之间插入 ReplySuggestArea
Dev->>New: AiRecommendBar 从 ConversationStore.aiDrafts 加载数据
Note over Dev: Phase 4 — 右栏建设
Dev->>New: 创建 AiTrainingPanel.vueTab容器)
Dev->>New: 创建 SmartTagEditor.vue(从 AAP 迁出标签逻辑)
Dev->>New: 创建 QualityFeedback.vue
Dev->>New: 创建 KnowledgeContribute.vue
Dev->>New: 创建 PanelModeToggle.vue
Dev->>AAP: AiAssistantPanel 承载 PanelModeToggle + AiTrainingPanel
```
### 4.2 关键交互说明
#### 4.2.1 ReplyBox 工具栏左右分区
```
┌─────────────────────────────────────────────────────────────────┐
│ ← 常规工具(toolbar-left AI 工具(toolbar-right → │
│ ┌────┬────┬────┬────┬────┐ ┌────┬────┬────┬────┐ │
│ │ ✂️ │ 📷 │ 😊 │ 📎 │ 👥 │ │ ✨ │ 🎭 │ ✏️ │ 🔄 │ │
│ │截图│拍照│表情│文件│邀请│ │补齐│语气│润色│改写│ │
│ └────┴────┴────┴────┴────┘ └────┴────┴────┴────┘ │
│ 背景: var(--toolbar-conv-bg) 背景: var(--toolbar-ai-bg) │
└─────────────────────────────────────────────────────────────────┘
```
- 左侧 5 个按钮保持原有功能不变
- 右侧 4 个 AI 按钮调用 wingman API
- `autocomplete`:基于当前输入框内容自动补齐
- `tone`:调整语气(专业/亲切/简洁)
- `polish`:润色文字
- `rewrite`:改写表达
#### 4.2.2 ReplySuggestArea 层级位置
```
ChatArea 垂直布局(从上到下):
┌─────────────────────────────┐
│ UserInfoBar (默认折叠) │ ← flex-shrink: 0
├─────────────────────────────┤
│ TroubleshootBar (图标条态) │ ← flex-shrink: 0
├─────────────────────────────┤
│ ParticipantBar (条件显示) │ ← flex-shrink: 0
├─────────────────────────────┤
│ 消息列表 (flex: 1) │ ← 占满剩余空间
├─────────────────────────────┤
│ ReplySuggestArea (新增) │ ← flex-shrink: 0, max-height: 120px
│ ├─ AiRecommendBar │
│ └─ QuickReplyBar │
├─────────────────────────────┤
│ ReplyBox │ ← flex-shrink: 0
└─────────────────────────────┘
```
#### 4.2.3 右栏训练区 Tab 结构
```
AiAssistantPanel (260px / 560px)
┌─────────────────────────────────┐
│ PanelModeToggle [放大/缩小] │ ← 顶部固定
├─────────────────────────────────┤
│ AiTrainingPanel │
│ ┌─────┬──────┬──────┐ │
│ │标注 │质量反馈│知识贡献│ ← Tab │
│ └─────┴──────┴──────┘ │
│ ┌─────────────────────┐ │
│ │ SmartTagEditor │ │
│ │ / QualityFeedback │ │
│ │ / KnowledgeContribute│ │
│ └─────────────────────┘ │
└─────────────────────────────────┘
```
---
## 5. 任务列表
### 5.1 任务概览
| 任务 ID | 任务名称 | Phase | 预估工时 | 优先级 | 依赖 |
|---------|---------|-------|---------|--------|------|
| T01 | 布局骨架 + CSS变量 + 折叠优化 | Phase 1 | 1.5 天 | P0 | 无 |
| T02 | 功能重复清理 + 删除孤儿组件 | Phase 1 | 0.5 天 | P0 | T01 |
| T03 | 回复建议区 + ReplyBox工具栏重构 | Phase 2+3 | 2.5 天 | P0 | T01, T02 |
| T04 | 右栏训练区 + 模式切换 | Phase 4 | 2 天 | P1 | T01, T02 |
| T05 | 联调测试 + 样式微调 | Phase 5 | 1 天 | P0 | T01-T04 |
### 5.2 任务依赖图
```mermaid
graph LR
T01[T01: 布局骨架+CSS变量+折叠优化] --> T02[T02: 功能重复清理+删除孤儿]
T02 --> T03[T03: 回复建议区+工具栏重构]
T02 --> T04[T04: 右栏训练区+模式切换]
T03 --> T05[T05: 联调测试+样式微调]
T04 --> T05
style T01 fill:#e1f5ee
style T02 fill:#faeeda
style T03 fill:#faece7
style T04 fill:#eaf3de
style T05 fill:#f0f0f0
```
### 5.3 任务详情
#### T01: 布局骨架 + CSS变量 + 折叠优化
| 属性 | 值 |
|------|-----|
| **Phase** | Phase 1 |
| **预估工时** | 1.5 天 |
| **优先级** | P0 |
| **依赖** | 无 |
**涉及文件(4 个):**
| 文件 | 修改内容 |
|------|---------|
| `src/styles/global.css` | ① `--sidebar-width`: 280px → 260px;② `--assistant-panel-width`: 320px → 260px;③ 新增 `--assistant-panel-expanded: 560px`;④ 新增 `--suggest-ai-bg: #FAECE7``--suggest-quick-bg: #EAF3DE``--toolbar-conv-bg: #E1F5EE``--toolbar-ai-bg: #FAEEDA`;⑤ 暗色主题 `[data-theme="dark"]` 同步新增对应变量 |
| `src/views/Workspace.vue` | ① 左栏宽度跟随 `--sidebar-width` 变量;② 右栏宽度绑定 `panelMode` 状态(normal → `--assistant-panel-width`expanded → `--assistant-panel-expanded`);③ 右栏拖拽范围下限从 220px → 200px,上限调整为 560px;④ 新增 `panelMode` ref 和 `togglePanelMode` 方法;⑤ 右栏 `<aside>` 添加 `:class` 动态绑定 |
| `src/components/chat/UserInfoBar.vue` | ① 确保 `isExpanded` 初始值为 `false`(当前已为 false,做显式确认);② 折叠态移除不必要的 padding/margin,优化紧凑度 |
| `src/components/chat/TroubleshootBar.vue` | ① 新增 `isIconBarCollapsed` ref(初始 `true`);② 新增图标条折叠态模板:仅显示 🔧 图标 + 当前步骤序号(高度 ~28px);③ 完整栏态保持现有 header + path + flowchart 结构;④ 图标条点击展开为完整栏 |
**验收标准:**
- [x] 左栏视觉宽度变为 260px,中栏对应增宽 20px
- [x] 右栏视觉宽度变为 260px
- [x] UserInfoBar 详情默认折叠,点击可展开
- [x] TroubleshootBar 默认显示为图标条,点击展开为完整栏
- [x] 暗色主题下新增 CSS 变量生效
---
#### T02: 功能重复清理 + 删除孤儿组件
| 属性 | 值 |
|------|-----|
| **Phase** | Phase 1 |
| **预估工时** | 0.5 天 |
| **优先级** | P0 |
| **依赖** | T01 |
**涉及文件(4 个):**
| 文件 | 修改内容 |
|------|---------|
| `src/components/chat/AiRecommendInline.vue` | **删除**。R5 孤儿组件,功能将被 AiRecommendBar 替代 |
| `src/components/assistant/AiSuggestReply.vue` | **删除**。R2 功能合并到 AiRecommendBar |
| `src/components/assistant/AiAssistantPanel.vue` | 移除已迁移到中栏的功能区块:① 删除 Wingman 触发按钮组(生成回复/知识库/排查流程);② 删除 AI 推荐区(含 AiSuggestReply 引用);③ 删除快速回复区(含 QuickReplyPanel 引用);④ 保留智能标注区代码骨架(将在 T04 中迁移到 SmartTagEditor);⑤ 组件暂时只保留空容器 + 标注区 |
| `src/components/chat/ChatArea.vue` | ① 移除 `AiRecommendInline` 的 import 和模板引用(如有);② 确认无其他对已删除组件的引用 |
**验收标准:**
- [x] `npm run build` 编译无错误
- [x] 全局 Grep 搜索 `AiRecommendInline``AiSuggestReply` 无残留引用
- [x] AiAssistantPanel 不再包含 Wingman/AI推荐/快速回复 UI
- [x] 右栏暂时只显示智能标注区(功能不丢失,T04 重建)
---
#### T03: 回复建议区 + ReplyBox工具栏重构
| 属性 | 值 |
|------|-----|
| **Phase** | Phase 2 + Phase 3 |
| **预估工时** | 2.5 天 |
| **优先级** | P0 |
| **依赖** | T01, T02 |
**涉及文件(5 个):**
| 文件 | 修改内容 |
|------|---------|
| `src/components/chat/ReplySuggestArea.vue` | **新增**。回复建议区容器组件:① Props: `conversationId: string`;② Emits: `select(content: string)`;③ 内部包含 AiRecommendBar(上)和 QuickReplyBar(下)两个子组件;④ Tab 切换"AI推荐"/"快速回复"视图;⑤ max-height: 120px,超出可滚动;⑥ 背景 `var(--suggest-ai-bg)` / `var(--suggest-quick-bg)` 区分 |
| `src/components/chat/AiRecommendBar.vue` | **新增**。AI 推荐条:① Props: `recommendations: AiRecommendation[]`, `loading: boolean`;② Emits: `select(content)`, `refresh()`;③ 横向展示 1-3 条推荐卡片(置信度药丸 + 2行截断文本 + Ctrl+N 快捷键提示);④ 从 `ConversationStore.aiDrafts` 加载数据(替代原 AiSuggestReply + AiRecommendInline 的数据源);⑤ 点击卡片 → `ConversationStore.pendingReplyText = content` |
| `src/components/chat/QuickReplyBar.vue` | **新增**。快速回复条:① Props: `templates: QuickReply[]`;② Emits: `select(content)`;③ 横向 2 层布局:L1 分类 chip 横向滚动条 + L2 当前分类条目预览;④ 复用 `QuickReplyStore.templatesByCategory` 计算属性;⑤ 选中条目 → `ConversationStore.pendingReplyText = content` |
| `src/components/chat/ReplyBox.vue` | 工具栏重构:① 将 `.chat-toolbar` 拆分为 `.toolbar-left`(常规工具:截图/拍照/表情/文件/邀请)和 `.toolbar-right`(AI 工具:自动补齐/语气/润色/改写);② 新增 `handleAiTool(action)` 方法处理 4 个 AI 按钮;③ 左侧背景 `var(--toolbar-conv-bg)`,右侧背景 `var(--toolbar-ai-bg)`;④ 中间用 `flex: 1` 间距分隔左右两组 |
| `src/components/chat/ChatArea.vue` | ① 在消息列表(`.message-list-scroll`)与 ReplyBox 之间插入 `<ReplySuggestArea>`;② 传入 `conversationId` prop;③ 监听 `@select` 事件(可选,主要走 store 通信) |
**验收标准:**
- [x] 消息列表下方、ReplyBox 上方显示回复建议区
- [x] AI 推荐条展示 1-3 条推荐,点击可填入输入框
- [x] 快速回复条横向 2 层布局,点击条目可填入输入框
- [x] ReplyBox 工具栏左右分区,左侧 5 个常规按钮,右侧 4 个 AI 按钮
- [x] AI 工具按钮点击后有反馈(loading 或 ElMessage 提示)
- [x] Ctrl+1/2/3 快捷键可选中对应推荐
---
#### T04: 右栏训练区 + 模式切换
| 属性 | 值 |
|------|-----|
| **Phase** | Phase 4 |
| **预估工时** | 2 天 |
| **优先级** | P1 |
| **依赖** | T01, T02 |
**涉及文件(6 个):**
| 文件 | 修改内容 |
|------|---------|
| `src/components/assistant/AiAssistantPanel.vue` | 重构为容器:① Props: `mode: PanelMode`;② Emits: `toggle`;③ 顶部放置 `<PanelModeToggle>`;④ 主体放置 `<AiTrainingPanel>`;⑤ 移除所有原有业务逻辑(已在 T02 中部分完成) |
| `src/components/assistant/AiTrainingPanel.vue` | **新增**。训练区主体:① Props: `conversationId: string`;② 内部 Tab 切换:智能标注 / 质量反馈 / 知识贡献;③ 使用 Element Plus `el-tabs` 组件;④ 切换会话时自动重置到第一个 Tab |
| `src/components/assistant/PanelModeToggle.vue` | **新增**。模式切换开关:① Props: `mode: PanelMode`;② Emits: `toggle`;③ UI 为一个小型图标按钮(⤢ 放大 / ⤡ 缩小);④ 放置在 AiAssistantPanel 右上角 |
| `src/components/assistant/SmartTagEditor.vue` | **新增**。智能标注编辑面板:① Props: `conversationId: string`;② 从原 AiAssistantPanel 迁出标签逻辑(loadCurrentTags / handleSuggestTags / handleAddSuggestedTag / handleRemoveTag / handleAddManualTag);③ R3 重命名:标题从"智能标注"保持,但排查流程按钮文案改为"智能标注"(消除命名混淆);④ R4 合并标签建议入口为单一面板 |
| `src/components/assistant/QualityFeedback.vue` | **新增**。质量反馈面板:① Props: `conversationId: string`;② 列出当前会话的 AI 回复消息,每条可标注"有用"/"无用";③ 调用 `createAnnotation` API`src/api/annotation.ts`);④ 调用 `getAnnotations` 加载已有标注 |
| `src/components/assistant/KnowledgeContribute.vue` | **新增**。知识贡献面板:① Props: `conversationId: string`;② 表单:标题/问题描述/解决方案/分类;③ 提交后调用后端知识建议 API(需确认接口);④ 提交成功后 ElMessage 提示并清空表单 |
**验收标准:**
- [x] 右栏顶部显示模式切换开关
- [x] 点击开关右栏在 260px ↔ 560px 之间切换,有 CSS transition 动画
- [x] 训练区 3 个 Tab 可正常切换
- [x] 智能标注 Tab 功能与重构前一致(标签增删/AI建议)
- [x] 质量反馈 Tab 可对 AI 回复标注有用/无用
- [x] 知识贡献 Tab 可提交表单
- [x] 放大模式下 Tab 内容区域有更多展示空间
---
#### T05: 联调测试 + 样式微调
| 属性 | 值 |
|------|-----|
| **Phase** | Phase 5 |
| **预估工时** | 1 天 |
| **优先级** | P0 |
| **依赖** | T01, T02, T03, T04 |
**涉及文件(3 个):**
| 文件 | 修改内容 |
|------|---------|
| `src/components/chat/ChatArea.vue` | 联调:① 确认 ReplySuggestArea 与 ReplyBox 的联动(推荐→填入→发送)正常;② 确认消息列表高度在折叠态下满足 ≥400px(1080p 屏幕);③ 确认 TroubleshootBar 图标条态/完整栏态切换不影响消息列表滚动 |
| `src/views/Workspace.vue` | 联调:① 确认三栏布局在不同分辨率(1080p/2K/4K)下的表现;② 确认右栏放大模式不挤压中栏至不可用;③ 确认拖拽手柄在新宽度范围下正常工作 |
| `src/styles/global.css` | 样式微调:① 根据联调结果微调 CSS 变量值;② 确认暗色主题下所有新增变量正确生效;③ 微调 ReplySuggestArea / ReplyBox 工具栏的间距/圆角 |
**验收标准:**
- [x] 1080p 屏幕:消息区可用高度 ≥ 400px
- [x] 三栏布局在 1080p/2K/4K 下均正常显示
- [x] 右栏放大模式(560px)下中栏 min-width ≥ 400px
- [x] 暗色主题下所有新增 CSS 变量正确生效
- [x] 所有功能流程(推荐→填入→发送 / 标注 / 质量反馈 / 知识贡献)端到端验证通过
---
## 6. 依赖包列表
本次重构 **不新增任何第三方 npm 包**,完全基于现有依赖实现。
| 包名 | 已有版本 | 用途 | 本次是否新增 |
|------|---------|------|------------|
| vue | ^3.x | 响应式框架 | 否 |
| element-plus | ^2.x | UI 组件库(el-tabs, el-button, el-tag, el-input 等) | 否 |
| pinia | ^2.x | 状态管理 | 否 |
| @element-plus/icons-vue | ^2.x | 图标组件 | 否 |
> **说明**:所有新组件均使用 Element Plus 现有组件 + CSS Variables 实现,无需引入额外 UI 库或工具库。
---
## 7. 共享知识
### 7.1 跨文件约定
| 约定 | 说明 |
|------|------|
| **组件通信策略** | 推荐内容/快速回复 → 输入框:统一通过 `ConversationStore.pendingReplyText` 单向数据流,不使用 emit 链传递内容(避免多层级 prop drilling |
| **CSS 变量命名** | 新增变量遵循现有命名规范:`--{区域}-{功能}-{属性}`,如 `--suggest-ai-bg`(回复建议区/AI推荐/背景色)、`--toolbar-ai-bg`(工具栏/AI区/背景色) |
| **组件文件位置** | 中栏新增组件放 `src/components/chat/`,右栏新增组件放 `src/components/assistant/`,与现有目录结构保持一致 |
| **TypeScript 类型** | 共享类型(如 `AiRecommendation``PanelMode`)定义在组件内部并 export,或在 `src/types/` 下新建类型文件 |
| **API 调用** | AI 相关调用复用 `src/api/wingman.ts`generateDraft / suggestTags);标注调用复用 `src/api/annotation.ts`createAnnotation / getAnnotations |
| **快捷键** | Ctrl+1/2/3 选中推荐(保持与原 AiSuggestReply 一致);快捷键注册在 `useKeyboardShortcuts` composable 中 |
### 7.2 CSS 命名规范
```css
/* BEM 风格,与现有组件保持一致 */
.reply-suggest-area { } /* 容器 */
.reply-suggest-area__tab { } /* Tab 按钮 */
.ai-recommend-bar { } /* AI 推荐条 */
.ai-recommend-bar__card { } /* 推荐卡片 */
.quick-reply-bar { } /* 快速回复条 */
.quick-reply-bar__chip { } /* 分类 chip */
.toolbar-left { } /* 工具栏左侧 */
.toolbar-right { } /* 工具栏右侧 */
.panel-mode-toggle { } /* 模式切换开关 */
.ai-training-panel { } /* 训练区主体 */
.smart-tag-editor { } /* 智能标注编辑 */
.quality-feedback { } /* 质量反馈 */
.knowledge-contribute { } /* 知识贡献 */
```
### 7.3 CSS 变量完整清单(本次新增/修改)
```css
:root {
/* === 修改 === */
--sidebar-width: 260px; /* 原 280px */
--assistant-panel-width: 260px; /* 原 320px */
/* === 新增 === */
--assistant-panel-expanded: 560px; /* 右栏放大模式宽度 */
--suggest-ai-bg: #FAECE7; /* 回复建议区 AI推荐 背景色 */
--suggest-quick-bg: #EAF3DE; /* 回复建议区 快速回复 背景色 */
--toolbar-conv-bg: #E1F5EE; /* 工具栏 常规区 背景色 */
--toolbar-ai-bg: #FAEEDA; /* 工具栏 AI区 背景色 */
}
[data-theme="dark"] {
/* 暗色主题对应值 */
--suggest-ai-bg: #3a2a26;
--suggest-quick-bg: #2a3326;
--toolbar-conv-bg: #1e3028;
--toolbar-ai-bg: #3a3526;
}
```
### 7.4 组件通信策略
```
┌──────────────────────────────────────────────────────────┐
│ ConversationStore │
│ │
│ pendingReplyText ←─── AiRecommendBar (写入) │
│ pendingReplyText ←─── QuickReplyBar (写入) │
│ pendingReplyText ───→ ReplyBox (读取, watch) │
│ │
│ aiDrafts ←─── Wingman API (写入) │
│ aiDrafts ───→ AiRecommendBar (读取, 展示) │
│ │
│ panelMode ←─── Workspace (写入, togglePanelMode) │
│ panelMode ───→ AiAssistantPanel (读取, Props) │
│ │
│ currentConversation ───→ SmartTagEditor (读取) │
│ currentConversation ───→ QualityFeedback (读取) │
│ currentConversation ───→ KnowledgeContribute (读取) │
└──────────────────────────────────────────────────────────┘
```
**核心原则**:跨组件数据传递一律走 Pinia Store,组件内部状态用 `ref`/`reactive`。父子组件配置项用 Props/Emits。
---
## 8. 已确认事项(2026-07-12 产品确认)
| 编号 | 问题 | 确认结论 | 影响范围 |
|------|------|---------|---------|
| Q1 | **ReplyBox AI 工具按钮的后端接口** | ✅ 需新建后端 API,属于"AI辅助消息框"项目范围。现有 wingman API 仅有 draft/summary/tags 三个端点,自动补齐/语气/润色/改写 4 个功能需新建。布局优化v2.0 先预留按钮位置,后端 API 在 AI辅助消息框项目中实现。两项目可并行推进。 | ReplyBox.vue T03 |
| Q2 | **知识贡献提交接口** | ✅ 复用现有 API `POST /api/knowledge-iteration/suggestions`。已有完整的知识建议 CRUD 链路(创建/审批/拒绝/重写/合并/统计),KnowledgeContribute.vue 直接调用 `POST /suggestions` 即可。 | KnowledgeContribute.vue T04 |
| Q3 | **QuickReplyBar 布局交互** | ✅ **L1 分类 chip 始终显示**(横向滚动条),**L2 条目采用悬浮框**展示。点击 L1 chip 后弹出悬浮框覆盖消息输入框区域(因此时浏览快速回复不需要看输入框内容),选择条目后悬浮框自动消失,选中文本填充到输入框。L1 始终可见保证分类入口稳定,L2 按需出现不与 AiRecommendBar 争抢空间。 | QuickReplyBar.vue T03 |
| Q4 | **右栏放大模式默认值** | ✅ 默认 normal(260px),持久化到 localStorage。新用户首次打开右栏为紧凑模式,中栏空间最大化。坐席需要时手动点击放大到 expanded(560px),偏好持久化。 | Workspace.vue T01/T04 |
| Q5 | **TroubleshootBar 图标条态交互** | ✅ 点击展开完整栏。图标条态显示 🔧 + 步骤号,点击后展开为完整排查栏(含流程图),再次点击收起回图标条态。 | TroubleshootBar.vue T01 |
| Q6 | **AiDraftBubble.vue 去留** | ✅ 删除,统一到中栏 ReplySuggestArea。R1 清理方案明确"AI 草稿双展示→统一到 ReplySuggestArea",保留两处展示正是本次要消除的重复问题。 | AiDraftBubble.vue |
| Q7 | **质量反馈标注对象范围** | ✅ 仅标注坐席采纳了 AI 草稿的回复。衡量 AI 质量,避免坐席手写回复被误标。 | QualityFeedback.vue T04 |
| Q8 | **使用统计功能** | ✅ 本期暂不实现。布局优化v2.0 聚焦核心布局重构(中栏建设 + 右栏 Tab 框架),使用统计需后端新建统计聚合 API + 数据表,属独立功能模块,后续单独迭代。 | AiTrainingPanel T04 |
---
## 附录 A: 现有代码关键信息
### A.1 现有三栏布局尺寸(global.css
```css
:root {
--sidebar-width: 280px; /* → 修改为 260px */
--assistant-panel-width: 320px; /* → 修改为 260px */
}
```
### A.2 现有 ReplyBox 工具栏按钮(6 个)
| 按钮 | 功能 | 处理函数 |
|------|------|---------|
| ✂️ 截图 | 截屏并框选 | `handleScreenshot()` |
| 📷 拍照 | 调用摄像头 | `handleCamera()` |
| 😊 表情 | 表情选择器 | `showEmojiPicker` |
| 📎 文件 | 文件上传 | `handleToolbarClick('file')` |
| 👥 邀请 | 邀请员工/部门 | `showInviteDialog` |
| ⚡ 快速回复 | 聚焦输入框 | `handleToolbarClick('quickReply')` |
### A.3 现有 AiAssistantPanel 功能区(5 个,将重构)
| 功能区 | 迁移去向 |
|--------|---------|
| Wingman 触发按钮组(生成回复/知识库/排查流程) | → 中栏 ReplySuggestArea + ReplyBox AI工具 |
| Wingman 结果展示区(草稿/知识库/排查流程) | → 中栏 ReplySuggestArea |
| AI 智能推荐区 | → 中栏 AiRecommendBar |
| 智能标注区 | → 右栏 SmartTagEditorTab 1 |
| 快速回复区 | → 中栏 QuickReplyBar |
### A.4 现有 ConversationStore 关键字段
```typescript
// 已有字段(本次不修改):
pendingReplyText: string // 待填充到输入框的文本
aiDrafts: Map<string, Set<DraftResult>> // 按会话ID存储的AI草稿
// 新增字段:
panelMode: Ref<PanelMode> // 右栏面板模式
setPanelMode(mode: PanelMode): void // 设置面板模式
```