解绑设备完成

This commit is contained in:
mmc
2026-02-27 14:16:29 +08:00
parent 6e6986a49a
commit 5170eeb4e7
3 changed files with 152 additions and 67 deletions

View File

@@ -27,53 +27,50 @@ class DevicesCubit extends Cubit<DevicesState> {
) : super(const DevicesState());
Future<void> 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()}'),
);
}
}

View File

@@ -372,7 +372,6 @@ class ImmersionHeader extends StatelessWidget {
softWrap: true, // 允许换行
),
),
],
),
const Text(

View File

@@ -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<MachineDetailsPage> {
late TextEditingController _nameController;
late String _deviceName;
late String _deviceId;
BuildContext? _dialogContext;
@override
void initState() {
@@ -122,32 +127,39 @@ class _MachineDetailsPageState extends State<MachineDetailsPage> {
}
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<DevicesCubit, DevicesState>(
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<MachineDetailsPage> {
child: const Text('取消'),
),
TextButton(
onPressed: () {
//Navigator.pop(dialogContext);
context.read<DevicesCubit>().unbindDevice(
_deviceId ?? '',
_deviceName ?? '',
);
// 执行解绑操作(传入设备ID)
// _unbindDevice(device?.deviceName ?? '');
},
onPressed: _executeUnbind, // 执行解绑
//onPressed: () {
// //Navigator.pop(dialogContext);
// //context.read<DevicesCubit>().unbindDevice(
// // _deviceId ?? '',
// // _deviceName ?? '',
// //);
// // 执行解绑操作(传入设备ID)
// // _unbindDevice(device?.deviceName ?? '');
//},
child: const Text('确认'),
),
],
@@ -420,8 +434,83 @@ class _MachineDetailsPageState extends State<MachineDetailsPage> {
);
}
// 可选:解绑设备的方法(根据你的业务实现)
// void _unbindDevice(String deviceId) {
// // 调用解绑接口的逻辑
// }
Future<void> _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<DevicesCubit>().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<AppUserCubit>().state.user?.username ?? "";
context.read<DevicesCubit>().fetchAllDevices(username);
context.go(RoutePaths.home);
}
}