bug fixes

This commit is contained in:
2026-08-29 00:00:09 +03:00
parent 6513a004d9
commit a556dc5736
15 changed files with 361 additions and 271 deletions

View File

@@ -2,7 +2,6 @@ class Tariff {
final int id;
final String title;
final String description;
final String descriptionJson;
final bool isActive;
final String currency;
final double holdPrice; // Старт / бронь
@@ -16,7 +15,6 @@ class Tariff {
required this.id,
required this.title,
required this.description,
required this.descriptionJson,
required this.isActive,
required this.currency,
required this.holdPrice,
@@ -35,7 +33,6 @@ class Tariff {
id: json['id'] ?? 0,
title: json['title'] ?? 'Unknown',
description: json['description'] ?? '',
descriptionJson: json['descriptionJson'] ?? '',
isActive: json['isActive'] ?? false,
currency: currency['currency'] ?? 'BYN',
holdPrice: (planPrice['hold'] as num?)?.toDouble() ?? 0.0,

View File

@@ -1,4 +1,6 @@
import 'dart:convert';
import 'package:be_happy/domain/entities/point.dart';
class Zone {
@@ -8,9 +10,6 @@ class Zone {
final String type;
final bool isActive;
final String shapeType;
// Трехмерная структура для поддержки MultiPolygon и дыр (holes):
// geometry[индекс_полигона][индекс_кольца][индекс_точки]
// индекс_кольца == 0 — внешняя граница, > 0 — внутренние вырезы (дыры)
final List<List<List<Point>>> geometry;
final String speedLimit;
@@ -25,7 +24,6 @@ class Zone {
required this.speedLimit,
});
// Геттер для обратной совместимости (возвращает внешнее кольцо первого полигона)
List<Point> get points {
if (geometry.isNotEmpty && geometry[0].isNotEmpty) {
return geometry[0][0];
@@ -45,77 +43,64 @@ class Zone {
if (decoded is List && decoded.isNotEmpty) {
if (shapeType == 'Polygon') {
// Структура: [[[lon, lat], [lon, lat], ...], [hole1], ...]
List<List<Point>> polygonRings = [];
for (var ring in decoded) {
if (ring is List) {
List<Point> ringPoints = [];
for (var coord in ring) {
if (coord is List && coord.length >= 2) {
// В GeoJSON сначала идет Longitude, затем Latitude
ringPoints.add(Point(
(coord[1] as num).toDouble(),
(coord[0] as num).toDouble(),
));
}
}
if (ringPoints.isNotEmpty) polygonRings.add(ringPoints);
}
}
final polygonRings = _parseRings(decoded);
if (polygonRings.isNotEmpty) parsedGeometry.add(polygonRings);
} else if (shapeType == 'MultiPolygon') {
// Структура: [[[[lon, lat], ...]], [[[lon, lat], ...]]]
for (var poly in decoded) {
if (poly is List) {
List<List<Point>> polygonRings = [];
for (var ring in poly) {
if (ring is List) {
List<Point> ringPoints = [];
for (var coord in ring) {
if (coord is List && coord.length >= 2) {
ringPoints.add(Point(
(coord[1] as num).toDouble(),
(coord[0] as num).toDouble(),
));
}
}
if (ringPoints.isNotEmpty) polygonRings.add(ringPoints);
}
}
final polygonRings = _parseRings(poly);
if (polygonRings.isNotEmpty) parsedGeometry.add(polygonRings);
}
}
} else {
// Fallback для LineString или плоских списков
List<Point> ringPoints = [];
for (var coord in decoded) {
if (coord is List && coord.length >= 2) {
ringPoints.add(Point(
(coord[1] as num).toDouble(),
(coord[0] as num).toDouble(),
));
}
}
if (ringPoints.isNotEmpty) parsedGeometry.add([ringPoints]);
final singleRing = _parseCoordinateList(decoded);
if (singleRing.isNotEmpty) parsedGeometry.add([singleRing]);
}
}
} catch (e) {
print("PARSE ERROR for Zone ID ${json['id']}: $e");
} catch (e, stackTrace) {
// Replace with your project logger (e.g., debugPrint or Logger)
assert(() {
print("PARSE ERROR for Zone ID ${json['id']}: $e\n$stackTrace");
return true;
}());
}
return Zone(
id: json['id'] ?? 0,
title: json['title'] ?? 'Unknown',
description: json['description'] ?? '',
type: json['type'] ?? '',
isActive: json['isActive'] ?? false,
speedLimit: json['speedLimit'] ?? '',
id: json['id'] as int? ?? 0,
title: json['title'] as String? ?? 'Unknown',
description: json['description'] as String? ?? '',
type: json['type'] as String? ?? '',
isActive: json['isActive'] as bool? ?? false,
speedLimit: json['speedLimit'] as String? ?? '',
shapeType: shapeType,
geometry: parsedGeometry,
);
}
static List<List<Point>> _parseRings(List rawRings) {
List<List<Point>> polygonRings = [];
for (var ring in rawRings) {
if (ring is List) {
final ringPoints = _parseCoordinateList(ring);
if (ringPoints.isNotEmpty) polygonRings.add(ringPoints);
}
}
return polygonRings;
}
static List<Point> _parseCoordinateList(List rawCoords) {
List<Point> ringPoints = [];
for (var coord in rawCoords) {
if (coord is List && coord.length >= 2) {
ringPoints.add(Point(
(coord[1] as num).toDouble(),
(coord[0] as num).toDouble(),
));
}
}
return ringPoints;
}
@override
String toString() {
return 'Zone{id: $id, title: $title, type: $type, polygonsCount: ${geometry.length}}';

View File

@@ -2,5 +2,6 @@ import '../entities/zone.dart';
abstract class ZoneRepository {
Future<List<Zone>> getZones(List<double> area, int page, int pageSize);
Future<List<Zone>> getAllZones(int page, int pageSize);
}

View File

@@ -0,0 +1,30 @@
import '../entities/zone.dart';
import '../repositories/zone_repository.dart';
class GetAllZonesUsecase {
final ZoneRepository repository;
GetAllZonesUsecase(this.repository);
static const int _pageSize = 100;
Future<List<Zone>> call() async {
final List<Zone> allZones = [];
int page = 0;
while (true) {
final zones = await repository.getAllZones(page, _pageSize);
if (zones == null || zones.isEmpty) break;
allZones.addAll(zones);
// если пришло меньше, чем размер страницы — это последняя страница
if (zones.length < _pageSize) break;
page++;
}
return allZones;
}
}