31 KiB
31 KiB
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 Store(currentTheme 响应式 + toggle 方法) |
| 5 | stores/todo.ts |
🆕 | 待办事项 Pinia Store(todoList + 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 类图
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 接口新增
// ---- 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 新增
# ---- 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 主题切换流程
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 待办事项点击 → 中间栏视图切换
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 排查步骤展开流程
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 推荐内联回复填入
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 右栏快速回复键盘导航
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 所需依赖包
# 前端(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 Storeviews/Workspace.vue— 应用data-theme,移除顶部栏到 TopBarcomponents/layout/TopBar.vue— 新建顶栏(系统名称 + 主题切换 + 坐席状态 + 应急模式)
后端文件:
models/employee.py— 新增it_level/it_level_source/notesmodels/conversation.py— 新增impact_scope/is_blocking/emotion_statemodels/todo_item.py— 新建 TodoItem 模型models/troubleshooting_template.py— 新建 TroubleshootingTemplate 模型models/__init__.py— 导入新模型schemas/employee.py— 新增ItLevelUpdateRequestschemas/conversation.py— ConversationResponse 新增字段schemas/todo_item.py— 新建schemas/troubleshooting_template.py— 新建
验收标准:
document.documentElement.setAttribute('data-theme', 'dark')后全局色值切换- 刷新页面后主题持久化
- 后端新增字段在 API 响应中返回
- 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 Storeapi/todo.ts— 新建待办 APIapi/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 |
| 我的会话 (serving + is_mine) | 📌 我的会话 | status === 'serving' && is_mine |
| 协作会话 | 📌 我的会话 | is_collaborator |
| 其他坐席会话 | 👥 同事会话 | !is_mine && status === 'serving' |
| AI 处理区 | 👥 同事会话 | status === 'ai_handling' |
| 已结单 | 🕐 历史会话 | status === 'resolved' |
验收标准:
- 三段折叠:📌我的默认展开,👥同事/🕐历史默认折叠
- 优先级图标:⛔ 阻断性红底、👥 影响范围黄底、⭐ 角色等级紫底、🔁 重复问题橙底
- 搜索标签:全部/待处理/进行中/已完成 药丸筛选
- 待办面板 max-height: 220px,内部滚动
- 点击待办条目 →
workspaceView = 'task'
T03: 中栏改造 — 用户信息栏 + AI 推荐内联 + 排查步骤栏
| 项目 | 说明 |
|---|---|
| 优先级 | P0 |
| 依赖 | T01 |
| 预估文件数 | ~8 |
| 关键变更点 |
前端文件:
components/chat/ChatArea.vue— 替换顶部栏为UserInfoBar;底部挂载TroubleshootBar;消息中插入AiRecommendInlinecomponents/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端点
验收标准:
- UserInfoBar 常驻显示 chips(情绪+时长+轮次+重复+备注+IT等级)
- 点击展开 6 卡片 3 列 grid,max-height 动画 0.35s
- AI 推荐仅在坐席未回复时显示,Ctrl+1/2/3 快捷填入
- TroubleshootBar 始终可见,默认路径方块;展开流程图含判断节点
- 快捷键仅在输入框未聚焦时生效
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/3 AI 推荐区,下方 ~2/3 快速回复区
- Alt+1~5 切换分类,↑↓ 导航条目,Enter 确认填入,/ 聚焦搜索
- 底部常驻键盘指南条
- TaskDetailView 支持 3 种子视图(工单/审批/设备),"← 返回会话" 切回聊天
- RiskAlert.vue、UserInfoPanel.vue 不再被任何组件引用
T05: 集成联调 + 快捷键完善 + 样式打磨
| 项目 | 说明 |
|---|---|
| 优先级 | P1 |
| 依赖 | T01, T02, T03, T04 |
| 预估文件数 | ~3 |
| 关键变更点 |
前端文件:
composables/useKeyboardShortcuts.ts— 完善全局快捷键注册/卸载(与 T03 初版合并后打磨)styles/global.css— 主题过渡动画完善 + 深色模式边缘 case 修复views/Workspace.vue— 最终集成调整(视图切换状态管理 + 双主题适配验证)
验收标准:
- 主题切换过渡 ≤ 300ms,所有组件双主题无色值遗漏
- 快捷键全局生效:Ctrl+1/2/3(AI 推荐)、Alt+1~5(快速回复分类)、↑↓ Enter /(快速回复操作)
- 快捷键与输入框不冲突(输入框聚焦时快捷键不触发)
- 视图切换(聊天↔任务)状态不丢失,WebSocket 保持连接
- 王者徽标
king-glow发光动画正常
5.3 任务依赖图
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 变量命名规范
: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 状态结构约定
// ---- 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} 格式:
{
"code": 0,
"data": { ... },
"message": "success"
}
6.5 IT 等级枚举映射
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 优先级图标映射
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
// Props
interface TopBarProps {
agentName: string
agentStatus: 'online' | 'busy' | 'offline'
emergencyMode: boolean
}
// Emits
interface TopBarEmits {
toggleTheme: []
changeStatus: [status: string]
toggleEmergency: [enabled: boolean]
logout: []
}
UserInfoBar.vue
// 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
// Props
interface TroubleshootBarProps {
category?: 'vpn' | 'email' | 'system' | 'account'
}
// 无 Emits — 坐席交互仅影响组件内部状态
TaskDetailView.vue
// Props
interface TaskDetailViewProps {
todoItem: TodoItem
}
// Emits
interface TaskDetailViewEmits {
back: [] // 返回聊天视图
statusChanged: [id: string, newStatus: string]
}
AiRecommendInline.vue
// 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 迁移:
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