整个课程和数据UI重新设计版本
This commit is contained in:
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../../core/app_state.dart';
|
||||
import '../../core/app_theme.dart';
|
||||
import '../../core/assessment_bank.dart';
|
||||
import '../../core/courses/courses.dart';
|
||||
import '../../core/models.dart';
|
||||
import '../../core/voice_service.dart';
|
||||
import '../../widgets/app_widgets.dart';
|
||||
@@ -221,7 +221,7 @@ class _AssessmentPageState extends State<AssessmentPage>
|
||||
results[task.id] = correct;
|
||||
widget.state.recordAssessmentAttempt(
|
||||
taskId: task.id,
|
||||
skill: _skillLabel(task.skill),
|
||||
skill: task.skill.label,
|
||||
correct: correct,
|
||||
rawAnswer: answer == null ? controller.text.trim() : task.choices[answer],
|
||||
spoken: task.skill == AssessmentSkill.speaking,
|
||||
@@ -254,7 +254,7 @@ class _AssessmentPageState extends State<AssessmentPage>
|
||||
results[speaking.id] = false;
|
||||
widget.state.recordAssessmentPending(
|
||||
taskId: speaking.id,
|
||||
skill: _skillLabel(AssessmentSkill.speaking),
|
||||
skill: AssessmentSkill.speaking.label,
|
||||
reason: '设备麦克风或语音识别不可用,等待补测。',
|
||||
);
|
||||
}
|
||||
@@ -327,13 +327,20 @@ class _AssessmentPageState extends State<AssessmentPage>
|
||||
SectionCard(
|
||||
tint: AppColors.warm,
|
||||
child: Text(
|
||||
'待评估:${record.pendingSkills.map(_skillLabel).join('、')}。技术问题不会计为语言错误。',
|
||||
'待评估:${record.pendingSkills.map((skill) => skill.label).join('、')}。技术问题不会计为语言错误。',
|
||||
),
|
||||
),
|
||||
if (record.failedSkills.isNotEmpty) const Text('建议补练:'),
|
||||
for (final skill in record.failedSkills)
|
||||
SectionCard(child: Text(_remediation(skill))),
|
||||
],
|
||||
if (_wrongTasks.isNotEmpty) ...[
|
||||
const Text(
|
||||
'错题回顾',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
||||
),
|
||||
for (final wrong in _wrongTasks) _WrongAnswerCard(wrong: wrong),
|
||||
],
|
||||
if (!record.passed && replacementFor(widget.pack.id) != null)
|
||||
SecondaryButton(
|
||||
label: '开始替换题补测',
|
||||
@@ -359,7 +366,7 @@ class _AssessmentPageState extends State<AssessmentPage>
|
||||
child: SpacedColumn(
|
||||
children: [
|
||||
Text(
|
||||
_skillLabel(task.skill),
|
||||
task.skill.label,
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
),
|
||||
const Text('评估中不提供翻译、句框或答案。需要帮助请退出后先做补练。'),
|
||||
@@ -435,16 +442,50 @@ class _AssessmentPageState extends State<AssessmentPage>
|
||||
);
|
||||
}
|
||||
|
||||
/// Tasks answered wrong in this attempt, with the learner's latest answer.
|
||||
List<({AssessmentTask task, String answer})> get _wrongTasks => [
|
||||
for (final task in widget.pack.tasks)
|
||||
if (results[task.id] == false)
|
||||
if (widget.state.attemptEvidence.reversed
|
||||
.where((item) => item.taskId == task.id)
|
||||
.firstOrNull
|
||||
case final evidence? when evidence.outcome != EvidenceKind.pending)
|
||||
(task: task, answer: evidence.rawAnswer ?? ''),
|
||||
];
|
||||
|
||||
String _remediation(AssessmentSkill skill) => switch (skill) {
|
||||
AssessmentSkill.listening => '听力:回到数字、星期/时间和场景听辨复习;下一次会使用不同音频。',
|
||||
AssessmentSkill.speaking => '口语:练姓名、号码、物品、家人、星期、整点和请求重复;确认未编辑转写后再补测。',
|
||||
AssessmentSkill.reading => '阅读:复习人物、地点、数字和时间信息定位,再阅读不同短对话。',
|
||||
AssessmentSkill.writing => '写作:分别练完整的姓名、地点、喜好、物品、星期/时间句,不使用句框。',
|
||||
};
|
||||
String _skillLabel(AssessmentSkill skill) => switch (skill) {
|
||||
AssessmentSkill.listening => '听力',
|
||||
AssessmentSkill.speaking => '口语',
|
||||
AssessmentSkill.reading => '阅读',
|
||||
AssessmentSkill.writing => '写作',
|
||||
};
|
||||
}
|
||||
|
||||
class _WrongAnswerCard extends StatelessWidget {
|
||||
const _WrongAnswerCard({required this.wrong});
|
||||
final ({AssessmentTask task, String answer}) wrong;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final task = wrong.task;
|
||||
return SectionCard(
|
||||
child: SpacedColumn(
|
||||
spacing: 6,
|
||||
children: [
|
||||
Text(
|
||||
'${task.skill.label} · ${task.audio ?? task.prompt}',
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
Text(
|
||||
'你的答案:${wrong.answer.isEmpty ? '(未作答)' : wrong.answer}',
|
||||
style: TextStyle(color: AppColors.warmInk),
|
||||
),
|
||||
Text(
|
||||
assessmentAnswerGuide(task, wrong.answer),
|
||||
style: TextStyle(color: AppColors.green),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user