Files
flutterApp/docs/DEVICE_TASK_CUBIT_USAGE.md
Songzex 71aea48d9f 集成接口 开始执行任务的领域层和数据层和UI层的开发啊(待测试)
集成功能 暂停 取消功能 恢复功能的接口的领域层和数据层的开发 下一步待集成到页面上
优化功能,优化了接口异常和未知异常对页面渲染的影响对用户的体验的不好情况。具体通过弹窗友好提示!
优化更新了tcp指示灯点击出现机器状态中添加选中设备的编号 方便用户使用的明白明了!。
优化更新关闭了tcp重连操作内链条中的获取用户设备和切换设备操作项。
调整了获取无人机状态信息的更新频率 为14秒一次
2026-06-16 17:34:00 +08:00

6.0 KiB
Raw Blame History

DeviceTaskCubit 使用指南

功能概述

DeviceTaskCubit 提供了设备任务管理的完整功能:

  • 获取任务池并过滤出当前设备的任务
  • 取消任务
  • 暂停任务
  • 恢复任务
  • 全局管理 taskId

在页面中集成

1. 在 BlocProvider 中注册

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get_it/get_it.dart';
import '../presentation/bloc/device_task_cubit.dart';

class YourPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => GetIt.I<DeviceTaskCubit>(),
      child: YourPageContent(),
    );
  }
}

2. 获取任务池(选择航线时调用)

// 当用户选择航线后,获取该设备的任务
final deviceId = targetDevice?.deviceId ?? '';
if (deviceId.isNotEmpty) {
  context.read<DeviceTaskCubit>().fetchAndFilterTask(deviceId);
}

3. 监听状态变化(自动显示错误弹窗)

BlocConsumer<DeviceTaskCubit, DeviceTaskState>(
  listener: (context, state) {
    // 🔥 自动显示错误弹窗(2秒后自动消失)
    if (state.shouldShowError && state.errorMessage != null) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(state.errorMessage!),
          backgroundColor: Colors.orange,
          duration: const Duration(seconds: 2),
        ),
      );
    }
    
    // 操作成功提示
    if (state.operationType == DeviceTaskOperationType.cancel && 
        !state.isLoading) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('取消任务成功')),
      );
    }
  },
  builder: (context, state) {
    // 显示加载状态
    if (state.isLoading) {
      return const CircularProgressIndicator();
    }
    
    // 显示当前任务ID
    final taskId = state.currentTaskId;
    return Text('当前任务ID: $taskId');
  },
)

关键点:

  • shouldShowError 为 true 时,表示发生了错误,需要显示弹窗
  • 弹窗会自动在 2 秒后消失
  • 不会影响页面展示,页面继续正常运行

4. 执行任务操作

取消任务

final deviceId = targetDevice?.deviceId ?? '';
context.read<DeviceTaskCubit>().cancelTask(deviceId);

暂停任务

final deviceId = targetDevice?.deviceId ?? '';
context.read<DeviceTaskCubit>().pauseTask(deviceId);

恢复任务

final deviceId = targetDevice?.deviceId ?? '';
context.read<DeviceTaskCubit>().recoveryTask(deviceId);

5. 手动更新 taskId(选择新航线时)

// 如果需要在选择航线时手动设置 taskId
context.read<DeviceTaskCubit>().updateCurrentTaskId(newTaskId);

6. 清除当前任务

// 退出页面或切换设备时清除
context.read<DeviceTaskCubit>().clearCurrentTask();

注意事项

  1. 自动获取用户信息和场站ID

    • Cubit 内部会自动从 AppUserCubit 和 SiteCubit 获取所需参数
    • 无需手动传递 userId、orgId、siteId
  2. 统一错误处理

    • 所有错误都会通过 ErrorHandler 转换为友好提示
    • 不会显示原始错误信息(如 HTTP 404、连接超时等)
  3. taskId 全局管理

    • fetchAndFilterTask 会自动过滤并保存当前设备的 taskId
    • 所有操作接口都会使用这个全局保存的 taskId
  4. 状态监听

    • operationType 可以区分当前正在进行的操作类型
    • isLoading 表示是否正在执行网络请求

完整示例

class RoutePlanningPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => GetIt.I<DeviceTaskCubit>(),
      child: Scaffold(
        appBar: AppBar(title: const Text('路径规划')),
        body: BlocConsumer<DeviceTaskCubit, DeviceTaskState>(
          listener: (context, state) {
            if (state.errorMessage != null) {
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(content: Text(state.errorMessage!)),
              );
            }
          },
          builder: (context, state) {
            return Column(
              children: [
                // 显示当前任务ID
                Text('当前任务ID: ${state.currentTaskId ?? "无"}'),
                
                // 操作按钮
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        final deviceId = 'YOUR_DEVICE_ID';
                        context.read<DeviceTaskCubit>().pauseTask(deviceId);
                      },
                      child: const Text('暂停'),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        final deviceId = 'YOUR_DEVICE_ID';
                        context.read<DeviceTaskCubit>().recoveryTask(deviceId);
                      },
                      child: const Text('恢复'),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        final deviceId = 'YOUR_DEVICE_ID';
                        context.read<DeviceTaskCubit>().cancelTask(deviceId);
                      },
                      child: const Text('取消'),
                    ),
                  ],
                ),
                
                // 加载指示器
                if (state.isLoading)
                  const CircularProgressIndicator(),
              ],
            );
          },
        ),
      ),
    );
  }
}

错误处理优化

项目中已实现统一的错误处理机制:

  • 所有接口错误都会转换为友好的中文提示
  • 不会显示原始的错误信息(如 "HTTP 404"、"Connection timeout" 等)
  • 提示会自动消失(2秒后)
  • 页面不会崩溃

示例错误提示:

  • "网络连接超时,请检查网络设置"
  • "登录已过期,请重新登录"
  • "操作失败,请稍后重试"
  • "未知错误,请稍后重试"