# en-project **Repository Path**: frinder/en-project ## Basic Information - **Project Name**: en-project - **Description**: 小学,初中单词,词组记忆APP - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-28 - **Last Updated**: 2026-10-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 项目说明 现在想做一个基于小学、初中阶段的英语教材,来实现一个单词背诵、关键词组熟记以及课文阅读的一个程序。后端基于Python来实现,前端就使用HTML或者Vue等一些前端的框架来实现。 想做一个快速背诵单词,然后是总结教材中常用到的固定搭配词组,以及借助于AI来梳理每一个年级核心知识点。 分为三个大模块。第一,单词背诵模块。第二,核心词组固定搭配。第三,课文阅读模块。 当然要预留好后期的一些扩展功能。 教材会提供小学一年级到小学九年级所有的PDF,通过解析PDF来读取每一个年级每一册书籍的内容,可以做到按年级上册、下册来进行切换。每一册内容都包含上面的三个模块,单词背诵模块、核心词组模块以及课文阅读模块。 同时核心词组模块需要做到所有年级的一个集合版本。 ### 问题清单 1. 单词发音接口调用时间比较长,点完之后不会立即发音,要过一会才会发音。这个时候我切换到别的操作,它突然发音就很奇怪,需要想个办法解决。 2. 人教版一年级和二年级是没有相关教材的,但是我点单词背诵,进来之后仍然可以看到,他看到的应该是人教版三年级的内容。这个问题需要优化,没有对应教材的可以选择禁用。 3. 核心词组固定搭配这块的功能设计的有点单薄,只有一个英文和中文,以及一个we often use in English class,最好能提供一个例句,方便记忆。 4. 核心知识点列表全量展示了所有的内容,如果数据量太多的话,就很难处理。可以一页展示8个节目,然后提供上一页、下一页的功能来分页展示。知识点中的功能句型、教材例句只是重复了上面的内容,并没有给出完整的例句。 ### 补充功能 提供登录功能,根据不同的用户来记录其学习的状态。 登录功能不用做得太复杂,甚至都不用密码校验,直接输入用户名就可以了。因为这是一个内部使用的一个小软件,没必要把登录功能做得太复杂。 ### 远程ssh nas ``` ssh frinder6@192.168.3.20 $ ssh frinder6@192.168.3.20 The authenticity of host '192.168.3.20 (192.168.3.20)' can't be established. ED25519 key fingerprint is: SHA256:k+fhHfNrzVRf7Pd8s1ZkKLtc9CZ0ME7xiY60f9bV5YM This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.3.20' (ED25519) to the list of known hosts. frinder6@192.168.3.20's password: Linux frinder6 6.12.18-trim #211 SMP PREEMPT_DYNAMIC Fri Jan 30 17:47:53 CST 2026 x86_64 Last login: Sun Mar 22 16:14:57 2026 from 127.0.0.1 frinder6@frinder6:~$ ``` ### > 用户可以隔离了,但缺少用户背诵内容的记忆功能,如:单词每次都是从头开始背诵,核心词组背诵功能缺少标记和记忆,提供优化方案。 ### > meterials 替换原来的 pdf,先读取其中内容并分析。其中pdf是对应的年级和册次,备份原来的数据并清理旧数据,重新读取pdf导入。其中增加了*.mp3 的音频文件。页面发音优先使用对应的音频,如果没有对应的音频,则使用原来的发音接口。提供优化方案。 ### 问题 1. 核心词组 实现(暂无中文释义,可运行 AI 增强补充)功能。 2. 课文阅读部分按单元展示是对的,但全部叠加在一起非常凌乱,小学阶段章节内有A/B做大区分,每个部分又有小标题区分,可以参照之;初中教材略有不同,但也有类似的参照。而且阅读按钮在最上面,读的哪部分也不清晰,再就是音频文件没有与课文对应起来。音频文件名称与课文中的标题是对应的,按这个重新梳理。朗读按钮显示在第一个有音频的标题处而非是最上面全局处。中英对照 功能也没有实现。 3. 知识点 模块也需要再梳理要怎么实现,现在的实现很鸡肋。先提供当下能用方案。 4. 课文阅读 仍然存在较大问题! - 整理了三年级、五年级、七年级 上册单元标题demo,放在目录txt中,分别是:小学三年级上册-章节demo.txt、小学五年级上册-章节demo.txt、初中七年级上册-章节demo.txt - 读取并分析这三个模板demo,了解教材的标题结构,txt目录中还有三年级到九年级教材的ocr纯文本内容 - 参照原pdf教材与纯文本重新梳理课文内容,在处理过程中加入降噪逻辑,对非教材内容智能过滤 - 原有功能不变 ### 改造升级 1. 先对meterials中的素材进行整理,结构类似: - meterials - 一年级 - 上册 - 下册 - 二年级 - 上册 - 下册 2. 评估素材整理的影响范围,同步完成所有相关资源更新 3. 部署时需要更新nas中素材目录结果 4. 因为现在课文阅读模块功能还存在很多缺陷,帮需要提供音频播放功能,在现有入口的基础上提供单独页面播放音频功能,可以调整播放速度 ### 导入素材并完成初始化(已完成) 1. 增加导入 zip 素材功能,包含pdf,音频 → `POST /api/admin/import-zip`,界面在 `/materials` 2. 支持所有文件在同一目录中,按名称区分后放入正确目录,也支持已划分好目录 → `scripts/import_materials_zip.py` 同时认这三种形态:`七年级/上册/`、 `六年级下册/`(目录名连写)、全平铺(靠文件名)。三道安全门(Zip Slip / 符号链接 / 体积上限) 3. 管理操作单独鉴权 → `X-Admin-Token` 比对 `.env` 的 `TEXTBOOK_ADMIN_TOKEN`, **未配置时整体 503**(不是放行:登录本身是免密用户名制,不构成权限边界) 4. 导入历史与回滚 → `GET /api/admin/import-runs`、`POST /api/admin/import-zip/rollback` 5. 音频索引重建 → `POST /api/admin/reindex-audio` 6. 素材导入后的教材册增量同步 → `POST /api/admin/import-books`(只导未入库的册, 默认 dry-run;同册重导会删掉真实学习进度) ### 单词列表(已完成) 1. 单词背诵提供列表展示功能,可以列表查看单词,方便快速回顾 → `GET /api/books/{id}/words` + 同页双 Tab 2. 中译英拼写改由提供字母点击选取方式 ### 常用单词及固定搭配(已完成) 1. materials/常用单词 目录中包含了 常用505个单词,基础积累、考试巩固、高年级拓展固定搭配 2. 解析之,提供核心单词及固定搭配背诵功能 → `/api/common/*` + 界面 `/common`;**进度与教材完全独立**(4 张独立进度表) 3. 关联单词与固定搭配,方便在背诵单词的同时熟悉其固定搭配 → `GET /api/common/vocabulary/{id}/collocations` 与 `GET /api/common/collocations/{id}/words`,界面里可双向点进去 4. 使用ai生成固定搭配使用例句,做到学以致用 → `POST /api/common/collocations/examples/generate`(手动触发、生成后缓存、 已生成的不覆盖)+ `scripts/enrich_collocation_examples.py`; AI 未配置时返回 501 ### 素材保护(`meterials/` 绝不删除) `meterials/` 被 `.gitignore` 排除(1167 个文件 / 2.77 GB),**git 里没有备份,删了就是真删了**。 2026-10-07 就发生过一次:`meterials/常用单词/` 整目录(8 个课标词表 PDF)被永久删除, 回收站里没有对应条目,只能重新下载。 因此除了写规矩,还加了一道**可执行的硬门禁** —— `backend/data/materials-manifest.json` 是素材的账本(244 KB,**入库**),记录每个文件的相对路径与字节数。 ```bash python backend/scripts/guard_materials.py verify # 校验素材与账本一致 python backend/scripts/guard_materials.py preflight # 脚本动手前的门禁 python backend/scripts/guard_materials.py snapshot # 有意增删素材后重建账本 ``` 规则: - **禁止**删除、移动、改名 `meterials/` 下任何文件。需要清理时先跑 `snapshot` 登记。 - `reorganize_materials.py` 的 `--apply` / `--rollback` 会自动先过守卫,不过就中止。 - `import_materials_zip.py --rollback` 删文件前会核对账本;若待删路径是账本里的既有素材, 直接拒绝回退(旧的 import manifest 可能指向别人的文件)。 - 账本只增不减地对照:文件缺失、大小不符(被截断)都算失败;未登记的新文件会拦下并提示去跑 `snapshot`。 ### 教材词表释义(用 `meterials/txt/` 补全,不需要换素材) > 原先记着两条「解析器修不了、需换原生版 PDF」的缺陷,**该结论已被实测推翻**。 > 问题不在 PDF 文本层,而在**词表解析把释义截短/配错**。`meterials/txt/` > (umi-ocr 纯文本,`app/parsing/ocr_txt_parser.py` 已在用它解析课文正文)足以补全。 > 逐条清单见 `docs/reports/vocab-meaning-fix.md`,工具是 > `backend/scripts/fix_meanings_from_txt.py`。 | 册 | 现象 | 状态 | |---|---|---| | 六年级下册 | 词表是**真双栏**被 `_columns` 判成单栏,相邻栏释义配错(`took→拍照`、`heavier→打扫`) | ✅ 已修 22 条 | | 八上/八下/九上 | 词表在 txt **中间段**(每单元一个 `Words and expressions` 小节),解析时释义被截短(`cover` 库=`遮`/txt=`v.遮盖`、`directly` 库缺右括号) | ✅ 已修 48 条 | 仍未处理(清单里有逐条依据,需人工定): - **粘连下一词条**(八上/八下/九上约 150 条):txt 释义尾部粘了下一个词条或词组释义, 取用需要「在下一音标结构处截断」的规则,而 `seat belt`/`pocket money` 这类 词组释义本身含斜杠会误切。 - **词形碎片** 8 条(`v.` `i` `ssions` `z` `rerfon` 等):词形本身是抽取垃圾, 前端仍会显示这些条目。删除或人工修正待定。 - **零散错位/换词** 约 72 条:txt 与库释义无交集,可能是 txt 抽到了别的词的释义 (如八上 `cost` 名词行拿到动词释义),机器判不了。 ### 已修(曾列为待办,根因与证据见 docs/reports/) - **课文与音频的关联**:原先「匹配 583/595 但只有 299 条落库」—— `link_audio` 算出的是多对多,而 `text_sections.audio_id` 每节只能存一条, 其余留在 `LinkReport.links` 里**从不落库也不进 API**。 现新增 `section_audio` 表把 582 条挂接全部落库,课文页每节渲染 「主按钮 + 另外 N 条」。见 `docs/reports/section-audio-links.md`(逐条清单) 与 `docs/reports/section-audio-acceptance.md`(浏览器验收)。 - **顺带修掉一个被藏住的匹配缺陷**:`title_tokens` 用 `_PART_RE` 剥掉 Part 前缀,于是 `A Let's talk` 与 `B Let's talk` 词集完全相同、两边都 1.00 分, `B` 的录音被挂到 `A` 的节上。以前只有主音频可见(恰好总是对的那条)所以看不出来。 加 Part 一致性门控后矛盾 40 → 0,主音频节 299 → 318。 - **磁盘上未索引的 476 个 MP3**:复核后确认**一个都没漏**,全是同名副本 与附录(`irregular verbs` / `proper nouns` 等),不需要索引新文件。 见 `docs/reports/unindexed-audio.md`。 - **课标模块分页**:505 词 11 页 / 250 搭配 5 页,纯前端、零后端改动 (难度筛选本来就在服务端,搜索是前端过滤,切页即切片)。 ### 初中单词&固定搭配 1. materials/常用单词 中新增了初中的单词及固定搭配,按归小学阶段的方式对初中阶段的进行导入及处理 2. 页面上需新增小学、初中不同阶段切换 ### minerU文件 1. meterials\mineru 中是我手工跑的五年级、七年级上册 json, md 格式教材 ### 问题列表 1. 课标 核心词 搭配点开后在弹出框点发音会打开的是 左箭头行为,不是发音 2. 单词背诵 点击 记住了 会立即跳转,而此时发音还没完成,跳到下一个词才会发音,很奇怪 ### 功能扩展 1. 参照页面:https://book.pep.com.cn/1212001501255/mobile/index.html 实现模拟翻书的功能 2. 在此基础上,将音频与之对应,点击 耳机图标时可以播放 3. 翻书功能现在只是测试了,感觉效果还行,将另外没有实现的也实现吧 4. 翻书 面板添加最大化功能,占满整个浏览器 5. 翻书 面板目录切换采用类似录音的浮动面板,显示在下面很奇怪 6. 课文-生成译文 报错,查看现在 生成译文 实现方式。 - 是否基于用户还是一次翻译不同用户都可以使用(尽量后者) - 是否是将整个单元全是给ai翻译,这样即使重试失败率也太高了 - 添加后台任务,将所有 生成译文 在后台跑一遍并存入db中 ``` 本单元还没有完整译文(翻译失败:AI 返回无法解析:Extra data: line 4 column 2 (char 35);原始内容前 200 字:{ "i": 1, "zh": "你在学校最喜欢哪一天?" }, { "i": 2, "zh": "是……" }, { "i": 3, "zh": "你在……有什么课?" }, { "i": 4, "zh": "我有……" }, { "i": 5, "zh": "姓名 最喜欢的一天 科目和活动" }, { "i": 6, "zh": "我们组有……人), 点上方「生成译文」按需翻译——只翻当前单元,已翻过的段落不会重复付费。 ``` ### 专题模块 1. 添加 专题模块,用于录入一些好的学习英语材料。materials/专题材料 中有一篇,分析之,并给出合适的实现方案,用于快速学习掌握其中的内容。 2. F:\Workspaces\en-project\meterials\专题材料\特殊疑问句 专题模块新增 特殊疑问句相关素材,读取合并并添加到专题——特殊疑问句 3. F:\Workspaces\en-project\meterials\专题材料\英语特殊疑问句学习材料.pdf 合并后的 特殊疑问句相关素材,结合现有的特殊疑问句内容分析之,并给出合适的实现方案,用于快速学习掌握其中的内容。 4. F:\Workspaces\en-project\meterials\专题材料\英语一般疑问句学习材料.pdf 一般疑问句相关素材,分析之,并给出合适的实现方案,用于快速学习掌握其中的内容。 5. 英语特殊疑问句 -> 7W1H 八大核心疑问词 -> 全部堆在一起,按分类拆分,更适合学习 ### 问题 1. 背诵 模块,词组/单词 点击记住了,还未发音,单词已跳转 2. 核心词组,选义 没有显示选项。 3. 将 核心词组,课标词汇 默认