import 'school_identity.dart'; /// School-specific term numbers, independent of teaching-week dates. class SchoolTerm { SchoolTerm(this.id, {this.school = SupportedSchool.uestcGraduate}) { if (id < 1 || id > 9999 || (school == SupportedSchool.uestcUndergraduate && (id < 3 || (id - 3) % 20 != 0))) { throw ArgumentError('学校学期编号无效'); } } final int id; final SupportedSchool school; String get label { if (school == SupportedSchool.uestcUndergraduate) { final n = (id - 3) ~/ 20, year = 2013 + ((id - 3) ~/ 40); return '$year-${year + 1}${n.isEven ? '第一学期' : '第二学期'}'; } final year = 1990 + ((id - 1) ~/ 2); return '$year-${year + 1}年${id.isOdd ? '秋' : '春'}'; } static List get choices => List.generate(73, (index) => SchoolTerm(73 - index)); static List undergraduateChoices( DateTime now, { SchoolTerm? saved, }) { final maxN = (now.year + 1 - 2013) * 2 + 1; final ids = { for (var n = 0; n <= maxN; n++) 3 + n * 20, if (saved?.school == SupportedSchool.uestcUndergraduate) saved!.id, }.toList()..sort((a, b) => b.compareTo(a)); return ids .where((id) => id <= 9999) .map((id) => SchoolTerm(id, school: SupportedSchool.uestcUndergraduate)) .toList(); } void _graduateOnly() { if (school != SupportedSchool.uestcGraduate) throw StateError('本科查询不能使用研究生链接'); } Uri get timetableUri { _graduateOnly(); return Uri.https('yjsjy.uestc.edu.cn', '/pyxx/pygl/xskbcx/index/$id'); } Uri get examUri { _graduateOnly(); return Uri.https('yjsjy.uestc.edu.cn', '/pyxx/pygl/kskcxx/index', { 'xq': '$id', }); } Map toJson() => {'id': id, 'schoolId': school.id}; factory SchoolTerm.fromJson(Map json) { if (json['id'] is! int) throw const FormatException('学校学期无效'); try { return SchoolTerm( json['id'] as int, school: json['schoolId'] == null ? SupportedSchool.uestcGraduate : SupportedSchool.fromId(json['schoolId'] as String), ); } catch (_) { throw const FormatException('学校学期无效'); } } @override bool operator ==(Object other) => other is SchoolTerm && other.id == id && other.school == school; @override int get hashCode => Object.hash(id, school); }