import 'dart:convert'; import 'dart:io'; import 'package:crypto/crypto.dart'; import 'package:dio/dio.dart'; import 'package:get/get.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_logic.dart'; import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/versionUndate/versionUndate_entity.dart'; import 'editVideoLog_state.dart'; class EditVideoLogLogic extends BaseGetXController { EditVideoLogState state = EditVideoLogState(); final VideoLogLogic videoLogLogic = Get.find(); Future deleteLockCloudStorageList() async { final VersionUndateEntity entity = await ApiRepository.to.deleteLockCloudStorageList( recordIds: state.selectVideoLogList.value.map((e) => e.recordId).toList(), ); if (entity.errorCode!.codeIsSuccessful) { showToast('删除成功'.tr); await getLockCloudStorageList(); state.selectVideoLogList.clear(); } } Future getLockCloudStorageList() async { final VideoLogEntity entity = await ApiRepository.to.getLockCloudStorageList( lockId: state.getLockId.value, ); if (entity.errorCode!.codeIsSuccessful) { state.videoLogList.value = entity.data!; state.videoLogList.refresh(); } } Future downloadAndSaveToGallery(String url, String fileName) async { try { // 请求存储权限 if (await _requestPermission()) { final dio = Dio(); final directory = await getTemporaryDirectory(); final filePath = '${directory.path}/$fileName'; // 下载文件 await dio.download( url, filePath, onReceiveProgress: (received, total) { if (total != -1) { final progress = (received / total) * 100; print('下载进度: $progress%'); } }, ); // 保存到图库 if (fileName.endsWith('.jpg') || fileName.endsWith('.png')) { // 保存图片 final result = await ImageGallerySaver.saveFile(filePath); if (result['isSuccess']) { print('图片已保存到图库'); } else { print('图片保存失败'); } } else if (fileName.endsWith('.mp4')) { // 保存视频 final result = await ImageGallerySaver.saveFile(filePath); if (result['isSuccess']) { print('视频已保存到图库'); } else { print('视频保存失败'); } } // 删除临时文件 await File(filePath).delete(); } else { print('存储权限被拒绝'); } } catch (e) { print('下载或保存文件失败: $e'); } } // 批量删除指定文件路径列表中的文件 Future deleteDownloadsByPaths(List filePaths) async { try { showEasyLoading(); // 获取应用专属目录 Directory appDocDir = await getApplicationDocumentsDirectory(); final logFilePath = '${appDocDir.path}/download_log.json'; if (await File(logFilePath).exists()) { final content = await File(logFilePath).readAsString(); Map logData = Map.from(json.decode(content)); // 过滤出需要保留的文件 final filteredLogData = {}; for (final entry in logData.entries) { final filePath = entry.key; if (!filePaths.contains(filePath)) { filteredLogData[filePath] = entry.value; // 保留其他文件 } else { // 删除文件 final file = File(filePath); if (await file.exists()) { await file.delete(); print('已删除文件:$filePath'); } } } // 更新日志文件 await File(logFilePath).writeAsString(json.encode(filteredLogData)); showToast('删除成功'.tr); // 重新分组统计下载文件 await videoLogLogic.groupDownloadsByDay(); Get.back(); return true; } else { print('日志文件不存在'); return false; } } catch (e) { print('批量删除失败:$e'); return false; } finally { dismissEasyLoading(); } } // 根据URL生成唯一的文件名(MD5哈希值) String getFileNameFromUrl(String url, String extension, int recordType) { final hash = md5.convert(utf8.encode(url)).toString(); // 使用 md5 生成哈希值 return '$recordType' + '_' + '$hash.$extension'; } Future recordDownloadTime(String filePath) async { final appDocDir = await getApplicationDocumentsDirectory(); final logFilePath = '${appDocDir.path}/download_log.json'; // 读取现有的日志文件 Map logData = {}; if (await File(logFilePath).exists()) { final content = await File(logFilePath).readAsString(); logData = Map.from(json.decode(content)); } // 添加新的下载记录 logData[filePath] = DateTime.now().millisecondsSinceEpoch; // 写入日志文件 await File(logFilePath).writeAsString(json.encode(logData)); } // 下载文件方法(支持视频和图片) Future downloadFile(String? url, int recordType) async { if (url == null || url.isEmpty) { print('URL不能为空'); return null; } // 请求存储权限 if (await Permission.storage.request().isGranted) { try { // 获取应用专属目录(避免与其他应用冲突) Directory appDocDir = await getApplicationDocumentsDirectory(); // 根据URL生成唯一文件名(自动识别扩展名) String extension = _getFileTypeFromUrl(url); // 自动检测文件类型 String fileName = getFileNameFromUrl(url, extension, recordType); // 根据URL生成唯一文件名 String savePath = '${appDocDir.path}/downloads/$fileName'; // 自定义保存路径 // 确保目录存在 final dir = Directory('${appDocDir.path}/downloads'); if (!await dir.exists()) { await dir.create(recursive: true); } // 检查文件是否已存在 File file = File(savePath); if (await file.exists()) { print('文件已存在,无需重新下载:$savePath'); return savePath; // 文件已存在,直接返回路径 } // 下载文件 await Dio().download(url, savePath, onReceiveProgress: (received, total) { if (total != -1) { print('下载进度: ${(received / total * 100).toStringAsFixed(0)}%'); } }); // 记录下载时间 await recordDownloadTime(savePath); print('文件已成功下载到:$savePath'); // 返回下载路径以便后续使用 return savePath; } catch (e) { print('下载失败:$e'); return null; } } else { print('未获取存储权限'); return null; } } // 根据URL自动检测文件类型 String _getFileTypeFromUrl(String url) { final uri = Uri.parse(url); final path = uri.path; final extension = path.split('.').last.toLowerCase(); return extension.isNotEmpty ? extension : 'unknown'; } // 请求存储权限 Future _requestPermission() async { final status = await Permission.storage.request(); return status.isGranted; } }