242 lines
7.7 KiB
Dart
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<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哈希值
String getFileNameFromUrl(String url, String extension, int recordType) {
final hash = md5.convert(utf8.encode(url)).toString(); // 使用 md5 生成哈希值
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));
}
// 下载文件方法(支持视频和图片)
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); // 自动检测文件类型
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;
}
}