Files
eryao/apps/lib/features/notifications/data/apis/notification_api.dart
T

122 lines
3.5 KiB
Dart
Raw Normal View History

2026-04-10 18:50:08 +08:00
import 'package:dio/dio.dart';
import '../../../../core/logging/logger.dart';
import '../../../../core/network/api_problem.dart';
import '../../../../data/network/api_client.dart';
import '../models/notification_item.dart';
import '../models/notification_list_result.dart';
class NotificationApi {
NotificationApi({required ApiClient apiClient}) : _apiClient = apiClient;
final ApiClient _apiClient;
final Logger _logger = getLogger('features.notifications.data.apis');
Future<NotificationListResult> listNotifications({
int limit = 20,
String? cursor,
String locale = 'zh',
2026-04-10 18:50:08 +08:00
}) async {
final queryParameters = <String, Object>{'limit': limit, 'locale': locale};
2026-04-10 18:50:08 +08:00
if (cursor != null) {
queryParameters['cursor'] = cursor;
2026-04-10 18:50:08 +08:00
}
try {
final response = await _apiClient.rawDio.get<Map<String, dynamic>>(
'/api/v1/notifications',
queryParameters: queryParameters,
);
final json = response.data ?? <String, dynamic>{};
2026-04-10 18:50:08 +08:00
final itemsJson = json['items'] as List<dynamic>? ?? [];
final items = itemsJson
.map((e) => parseNotificationItem(e as Map<String, dynamic>))
.toList();
return NotificationListResult(
items: items,
nextCursor: json['nextCursor'] as String?,
hasMore: json['hasMore'] as bool? ?? false,
);
} on DioException catch (error, stackTrace) {
_logger.error(
message: 'List notifications failed',
error: error,
stackTrace: stackTrace,
);
throw _mapProblem(error);
}
}
Future<int> getUnreadCount() async {
try {
final json = await _apiClient.getJson(
'/api/v1/notifications/unread-count',
);
return json['count'] as int? ?? 0;
} on DioException catch (error, stackTrace) {
_logger.error(
message: 'Get unread count failed',
error: error,
stackTrace: stackTrace,
);
throw _mapProblem(error);
}
}
Future<NotificationItem> markRead({
required String notificationId,
String locale = 'zh',
}) async {
2026-04-10 18:50:08 +08:00
try {
final response = await _apiClient.rawDio.patch<Map<String, dynamic>>(
'/api/v1/notifications/$notificationId/read',
queryParameters: {'locale': locale},
2026-04-10 18:50:08 +08:00
);
return parseNotificationItem(response.data!);
2026-04-10 18:50:08 +08:00
} on DioException catch (error, stackTrace) {
_logger.error(
message: 'Mark read failed',
error: error,
stackTrace: stackTrace,
);
throw _mapProblem(error);
}
}
Future<int> markAllRead() async {
try {
final response = await _apiClient.rawDio.patch<Map<String, dynamic>>(
'/api/v1/notifications/mark-all-read',
);
return response.data?['updatedCount'] as int? ?? 0;
2026-04-10 18:50:08 +08:00
} on DioException catch (error, stackTrace) {
_logger.error(
message: 'Mark all read failed',
error: error,
stackTrace: stackTrace,
);
throw _mapProblem(error);
}
}
ApiProblem _mapProblem(DioException error) {
final status = error.response?.statusCode ?? 500;
final data = error.response?.data;
if (data is Map<String, dynamic>) {
return ApiProblem(
status: status,
title: (data['title'] as String?) ?? 'Request failed',
detail: (data['detail'] as String?) ?? '',
code: data['code'] as String?,
);
}
return ApiProblem(
status: status,
title: 'Network error',
detail: error.message ?? 'Request failed',
);
}
}