From 5170eeb4e76c053298eae7dc576e1c60cc19e8d4 Mon Sep 17 00:00:00 2001 From: mmc <1556375442@qq.com> Date: Fri, 27 Feb 2026 14:16:29 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E7=BB=91=E8=AE=BE=E5=A4=87=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/bloc/devices_cubit.dart | 53 +++--- .../presentation/widgets/ImmersionHeader.dart | 1 - .../pages/machine_details_page.dart | 165 ++++++++++++++---- 3 files changed, 152 insertions(+), 67 deletions(-) diff --git a/lib/features/devices/presentation/bloc/devices_cubit.dart b/lib/features/devices/presentation/bloc/devices_cubit.dart index 687fd14a..c7875bde 100644 --- a/lib/features/devices/presentation/bloc/devices_cubit.dart +++ b/lib/features/devices/presentation/bloc/devices_cubit.dart @@ -27,53 +27,50 @@ class DevicesCubit extends Cubit { ) : super(const DevicesState()); Future unbindDevice(String deviceId, String deviceName) async { - // 1. 加载中状态 emit(state.copyWith(isLoading: true, errorMessage: '')); try { - // 2. 构建参数 final params = UnbindDeviceParams(deviceId, deviceName); - - // 3. 调用 UseCase(核心:执行解绑逻辑) final result = await _unbindDeviceUseCase.call(params); - // 4. 处理 UseCase 返回的 Either 结果 result.fold( - // 失败:更新错误状态 (failure) => emit( state.copyWith( isLoading: false, errorMessage: failure.message ?? '解绑设备失败', ), ), - // 成功:更新状态(比如从设备列表中移除该设备) (successCode) { - // 过滤掉已解绑的设备 - final updatedDevices = state.devices?.where((device) { - return device.deviceAlias != deviceId && - device.deviceName != deviceName; - }).toList(); + // 核心修复:int 转 bool 条件判断 + final isSuccess = successCode == 1; // 显式转为 bool + if (isSuccess) { + final updatedDevices = state.devices?.where((device) { + return device.deviceName != deviceId; + }).toList(); - // 更新状态:清空加载、更新设备列表、清空选中设备(如果解绑的是当前选中设备) - emit( - state.copyWith( - isLoading: false, - devices: updatedDevices, - selectedDevice: state.selectedDevice?.deviceAlias == deviceId - ? null - : state.selectedDevice, - errorMessage: '', - ), - ); + emit( + state.copyWith( + isLoading: false, + devices: updatedDevices, + selectedDevice: state.selectedDevice?.deviceName == deviceId + ? null + : state.selectedDevice, + errorMessage: '', + ), + ); + } else { + emit( + state.copyWith( + isLoading: false, + errorMessage: '解绑失败:状态码 $successCode', + ), + ); + } }, ); } catch (e) { - // 捕获其他异常 emit( - state.copyWith( - isLoading: false, - errorMessage: '解绑设备异常:${e.toString()}', - ), + state.copyWith(isLoading: false, errorMessage: '解绑异常:${e.toString()}'), ); } } diff --git a/lib/features/home/presentation/widgets/ImmersionHeader.dart b/lib/features/home/presentation/widgets/ImmersionHeader.dart index 29a7b775..dc81a786 100644 --- a/lib/features/home/presentation/widgets/ImmersionHeader.dart +++ b/lib/features/home/presentation/widgets/ImmersionHeader.dart @@ -372,7 +372,6 @@ class ImmersionHeader extends StatelessWidget { softWrap: true, // 允许换行 ), ), - ], ), const Text( diff --git a/lib/features/machine_details/presentation/pages/machine_details_page.dart b/lib/features/machine_details/presentation/pages/machine_details_page.dart index bedef01a..8390f79f 100644 --- a/lib/features/machine_details/presentation/pages/machine_details_page.dart +++ b/lib/features/machine_details/presentation/pages/machine_details_page.dart @@ -1,8 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:go_router/go_router.dart'; +import 'package:maibu_satabot_v2/core/app/app_user_cubit.dart'; +import 'package:maibu_satabot_v2/core/router/route_paths.dart'; import 'package:maibu_satabot_v2/features/devices/domain/entities/device_entity.dart'; import 'package:maibu_satabot_v2/features/devices/presentation/bloc/devices_cubit.dart'; +import 'package:maibu_satabot_v2/features/devices/presentation/bloc/devices_state.dart'; class MachineDetailsPage extends StatefulWidget { final DeviceEntity? device; @@ -17,6 +21,7 @@ class _MachineDetailsPageState extends State { late TextEditingController _nameController; late String _deviceName; late String _deviceId; + BuildContext? _dialogContext; @override void initState() { @@ -122,32 +127,39 @@ class _MachineDetailsPageState extends State { } final currentDevice = widget.device!; - - return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), - appBar: AppBar( - centerTitle: true, - title: const Text( - '设备详情', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + return BlocListener( + listener: (context, state) { + // 只有解绑操作触发的状态变化才处理 + if (state.isLoading || state.errorMessage != null) { + _handleUnbindResult(state); + } + }, + child: Scaffold( + backgroundColor: const Color(0xFFF5F5F5), + appBar: AppBar( + centerTitle: true, + title: const Text( + '设备详情', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios), + onPressed: () => Navigator.pop(context), + ), ), - leading: IconButton( - icon: const Icon(Icons.arrow_back_ios), - onPressed: () => Navigator.pop(context), - ), - ), - body: SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - children: [ - _buildDeviceStatusCard(currentDevice), - const SizedBox(height: 16), - _buildBasicInfoCard(context, currentDevice), // 传递context和设备数据 - const SizedBox(height: 16), - _buildResourceCenterCard(), - const SizedBox(height: 24), - _buildUnbindButton(context), - ], + body: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + _buildDeviceStatusCard(currentDevice), + const SizedBox(height: 16), + _buildBasicInfoCard(context, currentDevice), // 传递context和设备数据 + const SizedBox(height: 16), + _buildResourceCenterCard(), + const SizedBox(height: 24), + _buildUnbindButton(context), + ], + ), ), ), ); @@ -393,15 +405,17 @@ class _MachineDetailsPageState extends State { child: const Text('取消'), ), TextButton( - onPressed: () { - //Navigator.pop(dialogContext); - context.read().unbindDevice( - _deviceId ?? '', - _deviceName ?? '', - ); - // 执行解绑操作(传入设备ID) - // _unbindDevice(device?.deviceName ?? ''); - }, + onPressed: _executeUnbind, // 执行解绑 + //onPressed: () { + + // //Navigator.pop(dialogContext); + // //context.read().unbindDevice( + // // _deviceId ?? '', + // // _deviceName ?? '', + // //); + // // 执行解绑操作(传入设备ID) + // // _unbindDevice(device?.deviceName ?? ''); + //}, child: const Text('确认'), ), ], @@ -420,8 +434,83 @@ class _MachineDetailsPageState extends State { ); } - // 可选:解绑设备的方法(根据你的业务实现) - // void _unbindDevice(String deviceId) { - // // 调用解绑接口的逻辑 - // } + Future _executeUnbind() async { + if (_deviceId.isEmpty || _deviceName.isEmpty) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("设备信息异常,无法解绑"), + backgroundColor: Colors.red, + ), + ); + } + return; + } + + // 调用 Cubit 解绑方法 + await context.read().unbindDevice(_deviceId, _deviceName); + } + + /// 处理解绑结果(成功/失败) + void _handleUnbindResult(DevicesState state) { + // 1. 关闭确认弹窗 + if (_dialogContext != null && Navigator.canPop(_dialogContext!)) { + Navigator.pop(_dialogContext!); + _dialogContext = null; + } + + // 2. 处理加载状态(隐藏加载弹窗/按钮禁用等) + if (state.isLoading) { + // 可选:显示加载弹窗 + showDialog( + context: context, + barrierDismissible: false, + builder: (ctx) => const AlertDialog( + content: Row( + children: [ + CircularProgressIndicator(), + SizedBox(width: 16), + Text("正在解绑设备..."), + ], + ), + ), + ); + return; + } + + // 3. 处理结果 + if (state.errorMessage?.isEmpty == true) { + // 解绑成功 + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("设备「$_deviceName」解绑成功"), + backgroundColor: Colors.green, + duration: const Duration(seconds: 2), + ), + ); + + // 延迟返回上一页(让用户看到提示) + Future.delayed(const Duration(seconds: 1), () { + if (context.mounted) { + Navigator.pop(context); // 返回设备列表页 + } + }); + } else if (state.errorMessage?.isNotEmpty == true) { + // 解绑失败 + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("解绑失败:${state.errorMessage ?? '未知错误'}"), + backgroundColor: Colors.red, + ), + ); + + // 关闭加载弹窗(如果存在) + if (Navigator.canPop(context)) { + Navigator.pop(context); + } + } + final username = context.read().state.user?.username ?? ""; + context.read().fetchAllDevices(username); + context.go(RoutePaths.home); + } }