diff --git a/lib/core/consts/http_api_consts.dart b/lib/core/consts/http_api_consts.dart index b304ce23..54c3010b 100644 --- a/lib/core/consts/http_api_consts.dart +++ b/lib/core/consts/http_api_consts.dart @@ -14,4 +14,11 @@ class HttpApiConsts { static const String unbindDevice = "$baseUrl/forward/device/unbind"; // 切换设备 static const String switchDevice = "$baseUrl/forward/device/switchDevice"; + + + // 获取设备位置 + static const String getDeviceLocation = "$baseUrl/iot/device/userDevice"; + + + } diff --git a/lib/features/devices/data/datasources/device_http_datasource.dart b/lib/features/devices/data/datasources/device_http_datasource.dart index f11ae76e..23c9ea9e 100644 --- a/lib/features/devices/data/datasources/device_http_datasource.dart +++ b/lib/features/devices/data/datasources/device_http_datasource.dart @@ -5,4 +5,7 @@ abstract class DeviceHttpDatasource { Future bindDevice(String deviceId, String deviceAlias); Future unbindDevice(String deviceId); Future switchDevice(String platform, String deviceId); + + Future getDeviceLocation(String username) async {} + } diff --git a/lib/features/devices/data/datasources/impl/device_http_datasource_impl.dart b/lib/features/devices/data/datasources/impl/device_http_datasource_impl.dart index 334089cf..ea5fc9ae 100644 --- a/lib/features/devices/data/datasources/impl/device_http_datasource_impl.dart +++ b/lib/features/devices/data/datasources/impl/device_http_datasource_impl.dart @@ -78,4 +78,38 @@ class DeviceHttpDatasourceImpl implements DeviceHttpDatasource { // TODO: implement unbindDevice throw UnimplementedError(); } + + @override + Future getDeviceLocation(String username) async { + // TODO: implement getDeviceLocation + try { + // 发起 GET 请求 + final response = await dio.get( + 'https://serviceri.satabot.com/iot/device/userDevice', + queryParameters: {'tenantName': username}, + // options: Options( + // headers: { + // 'Content-Type': 'application/json', + // 'Authorization': 'Bearer ${await _getToken()}', // 获取 Token + // }, + // ), + ); + + // 检查响应状态码 + if (response.statusCode == 200) { + final data = response.data; + if (data['code'] == 200) { + return data['data']; // 返回设备数据 + } else { + throw Exception(data['msg'] ?? '业务异常'); + } + } else { + throw Exception('网络请求失败: ${response.statusCode}'); + } + } catch (e) { + throw Exception('获取设备位置失败: $e'); + } + + throw UnimplementedError(); + } } diff --git a/lib/features/devices/data/repositories/device_repository_impl.dart b/lib/features/devices/data/repositories/device_repository_impl.dart index 652da73b..9b44610c 100644 --- a/lib/features/devices/data/repositories/device_repository_impl.dart +++ b/lib/features/devices/data/repositories/device_repository_impl.dart @@ -2,6 +2,7 @@ import 'package:dio/dio.dart'; import 'package:fpdart/src/either.dart'; import 'package:maibu_satabot_v2/features/devices/data/datasources/device_http_datasource.dart'; import 'package:maibu_satabot_v2/features/devices/domain/entities/device_entity.dart'; +import 'package:maibu_satabot_v2/features/devices/domain/entities/device_location_entity.dart'; import 'package:maibu_satabot_v2/features/devices/domain/errors/device_failure.dart'; import '../../domain/repositories/device_repository.dart'; @@ -69,4 +70,12 @@ class DeviceRepositoryImpl implements DeviceRepository { return Left(DeviceFailure(cleanMessage)); } } + // TODO: implement switchDevice 实现获取设备的列表 + @override + Future>getDeviceLocation(String username) async { + // TODO: implement getDeviceLocation + var result = await _deviceHttpDatasource.getDeviceLocation(username); + return Right(result); + // throw UnimplementedError(); + } } diff --git a/lib/features/devices/domain/entities/device_location_entity.dart b/lib/features/devices/domain/entities/device_location_entity.dart new file mode 100644 index 00000000..953b3960 --- /dev/null +++ b/lib/features/devices/domain/entities/device_location_entity.dart @@ -0,0 +1,11 @@ +class DeviceLocationEntity { + final String deviceName; + final double latitude; // 新增字段 + final double longitude; // 新增字段 + + DeviceLocationEntity({ + required this.deviceName, + required this.latitude, + required this.longitude, + }); +} diff --git a/lib/features/devices/domain/repositories/device_hostrity_work_repository.dart b/lib/features/devices/domain/repositories/device_hostrity_work_repository.dart index 41be2bbd..290db2ae 100644 --- a/lib/features/devices/domain/repositories/device_hostrity_work_repository.dart +++ b/lib/features/devices/domain/repositories/device_hostrity_work_repository.dart @@ -11,4 +11,6 @@ abstract class DeviceHostrityWorkRepositoryRepository { required String deviceId, }); + + } diff --git a/lib/features/devices/domain/repositories/device_repository.dart b/lib/features/devices/domain/repositories/device_repository.dart index c963e6d0..a357a5c4 100644 --- a/lib/features/devices/domain/repositories/device_repository.dart +++ b/lib/features/devices/domain/repositories/device_repository.dart @@ -1,5 +1,6 @@ import 'package:fpdart/fpdart.dart'; import 'package:maibu_satabot_v2/features/devices/domain/entities/device_entity.dart'; +import 'package:maibu_satabot_v2/features/devices/domain/entities/device_location_entity.dart'; import 'package:maibu_satabot_v2/features/devices/domain/errors/device_failure.dart'; abstract class DeviceRepository { @@ -15,4 +16,6 @@ abstract class DeviceRepository { String platform, String deviceId, ); + // 获取设备位置 + Future> getDeviceLocation(String username); } diff --git a/lib/features/devices/domain/usecases/get_device_location_usecase.dart b/lib/features/devices/domain/usecases/get_device_location_usecase.dart new file mode 100644 index 00000000..897878db --- /dev/null +++ b/lib/features/devices/domain/usecases/get_device_location_usecase.dart @@ -0,0 +1,16 @@ +// features/devices/domain/usecases/get_device_location_usecase.dart +import 'package:fpdart/fpdart.dart'; +import 'package:maibu_satabot_v2/features/devices/domain/entities/device_entity.dart'; +import 'package:maibu_satabot_v2/features/devices/domain/entities/device_location_entity.dart'; +import 'package:maibu_satabot_v2/features/devices/domain/repositories/device_repository.dart'; +import 'package:maibu_satabot_v2/features/devices/domain/errors/device_failure.dart'; + +class GetDeviceLocationUseCase { + final DeviceRepository repository; + + GetDeviceLocationUseCase(this.repository); + //获取设备的位置 + Future> call(String username) async { + return await repository.getDeviceLocation(username); + } +} diff --git a/lib/features/devices/presentation/bloc/devices_cubit.dart b/lib/features/devices/presentation/bloc/devices_cubit.dart index c29bf8ea..5e428a00 100644 --- a/lib/features/devices/presentation/bloc/devices_cubit.dart +++ b/lib/features/devices/presentation/bloc/devices_cubit.dart @@ -3,21 +3,22 @@ import 'package:maibu_satabot_v2/features/devices/domain/entities/device_entity. import 'package:maibu_satabot_v2/features/devices/domain/repositories/device_repository.dart'; import 'package:maibu_satabot_v2/features/devices/domain/usecases/get_user_device_usecase.dart'; +import '../../domain/usecases/get_device_location_usecase.dart'; import 'devices_state.dart'; class DevicesCubit extends Cubit { final GetUserDeviceUseCase _getUserDeviceUseCase; - + final GetDeviceLocationUseCase _getDeviceLocationUseCase; final DeviceRepository repository; - DevicesCubit(this.repository, this._getUserDeviceUseCase) + DevicesCubit(this.repository, this._getUserDeviceUseCase, this._getDeviceLocationUseCase) : super(const DevicesState()); // 获取所有设备列表 Future fetchAllDevices(String username) async { emit(state.copyWith(isLoading: true)); try { - // 模拟网络请求获取列表 + // 网络请求获取列表 var resultEither = await _getUserDeviceUseCase.call( GetUserDeviceParams(username), ); @@ -63,7 +64,7 @@ class DevicesCubit extends Cubit { emit(state.copyWith(devices: newList, selectedDevice: newSelected)); } - + // 切换设备 Future switchDevice(DeviceEntity device) async { // 保持现有列表,只改 loading emit(state.copyWith(isLoading: true)); @@ -75,4 +76,19 @@ class DevicesCubit extends Cubit { selectDevice(device); }, (r) => emit(state.copyWith(isLoading: false, selectedDevice: device))); } + // 获取设备位置 + Future 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, + )), + ); + } + + } diff --git a/lib/features/devices/presentation/bloc/devices_state.dart b/lib/features/devices/presentation/bloc/devices_state.dart index 331f243c..04a848e4 100644 --- a/lib/features/devices/presentation/bloc/devices_state.dart +++ b/lib/features/devices/presentation/bloc/devices_state.dart @@ -6,12 +6,16 @@ class DevicesState extends Equatable { final DeviceEntity? selectedDevice; // 当前主界面选中的/操作的设备 final bool isLoading; // 是否正在加载 final String? errorMessage; // 错误信息 + final double? deviceLatitude; // 新增字段 + final double? deviceLongitude; // 新增字段 const DevicesState({ this.devices = const [], this.selectedDevice, this.isLoading = false, this.errorMessage, + this.deviceLatitude, + this.deviceLongitude, }); // 使用 copyWith 方便局部更新状态 @@ -20,15 +24,23 @@ class DevicesState extends Equatable { DeviceEntity? selectedDevice, bool? isLoading, String? errorMessage, + double? deviceLatitude, + double? deviceLongitude, }) { return DevicesState( devices: devices ?? this.devices, selectedDevice: selectedDevice ?? this.selectedDevice, isLoading: isLoading ?? this.isLoading, errorMessage: errorMessage, // 错误信息通常每次更新都要重新赋值或清空 + deviceLatitude: deviceLatitude ?? this.deviceLatitude, + deviceLongitude: deviceLongitude ?? this.deviceLongitude, ); } @override - List get props => [devices, selectedDevice, isLoading, errorMessage]; + List get props => [devices, selectedDevice, isLoading, + errorMessage, + deviceLatitude, + deviceLongitude, + ]; }