Files
ai_english/client/lib/shared/providers/notification_provider.dart
2025-11-17 14:09:17 +08:00

223 lines
5.8 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
});