242 lines
7.7 KiB
Dart
Raw Permalink Normal View History

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';
2023-11-18 10:38:13 +08:00
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/versionUndate/versionUndate_entity.dart';
2023-11-18 10:38:13 +08:00
import 'editVideoLog_state.dart';
class EditVideoLogLogic extends BaseGetXController {
2023-11-18 10:38:13 +08:00
EditVideoLogState state = EditVideoLogState();
final VideoLogLogic videoLogLogic = Get.find<VideoLogLogic>();
Future<void> 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<void> 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<void> 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<bool> deleteDownloadsByPaths(List<String> 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<String, dynamic> logData =
Map<String, dynamic>.from(json.decode(content));
// 过滤出需要保留的文件
final filteredLogData = <String, dynamic>{};
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哈希值
2025-08-20 10:06:03 +08:00
String getFileNameFromUrl(String url, String extension, int recordType) {
final hash = md5.convert(utf8.encode(url)).toString(); // 使用 md5 生成哈希值
2025-08-20 10:06:03 +08:00
return '$recordType' + '_' + '$hash.$extension';
}
Future<void> recordDownloadTime(String filePath) async {
final appDocDir = await getApplicationDocumentsDirectory();
final logFilePath = '${appDocDir.path}/download_log.json';
// 读取现有的日志文件
Map<String, int> logData = {};
if (await File(logFilePath).exists()) {
final content = await File(logFilePath).readAsString();
logData = Map<String, int>.from(json.decode(content));
}
// 添加新的下载记录
logData[filePath] = DateTime.now().millisecondsSinceEpoch;
// 写入日志文件
await File(logFilePath).writeAsString(json.encode(logData));
}
// 下载文件方法(支持视频和图片)
2025-08-20 10:06:03 +08:00
Future<String?> 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); // 自动检测文件类型
2025-08-20 10:06:03 +08:00
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<bool> _requestPermission() async {
final status = await Permission.storage.request();
return status.isGranted;
}
}