Files
flutterApp/lib/features/home/presentation/bloc/permission_request_bloc.dart
2026-04-29 14:29:49 +08:00

159 lines
7.0 KiB
Dart
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get_it/get_it.dart';
import '../../../../core/logging/i_logger_service.dart';
import '../../../../core/network/net_message_dispatcher.dart';
import '../../../remote_control/domain/repositories/remote_control_repository.dart';
import 'permission_request_event.dart';
import 'permission_request_state.dart';
class PermissionRequestBloc extends Bloc<PermissionRequestEvent, PermissionRequestState> {
final NetMessageDispatcher _dispatcher;
final RemoteControlRepository _repository;
final ILoggerService _logger = GetIt.I<ILoggerService>();
// 🔥 保存订阅引用,用于管理生命周期
StreamSubscription? _permissionSubscription;
PermissionRequestBloc(this._dispatcher, this._repository) : super(const PermissionRequestInitial()) {
// 🔥 核心:直接在构造函数中建立 0x12 监听(通过 NetMessageDispatcher)
_initPermissionListener();
// 事件处理
on<PermissionRequestReceived>(_handleRequestReceived);
on<PermissionDialogDismissed>(_handleDialogDismissed);
}
// 🔥 通过 NetMessageDispatcher 监听 TCP 0x12 指令,解析权限请求
void _initPermissionListener() {
debugPrint('🔗 [PermissionRequestBloc] 初始化 0x12 权限监听器(通过 NetMessageDispatcher)');
_logger.logWithLevel('🔗 [PermissionRequestBloc] 初始化 0x12 权限监听器', shouldLog: true);
_permissionSubscription = _dispatcher.onCommand(0x12).listen((packet) {
debugPrint('🔍 [PermissionRequestBloc] ✅✅✅ 0x12 包被监听到了!');
_logger.logWithLevel('>>> [PermissionRequestBloc] ✅✅✅ 0x12 包被监听到了!', shouldLog: true);
try {
_logger.logWithLevel('>>> [PermissionRequestBloc] ✅ 收到 0x12 原始包', shouldLog: true);
// 🔥 关键:手动去掉最后 2 个 CRC 字节
String jsonString;
if (packet.payload.length > 2) {
jsonString = utf8.decode(packet.payload.sublist(0, packet.payload.length - 2));
} else {
jsonString = utf8.decode(packet.payload);
}
debugPrint('>>> [PermissionRequestBloc] 收到 0x12: $jsonString');
_logger.logWithLevel('>>> [PermissionRequestBloc] 收到 0x12: $jsonString', shouldLog: true);
final jsonMap = jsonDecode(jsonString);
final requestType = jsonMap['request'];
final platform = jsonMap['platform'];
final respondData = jsonMap['respond'];
_logger.logWithLevel('>>> [PermissionRequestBloc] 解析结果: requestType=$requestType, platform=$platform', shouldLog: true);
// 情况 1: 响应格式(忽略)
if (respondData != null && respondData is Map) {
debugPrint('>>> [PermissionRequestBloc] 📊 收到响应格式,忽略');
_logger.logWithLevel('>>> [PermissionRequestBloc] 📊 收到响应格式,忽略', shouldLog: true);
return;
}
// 情况 2: 请求格式 - switch_control
if (requestType == 'switch_control') {
// 🔥 关键判断:只有当是其他平台(web)请求时才弹窗
if (platform != null && platform.toString().toLowerCase() != 'app') {
debugPrint('>>> [PermissionRequestBloc] 🚨 $platform 端请求控制权');
_logger.logWithLevel('>>> [PermissionRequestBloc] 🚨 $platform 端请求控制权', shouldLog: true);
if (!isClosed) {
_logger.logWithLevel('>>> [PermissionRequestBloc] 📤 准备 add PermissionRequestReceived 事件', shouldLog: true);
add(PermissionRequestReceived(
platform: platform.toString(),
requestType: requestType,
));
} else {
_logger.logWithLevel('>>> [PermissionRequestBloc] ⚠️ Bloc 已关闭,无法添加事件', shouldLog: true);
}
} else {
debugPrint('>>> [PermissionRequestBloc] ℹ️ APP 自己的请求回显,忽略');
_logger.logWithLevel('>>> [PermissionRequestBloc] ℹ️ APP 自己的请求回显,忽略', shouldLog: true);
}
}
// 情况 3: 异地登录通知
else if (requestType == 'have_logged_in') {
debugPrint('>>> [PermissionRequestBloc] ⚠️ 检测到异地登录');
_logger.logWithLevel('>>> [PermissionRequestBloc] ⚠️ 检测到异地登录', shouldLog: true);
if (!isClosed) {
_logger.logWithLevel('>>> [PermissionRequestBloc] 📤 准备 add PermissionRequestReceived 事件(异地登录)', shouldLog: true);
add(PermissionRequestReceived(
platform: 'unknown',
requestType: requestType,
));
}
}
} catch (e) {
debugPrint('>>> [PermissionRequestBloc] ❌ 解析失败:$e');
_logger.logWithLevel('>>> [PermissionRequestBloc] ❌ 解析失败:$e', shouldLog: true);
}
});
debugPrint('✅ [PermissionRequestBloc] 0x12 监听器已建立完成');
_logger.logWithLevel('✅ [PermissionRequestBloc] 0x12 监听器已建立完成', shouldLog: true);
}
Future<void> _handleRequestReceived(
PermissionRequestReceived event,
Emitter<PermissionRequestState> emit,
) async {
debugPrint('📤 [PermissionRequestBloc] emit DialogVisible - platform=${event.platform}');
_logger.logWithLevel('📤 [PermissionRequestBloc] emit DialogVisible - platform=${event.platform}', shouldLog: true);
emit(PermissionRequestDialogVisible(
platform: event.platform,
requestType: event.requestType,
));
_logger.logWithLevel('📤 [PermissionRequestBloc] ✅ 已 emit DialogVisible 状态', shouldLog: true);
}
Future<void> _handleDialogDismissed(
PermissionDialogDismissed event,
Emitter<PermissionRequestState> emit,
) async {
debugPrint('📤 [PermissionRequestBloc] emit DialogHidden');
_logger.logWithLevel('📤 [PermissionRequestBloc] emit DialogHidden');
// 🔥 发送响应到机器人(和远程遥控页面一样)
if (event.deviceId.isNotEmpty) {
debugPrint('📤 [PermissionRequestBloc] 发送权限响应: agree=${event.agree}, deviceId=${event.deviceId}');
_repository.respondPermission(event.agree, event.deviceId);
}
emit(const PermissionRequestDialogHidden());
}
@override
Future<void> close() {
debugPrint('🚫 [PermissionRequestBloc] 关闭,取消订阅');
_logger.logWithLevel('🚫 [PermissionRequestBloc] 关闭', shouldLog: true);
_permissionSubscription?.cancel();
return super.close();
}
/// 🔥 公开方法:重新初始化监听器(TCP 重连后调用)
void reinitListener() {
debugPrint('🔄 [PermissionRequestBloc] 重新初始化监听器');
_logger.logWithLevel('🔄 [PermissionRequestBloc] 重新初始化监听器', shouldLog: true);
_permissionSubscription?.cancel();
_initPermissionListener();
}
}