孔洞逻辑完成

This commit is contained in:
mmc
2026-03-03 09:40:29 +08:00
parent bb16a532ec
commit ca90d8dc05
7 changed files with 134 additions and 116 deletions

View File

@@ -19,22 +19,24 @@ class PathHttpDatasourceImpl implements PathHttpDatasource {
// 1. 先打印基础信息
print('=== 最终发送给后端的请求体 ===');
print('请求体类型:${body.runtimeType}');
print('是否包含holes:${body.containsKey('holes')}, holes长度:${(body['holes'] as List).length}');
// 2. 格式化打印JSON(带缩进,清晰展示嵌套结构)
final jsonString = const JsonEncoder.withIndent(' ').convert(body);
print('完整JSON请求体:\n$jsonString');
final _jsonString = jsonEncode(body);
print('完整JSON请求体:\n$jsonString');
// 3. 可选:单独打印holes的JSON(重点关注)
final holesJson = body['holes'] as List;
print('=== 单独打印holes的JSON ===');
if (holesJson.isEmpty) {
print('holes 为空数组');
} else {
for (int i = 0; i < holesJson.length; i++) {
print('第${i + 1}组hole:\n${const JsonEncoder.withIndent(' ').convert(holesJson[i])}');
}
}
//final holesJson = body['holes'] as List;
//print('=== 单独打印holes的JSON ===');
//if (holesJson.isEmpty) {
// print('holes 为空数组');
//} else {
// for (int i = 0; i < holesJson.length; i++) {
// print('第${i + 1}组hole:\n${const JsonEncoder.withIndent(' ').convert(holesJson[i])}');
// }
//}
} catch (e) {
// 防止JSON序列化失败导致崩溃
print('打印请求体失败:$e');

View File

@@ -4,10 +4,7 @@ class ReferencePoint {
ReferencePoint({required this.lat, required this.lon});
Map<String, dynamic> toJson() => {
'lat': lat,
'lon': lon,
};
Map<String, dynamic> toJson() => {'lat': lat, 'lon': lon};
}
class OuterBoundary {
@@ -16,22 +13,55 @@ class OuterBoundary {
OuterBoundary({required this.position, required this.sideWidth});
Map<String, dynamic> toJson() => {
'position': position.map((p) => p.toJson()).toList(),
'sideWidth': sideWidth,
};
Map<String, dynamic> toJson() => {'position': position.map((p) => p.toJson()).toList(), 'sideWidth': sideWidth};
}
class HoleBoundary {
final List<Position> position;
// 核心修改:position 改为二维列表(List<List<Position>>)
final List<List<Position>> position;
final double sideWidth;
HoleBoundary({required this.position, required this.sideWidth});
// 构造函数:支持传入一维/二维Position列表,自动适配格式
HoleBoundary({
required dynamic position, // 兼容一维/二维输入
required this.sideWidth,
}) : position = _normalizePosition(position);
// 辅助方法:将任意格式的position转为标准二维数组
static List<List<Position>> _normalizePosition(dynamic input) {
if (input is List<List<Position>>) {
// 已经是二维数组,直接返回
return input;
} else if (input is List<Position>) {
// 一维数组,包装成二维数组 [[p1,p2,p3]]
return [input];
} else {
throw ArgumentError('position 必须是 List<Position> 或 List<List<Position>> 类型');
}
}
// 核心修改:toJson 输出二维数组格式
Map<String, dynamic> toJson() => {
'position': position.map((p) => p.toJson()).toList(),
'position': position.map((innerList) => innerList.map((p) => p.toJson()).toList()).toList(), // 二维数组:[[{lat,lon}], ...]
'sideWidth': sideWidth,
};
// 可选:从JSON反序列化(方便解析返回值)
factory HoleBoundary.fromJson(Map<String, dynamic> json) {
// 1. 提取position数组(分步处理,更易读)
final List<dynamic> outerList = json['position'] as List;
// 2. 遍历外层数组,将每个内层数组转为 List<Position>
final List<List<Position>> position = outerList.map((innerList) {
// 3. 处理内层数组,转为 Position 对象列表
return (innerList as List).map((p) => Position.fromJson(p as Map<String, dynamic>)).toList();
}).toList();
// 4. 提取sideWidth(确保数字类型)
final double sideWidth = (json['sideWidth'] as num).toDouble();
// 5. 返回实例
return HoleBoundary(position: position, sideWidth: sideWidth);
}
}
class Position {
@@ -39,9 +69,12 @@ class Position {
final double lon;
Position({required this.lat, required this.lon});
factory Position.fromJson(Map<String, dynamic> json) {
// 安全解析经纬度,避免空值/非数字
final double lat = (json['lat'] as num?)?.toDouble() ?? 0.0;
final double lon = (json['lon'] as num?)?.toDouble() ?? 0.0;
return Position(lat: lat, lon: lon);
}
Map<String, dynamic> toJson() => {
'lat': lat,
'lon': lon,
};
Map<String, dynamic> toJson() => {'lat': lat, 'lon': lon};
}

View File

@@ -19,14 +19,17 @@ class PathRepositoryImpl implements PathRepository {
required ReferencePoint reference,
required int heading,
required OuterBoundary outer,
required List<HoleBoundary> holes,
required Map<String, HoleBoundary> holes,
required int workType,
}) async {
final body = {
'reference': reference.toJson(),
'heading': heading,
'outer': outer.toJson(),
'holes': holes.map((hole) => hole.toJson()).toList(),
'holes': holes != null && holes.isNotEmpty
? holes.values.first
.toJson() // 取第一个值并序列化,去掉外层 Map
: {},
'workType': workType,
};

View File

@@ -7,30 +7,19 @@ abstract class PathRepository {
required ReferencePoint reference,
required int heading,
required OuterBoundary outer,
required List<HoleBoundary> holes,
required Map<String, HoleBoundary> holes,
required int workType,
});
// Save work record (新增)
Future<Map<String, dynamic>> saveWorkRecord({
required String workName,
required String userId,
required String jsonData,
});
Future<Map<String, dynamic>> saveWorkRecord({required String workName, required String userId, required String jsonData});
// Get work record (查询)
Future<List<Map<String, dynamic>>> getWorkRecord({
required String userId,
});
Future<List<Map<String, dynamic>>> getWorkRecord({required String userId});
// Delete work record (删除)
Future<Map<String, dynamic>> deleteWorkRecord({
required String workName,
});
Future<Map<String, dynamic>> deleteWorkRecord({required String workName});
/// 根据作业名查询路径记录(用于“选择一个路径”)
Future<List<Map<String, dynamic>>> selectWorkRecordByName({
required String workName,
});
}
Future<List<Map<String, dynamic>>> selectWorkRecordByName({required String workName});
}

View File

@@ -11,10 +11,11 @@ abstract class GeneratePathUseCase {
required ReferencePoint reference,
required int heading,
required OuterBoundary outer,
required List<HoleBoundary> holes,
required Map<String, HoleBoundary> holes,
required int workType,
});
}
class GeneratePathUseCaseImpl implements GeneratePathUseCase {
final PathRepository _repository;
@@ -25,22 +26,14 @@ class GeneratePathUseCaseImpl implements GeneratePathUseCase {
required ReferencePoint reference,
required int heading,
required OuterBoundary outer,
required List<HoleBoundary> holes,
required Map<String, HoleBoundary> holes,
required int workType,
}) async {
try {
final result = await _repository.generatePath(
reference: reference,
heading: heading,
outer: outer,
holes: holes,
workType: workType,
);
final result = await _repository.generatePath(reference: reference, heading: heading, outer: outer, holes: holes, workType: workType);
return Right(result); // 成功时返回 Right
} catch (e) {
return Left(ServerFailure(e.toString(),1)); // 失败时返回 Left
return Left(ServerFailure(e.toString(), 1)); // 失败时返回 Left
}
}
}

View File

@@ -233,13 +233,13 @@ class DevicesCubit extends Cubit<DevicesState> {
required ReferencePoint reference,
required int heading,
required OuterBoundary outer,
required List<HoleBoundary> holes,
required Map<String, HoleBoundary> holes,
required int workType,
}) async {
holes.asMap().forEach((index, hole) {
final pointsStr = hole.position.map((p) => "(${p.lat.toStringAsFixed(6)}, ${p.lon.toStringAsFixed(6)})").join(', ');
debugPrint('第${index + 1}组holes:$pointsStr');
});
//holes.asMap().forEach((index, hole) {
// final pointsStr = hole.position.map((p) => "(${p.lat.toStringAsFixed(6)}, ${p.lon.toStringAsFixed(6)})").join(', ');
// debugPrint('第${index + 1}组holes:$pointsStr');
//});
emit(state.copyWith(isLoading: true));
final result = await _generatePathUseCase.execute(reference: reference, heading: heading, outer: outer, holes: holes, workType: workType);