fix
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../domain/entities/client_notification.dart';
|
||||
|
||||
class ClientNotificationDto {
|
||||
@@ -43,12 +42,19 @@ class ClientNotificationDto {
|
||||
clientId: clientId,
|
||||
type: _parseType(type),
|
||||
category: _parseCategory(category),
|
||||
createdAt: DateTime.parse(createdAt),
|
||||
canceledAt: canceledAt != null ? DateTime.parse(canceledAt!) : null,
|
||||
readAt: readAt != null ? DateTime.parse(readAt!) : null,
|
||||
createdAt: _parseUtcDate(createdAt),
|
||||
canceledAt: canceledAt != null ? _parseUtcDate(canceledAt!) : null,
|
||||
readAt: readAt != null ? _parseUtcDate(readAt!) : null,
|
||||
);
|
||||
}
|
||||
|
||||
DateTime _parseUtcDate(String dateString) {
|
||||
if (dateString.endsWith('Z') || dateString.contains('+') || dateString.contains('-')) {
|
||||
return DateTime.parse(dateString).toLocal();
|
||||
}
|
||||
return DateTime.parse('${dateString}Z').toLocal();
|
||||
}
|
||||
|
||||
NotificationType _parseType(String type) {
|
||||
switch (type.toLowerCase()) {
|
||||
case 'info':
|
||||
@@ -80,4 +86,4 @@ class ClientNotificationDto {
|
||||
return NotificationCategory.companyInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,11 +147,12 @@ class ApiService {
|
||||
}
|
||||
|
||||
dynamic balanceRaw = profileData["balance"];
|
||||
int? balance;
|
||||
if (balanceRaw is int) {
|
||||
balance = balanceRaw;
|
||||
double? balance;
|
||||
|
||||
if (balanceRaw is num) {
|
||||
balance = balanceRaw.toDouble();
|
||||
} else if (balanceRaw is String) {
|
||||
balance = int.tryParse(balanceRaw);
|
||||
balance = double.tryParse(balanceRaw);
|
||||
}
|
||||
|
||||
return UserProfile(
|
||||
@@ -238,11 +239,11 @@ class ApiService {
|
||||
}
|
||||
|
||||
dynamic balanceRaw = data["balance"];
|
||||
int? balance;
|
||||
if (balanceRaw is int) {
|
||||
double? balance;
|
||||
if (balanceRaw is double) {
|
||||
balance = balanceRaw;
|
||||
} else if (balanceRaw is String) {
|
||||
balance = int.tryParse(balanceRaw);
|
||||
balance = double.tryParse(balanceRaw);
|
||||
}
|
||||
|
||||
return UserProfile(
|
||||
@@ -420,7 +421,7 @@ class ApiService {
|
||||
int page = 1,
|
||||
int pageSize = 500,
|
||||
}) async {
|
||||
const path = "$baseUrl/zone/available";
|
||||
const path = "$baseUrl/zone/available2";
|
||||
|
||||
final queryParams = {
|
||||
'readAll': 'true',
|
||||
@@ -708,17 +709,13 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<ScooterOrder?> cancelRide(int orderId) async {
|
||||
Future<void> cancelRide(int orderId) async {
|
||||
try {
|
||||
final response = await _dio.put(
|
||||
"$baseUrl/scooterorder/$orderId/cancel",
|
||||
options: await _getAuthOptions(),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
return ScooterOrder.fromJson(response.data);
|
||||
}
|
||||
return null;
|
||||
} on DioException catch (e) {
|
||||
_handleDioError(e);
|
||||
return null;
|
||||
@@ -759,7 +756,7 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<ScooterOrder?> finishRide({
|
||||
Future<void> finishRide({
|
||||
required int orderId,
|
||||
required List<int> filesId,
|
||||
}) async {
|
||||
@@ -770,10 +767,6 @@ class ApiService {
|
||||
options: await _getAuthOptions(),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
return ScooterOrder.fromJson(response.data);
|
||||
}
|
||||
return null;
|
||||
} on DioException catch (e) {
|
||||
if (e.response?.statusCode == 400) {
|
||||
final data = e.response?.data;
|
||||
@@ -1013,10 +1006,10 @@ class ApiService {
|
||||
if (event.data != null && event.data!.isNotEmpty) {
|
||||
try {
|
||||
final Map<String, dynamic> jsonData = jsonDecode(event.data!);
|
||||
print("✅ [SSE] Parsed JSON: $jsonData");
|
||||
print("[SSE] Parsed JSON: $jsonData");
|
||||
controller.add(jsonData);
|
||||
} catch (e) {
|
||||
print("❌ [SSE] JSON Parse Error: $e | Raw: ${event.data}");
|
||||
print("[SSE] JSON Parse Error: $e | Raw: ${event.data}");
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1034,17 +1027,19 @@ class ApiService {
|
||||
return controller.stream;
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> getNotifications() async {
|
||||
final url = Uri.parse('$baseUrl/notification/client');
|
||||
Future<Map<String, dynamic>> getNotifications({
|
||||
int page = 1,
|
||||
int pageSize = 10,
|
||||
}) async {
|
||||
final url = Uri.parse('$baseUrl/notification/client').replace(
|
||||
queryParameters: {
|
||||
'page': page.toString(),
|
||||
'pageSize': pageSize.toString(),
|
||||
},
|
||||
);
|
||||
|
||||
final accessToken = await _securityService.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
print("APISERVICE Error: Access token is null.");
|
||||
throw UnauthorizedException();
|
||||
}
|
||||
|
||||
print("GET NOTIFICATIONS REQUEST:");
|
||||
print("URL: $url");
|
||||
if (accessToken == null) throw UnauthorizedException();
|
||||
|
||||
final response = await http.get(
|
||||
url,
|
||||
@@ -1054,34 +1049,17 @@ class ApiService {
|
||||
},
|
||||
);
|
||||
|
||||
print("GET NOTIFICATIONS RESPONSE:");
|
||||
print("STATUS: ${response.statusCode}");
|
||||
print("BODY: ${response.body}");
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(utf8.decode(response.bodyBytes));
|
||||
|
||||
// ✅ Проверяем, является ли ответ массивом или объектом с data[]
|
||||
if (data is List) {
|
||||
return data.cast<Map<String, dynamic>>();
|
||||
} else if (data is Map<String, dynamic>) {
|
||||
final list = data['data'];
|
||||
if (list is List) {
|
||||
return list.cast<Map<String, dynamic>>();
|
||||
} else {
|
||||
throw Exception(
|
||||
'Expected a List under "data" but got ${list.runtimeType}',
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw Exception('Expected a List or Map but got ${data.runtimeType}');
|
||||
if (data is Map<String, dynamic>) {
|
||||
return data;
|
||||
}
|
||||
throw Exception('Expected Map with data and pagination');
|
||||
} else if (response.statusCode == 401) {
|
||||
throw UnauthorizedException();
|
||||
} else if (response.statusCode == 403) {
|
||||
throw AuthBlockException();
|
||||
}
|
||||
|
||||
throw Exception('Ошибка сервера: ${response.statusCode}');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:be_happy/domain/entities/client_notification.dart';
|
||||
|
||||
import '../../data/network/api_service.dart';
|
||||
import '../../domain/entities/pagination_meta.dart';
|
||||
import '../../domain/repositories/notification_repository.dart';
|
||||
import '../../domain/usecase/get_notifications_usecase.dart';
|
||||
import '../models/client_notification_dto.dart';
|
||||
|
||||
class NotificationRepositoryImpl implements NotificationRepository {
|
||||
@@ -35,19 +37,27 @@ class NotificationRepositoryImpl implements NotificationRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ClientNotification>> getNotifications() async {
|
||||
Future<NotificationsResult> getNotifications({
|
||||
int page = 1,
|
||||
int pageSize = 10,
|
||||
}) async {
|
||||
try {
|
||||
final List<Map<String, dynamic>> data = await _apiService.getNotifications();
|
||||
final notifications = data.map((json) {
|
||||
final dto = ClientNotificationDto.fromJson(json);
|
||||
return dto.toEntity();
|
||||
}).toList();
|
||||
final response = await _apiService.getNotifications(
|
||||
page: page,
|
||||
pageSize: pageSize,
|
||||
);
|
||||
|
||||
// dev.log('NotificationRepository: Загружено ${notifications.length} уведомлений');
|
||||
final notifications = (response['data'] as List)
|
||||
.map((json) => ClientNotificationDto.fromJson(json).toEntity())
|
||||
.toList();
|
||||
|
||||
return notifications;
|
||||
final pagination = PaginationMeta.fromJson(response['pagination']);
|
||||
|
||||
return NotificationsResult(
|
||||
notifications: notifications,
|
||||
pagination: pagination,
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
// dev.log('NotificationRepository: Ошибка: $e', stackTrace: stackTrace);
|
||||
throw Exception('Не удалось загрузить уведомления: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,15 +192,11 @@ class ScooterRepositoryImpl extends ScooterRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Result<ScooterOrder>> cancelRide(int orderId) async {
|
||||
late final Result<ScooterOrder> result;
|
||||
Future<Result<void>> cancelRide(int orderId) async {
|
||||
late final Result<void> result;
|
||||
try {
|
||||
final order = await _apiService.cancelRide(orderId);
|
||||
if (order != null) {
|
||||
result = Success(order);
|
||||
} else {
|
||||
result = Failure(UnknownFailure("Неизвестная ошибка"));
|
||||
}
|
||||
await _apiService.cancelRide(orderId);
|
||||
result = Success(null);
|
||||
} on AuthException catch (e) {
|
||||
result = Failure(AuthFailure(e.attemptsLeft));
|
||||
} catch (e) {
|
||||
@@ -246,18 +242,11 @@ class ScooterRepositoryImpl extends ScooterRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Result<ScooterOrder>> finishRide(int orderId, List<int> files) async {
|
||||
Future<Result<void>> finishRide(int orderId, List<int> files) async {
|
||||
late final Result<ScooterOrder> result;
|
||||
try {
|
||||
final order = await _apiService.finishRide(
|
||||
orderId: orderId,
|
||||
filesId: files,
|
||||
);
|
||||
if (order != null) {
|
||||
result = Success(order);
|
||||
} else {
|
||||
result = Failure(UnknownFailure("Неизвестная ошибка"));
|
||||
}
|
||||
await _apiService.finishRide(orderId: orderId, filesId: files);
|
||||
result = Success(null);
|
||||
} on AuthException catch (e) {
|
||||
result = Failure(AuthFailure(e.attemptsLeft));
|
||||
} on WrongZoneException catch (e) {
|
||||
@@ -274,7 +263,6 @@ class ScooterRepositoryImpl extends ScooterRepository {
|
||||
try {
|
||||
await _apiService.payRide(orderId);
|
||||
result = Success(null);
|
||||
|
||||
} on AuthException catch (e) {
|
||||
result = Failure(AuthFailure(e.attemptsLeft));
|
||||
} catch (e) {
|
||||
@@ -345,7 +333,7 @@ class ScooterRepositoryImpl extends ScooterRepository {
|
||||
cardId: cardId,
|
||||
isBalance: isBalance,
|
||||
);
|
||||
result = Success(null);
|
||||
result = Success(null);
|
||||
} on AuthException catch (e) {
|
||||
result = Failure(AuthFailure(e.attemptsLeft));
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user