feat: add undergraduate import and exam selection screens

This commit is contained in:
Codex
2026-10-15 00:11:50 +08:00
parent 68fe71e29a
commit 7939bd4c3c
7 changed files with 584 additions and 24 deletions
+28 -24
View File
@@ -134,7 +134,9 @@ class AppController extends ChangeNotifier {
Future<void> applyImport(
ImportDraft draft, {
required bool confirmedEmpty,
bool Function()? canApply,
}) => _run(() async {
if (canApply != null && !canApply()) throw StateError('学校页面已变化,请重新导入。');
if (draft.courses.isEmpty && (!draft.explicitlyEmpty || !confirmedEmpty)) {
throw const FormatException('未检测到课程,已有课表保持不变');
}
@@ -202,30 +204,32 @@ class AppController extends ChangeNotifier {
}
await _cleanupCalendar();
});
Future<void> applyExams(ExamSchedule value) => _run(() async {
final validated = ExamSchedule.fromJson(value.toJson());
if (validated.school == SupportedSchool.uestcUndergraduate) {
await _save(snapshot.copyWith(examSchedule: validated));
return;
}
final term = SchoolTerm(int.parse(validated.termId));
final changed = _differentTerm(term);
await _save(
snapshot.copyWith(
examSchedule: validated,
schoolTerm: term,
courses: changed ? [] : null,
clearMetadata: changed,
settings: changed
? snapshot.settings.copyWith(clearSemester: true)
: null,
),
);
if (changed) {
isDemo = false;
await _reconcile();
}
});
Future<void> applyExams(ExamSchedule value, {bool Function()? canApply}) =>
_run(() async {
if (canApply != null && !canApply()) throw StateError('学校查询已取消,请重新读取。');
final validated = ExamSchedule.fromJson(value.toJson());
if (validated.school == SupportedSchool.uestcUndergraduate) {
await _save(snapshot.copyWith(examSchedule: validated));
return;
}
final term = SchoolTerm(int.parse(validated.termId));
final changed = _differentTerm(term);
await _save(
snapshot.copyWith(
examSchedule: validated,
schoolTerm: term,
courses: changed ? [] : null,
clearMetadata: changed,
settings: changed
? snapshot.settings.copyWith(clearSemester: true)
: null,
),
);
if (changed) {
isDemo = false;
await _reconcile();
}
});
bool _differentTerm(SchoolTerm? next) =>
next != null &&
((snapshot.schoolTerm != null && snapshot.schoolTerm != next) ||