332 lines
11 KiB
Dart
332 lines
11 KiB
Dart
import 'package:flutter/rendering.dart';
|
||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/entities/device_entity.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/repositories/device_repository.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/usecases/generate_path_usecase.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/usecases/get_user_device_usecase.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/usecases/save_work_record_usecase.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/usecases/select_work_record_usecase.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/usecases/unbind_device_usecase.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/usecases/update_devicename_usecase.dart';
|
||
|
||
import '../../data/models/device_work_area_param_model.dart';
|
||
import '../../domain/usecases/delete_work_record_usecase.dart';
|
||
import '../../domain/usecases/get_device_location_usecase.dart';
|
||
import '../../domain/usecases/get_work_record_usecase.dart';
|
||
import 'devices_state.dart';
|
||
|
||
class DevicesCubit extends Cubit<DevicesState> {
|
||
final GetUserDeviceUseCase _getUserDeviceUseCase;
|
||
final GetDeviceLocationUseCase _getDeviceLocationUseCase;
|
||
final DeviceRepository repository;
|
||
final GetWorkRecordUseCase _getWorkRecordUseCase;
|
||
final DeleteWorkRecordUseCase _deleteWorkRecordUseCase;
|
||
final UnbindDeviceUseCase _unbindDeviceUseCase;
|
||
final UpdateDevicenameUsecase _updateDevicename;
|
||
final SelectWorkRecordUseCase _selectWorkRecordUseCase;
|
||
final SaveWorkRecordUseCase _saveWorkRecordUseCase;
|
||
final GeneratePathUseCase _generatePathUseCase;
|
||
|
||
DevicesCubit(
|
||
this.repository,
|
||
this._getUserDeviceUseCase,
|
||
this._getDeviceLocationUseCase,
|
||
this._getWorkRecordUseCase,
|
||
this._deleteWorkRecordUseCase,
|
||
this._unbindDeviceUseCase,
|
||
this._updateDevicename,
|
||
this._selectWorkRecordUseCase,
|
||
this._saveWorkRecordUseCase,
|
||
this._generatePathUseCase
|
||
) : super(const DevicesState());
|
||
|
||
Future<void> unbindDevice(String deviceId, String deviceName) async {
|
||
emit(
|
||
state.copyWith(
|
||
isLoading: true,
|
||
errorMessage: '',
|
||
operationType: DeviceOperationType.unbind,
|
||
),
|
||
);
|
||
|
||
try {
|
||
final params = UnbindDeviceParams(deviceId, deviceName);
|
||
final result = await _unbindDeviceUseCase.call(params);
|
||
|
||
result.fold(
|
||
(failure) => emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
errorMessage: failure.message ?? '解绑设备失败',
|
||
operationType: DeviceOperationType.none, // 操作结束重置
|
||
),
|
||
),
|
||
(successCode) {
|
||
// 核心修复: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?.deviceName == deviceId
|
||
? null
|
||
: state.selectedDevice,
|
||
errorMessage: '',
|
||
operationType: DeviceOperationType.none,
|
||
),
|
||
);
|
||
} else {
|
||
emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
errorMessage: '解绑失败:状态码 $successCode',
|
||
operationType: DeviceOperationType.none,
|
||
),
|
||
);
|
||
}
|
||
},
|
||
);
|
||
} catch (e) {
|
||
emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
errorMessage: '解绑异常:${e.toString()}',
|
||
operationType: DeviceOperationType.none,
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
Future<void> updateDeviceName(String deviceId, String deviceName) async {
|
||
emit(
|
||
state.copyWith(
|
||
isLoading: true,
|
||
errorMessage: '',
|
||
operationType: DeviceOperationType.updateName,
|
||
),
|
||
);
|
||
|
||
try {
|
||
final params = UpdateDevicenameParams(deviceId, deviceName);
|
||
final result = await _updateDevicename.call(params);
|
||
|
||
result.fold(
|
||
(failure) => emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
errorMessage: failure.message ?? '更新设备名称失败',
|
||
operationType: DeviceOperationType.none,
|
||
),
|
||
),
|
||
(successCode) {
|
||
// 核心修复:int 转 bool 条件判断
|
||
print('更新设备名称结果代码: $successCode'); // 调试输出结果代码
|
||
final isSuccess = successCode == 1; // 显式转为 bool
|
||
if (isSuccess) {
|
||
//final updatedDevices = state.devices?.map((device) {
|
||
// return device.deviceName == deviceId ? device.copyWith(deviceName: deviceName) : device;
|
||
//}).toList();
|
||
|
||
emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
//devices: updatedDevices,
|
||
//selectedDevice: state.selectedDevice?.deviceName == deviceId ? state.selectedDevice?.copyWith(deviceName: deviceName) : state.selectedDevice,
|
||
errorMessage: '',
|
||
operationType: DeviceOperationType.none,
|
||
),
|
||
);
|
||
} else {
|
||
emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
errorMessage: '更新设备名称失败:状态码 $successCode',
|
||
operationType: DeviceOperationType.none,
|
||
),
|
||
);
|
||
}
|
||
},
|
||
);
|
||
} catch (e) {
|
||
emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
errorMessage: '更新设备名称异常:${e.toString()}',
|
||
operationType: DeviceOperationType.none,
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
// 获取所有设备列表
|
||
Future<void> fetchAllDevices(String username) async {
|
||
emit(state.copyWith(isLoading: true));
|
||
try {
|
||
// 网络请求获取列表
|
||
var resultEither = await _getUserDeviceUseCase.call(
|
||
GetUserDeviceParams(username),
|
||
);
|
||
|
||
resultEither.fold(
|
||
(failure) => emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
errorMessage: failure.message, //
|
||
),
|
||
),
|
||
(deviceList) {
|
||
print("设备列表:$deviceList"); // 调试输出
|
||
emit(
|
||
state.copyWith(
|
||
devices: deviceList,
|
||
selectedDevice: deviceList.isNotEmpty ? deviceList.first : null,
|
||
isLoading: false,
|
||
),
|
||
);
|
||
},
|
||
);
|
||
} catch (e) {
|
||
emit(state.copyWith(isLoading: false, errorMessage: e.toString()));
|
||
}
|
||
}
|
||
|
||
// 切换当前选中的设备
|
||
void selectDevice(DeviceEntity device) {
|
||
emit(state.copyWith(selectedDevice: device));
|
||
}
|
||
|
||
// 更新单个设备的状态(例如从 Tcp 收到实时电量更新)
|
||
void updateDeviceStatus(DeviceEntity updatedDevice) {
|
||
final newList = state.devices.map((d) {
|
||
return d.deviceName == updatedDevice.deviceName ? updatedDevice : d;
|
||
}).toList();
|
||
|
||
// 如果更新的是当前选中的设备,也要同步更新 selectedDevice
|
||
final newSelected =
|
||
state.selectedDevice?.deviceName == updatedDevice.deviceName
|
||
? updatedDevice
|
||
: state.selectedDevice;
|
||
|
||
emit(state.copyWith(devices: newList, selectedDevice: newSelected));
|
||
}
|
||
|
||
/// 切换设备
|
||
Future<void> switchDevice(DeviceEntity device) async {
|
||
// 保持现有列表,只改 loading
|
||
emit(state.copyWith(isLoading: true));
|
||
|
||
final result = await repository.switchDevice("app", device.deviceName);
|
||
|
||
result.fold((l) {
|
||
emit(state.copyWith(isLoading: false, errorMessage: l.message));
|
||
selectDevice(device);
|
||
}, (r) => emit(state.copyWith(isLoading: false, selectedDevice: device)));
|
||
}
|
||
|
||
/// 获取设备位置
|
||
Future<void> getDeviceLocation(DeviceEntity device) async {
|
||
emit(state.copyWith(isLoading: true));
|
||
final result = await _getDeviceLocationUseCase.call(device.deviceName);
|
||
result.fold(
|
||
(failure) =>
|
||
emit(state.copyWith(isLoading: false, errorMessage: failure.message)),
|
||
(location) => emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
deviceLatitude: location.latitude,
|
||
deviceLongitude: location.longitude,
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
///获取记录
|
||
Future<void> loadWorkRecords(String userId) async {
|
||
emit(state.copyWith(isLoading: true));
|
||
final result = await _getWorkRecordUseCase(userId);
|
||
result.fold(
|
||
(failure) =>
|
||
emit(state.copyWith(isLoading: false, errorMessage: failure.message)),
|
||
(records) => emit(state.copyWith(isLoading: false, workRecords: records)),
|
||
);
|
||
}
|
||
|
||
/// 删除工作记录
|
||
Future<void> deleteWorkRecord(String workName) async {
|
||
emit(state.copyWith(isLoading: true));
|
||
final result = await _deleteWorkRecordUseCase(workName);
|
||
result.fold(
|
||
(failure) =>
|
||
emit(state.copyWith(isLoading: false, errorMessage: failure.message)),
|
||
(_) => emit(
|
||
state.copyWith(
|
||
isLoading: false,
|
||
workRecords: state.workRecords
|
||
?.where((record) => record != workName)
|
||
.toList(),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
/// 加载指定作业名的路径数据
|
||
Future<void> loadSelectedPath(String workName) async {
|
||
emit(state.copyWith(isLoading: true));
|
||
try {
|
||
final result = await _selectWorkRecordUseCase.call(workName);
|
||
result.fold(
|
||
(failure) => emit(
|
||
state.copyWith(isLoading: false, errorMessage: failure.message),
|
||
),
|
||
(data) => emit(state.copyWith(isLoading: false, pathData: data)),
|
||
);
|
||
} catch (e) {
|
||
emit(state.copyWith(isLoading: false, errorMessage: e.toString()));
|
||
}
|
||
}
|
||
/// 保存路径数据
|
||
Future<void> saveWorkRecord(String workName, String userId, String jsonData) async {
|
||
emit(state.copyWith(isLoading: true));
|
||
final result = await _saveWorkRecordUseCase.call(
|
||
workName: workName,
|
||
userId: userId,
|
||
jsonData: jsonData,
|
||
);
|
||
result.fold(
|
||
(failure) => emit(state.copyWith(isLoading: false, errorMessage: failure.message)),
|
||
(data) => emit(state.copyWith(isLoading: false)),
|
||
);
|
||
}
|
||
/// generatePath
|
||
Future<void> generatePath({
|
||
required ReferencePoint reference,
|
||
required int heading,
|
||
required OuterBoundary outer,
|
||
required List<HoleBoundary> holes,
|
||
required int workType,
|
||
}) async {
|
||
emit(state.copyWith(isLoading: true));
|
||
final result = await _generatePathUseCase.execute(
|
||
reference: reference,
|
||
heading: heading,
|
||
outer: outer,
|
||
holes: holes,
|
||
workType: workType,
|
||
);
|
||
|
||
result.fold(
|
||
(failure) => emit(state.copyWith(errorMessage: failure.message)),
|
||
(pathData) => emit(state.copyWith(generatedPath: pathData)),
|
||
);
|
||
|
||
}
|
||
|
||
|
||
|
||
}
|