242 lines
7.7 KiB
Dart
Executable File
242 lines
7.7 KiB
Dart
Executable File
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;
|
||
}
|
||
}
|