new project stable version

This commit is contained in:
2026-05-10 19:11:31 +03:00
commit 3616f84556
391 changed files with 23857 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
import 'scooter.dart';
class ActiveScooterOrder {
final int orderId;
final int scooterId;
final double latitude;
final double longitude;
final double mileage;
final double speed;
final double price;
final double time;
final bool zone;
ActiveScooterOrder({
required this.orderId,
required this.scooterId,
required this.latitude,
required this.longitude,
required this.mileage,
required this.speed,
required this.price,
required this.time,
required this.zone,
});
factory ActiveScooterOrder.fromJson(Map<String, dynamic> json) {
return ActiveScooterOrder(
orderId: json['orderId'] ?? 0,
scooterId: json['scooterId'] ?? 0,
latitude: (json['latitude'] ?? 0).toDouble(),
longitude: (json['longitude'] ?? 0).toDouble(),
mileage: (json['mileage'] ?? 0).toDouble(),
speed: (json['speed'] ?? 0).toDouble(),
price: (json['price'] ?? 0).toDouble(),
time: (json['time'] ?? 0.0).toDouble(),
zone: json['zone'],
);
}
Map<String, dynamic> toJson() {
return {
'orderId': orderId,
'scooterId': scooterId,
'latitude': latitude,
'longitude': longitude,
'mileage': mileage,
'speed': speed,
'price': price,
};
}
}

View File

@@ -0,0 +1,94 @@
class Currency {
final int id;
final String title;
final String currency;
final String code;
final bool isBase;
final int denomination;
final double exchangeRate;
final String formatString;
final String floatSeparator;
final int decimals;
final bool isHideZero;
Currency({
required this.id,
required this.title,
required this.currency,
required this.code,
required this.isBase,
required this.denomination,
required this.exchangeRate,
required this.formatString,
required this.floatSeparator,
required this.decimals,
required this.isHideZero,
});
factory Currency.fromJson(Map<String, dynamic> json) {
return Currency(
id: json['id'] as int,
title: json['title'] as String,
currency: json['currency'] as String,
code: json['code'] as String,
isBase: json['isBase'] as bool,
denomination: json['denomination'] as int,
exchangeRate: (json['exchangeRate'] as num).toDouble(),
formatString: json['formatString'] as String,
floatSeparator: json['floatSeparator'] as String,
decimals: json['decimals'] as int,
isHideZero: json['isHideZero'] as bool,
);
}
}
class Certificate {
final int id;
final String title;
final String? description;
final double price;
final int currencyId;
final int value;
final double discount;
final DateTime createdAt;
final DateTime updatedAt;
final int sort;
final bool isActive;
final Currency? currency;
final String? pricePrint;
Certificate({
required this.id,
required this.title,
this.description,
required this.price,
required this.currencyId,
required this.value,
required this.discount,
required this.createdAt,
required this.updatedAt,
required this.sort,
required this.isActive,
this.currency,
this.pricePrint,
});
factory Certificate.fromJson(Map<String, dynamic> json) {
return Certificate(
id: json['id'] as int,
title: json['title'] as String,
description: json['description'] as String?,
price: (json['price'] as num).toDouble(),
currencyId: json['currencyId'] as int,
value: json['value'] as int,
discount: (json['discount'] as num).toDouble(),
createdAt: DateTime.parse(json['createdAt'] as String),
updatedAt: DateTime.parse(json['updatedAt'] as String),
sort: json['sort'] as int,
isActive: json['isActive'] as bool,
currency: json['currency'] != null ? Currency.fromJson(json['currency']) : null,
pricePrint: json['pricePrint'] as String?,
);
}
}

View File

@@ -0,0 +1,58 @@
enum NotificationType {
info,
attention,
warning,
}
enum NotificationCategory {
auth,
zone,
payment,
companyInfo,
adminInfo,
scooter,
}
class ClientNotification {
final int id;
final String content;
final int clientId;
final NotificationType type;
final NotificationCategory category;
final DateTime createdAt;
final DateTime? canceledAt;
final DateTime? readAt;
ClientNotification({
required this.id,
required this.content,
required this.clientId,
required this.type,
required this.category,
required this.createdAt,
this.canceledAt,
this.readAt,
});
ClientNotification copyWith({
int? id,
String? content,
int? clientId,
NotificationType? type,
NotificationCategory? category,
DateTime? createdAt,
DateTime? canceledAt,
DateTime? readAt,
}) {
return ClientNotification(
id: id ?? this.id,
content: content ?? this.content,
clientId: clientId ?? this.clientId,
type: type ?? this.type,
category: category ?? this.category,
createdAt: createdAt ?? this.createdAt,
canceledAt: canceledAt ?? this.canceledAt,
readAt: readAt ?? this.readAt,
);
}
}

View File

@@ -0,0 +1,15 @@
class MapSettings {
final bool all_placemarks;
final bool all_zones;
final bool parking_zones;
final bool restricted_parking_zones;
final bool restricted_driving_zones;
MapSettings({
required this.all_placemarks,
required this.all_zones,
required this.parking_zones,
required this.restricted_parking_zones,
required this.restricted_driving_zones,
});
}

View File

@@ -0,0 +1,62 @@
class NewsEntity {
final int id;
final String title;
final String previewText;
final String text;
final DateTime createdAt;
final DateTime publishedAt;
final bool isActive;
final String? imageUrl;
final String? textJson;
final int? userId;
final int? pictureId;
final dynamic user;
final dynamic picture;
NewsEntity({
required this.id,
required this.title,
required this.previewText,
required this.text,
required this.createdAt,
required this.publishedAt,
required this.isActive,
this.imageUrl,
this.textJson,
this.userId,
this.pictureId,
this.user,
this.picture,
});
factory NewsEntity.fromJson(Map<String, dynamic> json) {
DateTime _parseDate(String? dateStr) {
try {
return dateStr != null ? DateTime.parse(dateStr) : DateTime.now();
} catch (_) {
return DateTime.now();
}
}
return NewsEntity(
id: json['id'] ?? 0,
title: json['title'] ?? '',
previewText: json['previewText'] ?? '',
text: json['text'] ?? '',
createdAt: _parseDate(json['createdAt']),
publishedAt: _parseDate(json['publishedAt']),
isActive: json['isActive'] ?? false,
imageUrl: json['picture'] != null
? 'https://sharing-api.sparkit.by/${json['picture']['path']}'
: null,
textJson: json['textJson'],
userId: json['userId'],
pictureId: json['pictureId'],
user: json['user'],
picture: json['picture'],
);
}
}

View File

@@ -0,0 +1,19 @@
class Pagination {
final int total;
final int currentPage;
final int lastPage;
Pagination({
required this.total,
required this.currentPage,
required this.lastPage,
});
factory Pagination.fromJson(Map<String, dynamic> json) {
return Pagination(
total: json['total'] ?? 0,
currentPage: json['currentPage'] ?? 0,
lastPage: json['lastPage'] ?? 0,
);
}
}

View File

@@ -0,0 +1,43 @@
class PaymentCard {
final int id;
final int clientId;
final int expirationMonth;
final int expirationYear;
final String cardHolder;
final String cardLastNumber;
final bool isMain;
final String type;
PaymentCard({
required this.id,
required this.clientId,
required this.expirationMonth,
required this.expirationYear,
required this.cardHolder,
required this.cardLastNumber,
required this.isMain,
required this.type,
});
PaymentCard copyWith({
int? id,
int? clientId,
int? expirationMonth,
int? expirationYear,
String? cardHolder,
String? cardLastNumber,
bool? isMain,
String? type,
}) {
return PaymentCard(
id: id ?? this.id,
clientId: clientId ?? this.clientId,
expirationMonth: expirationMonth ?? this.expirationMonth,
expirationYear: expirationYear ?? this.expirationYear,
cardHolder: cardHolder ?? this.cardHolder,
cardLastNumber: cardLastNumber ?? this.cardLastNumber,
isMain: isMain ?? this.isMain,
type: type ?? this.type,
);
}
}

View File

@@ -0,0 +1,12 @@
class Point {
final double latitude;
final double longitude;
Point(this.latitude, this.longitude);
@override
String toString() {
return 'Point{latitude: $latitude, longitude: $longitude}';
}
}

View File

@@ -0,0 +1,50 @@
class Scooter {
final int id;
final String title;
final String status;
final double latitude;
final double longitude;
final int batteryLevel;
final bool isOnline;
final int maxSpeed;
final String number;
double? distance;
double? timeToTravel;
Scooter({
required this.id,
required this.title,
required this.status,
required this.latitude,
required this.longitude,
required this.batteryLevel,
required this.isOnline,
required this.maxSpeed,
required this.number,
this.distance,
this.timeToTravel,
});
factory Scooter.fromJson(Map<String, dynamic> json) {
final scooterDetail = json['scooterDetail'] as Map<String, dynamic>? ?? {};
final model = json['model'] as Map<String, dynamic>? ?? {};
return Scooter(
id: json['id'] ?? 0,
title: json['title'] ?? 'Unknown',
status: json['status'] ?? 'Unavailable',
latitude: (scooterDetail['latitude'] as num?)?.toDouble() ?? 0.0,
longitude: (scooterDetail['longitude'] as num?)?.toDouble() ?? 0.0,
batteryLevel: (scooterDetail['batteryLevel'] as num?)?.toInt() ?? 0,
isOnline: scooterDetail['isOnline'] ?? false,
maxSpeed: (json['maxSpeed'] as num?)?.toInt() ?? 25,
number: json['title'] ?? 'Unknown',
);
}
@override
String toString() {
return 'Scooter{id: $id, title: $title}';
}
}

View File

@@ -0,0 +1,143 @@
import 'scooter.dart';
class ScooterOrder {
final int id;
final int scooterId;
final Scooter? scooter;
final int? planId;
final ScooterPlan? plan;
final int clientId;
final int? subscriptionId;
final int? cardId;
final bool isBalance;
final int decimals;
final bool isInsurance;
final double? insurancePrice;
final String? insurancePricePrint;
final double? holdPrice;
final String? holdPricePrint;
final double? totalPrice;
final String? totalPricePrint;
final int? currencyId;
final String status;
final DateTime createdAt;
final DateTime? updatedAt;
final DateTime? startAt;
final DateTime? finishAt;
final DateTime? expiresAt;
final DateTime? cancelAt;
final String? cancelDescription;
final double mileage; //эту
final double avgSpeed; //эту и снизу еще 4 есть
ScooterOrder({
required this.id,
required this.scooterId,
this.scooter,
this.planId,
this.plan,
required this.clientId,
this.subscriptionId,
this.cardId,
required this.isBalance,
required this.decimals,
required this.isInsurance,
this.insurancePrice,
this.insurancePricePrint,
this.holdPrice,
this.holdPricePrint,
this.totalPrice,
this.totalPricePrint,
this.currencyId,
required this.status,
required this.createdAt,
this.updatedAt,
this.startAt,
this.finishAt,
this.expiresAt,
this.cancelAt,
this.cancelDescription,
required this.mileage, //эту
required this.avgSpeed, //эту и снизу еще 2 есть
});
factory ScooterOrder.fromJson(Map<String, dynamic> json) {
return ScooterOrder(
id: json['id'] ?? 0,
scooterId: json['scooterId'] ?? 0,
scooter: json['scooter'] != null ? Scooter.fromJson(json['scooter']) : null,
planId: json['planId'],
plan: json['plan'] != null ? ScooterPlan.fromJson(json['plan']) : null,
clientId: json['clientId'] ?? 0,
subscriptionId: json['subscriptionId'],
cardId: json['cardId'],
isBalance: json['isBalance'] ?? false,
decimals: json['decimals'] ?? 0,
isInsurance: json['isInsurance'] ?? false,
insurancePrice: (json['insurancePrice'] as num?)?.toDouble(),
insurancePricePrint: json['insurancePricePrint'],
holdPrice: (json['holdPrice'] as num?)?.toDouble(),
holdPricePrint: json['holdPricePrint'],
totalPrice: (json['totalPrice'] as num?)?.toDouble(),
totalPricePrint: json['totalPricePrint'],
currencyId: json['currencyId'],
status: json['status'] ?? '',
createdAt: json['createdAt'] != null
? DateTime.parse(json['createdAt'])
: DateTime.now(),
updatedAt: json['updatedAt'] != null
? DateTime.parse(json['updatedAt'])
: null,
startAt: json['startAt'] != null
? DateTime.parse(json['startAt'])
: null,
finishAt: json['finishAt'] != null
? DateTime.parse(json['finishAt'])
: null,
expiresAt: json['expiresAt'] != null
? DateTime.parse(json['expiresAt'])
: null,
cancelAt: json['cancelAt'] != null
? DateTime.parse(json['cancelAt'])
: null,
cancelDescription: json['cancelDescription'],
mileage: (json['mileage'] as num?)?.toDouble() ?? 0.0, //эту
avgSpeed: (json['avgSpeed'] as num?)?.toDouble() ?? 0.0, //эту
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'scooterId': scooterId,
'planId': planId,
'subscriptionId': subscriptionId,
'cardId': cardId,
'isBalance': isBalance,
'isInsurance': isInsurance,
};
}
}
class ScooterPlan {
final int id;
final String title;
final double price;
final String? description;
ScooterPlan({
required this.id,
required this.title,
required this.price,
this.description,
});
factory ScooterPlan.fromJson(Map<String, dynamic> json) {
return ScooterPlan(
id: json['id'] ?? 0,
title: json['title'] ?? '',
price: (json['price'] as num?)?.toDouble() ?? 0.0,
description: json['description'],
);
}
}

View File

@@ -0,0 +1,59 @@
import 'package:be_happy/domain/entities/subscription_period.dart';
class Subscription {
final int id;
final String title;
final String shortDescription;
final String fullDescription;
final int planId;
final bool isActive;
final String currency;
final DateTime? activeFrom;
final DateTime? activeTo;
final DateTime createdAt;
final DateTime updatedAt;
final List<SubscriptionPeriod> options;
Subscription({
required this.id,
required this.title,
required this.shortDescription,
required this.fullDescription,
required this.planId,
required this.isActive,
required this.currency,
this.activeFrom,
this.activeTo,
required this.createdAt,
required this.updatedAt,
required this.options,
});
factory Subscription.fromJson(Map<String, dynamic> json) {
final currencyData = json['currency'] as Map<String, dynamic>? ?? {};
final optionsData = json['options'] as List<dynamic>? ?? [];
return Subscription(
id: json['id'] ?? 0,
title: json['title'] ?? '',
shortDescription: json['shortDescription'] ?? '',
fullDescription: json['fullDescription'] ?? '',
planId: json['planId'] ?? 0,
isActive: json['isActive'] ?? false,
currency: currencyData['currency'] ?? 'BYN',
activeFrom: json['activeFrom'] != null ? DateTime.parse(json['activeFrom']) : null,
activeTo: json['activeTo'] != null ? DateTime.parse(json['activeTo']) : null,
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt']) : DateTime.now(),
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : DateTime.now(),
options: optionsData.map((e) => SubscriptionPeriod.fromJson(e as Map<String, dynamic>)).toList(),
);
}
@override
String toString() {
return 'Subscription{id: $id, title: $title, isActive: $isActive}';
}
}

View File

@@ -0,0 +1,33 @@
class SubscriptionPeriod {
final int id;
final int subscriptionId;
final int days;
final String title;
final double price;
final String pricePrint;
SubscriptionPeriod({
required this.id,
required this.subscriptionId,
required this.days,
required this.title,
required this.price,
required this.pricePrint,
});
factory SubscriptionPeriod.fromJson(Map<String, dynamic> json) {
return SubscriptionPeriod(
id: json['id'] ?? 0,
subscriptionId: json['subscriptionId'] ?? 0,
days: json['days'] ?? 0,
title: json['title'] ?? '',
price: (json['price'] ?? 0).toDouble(),
pricePrint: json['pricePrint'] ?? '',
);
}
@override
String toString() {
return 'SubscriptionPeriod{id: $id, title: $title, days: $days, price: $price}';
}
}

View File

@@ -0,0 +1,51 @@
class Tariff {
final int id;
final String title;
final String description;
final bool isActive;
final String currency;
final double holdPrice; // Старт / бронь
final double drivePrice; // Цена минуты
final double pausePrice; // Пауза
final double startPrice; // Старт цена
final double cashback; // Процент кэшбэка
final double insurance; // Страховка
Tariff({
required this.id,
required this.title,
required this.description,
required this.isActive,
required this.currency,
required this.holdPrice,
required this.drivePrice,
required this.pausePrice,
required this.startPrice,
required this.cashback,
required this.insurance,
});
factory Tariff.fromJson(Map<String, dynamic> json) {
final planPrice = json['planPrice'] as Map<String, dynamic>? ?? {};
final currency = json['currency'] as Map<String, dynamic>? ?? {};
return Tariff(
id: json['id'] ?? 0,
title: json['title'] ?? 'Unknown',
description: json['description'] ?? '',
isActive: json['isActive'] ?? false,
currency: currency['currency'] ?? 'BYN',
holdPrice: (planPrice['hold'] as num?)?.toDouble() ?? 0.0,
drivePrice: (planPrice['drive'] as num?)?.toDouble() ?? 0.0,
pausePrice: (planPrice['pause'] as num?)?.toDouble() ?? 0.0,
startPrice: (planPrice['start'] as num?)?.toDouble() ?? 0.0,
cashback: (planPrice['cashback'] as num?)?.toDouble() ?? 0.0,
insurance: (planPrice['insurance'] as num?)?.toDouble() ?? 0.0,
);
}
@override
String toString() {
return 'Tariff{id: $id, title: $title, isActive: $isActive}';
}
}

View File

@@ -0,0 +1,17 @@
class TopUpTariff {
final int id;
final int points;
final double price;
final double? discountPercent;
TopUpTariff({
required this.id,
required this.points,
required this.price,
this.discountPercent,
});
double get finalPrice => discountPercent != null
? price * (1 - discountPercent! / 100)
: price;
}

View File

@@ -0,0 +1,9 @@
class UserAuthData {
final String accessToken;
final String refreshToken;
UserAuthData({
required this.accessToken,
required this.refreshToken,
});
}

View File

@@ -0,0 +1,23 @@
class UserCheckFlags {
final bool hasFine;
final bool hasUnpaidOrder;
final bool hasCard;
const UserCheckFlags({
required this.hasFine,
required this.hasUnpaidOrder,
required this.hasCard,
});
UserCheckFlags copyWith({
bool? hasFine,
bool? hasUnpaidOrder,
bool? hasCard,
}) {
return UserCheckFlags(
hasFine: hasFine ?? this.hasFine,
hasUnpaidOrder: hasUnpaidOrder ?? this.hasUnpaidOrder,
hasCard: hasCard ?? this.hasCard,
);
}
}

View File

@@ -0,0 +1,38 @@
class UserProfile {
String name;
String birthDate;
String phone;
String email;
int? balance;
int? avatarId;
String? avatarUrl;
UserProfile({
required this.name,
required this.birthDate,
required this.phone,
required this.email,
this.balance,
this.avatarId,
this.avatarUrl,
});
UserProfile copyWith({
String? name,
String? birthDate,
String? email,
int? balance,
int? avatarId,
String? avatarUrl,
}) {
return UserProfile(
name: name ?? this.name,
birthDate: birthDate ?? this.birthDate,
phone: phone, // телефон не меняется
email: email ?? this.email,
balance: balance ?? this.balance,
avatarId: avatarId ?? this.avatarId,
avatarUrl: avatarUrl ?? this.avatarUrl,
);
}
}

View File

@@ -0,0 +1,74 @@
import 'dart:convert';
import 'package:be_happy/domain/entities/point.dart';
class Zone {
final int id;
final String title;
final String description;
final String type;
final bool isActive;
final String shapeType;
final List<Point> points;
final String speedLimit;
Zone({
required this.id,
required this.title,
required this.description,
required this.type,
required this.isActive,
required this.shapeType,
required this.points,
required this.speedLimit,
});
factory Zone.fromJson(Map<String, dynamic> json) {
final zoneCoordinates = json['coordinates'] as Map<String, dynamic>? ?? {};
final String coordsString = zoneCoordinates['coordinates'] ?? '[]';
final String shapeType = zoneCoordinates['type'] ?? 'Polygon';
List<Point> points = [];
try {
final dynamic decoded = jsonDecode(coordsString);
if (decoded is List && decoded.isNotEmpty) {
List<dynamic> targetList = [];
if (shapeType == 'Polygon') {
// У полигона структура [[[lat, lon], ...]] -> уходим на 1 уровень вглубь
targetList = decoded[0] as List<dynamic>;
} else {
// У LineString структура [[lat, lon], ...] -> используем как есть
targetList = decoded;
}
points = targetList.map((item) {
final List<dynamic> coords = item as List<dynamic>;
return Point(
(coords[1] as num).toDouble(),
(coords[0] as num).toDouble(),
);
}).toList();
}
} catch (e) {
print("PARSE ERROR for Zone ID ${json['id']}: $e");
}
return Zone(
id: json['id'] ?? 0,
title: json['title'] ?? 'Unknown',
description: json['description'] ?? '',
type: json['type'] ?? '',
isActive: json['isActive'] ?? false,
speedLimit: json['speedLimit'] ?? '',
shapeType: shapeType,
points: points,
);
}
@override
String toString() {
return 'Zone{id: $id, title: $title, type: $type, points: $points}';
}
}