refactor(page): 删除旧版页面文件
This commit is contained in:
137
lib/features/auth/presentation/auth_controller.dart
Normal file
137
lib/features/auth/presentation/auth_controller.dart
Normal file
@@ -0,0 +1,137 @@
|
||||
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<AuthState> {
|
||||
AuthController();
|
||||
|
||||
Timer? _countdownTimer;
|
||||
|
||||
@override
|
||||
AuthState build() {
|
||||
ref.keepAlive();
|
||||
ref.onDispose(() => _countdownTimer?.cancel());
|
||||
return const AuthState();
|
||||
}
|
||||
|
||||
String get _deviceId => TokenStorage.deviceId;
|
||||
|
||||
/// 密码登录。
|
||||
Future<bool> loginByPassword({
|
||||
required String phone,
|
||||
required String password,
|
||||
}) async {
|
||||
return _run(() => ref.read(authRepositoryProvider).loginByPassword(
|
||||
phone: phone,
|
||||
password: password,
|
||||
deviceId: _deviceId,
|
||||
));
|
||||
}
|
||||
|
||||
/// 短信登录。
|
||||
Future<bool> loginBySms({
|
||||
required String phone,
|
||||
required String code,
|
||||
}) async {
|
||||
return _run(() => ref.read(authRepositoryProvider).loginBySms(
|
||||
phone: phone,
|
||||
code: code,
|
||||
deviceId: _deviceId,
|
||||
));
|
||||
}
|
||||
|
||||
/// 注册。
|
||||
Future<bool> 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<void> 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<bool> _run(Future<LoginResult> 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, AuthState>(AuthController.new);
|
||||
Reference in New Issue
Block a user