import 'dart:io'; import 'package:path_provider/path_provider.dart'; /// 生图流程创建任务后,按接口返回的 `tree`(任务 id)将用户上传的压缩图存一份到本地; /// Gallery 在接口未返回封面 URL 时可用其作为卡片底图。 abstract final class GalleryUploadCoverStore { static const String _subdir = 'gallery_upload_covers'; static const String _fileExt = '.jpg'; /// 本地封面最多保留时长,超时文件会在下次读/写前删除。 static const Duration maxRetention = Duration(hours: 25); static Future _directory() async { final base = await getApplicationSupportDirectory(); final dir = Directory('${base.path}/$_subdir'); if (!await dir.exists()) { await dir.create(recursive: true); } return dir; } static Future _directoryAfterPurge() async { final dir = await _directory(); await _purgeExpired(dir); return dir; } static Future _purgeExpired(Directory dir) async { if (!await dir.exists()) return; final now = DateTime.now(); try { await for (final entity in dir.list(followLinks: false)) { if (entity is! File) continue; final name = entity.uri.pathSegments.last; if (!name.endsWith(_fileExt)) continue; final stat = await entity.stat(); if (now.difference(stat.modified) >= maxRetention) { try { await entity.delete(); } catch (_) {} } } } catch (_) {} } static File _fileForTask(Directory dir, int taskId) => File('${dir.path}/$taskId$_fileExt'); /// [source] 一般为 [compressImageForUpload] 输出的待上传文件。 static Future saveForTask(int taskId, File source) async { if (taskId <= 0) return; if (!await source.exists()) return; final dir = await _directoryAfterPurge(); final dest = _fileForTask(dir, taskId); await source.copy(dest.path); } static Future pathIfExists(int taskId) async { if (taskId <= 0) return null; final dir = await _directoryAfterPurge(); final f = _fileForTask(dir, taskId); return await f.exists() ? f.path : null; } /// 仅查询 [ids] 中已有文件的 path,用于列表刷新后一次性填充状态。 static Future> existingPathsForTaskIds( Iterable ids, ) async { final dir = await _directoryAfterPurge(); final out = {}; for (final id in ids) { if (id <= 0) continue; final f = _fileForTask(dir, id); if (await f.exists()) { out[id] = f.path; } } return out; } }