Repository navigation
Conversation
|
在测试过程中发现了以下几个问题(脱敏后的接口响应:loadKbxx.sanitized.json): 1. 仅含文字排课的历史课程被误归入“未排课”在脱敏数据中, {
"KCDM": "TEST001",
"KCMC": "测试课程01",
"XNXQMC": "2025-2026学年 第二学期",
"PKSJDD": "1-12周 星期二[3-4节]测试教室01;1-12周 星期四[3-4节]测试教室01;13-16周 星期二[3-4节]测试教室02;13-16周 星期四[3-4节]测试教室02"
}目前 传入上述 JSON 后调用 建议: 当 2. 切回本科来源后重启,仍会加载旧的研究生课表从研究生切回本科时,回退逻辑只更新了内存中的 if (!_semesterInfo!.semesters.values
.any((terms) => terms.containsValue(_selectedSemesterId))) {
_selectedSemesterId = _semesterInfo?.defaultSemester;
}重启并重新加载缓存时,读取的仍是旧的研究生学期 ID,且学期合法性校验仅在 建议: 切换回退学期时同步持久化 3. 同一课程存在分段排课时,调课日期会被忽略
} else if (_text(row['BJDM']).isNotEmpty &&
rows
.where(
(r) =>
_inTerm(r, rawTerm(semesterId)) &&
r['BJDM'] == row['BJDM'] &&
_text(r['KSJCDM']) == _text(row['KSJCDM']) &&
_text(r['JSJCDM']) == _text(row['JSJCDM']),
)
.length ==
1) {遇到前后半学期换教室等拆分为多条记录的情况时,实际日期会被跳过,退回按 建议: 放宽唯一记录限制或按周次范围匹配调课日期,并补充拆分记录下的调课、停课及教室分配单测。 4. 刷新途中切换账号,会导致新账号无法拉取课表当账号 A 的请求尚未结束时切换到账号 B,B 的 600ms 定时刷新触发后, Future<void> _fetchAndStamp() async {
final account = _campusAccount();
await fetchAll();
if (account != null && account == _campusAccount() && _error == null) {
_fetchedForAccount = account;
}
}随后 A 的响应因账号变更被丢弃,而 B 因为已被标记为 建议: 仅在当前账号的请求真正完成且未发生账号切换时更新 5. 学期名称重复拼接学年与“学期”后缀当 原因是 研究生学期解析只匹配了“秋 / 春 / 暑”,未命中时直接保留了完整的 建议: 解析时兼容“第一学期 / 第二学期”等官方命名(或剥离已有的学年与“学期”字样),避免重复拼接。 6. 切换课表来源后,加载中或请求失败时仍展示旧来源课表从研究生课表切换到本科课表时, 由于 建议: 切换来源时立即切换或重置展示状态,优先加载目标来源的本地缓存;若无缓存则展示对应的加载态或错误态,避免跨来源残留旧数据。 |
|
谢谢提供脱敏样本和复现步骤。我在 PR 提交 |
There was a problem hiding this comment.
🟡 Changes recommended
Active moderate and critical findings remain around stale graduate cache reuse, incorrect CASTGC handling, missing owner scoping, and account-revision race conditions.
6 open issues
Keep the bound CASTGC instead of persisting response cookies · New Clear persisted graduate caches when unbinding an account · New Persist graduate course tables with account ownership · New Recheck account revision before persisting graduate responses · New Owner-scope cached tables for non-selected graduate semesters · New Clear stale undergraduate exams when graduate exams are unsupported · New
Review effort: Lite
| if (raw.trim().isEmpty) continue; | ||
| try { | ||
| final cookie = Cookie.fromSetCookieValue(raw.trim()); | ||
| if (cookie.name == 'CASTGC' && uri.host != idsHost) continue; |
| _identityForAccount = null; | ||
| _graduateIdentity = false; | ||
| _identityLabel = null; | ||
| _identityWarning = null; | ||
| _fetchedForAccount = null; | ||
| _clearSchedule(); |
| _courseTable = table; | ||
| await _storage.saveGraduateSchedule(account, snapshot); | ||
| await _storage.setSelectedSemester(semester); | ||
| await _storage.saveCourseTable(semester, table); |
| await _storage.saveGraduateSchedule(account, snapshot); | ||
| await _storage.setSelectedSemester(semester); | ||
| await _storage.saveCourseTable(semester, table); | ||
| if (revision != _accountRevision) return true; |
| Future<void> saveCourseTable(String semesterId, CourseTable table, {String? owner}) => | ||
| _prefs.setString( | ||
| '$_courseTablePrefix$semesterId', | ||
| jsonEncode({...table.toJson(), if (owner != null) 'owner': owner}), | ||
| ); |
| if (_schedule.hasGraduateIdentity || | ||
| _schedule.isGraduate || | ||
| semesterId?.startsWith(graduateSemesterPrefix) == true) { | ||
| _platformErrors.remove('exam'); | ||
| return null; |



改动
现有课表仅使用本科 EAMS,研究生账号无法读取研究生选课系统的排课。新增 IDS 身份分流和研究生只读适配,将学校响应转换成现有课表数据结构,复用时间网格、周切换、自定义课程和日历导出。
rq与教学周交叉验证首周日期,不能唯一确定时保留手动配置。自动模式每次启动的首轮刷新会新增 IDS 分类查询;查询失败时仅沿用同账号已确认的分类,或由用户手动选择来源,不根据研究生系统可访问性猜测身份。
此次改动无需修改后端代码。
本地验证
验证基于上游
00c5645加本次 11 文件补丁的独立快照:flutter analyze --no-pub:无问题。flutter test --no-pub:718 项通过,3 项失败;课表、身份、SSO、日期推算、缓存、本科分流及请求合并相关测试均通过。已知限制
研究生考试暂未接入。