getCachedMetaDataStatus method
根据本地缓存文件判定当前缓存状态。 success.json 校验失败时先尝试按课程目录修复路径;仅当磁盘上已无核心视频时才删除 manifest,避免直连 Flutter/iOS 误判导致「缓存丢失」。
Implementation
Future<CacheStatusEnum> getCachedMetaDataStatus(String classId) async {
classId = _trimClassId(classId);
if (classId.isEmpty) return CacheStatusEnum.notCached;
final cacheDir = await _ensureCacheDir();
final safeId = _safeId(classId);
final successPath = p.join(cacheDir.path, '$safeId-success.json');
final successFile = File(successPath);
if (await successFile.exists()) {
var valid = await _validateSuccessJsonFiles(successFile);
if (!valid) {
await _repairSuccessJsonFromClassDir(safeId, successFile);
valid = await _validateSuccessJsonFiles(successFile);
}
if (!valid) {
valid = await _validateSuccessCoreVideosOnly(successFile);
}
if (!valid) {
if (!await _classCoreVideosExist(safeId)) {
try {
await successFile.delete();
} catch (_) {}
}
return CacheStatusEnum.notCached;
}
return CacheStatusEnum.cachedSuccess;
}
// 优先于 failed.json:重试下载时会先写入 meta,避免仍显示「缓存失败」
final metaPath = p.join(cacheDir.path, '$safeId.json');
if (await File(metaPath).exists()) {
if (_downloadingClassIds.contains(classId)) {
return CacheStatusEnum.caching;
}
if (_pausedClassIds.contains(classId)) {
return CacheStatusEnum.cachePaused;
}
return CacheStatusEnum.cacheInterrupted;
}
if (await File(p.join(cacheDir.path, '$safeId-failed.json')).exists()) {
return CacheStatusEnum.cachedFailed;
}
return CacheStatusEnum.notCached;
}