import 'dart:async'; import 'package:flutter/widgets.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/di/injection.dart'; import '../../core/services/notification_service.dart'; import 'user_providers.dart'; /// ==================== 通知服务 Provider ==================== /// NotificationService 单例 Provider(从 GetIt 获取 ApiClient 构建) final notificationServiceProvider = Provider((ref) { return NotificationService(apiClient: getIt()); }); /// ==================== 未读通知角标 ==================== /// 未读通知数量状态 class NotificationBadgeState { final int unreadCount; final bool isLoading; const NotificationBadgeState({ this.unreadCount = 0, this.isLoading = false, }); NotificationBadgeState copyWith({ int? unreadCount, bool? isLoading, }) { return NotificationBadgeState( unreadCount: unreadCount ?? this.unreadCount, isLoading: isLoading ?? this.isLoading, ); } } /// 未读通知数量管理器 /// /// 功能: /// - 初始化时立即加载未读数量 /// - 每 30 秒自动轮询刷新 /// - 监听 App 生命周期,前台恢复时立即刷新 /// - 提供手动刷新、递减、清零方法供其他组件调用 /// /// 数据源:通过 [NotificationService.getUnreadCount] 调用后端 API /// 用户标识:从 [currentAccountSequenceProvider] 获取当前登录用户的 accountSequence class NotificationBadgeNotifier extends StateNotifier with WidgetsBindingObserver { final NotificationService _notificationService; final Ref _ref; Timer? _refreshTimer; /// 定时刷新间隔(30秒,与 1.0 一致) static const _refreshIntervalSeconds = 30; NotificationBadgeNotifier(this._notificationService, this._ref) : super(const NotificationBadgeState()) { // 监听 App 生命周期 WidgetsBinding.instance.addObserver(this); // 初始化时立即加载未读数量 _loadUnreadCount(); // 启动定时刷新 _startAutoRefresh(); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); _refreshTimer?.cancel(); super.dispose(); } /// App 从后台切回前台时立即刷新 @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { debugPrint('[NotificationBadge] App 恢复前台,刷新未读数量'); _loadUnreadCount(); } } /// 启动 30 秒自动轮询 void _startAutoRefresh() { _refreshTimer?.cancel(); _refreshTimer = Timer.periodic( const Duration(seconds: _refreshIntervalSeconds), (_) => _loadUnreadCount(), ); debugPrint('[NotificationBadge] 自动刷新已启动 (间隔: ${_refreshIntervalSeconds}s)'); } /// 停止自动刷新(账号切换时调用,避免混账号请求) void stopAutoRefresh() { _refreshTimer?.cancel(); _refreshTimer = null; debugPrint('[NotificationBadge] 自动刷新已停止(切换账号)'); } /// 从后端加载未读通知数量 Future _loadUnreadCount() async { try { // 使用 2.0 的 currentAccountSequenceProvider 获取用户账号 final accountSequence = _ref.read(currentAccountSequenceProvider); if (accountSequence == null || accountSequence.isEmpty) { state = state.copyWith(unreadCount: 0); return; } state = state.copyWith(isLoading: true); final count = await _notificationService.getUnreadCount( userSerialNum: accountSequence, ); state = state.copyWith( unreadCount: count, isLoading: false, ); debugPrint('[NotificationBadge] 未读通知数量: $count'); } catch (e) { debugPrint('[NotificationBadge] 加载未读数量失败: $e'); state = state.copyWith(isLoading: false); } } /// 手动刷新未读数量 Future refresh() async { await _loadUnreadCount(); } /// 更新未读数量(本地同步) void updateCount(int count) { state = state.copyWith(unreadCount: count); } /// 减少未读数量(标记单条已读后调用) void decrementCount() { if (state.unreadCount > 0) { state = state.copyWith(unreadCount: state.unreadCount - 1); } } /// 清空未读数量(全部标记已读后调用) void clearCount() { state = state.copyWith(unreadCount: 0); } } /// 未读通知角标 Provider final notificationBadgeProvider = StateNotifierProvider( (ref) { final notificationService = ref.watch(notificationServiceProvider); return NotificationBadgeNotifier(notificationService, ref); }); /// 便捷 Provider: 只获取未读数量(供 UI 直接使用) final unreadNotificationCountProvider = Provider((ref) { return ref.watch(notificationBadgeProvider).unreadCount; });