# 英语词书导入方案(以雅思为例) > 2026年9月首次执行:雅思词汇 3346 词导入秒过知识库。 > 本文档记录完整过程,供后续导入其他英语词书(考研、托福、GRE 等)复用。 > 原始数据和导入脚本见本目录 `ielts/`。 ## 一、涉及的表和关键约束 | 表 | 库 | 作用 | 本次新增 | |---|---|---|---| | `WordBooks` | kylx365_db | 旧知识库词书表(浏览/背单词入口) | 6 条(ID 212-217) | | `MiaoguoBook` | 秒过库 | 新知识库词书表(检测入口) | 6 条(ID 306-311,自增) | | `Words` | kylx365_db | 单词明细,`BookID`=WordBooks.ID | 3346 条 | 关键约束: 1. `MiaoguoBook.BookIDOld` 指向 `WordBooks.ID`,两表各加一套记录是**正常设计**(旧新知识库并存)。 2. `Words.BookID` 关联的是 **WordBooks.ID(BookIDOld)**,不是 MiaoguoBook.ID。 3. WordBooks 的 ID **必须人工分配**(取当前 MAX(ID)+1 起),因为服务端代码里有大量按 BookID 范围硬编码的分支(见第四节)。 4. `MiaoguoBook.Sort` 决定词库列表排序(雅思=14,排在六级 13 之后)。 5. 写库必须走事务,导入前先 `--dry-run` 预检。 ## 二、数据准备 ### 2.1 数据源与合并去重 本次两个渠道(放在 `ielts/` 下): - `ielts-xdf-random.json`:新东方 3050 词,含音标/词性/中文释义。 - `ielts-4000.json`:526 词(学术词汇表),仅英文释义。 合并规则(脚本内置): - 以小写规范化后的单词为 key 去重,xdf 优先; - 4000 独有的 296 词:优先从现有**四六级/高考词库(BookID 169-183)**取中文释义+音标;取不到的用英文释义顶替; - 音标统一为 `[xxx]` 格式(参照四级 `[əˈbændən]`); - 释义格式 `词性+中文`(参照 `vt.丢弃;放弃`);教材没有音标时存 `NULL`,不臆造。 ### 2.2 分册规则 - 每课固定 10 词(`WORDS_PER_LESSON=10`),`LessonID` 从 1 递增,`LessonName` 由服务端按 `Lesson N` 生成; - 3500 左右的词量分 6 册(`第一部分`~`第六部分`),均分后前几册多 1 词; - `Words.Sort` 本批次统一为 0(接口按 `LessonID,Sort,ID` 排序,插入顺序即最终顺序)。 ## 三、书字段命名规则(参照四六级) ### WordBooks(旧表) ``` Category = '雅思英语' # 词书分类名(唯一,用于查重) Name = '第一部分' ~ '第六部分' Name2 = '词汇558' # 该册词数 Grade = '高中,大学' # 客户端按用户年级过滤,多学段用逗号分隔 Category2 = '大学英语' # 一级分类 = MiaoguoBook.LibraryName1 Category3 = '雅思考试单词' # 二级分类 = MiaoguoBook.LibraryName2 WordType = '单词' Sort = 14 # 词书排序 Package = Name BookImageName = 'ieltsWords' # 图片名(见 3.3) Image = '../images/examine_subject_a00N.png' # N=册序号,沿用现有占位图 ``` ### MiaoguoBook(新表) ``` BookIDOld = WordBooks.ID Category = 'English' LibraryName1 = '大学英语' # 词库列表一级 LibraryName2 = '雅思考试单词' # 词库列表二级 Grade = '高中,大学' Category2 = '课外拓展' BookName = '第一部分' ~ '第六部分' UnitNum = 每册 Lesson 数 WordNum = 每册词数 BookImageName = 'ieltsWords' KnowledgeImageName = '' TestFunction = JSON(read: 念单词说含义 / write: 听写单词,照抄六级的即可) ``` ### 封面图片(COS) 命名规则参照四六级 `picZs_en_cet4Words_cov`,雅思为 `picZs_en_ieltsWords_cov`,需要三张后缀 `_a/_b/_c` 的 PNG 上传到 COS 图片目录(AI 生成的图在 `ielts/generated/`)。服务端列表接口会拼成 `picZs_en__cov`。 ## 四、服务端代码适配(易漏步骤!) `src/api/miaoguo/miaoguoController.js` 的 `GetTestEnglishWords` 中,**BookID 分支全部是硬编码范围**。新词书如果不加范围,检测页(`GetMiaoguoTestExamine` → 内部再调 `GetTestEnglishWords`)会返回**空列表**且不报错。 2026年9月为雅思(WordBooks ID 212-217)所做的修改: 1. **GET6 分支范围扩展**(约 4796 行): ```js } else if ((Number(param.BookID) >= 169 && Number(param.BookID) <= 183) || (Number(param.BookID) >= 212 && Number(param.BookID) <= 217)) { ... else if (Number(param.BookID) >= 212 && Number(param.BookID) <= 217) param.Type = "GET6"; ``` 让雅思与六级走完全相同的渲染逻辑(发音 + 基本中文释义 + 高亮)。 2. **JSONString 空值兜底**(同函数循环开头):GET6 分支依赖 `MiaoguoLiteracy.JSONString`,雅思有约 50 个词(多为英式 -ise 拼写、复合词,如 epitomise、minimise)在 MiaoguoLiteracy 中没有词典数据,`JSON.parse(null)` 会直接崩溃。已加兜底:无 JSONString 时用百度 TTS + Words 表的音标/释义构建内容。 下次导入新书时需要: - 把新的 BookID 范围加入该分支(或借机重构为查表配置); - 评估新书词汇在 `MiaoguoLiteracy` 的覆盖率,确认兜底逻辑覆盖无词典词。 其余接口无需改动:`GetMiaoguoTestLibrary`、`GetMiaoguoTestUnit`、`GetMiaoguoTestExamine` 的 English 分支对 BookID 无范围限制。 ## 五、导入操作步骤 ```bash cd /Users/chengjie/Documents/git/miaoguo_system_server # 1. 预检(只读,校验 ID 未被占用、无重复 Category、显示分册统计) node "秒过知识库更新/04-英语词书导入/ielts/import_ielts.js" --dry-run # 2. 确认输出后正式导入(事务:WordBooks 6 条 + MiaoguoBook 6 条 + Words 3346 条) node "秒过知识库更新/04-英语词书导入/ielts/import_ielts.js" --import ``` 脚本内置防呆:`START_BOOK_ID`(212)被占用、或 `Category` 已存在时中止。 ### 导入后验证 ```bash # 1. 词库列表应出现新分类,Grade 正确 curl -s "http://localhost:3010/api/GetMiaoguoTestLibrary" | python3 -m json.tool | grep -A3 雅思 # 2. 单元列表(应返回 Lesson 1..N) curl -s "http://localhost:3010/api/GetMiaoguoTestUnit?BookID=" | head -c 500 # 3. 检测列表 read/write(各应返回 10 词,格式同六级) curl -s "http://localhost:3010/api/GetMiaoguoTestExamine?UserID=1&BookID=&UnitName=Lesson%201&UnitID=1&TestType=read" curl -s "http://localhost:3010/api/GetMiaoguoTestExamine?UserID=1&BookID=&UnitName=Lesson%201&UnitID=1&TestType=write" ``` **重要**:`GetMiaoguoTestExamine` 有 `globalCache`,若导入前调用过会缓存空结果。改代码或导数据后必须重启服务(`npm run dev`,非 nodemon 不会自动重载)。 ## 六、本次结果记录(2026-09-15) - WordBooks:ID 212-217,每册 557~558 词,各 56 Lesson。 - MiaoguoBook:ID 306-311(BookIDOld=212-217),Sort=14,Grade 先设"大学"后按需求改为"高中,大学"。 - Words:3346 条(xdf 3050 + 4000 独有 296,其中 171 词从四六级词库补了中文释义,125 词用英文释义)。 - 服务端代码:`GetTestEnglishWords` 增加 212-217 → GET6 分支 + JSONString 兜底(见第四节)。 - 踩坑记录: 1. 导入完成后检测页为空 → 原因是硬编码 BookID 范围未包含新书(第四节); 2. 词库列表看不到新书 → `Grade` 会被客户端按用户年级过滤,多学段可用逗号分隔; 3. 接口返回旧数据 → `globalCache` 缓存,需重启服务。 ## 七、下次导入新书 Checklist 1. [ ] 整理词源数据为 JSON(word/phonetic/pos/zh),放本目录新建子文件夹 2. [ ] 复制 `import_ielts.js` 修改:START_BOOK_ID、SORT、Category、Category2/3、Grade、BOOK_IMAGE_NAME、分册数 3. [ ] 生成封面图三张(`picZs_en__cov_a/b/c.png`)上传 COS 4. [ ] `--dry-run` 预检 → 人工确认分册统计 → `--import` 5. [ ] `miaoguoController.js` 的 `GetTestEnglishWords` 增加新 BookID 范围分支 6. [ ] 检查新书词汇在 MiaoguoLiteracy 的覆盖率(兜底逻辑已就位,但需确认) 7. [ ] 重启服务,按第五节验证三个接口 8. [ ] 小程序端用对应学段账号实际走一遍词库列表 → 单元 → 检测流程