fix: 修正学习流程中的证据、复习与进度问题
- 独立尝试按课程要求校验内容,不再任意输入即算独立成功 - 复习节点改为学后第 1/3/7/14 天,之后每 30 天抽查;复习轮换情境 - 掌握状态按作答记录推导:需认识、可回忆、跨情境使用及最近两次无帮助 - 课程证据按实际用到的目标记录;跟读与课程对话只算辅助练习 - 复习成功不再降低已有状态 - 学完课程后进入下一节未完成课程;全部学完后引导巩固与阶段评估 - 新增 3 题基础定位,按结果设置起始课程 - 新增按课程开放的对话场景,首页推荐最少练习的场景 - 切换课程时清空上一课的步骤进度 - AI 返回 JSON 格式并按 JSON 回放历史;拼写校验忽略大小写与连字符;移除学习目标选择 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ class _LearningShellState extends State<LearningShell> {
|
||||
var route = _ShellRoute.tab;
|
||||
_ShellRoute? previousRoute;
|
||||
bool dialogueInLesson = false;
|
||||
String sceneId = 'a0-meet';
|
||||
AssessmentPack? assessmentPack;
|
||||
DialogueSummaryData? dialogueSummary;
|
||||
|
||||
@@ -45,9 +46,10 @@ class _LearningShellState extends State<LearningShell> {
|
||||
route = _ShellRoute.scene;
|
||||
});
|
||||
|
||||
void showDialogue({bool inLesson = false}) => setState(() {
|
||||
void showDialogue({bool inLesson = false, String? scene}) => setState(() {
|
||||
previousRoute = route;
|
||||
dialogueInLesson = inLesson;
|
||||
if (scene != null) sceneId = scene;
|
||||
route = _ShellRoute.dialogue;
|
||||
});
|
||||
|
||||
@@ -125,13 +127,16 @@ class _LearningShellState extends State<LearningShell> {
|
||||
);
|
||||
case _ShellRoute.scene:
|
||||
body = DialogueScenePage(
|
||||
onStart: showDialogue,
|
||||
state: widget.state,
|
||||
onStart: (id) => showDialogue(scene: id),
|
||||
onBack: () => showTab(tab),
|
||||
);
|
||||
case _ShellRoute.dialogue:
|
||||
body = DialoguePage(
|
||||
key: ValueKey(dialogueInLesson ? 'lesson' : 'scene-$sceneId'),
|
||||
state: widget.state,
|
||||
isLessonDialogue: dialogueInLesson,
|
||||
sceneId: sceneId,
|
||||
onFinished: (summary) {
|
||||
if (dialogueInLesson) {
|
||||
showLesson();
|
||||
@@ -147,7 +152,7 @@ class _LearningShellState extends State<LearningShell> {
|
||||
summary: dialogueSummary!,
|
||||
onHome: () => showTab(AppTab.home),
|
||||
onLesson: showLesson,
|
||||
onRetry: showDialogue,
|
||||
onRetry: () => showDialogue(scene: sceneId),
|
||||
onBack: () => showTab(tab),
|
||||
);
|
||||
case _ShellRoute.settings:
|
||||
@@ -194,7 +199,8 @@ class _LearningShellState extends State<LearningShell> {
|
||||
selectedIndex: tab.index,
|
||||
height: 70,
|
||||
indicatorColor: AppColors.softGreen,
|
||||
onDestinationSelected: (index) => showTab(AppTab.values[index]),
|
||||
onDestinationSelected: (index) =>
|
||||
showTab(AppTab.values[index]),
|
||||
destinations: const [
|
||||
NavigationDestination(
|
||||
icon: Icon(Icons.home_outlined),
|
||||
@@ -243,6 +249,16 @@ class _LearningShellState extends State<LearningShell> {
|
||||
},
|
||||
onOpenDialogue: showDialogueScene,
|
||||
onResumeLessonDialogue: () => showDialogue(inLesson: true),
|
||||
onStartReinforcement: () {
|
||||
widget.state.scheduleA0Reinforcement();
|
||||
showTab(AppTab.review);
|
||||
},
|
||||
onOpenAssessment: (packId) {
|
||||
final pack = a0AssessmentPacks
|
||||
.where((item) => item.id == packId)
|
||||
.firstOrNull;
|
||||
if (pack != null) showAssessment(pack);
|
||||
},
|
||||
);
|
||||
case AppTab.learn:
|
||||
return _LearningMap(
|
||||
@@ -258,7 +274,10 @@ class _LearningShellState extends State<LearningShell> {
|
||||
state: widget.state,
|
||||
);
|
||||
case AppTab.dialogue:
|
||||
return DialogueScenePage(onStart: showDialogue);
|
||||
return DialogueScenePage(
|
||||
state: widget.state,
|
||||
onStart: (id) => showDialogue(scene: id),
|
||||
);
|
||||
case AppTab.review:
|
||||
return ReviewPage(
|
||||
state: widget.state,
|
||||
|
||||
Reference in New Issue
Block a user