## Context

PPT 项目是基于 Vue 3 + TypeScript + Pinia 的课件编辑器，以 iframe 嵌入 cocorobo 父应用。编辑器使用 `CollapsibleToolbar/index2.vue` 作为左侧栏，已有"英语"tab 入口（`activeSubmenu === 'english'`）。

enspeak demo（React/Next.js）`SpeakingPanelV2.tsx` 实现了三层页面结构：
- Layer 1：英语学科主页（教材/年级/单元联动 + 练习类型选择）
- Layer 2：口语子页面（创建方式切换 + 任务筛选 + 推荐卡片）
- Layer 3：具体配置页（如 TopicDiscussionConfig）

本次只迁移话题讨论（Topic Discussion）功能，只做左侧配置面板。

## Goals / Non-Goals

**Goals:**
- 完整迁移 demo 三层页面结构到 Vue 3（Layer 1 + Layer 2 + Layer 3）
- Layer 1：教材/年级/单元三级联动下拉框 + 单元信息卡 + 练习类型入口
- Layer 2：创建方式切换（参照 demo）+ 推荐卡片列表（目前只有话题讨论类型）
- Layer 3：TopicDiscussionConfig 话题讨论配置（讨论话题、学习目标、练习方式、高级配置）
- AI 生成模式只迁移 UI 壳子，保留切换入口
- 配置完成后通过 `parentWindow.addTool(77)` 集成到课件
- 所有文案走 i18n（cn/en/hk）

**Non-Goals:**
- 不实现听力、阅读、写作的配置页（只做口语 - 话题讨论）
- 不实现右侧主预览区域（由独立项目完成）
- 不实现学生端练习界面
- 不实现 AI 生成的后端功能（只保留 UI）
- 不实现后端 API 对接（静态 JSON 数据，后续改接口）
- 不实现 TTS/ASR
- 不做 teacher-dashboard

## Decisions

### 1. 组件目录结构

```
src/views/Editor/EnglishSpeaking/
  SpeakingPanel.vue              # 三层页面容器（管理 layer1/layer2/config 切换）
  layers/
    Layer1Home.vue               # 英语学科主页：联动下拉框 + 单元信息 + 练习类型入口
    Layer2Speaking.vue            # 口语子页面：创建方式切换 + 推荐卡片
  configs/
    TopicDiscussionConfig.vue    # 话题讨论配置（Layer 3）
  components/
    CurriculumSelector.vue       # 教材/年级/单元三级联动下拉框
    UnitInfoCard.vue             # 单元信息展示卡片
    ExerciseTypeGrid.vue         # 练习类型网格（口语/听力/阅读/写作）
    RecommendCard.vue            # 推荐任务卡片
    CreationModeSwitch.vue       # 创建方式切换（智能推荐/AI生成/手动创建）
    AIGenerationForm.vue         # AI 生成表单（仅 UI 壳子）
  data/
    curriculum.json              # 教材联动数据（来源 units-en.txt）
    topicDiscussionTasks.json    # 话题讨论推荐任务（来源 task.txt）
```

**Why**: 按页面层级 + 职责拆分组件，而非按功能类型一股脑堆在一个文件里。layers/ 对应三层导航，configs/ 对应具体配置页，components/ 是复用的 UI 片段。符合用户要求的"合理分组件"。

**Alternatives considered**: 全部平铺在 EnglishSpeaking/ 下 — 文件多了会混乱，层级不清晰。

### 2. 页面状态管理：组件内 ref

三层页面切换（`pageMode: 'layer1' | 'layer2' | 'config'`）由 `SpeakingPanel.vue` 内的 ref 管理，不需要放 Pinia store。

**Why**: 页面导航状态是纯 UI 状态，只在 SpeakingPanel 内部使用。demo 中也是组件内 useState 管理。Store 只放需要跨组件共享的配置数据。

### 3. 配置数据管理：Pinia store `src/store/speaking.ts`

管理话题讨论配置状态（topic、learningGoals、practice、evaluation 等），对应 demo 中 `useTopicDiscussionConfig` hook 的逻辑。

**Why**: 配置数据需要在 Layer 2（推荐卡片预填充）和 Layer 3（配置表单编辑）之间共享，也需要在"应用配置"时传给父窗口。

### 4. 类型定义：`src/types/englishSpeaking.ts`

从 enspeak `useTopicDiscussionConfig.ts` 移植话题讨论相关类型：TopicDiscussionConfig、PracticeSettings、EvaluationSettings、LearningGoals、Role 等。只移植话题讨论需要的，不搬整个 types/index.ts。

### 5. 集成方式：替换英语 tab submenu 内容

当前 `CollapsibleToolbar/index2.vue` 英语 tab 的 submenu 里只有 video 占位。替换为渲染 `SpeakingPanel` 组件。

**Why**: 利用现有 submenu 面板机制，不需要改动 CollapsibleToolbar 的框架逻辑。

### 6. 与父应用通信：`addTool(77)`

配置完成 → 调用 `parentWindow.addTool(77)` → 父应用回调 `window.addContent(data)` → PPT 创建 `{ type: 'frame', toolType: 77 }` element 嵌入 slide。

toolType 77 需要在 `BaseFrameElement.vue` 的 `getTypeLabel` 中注册。

## Risks / Trade-offs

- **[Tailwind → SCSS]** → Demo 用 Tailwind CSS，PPT 用 SCSS。需要逐个转换样式。→ 优先保证功能和布局一致，视觉细节可迭代。
- **[只有 Unit 2 有推荐数据]** → `topicDiscussionTasks.json` 目前只有 Unit 2 的 4 条推荐。→ 选择其他 Unit 时推荐列表为空，UI 上显示空状态提示，后续补充数据。
- **[AI 生成无后端]** → UI 壳子就绪但无实际功能。→ 点击生成后可显示"功能开发中"提示，不影响主流程。
- **[父应用 addTool(77) 未对接]** → 父应用侧还没有注册 77 类型工具。→ PPT 侧先做完配置面板，addTool 调用就绪，等父应用配合对接。
