From bcaebade9a499aec7e158acd1e50b574fc0ff69c Mon Sep 17 00:00:00 2001 From: mmc <1556375442@qq.com> Date: Sat, 28 Feb 2026 17:06:14 +0800 Subject: [PATCH] =?UTF-8?q?=E7=82=B9=E5=87=BB=E5=AE=8C=E6=88=90=E7=94=9F?= =?UTF-8?q?=E6=88=90=E8=B7=AF=E5=BE=84=20=20=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/device_add_path_point_model.dart | 18 +++-- .../generate_path_repository_Impl.dart | 76 ++++++------------- .../presentation/bloc/devices_state.dart | 3 + .../widgets/map/testmap_pages.dart | 21 ++--- 4 files changed, 49 insertions(+), 69 deletions(-) diff --git a/lib/features/devices/data/models/device_add_path_point_model.dart b/lib/features/devices/data/models/device_add_path_point_model.dart index 00ab59b1..30ecbc50 100644 --- a/lib/features/devices/data/models/device_add_path_point_model.dart +++ b/lib/features/devices/data/models/device_add_path_point_model.dart @@ -4,13 +4,15 @@ class DeviceAddPathPointModel { DeviceAddPathPointModel({required this.latitude, required this.longitude}); - Map toJson() => { - 'latitude': latitude, - 'longitude': longitude, - }; + Map toJson() => {'lat': latitude.toString(), 'lon': longitude.toString()}; - factory DeviceAddPathPointModel.fromJson(Map json) => DeviceAddPathPointModel( - latitude: json['latitude'], - longitude: json['longitude'], - ); + factory DeviceAddPathPointModel.fromJson(Map json) { + return DeviceAddPathPointModel( + latitude: double.parse((json['lat'] ?? json['latitude']).toString()), + longitude: double.parse((json['lon'] ?? json['longitude']).toString()), + ); + } + + @override + String toString() => '{lat: ${latitude.toString()}, lon: ${longitude.toString()}}'; } diff --git a/lib/features/devices/data/repositories/generate_path_repository_Impl.dart b/lib/features/devices/data/repositories/generate_path_repository_Impl.dart index 1a24dbb1..7e75745d 100644 --- a/lib/features/devices/data/repositories/generate_path_repository_Impl.dart +++ b/lib/features/devices/data/repositories/generate_path_repository_Impl.dart @@ -10,8 +10,8 @@ import '../models/device_add_path_point_model.dart'; import '../models/device_work_area_param_model.dart'; class PathRepositoryImpl implements PathRepository { - /* final String baseUrl = 'https://serviceri.satabot.com'; // 后端接口地址*/ - /* final UserStorage localTokenStorage; + /* final String baseUrl = 'https://serviceri.satabot.com'; // 后端接口地址*/ + /* final UserStorage localTokenStorage; PathRepositoryImpl({ required this.localTokenStorage, // 👈 关键:注入依赖 });*/ @@ -23,7 +23,6 @@ class PathRepositoryImpl implements PathRepository { required OuterBoundary outer, required List holes, required int workType, - }) async { final url = Uri.parse('https://servicepathplan.satabot.com/api/path'); // ✅ 直接从 GetIt 获取 UserStorage(无需构造函数传参) @@ -33,10 +32,7 @@ class PathRepositoryImpl implements PathRepository { if (token == null) throw Exception('请先登录'); // ✅ 设置带 token 的 headers - final headers = { - 'Content-Type': 'application/json', - 'Authorization': token, - }; + final headers = {'Content-Type': 'application/json', 'Authorization': token}; final body = jsonEncode({ 'reference': reference.toJson(), @@ -51,8 +47,10 @@ class PathRepositoryImpl implements PathRepository { final response = await http.post(url, headers: headers, body: body); print('响应体: ${response.body}'); final decoded = jsonDecode(response.body) as Map; - if (decoded['code'] == 200) { - final pathJson = decoded['path']; + print('解码后的响应: $decoded'); // 调试输出解码后的响应 + if (decoded['success'] == true) { + final pathJson = decoded['data']?['path']; + print('路径数据: $pathJson'); // 调试输出路径数据 if (pathJson == null) { throw Exception('API returned null for "path"'); } @@ -60,6 +58,8 @@ class PathRepositoryImpl implements PathRepository { throw Exception('Expected "path" to be a List, but got ${pathJson.runtimeType}'); } final List jsonData = pathJson; + print('路径数据1111: $jsonData'); // 调试输出路径数据 + print('路径数据11112222: ${jsonData.map((item) => DeviceAddPathPointModel.fromJson(item)).toList()}'); return jsonData.map((item) => DeviceAddPathPointModel.fromJson(item)).toList(); } else { throw Exception('Failed to load path: ${response.statusCode}'); @@ -71,18 +71,10 @@ class PathRepositoryImpl implements PathRepository { // 保存工作记录 @override - Future> saveWorkRecord({ - required String workName, - required String userId, - required String jsonData, - }) async { + Future> saveWorkRecord({required String workName, required String userId, required String jsonData}) async { final url = Uri.parse('https://serviceri.satabot.com/iot/workRecord/add'); final headers = {'Content-Type': 'application/json'}; - final body = jsonEncode({ - 'workName': workName, - 'userId': userId, - 'jsonData': jsonData, - }); + final body = jsonEncode({'workName': workName, 'userId': userId, 'jsonData': jsonData}); try { final response = await http.post(url, headers: headers, body: body); @@ -98,9 +90,7 @@ class PathRepositoryImpl implements PathRepository { } @override - Future>> getWorkRecord({ - required String userId, - }) async { + Future>> getWorkRecord({required String userId}) async { final timestamp = DateTime.now().millisecondsSinceEpoch; final url = Uri.parse( 'https://serviceri.satabot.com/iot/workRecord/selectByUserId', @@ -116,9 +106,7 @@ class PathRepositoryImpl implements PathRepository { throw Exception('API error: ${data['msg'] ?? 'Unknown'}'); } } else { - throw Exception( - 'HTTP ${response.statusCode}: ${response.reasonPhrase}', - ); + throw Exception('HTTP ${response.statusCode}: ${response.reasonPhrase}'); } } catch (e) { throw Exception('Network error in getWorkRecord: $e'); @@ -126,16 +114,11 @@ class PathRepositoryImpl implements PathRepository { } @override - Future> deleteWorkRecord({ - required String workName, - }) async { + Future> deleteWorkRecord({required String workName}) async { final timestamp = DateTime.now().millisecondsSinceEpoch; - final url = - Uri.parse( - 'https://serviceri.satabot.com/iot/workRecord/deleteByWorkName', - ).replace( - queryParameters: {'workName': workName, '_t': timestamp.toString()}, - ); + final url = Uri.parse( + 'https://serviceri.satabot.com/iot/workRecord/deleteByWorkName', + ).replace(queryParameters: {'workName': workName, '_t': timestamp.toString()}); try { final response = await http.get(url); @@ -144,9 +127,7 @@ class PathRepositoryImpl implements PathRepository { if (response.statusCode == 200 && data['code'] == 200) { return data; // 返回 {"code": 200, "msg": "删除成功"} } else { - throw Exception( - 'Delete failed: ${data['msg'] ?? response.reasonPhrase}', - ); + throw Exception('Delete failed: ${data['msg'] ?? response.reasonPhrase}'); } } catch (e) { throw Exception('Network error in deleteWorkRecord: $e'); @@ -155,16 +136,11 @@ class PathRepositoryImpl implements PathRepository { /// 选择工作记录 @override - Future>> selectWorkRecordByName({ - required String workName, - }) async { + Future>> selectWorkRecordByName({required String workName}) async { final timestamp = DateTime.now().millisecondsSinceEpoch; - final url = - Uri.parse( - 'https://serviceri.satabot.com/iot/workRecord/selectByWorkName', - ).replace( - queryParameters: {'workName': workName, '_t': timestamp.toString()}, - ); + final url = Uri.parse( + 'https://serviceri.satabot.com/iot/workRecord/selectByWorkName', + ).replace(queryParameters: {'workName': workName, '_t': timestamp.toString()}); try { final response = await http.get(url); @@ -188,9 +164,7 @@ class PathRepositoryImpl implements PathRepository { } else if (rawData is Map) { records = [Map.from(rawData)]; } else { - throw Exception( - 'Unexpected data type for "data": ${rawData.runtimeType}', - ); + throw Exception('Unexpected data type for "data": ${rawData.runtimeType}'); } return records; @@ -198,9 +172,7 @@ class PathRepositoryImpl implements PathRepository { throw Exception('API error: ${data['msg'] ?? 'Unknown'}'); } } else { - throw Exception( - 'HTTP ${response.statusCode}: ${response.reasonPhrase}', - ); + throw Exception('HTTP ${response.statusCode}: ${response.reasonPhrase}'); } } catch (e) { throw Exception('Network error in selectWorkRecordByName: $e'); diff --git a/lib/features/devices/presentation/bloc/devices_state.dart b/lib/features/devices/presentation/bloc/devices_state.dart index 3959e3db..ccb868f9 100644 --- a/lib/features/devices/presentation/bloc/devices_state.dart +++ b/lib/features/devices/presentation/bloc/devices_state.dart @@ -59,6 +59,7 @@ class DevicesState extends Equatable { pathData: pathData ?? this.pathData, workRecords: workRecords ?? this.workRecords, operationType: operationType ?? this.operationType, // 更新操作类型 + generatedPath: generatedPath ?? this.generatedPath, // 更新生成的路径数据 ); } @@ -69,5 +70,7 @@ class DevicesState extends Equatable { deviceLongitude, workRecords, pathData, + operationType, + generatedPath, ]; } diff --git a/lib/features/home/presentation/widgets/map/testmap_pages.dart b/lib/features/home/presentation/widgets/map/testmap_pages.dart index 808b89ed..282905ee 100644 --- a/lib/features/home/presentation/widgets/map/testmap_pages.dart +++ b/lib/features/home/presentation/widgets/map/testmap_pages.dart @@ -11,6 +11,7 @@ import 'package:maibu_satabot_v2/core/app/app_user_cubit.dart'; import 'package:maibu_satabot_v2/core/di/injection.dart'; import 'package:maibu_satabot_v2/core/network/net_message_dispatcher.dart'; import 'package:maibu_satabot_v2/core/network/protocol_decoder.dart'; +import 'package:maibu_satabot_v2/features/devices/data/models/device_add_path_point_model.dart' as work_area_model; import 'package:maibu_satabot_v2/features/devices/data/models/device_work_area_param_model.dart' as work_area_model; import 'package:maibu_satabot_v2/features/devices/data/repositories/generate_path_repository_Impl.dart'; import 'package:maibu_satabot_v2/features/devices/domain/usecases/get_work_record_usecase.dart'; @@ -1091,6 +1092,7 @@ class _MapPageEnterpriseState extends State { // 4. 获取生成结果并处理 final cubitState = context.read().state; + print('${cubitState.generatedPath},路径生成结果'); if (cubitState.errorMessage != null) { // 生成失败 ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('路径生成失败:${cubitState.errorMessage}'), backgroundColor: Colors.red)); @@ -1100,21 +1102,22 @@ class _MapPageEnterpriseState extends State { debugPrint('生成的路径数据:${cubitState.generatedPath}'); // 可选:将生成的路径转换为地图可显示的坐标(WGS84 → GCJ02) - if (cubitState.generatedPath is List) { + if (cubitState.generatedPath is List) { setState(() { - // 关键:生成的路径是 WGS84,需转回 GCJ02 才能在高德地图正确显示 - gcjPathPoints = (cubitState.generatedPath as List).map((point) { - // 先取 WGS84 坐标 - double wgs84Lat = safeToDouble(point['lat']) ?? 0.0; - double wgs84Lon = safeToDouble(point['lon']) ?? 0.0; - // 转换为 GCJ02 + // 先将 List 转换为 List + final pathList = cubitState.generatedPath as List; + final typedPathList = pathList.whereType().toList(); + + // 然后使用 .lat 和 .lon 属性访问 + gcjPathPoints = typedPathList.map((point) { + double wgs84Lat = point.latitude; + double wgs84Lon = point.longitude; final gcjPoint = wgs84ToGcj02(wgs84Lat, wgs84Lon); return LatLng(gcjPoint.latitude, gcjPoint.longitude); }).toList(); - // 外边界也转回 GCJ02 显示(可选,保持和地图坐标系一致) + gcjOuterPoints = _markedPoints; }); - // 移动地图到生成的路径中心 moveMapToPointsCenter(gcjPathPoints); } }