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

915 lines
31 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.
# 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`