Files
feature-next-arch/docs/DEVICE_TASK_CUBIT_USAGE.md

214 lines
6.0 KiB
Markdown
Raw Normal View History

# DeviceTaskCubit 使用指南
## 功能概述
DeviceTaskCubit 提供了设备任务管理的完整功能:
- 获取任务池并过滤出当前设备的任务
- 取消任务
- 暂停任务
- 恢复任务
- 全局管理 taskId
## 在页面中集成
### 1. 在 BlocProvider 中注册
```dart
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. 获取任务池(选择航线时调用)
```dart
// 当用户选择航线后,获取该设备的任务
final deviceId = targetDevice?.deviceId ?? '';
if (deviceId.isNotEmpty) {
context.read<DeviceTaskCubit>().fetchAndFilterTask(deviceId);
}
```
### 3. 监听状态变化(自动显示错误弹窗)
```dart
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. 执行任务操作
#### 取消任务
```dart
final deviceId = targetDevice?.deviceId ?? '';
context.read<DeviceTaskCubit>().cancelTask(deviceId);
```
#### 暂停任务
```dart
final deviceId = targetDevice?.deviceId ?? '';
context.read<DeviceTaskCubit>().pauseTask(deviceId);
```
#### 恢复任务
```dart
final deviceId = targetDevice?.deviceId ?? '';
context.read<DeviceTaskCubit>().recoveryTask(deviceId);
```
### 5. 手动更新 taskId(选择新航线时)
```dart
// 如果需要在选择航线时手动设置 taskId
context.read<DeviceTaskCubit>().updateCurrentTaskId(newTaskId);
```
### 6. 清除当前任务
```dart
// 退出页面或切换设备时清除
context.read<DeviceTaskCubit>().clearCurrentTask();
```
## 注意事项
1. **自动获取用户信息和场站ID**
- Cubit 内部会自动从 AppUserCubit 和 SiteCubit 获取所需参数
- 无需手动传递 userId、orgId、siteId
2. **统一错误处理**
- 所有错误都会通过 ErrorHandler 转换为友好提示
- 不会显示原始错误信息(如 HTTP 404、连接超时等)
3. **taskId 全局管理**
- fetchAndFilterTask 会自动过滤并保存当前设备的 taskId
- 所有操作接口都会使用这个全局保存的 taskId
4. **状态监听**
- operationType 可以区分当前正在进行的操作类型
- isLoading 表示是否正在执行网络请求
## 完整示例
```dart
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秒后)
- 页面不会崩溃
示例错误提示:
- "网络连接超时,请检查网络设置"
- "登录已过期,请重新登录"
- "操作失败,请稍后重试"
- "未知错误,请稍后重试"