import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:maibu_satabot_v2/core/consts/tcp_consts.dart'; import 'package:maibu_satabot_v2/core/domain/entities/user_entity.dart'; import 'package:maibu_satabot_v2/core/network/net_message_dispatcher.dart'; import '../../../../core/app/app_user_cubit.dart'; import '../../../../core/network/tcp/tcp_client.dart'; import '../../../../core/storage/user_storage.dart'; import '../../../devices/domain/usecases/get_user_device_usecase.dart'; import '../../../devices/domain/usecases/switch_device_usecase.dart'; import '../../data/datasources/auth_tcp_datasource.dart'; import '../../data/datasources/impl/auth_tcp_datasource_impl.dart'; import 'auth_state.dart'; /// emit做的事情: /// 1.修改状态标志:通过改变类的类型(从 Initial 变成 Authenticated) /// 2.携带数据:把 user 对象塞进了状态里,让外部能拿到 /// 3.发送通知:自动触发监听(如 GoRouter 的刷新)。 class AuthCubit extends Cubit { final UserStorage storage; final TcpClient tcp; final AppUserCubit appCubit; final NetMessageDispatcher dispatcher; final AuthTcpDatasource _authTcpDatasource; StreamSubscription? _kickOutSub; // 新增:用于管理监听生命周期 AuthCubit(this.storage, this.tcp, this.appCubit, this.dispatcher, this._authTcpDatasource) : super(AuthInitial()) { // Cubit 一启动就开始监听 TCP 的“自动逻辑” _listenToAuthResponse(); } /// App 启动时检查本地缓存 Future appStarted() async { final user = await storage.getUser(); if (user != null) { // 1. 建立 TCP 连接 (远程控制) tcp.connect(host: TCPConsts.TCP_IP, port: TCPConsts.TCP_PORT); //await _authTcpDatasource.sendAuthPacket();//包括发送认证包和获取列表和切换函数 // 2. 同步全局 App 状态 appCubit.setAuth(user); // 3. 进入已登录状态 emit(AuthAuthenticated(user)); } else { emit(AuthUnauthenticated()); } } /// 当 HTTP 登录/注册成功后调用 Future loginSuccess(UserEntity user) async { await storage.saveUser(user); await tcp.connect(host: TCPConsts.TCP_IP, port: TCPConsts.TCP_PORT); await _authTcpDatasource.sendAuthPacket();//包括发送认证包和获取列表和切换函数 tcp.startHeartbeat(interval: const Duration(seconds: 4)); //启动心跳 appCubit.setAuth(user); emit(AuthAuthenticated(user)); } /// 退出登录 (主动或被动) Future logout() async { print("退出登录"); await storage.deleteUser(); tcp.disconnect(); appCubit.clearAuth(); emit(AuthUnauthenticated()); } /// TCP 指令监听 void _listenToAuthResponse() { _kickOutSub?.cancel(); // 防止重复监听 // 假设 0x12 是踢下线或多设备登录提醒 _kickOutSub = dispatcher.onJsonMessage(0x12).listen((json) { // 如果后端发来指令确认需要退出 // print('>>> [AUTH] 收到 0x12: $json'); // logout(); }); } @override Future close() { _kickOutSub?.cancel(); // 销毁 Cubit 时关闭监听 return super.close(); } }