---
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 换行）。