---
url: https://gaojian.site/api-examples.md
description: 从学习流程到内容工程、Vue课程组件、音频复用与静态分发，记录gaojian.site的系统架构与设计取舍。
---

SELECTED WORK

# 作品集

这里收录已经可以使用的课程、持续更新的写作项目，以及从真实需求中生长出来的技术实践。它不是完成清单，而是一份长期建设记录。

## 英语学习课程

COURSES · NEW CONCEPT 2 / 3 / 4

### 新概念英语 · 三册精读课

按基础叙事、长句转述与抽象论述分为三门课程。以PDF整理稿为底稿，配合双向回忆、句法解析与段落级FSRS复习。

选择适合的一册 →
COURSE · 94 TOPICS

### 雅思口语 · 高分话题课

按生活半径组织 94 个话题与 846 道练习，结合考试策略、脱稿表达、换题迁移和间隔复习。

进入课程地图 →
COURSE · WRITING PRACTICE

### 雅思写作 · 从构思到成文

按A类、G类与Task 2选择路线，练习审题、分组、论证与修改；保留自己的初稿，再用新题验证。

选择学习路线 →
COURSE · 123 LESSONS

### 地道英文写作进阶

从外刊语料中理解表达，通过分级仿写、参考答案和间隔复习，把短语真正写进自己的文章。

进入课程 →
COURSE · 100 SENTENCES

### 雅思 100 句

以一百个真实长句为入口，训练词汇、语法结构、听力辨音、朗读节奏与表达迁移。

从第 1 课开始 →
COURSE · 41 TOPICS

### 实用英语口语 41 话题

覆盖日常、职场与社会话题，配合英美音频、情景对话和主动输出练习，解决“没话可说”。

查看课程地图 →
HANDBOOK · LEARNING METHODS

### 人人都能用英语

李笑来的方法小册子。从学习观念、口语和朗读，到词典、语法与精读；配合本站练习入口，把方法放回实际使用。

阅读方法小册子 →

## 写作与记录

KNOWLEDGE · 100 IDEAS

### 现代思维工具 100 讲

从决策、成长、商业到复杂系统，整理一百个可以反复调用的现代思维框架。

开始阅读 →
ESSAY · CYCLING

### 环崂日记

用骑行丈量城市与山海，也记录体力、天气、路线和人在路上的细微变化。

阅读专栏 →
ESSAY · FIELD NOTES

### 外卖骑士这边请

从真实劳动现场出发，观察城市系统、普通人的选择，以及技术如何进入日常生活。

阅读专栏 →

## 技术与系统

CASE STUDY · CONTENT-DRIVEN LEARNING

### gaojian.site · 把学习材料做成可反复使用的工具

这个网站的起点是整理自己的知识，后来逐渐变成一套可以阅读、听读、回忆、练习和复盘的学习系统。技术的任务，是让同一份高质量材料在不同练习中保持一致，让学习者少花精力找功能，多花精力理解和表达。

VitePress + Vue 3构建时整理内容静态音频复用浏览器本地练习

学习设计内容架构音频复用本地数据发布与分发设计取舍

### 从学习者看，网站要支持什么 {#learning-system}

我不希望课程只是题目和范文的集合。学习者读懂了一篇文章，并不等于能够在新题里表达同样的意思。课程需要把“看懂”之后的路铺出来：观察表达、遮住参考回忆、组织自己的答案，再用新问题检验。

#### 先让材料容易理解

课程地图帮助选择路线；原文、自然中文、题图与范文对照，降低来回寻找信息的负担。逻辑链、词伙与句型说明，解释答案为什么这样组织。

#### 再让理解变成输出

用词块回忆、英译汉、汉译英和跟读，把“眼熟”变成主动提取。逐句练习降低起步难度，整篇回忆保留段落之间的关系。

#### 最后用新题判断进步

口语练脱稿与换场景；写作保留提纲、初稿、修改、迁移与复盘。自检关注遗漏、逻辑和表达是否改善，完成数量不等同于能力或考试分数。

课程之间也有分工：日常话题练习提供表达情境，雅思100句帮助拆解长句，口语课程训练按问题组织答案，写作课程训练比较、论证与修改，地道写作课程积累语境中的表达。学习者可以按当前问题选择入口，共用的交互方式让切换课程时不用重新学习操作。

### 从架构师看，先把三件事分开 {#content-architecture}

**内容生产、站点分发、个人练习**拥有不同的变化节奏。课程文本需要审校，发布资源需要处理版本，个人草稿则要在输入时及时保存。把它们分层，才能分别改进，而不是把所有逻辑塞进一个页面。

#### Markdown 负责内容，Vue 负责行为

正文保留在 Markdown 中，便于写作、审校和版本对比。题目、路线、参考回答与教学说明进一步整理成 frontmatter 或独立的数据文件；Vue 组件负责交互状态，工具函数负责拆句、词数统计、数据解析等可复用规则。

例如 Task 2 的七种学习方式并不是七篇独立材料。它们基于同一份参考原文和句子索引：标记朗读显示表达重点，双向译练切换提示与答案，逻辑链展示组织关系，词汇与语法回到原句说明。原文一旦修改，相应译文、教学标记和音频就需要一起核对。

#### 重复劳动放到构建阶段

课程生成脚本负责归类、排序、生成目录和页面。部分已有课程通过 VitePress 的 `transformPageData` 在构建时抽取学习数据；浏览器拿到准备好的结构，不必每次打开页面都重新分析长篇材料。

Task 2 参考回答还保留了原文的 SHA-256 签名。生成时发现原文版本变化，会要求重新核对教学数据；播放器也核对音频清单与当前原文的版本。这个约束解决的是一个很实际的问题：不能让学习者点着新句子，却听到旧版内容。

```text
内容与页面        docs/ 下的 Markdown
交互组件          docs/.vitepress/components/
规则与学习数据    docs/.vitepress/utils/、data/、composables/
课程整理与生成    scripts/ 及对应的源材料
公共媒体          docs/public/ 下的题图、音频、视频
发布产物          docs/.vitepress/dist/
```

目录的价值不在于分了多少文件，而在于边界清楚：调整练习样式不应迫使作者重写教材，修订译文也不应改变学习者保存草稿所用的课程标识。

### 音频：用完整音轨承载逐句练习 {#audio-architecture}

雅思写作的 Task 2 与话题工作坊采用了一个重要取舍：**每份材料、每种口音生成一条完整音轨，同时保存每句话的起止时间**。前端按时间范围播放单句，或者连续播放全文。句子是练习单位，完整音轨是媒体文件单位。

44份参考材料

88条英美音轨

420个句子练习单元

这批文件合计约76.7 MB。若逐句生成两种口音，会形成840个句子文件，全文还可能需要另外处理；当前方案用88条音轨，同时支撑点读和全文跟读。它减少媒体碎片，也保留同一篇回答的声音连贯性。代价是播放一句时仍然要加载或定位到完整音轨中的对应位置，逐句体验依赖时间标记、网络和浏览器的媒体定位能力。

音频清单保存路径、口音、音色、时长、原文版本和句子区间。播放控制统一处理当前音轨、速度、跟读次数和活动句子；原文朗读、英译汉、汉译英与语法原句复用同一份音频。页面切换或学习模式改变时停止原来的播放，避免声音和界面脱节；新写的拓展句没有对应录音时，不套用原句音频。

语音生成发生在材料制作阶段。学习者点击播放时访问已经生成的静态媒体，不实时调用语音生成接口，因此重复收听主要消耗资源分发带宽。制作费用和日常访问成本可以分开考虑，也更容易在发布前检查音频与文本是否一致。

### 个人数据：及时保存，也说清边界 {#browser-data}

| 数据 | 当前保存方式 | 为什么这样选择 |
| --- | --- | --- |
| 学习状态、实践笔记、写作稿 | localStorage | 轻量、输入后就能保存，适合当前没有账号系统的练习流程 |
| 支持录音课程中的跟读录音 | MediaRecorder 采集，IndexedDB 保存 Blob | 二进制媒体与文字状态分开保存，录音组件无需上传到业务服务器 |
| 课程文本、示例音频与题图 | 静态构建产物与公共媒体 | 内容制作一次，发布后可以供多人重复访问 |

这种设计让用户不必先注册就能练习，也降低了账号和个人录音服务的维护成本。相应的限制同样真实：记录留在当前浏览器与站点域名下，换设备、切换浏览器或清理站点数据后，不会自动找回。写作台因此提供文本导出；浏览器保存失败时，也会提示用户备份。

当前的复盘与检查属于学习者自评，没有接入自动判分，也不把一次勾选当作官方能力评估。站点配置中的 Google Analytics 是独立的访问分析服务，不承担草稿和录音的保存；“学习记录保存在本地”也不意味着页面没有其他网络请求。

### 发布与分发：静态不等于没有系统设计 {#delivery-architecture}

VitePress 先生成可直接阅读的 HTML，Vue 再在浏览器中接管交互。课程正文不依赖实时业务 API，发布对象主要是页面、代码、搜索索引与媒体资源。导航、分组侧栏、本地搜索、站点地图和 canonical 地址共同解决“怎么找到内容”与“如何保持页面身份清楚”的问题。

线上站点是 **www.gaojian.site**。源站是一台运行 OpenCloudOS 的腾讯云服务器，由 **Nginx** 提供静态文件，再通过 **腾讯云 EdgeOne** 对外分发。当前采用手动发布：本地完成构建后，用 **WebStorm Deployment** 把 `dist` 中的构建产物上传到服务器的站点目录。

```text
本地编辑与构建
  → WebStorm Deployment 上传 dist
  → 腾讯云服务器 / Nginx / 页面与媒体
  → EdgeOne 边缘分发
  → www.gaojian.site / 学习者浏览器
```

#### 为什么暂时不把音频放进对象存储

目前图片和音频与页面一起由源站提供。前期材料主要供站长自己使用，已有服务器套餐包含无限流量、峰值带宽200 Mbps；复用这台服务器，可以减少新引入的存储服务及其计费、权限和资源迁移管理。这个选择基于当前使用规模和已有资源，而不是因为静态学习网站必须这样部署。

它的代价是媒体容量、并发传输与页面资源共用服务器的磁盘和带宽。峰值带宽不是每位访客都能独占的下载速度；随着课程媒体和访问量增长，需要再依据实际访问、容量和边缘分发成本决定是否拆出媒体存储。内容、媒体路径与播放清单已经分开组织，后续迁移可以从资源层着手。

发布时更需要关注**资源之间的版本一致性**：

* Nginx 配置对 `/assets/` 中的哈希资源设置长期缓存与 `immutable`；新内容对应新文件名。
* HTML 使用不缓存策略，同名的音频、图片要求重新验证。搜索索引随构建更新；边缘规则也要与源站策略一致，不能把所有资源一律长缓存。
* Nginx 的音频配置保留字节范围请求能力，为媒体定位提供支持。页面也不应提前下载所有音轨；Task 2 播放器使用 `preload="none"`，按用户操作加载。
* 源码、原始工作材料和部署配置，与公开内容及构建产物分开。尤其是本项目的 MP3、MP4 不进入 Git，媒体需要独立备份；克隆源码并不等于恢复了完整站点。

构建通过只证明生成成功。一个完整的发布过程还应核对页面引用的资源版本、目录与深层链接、图片与音频是否可访问，以及边缘缓存是否已经更新。当前 WebStorm 上传流程和自动部署脚本是两件事：日常发布仍由站长手动完成。发布清单要覆盖媒体文件与缓存更新，不能把脚本的存在当作这些检查已经自动执行。

### 关键决策与代价 {#architecture-decisions}

| 选择 | 解决的问题 | 同时承担的代价 |
| --- | --- | --- |
| 静态正文 + 浏览器交互 | 让内容易维护，练习可独立演进，减少运行时业务依赖 | 内容变更需要重新构建和发布；交互组件增多后仍要控制前端体积 |
| 原文、句子索引与版本校验共用 | 降低译文、标记、练习与音频错位的风险 | 修订原文时需要联动审校，不能只替换一段文字 |
| 完整音轨 + 句子时间范围 | 点读和全文复用，减少文件碎片 | 定位精度、媒体加载和长音轨体积需要持续检查 |
| 浏览器本地保存 | 无需账号即可开始，草稿输入及时保存 | 缺少跨设备同步，用户需要理解保存范围并备份 |
| 共享组件与移动端适配 | 不同课程沿用熟悉的操作方式 | 改动播放速度、弹层等共用组件时，要检查其他课程是否受影响 |

作为架构师，我更关心这些选择是否服务于当前的学习问题。技术上的简洁，是减少用户需要操心的事情：看图时能同时读范文，展开速度菜单不挤动邻近按钮，播放完毕有明确反馈，小屏幕仍能完整操作。它们是系统质量的一部分，而不是功能做完后的装饰。

## 继续建设

后续的重点，是让已经能用的系统更稳定、更容易判断学习效果：

1. **把内容校验继续前移。** 保持题目、原文、中文与音频的对应，补充课程修订记录；自动校验负责找出错位，人工审校负责表达与教学质量。
2. **按课程拆分前端负担。** 随着共用组件、目录和数据增多，持续检查首屏资源与构建体积，按实际使用路径考虑延迟加载，而不是让每个读者一次承担整个站点的交互代码。
3. **让复盘形成可观察的作品。** 用初稿、修改稿与新题作答看进步，改善备份和学习记录的可见性；跨设备同步若成为真实需求，再评估账号和数据服务。
4. **把发布检查与媒体备份固化。** 不只检查首页，还检查课程深链、音频定位、移动端操作和资源版本，减少“代码上传了，学习材料却没完整到达”的问题。

这个项目让我学到：课程质量、交互质量和交付质量需要一起设计。更多技术层次并不自然带来更好的学习体验；真正有用的架构，应当让内容更准确、练习更顺畅，并让后续维护有据可循。
