diff --git a/lib/main/lockDetail/doorLockLog/doorLockLog_page.dart b/lib/main/lockDetail/doorLockLog/doorLockLog_page.dart index 05bbf80d..3a5bcdd8 100755 --- a/lib/main/lockDetail/doorLockLog/doorLockLog_page.dart +++ b/lib/main/lockDetail/doorLockLog/doorLockLog_page.dart @@ -118,7 +118,10 @@ class _DoorLockLogPageState extends State with RouteAware { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text(value, style: TextStyle(color: Colors.white, fontSize: 22.sp)), + Text( + value, + style: TextStyle(color: Colors.white, fontSize: 22.sp), + ), ], ), ), @@ -241,13 +244,16 @@ class _DoorLockLogPageState extends State with RouteAware { child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - Obx(() => XSDropDownWidget( + Obx( + () => XSDropDownWidget( items: state.getDropDownItemList, value: state.dropdownTitle.value, - valueChanged: (value) { + valueChanged: (value) async { state.dropdownValue.value = int.parse(value); - logic.mockNetworkDataRequest(isRefresh: true); - })), + await logic.mockNetworkDataRequest(isRefresh: true); + }, + ), + ), ], ), ); @@ -261,24 +267,26 @@ class _DoorLockLogPageState extends State with RouteAware { color: Colors.white, borderRadius: BorderRadius.circular(16.w), ), - child: Obx(() => state.lockLogItemList.isNotEmpty - ? Timeline.tileBuilder( - builder: _timelineBuilderWidget(), - theme: TimelineThemeData( - nodePosition: 0.04, //居左侧距离 - connectorTheme: const ConnectorThemeData( - thickness: 1.0, - color: AppColors.greyLineColor, - indent: 0.5, + child: Obx( + () => state.lockLogItemList.isNotEmpty + ? Timeline.tileBuilder( + builder: _timelineBuilderWidget(), + theme: TimelineThemeData( + nodePosition: 0.04, //居左侧距离 + connectorTheme: const ConnectorThemeData( + thickness: 1.0, + color: AppColors.greyLineColor, + indent: 0.5, + ), + indicatorTheme: const IndicatorThemeData( + size: 8.0, + color: AppColors.greyLineColor, + position: 0.45, + ), ), - indicatorTheme: const IndicatorThemeData( - size: 8.0, - color: AppColors.greyLineColor, - position: 0.4, - ), - ), - ) - : NoData()), + ) + : NoData(), + ), ); } @@ -288,15 +296,12 @@ class _DoorLockLogPageState extends State with RouteAware { itemCount: state.lockLogItemList.length, contentsBuilder: (BuildContext context, int index) { final DoorLockLogDataItem timelineData = state.lockLogItemList[index]; - final DateTime dateTime = - DateTime.fromMillisecondsSinceEpoch(timelineData.operateDate!); - final String formattedTime = - '${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}'; - return GestureDetector( onTap: () { - Get.toNamed(Routers.doorLockLogDetailPage, - arguments: {'doorLockLogDataItem': timelineData}); + Get.toNamed( + Routers.doorLockLogDetailPage, + arguments: {'doorLockLogDataItem': timelineData}, + ); }, child: Padding( padding: EdgeInsets.only(left: 20.w, top: 20.h), @@ -305,7 +310,6 @@ class _DoorLockLogPageState extends State with RouteAware { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - // '$formattedTime ${timelineData.username!.isNotEmpty ? "${timelineData.username}操作" : ""}${timelineData.recordTypeName}', timelineData.recordStr ?? '', textAlign: TextAlign.left, style: TextStyle( @@ -315,15 +319,17 @@ class _DoorLockLogPageState extends State with RouteAware { ), ), SizedBox( - height: 10.h, + height: 12.h, + ), + videoItem( + RecordListData( + recordId: state.lockLogItemList.value[index].recordId, + recordType: state.lockLogItemList.value[index].recordType, + operateDate: state.lockLogItemList.value[index].operateDate, + imagesUrl: state.lockLogItemList.value[index].imagesUrl, + videoUrl: state.lockLogItemList.value[index].videoUrl, + ), ), - videoItem(RecordListData( - recordId: state.lockLogItemList.value[index].recordId, - recordType: state.lockLogItemList.value[index].recordType, - operateDate: state.lockLogItemList.value[index].operateDate, - imagesUrl: state.lockLogItemList.value[index].imagesUrl, - videoUrl: state.lockLogItemList.value[index].videoUrl, - )), SizedBox( height: 20.h, ), @@ -341,13 +347,15 @@ class _DoorLockLogPageState extends State with RouteAware { if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) { final lockLogItemList = state.lockLogItemList.value; final list = lockLogItemList - .map((e) => RecordListData( - videoUrl: e.videoUrl, - imagesUrl: e.imagesUrl, - operateDate: e.operateDate, - recordId: e.recordId, - recordType: e.recordType, - )) + .map( + (e) => RecordListData( + videoUrl: e.videoUrl, + imagesUrl: e.imagesUrl, + operateDate: e.operateDate, + recordId: e.recordId, + recordType: e.recordType, + ), + ) .toList(); final selectDateString = DateTool().dateToYMDString(state.startDate.value.toString()); @@ -369,12 +377,9 @@ class _DoorLockLogPageState extends State with RouteAware { ); } }, - child: SizedBox( - width: 260.w, - height: 260.h, - child: Column( - children: [ - Container( + child: ((recordData.imagesUrl != null && recordData.imagesUrl != '') || + (recordData.videoUrl != null && recordData.videoUrl != '')) + ? Container( width: 260.w, height: 260.h, margin: const EdgeInsets.all(0), @@ -383,18 +388,19 @@ class _DoorLockLogPageState extends State with RouteAware { borderRadius: BorderRadius.circular(10.w), child: _buildImageOrVideoItem(recordData), ), - ), - ], - ), - ), + ) + : SizedBox.shrink(), ); } _buildImageOrVideoItem(RecordListData recordData) { if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) { return _buildVideoItem(recordData); - } else { + } else if (recordData.imagesUrl != null && + recordData.imagesUrl!.isNotEmpty) { return _buildImageItem(recordData); + } else { + return SizedBox.shrink(); } } @@ -411,12 +417,9 @@ class _DoorLockLogPageState extends State with RouteAware { errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) { // 图片加载失败时显示错误图片 - return RotatedBox( - quarterTurns: -1, - child: Image.asset( - 'images/icon_unHaveData.png', // 错误图片路径 - fit: BoxFit.cover, - ), + return Image.asset( + 'images/icon_unHaveData.png', // 错误图片路径 + fit: BoxFit.cover, ); }, ), diff --git a/lib/main/lockDetail/doorLockLog/exportRecordDialog/exportRecordDialog_page.dart b/lib/main/lockDetail/doorLockLog/exportRecordDialog/exportRecordDialog_page.dart index 0126280b..4d88ff05 100644 --- a/lib/main/lockDetail/doorLockLog/exportRecordDialog/exportRecordDialog_page.dart +++ b/lib/main/lockDetail/doorLockLog/exportRecordDialog/exportRecordDialog_page.dart @@ -1,4 +1,3 @@ - import 'dart:io'; import 'package:flutter/material.dart'; @@ -225,8 +224,13 @@ class __DerivedRecordWidgetState extends State<_DerivedRecordWidget> { Future downloadAndSaveFile(String url) async { final http.Response response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { + // 格式化日期为 yyyyMMdd 格式 + final String formattedDate = + DateFormat('yyyyMMdd').format(DateTime.now()); + final Directory directory = await getApplicationDocumentsDirectory(); - final File file = File('${directory.path}/record.xlsx'); + final File file = + File('${directory.path}/openLockRecord_${formattedDate}.xlsx'); await file.writeAsBytes(response.bodyBytes); return file.path; } else { diff --git a/lib/talk/startChart/handle/impl/udp_talk_hangup_handler.dart b/lib/talk/startChart/handle/impl/udp_talk_hangup_handler.dart index 26e7d368..a0da47d7 100644 --- a/lib/talk/startChart/handle/impl/udp_talk_hangup_handler.dart +++ b/lib/talk/startChart/handle/impl/udp_talk_hangup_handler.dart @@ -34,7 +34,7 @@ class UdpTalkHangUpHandler extends ScpMessageBaseHandle talkePingOverTimeTimerManager.cancel(); talkDataOverTimeTimerManager.cancel(); - EasyLoading.showToast('已挂断'.tr); + // EasyLoading.showToast('已挂断'.tr); Get.back(); } diff --git a/lib/talk/startChart/handle/other/talke_ping_over_time_timer_manager.dart b/lib/talk/startChart/handle/other/talke_ping_over_time_timer_manager.dart index 4da40500..f8689d9e 100644 --- a/lib/talk/startChart/handle/other/talke_ping_over_time_timer_manager.dart +++ b/lib/talk/startChart/handle/other/talke_ping_over_time_timer_manager.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; +import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/talk/startChart/constant/talk_constant.dart'; import 'package:star_lock/talk/startChart/constant/talk_status.dart'; import 'package:star_lock/talk/startChart/start_chart_manage.dart'; @@ -27,7 +28,9 @@ class TalkePingOverTimeTimerManager { // 超时处理函数 static void _handleTalkePingOverTime() { - if (talkStatus.status == TalkStatus.answeredSuccessfully) { + // 如果是接听中或者是主动呼叫等待接听状态 + if (talkStatus.status == TalkStatus.answeredSuccessfully || + talkStatus.status == TalkStatus.proactivelyCallWaitingAnswer) { EasyLoading.showToast('通话异常中断'.tr, duration: 2000.milliseconds); // 停止发送通话保持的命令 StartChartManage().stopTalkPingMessageTimer(); @@ -42,6 +45,7 @@ class TalkePingOverTimeTimerManager { // 启动定时器 void start() { + AppLog.log('启动talkping判断'); // 取消之前的定时器 _timer?.cancel(); _timer = Timer(timeout, onTimeout); diff --git a/lib/talk/startChart/handle/scp_message_base_handle.dart b/lib/talk/startChart/handle/scp_message_base_handle.dart index 281c2738..dc3d0514 100644 --- a/lib/talk/startChart/handle/scp_message_base_handle.dart +++ b/lib/talk/startChart/handle/scp_message_base_handle.dart @@ -57,6 +57,7 @@ class ScpMessageBaseHandle { ToPeerId: scpMessage.FromPeerId!, FromPeerId: scpMessage.ToPeerId!, PayloadType: scpMessage.PayloadType!, + messageId: scpMessage.MessageId!, ); } diff --git a/lib/talk/startChart/start_chart_manage.dart b/lib/talk/startChart/start_chart_manage.dart index 2a93b0d8..464f4f5c 100644 --- a/lib/talk/startChart/start_chart_manage.dart +++ b/lib/talk/startChart/start_chart_manage.dart @@ -422,6 +422,9 @@ class StartChartManage { }, ); talkStatus.setProactivelyCallWaitingAnswer(); + startTalkPingMessageTimer(); + // 启动是否收到ping超时判断定时器 + talkePingOverTimeTimerManager.start(); } /// 停止持续发送对讲请求 @@ -598,15 +601,20 @@ class StartChartManage { } // 回复成功消息 - void sendGenericRespSuccessMessage( - {required String ToPeerId, - required String FromPeerId, - required int PayloadType}) async { + void sendGenericRespSuccessMessage({ + required String ToPeerId, + required String FromPeerId, + required int PayloadType, + required int messageId, + }) async { + if (messageId == null) { + messageId = MessageCommand.getNextMessageId(ToPeerId, increment: false); + } final message = MessageCommand.genericRespSuccessMessage( ToPeerId: ToPeerId, FromPeerId: FromPeerId, PayloadType: PayloadType, - MessageId: MessageCommand.getNextMessageId(ToPeerId, increment: false), + MessageId: messageId, ); await _sendMessage(message: message); } diff --git a/lib/tools/menuItem/xsDropDownWidget.dart b/lib/tools/menuItem/xsDropDownWidget.dart index 554473d4..50c8135a 100755 --- a/lib/tools/menuItem/xsDropDownWidget.dart +++ b/lib/tools/menuItem/xsDropDownWidget.dart @@ -122,15 +122,15 @@ class _XSDropDownWidgetState extends State { child: Container( margin: EdgeInsets.only(left: 0.w, right: 0, top: 0, bottom: 0), - color: item.itemValue == currentValue - ? AppColors.mainColor - : null, // 设置选中项背景色为蓝色 + // color: item.itemValue == currentValue + // ? AppColors.mainColor + // : null, // 设置选中项背景色为蓝色 child: Text( item.itemTitle, style: TextStyle( fontSize: 24.sp, color: item.itemValue == currentValue - ? Colors.white + ? AppColors.mainColor : Colors.black, // 设置选中项文字颜色为白色 ), ), diff --git a/pubspec.lock b/pubspec.lock index da22a6a3..58763db6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1148,6 +1148,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.6" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" network_info_plus: dependency: "direct main" description: @@ -1388,6 +1396,14 @@ packages: url: "https://pub.dev" source: hosted version: "21.1.2" + provider: + dependency: "direct main" + description: + name: provider + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c + url: "https://pub.dev" + source: hosted + version: "6.1.2" pub_semver: dependency: transitive description: