168 lines
6.5 KiB
Markdown
168 lines
6.5 KiB
Markdown
---
|
||
name: ai-speaking-dialog
|
||
overview: 新建 AI 口语对话页面 SpeakingDialog.vue,复用豆包 TTS API(同 Pronunciation.vue),实现用户输入文字/语音 → AI 外教回复 → TTS 朗读的完整对话流程,并在首页和路由中注册入口。
|
||
design:
|
||
architecture:
|
||
framework: vue
|
||
styleKeywords:
|
||
- Glassmorphism
|
||
- 深色背景
|
||
- 紫蓝渐变
|
||
- 聊天气泡
|
||
- 毛玻璃面板
|
||
- 微动效
|
||
fontSystem:
|
||
fontFamily: PingFang SC
|
||
heading:
|
||
size: 1.5rem
|
||
weight: 600
|
||
subheading:
|
||
size: 1rem
|
||
weight: 600
|
||
body:
|
||
size: 1rem
|
||
weight: 400
|
||
colorSystem:
|
||
primary:
|
||
- "#6366f1"
|
||
- "#8b5cf6"
|
||
background:
|
||
- var(--card-bg)
|
||
- rgba(0,0,0,0.2)
|
||
text:
|
||
- var(--text-primary)
|
||
- var(--text-secondary)
|
||
functional:
|
||
- "#22c55e"
|
||
- "#ef4444"
|
||
- "#f59e0b"
|
||
todos:
|
||
- id: config-proxy-and-router
|
||
content: 在 vite.config.js 中新增 /ark-api 代理,在 router/index.js 中注册 /speaking 路由,在 HomePage.vue 中将 card-2 的 route 改为 /speaking
|
||
status: completed
|
||
- id: create-speaking-view
|
||
content: 新建 src/views/Speaking.vue,实现完整的 AI 口语对话页面:场景选择、音色选择、聊天气泡布局、Ark API 调用与降级模板、TTS 自动朗读与重播
|
||
status: completed
|
||
dependencies:
|
||
- config-proxy-and-router
|
||
---
|
||
|
||
## 用户需求
|
||
|
||
基于现有项目的豆包 TTS API,新建一个 AI 口语对话页面,实现与 AI 英语外教的实时对话练习功能。
|
||
|
||
## 产品概述
|
||
|
||
页面采用聊天气泡布局,用户在底部输入框输入英语文本,AI 外教自动回复并通过豆包 TTS 合成语音播放。页面风格与现有项目保持一致(深色玻璃拟态风格),并接入首页 card-2 入口。
|
||
|
||
## 核心功能
|
||
|
||
- **对话界面**:聊天气泡布局,用户消息靠右(蓝紫色),AI 消息靠左(带头像),支持滚动历史记录
|
||
- **AI 回复**:调用字节跳动 Ark 大模型 API(`/ark-api/api/v3/chat/completions`)生成英语对话回复;未配置 API Key 时降级为预设模板回复
|
||
- **TTS 朗读**:AI 每条回复自动调用豆包 TTS 合成语音播放,消息旁提供重播按钮,播放时显示动态音波动画
|
||
- **音色选择**:顶部可选英语音色(Dacey 美音、Tim 美音、Tina 英音等)
|
||
- **场景选择**:提供日常对话、面试练习、旅游英语、购物场景等预设场景,切换场景重置对话并注入对应系统提示词
|
||
- **路由与入口**:注册 `/speaking` 路由,首页 card-2 的 `route` 改为 `/speaking`
|
||
|
||
## 技术栈
|
||
|
||
- Vue 3 Composition API(`<script setup>`)+ Vite,与现有项目完全一致
|
||
- Vue Router 4,复用现有路由配置模式
|
||
- 原生 CSS(scoped),复用现有 CSS 变量(`--card-bg`、`--accent-1` 等)
|
||
- 豆包 TTS V3 API(已有代理 `/tts-api`)
|
||
- 字节跳动 Ark Chat API(新增代理 `/ark-api`)
|
||
|
||
## 实现方案
|
||
|
||
### AI 对话回复
|
||
|
||
调用 Ark API(`POST /ark-api/api/v3/chat/completions`),携带系统提示词(根据场景动态注入)和对话历史,模型使用 `doubao-pro-4k`。用户需在页面顶部配置 `ARK_API_KEY`;若为空则使用预设英语回复模板降级,保证页面可用性。
|
||
|
||
### TTS 朗读
|
||
|
||
复用 Pronunciation.vue 中已验证的流式 Chunked JSON 解析逻辑,AI 消息生成后自动触发 TTS 合成并播放。每条 AI 消息独立维护播放状态,支持重播,同一时刻只允许一个音频实例播放。
|
||
|
||
### 对话历史管理
|
||
|
||
维护 `messages` 数组(`{ role, content, audioUrl, isPlaying, isLoading }`),AI 回复时先插入 loading 占位气泡,完成后替换内容并触发 TTS,避免界面跳动。
|
||
|
||
### 性能考量
|
||
|
||
- TTS 音频 Blob URL 在组件卸载时统一 `revokeObjectURL`,防止内存泄漏
|
||
- 对话历史最多保留最近 20 条发送给 API,避免 token 超限
|
||
- 消息新增后自动滚动到底部(`nextTick` + `scrollIntoView`)
|
||
|
||
## 架构设计
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[用户输入文本] --> B[发送消息]
|
||
B --> C{ARK_API_KEY 是否配置?}
|
||
C -- 是 --> D[调用 Ark Chat API]
|
||
C -- 否 --> E[预设模板回复]
|
||
D --> F[AI 回复文本]
|
||
E --> F
|
||
F --> G[插入 AI 消息气泡]
|
||
G --> H[调用豆包 TTS API]
|
||
H --> I[流式解析 Chunked JSON]
|
||
I --> J[合并音频 Blob 自动播放]
|
||
J --> K[消息旁显示重播按钮]
|
||
```
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
src/
|
||
├── views/
|
||
│ ├── HomePage.vue # [MODIFY] card-2 的 route: null 改为 route: '/speaking'
|
||
│ ├── Pronunciation.vue # [不变]
|
||
│ └── Speaking.vue # [NEW] AI 口语对话页面主组件
|
||
│ # 包含:场景选择栏、音色选择、聊天气泡列表、底部输入框
|
||
│ # 实现:Ark API 调用、TTS 合成复用逻辑、消息状态管理、音频生命周期管理
|
||
└── router/
|
||
└── index.js # [MODIFY] 新增 /speaking 路由指向 Speaking.vue
|
||
vite.config.js # [MODIFY] 新增 /ark-api 代理指向 https://ark.cn-beijing.volces.com
|
||
```
|
||
|
||
## 关键接口定义
|
||
|
||
```js
|
||
// 消息数据结构
|
||
{
|
||
id: Number, // 唯一标识
|
||
role: 'user' | 'assistant',
|
||
content: String, // 消息文本
|
||
audioUrl: String | null, // TTS 生成的 Blob URL
|
||
isPlaying: Boolean,
|
||
isLoading: Boolean // AI 回复生成中占位
|
||
}
|
||
|
||
// 场景配置
|
||
{
|
||
id: String,
|
||
name: String, // 显示名称
|
||
systemPrompt: String // 注入给 Ark API 的系统提示词
|
||
}
|
||
```
|
||
|
||
## 设计风格
|
||
|
||
延续现有项目的深色玻璃拟态(Glassmorphism)风格,与 Pronunciation.vue 视觉语言保持一致。整体背景深色,面板使用 `--card-bg` 半透明毛玻璃效果,强调色使用紫蓝渐变(`--accent-1` / `#8b5cf6`)。
|
||
|
||
## 页面布局
|
||
|
||
### 顶部导航栏
|
||
|
||
返回按钮(左)+ 页面标题"AI 口语对话"(居中)+ 音色选择下拉(右)。与 Pronunciation.vue 导航栏结构一致。
|
||
|
||
### 场景选择栏
|
||
|
||
横向滚动 Tab 条,提供"日常对话 / 面试练习 / 旅游英语 / 购物场景 / 自由练习"5 个场景,选中态使用 accent 色高亮,切换时重置对话。
|
||
|
||
### 聊天消息区域
|
||
|
||
占据页面主体,垂直滚动。AI 消息靠左(头像 + 气泡),用户消息靠右(气泡)。AI 气泡下方显示播放/重播按钮及音波动画。Loading 状态显示三点跳动动画。
|
||
|
||
### 底部输入区域
|
||
|
||
固定在底部,输入框 + 发送按钮。发送中禁用输入,按钮显示 loading 状态。支持 Enter 发送(Shift+Enter 换行)。 |