refactor(apps): 重构数据层目录结构并新增启动预热编排器
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
import '../../../../data/network/i_api_client.dart';
|
||||
import '../../../../data/cache/cache_policy.dart';
|
||||
import '../../../../data/cache/cached_repository.dart';
|
||||
import '../models/inbox_message.dart';
|
||||
|
||||
abstract class InboxRepository {
|
||||
Future<List<InboxMessage>> getMessages({bool? isRead});
|
||||
Future<InboxMessage> markAsRead(String messageId);
|
||||
}
|
||||
|
||||
class InboxRepositoryImpl extends CachedRepository<List<InboxMessage>>
|
||||
implements InboxRepository {
|
||||
final IApiClient _apiClient;
|
||||
static const _prefix = '/api/v1/inbox/messages';
|
||||
|
||||
InboxRepositoryImpl({required IApiClient apiClient, required super.store})
|
||||
: _apiClient = apiClient,
|
||||
super(
|
||||
policy: const CachePolicy(
|
||||
softTtl: Duration(seconds: 15),
|
||||
hardTtl: Duration(minutes: 2),
|
||||
minRefreshInterval: Duration(seconds: 10),
|
||||
),
|
||||
encodeValue: _encodeMessages,
|
||||
decodeValue: _decodeMessages,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<List<InboxMessage>> getMessages({bool? isRead}) async {
|
||||
return getOrLoad(
|
||||
key: _messagesKey(isRead),
|
||||
loadFromRemote: () => _loadMessagesFromRemote(isRead: isRead),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<InboxMessage>> _loadMessagesFromRemote({bool? isRead}) async {
|
||||
final queryParams = isRead != null ? '?is_read=$isRead' : '';
|
||||
final response = await _apiClient.get<List<dynamic>>(
|
||||
'$_prefix$queryParams',
|
||||
);
|
||||
final data = response.data;
|
||||
if (data == null) {
|
||||
throw StateError('Invalid getMessages response: empty payload');
|
||||
}
|
||||
return data
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map(InboxMessage.fromJson)
|
||||
.toList(growable: false);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<InboxMessage> markAsRead(String messageId) async {
|
||||
final response = await _apiClient.patch<Map<String, dynamic>>(
|
||||
'$_prefix/$messageId/read',
|
||||
);
|
||||
final data = response.data;
|
||||
if (data == null) {
|
||||
throw StateError('Invalid markAsRead response: empty payload');
|
||||
}
|
||||
final message = InboxMessage.fromJson(data);
|
||||
await Future.wait([
|
||||
removeCacheKey(_messagesKey(false)),
|
||||
removeCacheKey(_messagesKey(true)),
|
||||
removeCacheKey(_messagesKey(null)),
|
||||
]);
|
||||
return message;
|
||||
}
|
||||
|
||||
static String _messagesKey(bool? isRead) {
|
||||
if (isRead == null) {
|
||||
return 'inbox:list:all';
|
||||
}
|
||||
return isRead ? 'inbox:list:read' : 'inbox:list:unread';
|
||||
}
|
||||
|
||||
static Object? _encodeMessages(List<InboxMessage> messages) {
|
||||
return messages.map(_encodeMessage).toList(growable: false);
|
||||
}
|
||||
|
||||
static List<InboxMessage> _decodeMessages(Object? raw) {
|
||||
if (raw is! List) {
|
||||
throw const FormatException('Invalid cached inbox message payload');
|
||||
}
|
||||
return raw
|
||||
.whereType<Map>()
|
||||
.map((item) => InboxMessage.fromJson(Map<String, dynamic>.from(item)))
|
||||
.toList(growable: false);
|
||||
}
|
||||
|
||||
static Map<String, Object?> _encodeMessage(InboxMessage message) {
|
||||
return <String, Object?>{
|
||||
'id': message.id,
|
||||
'recipient_id': message.recipientId,
|
||||
'sender_id': message.senderId,
|
||||
'message_type': _messageTypeToApi(message.messageType),
|
||||
'schedule_item_id': message.scheduleItemId,
|
||||
'friendship_id': message.friendshipId,
|
||||
'content': message.content,
|
||||
'is_read': message.isRead,
|
||||
'status': _messageStatusToApi(message.status),
|
||||
'created_at': message.createdAt.toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
static String _messageTypeToApi(InboxMessageType type) {
|
||||
switch (type) {
|
||||
case InboxMessageType.friendRequest:
|
||||
return 'friend_request';
|
||||
case InboxMessageType.calendar:
|
||||
return 'calendar';
|
||||
case InboxMessageType.system:
|
||||
return 'system';
|
||||
case InboxMessageType.group:
|
||||
return 'group';
|
||||
}
|
||||
}
|
||||
|
||||
static String _messageStatusToApi(InboxMessageStatus status) {
|
||||
switch (status) {
|
||||
case InboxMessageStatus.pending:
|
||||
return 'pending';
|
||||
case InboxMessageStatus.accepted:
|
||||
return 'accepted';
|
||||
case InboxMessageStatus.rejected:
|
||||
return 'rejected';
|
||||
case InboxMessageStatus.dismissed:
|
||||
return 'dismissed';
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user