docs: 建立项目文档体系(vision/requirements/tech-stack/architecture/coding-rules)
- docs/01-vision 核心目标、目标用户、产品原则、非目标 - docs/02-requirements 产品语言需求 + MVP 验收标准(无技术词) - docs/03-tech-stack go-app / 纯CSS / SQLite / Session Cookie / 单二进制部署 - docs/04-architecture 系统结构、前后端职责、真实 episodes.json 数据模型、技术难点 - docs/05-coding-rules AI 写代码前必读的硬约束(防跑偏) - CLAUDE.md AI 入口:文档地图、真实数据 schema、强制必读编码规则 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# 架构设计
|
||||
|
||||
> 本文讲"怎么把技术栈搭起来":系统结构、前后端职责、数据模型、技术难点、开发顺序。
|
||||
> 具体用了哪些框架 / 库 / 数据库 / 部署方式,见 [技术栈](03-tech-stack.md)。
|
||||
|
||||
## 一、系统结构
|
||||
|
||||
```
|
||||
┐
|
||||
│ 用户浏览器 (大屏手机 / 平板)
|
||||
│ │
|
||||
│ ▼ 安装为 PWA,离线缓存
|
||||
│ 前端 go-app (app.wasm)
|
||||
│ - 课程列表 / 播放器 / 字幕同步 / 生词本 UI
|
||||
│ - Service Worker 缓存音频与文稿
|
||||
│ │
|
||||
│ ▼ REST API (JSON over HTTPS)
|
||||
│ 后端 Go net/http
|
||||
│ - 账号鉴权 / 进度 / 生词本
|
||||
│ │
|
||||
│ ▼
|
||||
│ SQLite 数据库
|
||||
┘
|
||||
```
|
||||
|
||||
## 二、前后端职责划分
|
||||
|
||||
**前端(go-app / wasm)**
|
||||
|
||||
- 课程列表、音频播放器
|
||||
- 字幕同步高亮 + 点击跳转(核心,自写)
|
||||
- 生词本界面
|
||||
- PWA manifest + Service Worker
|
||||
|
||||
**后端(net/http)**
|
||||
|
||||
- 用户注册 / 登录 / 鉴权(方式见技术栈,待定)
|
||||
- 生词本增删查
|
||||
- 学习进度读写
|
||||
- (静态音频与文稿可由 go-app Handler 或 CDN 提供)
|
||||
|
||||
## 三、数据模型
|
||||
|
||||
数据分两类:**内容数据(静态、只读)** 与 **用户数据(动态、需后端)**。
|
||||
|
||||
### 3.1 内容数据 — 静态 `episodes.json`(前端直接读,不入库)
|
||||
|
||||
实际素材已存在:`family-album-usa/episodes.json`(约 700KB)+ `family-album-usa/audio/*.mp3`。
|
||||
结构为 **episode(集)→ act(幕)→ line(句)** 三级(以下为真实结构):
|
||||
|
||||
```json
|
||||
{
|
||||
"meta": { "version": "1.0.0", "title": "走遍美国 Family Album U.S.A.",
|
||||
"totalEpisodes": 26, "totalActs": 78, "audioActs": 49, "lastUpdated": "2026-05-29" },
|
||||
"episodes": [
|
||||
{
|
||||
"id": 1, "title": "46 Linden Street", "titleCn": "林登大街46号",
|
||||
"acts": [
|
||||
{
|
||||
"act": 1, "label": "Act I",
|
||||
"audio": "/family-album/audio/u0101.mp3",
|
||||
"hasAudio": true, "lineCount": 86,
|
||||
"lines": [
|
||||
{ "t": 34.18, "en": "Excuse me. My name is Richard Stewart." }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
要点(**以实际数据为准,勿臆测字段**):
|
||||
|
||||
- **集 episode**:`id` / `title` / `titleCn`(26 集**全部**有中文标题)/ `acts[]`
|
||||
- **幕 act**:`act` 序号 / `label` / `audio`(服务路径 `/family-album/audio/u{集}{幕}.mp3`)/ `hasAudio` / `lineCount` / `lines[]`
|
||||
- **句 line**:**只有 `{ t, en }` 两个字段**。`t` 为音频时间戳(秒),`en` 为英文原句。**无 `zh` 字段**——行级中文翻译目前不存在,未来要补需扩展 schema
|
||||
- 规模:26 集 / 78 个 act 条目,其中 49 个 `hasAudio=true`;`audio/` 目录共 50 个 mp3,合计 6335 句
|
||||
- ⚠️ **路径映射**:JSON 里的 `/family-album/audio/...` 是**对外服务路径**,对应磁盘目录 `family-album-usa/audio/`,后端路由需做这层映射
|
||||
- ⚠️ `audio/episode12_act2.mp3` 命名不符合 `u####.mp3` 规则且未被 JSON 引用,属游离文件,接入时需核对
|
||||
|
||||
> 多教材扩展:未来接入新概念英语等,可沿用「教材 → 单元 → 句子」三级抽象——「走遍美国」即一个教材。新教材未必每句有时间戳,line 的 `t` 允许缺省。第一版无需为此提前建库,前端按 JSON 渲染即可。
|
||||
|
||||
### 3.2 用户数据 — SQLite(需账号,后端读写)
|
||||
|
||||
仅存「用户态」,**内容数据不入库**:
|
||||
|
||||
**users** — id, email, password_hash, created_at
|
||||
|
||||
**progress** — user_id, episode_id, act, last_position(秒), completed, updated_at
|
||||
|
||||
**vocab** — id, user_id, word, episode_id, act, context_sentence, created_at
|
||||
|
||||
**功能模块化**:字幕同步、生词本、播放器做成可复用组件,不同教材按需启用(走遍美国用字幕同步;新概念可能更重单词表与语法)。
|
||||
|
||||
## 四、关键技术难点
|
||||
|
||||
| 难点 | 说明 | 应对 |
|
||||
| --- | --- | --- |
|
||||
| 字幕同步 | 音频 currentTime 匹配 `t`,逐句高亮 + 点句跳转 | 先出最小原型验证 |
|
||||
| Audio API 互操 | go-app 需通过 syscall/js 调浏览器 | 封装成可复用组件 |
|
||||
| wasm 首屏体积 | Go wasm 最小约 2MB,首屏较慢 | 离线缓存后续访问快 |
|
||||
| 离线音频 | 大体积音频缓存策略 | Service Worker 按需缓存 |
|
||||
|
||||
## 五、推荐开发顺序
|
||||
|
||||
1. **先写「音频 + 时间戳字幕同步」最小原型**(验证最难一环)
|
||||
2. 搭课程列表 + 播放页骨架
|
||||
3. 后端账号体系 + 鉴权
|
||||
4. 生词本(前端 UI + 后端 API)
|
||||
5. 进度同步
|
||||
6. PWA manifest + Service Worker 离线化
|
||||
7. (V2)复读 / 测验 / 打卡
|
||||
|
||||
> 原则:先验证最难的字幕同步,跑通再往上搭架子,避免先搭一堆架构最后卡在核心功能。
|
||||
Reference in New Issue
Block a user