import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/storage/token_storage.dart'; import '../data/auth_providers.dart'; import '../domain/auth_models.dart'; import '../domain/auth_state.dart'; /// 认证控制器。 /// /// 承载登录 / 注册 / 发送验证码 / 倒计时等全部业务逻辑,UI 仅触发动作并消费状态。 /// 使用 keepAlive,避免登录流程中页面切换导致状态丢失。 class AuthController extends Notifier { AuthController(); Timer? _countdownTimer; @override AuthState build() { ref.keepAlive(); ref.onDispose(() => _countdownTimer?.cancel()); return const AuthState(); } String get _deviceId => TokenStorage.deviceId; /// 密码登录。 Future loginByPassword({ required String phone, required String password, }) async { return _run(() => ref.read(authRepositoryProvider).loginByPassword( phone: phone, password: password, deviceId: _deviceId, )); } /// 短信登录。 Future loginBySms({ required String phone, required String code, }) async { return _run(() => ref.read(authRepositoryProvider).loginBySms( phone: phone, code: code, deviceId: _deviceId, )); } /// 注册。 Future register({ required String phone, required String code, required String password, }) async { return _run(() => ref.read(authRepositoryProvider).register( phone: phone, code: code, password: password, deviceId: _deviceId, )); } /// 发送短信验证码并启动 60s 倒计时。 Future sendSmsCode({ required String phone, required SmsScene scene, }) async { if (state.isSendingCode || state.countdownSeconds > 0) return; state = state.copyWith(isSendingCode: true, clearAlert: true); try { await ref.read(authRepositoryProvider).sendSmsCode( phone: phone, scene: scene, ); _startCountdown(); } catch (e) { state = state.copyWith( isSendingCode: false, alert: _messageOf(e), ); } } /// 消费一次性提示。 void consumeAlert() { if (state.alert != null) { state = state.copyWith(clearAlert: true); } } /// 登出。 void logout() { _countdownTimer?.cancel(); TokenStorage.clear(); state = const AuthState(); } Future _run(Future Function() action) async { state = state.copyWith(isLoading: true, clearAlert: true); try { await action(); state = state.copyWith(isLoading: false); return true; } catch (e) { state = state.copyWith(isLoading: false, alert: _messageOf(e)); return false; } } void _startCountdown() { state = state.copyWith(isSendingCode: false, countdownSeconds: 60); _countdownTimer?.cancel(); _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) { final left = state.countdownSeconds - 1; if (left <= 0) { timer.cancel(); state = state.copyWith(countdownSeconds: 0); } else { state = state.copyWith(countdownSeconds: left); } }); } String _messageOf(Object e) { if (e is Exception) { return e.toString().replaceFirst('Exception: ', ''); } return '操作失败,请稍后重试'; } } /// 认证控制器 Provider(会话级 keepAlive 在 build 内通过 ref.keepAlive 实现)。 final authControllerProvider = NotifierProvider(AuthController.new);