优化和路径规划新适配

This commit is contained in:
2026-07-11 16:46:53 +08:00
parent 2124f3bc02
commit 1a4d0aedfd
43 changed files with 2454 additions and 685 deletions

View File

@@ -34,7 +34,7 @@ class DeviceHttpDatasourceImpl implements DeviceHttpDatasource {
logger.logWithLevel(
'用户点击bindDevice方法API 请求开始',
level: 'INFO',
data: {'url': 'https://serviceri.satabot.com/iot/device/bindDevice'},
data: {'url': 'http://1.95.137.212:8081/iot/device/bindDevice'},
);
var response = await dio.post(
HttpApiConsts.bindDevice,
@@ -44,7 +44,7 @@ class DeviceHttpDatasourceImpl implements DeviceHttpDatasource {
'请求详细参数',
level: 'DEBUG',
data: {
'url': 'https://serviceri.satabot.com/iot/device/bindDevice',
'url': 'http://1.95.137.212:8081/iot/device/bindDevice',
'deviceId': deviceId,
'deviceAlias': deviceAlias,
},
@@ -122,7 +122,7 @@ class DeviceHttpDatasourceImpl implements DeviceHttpDatasource {
logger.logWithLevel(
'用户点击switchDevice方法API 请求开始',
level: 'INFO',
data: {'url': 'https://serviceri.satabot.com/iot/device/switchDevice'},
data: {'url': 'http://1.95.137.212:8081/iot/device/switchDevice'},
);
var response = await dio.post(
HttpApiConsts.switchDevice,
@@ -138,7 +138,7 @@ class DeviceHttpDatasourceImpl implements DeviceHttpDatasource {
'请求详细参数',
level: 'DEBUG',
data: {
'url': 'https://serviceri.satabot.com/iot/device/switchDevice',
'url': 'http://1.95.137.212:8081/iot/device/switchDevice',
'platform': platform,
'deviceId': deviceId,
},
@@ -219,12 +219,12 @@ class DeviceHttpDatasourceImpl implements DeviceHttpDatasource {
'请求详细参数',
level: 'DEBUG',
data: {
'url': 'https://serviceri.satabot.com/iot/device/userDevice',
'url': 'http://1.95.137.212:8081/iot/device/userDevice',
'tenantName': deviceame,
},
);
final response = await dio.get(
'https://serviceri.satabot.com/iot/device/userDevice',
'http://1.95.137.212:8081/iot/device/userDevice',
queryParameters: {'tenantName': deviceame},
// options: Options(
// headers: {

View File

@@ -21,66 +21,83 @@ class PathHttpDatasourceImpl implements PathHttpDatasource {
@override
Future<List<DeviceAddPathPointModel>> generatePathRaw({required Map<String, dynamic> body}) async {
try {
_logger.logWithLevel( '请求体类型:${body.runtimeType}',level: 'INFO');
_logger.logWithLevel( '璇锋眰浣撶被鍨嬶細${body.runtimeType}',level: 'INFO');
// 2. 格式化打印JSON(带缩进,清晰展示嵌套结构)
// 2. 鏍煎紡鍖栨墦鍗癑SON锛堝甫缂╄繘锛屾竻鏅板睍绀哄祵濂楃粨鏋勶級
final jsonString = const JsonEncoder.withIndent(' ').convert(body);
final _jsonString = jsonEncode(body);
// print('完整JSON请求体:\n$jsonString');
_logger.logWithLevel( '请求体:$_jsonString',level: 'INFO');
// print('瀹屾暣JSON璇锋眰浣擄細\n$jsonString');
_logger.logWithLevel( '璇锋眰浣擄細$_jsonString',level: 'INFO');
// 3. 可选:单独打印holes的JSON(重点关注)
// 3. 鍙€夛細鍗曠嫭鎵撳嵃holes鐨凧SON锛堥噸鐐瑰叧娉級
//final holesJson = body['holes'] as List;
//print('=== 单独打印holes的JSON ===');
//print('=== 鍗曠嫭鎵撳嵃holes鐨凧SON ===');
//if (holesJson.isEmpty) {
// print('holes 为空数组');
// print('holes 涓虹┖鏁扮粍');
//} else {
// for (int i = 0; i < holesJson.length; i++) {
// print('第${i + 1}组hole:\n${const JsonEncoder.withIndent(' ').convert(holesJson[i])}');
// print('绗?{i + 1}缁刪ole锛歕n${const JsonEncoder.withIndent(' ').convert(holesJson[i])}');
// }
//}
} catch (e) {
// 防止JSON序列化失败导致崩溃
//print('打印请求体失败:$e');
_logger.logWithLevel( '打印请求体失败:$e',level: 'ERROR');
// 降级打印原始body(虽然格式乱,但能看基础数据)
// print('原始body数据:$body');
_logger.logWithLevel( '原始body数据:$body',level: 'ERROR');
// 闃叉JSON搴忓垪鍖栧け璐ュ鑷村穿婧?
//print('鎵撳嵃璇锋眰浣撳け璐ワ細$e');
_logger.logWithLevel( '鎵撳嵃璇锋眰浣撳け璐ワ細$e',level: 'ERROR');
// 闄嶇骇鎵撳嵃鍘熷body锛堣櫧鐒舵牸寮忎贡锛屼絾鑳界湅鍩虹鏁版嵁锛?
// print('鍘熷body鏁版嵁锛?body');
_logger.logWithLevel( '鍘熷body鏁版嵁锛?body',level: 'ERROR');
}
final token = (await _userStorage.getUser())?.token;
if (token == null) throw Exception('Token missing');
final requestBody = jsonEncode(body);
// print('🔍 [路径规划请求] ====== 完整请求体 ======');
// print(requestBody);
//print('🔍 [路径规划请求] ====== 请求体结束 ======');
final response = await http.post(
Uri.parse('https://servicepathplan.satabot.com/api/path'),
headers: {'Content-Type': 'application/json', 'Authorization': token},
body: jsonEncode(body),
headers: {'Content'
'-Type': 'application/json', 'Authorization': token},
body: requestBody,
);
// 🔥 完整打印响应体
//printFullString(formatJson(jsonEncode(response.body)));
//print('🔄 [路径规划API] 响应状态码: ${response.statusCode}');
// print('🔄 [路径规划API] 响应体长度: ${response.body.length}');
//print('🔄 [路径规划API] 响应体前500字符: ${response.body.length > 500 ? response.body.substring(0, 500) : response.body}');
try {
final decoded = jsonDecode(response.body) as Map<String, dynamic>;
if (decoded['success'] == true) {
final pathJson = decoded['data']?['path'];
// print('路径数据: $pathJson'); // 调试输出路径数据
_logger.logWithLevel( '路径数据: $pathJson',level: 'INFO');
if (pathJson == null) {
throw Exception('API returned null for "path"');
}
// print('🔄 [路径规划API] 解析后 keys: ${decoded.keys.toList()}');
//print('🔄 [路径规划API] code=${decoded['code']}, success=${decoded['success']}, msg=${decoded['msg']}, hasData=${decoded.containsKey('data')}');
// 🔥 对齐 Web 端:优先判断 data.path 是否存在,兼容 code==200 和 success==true 两种格式
final dataObj = decoded['data'];
final pathJson = dataObj is Map ? dataObj['path'] : null;
if (pathJson != null) {
/ print('✅ [路径规划API] 路径数据点数: ${pathJson is List ? pathJson.length : '非列表'}');
if (pathJson is! List) {
throw Exception('Expected "path" to be a List, but got ${pathJson.runtimeType}');
}
final List<dynamic> jsonData = pathJson;
return jsonData.map((item) => DeviceAddPathPointModel.fromJson(item)).toList();
} else {
final apiCode = decoded['code'] ?? -1;
final msg = decoded['msg'] ?? '未知错误';
throw Exception('API 错误 [$apiCode]: $msg');
}
// 检查 success 字段(旧格式兼容)
if (decoded['success'] == true) {
if (pathJson == null) {
throw Exception('API returned null for "path"');
}
}
// 兼容 code==200 格式
final apiCode = decoded['code'];
if (apiCode != null && apiCode.toString() == '200') {
throw Exception('API code=200 但 data.path 为空');
}
final msg = decoded['message'] ?? decoded['msg'] ?? '未知错误';
throw Exception('API 错误 [${decoded['code'] ?? -1}]: $msg');
} catch (e) {
throw Exception('Network error: $e');
}
}
}