feat: A1 短材料复现本单元理解词,并加入黑夜模式

课程内容
- 重写全部 21 个 A1 单元的听读材料,把本单元理解词织进听/读文本,
  单元内理解词复现率从约 20% 提升到约 77%(各单元 56–96%)。
- 修正 U01 房间号与机场大巴同为 thirty 的撞车(改为 17/30/40)。
- 校验器容差按级别读取(A1 为 8%),materials 覆盖率、字数、
  选项子串等校验全部通过;course_content_test 通过。

黑夜模式
- app_theme 拆分明/暗两套调色板,AppColors 随亮度切换;
  main 用 theme/darkTheme/themeMode + builder 镜像已解析亮度;
  主题偏好持久化到快照;进度页新增“外观主题”切换。

文档
- COURSE-PACK-JSON.md 更新 A1 词池覆盖(840/933)与材料复现约定。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-18 11:16:09 +09:00
co-authored by Claude Opus 4.8
parent 9ab08c25ef
commit febfd30f49
93 changed files with 72676 additions and 274 deletions
+907
View File
@@ -0,0 +1,907 @@
{
"schemaVersion": 1,
"id": "A1-U03",
"revision": 1,
"level": "A1",
"title": "在咖啡店点单",
"categories": [
"日常"
],
"canDo": "点饮料、说大小杯、礼貌确认",
"status": "draft",
"meta": {
"draftedBy": "claude-opus-5",
"draftedAt": "2026-09-17",
"sources": [
"CEFR-J Vocabulary Profile 1.5",
"CEFR-J Grammar Profile 20180315"
],
"reviews": [],
"frozenAt": null
},
"names": [],
"grammar": [
{
"id": "142",
"use": "active",
"reason": "I'd like… 作为点单的礼貌固定句块使用,不展开 would 的其他用法"
},
{
"id": "239",
"use": "receptive"
},
{
"id": "150",
"use": "active"
},
{
"id": "21",
"use": "active"
},
{
"id": "16",
"use": "active"
}
],
"coreItems": [
{
"id": "A1-U03-P01",
"type": "pattern",
"en": "I'd like a coffee, please.",
"zh": "我想要一杯咖啡。",
"sceneWord": false,
"match": [
[
"would like"
]
],
"example": {
"en": "I'd like a small orange juice, please.",
"zh": "我想要一小杯橙汁。"
},
"review": {
"prompt": "店员问你想喝什么,礼貌地点一杯咖啡。"
}
},
{
"id": "A1-U03-P02",
"type": "pattern",
"en": "Can I see the menu, please?",
"zh": "可以看一下菜单吗?",
"sceneWord": true,
"sceneReason": "menu 在 CEFR-J 为 A2,但点单前看菜单是咖啡店和餐厅的第一步",
"match": [
[
"menu"
]
],
"example": {
"en": "Sorry, can I see the menu, please?",
"zh": "抱歉,可以看一下菜单吗?"
},
"review": {
"prompt": "你还没想好点什么,请店员给你看菜单。"
}
},
{
"id": "A1-U03-W01",
"type": "word",
"en": "small",
"zh": "小的;小杯",
"sceneWord": false,
"match": [
[
"small"
]
],
"example": {
"en": "A small tea, please.",
"zh": "一小杯茶,谢谢。"
},
"review": {
"prompt": "店员问你要多大的,说要小杯。"
}
},
{
"id": "A1-U03-W02",
"type": "word",
"en": "large",
"zh": "大的;大杯",
"sceneWord": false,
"match": [
[
"large"
]
],
"example": {
"en": "Large, please.",
"zh": "大杯,谢谢。"
},
"review": {
"prompt": "店员问你要多大的,说要大杯。"
}
},
{
"id": "A1-U03-W03",
"type": "word",
"en": "cup",
"zh": "杯子;一杯",
"sceneWord": false,
"match": [
[
"cup"
]
],
"example": {
"en": "A cup of tea for my friend.",
"zh": "给我朋友一杯茶。"
},
"review": {
"prompt": "说“一杯茶”。"
}
},
{
"id": "A1-U03-W04",
"type": "word",
"en": "hot",
"zh": "热的",
"sceneWord": false,
"match": [
[
"hot"
]
],
"example": {
"en": "A hot coffee, please.",
"zh": "一杯热咖啡,谢谢。"
},
"review": {
"prompt": "你想要热饮,告诉店员。"
}
},
{
"id": "A1-U03-W05",
"type": "word",
"en": "cold",
"zh": "冷的;冰的",
"sceneWord": false,
"match": [
[
"cold"
]
],
"example": {
"en": "Cold, please.",
"zh": "要冰的,谢谢。"
},
"review": {
"prompt": "天很热,你想要冰饮,告诉店员。"
}
},
{
"id": "A1-U03-P03",
"type": "phrase",
"en": "with milk",
"zh": "加奶",
"sceneWord": false,
"match": [
[
"with milk"
]
],
"example": {
"en": "Yes, with milk, please.",
"zh": "要,加奶,谢谢。"
},
"review": {
"prompt": "你的咖啡要加奶,告诉店员。"
}
},
{
"id": "A1-U03-P04",
"type": "phrase",
"en": "No sugar, please.",
"zh": "不要加糖。",
"sceneWord": false,
"match": [
[
"no sugar"
]
],
"example": {
"en": "With milk. No sugar, please.",
"zh": "加奶,不要糖。"
},
"review": {
"prompt": "你不想加糖,告诉店员。"
}
},
{
"id": "A1-U03-W06",
"type": "word",
"en": "juice",
"zh": "果汁",
"sceneWord": false,
"match": [
[
"juice"
]
],
"example": {
"en": "An apple juice for my sister.",
"zh": "给我妹妹一杯苹果汁。"
},
"review": {
"prompt": "你不想喝咖啡,点一杯橙汁。"
}
},
{
"id": "A1-U03-W07",
"type": "word",
"en": "sandwich",
"zh": "三明治",
"sceneWord": false,
"match": [
[
"sandwich"
]
],
"example": {
"en": "And a sandwich, please.",
"zh": "再要一个三明治。"
},
"review": {
"prompt": "饮料点好了,再加一个三明治。"
}
},
{
"id": "A1-U03-P05",
"type": "pattern",
"en": "To go, please.",
"zh": "带走,谢谢。(在店里吃说 For here.)",
"sceneWord": false,
"match": [
[
"to go",
"for here"
]
],
"example": {
"en": "For here or to go? To go, please.",
"zh": "在这儿吃还是带走?带走,谢谢。"
},
"review": {
"prompt": "店员问你在店里喝还是带走,说带走。"
}
},
{
"id": "A1-U03-P06",
"type": "phrase",
"en": "That's all, thanks.",
"zh": "就这些,谢谢。",
"sceneWord": false,
"match": [
[
"that is all",
"that is it"
]
],
"example": {
"en": "No, that's all, thanks.",
"zh": "不用了,就这些,谢谢。"
},
"review": {
"prompt": "店员问你还要别的吗,说就这些。"
}
}
],
"receptiveWords": [
{
"id": "A1-U03-R01",
"en": "drink",
"zh": "饮料;喝"
},
{
"id": "A1-U03-R02",
"en": "eat",
"zh": "吃"
},
{
"id": "A1-U03-R03",
"en": "food",
"zh": "食物"
},
{
"id": "A1-U03-R04",
"en": "cake",
"zh": "蛋糕"
},
{
"id": "A1-U03-R05",
"en": "chocolate",
"zh": "巧克力"
},
{
"id": "A1-U03-R06",
"en": "bread",
"zh": "面包"
},
{
"id": "A1-U03-R07",
"en": "breakfast",
"zh": "早餐"
},
{
"id": "A1-U03-R08",
"en": "cookie",
"zh": "饼干"
},
{
"id": "A1-U03-R09",
"en": "apple",
"zh": "苹果"
},
{
"id": "A1-U03-R10",
"en": "orange",
"zh": "橙子;橙色的"
},
{
"id": "A1-U03-R11",
"en": "cheese",
"zh": "奶酪"
},
{
"id": "A1-U03-R12",
"en": "chicken",
"zh": "鸡肉"
},
{
"id": "A1-U03-R13",
"en": "table",
"zh": "桌子"
},
{
"id": "A1-U03-R14",
"en": "ready",
"zh": "准备好的"
},
{
"id": "A1-U03-R15",
"en": "order",
"zh": "点单"
},
{
"id": "A1-U03-R16",
"en": "next",
"zh": "下一个"
},
{
"id": "A1-U03-R17",
"en": "minute",
"zh": "分钟"
},
{
"id": "A1-U03-R18",
"en": "sweet",
"zh": "甜的"
},
{
"id": "A1-U03-R19",
"en": "delicious",
"zh": "好吃的"
},
{
"id": "A1-U03-R20",
"en": "enjoy",
"zh": "享用;喜欢"
},
{
"id": "A1-U03-R21",
"en": "good morning",
"zh": "早上好"
},
{
"id": "A1-U03-R22",
"en": "friend",
"zh": "朋友"
},
{
"id": "A1-U03-R23",
"en": "cafe",
"zh": "咖啡店"
}
],
"segments": [
{
"id": "A1-U03-S1",
"title": "点一杯饮料",
"minutes": 12,
"itemIds": [
"A1-U03-P02",
"A1-U03-P01",
"A1-U03-W03",
"A1-U03-W01",
"A1-U03-W02"
],
"listening": {
"text": "Hi. Can I see the menu, please? Sure. Here you are. What would you like? I'd like a coffee, please. Small or large? Large, please.",
"question": "顾客要了多大杯的咖啡?",
"options": [
"大杯",
"小杯",
"没说大小"
]
},
"speaking": [
{
"text": "Can I see the menu, please?"
},
{
"text": "I'd like a coffee, please.",
"tip": "I'd 读作 /aɪd/,很轻很短"
},
{
"text": "A small cup of tea, please.",
"tip": "cup of 连读成 cuppa"
},
{
"text": "Large, please."
}
],
"reading": {
"text": "CAFE MENU\nCoffee: small three dollars, large four dollars\nTea: two dollars fifty\nHot chocolate: four dollars\nOrange juice: three dollars\nBread: two dollars\nCake: five dollars\nCookies: one dollar\nGood morning! Breakfast is ready!",
"question": "大杯咖啡多少钱?",
"options": [
"four dollars",
"three dollars",
"five dollars"
]
},
"writing": {
"prompt": "写一句话,点一杯小杯咖啡。",
"example": "I'd like a small coffee, please.",
"itemIds": [
"A1-U03-P01",
"A1-U03-W01"
]
},
"independent": {
"prompt": "看着菜单,不看提示点一杯你想喝的饮料,并说要大杯还是小杯。",
"itemIds": [
"A1-U03-P01",
"A1-U03-W01",
"A1-U03-W02"
]
}
},
{
"id": "A1-U03-S2",
"title": "冷热、加奶和糖",
"minutes": 12,
"itemIds": [
"A1-U03-W04",
"A1-U03-W05",
"A1-U03-P03",
"A1-U03-P04",
"A1-U03-W06"
],
"listening": {
"text": "I'd like a tea, please. Hot or cold? Hot, please. With milk? Yes, with milk. No sugar, please.",
"question": "顾客的茶是怎么要的?",
"options": [
"热的,加奶,不加糖",
"冰的,加奶,加糖",
"热的,不加奶,加糖"
]
},
"speaking": [
{
"text": "Hot, please."
},
{
"text": "With milk, please."
},
{
"text": "No sugar, please."
},
{
"text": "A cold orange juice, please."
}
],
"reading": {
"text": "Anna: Hi. I'd like a coffee, please.\nTom: Hot or cold?\nAnna: Cold, please. With milk.\nTom: Sugar?\nAnna: No sugar, please. And an apple juice for my sister.\nTom: Okay. One cold coffee with milk and one apple juice.",
"question": "Anna 给妹妹点了什么?",
"options": [
"apple juice",
"cold coffee",
"milk"
]
},
"writing": {
"prompt": "写下你想要的饮料:热的、加奶、不加糖。",
"example": "A hot coffee with milk, please. No sugar.",
"itemIds": [
"A1-U03-W04",
"A1-U03-P03",
"A1-U03-P04"
]
},
"independent": {
"prompt": "说说你平时怎么喝咖啡或茶:要热的还是冰的,加不加奶和糖。",
"itemIds": [
"A1-U03-W04",
"A1-U03-W05",
"A1-U03-P03",
"A1-U03-P04"
]
}
},
{
"id": "A1-U03-S3",
"title": "加点吃的、带走和结束点单",
"minutes": 12,
"itemIds": [
"A1-U03-W07",
"A1-U03-P05",
"A1-U03-P06"
],
"listening": {
"text": "Anything else? A sandwich, please. For here or to go? To go, please. Is that all? Yes, that's all, thanks.",
"question": "顾客是在店里吃还是带走?",
"options": [
"带走",
"在店里吃",
"还没决定"
]
},
"speaking": [
{
"text": "A chicken sandwich, please."
},
{
"text": "To go, please."
},
{
"text": "For here, please."
},
{
"text": "That's all, thanks."
}
],
"reading": {
"text": "Tom: Next, please! What would you like?\nMia: A cheese sandwich and a small tea, please.\nTom: For here or to go?\nMia: For here. Is there a free table?\nTom: Yes, there. Anything else? The cake is delicious.\nMia: No, that's all, thanks.\nTom: That's nine dollars. Your food is ready in five minutes.",
"question": "Mia 点了什么?",
"options": [
"奶酪三明治和小杯茶",
"蛋糕和小杯茶",
"奶酪三明治和蛋糕"
]
},
"writing": {
"prompt": "写两句话:说要带走,再说不要别的了。",
"example": "To go, please. That's all, thanks.",
"itemIds": [
"A1-U03-P05",
"A1-U03-P06"
]
},
"independent": {
"prompt": "你点了一杯饮料和一个三明治:说带走还是在店里吃,最后结束点单。",
"itemIds": [
"A1-U03-W07",
"A1-U03-P05",
"A1-U03-P06"
]
}
}
],
"scenes": [
{
"id": "A1-U03-C1",
"kind": "main",
"title": "早上买咖啡",
"learnerRole": "顾客",
"aiRole": "咖啡店店员",
"setting": "早上你在咖啡店,想买一杯热咖啡和一个三明治带走。",
"turns": [
{
"ai": "Good morning! What would you like?",
"goal": "点一杯咖啡",
"model": "I'd like a coffee, please.",
"zh": "我想要一杯咖啡。",
"itemIds": [
"A1-U03-P01"
]
},
{
"ai": "Sure. Small or large?",
"goal": "要大杯、热的",
"model": "Large, please. Hot.",
"zh": "大杯,热的。",
"itemIds": [
"A1-U03-W02",
"A1-U03-W04"
]
},
{
"ai": "Milk and sugar?",
"goal": "加奶,不加糖",
"model": "With milk, please. No sugar.",
"zh": "加奶,不要糖。",
"itemIds": [
"A1-U03-P03",
"A1-U03-P04"
]
},
{
"ai": "Okay. Anything else? The chocolate cake is very sweet.",
"goal": "不要蛋糕,加一个三明治",
"model": "No, thanks. A sandwich, please.",
"zh": "不用了,谢谢。要一个三明治。",
"itemIds": [
"A1-U03-W07"
]
},
{
"ai": "For here or to go?",
"goal": "说带走,并结束点单",
"model": "To go, please. That's all, thanks.",
"zh": "带走。就这些,谢谢。",
"itemIds": [
"A1-U03-P05",
"A1-U03-P06"
]
}
]
},
{
"id": "A1-U03-C2",
"kind": "variant",
"title": "先看菜单,替朋友点单",
"learnerRole": "顾客",
"aiRole": "咖啡店店员",
"setting": "你和朋友在咖啡店,你还没看菜单,店员已经来问了。",
"turns": [
{
"ai": "Hi! Are you ready to order?",
"goal": "说抱歉,请店员给你看菜单",
"model": "Sorry, can I see the menu, please?",
"zh": "抱歉,可以看一下菜单吗?",
"itemIds": [
"A1-U03-P02"
]
},
{
"ai": "Here you are. Drinks: tea, coffee and juice.",
"goal": "给自己点一小杯橙汁",
"model": "I'd like a small orange juice, please.",
"zh": "我要一小杯橙汁。",
"itemIds": [
"A1-U03-P01",
"A1-U03-W01",
"A1-U03-W06"
]
},
{
"ai": "A cold orange juice. It's two dollars.",
"goal": "再给朋友点一杯茶",
"model": "Okay. And a cup of tea for my friend.",
"zh": "好的。再给我朋友一杯茶。",
"itemIds": [
"A1-U03-W03"
]
},
{
"ai": "Hot tea. With milk?",
"goal": "说不加奶,也不加糖",
"model": "No milk. No sugar, please.",
"zh": "不加奶,也不要糖。",
"itemIds": [
"A1-U03-P04"
]
},
{
"ai": "Okay. Anything else?",
"goal": "说就这些",
"model": "That's all, thanks.",
"zh": "就这些,谢谢。",
"itemIds": [
"A1-U03-P06"
]
}
]
},
{
"id": "A1-U03-C3",
"kind": "variant",
"title": "没有冰咖啡了",
"learnerRole": "顾客",
"aiRole": "早餐店店员",
"setting": "你想要冰咖啡,但店里今天没有。",
"turns": [
{
"ai": "Hello! What would you like?",
"goal": "点一个三明治和一杯冰咖啡",
"model": "I'd like a sandwich and a cold coffee, please.",
"zh": "我要一个三明治和一杯冰咖啡。",
"itemIds": [
"A1-U03-P01",
"A1-U03-W07",
"A1-U03-W05"
]
},
{
"ai": "Sorry, no cold coffee today. Hot coffee?",
"goal": "说热的也行,要小杯",
"model": "Okay, a small hot coffee, please.",
"zh": "好吧,一小杯热咖啡。",
"itemIds": [
"A1-U03-W01",
"A1-U03-W04"
]
},
{
"ai": "With milk?",
"goal": "说要加奶",
"model": "Yes, with milk, please.",
"zh": "要,加奶。",
"itemIds": [
"A1-U03-P03"
]
},
{
"ai": "For here or to go? You can eat at this table.",
"goal": "说在店里吃",
"model": "For here, please.",
"zh": "在这里吃。",
"itemIds": [
"A1-U03-P05"
]
},
{
"ai": "That's six dollars. Enjoy your breakfast!",
"goal": "付钱并道谢",
"model": "Here you are. Thank you!",
"zh": "给你。谢谢!",
"itemIds": []
}
]
}
],
"tasks": [
{
"id": "A1-U03-T1",
"sceneId": "A1-U03-C1",
"goal": "点一杯大杯热咖啡,说清加奶不加糖,再加一个三明治带走",
"itemIds": [
"A1-U03-P01",
"A1-U03-W02",
"A1-U03-W04",
"A1-U03-P03",
"A1-U03-P04",
"A1-U03-W07",
"A1-U03-P05",
"A1-U03-P06"
],
"slots": [
"饮料",
"大小",
"冷热",
"奶和糖",
"带走或堂食"
]
},
{
"id": "A1-U03-T2",
"sceneId": "A1-U03-C2",
"goal": "先要菜单,再给自己和朋友各点一杯饮料",
"itemIds": [
"A1-U03-P02",
"A1-U03-P01",
"A1-U03-W01",
"A1-U03-W06",
"A1-U03-W03",
"A1-U03-P04",
"A1-U03-P06"
],
"slots": [
"自己的饮料",
"朋友的饮料"
]
},
{
"id": "A1-U03-T3",
"sceneId": "A1-U03-C3",
"goal": "想要的饮料没有时换一个,并说在店里吃",
"itemIds": [
"A1-U03-P01",
"A1-U03-W07",
"A1-U03-W05",
"A1-U03-W01",
"A1-U03-W04",
"A1-U03-P03",
"A1-U03-P05"
],
"slots": [
"替代的饮料",
"堂食或带走"
]
}
],
"materials": [
{
"id": "A1-U03-M1",
"mode": "listening",
"title": "咖啡店广播:介绍吃的喝的",
"text": "Good morning, and welcome to our cafe! Would you like a hot drink or a cold drink? Our coffee is very good. A small cup is three dollars, a large cup is four dollars. Do you want it with milk? We also have food: fresh bread, cake, chocolate cookies, cheese sandwiches and chicken. There is orange juice and sweet apple cake too. It's all delicious! Is it for here or to go? Sit at a table, please. Your order is ready in one minute. Enjoy your breakfast!",
"glosses": {
"fresh": "新鲜的",
"too": "也",
"sit": "坐"
},
"questions": [
{
"type": "gist",
"question": "这段话主要介绍什么?",
"options": [
"咖啡店的饮料和吃的",
"怎么坐公交车",
"酒店的房间"
]
},
{
"type": "detail",
"question": "大杯咖啡多少钱?",
"options": [
"四美元",
"三美元",
"五美元"
]
}
]
},
{
"id": "A1-U03-M2",
"mode": "reading",
"title": "读一段对话:点咖啡和点心",
"text": "Ben: Good morning! Can I see the menu, please? I want some breakfast.\nStaff: Sure. Here you are.\nBen: I'd like a large coffee, hot, with milk. No sugar, please. And some bread.\nStaff: We have fresh bread, apple cake and chocolate cookies. They are all sweet.\nBen: One chocolate cake, please. Is the chicken sandwich good?\nStaff: Yes, it's delicious. The cheese one is nice too.\nBen: OK, a chicken sandwich. That's all, thanks. To go, please.\nStaff: Sit at that table for one minute. Your order is ready. Enjoy!\nBen: Thank you, my friend!",
"glosses": {
"staff": "员工,服务员",
"fresh": "新鲜的",
"too": "也",
"sit": "坐"
},
"questions": [
{
"type": "detail",
"question": "Ben 的咖啡怎么做?",
"options": [
"大杯、热的、加奶、不加糖",
"小杯、冷的、加糖",
"中杯、加奶和糖"
]
},
{
"type": "detail",
"question": "他点了哪种三明治?",
"options": [
"鸡肉的",
"奶酪的",
"没有点三明治"
]
}
]
}
],
"excluded": [
{
"en": "medium",
"reason": "B1;A1 只学 small 和 large"
},
{
"en": "latte / cappuccino",
"reason": "CEFR-J 未收录,作为菜单专名由应用临时提示"
}
]
}