From bc74511fd5a809fe85eee14cd400d256437e99b7 Mon Sep 17 00:00:00 2001 From: sky_min Date: Tue, 2 Dec 2025 13:44:20 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lockDetail/lockDetail_logic.dart | 341 +++--------------- .../status/appLifecycle_observer.dart | 8 +- .../native/talk_view_native_decode_logic.dart | 25 +- 3 files changed, 66 insertions(+), 308 deletions(-) diff --git a/lib/main/lockDetail/lockDetail/lockDetail_logic.dart b/lib/main/lockDetail/lockDetail/lockDetail_logic.dart index cb5c3072..64874848 100755 --- a/lib/main/lockDetail/lockDetail/lockDetail_logic.dart +++ b/lib/main/lockDetail/lockDetail/lockDetail_logic.dart @@ -397,32 +397,19 @@ class LockDetailLogic extends BaseGetXController { indexMap['type'] = indexList[0].toString(); final int userNo = (indexList[1] * 256) + indexList[2]; - indexMap['user'] = userNo.toString(); - // AppLog.log('userNouserNouserNouserNo:$userNo'); - if (userNo == 0xFFFF) { - // 离线密码情况:16进制格式,去除结束符F(0x1F)及其之后的内容 - final List passwordData = indexList.sublist(7, 17); // 取10个字节 - // 找到结束符F(0x1F)的位置 - int endIndex = passwordData.indexOf(0x1F); - if (endIndex == -1) { - // 如果没有结束符,取全部数据 - endIndex = passwordData.length; - } - // 只取结束符前的部分(不包括结束符) - final List actualPasswordData = passwordData.sublist(0, endIndex); - // 转换为十六进制字符串 - String passwordHex = actualPasswordData.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(); - // 过滤掉字母部分 - passwordHex = passwordHex.replaceAll(RegExp(r'[^0-9]'), ''); - - indexMap['password'] = passwordHex; - // indexMap['password'] = passwordHex; // 存储十六进制字符串表示 - AppLog.log('离线密码开锁:$passwordHex'); + final List passwordData = indexList.sublist(7, 17); + final String password; + if(userNo == 65535){ + //离线密码 + password = passwordData + .map((byte) => byte.toRadixString(16).padLeft(2, '0')) + .join('') + .replaceAll(RegExp(r'f*$'), ''); } else { - final List passwordData = indexList.sublist(7, 17); - final String password = utf8String(passwordData); - indexMap['password'] = password.toString(); + indexMap['user'] = userNo.toString(); + password = utf8String(passwordData); } + indexMap['password'] = password.toString(); // AppLog.log('passwordpasswordpassword:$password'); @@ -481,42 +468,7 @@ class LockDetailLogic extends BaseGetXController { final List? token = await Storage.getStringList(saveBlueToken); final List getTokenList = changeStringListToIntList(token!); - final String command = OpenLockCommand( - lockID: BlueManage().connectDeviceName, - userID: await Storage.getUid(), - openMode: state.openDoorModel, - openTime: getUTCNetTime(), - onlineToken: state.lockNetToken, - token: getTokenList, - needAuthor: 1, - signKey: signKeyDataList, - privateKey: getPrivateKeyList, - ).toString(); - AppLog.log('command:${command}'); - - showBlueConnetctToastTimer( - outTimer: 20, - action: () async { - final String getMobile = (await Storage.getMobile())!; - ApmHelper.instance.trackEvent('open_lock', { - 'lock_name': state.keyInfos.value.lockName!, - 'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date': DateTool().getNowDateWithType(1), - 'open_lock_result': '超时', - }); - - resetOpenDoorState(); - blueManageDisconnect(); - BuglyTool.uploadException( - message: '开门超时处理-开锁失败', detail: '开门超时,断开连接,开锁失败--OpenLockCommand:$command', upload: true); - }, - ); - - BlueManage().blueSendData(state.keyInfos.value.bluetooth!.bluetoothDeviceName!, - (BluetoothConnectionState deviceConnectionState) async { - if (deviceConnectionState == BluetoothConnectionState.connected) { - BuglyTool.uploadException(message: '蓝牙连接成功', detail: '蓝牙连接成功,发送开锁指令--OpenLockCommand:$command', upload: false); - // FlutterBuglyPlugin.reportException(exceptionName: '蓝牙连接成功', reason: '蓝牙连接成功,发送开锁指令'); + BlueManage().blueSendData(state.keyInfos.value.bluetooth!.bluetoothDeviceName!, (BluetoothConnectionState deviceConnectionState) async { IoSenderManage.senderOpenLock( lockID: BlueManage().connectDeviceName, userID: await Storage.getUid(), @@ -528,23 +480,6 @@ class LockDetailLogic extends BaseGetXController { signKey: signKeyDataList, privateKey: getPrivateKeyList, ); - } else if (deviceConnectionState == BluetoothConnectionState.disconnected) { - cancelBlueConnetctToastTimer(); - BuglyTool.uploadException( - message: '蓝牙连接失败-开锁失败', detail: '蓝牙连接失败,断开连接, 开锁失败--OpenLockCommand:$command', upload: true); - final String getMobile = (await Storage.getMobile())!; - ApmHelper.instance.trackEvent('open_lock', { - 'lock_name': state.keyInfos.value.lockName!, - 'account': getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!, - 'date': DateTool().getNowDateWithType(1), - 'open_lock_result': '断开连接', - }); - - // if (state.ifCurrentScreen.value == true) { - // showBlueConnetctToast(); - // } - resetOpenDoorState(); - } }); } @@ -689,224 +624,62 @@ class LockDetailLogic extends BaseGetXController { // 远程开锁 Future remoteOpenLock() async { - final LockListInfoItemEntity currentKeyInfo = CommonDataManage().currentKeyInfo; - - var lockId = currentKeyInfo.lockId ?? 0; - var remoteUnlock = currentKeyInfo.lockSetting?.remoteUnlock ?? 0; - - final lockPeerId = StartChartManage().lockPeerId; - final LockListInfoGroupEntity? lockListInfoGroupEntity = await Storage.getLockMainListData(); - - //检查蓝牙连接状态 - final connectedDevices = await FlutterBluePlus.connectedDevices; - final isDeviceConnected = connectedDevices.any((device) => - device.remoteId.str == BlueManage().connectDeviceName); - - if (!isDeviceConnected) { - AppLog.log('蓝牙已断开,尝试重新连接'); - // 蓝牙断开,需要重新连接并获取新的token - await _reconnectAndRefreshToken(); + final catEyeConfig = state.keyInfos.value.lockSetting?.catEyeConfig ?? []; + // 支持猫眼功能时,才需要判断是否是省电模式 + if (state.keyInfos.value.lockFeature?.isSupportCatEye == 1 && catEyeConfig[0].catEyeMode == 0) { + showToast('猫眼设置为省电模式时无法进行远程开锁,请在猫眼设置中切换为其他模式'.tr); + return; } - - if (lockListInfoGroupEntity != null) { - lockListInfoGroupEntity!.groupList?.forEach((element) { - final lockList = element.lockList; - if (lockList != null && lockList.length != 0) { - for (var lockInfo in lockList) { - final peerId = lockInfo.network?.peerId; - if (peerId != null && peerId != '') { - if (peerId == lockPeerId) { - lockId = lockInfo.lockId ?? 0; - remoteUnlock = lockInfo.lockSetting?.remoteUnlock ?? 0; - } - } - } - } - }); - } - - if (remoteUnlock == 1) { - // 发送蓝牙透传开锁 - await _sendUnlockViaBluetooth(); - // 发送远程开锁api - final LoginEntity entity = await ApiRepository.to.remoteOpenLock(lockId: lockId.toString(), timeOut: 60); + if(state.keyInfos.value.network?.peerId != null){ + // wifi锁 + final LoginEntity entity = await ApiRepository.to.remoteOpenLock( + lockId: state.keyInfos.value.lockId.toString(), + timeOut: 60, + ); if (entity.errorCode!.codeIsSuccessful) { showToast('已开锁'.tr); - StartChartManage().lockListPeerId = []; } - } - } - // 新增方法:通过蓝牙透传发送开锁命令 - Future _sendUnlockViaBluetooth() async { - try { - // 获取必要的密钥信息 - final List? privateKey = await Storage.getStringList(saveBluePrivateKey); - final List privateKeyList = changeStringListToIntList(privateKey!); + } else { + // 网关锁 + // 使用存储的新token进行远程开锁 + final List? privateKey = await Storage.getStringList( + saveBluePrivateKey); + final List getPrivateKeyList = changeStringListToIntList( + privateKey!); - final List? signKey = await Storage.getStringList(saveBlueSignKey); - final List signKeyList = changeStringListToIntList(signKey!); + final List? signKey = await Storage.getStringList( + saveBlueSignKey); + final List signKeyDataList = changeStringListToIntList(signKey!); - final List? token = await Storage.getStringList(saveBlueToken); - final List tokenList = changeStringListToIntList(token!); + final List? storedToken = await Storage.getStringList( + saveBlueToken); + final List tokenToUse = storedToken != null + ? changeStringListToIntList(storedToken) + : [0, 0, 0, 0]; - // 构建开锁命令 - final OpenLockCommand openLockCommand = OpenLockCommand( - lockID: BlueManage().connectDeviceName, - userID: await Storage.getUid(), - openMode: state.openDoorModel, - openTime: getUTCNetTime(), - onlineToken: state.lockNetToken, - token: tokenList, - needAuthor: 1, - signKey: signKeyList, - privateKey: privateKeyList, - ); - // 包装命令数据 - final List messageDetail = openLockCommand.packageData(); + final OpenLockCommand openLockCommand = OpenLockCommand( + lockID: BlueManage().connectDeviceName, + userID: await Storage.getUid(), + openMode: state.openDoorModel, + openTime: getUTCNetTime(), + onlineToken: state.lockNetToken, + token: tokenToUse, + // 使用新获取的token + needAuthor: 1, + signKey: signKeyDataList, + privateKey: getPrivateKeyList, + ); - // 通过蓝牙透传发送开锁命令 - StartChartManage().sendRemoteUnLockMessage( - bluetoothDeviceName: BlueManage().connectDeviceName, - openLockCommand: messageDetail, - ); + final messageDetail = openLockCommand.packageData(); - AppLog.log('通过蓝牙透传发送远程开锁命令'); - - // 监听开锁结果,处理token不一致的情况 - _listenForOpenLockReply(tokenList); - } catch (e) { - AppLog.log('蓝牙透传开锁异常: $e'); - showToast('蓝牙透传开锁失败'.tr); - } - } - - // 监听开锁回复,处理token验证 - void _listenForOpenLockReply(List originalToken) { - StreamSubscription? subscription; - // 设置监听器处理开锁回复 - subscription = EventBusManager().eventBus!.on().listen((Reply reply) async { - if (reply is OpenDoorReply) { - final int status = reply.data[6]; - - // 如果是token不一致的情况(状态码0x06) - if (status == 0x06) { - AppLog.log('token不一致,使用新token重新开锁'); - - // 提取新的token - final List newToken = reply.data.sublist(2, 6); - - // 保存新token到存储 - final List saveStrList = changeIntListToStringList(newToken); - Storage.setStringList(saveBlueToken, saveStrList); - - // 使用新token重新发送开锁命令 - await _reSendUnlockWithNewToken(newToken); - } - - // 取消监听 - subscription?.cancel(); - } - }); - - // 设置超时机制,避免监听器一直存在 - Timer(const Duration(seconds: 10), () { - subscription?.cancel(); - }); - } - - // 使用新token重新发送开锁命令 - Future _reSendUnlockWithNewToken(List newToken) async { - try { - // 获取必要的密钥信息 - final List? privateKey = await Storage.getStringList(saveBluePrivateKey); - final List privateKeyList = changeStringListToIntList(privateKey!); - - final List? signKey = await Storage.getStringList(saveBlueSignKey); - final List signKeyList = changeStringListToIntList(signKey!); - - // 构建新的开锁命令 - final OpenLockCommand openLockCommand = OpenLockCommand( - lockID: BlueManage().connectDeviceName, - userID: await Storage.getUid(), - openMode: state.openDoorModel, - openTime: getUTCNetTime(), - onlineToken: state.lockNetToken, - token: newToken, - needAuthor: 1, - signKey: signKeyList, - privateKey: privateKeyList, - ); - - // 包装命令数据 - final List messageDetail = openLockCommand.packageData(); - - // 通过蓝牙透传发送开锁命令 - StartChartManage().sendRemoteUnLockMessage( - bluetoothDeviceName: BlueManage().connectDeviceName, - openLockCommand: messageDetail, - ); - - AppLog.log('使用新token重新发送开锁命令'); - } catch (e) { - AppLog.log('使用新token重新开锁异常: $e'); - showToast('重新开锁失败'.tr); - } - } - - // 新增方法:重新连接蓝牙并刷新token - Future _reconnectAndRefreshToken() async { - try { - // 重新连接蓝牙 - await BlueManage().blueSendData( - state.keyInfos.value.bluetooth!.bluetoothDeviceName!, - (BluetoothConnectionState deviceConnectionState) async { - if (deviceConnectionState == BluetoothConnectionState.connected) { - AppLog.log('蓝牙重新连接成功'); - // 获取新的token - await _refreshLockToken(); - } else if (deviceConnectionState == BluetoothConnectionState.disconnected) { - AppLog.log('蓝牙重新连接失败'); - showToast('蓝牙连接失败,请重试'.tr); - } - }, - ); - } catch (e) { - AppLog.log('蓝牙重连异常: $e'); - showToast('蓝牙连接异常,请重试'.tr); - } - } - - // 新增方法:刷新锁token - Future _refreshLockToken() async { - try { - final List? token = await Storage.getStringList(saveBlueToken); - final List tokenList = changeStringListToIntList(token!); - - final List? privateKey = await Storage.getStringList(saveBluePrivateKey); - final List privateKeyList = changeStringListToIntList(privateKey!); - - final List? signKey = await Storage.getStringList(saveBlueSignKey); - final List signKeyList = changeStringListToIntList(signKey!); - - // 发送获取新token的命令 - IoSenderManage.senderOpenLock( - lockID: BlueManage().connectDeviceName, - userID: await Storage.getUid(), - openMode: state.openDoorModel, - openTime: getUTCNetTime(), - onlineToken: state.lockNetToken, - token: tokenList, - needAuthor: 1, - signKey: signKeyList, - privateKey: privateKeyList, - ); - - // 等待一段时间让token更新完成 - await Future.delayed(Duration(milliseconds: 500)); - } catch (e) { - AppLog.log('刷新token异常: $e'); + // 发送远程开门消息 + StartChartManage().sendRemoteUnLockMessage( + bluetoothDeviceName: BlueManage().connectDeviceName, + openLockCommand: messageDetail, + ); + AppLog.log('使用新token重新发送开锁命令'); } } diff --git a/lib/talk/starChart/status/appLifecycle_observer.dart b/lib/talk/starChart/status/appLifecycle_observer.dart index c9e92ab8..b5e30109 100644 --- a/lib/talk/starChart/status/appLifecycle_observer.dart +++ b/lib/talk/starChart/status/appLifecycle_observer.dart @@ -66,14 +66,12 @@ class AppLifecycleObserver extends WidgetsBindingObserver { final status = StartChartManage().talkStatus.status; if ((status == TalkStatus.passiveCallWaitingAnswer || status == TalkStatus.proactivelyCallWaitingAnswer || - status == TalkStatus.answeredSuccessfully) && + status == TalkStatus.answeredSuccessfully || + status == TalkStatus.uninitialized) && Get.currentRoute != '/StarLockRegisterPage') { // 避免在注册页返回 Get.back(); } - // 避免在无通话状态时销毁对讲资源 - if (status != TalkStatus.uninitialized) { - StartChartManage().destruction(); - } + StartChartManage().destruction(); _readMessageRefreshUIEvent?.cancel(); } diff --git a/lib/talk/starChart/views/native/talk_view_native_decode_logic.dart b/lib/talk/starChart/views/native/talk_view_native_decode_logic.dart index 9a6cbcbf..ef74d139 100644 --- a/lib/talk/starChart/views/native/talk_view_native_decode_logic.dart +++ b/lib/talk/starChart/views/native/talk_view_native_decode_logic.dart @@ -1301,13 +1301,8 @@ class TalkViewNativeDecodeLogic extends BaseGetXController { state.currentQuality.value = quality; TalkExpectReq talkExpectReq = StartChartManage().getDefaultTalkExpect(); final audioType = talkExpectReq.audioType; - - // 立即显示loading状态 - state.isLoading.value = true; - int width = 864; int height = 480; - switch (quality) { case '高清': talkExpectReq = TalkExpectReq( @@ -1327,23 +1322,15 @@ class TalkViewNativeDecodeLogic extends BaseGetXController { break; } - // 立即预设解码器尺寸 + /// 修改发送预期数据 + StartChartManage().changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(talkExpect: talkExpectReq); + + // 不立即loading,继续解码旧流帧,等待frameSeq回绕检测 + // 仅重置frameSeq回绕检测标志 + _pendingStreamReset = false; _pendingResetWidth = width; _pendingResetHeight = height; - try { - // 并行执行两个操作以提高效率,设置更短的总超时时间 - await Future.wait([ - // 立即重置解码器 - _resetDecoderForNewStream(width, height), - // 修改发送预期数据 - Future.microtask(() => - StartChartManage().changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(talkExpect: talkExpectReq)) - ]).timeout(const Duration(milliseconds: 1500)); // 设置总超时时间 - } catch (e) { - AppLog.log('切换清晰度超时或失败: $e'); - state.isLoading.value = false; - } } void _initHdOptions() {