集成接口 开始执行任务的领域层和数据层和UI层的开发啊(待测试)

集成功能 暂停 取消功能 恢复功能的接口的领域层和数据层的开发 下一步待集成到页面上
优化功能,优化了接口异常和未知异常对页面渲染的影响对用户的体验的不好情况。具体通过弹窗友好提示!
优化更新了tcp指示灯点击出现机器状态中添加选中设备的编号 方便用户使用的明白明了!。
优化更新关闭了tcp重连操作内链条中的获取用户设备和切换设备操作项。
调整了获取无人机状态信息的更新频率 为14秒一次
This commit is contained in:
2026-06-16 17:34:00 +08:00
parent 52fe17c0d5
commit 71aea48d9f
61 changed files with 2896 additions and 1648 deletions

View File

@@ -0,0 +1,315 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get_it/get_it.dart';
import '../../../../core/app/app_user_cubit.dart';
import '../../../../core/logging/i_logger_service.dart';
import '../../../../core/network/error_handler.dart';
import '../../../../features/v2/site/presentation/cubit/site_cubit.dart';
import '../../domain/usecases/cancel_task_usecase.dart';
import '../../domain/usecases/get_device_task_pool_usecase.dart';
import '../../domain/usecases/pause_task_usecase.dart';
import '../../domain/usecases/recovery_task_usecase.dart';
import 'device_task_state.dart';
class DeviceTaskCubit extends Cubit<DeviceTaskState> {
final GetDeviceTaskPoolUseCase _getDeviceTaskPoolUseCase;
final CancelTaskUseCase _cancelTaskUseCase;
final PauseTaskUseCase _pauseTaskUseCase;
final RecoveryTaskUseCase _recoveryTaskUseCase;
final ILoggerService _logger = GetIt.I<ILoggerService>();
DeviceTaskCubit(
this._getDeviceTaskPoolUseCase,
this._cancelTaskUseCase,
this._pauseTaskUseCase,
this._recoveryTaskUseCase,
) : super(const DeviceTaskState());
/// 获取任务池并过滤出当前设备的任务
Future<void> fetchAndFilterTask(String deviceId) async {
emit(state.copyWith(isLoading: true, errorMessage: null));
try {
// 获取用户信息
final userCubit = GetIt.I<AppUserCubit>();
final user = userCubit.state.user;
if (user == null) {
emit(state.copyWith(
isLoading: false,
errorMessage: '用户未登录',
));
return;
}
// 获取场站ID
final siteCubit = GetIt.I<SiteCubit>();
final siteId = siteCubit.state.selectedSite?.id;
if (siteId == null) {
emit(state.copyWith(
isLoading: false,
errorMessage: '未选择场站',
));
return;
}
// 调用接口获取任务池
final result = await _getDeviceTaskPoolUseCase.call(
GetDeviceTaskPoolParams(
userId: user.userId ?? '',
siteId: siteId,
orgId: user.orgId ?? 0,
),
);
result.fold(
(failure) {
_logger.logWithLevel('❌ 获取任务池失败: ${failure.message}');
emit(state.copyWith(
isLoading: false,
errorMessage: ErrorHandler.getErrorMessage(failure.message),
shouldShowError: true, // 🔥 标记需要显示错误弹窗
));
},
(taskList) {
// 过滤出当前设备的任务
final deviceTasks = taskList
.where((task) => task.deviceId == deviceId)
.toList();
// 取第一个任务(或根据业务逻辑选择)
final currentTask = deviceTasks.isNotEmpty ? deviceTasks.first : null;
_logger.logWithLevel(
'✅ 找到 ${deviceTasks.length} 个任务,当前任务ID: ${currentTask?.id}',
);
emit(state.copyWith(
isLoading: false,
taskPool: taskList,
currentTask: currentTask,
currentTaskId: currentTask?.id,
));
},
);
} catch (e) {
_logger.logWithLevel('❌ 获取任务池异常: $e');
emit(state.copyWith(
isLoading: false,
errorMessage: ErrorHandler.getErrorMessage(e),
shouldShowError: true, // 🔥 标记需要显示错误弹窗
));
}
}
/// 取消任务
Future<void> cancelTask(String deviceId) async {
final taskId = state.currentTaskId;
if (taskId == null) {
emit(state.copyWith(errorMessage: '无可用任务'));
return;
}
emit(state.copyWith(
isLoading: true,
operationType: DeviceTaskOperationType.cancel,
));
try {
final userCubit = GetIt.I<AppUserCubit>();
final user = userCubit.state.user;
final siteCubit = GetIt.I<SiteCubit>();
final siteId = siteCubit.state.selectedSite?.id;
if (user == null || siteId == null) {
emit(state.copyWith(
isLoading: false,
errorMessage: '参数不完整',
operationType: DeviceTaskOperationType.none,
));
return;
}
final result = await _cancelTaskUseCase.call(
CancelTaskParams(
deviceId: deviceId,
taskId: taskId,
orgId: user.orgId ?? 0,
siteId: siteId,
),
);
result.fold(
(failure) {
_logger.logWithLevel('❌ 取消任务失败: ${failure.message}');
emit(state.copyWith(
isLoading: false,
errorMessage: ErrorHandler.getErrorMessage(failure.message),
operationType: DeviceTaskOperationType.none,
shouldShowError: true, // 🔥 标记需要显示错误弹窗
));
},
(success) {
_logger.logWithLevel('✅ 取消任务成功');
emit(state.copyWith(
isLoading: false,
operationType: DeviceTaskOperationType.none,
));
},
);
} catch (e) {
_logger.logWithLevel('❌ 取消任务异常: $e');
emit(state.copyWith(
isLoading: false,
errorMessage: ErrorHandler.getErrorMessage(e),
operationType: DeviceTaskOperationType.none,
shouldShowError: true, // 🔥 标记需要显示错误弹窗
));
}
}
/// 暂停任务
Future<void> pauseTask(String deviceId) async {
final taskId = state.currentTaskId;
if (taskId == null) {
emit(state.copyWith(errorMessage: '无可用任务'));
return;
}
emit(state.copyWith(
isLoading: true,
operationType: DeviceTaskOperationType.pause,
));
try {
final userCubit = GetIt.I<AppUserCubit>();
final user = userCubit.state.user;
final siteCubit = GetIt.I<SiteCubit>();
final siteId = siteCubit.state.selectedSite?.id;
if (user == null || siteId == null) {
emit(state.copyWith(
isLoading: false,
errorMessage: '参数不完整',
operationType: DeviceTaskOperationType.none,
));
return;
}
final result = await _pauseTaskUseCase.call(
PauseTaskParams(
deviceId: deviceId,
taskId: taskId,
orgId: user.orgId ?? 0,
siteId: siteId,
),
);
result.fold(
(failure) {
_logger.logWithLevel('❌ 暂停任务失败: ${failure.message}');
emit(state.copyWith(
isLoading: false,
errorMessage: ErrorHandler.getErrorMessage(failure.message),
operationType: DeviceTaskOperationType.none,
shouldShowError: true, // 🔥 标记需要显示错误弹窗
));
},
(success) {
_logger.logWithLevel('✅ 暂停任务成功');
emit(state.copyWith(
isLoading: false,
operationType: DeviceTaskOperationType.none,
));
},
);
} catch (e) {
_logger.logWithLevel('❌ 暂停任务异常: $e');
emit(state.copyWith(
isLoading: false,
errorMessage: ErrorHandler.getErrorMessage(e),
operationType: DeviceTaskOperationType.none,
shouldShowError: true, // 🔥 标记需要显示错误弹窗
));
}
}
/// 恢复任务
Future<void> recoveryTask(String deviceId) async {
final taskId = state.currentTaskId;
if (taskId == null) {
emit(state.copyWith(errorMessage: '无可用任务'));
return;
}
emit(state.copyWith(
isLoading: true,
operationType: DeviceTaskOperationType.recovery,
));
try {
final userCubit = GetIt.I<AppUserCubit>();
final user = userCubit.state.user;
final siteCubit = GetIt.I<SiteCubit>();
final siteId = siteCubit.state.selectedSite?.id;
if (user == null || siteId == null) {
emit(state.copyWith(
isLoading: false,
errorMessage: '参数不完整',
operationType: DeviceTaskOperationType.none,
));
return;
}
final result = await _recoveryTaskUseCase.call(
RecoveryTaskParams(
deviceId: deviceId,
taskId: taskId,
orgId: user.orgId ?? 0,
siteId: siteId,
),
);
result.fold(
(failure) {
_logger.logWithLevel('❌ 恢复任务失败: ${failure.message}');
emit(state.copyWith(
isLoading: false,
errorMessage: ErrorHandler.getErrorMessage(failure.message),
operationType: DeviceTaskOperationType.none,
shouldShowError: true, // 🔥 标记需要显示错误弹窗
));
},
(data) {
_logger.logWithLevel('✅ 恢复任务成功: $data');
emit(state.copyWith(
isLoading: false,
operationType: DeviceTaskOperationType.none,
));
},
);
} catch (e) {
_logger.logWithLevel('❌ 恢复任务异常: $e');
emit(state.copyWith(
isLoading: false,
errorMessage: ErrorHandler.getErrorMessage(e),
operationType: DeviceTaskOperationType.none,
shouldShowError: true, // 🔥 标记需要显示错误弹窗
));
}
}
/// 更新当前任务ID(当选择新航线时调用)
void updateCurrentTaskId(int taskId) {
emit(state.copyWith(currentTaskId: taskId));
_logger.logWithLevel('🔄 更新当前任务ID: $taskId');
}
/// 清除当前任务
void clearCurrentTask() {
emit(state.copyWith(
currentTask: null,
currentTaskId: null,
));
_logger.logWithLevel('🧹 清除当前任务');
}
}

View File

@@ -0,0 +1,60 @@
import 'package:equatable/equatable.dart';
import '../../domain/entities/device_task_entity.dart';
enum DeviceTaskOperationType {
none,
cancel,
pause,
recovery,
}
class DeviceTaskState extends Equatable {
final List<DeviceTaskEntity> taskPool;
final DeviceTaskEntity? currentTask;
final int? currentTaskId;
final bool isLoading;
final String? errorMessage;
final DeviceTaskOperationType operationType;
final bool shouldShowError; // 🔥 标记是否需要显示错误弹窗
const DeviceTaskState({
this.taskPool = const [],
this.currentTask,
this.currentTaskId,
this.isLoading = false,
this.errorMessage,
this.operationType = DeviceTaskOperationType.none,
this.shouldShowError = false,
});
DeviceTaskState copyWith({
List<DeviceTaskEntity>? taskPool,
DeviceTaskEntity? currentTask,
int? currentTaskId,
bool? isLoading,
String? errorMessage,
DeviceTaskOperationType? operationType,
bool? shouldShowError,
}) {
return DeviceTaskState(
taskPool: taskPool ?? this.taskPool,
currentTask: currentTask ?? this.currentTask,
currentTaskId: currentTaskId ?? this.currentTaskId,
isLoading: isLoading ?? this.isLoading,
errorMessage: errorMessage,
operationType: operationType ?? this.operationType,
shouldShowError: shouldShowError ?? false, // 🔥 默认重置为 false
);
}
@override
List<Object?> get props => [
taskPool,
currentTask,
currentTaskId,
isLoading,
errorMessage,
operationType,
shouldShowError,
];
}

View File

@@ -623,4 +623,53 @@ class DevicesCubit extends Cubit<DevicesState> {
//print('🔄 [DevicesCubit] 已重置到达位置');
_logger.logWithLevel('🔄 [DevicesCubit] 已重置到达位置');
}
/// 🔥 获取当前选中的设备
DeviceEntity? getSelectedDevice() {
return state.selectedDevice;
}
/// 🔥 异步获取当前选中的设备(兼容 RemoteControlCubit 接口)
Future<DeviceEntity?> getDevice() async {
return state.selectedDevice;
}
/// 🔥 判断是否有选中设备
bool hasSelectedDevice() {
return state.selectedDevice != null;
}
/// 🔥 获取选中设备名称(安全获取,返回空字符串而非null)
String getSelectedDeviceName() {
return state.selectedDevice?.deviceName ?? '';
}
/// 🔥 获取选中设备ID(安全获取,返回空字符串而非null)
String getSelectedDeviceId() {
return state.selectedDevice?.deviceName ?? '';
}
/// 🔥 清除选中设备
void clearSelectedDevice() {
debugPrint('🧹 [DevicesCubit] 清除选中设备');
_logger.logWithLevel('🧹 [DevicesCubit] 清除选中设备');
emit(state.copyWith(selectedDevice: null));
}
/// 🔥 检查设备是否在列表中
bool isDeviceInList(String deviceName) {
return state.devices.any((device) => device.deviceName == deviceName);
}
/// 🔥 根据设备名称查找设备
DeviceEntity? findDeviceByName(String deviceName) {
try {
return state.devices.firstWhere(
(device) => device.deviceName == deviceName,
orElse: () => throw Exception('Device not found'),
);
} catch (e) {
return null;
}
}
}