Merge remote-tracking branch 'origin/develop_liyi' into develop_liyi

This commit is contained in:
Liuyf 2025-02-26 19:08:52 +08:00
commit 07e7d1dc91
16 changed files with 676 additions and 157 deletions

View File

@ -97,6 +97,7 @@ class CatEyeWorkModeLogic extends BaseGetXController {
); );
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
showToast('设置成功'.tr); showToast('设置成功'.tr);
getLockSettingInfoData();
} }
} }

View File

@ -197,7 +197,7 @@ class _VideoSlotPageState extends State<VideoSlotPage> {
Obx(() => Text( Obx(() => Text(
isEndTime == false isEndTime == false
? '${'当日'.tr}${state.startDate.value}' ? '${'当日'.tr}${state.startDate.value}'
: '${''.tr}${state.endDate.value}', : '${''.tr}${state.endDate.value}',
style: TextStyle( style: TextStyle(
color: state.isCustom.value == true color: state.isCustom.value == true
? AppColors.blueTextTipsColor ? AppColors.blueTextTipsColor

View File

@ -75,6 +75,11 @@ class ConfiguringWifiLogic extends BaseGetXController {
} else { } else {
Get.offAllNamed(Routers.starLockMain); Get.offAllNamed(Routers.starLockMain);
} }
dismissEasyLoading();
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
}
}); });
} }
} }
@ -85,6 +90,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
void _initReplySubscription() { void _initReplySubscription() {
_replySubscription = _replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async { EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
AppLog.log('收到蓝牙回调${EasyLoading.isShow}');
// WIFI配网结果 // WIFI配网结果
if (reply is GatewayConfiguringWifiResultReply) { if (reply is GatewayConfiguringWifiResultReply) {
_replySenderConfiguringWifiResult(reply); _replySenderConfiguringWifiResult(reply);
@ -95,6 +101,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
if (reply is GatewayGetStatusReply) { if (reply is GatewayGetStatusReply) {
_replyStatusInfo(reply); _replyStatusInfo(reply);
} }
AppLog.log('蓝牙回调处理完毕${EasyLoading.isShow}');
}); });
} }
@ -106,9 +113,6 @@ class ConfiguringWifiLogic extends BaseGetXController {
switch (status) { switch (status) {
case 0x00: case 0x00:
//
cancelBlueConnetctToastTimer();
final int secretKeyJsonLength = (reply.data[4] << 8) + reply.data[3]; final int secretKeyJsonLength = (reply.data[4] << 8) + reply.data[3];
final List<int> secretKeyList = final List<int> secretKeyList =
@ -126,7 +130,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
/// ,peerId /// ,peerId
StartChartManage().lockPeerId = peerId ?? ''; StartChartManage().lockPeerId = peerId ?? '';
dismissEasyLoading();
state.isLoading.value = false; state.isLoading.value = false;
// //
await Storage.saveLockNetWorkInfo(jsonMap); await Storage.saveLockNetWorkInfo(jsonMap);
@ -141,6 +145,10 @@ class ConfiguringWifiLogic extends BaseGetXController {
default: default:
// //
dismissEasyLoading(); dismissEasyLoading();
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
}
cancelBlueConnetctToastTimer(); cancelBlueConnetctToastTimer();
showToast('配网失败'.tr); showToast('配网失败'.tr);
state.isLoading.value = false; state.isLoading.value = false;
@ -156,6 +164,8 @@ class ConfiguringWifiLogic extends BaseGetXController {
// wifi // wifi
Future<void> senderConfiguringWifiAction() async { Future<void> senderConfiguringWifiAction() async {
AppLog.log('开始配网${EasyLoading.isShow}');
EasyLoading.show();
if (state.isLoading.isTrue) { if (state.isLoading.isTrue) {
AppLog.log('正在配网中请勿重复点击'); AppLog.log('正在配网中请勿重复点击');
return; return;
@ -175,7 +185,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
state.sureBtnState.value = 1; state.sureBtnState.value = 1;
final GetGatewayConfigurationEntity entity = final GetGatewayConfigurationEntity entity =
await ApiRepository.to.getGatewayConfiguration(timeout: 60); await ApiRepository.to.getGatewayConfigurationNotLoading(timeout: 60);
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
state.getGatewayConfigurationStr = entity.data ?? ''; state.getGatewayConfigurationStr = entity.data ?? '';
} }
@ -210,6 +220,8 @@ class ConfiguringWifiLogic extends BaseGetXController {
state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}"; state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}";
} }
AppLog.log('获取到配网信息===开始发送蓝牙指令${EasyLoading.isShow}');
BlueManage().blueSendData( BlueManage().blueSendData(
BlueManage().connectDeviceName, BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async { (BluetoothConnectionState connectionState) async {
@ -223,8 +235,12 @@ class ConfiguringWifiLogic extends BaseGetXController {
}, },
isAddEquipment: true, isAddEquipment: true,
); );
// state.loadingTimer ??= Timer.periodic(Duration(milliseconds: 100), (timer) {
showEasyLoading(); if (!EasyLoading.isShow) {
EasyLoading.show();
}
});
state.isLoading.value = true; state.isLoading.value = true;
// 15 // 15
Future.delayed(const Duration(seconds: 15), () { Future.delayed(const Duration(seconds: 15), () {
@ -232,9 +248,14 @@ class ConfiguringWifiLogic extends BaseGetXController {
EasyLoading.dismiss(); EasyLoading.dismiss();
state.isLoading.value = false; state.isLoading.value = false;
state.sureBtnState.value = 0; state.sureBtnState.value = 0;
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
}
showToast('配网失败'.tr); showToast('配网失败'.tr);
} }
}); });
AppLog.log('发送方法执行完毕${EasyLoading.isShow}');
} }
// //
@ -358,9 +379,24 @@ class ConfiguringWifiLogic extends BaseGetXController {
// //
dismissEasyLoading(); dismissEasyLoading();
showToast('配网失败'.tr); showToast('配网失败'.tr);
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
}
break; break;
} }
} }
void _replyStatusInfo(reply) {} void _replyStatusInfo(reply) {}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
state.isLoading.value = false;
if (state.loadingTimer != null) {
state.loadingTimer!.cancel();
state.loadingTimer = null;
}
}
} }

View File

@ -1,4 +1,6 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -30,4 +32,5 @@ class ConfiguringWifiState{
String getGatewayConfigurationStr = ''; String getGatewayConfigurationStr = '';
RxBool isLoading=false.obs; RxBool isLoading=false.obs;
Timer? loadingTimer;
} }

View File

@ -78,10 +78,10 @@ class _WifiListPageState extends State<WifiListPage> {
borderRadius: 20.w, borderRadius: 20.w,
padding: EdgeInsets.only(top: 25.w, bottom: 25.w), padding: EdgeInsets.only(top: 25.w, bottom: 25.w),
onClick: () { onClick: () {
Get.toNamed(Routers.configuringWifiPage, Get.toNamed(Routers.configuringWifiPage, arguments: {
arguments: <String, LockSetInfoData>{ 'lockSetInfoData': state.lockSetInfoData.value,
'lockSetInfoData': state.lockSetInfoData.value 'pageName': state.pageName.value,
}); });
}), }),
SizedBox( SizedBox(
height: 64.h, height: 64.h,

View File

@ -1,11 +1,15 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.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_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/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/versionUndate/versionUndate_entity.dart'; import 'package:star_lock/versionUndate/versionUndate_entity.dart';
@ -14,6 +18,8 @@ import 'editVideoLog_state.dart';
class EditVideoLogLogic extends BaseGetXController { class EditVideoLogLogic extends BaseGetXController {
EditVideoLogState state = EditVideoLogState(); EditVideoLogState state = EditVideoLogState();
final VideoLogLogic videoLogLogic = Get.find<VideoLogLogic>();
Future<void> deleteLockCloudStorageList() async { Future<void> deleteLockCloudStorageList() async {
final VersionUndateEntity entity = final VersionUndateEntity entity =
await ApiRepository.to.deleteLockCloudStorageList( await ApiRepository.to.deleteLockCloudStorageList(
@ -86,6 +92,146 @@ class EditVideoLogLogic extends BaseGetXController {
} }
} }
//
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) {
final hash = md5.convert(utf8.encode(url)).toString(); // 使 md5
return '$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) 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); // 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 { Future<bool> _requestPermission() async {
final status = await Permission.storage.request(); final status = await Permission.storage.request();

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
@ -180,55 +182,70 @@ class _EditVideoLogPageState extends State<EditVideoLogPage> {
Widget bottomBottomBtnWidget() { Widget bottomBottomBtnWidget() {
return SizedBox( return SizedBox(
width: 1.sw, width: 1.sw,
child: child: Row(
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ mainAxisAlignment: MainAxisAlignment.center,
bottomBtnItemWidget( children: <Widget>[
'images/main/icon_lockDetail_monitoringDownloadVideo.png', state.isNavLocal.value == false
'下载'.tr, ? bottomBtnItemWidget(
Colors.white, 'images/main/icon_lockDetail_monitoringDownloadVideo.png',
_onDownLoadClick, '下载'.tr,
), Colors.white,
SizedBox(width: 100.w), _onDownLoadClick,
bottomBtnItemWidget( )
'images/main/icon_lockDetail_monitoringDeletVideo.png', : SizedBox.shrink(),
'删除'.tr, state.isNavLocal.value == false
AppColors.mainColor, ? SizedBox(width: 100.w)
_onDelClick, : SizedBox.shrink(),
) bottomBtnItemWidget(
]), 'images/main/icon_lockDetail_monitoringDeletVideo.png',
'删除'.tr,
AppColors.mainColor,
_onDelClick,
)
],
),
); );
} }
Future<void> _onDownLoadClick() async { Future<void> _onDownLoadClick() async {
if (state.selectVideoLogList.value.isNotEmpty) { if (state.selectVideoLogList.value.isNotEmpty) {
double _progress = 0.0; state.selectVideoLogList.value.forEach((element) {
if (element.videoUrl != null && element.videoUrl != '') {
logic.downloadFile(element.videoUrl ?? '');
} else if (element.imagesUrl != null && element.imagesUrl != '') {
logic.downloadFile(element.imagesUrl ?? '');
}
});
// double _progress = 0.0;
// //
// //
EasyLoading.showProgress(_progress, status: '加载数据中'.tr); // EasyLoading.showProgress(_progress, status: '加载数据中'.tr);
//
// // //
for (int i = 0; i <= state.selectVideoLogList.length - 1; i++) { // for (int i = 0; i <= state.selectVideoLogList.length - 1; i++) {
final item = state.selectVideoLogList.value[i]; // final item = state.selectVideoLogList.value[i];
//
// imagesUrl // // imagesUrl
if (item.imagesUrl != null && item.imagesUrl!.isNotEmpty) { // if (item.imagesUrl != null && item.imagesUrl!.isNotEmpty) {
await logic.downloadAndSaveToGallery(item.imagesUrl!, 'image_$i.jpg'); // await logic.downloadAndSaveToGallery(item.imagesUrl!, 'image_$i.jpg');
} // }
//
// videoUrl // // videoUrl
if (item.videoUrl != null && item.videoUrl!.isNotEmpty) { // if (item.videoUrl != null && item.videoUrl!.isNotEmpty) {
await logic.downloadAndSaveToGallery(item.videoUrl!, 'video_$i.mp4'); // await logic.downloadAndSaveToGallery(item.videoUrl!, 'video_$i.mp4');
} // }
//
// // //
_progress = (i + 1) / state.selectVideoLogList.length; // _progress = (i + 1) / state.selectVideoLogList.length;
EasyLoading.showProgress(_progress, status: '加载数据中'.tr); // EasyLoading.showProgress(_progress, status: '加载数据中'.tr);
} // }
//
// // //
EasyLoading.dismiss(); // EasyLoading.dismiss();
EasyLoading.showSuccess('下载完成,请到相册查看'.tr); // EasyLoading.showSuccess('下载完成,请到相册查看'.tr);
EasyLoading.showSuccess('下载完成'.tr);
state.selectVideoLogList.clear(); state.selectVideoLogList.clear();
Get.back();
setState(() {}); setState(() {});
// Get.toNamed(Routers.videoLogDownLoadPage, // Get.toNamed(Routers.videoLogDownLoadPage,
// arguments: <String, List<RecordListData>>{ // arguments: <String, List<RecordListData>>{
@ -240,11 +257,28 @@ class _EditVideoLogPageState extends State<EditVideoLogPage> {
} }
Future<void> _onDelClick() async { Future<void> _onDelClick() async {
if (state.selectVideoLogList.value.isNotEmpty) { if (state.isNavLocal.isFalse) {
await logic.deleteLockCloudStorageList(); if (state.selectVideoLogList.value.isNotEmpty) {
setState(() {}); await logic.deleteLockCloudStorageList();
setState(() {});
} else {
logic.showToast('请选择要删除的视频'.tr);
}
} else { } else {
logic.showToast('请选择要删除的视频'.tr); if (state.selectVideoLogList.value.isNotEmpty) {
List<String> deletePaths = [];
state.selectVideoLogList.value.forEach((element) {
if (element.imagesUrl != null && element.imagesUrl != '') {
deletePaths.add(element.imagesUrl!);
}
if (element.videoUrl != null && element.videoUrl != '') {
deletePaths.add(element.videoUrl!);
}
});
logic.deleteDownloadsByPaths(deletePaths);
} else {
logic.showToast('请选择要删除的视频'.tr);
}
} }
} }
@ -365,21 +399,56 @@ class _EditVideoLogPageState extends State<EditVideoLogPage> {
_buildImageItem(RecordListData recordData) { _buildImageItem(RecordListData recordData) {
return RotatedBox( return RotatedBox(
quarterTurns: -1, quarterTurns: -1,
child: Image.network( child: _buildImageWidget(recordData.imagesUrl),
recordData.imagesUrl!, );
}
// Image Widget
Widget _buildImageWidget(String? imageUrl) {
if (imageUrl == null || imageUrl.isEmpty) {
//
return Image.asset(
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
);
}
//
if (_isNetworkUrl(imageUrl)) {
return Image.network(
imageUrl,
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder: errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) { (BuildContext context, Object error, StackTrace? stackTrace) {
// //
return RotatedBox( return Image.asset(
quarterTurns: -1, 'images/icon_unHaveData.png', //
child: Image.asset( fit: BoxFit.cover,
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
),
); );
}, },
), );
); } else {
// 使 FileImage
return Image.file(
File(imageUrl),
fit: BoxFit.cover,
errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
//
return Image.asset(
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
);
},
);
}
}
//
bool _isNetworkUrl(String url) {
final uri = Uri.tryParse(url);
return uri != null &&
uri.scheme.isNotEmpty &&
uri.scheme.startsWith('http');
} }
} }

View File

@ -12,9 +12,13 @@ class EditVideoLogState {
if (map['lockId'] != null) { if (map['lockId'] != null) {
getLockId.value = map['lockId']; getLockId.value = map['lockId'];
} }
if (map['isNavLocal'] != null) {
isNavLocal.value = map['isNavLocal'];
}
} }
RxList<RecordListData> selectVideoLogList = <RecordListData>[].obs; // RxList<RecordListData> selectVideoLogList = <RecordListData>[].obs; //
RxBool isSelectAll = false.obs; RxBool isSelectAll = false.obs;
RxList videoLogList = [].obs; // RxList videoLogList = <CloudStorageData>[].obs; //
RxInt getLockId = 0.obs; RxInt getLockId = 0.obs;
var isNavLocal = false.obs;
} }

View File

@ -1,5 +1,8 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:path_provider/path_provider.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
import 'package:star_lock/network/api_repository.dart'; import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/baseGetXController.dart';
@ -28,6 +31,117 @@ class VideoLogLogic extends BaseGetXController {
} }
} }
//
Future<void> listDownloadedVideos() async {
Directory appDocDir = await getApplicationDocumentsDirectory();
Directory downloadsDir = Directory('${appDocDir.path}/downloads');
if (await downloadsDir.exists()) {
List<FileSystemEntity> files = downloadsDir.listSync();
final list =
files.where((file) => file is File).map((file) => file.path).toList();
list.forEach((element) async {
final downloadTime = await getDownloadTime(element);
//
});
}
}
//
Future<List<CloudStorageData>> groupDownloadsByDay() async {
final appDocDir = await getApplicationDocumentsDirectory();
final logFilePath = '${appDocDir.path}/download_log.json';
//
Map<String, List<RecordListData>> groupedDownloads = {};
if (await File(logFilePath).exists()) {
final content = await File(logFilePath).readAsString();
final logData = Map<String, int>.from(json.decode(content));
//
logData.forEach((filePath, timestamp) {
final downloadDateTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
final dateKey =
'${downloadDateTime.year}-${downloadDateTime.month.toString().padLeft(2, '0')}-${downloadDateTime.day.toString().padLeft(2, '0')}';
//
if (!groupedDownloads.containsKey(dateKey)) {
groupedDownloads[dateKey] = [];
}
//
if (filePath.endsWith('.jpg')) {
groupedDownloads[dateKey]?.add(
RecordListData(operateDate: timestamp, imagesUrl: filePath),
);
} else if (filePath.endsWith('.mp4')) {
groupedDownloads[dateKey]?.add(
RecordListData(operateDate: timestamp, videoUrl: filePath),
);
}
});
}
// CloudStorageData
List<CloudStorageData> cloudStorageData = [];
groupedDownloads.forEach((dateKey, recordList) {
cloudStorageData.add(
CloudStorageData(date: dateKey, recordList: recordList),
);
});
state.lockVideoList.value = cloudStorageData;
return cloudStorageData;
}
//
Future<int?> getDownloadTime(String filePath) async {
final appDocDir = await getApplicationDocumentsDirectory();
final logFilePath = '${appDocDir.path}/download_log.json';
if (await File(logFilePath).exists()) {
final content = await File(logFilePath).readAsString();
final logData = Map<String, int>.from(json.decode(content));
return logData[filePath];
}
return null;
}
//
Future<bool> clearDownloads() async {
try {
//
Directory appDocDir = await getApplicationDocumentsDirectory();
//
final downloadsDir = Directory('${appDocDir.path}/downloads');
if (await downloadsDir.exists()) {
await downloadsDir.list().forEach((entity) {
if (entity is File) {
entity.delete(recursive: true);
}
});
print('下载目录已清空');
} else {
print('下载目录不存在');
}
//
final logFilePath = '${appDocDir.path}/download_log.json';
if (await File(logFilePath).exists()) {
await File(logFilePath).delete();
print('日志文件已删除');
} else {
print('日志文件不存在');
}
return true;
} catch (e) {
print('清空失败:$e');
return false;
}
}
@override @override
onReady() { onReady() {
super.onReady(); super.onReady();

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -30,6 +32,7 @@ class _VideoLogPageState extends State<VideoLogPage> {
void initState() { void initState() {
// TODO: implement initState // TODO: implement initState
super.initState(); super.initState();
logic.groupDownloadsByDay();
} }
@override @override
@ -50,53 +53,94 @@ class _VideoLogPageState extends State<VideoLogPage> {
Visibility(visible: state.isNavLocal.value, child: localTip()), Visibility(visible: state.isNavLocal.value, child: localTip()),
// title加编辑按钮 // title加编辑按钮
editVideoTip(), editVideoTip(),
Obx(() => Visibility( Obx(
() => Visibility(
visible: !state.isNavLocal.value, visible: !state.isNavLocal.value,
child: Expanded( child: state.videoLogList.length > 0
child: ListView.builder( ? Expanded(
itemCount: state.videoLogList.length, child: ListView.builder(
itemBuilder: (BuildContext c, int index) { itemCount: state.videoLogList.length,
final CloudStorageData item = state.videoLogList[index]; itemBuilder: (BuildContext c, int index) {
return Column( final CloudStorageData item =
children: <Widget>[ state.videoLogList[index];
Container( return Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(
left: 20.w, top: 15.w, bottom: 15.w),
child: Row(children: <Widget>[
Text(item.date ?? '',
style: TextStyle(fontSize: 20.sp)),
])),
mainListView(index, item)
],
);
},
),
)
: _buildNotData(),
),
),
//
Obx(
() => Visibility(
visible: state.isNavLocal.value,
child: state.lockVideoList.length > 0
? Expanded(
child: ListView.builder(
itemCount: state.lockVideoList.length,
itemBuilder: (BuildContext c, int index) {
final CloudStorageData item =
state.lockVideoList[index];
return Column(
children: <Widget>[
Container(
margin: EdgeInsets.only( margin: EdgeInsets.only(
left: 20.w, top: 15.w, bottom: 15.w), left: 20.w, top: 15.w, bottom: 15.w),
child: Row(children: <Widget>[ child: Row(
Text(item.date ?? '', children: <Widget>[
style: TextStyle(fontSize: 20.sp)), Text(item.date ?? '',
])), style: TextStyle(fontSize: 20.sp)),
mainListView(index, item) ],
], ),
); ),
})))), lockMainListView(index, item)
// ],
Visibility( );
visible: state.isNavLocal.value, },
child: Expanded( ),
child: state.localList.isNotEmpty )
? ListView.builder( : _buildNotData(),
itemCount: 5, ),
itemBuilder: (BuildContext c, int index) { ),
return Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(
left: 20.w, top: 15.w, bottom: 15.w),
child: Row(children: <Widget>[
Text('2023.10.2$index',
style: TextStyle(fontSize: 20.sp)),
])),
mainListView(index, CloudStorageData()),
],
);
})
: NoData())),
], ],
), ),
); );
} }
Widget _buildNotData() {
return Expanded(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
'images/icon_noData.png',
width: 160.w,
height: 180.h,
),
Text(
'暂无数据'.tr,
style: TextStyle(
color: AppColors.darkGrayTextColor, fontSize: 22.sp),
)
],
),
),
);
}
// nav按钮 // nav按钮
Widget navBtn() { Widget navBtn() {
return SizedBox( return SizedBox(
@ -109,6 +153,8 @@ class _VideoLogPageState extends State<VideoLogPage> {
onPressed: () { onPressed: () {
setState(() { setState(() {
state.isNavLocal.value = false; state.isNavLocal.value = false;
state.lockVideoList.clear();
// logic.clearDownloads();
}); });
}, },
child: Obx(() => Text('云存'.tr, child: Obx(() => Text('云存'.tr,
@ -122,21 +168,27 @@ class _VideoLogPageState extends State<VideoLogPage> {
fontSize: 28.sp, fontSize: 28.sp,
fontWeight: FontWeight.w600)))), fontWeight: FontWeight.w600)))),
TextButton( TextButton(
onPressed: () { onPressed: () {
setState(() { setState(() {
state.isNavLocal.value = true; state.isNavLocal.value = true;
}); logic.groupDownloadsByDay();
}, });
child: Obx(() => Text('本地'.tr, },
style: state.isNavLocal.value == true child: Obx(
? TextStyle( () => Text(
color: Colors.white, '已下载'.tr,
fontSize: 28.sp, style: state.isNavLocal.value == true
fontWeight: FontWeight.w600) ? TextStyle(
: TextStyle( color: Colors.white,
color: Colors.grey, fontSize: 28.sp,
fontSize: 26.sp, fontWeight: FontWeight.w600)
fontWeight: FontWeight.w600)))), : TextStyle(
color: Colors.grey,
fontSize: 26.sp,
fontWeight: FontWeight.w600),
),
),
),
], ],
), ),
); );
@ -243,10 +295,21 @@ class _VideoLogPageState extends State<VideoLogPage> {
iconSize: 30, iconSize: 30,
color: Colors.black54, color: Colors.black54,
onPressed: () { onPressed: () {
Get.toNamed(Routers.editVideoLogPage, arguments: <String, Object>{ if (state.isNavLocal.value) {
'videoDataList': state.videoLogList.value, Get.toNamed(Routers.editVideoLogPage,
'lockId': state.getLockId.value arguments: <String, Object>{
}); 'videoDataList': state.lockVideoList.value,
'lockId': state.getLockId.value,
'isNavLocal': state.isNavLocal.value
});
} else {
Get.toNamed(Routers.editVideoLogPage,
arguments: <String, Object>{
'videoDataList': state.videoLogList.value,
'lockId': state.getLockId.value,
'isNavLocal': state.isNavLocal.value
});
}
}, },
) )
// TextButton( // TextButton(
@ -286,6 +349,28 @@ class _VideoLogPageState extends State<VideoLogPage> {
); );
} }
Widget lockMainListView(int index, CloudStorageData itemData) {
return GridView.builder(
padding: EdgeInsets.only(left: 15.w, right: 15.w),
itemCount: itemData.recordList!.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//
crossAxisCount: 3,
//
mainAxisSpacing: 15.w,
//
crossAxisSpacing: 15.w,
//
childAspectRatio: itemW / itemH),
itemBuilder: (BuildContext context, int index) {
final RecordListData recordData = itemData.recordList![index];
return videoItem(recordData);
},
);
}
Widget videoItem(RecordListData recordData) { Widget videoItem(RecordListData recordData) {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
@ -323,9 +408,10 @@ class _VideoLogPageState extends State<VideoLogPage> {
), ),
SizedBox(height: 5.h), SizedBox(height: 5.h),
Text( Text(
DateTool().dateToYMDHNString(recordData.operateDate.toString()), DateTool().dateToYMDHNString(recordData.operateDate.toString()),
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.sp)) style: TextStyle(fontSize: 18.sp),
)
], ],
), ),
), ),
@ -347,21 +433,56 @@ class _VideoLogPageState extends State<VideoLogPage> {
_buildImageItem(RecordListData recordData) { _buildImageItem(RecordListData recordData) {
return RotatedBox( return RotatedBox(
quarterTurns: -1, quarterTurns: -1,
child: Image.network( child: _buildImageWidget(recordData.imagesUrl),
recordData.imagesUrl!, );
}
// Image Widget
Widget _buildImageWidget(String? imageUrl) {
if (imageUrl == null || imageUrl.isEmpty) {
//
return Image.asset(
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
);
}
//
if (_isNetworkUrl(imageUrl)) {
return Image.network(
imageUrl,
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder: errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) { (BuildContext context, Object error, StackTrace? stackTrace) {
// //
return RotatedBox( return Image.asset(
quarterTurns: -1, 'images/icon_unHaveData.png', //
child: Image.asset( fit: BoxFit.cover,
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
),
); );
}, },
), );
); } else {
// 使 FileImage
return Image.file(
File(imageUrl),
fit: BoxFit.cover,
errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
//
return Image.asset(
'images/icon_unHaveData.png', //
fit: BoxFit.cover,
);
},
);
}
}
//
bool _isNetworkUrl(String url) {
final uri = Uri.tryParse(url);
return uri != null &&
uri.scheme.isNotEmpty &&
uri.scheme.startsWith('http');
} }
} }

View File

@ -8,6 +8,7 @@ class VideoLogState {
var localList = []; var localList = [];
var getLockId = 0.obs; var getLockId = 0.obs;
var videoLogList = <CloudStorageData>[].obs; var videoLogList = <CloudStorageData>[].obs;
var lockVideoList = <CloudStorageData>[].obs;
var videoCoverList = <Uint8List>[].obs; var videoCoverList = <Uint8List>[].obs;
VideoLogState() { VideoLogState() {

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart'; import 'package:photo_view/photo_view_gallery.dart';
@ -11,18 +13,42 @@ class FullScreenImagePage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: GestureDetector( body: GestureDetector(
onTap: (){ onTap: () {
Navigator.pop(context); // Navigator.pop(context); //
}, },
child: Container( child: Container(
child: RotatedBox( child: RotatedBox(
quarterTurns: -1, quarterTurns: -1,
child: PhotoView( child: PhotoView(
imageProvider: NetworkImage(imageUrl), imageProvider:
_getImageProvider(imageUrl), // imageUrl
), ),
), ),
), ),
), ),
); );
} }
// imageUrl ImageProvider
ImageProvider<Object> _getImageProvider(String? imageUrl) {
if (imageUrl == null || imageUrl.isEmpty) {
//
return AssetImage('images/icon_unHaveData.png'); //
}
//
if (_isNetworkUrl(imageUrl)) {
return NetworkImage(imageUrl); //
} else {
return FileImage(File(imageUrl)); //
}
}
//
bool _isNetworkUrl(String url) {
final uri = Uri.tryParse(url);
return uri != null &&
uri.scheme.isNotEmpty &&
uri.scheme.startsWith('http');
}
} }

View File

@ -491,25 +491,12 @@ class SaveLockLogic extends BaseGetXController {
// //
final LockSetInfoEntity entity = final LockSetInfoEntity entity =
await ApiRepository.to.getLockSettingInfoDataIsNotLoadingIcon( await ApiRepository.to.getLockSettingInfoData(
lockId: state.lockId.toString(), lockId: state.lockId.toString(),
); );
if (entity.errorCode!.codeIsSuccessful) { if (entity.errorCode!.codeIsSuccessful) {
state.lockSetInfoData.value = entity.data!; state.lockSetInfoData.value = entity.data!;
if (state.lockSetInfoData.value.lockFeature?.wifi == 1) { if (state.lockSetInfoData.value.lockFeature?.wifi == 1) {
// await Future<void>.delayed(const Duration(seconds: 1), () {c
// Get.close(state.isFromMap == 1
// ? (CommonDataManage().seletLockType == 0 ? 4 : 5)
// : (CommonDataManage().seletLockType == 0 ? 5 : 6));
// });
// // 2
// await Future<void>.delayed(const Duration(milliseconds: 200), () {
// if (Get.isRegistered<LockDetailLogic>()) {
// Get.find<LockDetailLogic>()
// .functionBlocker
// .countdownProhibited(duration: const Duration(seconds: 2));
// }
// });
// wifi锁WIFI // wifi锁WIFI
Get.toNamed(Routers.wifiListPage, arguments: { Get.toNamed(Routers.wifiListPage, arguments: {
'lockSetInfoData': state.lockSetInfoData.value, 'lockSetInfoData': state.lockSetInfoData.value,

View File

@ -1811,6 +1811,9 @@ class ApiProvider extends BaseProvider {
Future<Response> getGatewayConfiguration(int timeout) => Future<Response> getGatewayConfiguration(int timeout) =>
post(getGatewayConfigURL.toUrl, jsonEncode({}), timeout: timeout); post(getGatewayConfigURL.toUrl, jsonEncode({}), timeout: timeout);
Future<Response> getGatewayConfigurationNotLoading(int timeout) =>
post(getGatewayConfigURL.toUrl, jsonEncode({}), timeout: timeout,isUnShowLoading: true);
Future<Response> gatewayConnectionLockListLoadData( Future<Response> gatewayConnectionLockListLoadData(
int gatewayId, int timeout) => int gatewayId, int timeout) =>
post(gatewayListByLockURL.toUrl, jsonEncode({'gatewayId': gatewayId}), post(gatewayListByLockURL.toUrl, jsonEncode({'gatewayId': gatewayId}),

View File

@ -2010,6 +2010,14 @@ class ApiRepository {
return GetGatewayConfigurationEntity.fromJson(res.body); return GetGatewayConfigurationEntity.fromJson(res.body);
} }
//
Future<GetGatewayConfigurationEntity> getGatewayConfigurationNotLoading(
{required int timeout}) async {
final res = await apiProvider.getGatewayConfigurationNotLoading(timeout);
return GetGatewayConfigurationEntity.fromJson(res.body);
}
// //
Future<RecipientInformationEntity> removeBrokenLockData( Future<RecipientInformationEntity> removeBrokenLockData(
{required List lockIdList}) async { {required List lockIdList}) async {

View File

@ -186,7 +186,7 @@ dependencies:
lpinyin: ^2.0.3 lpinyin: ^2.0.3
#加密解密 #加密解密
# encrypt: ^5.0.1 # encrypt: ^5.0.1
# crypto: ^3.0.3 crypto: ^3.0.3
pointycastle: ^3.7.3 # 使用最新版本 pointycastle: ^3.7.3 # 使用最新版本
date_format: ^2.0.7 date_format: ^2.0.7