feat: 完善听力口语辅助状态记录、练习分块与复习抽查间隔机制

This commit is contained in:
shen
2026-09-23 18:33:22 -07:00
parent 6b42b7abc3
commit d740a9e19c
106 changed files with 2933 additions and 845 deletions
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import '../../core/app_state.dart';
import '../../core/app_theme.dart';
import '../../core/courses/courses.dart';
import '../../core/models.dart';
import '../../widgets/app_widgets.dart';
/// 课程路径:全部课程按顺序排列,显示完成、当前与锁定状态。
@@ -17,7 +18,10 @@ class LessonPath extends StatelessWidget {
@override
Widget build(BuildContext context) {
final done = allLessons
final available = allLessons
.where((lesson) => lesson.status == ContentStatus.approved)
.toList();
final done = available
.where((lesson) => state.completedLessonIds.contains(lesson.id))
.length;
return SpacedColumn(
@@ -32,7 +36,7 @@ class LessonPath extends StatelessWidget {
),
),
Text(
'$done/${allLessons.length} 完成',
'$done/${available.length} 已开放课程完成',
style: TextStyle(fontSize: 13, color: AppColors.muted),
),
],
@@ -66,7 +70,8 @@ class _LessonTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
final completed = state.completedLessonIds.contains(lesson.id);
final current = lesson.id == state.activeLessonId && !completed;
final draft = lesson.status != ContentStatus.approved;
final current = lesson.id == state.activeLessonId && !completed && !draft;
final open =
state.isLessonUnlocked(lesson.id) &&
(!state.reviewBacklog || completed);
@@ -98,7 +103,9 @@ class _LessonTile extends StatelessWidget {
),
const SizedBox(height: 3),
Text(
segments > 1
draft
? '待教学审校后开放'
: segments > 1
? '${lesson.outcome} · 小段 $segmentsDone/$segments'
: lesson.outcome,
style: Theme.of(context).textTheme.bodyMedium,
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import '../../core/app_state.dart';
import '../../core/app_theme.dart';
import '../../core/courses/courses.dart';
import '../../core/models.dart';
import '../../widgets/app_widgets.dart';
/// 今天最该做的一件事:继续课程对话 → 到期复习 → 阶段评估/巩固 → 下一课。
@@ -50,7 +51,8 @@ class TodayTaskCard extends StatelessWidget {
_TodayTask _todayTask() {
var lessonId = state.activeLessonId;
if (state.completedLessonIds.contains(lessonId)) {
if (state.completedLessonIds.contains(lessonId) ||
lessonById(lessonId).status != ContentStatus.approved) {
final next = state.nextIncompleteLessonId;
if (next != null) {
lessonId = next;
@@ -101,8 +103,8 @@ class TodayTaskCard extends StatelessWidget {
if (state.allLessonsComplete) {
return _TodayTask(
label: '已学完',
title: '所有课程已完成',
note: '你已学完全部课程内容!建议保持日常到期复习或自由情境对话。',
title: '当前开放课程已完成',
note: '后续课程待教学审校开放。现在可以继续到期复习或自由情境对话。',
action: '去复习',
minutes: '10 分钟',
onPressed: onStartReview,