92 lines
2.5 KiB
Dart
92 lines
2.5 KiB
Dart
import 'dart:convert';
|
||
|
||
import 'package:http/http.dart' as http;
|
||
|
||
class AppNotification {
|
||
const AppNotification({
|
||
required this.id,
|
||
required this.type,
|
||
required this.title,
|
||
required this.body,
|
||
required this.createdAt,
|
||
this.resourceType,
|
||
this.resourceId,
|
||
this.readAt,
|
||
});
|
||
|
||
final String id;
|
||
final String type;
|
||
final String title;
|
||
final String body;
|
||
final String? resourceType;
|
||
final String? resourceId;
|
||
final DateTime createdAt;
|
||
final DateTime? readAt;
|
||
|
||
bool get isRead => readAt != null;
|
||
|
||
factory AppNotification.fromJson(Map<String, Object?> json) =>
|
||
AppNotification(
|
||
id: json['id']! as String,
|
||
type: json['type']! as String,
|
||
title: json['title']! as String,
|
||
body: json['body']! as String,
|
||
resourceType: json['resourceType'] as String?,
|
||
resourceId: json['resourceId'] as String?,
|
||
createdAt: DateTime.parse(json['createdAt']! as String),
|
||
readAt: json['readAt'] == null
|
||
? null
|
||
: DateTime.parse(json['readAt']! as String),
|
||
);
|
||
}
|
||
|
||
class NotificationRepository {
|
||
NotificationRepository({
|
||
http.Client? client,
|
||
this.baseUrl = const String.fromEnvironment(
|
||
'AIOA_API_BASE_URL',
|
||
defaultValue: 'http://127.0.0.1:8080/api/v1',
|
||
),
|
||
this.accessToken = const String.fromEnvironment('AIOA_ACCESS_TOKEN'),
|
||
}) : _client = client ?? http.Client();
|
||
|
||
final http.Client _client;
|
||
final String baseUrl;
|
||
final String accessToken;
|
||
|
||
Future<List<AppNotification>> list() async {
|
||
final response = await _client.get(
|
||
Uri.parse('$baseUrl/notifications'),
|
||
headers: _headers,
|
||
);
|
||
_requireSuccess(response);
|
||
return (jsonDecode(response.body) as List)
|
||
.map(
|
||
(item) =>
|
||
AppNotification.fromJson(Map<String, Object?>.from(item as Map)),
|
||
)
|
||
.toList();
|
||
}
|
||
|
||
Future<AppNotification> markRead(String id) async {
|
||
final response = await _client.post(
|
||
Uri.parse('$baseUrl/notifications/$id/read'),
|
||
headers: _headers,
|
||
);
|
||
_requireSuccess(response);
|
||
return AppNotification.fromJson(
|
||
jsonDecode(response.body) as Map<String, Object?>,
|
||
);
|
||
}
|
||
|
||
Map<String, String> get _headers => {
|
||
'Accept': 'application/json',
|
||
if (accessToken.isNotEmpty) 'Authorization': 'Bearer $accessToken',
|
||
};
|
||
|
||
void _requireSuccess(http.Response response) {
|
||
if (response.statusCode >= 200 && response.statusCode < 300) return;
|
||
throw Exception('通知请求失败(${response.statusCode})');
|
||
}
|
||
}
|