Files
wecom_it_smart_desk/docs/archive/ARCHITECTURE-v53-incremental.md
T

915 lines
31 KiB
Markdown
Raw Normal View History

# IT智能服务台 · 坐席工作台 v5.3 增量架构设计
> **版本**: v5.3-incremental
> **日期**: 2026-06-06
> **作者**: 高见远(Gao)· 架构师
> **状态**: 待评审
> **基线**: 现有坐席工作台 v5.2 三栏布局
---
## 1. 实现方案与框架选型
### 1.1 核心技术挑战
| # | 挑战 | 难度 | 应对策略 |
|---|------|------|---------|
| 1 | CSS 变量驱动双主题系统,需确保所有现有硬编码色值迁移完成 | ⭐⭐ | 分层替换:先定义变量体系 → 替换 `global.css` → 逐组件迁移 inline style |
| 2 | 右栏 5-Tab → 上下两区重构,需保持快速回复键盘导航的焦点管理 | ⭐⭐⭐ | 使用 `useKeyboardShortcuts` composable 统一管理快捷键,避免各组件各自监听 |
| 3 | 中栏视图切换(聊天↔任务详情),需保持 WebSocket 连接和 Store 状态不丢失 | ⭐⭐ | 纯前端 `v-if`/`v-show` 切换,不销毁 Store;用 `workspaceView` 状态控制 |
| 4 | 排查步骤决策树 JSON 渲染,需支持判断节点 + 分支缩进 + 动画展开 | ⭐⭐⭐ | 递归组件 `FlowchartNode.vue``max-height` 过渡 + `overflow: hidden` |
| 5 | 会话列表 6 区 → 3 段折叠,数据映射需重新定义 computed 属性 | ⭐⭐ | 新增 `myConversations`/`colleagueConversations`/`historyConversations` 三个 computed |
### 1.2 框架选型(沿用 + 增量)
| 层 | 框架/库 | 版本 | 说明 |
|----|--------|------|------|
| 前端框架 | Vue 3 | ^3.4 | Composition API + `<script setup>` |
| UI 组件库 | Element Plus | ^2.7 | 沿用,少量自定义样式覆盖 |
| 状态管理 | Pinia | ^2.1 | 新增 `useTodoStore``useThemeStore` |
| 构建工具 | Vite | ^5.x | 沿用 |
| CSS 方案 | CSS Variables | 原生 | 双主题核心,不引入额外 CSS-in-JS |
| 后端框架 | FastAPI | ^0.111 | 沿用 |
| ORM | SQLAlchemy 2.0 | ^2.0 | 异步模式,新增模型 |
| 数据验证 | Pydantic v2 | ^2.7 | 沿用,新增 Schema |
> **决策**:不引入新 UI 框架或 CSS-in-JS 方案。双主题完全通过 CSS 变量 + `data-theme` 属性切换实现,与 Element Plus 主题变量共存。
### 1.3 架构模式
沿用现有 **MVVM + Composable** 模式:
```
View (Vue SFC)
↕ 双向绑定 / 事件
ViewModel (Pinia Store + Composables)
↕ API 调用
Model (TypeScript 接口 ↔ Pydantic Schema ↔ SQLAlchemy Model)
```
新增 Composable 层:
- `useTheme.ts` — 主题切换 + 持久化
- `useKeyboardShortcuts.ts` — 全局快捷键注册/卸载
---
## 2. 文件列表及相对路径
> 变更类型标记:🆕新增 / ✏️修改 / 🔄重写 / 🗑️废弃
### 2.1 前端文件
| # | 相对路径(基于 `frontend-agent/src/` | 变更 | 说明 |
|---|--------------------------------------|------|------|
| 1 | `styles/global.css` | ✏️ | 新增深色主题 CSS 变量块 + 双主题色值体系;替换硬编码色为 `var()` |
| 2 | `composables/useTheme.ts` | 🆕 | 主题切换 composable(读取/写入 localStorage + 设置 `data-theme` |
| 3 | `composables/useKeyboardShortcuts.ts` | 🆕 | 全局快捷键统一管理(Ctrl+1/2/3, Alt+1~5, ↑↓, Enter, / |
| 4 | `stores/theme.ts` | 🆕 | 主题 Pinia StorecurrentTheme 响应式 + toggle 方法) |
| 5 | `stores/todo.ts` | 🆕 | 待办事项 Pinia StoretodoList + fetch/更新状态) |
| 6 | `api/todo.ts` | 🆕 | 待办事项 API(GET 列表/详情, PUT 状态) |
| 7 | `api/troubleshooting.ts` | 🆕 | 排查模板 API(GET 列表/详情) |
| 8 | `api/conversation.ts` | ✏️ | Conversation 接口新增 `impact_scope`/`is_blocking`/`emotion_state` 字段 |
| 9 | `views/Workspace.vue` | ✏️ | 顶部栏抽离为 `TopBar.vue`;新增 `workspaceView` 状态控制视图切换 |
| 10 | `components/layout/TopBar.vue` | 🆕 | 独立顶栏组件(系统名称 FE-09 + 主题切换 + 坐席状态 + 应急模式) |
| 11 | `components/conversation/ConversationList.vue` | 🔄 | 三段折叠 + 搜索标签 + 底部待办面板挂载点 |
| 12 | `components/conversation/ConversationItem.vue` | ✏️ | 新增优先级图标(⛔👥⭐🔁);移除旧标签部分 |
| 13 | `components/conversation/TodoPanel.vue` | 🆕 | 左栏底部待办事项面板 |
| 14 | `components/chat/ChatArea.vue` | ✏️ | 顶部替换为 `UserInfoBar`;底部挂载 `TroubleshootBar`;新增视图切换逻辑 |
| 15 | `components/chat/UserInfoBar.vue` | 🆕 | 用户信息栏(chips + 展开详情 6 卡片) |
| 16 | `components/chat/ItLevelBadge.vue` | 🆕 | IT 等级徽标组件(7 级段位 + 渐变 + 王者发光) |
| 17 | `components/chat/AiRecommendInline.vue` | 🆕 | 聊天区内 AI 推荐回复(Ctrl+1/2/3 |
| 18 | `components/chat/TroubleshootBar.vue` | 🆕 | 排查步骤栏(路径视图 + 可展开流程图) |
| 19 | `components/chat/FlowchartNode.vue` | 🆕 | 决策树递归渲染节点 |
| 20 | `components/chat/TaskDetailView.vue` | 🆕 | 任务详情视图(工单/审批/设备三种子视图) |
| 21 | `components/assistant/AiAssistantPanel.vue` | 🔄 | 完全重写:移除 5 Tab,改为上下两区 |
| 22 | `components/assistant/AiSuggestReply.vue` | ✏️ | 适配右栏上方 AI 推荐区样式;增加置信度 + 快捷键提示 |
| 23 | `components/assistant/QuickReplyPanel.vue` | 🔄 | 重写:搜索置顶 + Alt 分类 + ↑↓ 导航 + Enter 确认 + 键盘指南 |
| 24 | `components/assistant/RiskAlert.vue` | 🗑️ | 废弃,不再引用 |
| 25 | `components/assistant/UserInfoPanel.vue` | 🗑️ | 废弃,功能并入 `UserInfoBar.vue` |
### 2.2 后端文件
| # | 相对路径(基于 `backend/app/` | 变更 | 说明 |
|---|-------------------------------|------|------|
| 1 | `models/employee.py` | ✏️ | 新增 `it_level`/`it_level_source`/`notes` 字段 |
| 2 | `models/conversation.py` | ✏️ | 新增 `impact_scope`/`is_blocking`/`emotion_state` 字段 |
| 3 | `models/todo_item.py` | 🆕 | TodoItem 模型(id/type/title/priority/description/status/... |
| 4 | `models/troubleshooting_template.py` | 🆕 | TroubleshootingTemplate 模型(id/name/category/path_steps/flowchart/... |
| 5 | `schemas/employee.py` | ✏️ | EmployeeResponse 新增字段;新增 `ItLevelUpdateRequest` Schema |
| 6 | `schemas/conversation.py` | ✏️ | ConversationResponse/ConversationTags 新增字段 |
| 7 | `schemas/todo_item.py` | 🆕 | TodoItem CRUD Schema |
| 8 | `schemas/troubleshooting_template.py` | 🆕 | TroubleshootingTemplate CRUD Schema |
| 9 | `api/employees.py` | ✏️ | 新增 `PUT /api/employees/{id}/it-level` 端点 |
| 10 | `api/conversations.py` | ✏️ | 响应包含新字段(无需新端点) |
| 11 | `api/todo_items.py` | 🆕 | GET 列表/详情 + PUT 状态更新 |
| 12 | `api/troubleshooting_templates.py` | 🆕 | GET 列表/详情 + POST/PUT/DELETE(管理员) |
| 13 | `api/router.py` | ✏️ | 注册新路由 |
| 14 | `models/__init__.py` | ✏️ | 导入新模型(确保 SQLite 自动建表) |
### 2.3 文档与配置文件
| # | 相对路径 | 变更 | 说明 |
|---|---------|------|------|
| 1 | `docs/ARCHITECTURE-v53-incremental.md` | 🆕 | 本文档 |
| 2 | `docs/sequence-diagram.mermaid` | 🆕 | 时序图 |
| 3 | `docs/class-diagram.mermaid` | 🆕 | 类图 |
---
## 3. 数据结构与接口
### 3.1 类图
```mermaid
classDiagram
direction TB
class Employee {
+str id
+str corp_id
+str employee_id
+str name
+str department
+str position
+str mobile
+str email
+str avatar
+int status
+str it_level ★NEW
+str it_level_source ★NEW
+dict notes ★NEW
+datetime last_login_at
+datetime created_at
+datetime updated_at
}
class Conversation {
+str id
+str corp_id
+str employee_id
+str employee_name
+str department
+str status
+bool is_vip
+bool is_pinned
+bool is_todo
+int urgency_score
+dict tags
+str assigned_agent_id
+list collaborating_agent_ids
+int impact_scope ★NEW
+bool is_blocking ★NEW
+str emotion_state ★NEW
+datetime last_message_at
+str last_message_summary
+datetime created_at
+datetime updated_at
}
class TodoItem {
+str id
+str type
+str title
+str priority
+dict description
+str status
+str assigned_agent_id
+str corp_id
+datetime created_at
+datetime updated_at
}
class TroubleshootingTemplate {
+str id
+str name
+str category
+list path_steps
+dict flowchart
+bool is_active
+datetime created_at
+datetime updated_at
}
Employee "1" --> "*" Conversation : has
Conversation "1" --> "*" TodoItem : may generate
TroubleshootingTemplate "1" --> "0..1" Conversation : applied to
note for Employee "it_level: bronze|silver|gold|platinum|diamond|star|king\nit_level_source: system|manual"
note for Conversation "impact_scope: 受影响人数\nis_blocking: 是否阻断性\nemotion_state: normal|anxious|angry|urgent"
note for TodoItem "type: ticket|approval|device\npriority: urgent|high|normal\nstatus: pending|processing|resolved"
note for TroubleshootingTemplate "category: vpn|email|system|account\npath_steps: [{label, status}]\nflowchart: 递归树结构"
```
### 3.2 前端 TypeScript 接口新增
```typescript
// ---- api/conversation.ts 新增字段 ----
export interface Conversation {
// ... 现有字段 ...
impact_scope: number // ★NEW 影响范围(受影响人数)
is_blocking: boolean // ★NEW 阻断性标记
emotion_state: string // ★NEW 情绪状态: normal/anxious/angry/urgent
}
// ---- api/todo.ts ----
export interface TodoItem {
id: string
type: 'ticket' | 'approval' | 'device'
title: string
priority: 'urgent' | 'high' | 'normal'
description: Record<string, any>
status: 'pending' | 'processing' | 'resolved'
assigned_agent_id: string | null
corp_id: string
created_at: string
updated_at: string
}
// ---- api/troubleshooting.ts ----
export interface PathStep {
label: string
status: 'done' | 'current' | 'pending'
}
export interface FlowchartNode {
id: string
type: 'step' | 'decision'
label: string
status?: 'done' | 'current' | 'pending'
children?: FlowchartNode[]
yes_branch?: FlowchartNode
no_branch?: FlowchartNode
}
export interface TroubleshootingTemplate {
id: string
name: string
category: 'vpn' | 'email' | 'system' | 'account'
path_steps: PathStep[]
flowchart: FlowchartNode
is_active: boolean
created_at: string
updated_at: string
}
// ---- stores/theme.ts ----
export type ThemeMode = 'light' | 'dark'
// ---- stores/todo.ts ----
export interface TodoState {
todoList: TodoItem[]
loading: boolean
}
```
### 3.3 后端 Pydantic Schema 新增
```python
# ---- schemas/employee.py 新增 ----
class ItLevelUpdateRequest(BaseModel):
it_level: str = Field(..., pattern="^(bronze|silver|gold|platinum|diamond|star|king)$")
source: str = Field(default="manual", pattern="^(system|manual)$")
# ---- schemas/todo_item.py ----
class TodoItemResponse(BaseModel):
id: str
type: str # ticket/approval/device
title: str
priority: str # urgent/high/normal
description: Dict[str, Any]
status: str # pending/processing/resolved
assigned_agent_id: Optional[str] = None
corp_id: str
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
class TodoStatusUpdateRequest(BaseModel):
status: str = Field(..., pattern="^(pending|processing|resolved)$")
# ---- schemas/troubleshooting_template.py ----
class TroubleshootingTemplateResponse(BaseModel):
id: str
name: str
category: str
path_steps: List[Dict[str, Any]]
flowchart: Dict[str, Any]
is_active: bool
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
```
---
## 4. 程序调用流程
### 4.1 主题切换流程
```mermaid
sequenceDiagram
participant U as 坐席
participant TB as TopBar.vue
participant TS as useThemeStore
participant UT as useTheme.ts
participant DOM as document.documentElement
participant LS as localStorage
U->>TB: 点击 ☀️/🌙 切换开关
TB->>TS: toggleTheme()
TS->>TS: currentTheme = currentTheme === 'light' ? 'dark' : 'light'
TS->>UT: applyTheme(currentTheme)
UT->>DOM: setAttribute('data-theme', theme)
UT->>LS: setItem('theme', theme)
DOM-->>DOM: CSS 变量自动切换(`:root` / `[data-theme="dark"]`
DOM-->>U: 300ms 过渡动画,界面变色
Note over U,LS: 页面加载时
U->>UT: 首次进入页面
UT->>LS: getItem('theme')
LS-->>UT: 'dark' | 'light' | null
UT->>DOM: setAttribute('data-theme', theme || 'light')
```
### 4.2 待办事项点击 → 中间栏视图切换
```mermaid
sequenceDiagram
participant U as 坐席
participant TP as TodoPanel.vue
participant TDS as useTodoStore
participant WS as Workspace.vue
participant TDV as TaskDetailView.vue
U->>TP: 点击待办条目(type=ticket
TP->>TDS: selectTodoItem(item)
TDS->>TDS: currentTodoItem = item
TDS->>WS: conversationStore.workspaceView = 'task'
WS->>WS: v-if 判断 workspaceView
WS->>TDV: 渲染 TaskDetailView(type='ticket')
TDV->>TDV: 根据 type 渲染对应子视图
Note over U,TDV: 返回聊天视图
U->>TDV: 点击 "← 返回会话"
TDV->>WS: conversationStore.workspaceView = 'chat'
WS->>WS: 切回 ChatArea 渲染
```
### 4.3 排查步骤展开流程
```mermaid
sequenceDiagram
participant U as 坐席
participant TSB as TroubleshootBar.vue
participant TS as troubleshooting API
participant FN as FlowchartNode.vue
Note over TSB: 默认显示路径方块(横向滚动)
TSB->>TS: GET /api/troubleshooting-templates?category=vpn
TS-->>TSB: 返回模板列表
TSB->>TSB: 渲染 path_steps 横向方块
U->>TSB: 点击 "▶ 展开全流程图"
TSB->>TSB: expanded = true
TSB->>FN: 递归渲染 flowchart 节点
FN->>FN: type='step' → 渲染步骤节点
FN->>FN: type='decision' → 渲染判断节点(❓黄底)
FN->>FN: 递归渲染 yes_branch / no_branch
Note over TSB: max-height 过渡 0.35s 展开
```
### 4.4 AI 推荐内联回复填入
```mermaid
sequenceDiagram
participant U as 坐席
participant CA as ChatArea.vue
participant ARI as AiRecommendInline.vue
participant RB as ReplyBox.vue
participant CS as conversationStore
CA->>ARI: 坐席未回复 + 有用户消息 → 显示
ARI->>ARI: 渲染 1-3 条 AI 推荐卡片
alt 快捷键 Ctrl+1
U->>ARI: Ctrl+1 按下
ARI->>CS: pendingReplyText = recommendations[0].content
CS-->>RB: watch pendingReplyText → 填入输入框并聚焦
else 点击卡片
U->>ARI: 点击第 N 张卡片
ARI->>CS: pendingReplyText = recommendations[N].content
CS-->>RB: 填入输入框并聚焦
end
U->>RB: 发送回复
RB->>ARI: 坐席已回复 → 自动隐藏
```
### 4.5 右栏快速回复键盘导航
```mermaid
sequenceDiagram
participant U as 坐席
participant KS as useKeyboardShortcuts
participant QRP as QuickReplyPanel.vue
participant CS as conversationStore
Note over KS: 全局注册(仅在输入框未聚焦时生效)
alt Alt+1 切换分类
U->>KS: Alt+1 按下
KS->>QRP: activeCategory = categories[0]
QRP->>QRP: 重新渲染当前分类回复列表
end
alt ↑↓ 导航条目
U->>KS: ↓ 按下
KS->>QRP: selectedIndex++
QRP->>QRP: 高亮下一条回复
end
alt Enter 确认填入
U->>KS: Enter 按下
KS->>QRP: 使用选中条目
QRP->>CS: pendingReplyText = selected.content
CS-->>QRP: ReplyBox 填入
end
alt / 聚焦搜索
U->>KS: / 按下
KS->>QRP: focusSearchInput()
end
```
---
## 5. 任务列表
### 5.1 所需依赖包
```yaml
# 前端(npm)— 无新增包
# CSS 变量 + 原生 DOM API 实现主题,无需额外依赖
# 后端(pip)— 无新增包
# SQLAlchemy 2.0 / Pydantic v2 / FastAPI 已包含所需功能
# 开发依赖(可选)
# - @vue/test-utils: 单元测试(如需)
```
> **说明**:本次增量无需新增任何 npm/pip 依赖。主题系统使用原生 CSS 变量,快捷键使用原生 `addEventListener`,决策树渲染使用 Vue 递归组件。
### 5.2 任务分解
---
#### T01: 项目基础设施 — 主题系统 + 后端模型扩展 + 入口改造
| 项目 | 说明 |
|------|------|
| **优先级** | P0 |
| **依赖** | 无 |
| **预估文件数** | ~14 |
| **关键变更点** | |
**前端文件**:
- `styles/global.css` — 新增深色主题 CSS 变量块,替换硬编码色为 `var(--bg-primary)`
- `composables/useTheme.ts` — 主题切换逻辑
- `stores/theme.ts` — 主题 Pinia Store
- `views/Workspace.vue` — 应用 `data-theme`,移除顶部栏到 TopBar
- `components/layout/TopBar.vue` — 新建顶栏(系统名称 + 主题切换 + 坐席状态 + 应急模式)
**后端文件**:
- `models/employee.py` — 新增 `it_level`/`it_level_source`/`notes`
- `models/conversation.py` — 新增 `impact_scope`/`is_blocking`/`emotion_state`
- `models/todo_item.py` — 新建 TodoItem 模型
- `models/troubleshooting_template.py` — 新建 TroubleshootingTemplate 模型
- `models/__init__.py` — 导入新模型
- `schemas/employee.py` — 新增 `ItLevelUpdateRequest`
- `schemas/conversation.py` — ConversationResponse 新增字段
- `schemas/todo_item.py` — 新建
- `schemas/troubleshooting_template.py` — 新建
**验收标准**:
1. `document.documentElement.setAttribute('data-theme', 'dark')` 后全局色值切换
2. 刷新页面后主题持久化
3. 后端新增字段在 API 响应中返回
4. SQLite 自动建表包含 `todo_items``troubleshooting_templates`
---
#### T02: 左栏改造 — 三段折叠 + 优先级图标 + 待办面板
| 项目 | 说明 |
|------|------|
| **优先级** | P0 |
| **依赖** | T01 |
| **预估文件数** | ~7 |
| **关键变更点** | |
**前端文件**:
- `components/conversation/ConversationList.vue` — 重构为 3 段折叠 + 搜索标签
- `components/conversation/ConversationItem.vue` — 新增优先级图标渲染
- `components/conversation/TodoPanel.vue` — 新建待办事项面板
- `stores/todo.ts` — 新建待办 Pinia Store
- `api/todo.ts` — 新建待办 API
- `api/conversation.ts` — Conversation 接口新增 `impact_scope`/`is_blocking`/`emotion_state`
**后端文件**:
- `api/todo_items.py` — 新建待办 CRUD API(含 Mock 数据)
- `api/router.py` — 注册待办路由
**数据映射规则**6 区 → 3 段):
| 原 6 区 | 新 3 段 | 映射逻辑 |
|---------|---------|---------|
| 待接单 (queued) | 📌 我的会话 | `is_mine || status === 'queued'` |
| 我的会话 (serving + is_mine) | 📌 我的会话 | `status === 'serving' && is_mine` |
| 协作会话 | 📌 我的会话 | `is_collaborator` |
| 其他坐席会话 | 👥 同事会话 | `!is_mine && status === 'serving'` |
| AI 处理区 | 👥 同事会话 | `status === 'ai_handling'` |
| 已结单 | 🕐 历史会话 | `status === 'resolved'` |
**验收标准**:
1. 三段折叠:📌我的默认展开,👥同事/🕐历史默认折叠
2. 优先级图标:⛔ 阻断性红底、👥 影响范围黄底、⭐ 角色等级紫底、🔁 重复问题橙底
3. 搜索标签:全部/待处理/进行中/已完成 药丸筛选
4. 待办面板 max-height: 220px,内部滚动
5. 点击待办条目 → `workspaceView = 'task'`
---
#### T03: 中栏改造 — 用户信息栏 + AI 推荐内联 + 排查步骤栏
| 项目 | 说明 |
|------|------|
| **优先级** | P0 |
| **依赖** | T01 |
| **预估文件数** | ~8 |
| **关键变更点** | |
**前端文件**:
- `components/chat/ChatArea.vue` — 替换顶部栏为 `UserInfoBar`;底部挂载 `TroubleshootBar`;消息中插入 `AiRecommendInline`
- `components/chat/UserInfoBar.vue` — 新建(chips + 展开详情 6 卡片)
- `components/chat/ItLevelBadge.vue` — 新建(7 级段位徽标)
- `components/chat/AiRecommendInline.vue` — 新建(内联 AI 推荐)
- `components/chat/TroubleshootBar.vue` — 新建(路径视图 + 流程图)
- `components/chat/FlowchartNode.vue` — 新建(递归决策树节点)
- `composables/useKeyboardShortcuts.ts` — 新建(Ctrl+1/2/3 注册)
- `api/troubleshooting.ts` — 新建排查模板 API
**后端文件**:
- `api/troubleshooting_templates.py` — 新建排查模板 CRUD API(含 Mock 数据 5-8 套模板)
- `api/router.py` — 注册排查模板路由
- `api/employees.py` — 新增 `PUT /api/employees/{id}/it-level` 端点
**验收标准**:
1. UserInfoBar 常驻显示 chips(情绪+时长+轮次+重复+备注+IT等级)
2. 点击展开 6 卡片 3 列 gridmax-height 动画 0.35s
3. AI 推荐仅在坐席未回复时显示,Ctrl+1/2/3 快捷填入
4. TroubleshootBar 始终可见,默认路径方块;展开流程图含判断节点
5. 快捷键仅在输入框未聚焦时生效
---
#### T04: 右栏改造 + 任务详情视图
| 项目 | 说明 |
|------|------|
| **优先级** | P0 |
| **依赖** | T01, T02 |
| **预估文件数** | ~5 |
| **关键变更点** | |
**前端文件**:
- `components/assistant/AiAssistantPanel.vue` — 完全重写(上下两区)
- `components/assistant/AiSuggestReply.vue` — 适配新布局 + 置信度显示
- `components/assistant/QuickReplyPanel.vue` — 重写(搜索置顶 + Alt 分类 + ↑↓ 导航 + Enter + 键盘指南)
- `components/chat/TaskDetailView.vue` — 新建(工单/审批/设备 3 种子视图)
**废弃文件**:
- `components/assistant/RiskAlert.vue` — 移除引用
- `components/assistant/UserInfoPanel.vue` — 移除引用
**验收标准**:
1. 右栏上方 ~1/3 AI 推荐区,下方 ~2/3 快速回复区
2. Alt+1~5 切换分类,↑↓ 导航条目,Enter 确认填入,/ 聚焦搜索
3. 底部常驻键盘指南条
4. TaskDetailView 支持 3 种子视图(工单/审批/设备),"← 返回会话" 切回聊天
5. RiskAlert.vue、UserInfoPanel.vue 不再被任何组件引用
---
#### T05: 集成联调 + 快捷键完善 + 样式打磨
| 项目 | 说明 |
|------|------|
| **优先级** | P1 |
| **依赖** | T01, T02, T03, T04 |
| **预估文件数** | ~3 |
| **关键变更点** | |
**前端文件**:
- `composables/useKeyboardShortcuts.ts` — 完善全局快捷键注册/卸载(与 T03 初版合并后打磨)
- `styles/global.css` — 主题过渡动画完善 + 深色模式边缘 case 修复
- `views/Workspace.vue` — 最终集成调整(视图切换状态管理 + 双主题适配验证)
**验收标准**:
1. 主题切换过渡 ≤ 300ms,所有组件双主题无色值遗漏
2. 快捷键全局生效:Ctrl+1/2/3AI 推荐)、Alt+1~5(快速回复分类)、↑↓ Enter /(快速回复操作)
3. 快捷键与输入框不冲突(输入框聚焦时快捷键不触发)
4. 视图切换(聊天↔任务)状态不丢失,WebSocket 保持连接
5. 王者徽标 `king-glow` 发光动画正常
---
### 5.3 任务依赖图
```mermaid
graph LR
T01[T01: 基础设施<br/>主题+模型+TopBar] --> T02[T02: 左栏改造<br/>三段折叠+待办面板]
T01 --> T03[T03: 中栏改造<br/>用户信息栏+AI推荐+排查]
T01 --> T04[T04: 右栏+任务视图<br/>AI助手重构+TaskDetail]
T02 --> T04
T01 --> T05[T05: 集成联调<br/>快捷键+样式打磨]
T02 --> T05
T03 --> T05
T04 --> T05
```
---
## 6. 共享知识
### 6.1 CSS 变量命名规范
```css
:root {
/* 背景 */
--bg-primary: #f5f7fa; /* 主背景 */
--bg-secondary: #ffffff; /* 次背景(卡片/面板) */
--bg-tertiary: #f0f2f5; /* 三级背景(段头/分区) */
--bg-hover: #e8eaed; /* 悬停背景 */
--bg-active: #d9dce0; /* 激活/选中背景 */
--bg-accent-soft: #ecf5ff; /* 强调色浅底 */
/* 文字 */
--text-primary: #303133; /* 主文字 */
--text-secondary: #606266; /* 次文字 */
--text-tertiary: #909399; /* 辅助文字 */
--text-placeholder: #c0c4cc;/* 占位文字 */
/* 边框 */
--border-color: #e4e7ed;
--border-light: #ebeef5;
/* 强调色 */
--accent: #409eff;
--accent-hover: #66b1ff;
--accent-soft: #ecf5ff;
/* 语义色 */
--color-success: #67c23a;
--color-warning: #e6a23c;
--color-danger: #f56c6c;
--color-info: #909399;
/* 深色主题覆盖 */
}
[data-theme="dark"] {
--bg-primary: #0f1923;
--bg-secondary: #151f2b;
--bg-tertiary: #1a2736;
--bg-hover: #1e3044;
--bg-active: #243b52;
--bg-accent-soft: rgba(77, 166, 255, 0.12);
--text-primary: #e8edf2;
--text-secondary: #8ba1b7;
--text-tertiary: #5c7a94;
--text-placeholder: #3d5568;
--border-color: #243b52;
--border-light: #1e3044;
--accent: #4da6ff;
--accent-hover: #73b9ff;
--accent-soft: rgba(77, 166, 255, 0.12);
--color-success: #52c41a;
--color-warning: #faad14;
--color-danger: #ff4d4f;
--color-info: #8ba1b7;
}
```
**使用规则**
- 所有新增组件**必须**使用 CSS 变量,禁止硬编码色值
- 现有组件在修改时逐步替换硬编码为变量
- Element Plus 组件的主题覆盖通过 `:deep()` 选择器 + CSS 变量实现
### 6.2 组件通信模式
| 场景 | 模式 | 示例 |
|------|------|------|
| 跨组件快捷键填入 | `conversationStore.pendingReplyText` | AI推荐/快速回复 → ReplyBox |
| 视图切换 | `conversationStore.workspaceView` | TodoPanel → Workspace → ChatArea/TaskDetailView |
| 主题切换 | `useThemeStore.currentTheme` + `data-theme` 属性 | TopBar → 全局 DOM |
| 待办事项选中 | `useTodoStore.currentTodoItem` | TodoPanel → TaskDetailView |
| 排查模板选中 | `local ref` in TroubleshootBar | 不需跨组件,局部状态 |
### 6.3 Store 状态结构约定
```typescript
// ---- conversationStore 扩展 ----
{
// ... 现有状态 ...
workspaceView: 'chat' | 'task' // ★NEW 中间栏当前视图
}
// ---- themeStore ----
{
currentTheme: 'light' | 'dark'
toggleTheme(): void
}
// ---- todoStore ----
{
todoList: TodoItem[]
currentTodoItem: TodoItem | null
loading: boolean
fetchTodoList(): Promise<void>
selectTodoItem(item: TodoItem): void
updateTodoStatus(id: string, status: string): Promise<void>
}
```
### 6.4 API 响应格式约定
沿用现有 `{code, data, message}` 格式:
```json
{
"code": 0,
"data": { ... },
"message": "success"
}
```
### 6.5 IT 等级枚举映射
```typescript
const IT_LEVELS = [
{ key: 'bronze', label: '青铜', level: 1, cssClass: 'bronze' },
{ key: 'silver', label: '白银', level: 2, cssClass: 'silver' },
{ key: 'gold', label: '黄金', level: 3, cssClass: 'gold' },
{ key: 'platinum', label: '铂金', level: 4, cssClass: 'platinum' },
{ key: 'diamond', label: '钻石', level: 5, cssClass: 'diamond' },
{ key: 'star', label: '星耀', level: 6, cssClass: 'star' },
{ key: 'king', label: '王者', level: 7, cssClass: 'king' },
] as const
```
### 6.6 优先级图标映射
```typescript
const PRIORITY_ICONS = [
{ key: 'is_blocking', icon: '⛔', cssClass: 'pi-blocked', bg: '#f56c6c' },
{ key: 'impact_scope', icon: '👥', cssClass: 'pi-impact', bg: '#e6a23c', highThreshold: 5 },
{ key: 'role_level', icon: '⭐', cssClass: 'pi-role', bg: '#9b59b6' },
{ key: 'is_repeat', icon: '🔁', cssClass: 'pi-repeat', bg: '#f59e0b' },
] as const
```
---
## 7. 待明确事项
| # | 事项 | 影响范围 | 建议默认值 | 优先级 |
|---|------|---------|-----------|--------|
| 1 | **情绪状态识别方式**:AI 自动分析 vs 坐席手动标记? | BE-02, FE-04 | P0 先坐席手动标记,P1 加 AI 辅助 | P0 |
| 2 | **影响范围数据来源**:坐席标记 vs 系统自动判断? | BE-02, FE-02 | P0 坐席手动标记,`impact_scope` 默认 0 | P0 |
| 3 | **原 6 区→3 段映射**:协作会话归入"我的会话"还是"同事会话" | FE-02 | 协作会话归入"📌我的会话"(因为坐席仍在参与) | P0 |
| 4 | **排查模板匹配方式**:自动匹配 vs 坐席手动选择? | BE-04, FE-06 | P0 坐席手动选择,P2 做自动匹配 | P0 |
| 5 | **同事会话范围**:全部坐席 vs 同组坐席? | FE-02 | P0 全部坐席(前端过滤可后续加) | P1 |
| 6 | **排查步骤栏最小/最大高度** | FE-06 | 最小 44px(路径方块),最大 300px(展开流程图) | P1 |
| 7 | **AI 推荐回复触发时机**:每条用户消息后都触发? | FE-05 | 仅坐席未回复时显示(已确认) | P0 |
| 8 | **IT 等级在用户端显示方式**:完整徽标 vs 简化文本? | FE-04 | 需与用户端产品确认,坐席端先用完整徽标 | P2 |
| 9 | **Element Plus 深色主题适配**EP 组件(ElInput/ElTag 等)在深色模式下的样式覆盖策略 | 全局 | 通过 `:deep()` + CSS 变量覆盖 EP 的 `--el-*` 变量 | P1 |
| 10 | **排查模板 Mock 数据结构**flowchart JSON 的具体递归结构定义 | BE-04 | 需定义标准节点结构(见 §3.2 FlowchartNode | P0 |
---
## 附录 A:关键组件 Props/Emits 定义
### TopBar.vue
```typescript
// Props
interface TopBarProps {
agentName: string
agentStatus: 'online' | 'busy' | 'offline'
emergencyMode: boolean
}
// Emits
interface TopBarEmits {
toggleTheme: []
changeStatus: [status: string]
toggleEmergency: [enabled: boolean]
logout: []
}
```
### UserInfoBar.vue
```typescript
// Props
interface UserInfoBarProps {
employeeName: string
department: string
position: string
itLevel: string
emotionState: string
waitDuration: number // 秒
conversationCount: number
isRepeat: boolean
hasNotes: boolean
}
// Emits
interface UserInfoBarEmits {
adjustItLevel: [newLevel: string]
}
```
### TroubleshootBar.vue
```typescript
// Props
interface TroubleshootBarProps {
category?: 'vpn' | 'email' | 'system' | 'account'
}
// 无 Emits — 坐席交互仅影响组件内部状态
```
### TaskDetailView.vue
```typescript
// Props
interface TaskDetailViewProps {
todoItem: TodoItem
}
// Emits
interface TaskDetailViewEmits {
back: [] // 返回聊天视图
statusChanged: [id: string, newStatus: string]
}
```
### AiRecommendInline.vue
```typescript
// Props
interface AiRecommendInlineProps {
recommendations: Array<{
id: string
content: string
confidence: number
}>
visible: boolean // 仅坐席未回复时 true
}
// Emits
interface AiRecommendInlineEmits {
fillReply: [content: string]
}
```
---
## 附录 B:数据库迁移注意事项
### SQLite(本地开发)
SQLite 使用 `Base.metadata.create_all` 自动建表,新增模型只需在 `models/__init__.py` 中导入即可。新增字段需注意:
- SQLite 不支持 `ALTER TABLE ADD COLUMN` 添加带 `NOT NULL` 且无默认值的列
- 所有新增字段**必须**设置 `default` 值(已在模型定义中保证)
### PostgreSQL(生产)
使用 Alembic 迁移:
```bash
alembic revision --autogenerate -m "v53_add_it_level_impact_scope_todo_troubleshooting"
alembic upgrade head
```
新增表:`todo_items``troubleshooting_templates`
新增列:`employees.it_level``employees.it_level_source``employees.notes``conversations.impact_scope``conversations.is_blocking``conversations.emotion_state`