## Context

PPT 编辑器采用三栏布局：左侧 CollapsibleToolbar（配置面板）、中间 Canvas（画布）、右侧 Toolbar（目前隐藏）。english-speaking 功能已完成教师配置流程（Layer 1-3），教师点击"应用配置"后触发 `parentWindow.addTool(77)` 向画布添加一个 `PPTFrameElement`。

画布中的 `BaseFrameElement.vue` 负责渲染 `PPTFrameElement`，按 `toolType` 分支：
- toolType 74 → `<video>` 标签
- toolType 75 → `<iframe>` (bilibili)
- 其他 → `<iframe :src="url">` 或 `<iframe :srcdoc="url">`

当前 toolType 77 走的是通用 iframe 分支。现在要改为直接渲染 Vue 组件，不再使用 iframe。

enspeak demo 项目中的 `TopicDiscussionPreview` 组件提供了完整的学生视角预览，包含三个阶段：准备页（Ready）→ 对话过程（Chatting）→ 完成报告（Completed），需要迁移到 PPT 项目中。

demo 组件依赖树：
```
TopicDiscussionPreview.tsx
├── StudentPreview.tsx        — 16:9 PPT 页面容器
├── DialogueChatView.tsx      — 对话交互（语音条、即时反馈、提示、徽章）
├── OverallReport.tsx         — 整体报告（评分、四维能力、AI 点评、统计）
└── DetailedReport.tsx        — 详细报告（按轮次分组、单句评价卡片）
```

## Goals / Non-Goals

**Goals:**
- 将 TopicDiscussionPreview 从 React + Tailwind 迁移为 Vue 3 + SCSS
- 保持 demo 的完整 UI 和交互逻辑（三阶段切换、模拟对话脚本、模拟评估数据）
- 组件放在 `src/views/Editor/EnglishSpeaking/preview/` 目录下
- 在 `BaseFrameElement.vue` 中 toolType 77 时直接渲染 Vue 组件（替代 iframe）
- 在现有 `src/types/englishSpeaking.ts` 中追加预览相关类型

**Non-Goals:**
- 不实现真实的语音识别/AI 对话（使用模拟脚本）
- 不实现真实的音频播放（静态波形展示）
- 不修改编辑器主布局（index3.vue）
- 不处理与后端 API 的对接

## Decisions

### 1. 集成方式：Vue 组件直接渲染 vs iframe
**选择**: 在 `BaseFrameElement.vue` 的 v-if/v-else-if 链中新增 toolType 77 分支，直接渲染 `<TopicDiscussionPreview>` Vue 组件。
**理由**: 与 iframe 方式相比，Vue 组件可以直接访问 Pinia store 和父组件状态，便于后续配置联动；同时避免了 iframe 通信的复杂性。类似 toolType 74 渲染 `<video>` 的模式。
**实现**: 
```vue
<!-- BaseFrameElement.vue 第 26 行后插入 -->
<TopicDiscussionPreview
  v-else-if="elementInfo.toolType === 77 && !isThumbnail && isVisible"
  :style="{ width: width + 'px', height: height + 'px' }"
/>
```

### 2. 组件架构：平铺式组件 vs 嵌套式组件
**选择**: 平铺式组件（每个子组件独立文件），保持与 demo 一致的层级结构。
**理由**: 每个组件职责明确、代码量大（DialogueChatView 700+ 行），拆分有利于维护。

### 3. 状态管理：组件内 ref vs Pinia store
**选择**: 组件内 ref 管理预览状态（dialogueState、messages 等）。
**理由**: 预览状态是纯 UI 状态，不需要跨组件共享或持久化，使用 store 过度设计。

### 4. 样式方案：Tailwind 转换策略
**选择**: 手动转换为 scoped SCSS，与 PPT 项目其他组件保持一致。
**理由**: PPT 项目不使用 Tailwind，保持技术栈统一。

### 5. 图标方案：SVG 内联
**选择**: 所有图标（MicIcon、VolumeIcon、LightbulbIcon、RefreshIcon、XIcon、ChevronDownIcon、PlayIcon、CheckIcon）使用 SVG 内联方式直接写在模板中。
**理由**: PPT 项目没有统一的图标组件库，内联 SVG 最简单直接，不引入额外依赖。从 enspeak demo 的 `@/components/icons` 中提取 SVG 路径数据。

### 6. 类型文件：扩展现有文件
**选择**: 在现有 `src/types/englishSpeaking.ts` 中追加预览相关类型（`OverallEvaluation`、`SentenceEvaluation`、`AIRole` 等）。
**理由**: 该文件已存在且包含配置侧类型（`TopicDiscussionConfig`、`Role` 等），预览类型与其紧密关联，保持集中管理。

## Risks / Trade-offs

- **[代码量大]** DialogueChatView 有 700+ 行 React 代码，迁移工作量较大 → 分步迁移，先骨架后细节
- **[模拟数据硬编码]** 对话脚本和评分数据硬编码在组件中 → 后续可提取为配置，当前阶段可接受
- **[无真实音频]** 语音条是纯静态的 → 与 demo 行为一致，后续集成真实语音时再改
- **[画布缩放]** BaseFrameElement 内的 Vue 组件需要适配画布的缩放比例 → 组件使用 100% 宽高填充父容器，缩放由 BaseFrameElement 外层处理
- **[SVG 内联冗余]** 多个组件可能重复相同的 SVG 代码 → 当前可接受，后续如果图标增多可抽取为公共组件
