223 lines
5.8 KiB
Dart
223 lines
5.8 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import '../models/notification_model.dart';
|
||
import '../services/notification_service.dart';
|
||
|
||
/// 通知状态
|
||
class NotificationState {
|
||
final List<NotificationModel> notifications;
|
||
final int total;
|
||
final int unreadCount;
|
||
final bool isLoading;
|
||
final String? error;
|
||
|
||
NotificationState({
|
||
this.notifications = const [],
|
||
this.total = 0,
|
||
this.unreadCount = 0,
|
||
this.isLoading = false,
|
||
this.error,
|
||
});
|
||
|
||
NotificationState copyWith({
|
||
List<NotificationModel>? notifications,
|
||
int? total,
|
||
int? unreadCount,
|
||
bool? isLoading,
|
||
String? error,
|
||
}) {
|
||
return NotificationState(
|
||
notifications: notifications ?? this.notifications,
|
||
total: total ?? this.total,
|
||
unreadCount: unreadCount ?? this.unreadCount,
|
||
isLoading: isLoading ?? this.isLoading,
|
||
error: error,
|
||
);
|
||
}
|
||
}
|
||
|
||
/// 通知Notifier
|
||
class NotificationNotifier extends StateNotifier<NotificationState> {
|
||
final NotificationService _service = NotificationService();
|
||
|
||
NotificationNotifier() : super(NotificationState());
|
||
|
||
/// 加载通知列表
|
||
Future<void> loadNotifications({
|
||
int page = 1,
|
||
int limit = 10,
|
||
bool onlyUnread = false,
|
||
}) async {
|
||
state = state.copyWith(isLoading: true, error: null);
|
||
|
||
try {
|
||
final response = await _service.getNotifications(
|
||
page: page,
|
||
limit: limit,
|
||
onlyUnread: onlyUnread,
|
||
);
|
||
|
||
if (response.success && response.data != null) {
|
||
state = state.copyWith(
|
||
notifications: response.data!['notifications'] as List<NotificationModel>,
|
||
total: response.data!['total'] as int,
|
||
isLoading: false,
|
||
);
|
||
} else {
|
||
state = state.copyWith(
|
||
isLoading: false,
|
||
error: response.message,
|
||
);
|
||
}
|
||
} catch (e) {
|
||
state = state.copyWith(
|
||
isLoading: false,
|
||
error: '加载通知列表失败: $e',
|
||
);
|
||
}
|
||
}
|
||
|
||
/// 加载未读通知数量
|
||
Future<void> loadUnreadCount() async {
|
||
try {
|
||
final response = await _service.getUnreadCount();
|
||
|
||
if (response.success && response.data != null) {
|
||
state = state.copyWith(
|
||
unreadCount: response.data!,
|
||
);
|
||
}
|
||
} catch (e) {
|
||
print('加载未读通知数量失败: $e');
|
||
}
|
||
}
|
||
|
||
/// 标记通知为已读
|
||
Future<bool> markAsRead(int notificationId) async {
|
||
try {
|
||
final response = await _service.markAsRead(notificationId);
|
||
|
||
if (response.success) {
|
||
// 更新本地状态
|
||
final updatedNotifications = state.notifications.map((n) {
|
||
if (n.id == notificationId) {
|
||
return NotificationModel(
|
||
id: n.id,
|
||
userId: n.userId,
|
||
type: n.type,
|
||
title: n.title,
|
||
content: n.content,
|
||
link: n.link,
|
||
isRead: true,
|
||
priority: n.priority,
|
||
createdAt: n.createdAt,
|
||
readAt: DateTime.now(),
|
||
);
|
||
}
|
||
return n;
|
||
}).toList();
|
||
|
||
state = state.copyWith(
|
||
notifications: updatedNotifications,
|
||
unreadCount: state.unreadCount > 0 ? state.unreadCount - 1 : 0,
|
||
);
|
||
|
||
return true;
|
||
}
|
||
return false;
|
||
} catch (e) {
|
||
print('标记通知已读失败: $e');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// 标记所有通知为已读
|
||
Future<bool> markAllAsRead() async {
|
||
try {
|
||
final response = await _service.markAllAsRead();
|
||
|
||
if (response.success) {
|
||
// 更新本地状态
|
||
final updatedNotifications = state.notifications.map((n) {
|
||
return NotificationModel(
|
||
id: n.id,
|
||
userId: n.userId,
|
||
type: n.type,
|
||
title: n.title,
|
||
content: n.content,
|
||
link: n.link,
|
||
isRead: true,
|
||
priority: n.priority,
|
||
createdAt: n.createdAt,
|
||
readAt: DateTime.now(),
|
||
);
|
||
}).toList();
|
||
|
||
state = state.copyWith(
|
||
notifications: updatedNotifications,
|
||
unreadCount: 0,
|
||
);
|
||
|
||
return true;
|
||
}
|
||
return false;
|
||
} catch (e) {
|
||
print('标记所有通知已读失败: $e');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// 删除通知
|
||
Future<bool> deleteNotification(int notificationId) async {
|
||
try {
|
||
final response = await _service.deleteNotification(notificationId);
|
||
|
||
if (response.success) {
|
||
// 从本地状态中移除
|
||
final updatedNotifications =
|
||
state.notifications.where((n) => n.id != notificationId).toList();
|
||
|
||
// 如果删除的是未读通知,更新未读数量
|
||
final deletedNotification =
|
||
state.notifications.firstWhere((n) => n.id == notificationId);
|
||
final newUnreadCount = deletedNotification.isRead
|
||
? state.unreadCount
|
||
: (state.unreadCount > 0 ? state.unreadCount - 1 : 0);
|
||
|
||
state = state.copyWith(
|
||
notifications: updatedNotifications,
|
||
total: state.total - 1,
|
||
unreadCount: newUnreadCount,
|
||
);
|
||
|
||
return true;
|
||
}
|
||
return false;
|
||
} catch (e) {
|
||
print('删除通知失败: $e');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// 刷新通知列表
|
||
Future<void> refresh() async {
|
||
await loadNotifications();
|
||
await loadUnreadCount();
|
||
}
|
||
}
|
||
|
||
/// 通知Provider
|
||
final notificationProvider =
|
||
StateNotifierProvider<NotificationNotifier, NotificationState>(
|
||
(ref) => NotificationNotifier(),
|
||
);
|
||
|
||
/// 未读通知数量Provider(便捷访问)
|
||
final unreadCountProvider = Provider<int>((ref) {
|
||
return ref.watch(notificationProvider).unreadCount;
|
||
});
|
||
|
||
/// 通知列表Provider(便捷访问)
|
||
final notificationListProvider = Provider<List<NotificationModel>>((ref) {
|
||
return ref.watch(notificationProvider).notifications;
|
||
});
|