| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- import 'dart:async';
- import 'dart:developer' as developer;
- import 'package:dio/dio.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import '../core/network/api_response.dart';
- import '../core/network/dio_client.dart';
- import '../data/services/auth_service.dart';
- // ── State ──────────────────────────────────────────────────
- class ChangePasswordState {
- final bool isLoading;
- final bool isSendingCode;
- final String? errorMessage;
- final int codeCooldown;
- const ChangePasswordState({
- this.isLoading = false,
- this.isSendingCode = false,
- this.errorMessage,
- this.codeCooldown = 0,
- });
- ChangePasswordState copyWith({
- bool? isLoading,
- bool? isSendingCode,
- String? errorMessage,
- int? codeCooldown,
- }) =>
- ChangePasswordState(
- isLoading: isLoading ?? this.isLoading,
- isSendingCode: isSendingCode ?? this.isSendingCode,
- errorMessage: errorMessage,
- codeCooldown: codeCooldown ?? this.codeCooldown,
- );
- }
- // ── Notifier ───────────────────────────────────────────────
- class ChangePasswordNotifier extends Notifier<ChangePasswordState> {
- AuthService get _service => AuthService(ref.read(dioClientProvider));
- Timer? _countdownTimer;
- @override
- ChangePasswordState build() {
- ref.onDispose(() => _countdownTimer?.cancel());
- return const ChangePasswordState();
- }
- void clearError() => state = state.copyWith(errorMessage: null);
- /// 发送邮箱验证码
- Future<bool> sendEmailCode() async {
- state = state.copyWith(isSendingCode: true, errorMessage: null);
- try {
- await _service.sendChangePasswordEmailCode();
- state = state.copyWith(isSendingCode: false);
- _startCountdown();
- return true;
- } catch (e) {
- state = state.copyWith(
- isSendingCode: false,
- errorMessage: _parseError(e),
- );
- return false;
- }
- }
- /// 提交修改登录密码
- Future<bool> changePassword({
- required String oldPassword,
- required String newPassword,
- required String vcode,
- }) async {
- state = state.copyWith(isLoading: true, errorMessage: null);
- try {
- await _service.changeLoginPassword(
- oldPassword: oldPassword,
- newPassword: newPassword,
- vcode: vcode,
- );
- state = state.copyWith(isLoading: false);
- return true;
- } catch (e) {
- state = state.copyWith(
- isLoading: false,
- errorMessage: _parseError(e),
- );
- return false;
- }
- }
- void _startCountdown() {
- _countdownTimer?.cancel();
- state = state.copyWith(codeCooldown: 60);
- _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
- final remaining = state.codeCooldown - 1;
- state = state.copyWith(codeCooldown: remaining);
- if (remaining <= 0) {
- timer.cancel();
- _countdownTimer = null;
- }
- });
- }
- String _parseError(Object e) {
- developer.log('ChangePassword error: $e', name: 'CHANGE_PWD', error: e);
- if (e is DioException) {
- if (e.error is ApiException) return (e.error as ApiException).message;
- final responseData = e.response?.data;
- if (responseData is Map<String, dynamic>) {
- final msg = responseData['message'] as String? ??
- responseData['msg'] as String?;
- if (msg != null && msg.isNotEmpty) return msg;
- }
- return e.message ?? 'errNetworkError';
- }
- if (e is ApiException) return e.message;
- return e.toString();
- }
- }
- // ── Provider ──────────────────────────────────────────────
- final changePasswordProvider =
- NotifierProvider<ChangePasswordNotifier, ChangePasswordState>(
- ChangePasswordNotifier.new,
- );
|