整个课程和数据UI重新设计版本
This commit is contained in:
+59
-4
@@ -1,6 +1,6 @@
|
||||
# 课程内容包 JSON 格式
|
||||
|
||||
> 对应《学习引擎规格》第 5 节。本文说明 A1–B1 单元内容包的文件位置、字段和程序校验规则。A0 仍按《A0 初始核心课程包》,不在此格式内。
|
||||
> 对应《学习引擎规格》第 5 节。本文说明 A0–B1 单元内容包的文件位置、字段和程序校验规则。所有等级共用这一套结构,由 `CourseRepository` 用同一套规则转换成学习和复习数据;A0 的内容标准仍以《A0 初始核心课程包》为准(见 4.10)。
|
||||
|
||||
## 1. 文件与工具
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|---|---|
|
||||
| `kouyu_english/assets/courses/course-map.json` | 主题地图:等级、单元顺序、每级的数量范围、名称白名单 |
|
||||
| `kouyu_english/assets/courses/<等级>/<单元ID>.json` | 单元内容包,一个单元一个文件 |
|
||||
| `kouyu_english/assets/courses/A0/assessment.json` | A0 阶段测评题(见 4.11) |
|
||||
| `kouyu_english/tool/courses/lexicon/` | 锁定的 CEFR-J 数据与 `SOURCES.md` |
|
||||
| `kouyu_english/tool/courses/pools/` | 等级词池(`build_word_pools.py` 生成) |
|
||||
| `kouyu_english/tool/courses/validate.dart` | 校验全部内容包,报告词池覆盖率 |
|
||||
@@ -20,17 +21,18 @@ dart run tool/courses/validate.dart --uncovered B1 # 按主题列出未覆盖
|
||||
dart run tool/courses/validate.dart --levels B1-U14 # 打印条目的计算等级
|
||||
```
|
||||
|
||||
内容包目前只是资源文件,尚未加入 `pubspec.yaml`,运行时也还不读取。
|
||||
运行时由 `lib/core/courses/course_repository.dart` 读取:`main` 启动前先加载 A0,`AppState.load` 再加载其余等级。学习(教学段、对话、写作、独立表达)和复习(产出核心的 `match` 与 `review`)都只读这些 JSON,代码里不再写死课程数据。`test/course_self_consistency_test.dart` 要求每个示范答案都能通过它自己的判定规则。
|
||||
|
||||
## 2. 当前内容(2026-09-17,全部为 `draft`)
|
||||
## 2. 当前内容(2026-09-18,A1–B1 为 `draft`)
|
||||
|
||||
| 等级 | 单元 | 产出核心 | 理解词 | 听读材料 | 词池覆盖 |
|
||||
|---|---|---|---|---|---|
|
||||
| A0 | 10 | 见 A0 标准 | — | — | —(`approved`,不参与词池校验) |
|
||||
| A1 | 21 | 265 | 598 | 42 | 840/933(90.0%) |
|
||||
| A2 | 15 | 217 | 862 | 44 | 1040/1078(96.5%) |
|
||||
| B1 | 14 | 206 | 1121 | 42 | 1345/1552(86.7%) |
|
||||
|
||||
全部由 AI 起草、程序校验通过,尚未经过独立审核和用户确认,不能冻结。
|
||||
A1–B1 全部由 AI 起草、程序校验通过,尚未经过独立审核和用户确认,不能冻结。
|
||||
|
||||
## 3. course-map.json
|
||||
|
||||
@@ -48,6 +50,7 @@ dart run tool/courses/validate.dart --levels B1-U14 # 打印条目的计算等
|
||||
"coreRange": [10, 15],
|
||||
"receptiveRange": [70, 110],
|
||||
"materials": {"count": [2, 3], "listeningWords": [250, 550], "readingWords": [300, 500]},
|
||||
"assessment": "A0/assessment.json", // 可选:本级阶段测评题,目前只有 A0 有
|
||||
// A1 的材料较短,且可选 "unknownTolerance"(默认 0.02)放宽超纲词占比
|
||||
"units": [{"id": "B1-U01", "file": "B1/B1-U01.json", "title": "…", "categories": ["旅行"], "canDo": "…"}]
|
||||
}]
|
||||
@@ -202,6 +205,58 @@ A1 材料短、面向零基础,`unknownTolerance` 设为 0.08(听读材料
|
||||
|
||||
至少 2 个维度,每维至少 3 档;`pass` 是及格档在 `bands` 中的下标(从 0 起),须大于 0。
|
||||
|
||||
### 4.9 可选字段:显式规则优先
|
||||
|
||||
以下字段都可省略;省略时由 `itemIds` 引用的产出核心推导(`match` 合并成一组“或”,示范取 `en`),写了就以写的为准。规则写法见 `lib/core/courses/answer_rules.dart`:外层“且”、内层“或”,内层首项可写 `#min:N` 表示至少用上 N 项;词条可写 `a + b`、`/正则/`,以及 `#spelling`、`#digit`、`#word`、`#question`、`#numbers:N`、`#words:N` 这些结构。
|
||||
|
||||
| 位置 | 字段 | 作用 | 省略时 |
|
||||
|---|---|---|---|
|
||||
| 单元 | `status` | `approved` / `draft` 等 | `draft` |
|
||||
| 单元 | `vocabulary` | 整课词表(离线查词) | 产出核心 + 理解词 |
|
||||
| 教学段 | `grammarNote` | 本段语法提示 | 不显示 |
|
||||
| 教学段 | `vocabulary` | 预习词表 `[{id, word, meaning, example, exampleMeaning}]` | 本段产出核心 |
|
||||
| 教学段 | `sceneId` | 本段对话用的场景 | 第 N 段用第 N 个场景,没有则用 main 场景 |
|
||||
| 教学段 | `writing.accept` / `writing.hint` | 写作判定规则 / 未通过时的提示 | 由 `writing.itemIds` 推导 |
|
||||
| 教学段 | `independent.accept` / `independent.help` | 独立表达的完整规则 / 帮助 | 由 `independent.itemIds` 推导;为空则任何真实尝试都算 |
|
||||
| 场景 | `goal` | 对话目标 | `setting`,再没有则 `title` |
|
||||
| 场景 | `practice` | 同时作为自由练习场景:`{title, summary, recapPrompt, alwaysOpen}`,都可省略;写 `{}` 即可 | 不进入自由练习 |
|
||||
| 轮次 | `aiZh` | `ai` 这句的中文(`zh` 是示范回答的中文) | 不提供翻译 |
|
||||
| 轮次 | `accept` | 本轮判定用的一组“或” | 由本轮 `itemIds` 推导 |
|
||||
|
||||
自由练习场景在其所属单元完成后解锁,`alwaysOpen: true` 则一开始就开放。
|
||||
|
||||
### 4.10 A0 单元
|
||||
|
||||
A0 用同一结构,文件为 `A0/a0-01.json` … `a0-10.json`,在 `course-map.json` 中排在最前。为兼容已保存的学习进度,A0 保留原有 ID:单元 `a0-01`,教学段 `a0-01-a`(拆段课为 `a0-04-a/b/c`、`a0-08-a/b/c`),产出核心 `A0-W01` / `A0-P01`。A0 的规则、提示和对话都用上面的显式字段写明;`validate.dart` 只把 A0 的产出核心和听写句当作“已教的词”,不按 A1–B1 的数量范围和词池校验 A0。
|
||||
|
||||
### 4.11 阶段测评(assessment.json)
|
||||
|
||||
等级在 `course-map.json` 里写了 `assessment`,就由 `CourseRepository` 加载对应文件,运行时代码在 `lib/core/courses/assessment.dart`。目前只有 A0 的 `A0/assessment.json`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"packs": [
|
||||
{"id": "A0-E1", "level": "A0", "tasks": [
|
||||
{"id": "A0-A-L1", "skill": "listening", "prompt": "选择正确答案",
|
||||
"audio": "Hello. I’m Mia.", "choices": ["自我介绍", "买东西", "问时间"], "answerIndex": 0},
|
||||
{"id": "A0-A-W1", "skill": "writing", "prompt": "用英语介绍自己。",
|
||||
"accept": [["hello", "hi"], ["i am", "my name is"]],
|
||||
"guide": "试着同时写一句问候和姓名,例如:Hello. I’m …"}
|
||||
]},
|
||||
{"id": "A0-E1R", "level": "A0", "replaces": "A0-E1", "tasks": […]}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `skill` 取 `listening` / `reading` / `writing` / `speaking`。听力、阅读是选择题,写 `choices` 和 `answerIndex`(从 0 开始);听力另写 `audio`。
|
||||
- 写作、口语是开放题,`accept` 用 4.9 的规则写法,`guide` 是答错后展示的要求。
|
||||
- 没有 `replaces` 的套题按文件顺序解锁:第一套直接开放,之后每套要在上一套通过 24 小时后才开放。
|
||||
- 有 `replaces` 的是替换题,用不同的人名、地点、数字考同样的能力,成绩记在原题 ID 上。
|
||||
- 题目和套题 ID 写进学习记录,发布后不要改。
|
||||
|
||||
`test/course_self_consistency_test.dart` 检查:每道开放题都有 `accept` 和 `guide`,每道选择题的 `answerIndex` 有效,`replaces` 指向存在的套题。
|
||||
|
||||
## 5. 文本用词检查
|
||||
|
||||
“已知词”包括:`alwaysAllowedWords`、功能词、A0 已教的词、推荐顺序在前的单元的产出核心和理解词、本单元的产出核心和理解词(均按词形还原),以及全局与本单元的 `names`。数字不计。
|
||||
|
||||
Reference in New Issue
Block a user