Files
customer-im-client-dev/apps/im_app/lib/features/login/presentation/login_state.dart
2026-03-09 19:05:55 +08:00

62 lines
1.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:freezed_annotation/freezed_annotation.dart';
part 'login_state.freezed.dart';
/// 登录流程的当前步骤
enum LoginStep {
/// 步骤 1输入手机号
phone,
/// 步骤 2输入验证码
otp,
}
/// 登录页面状态(@freezed 自动生成 copyWith / == / toString
///
/// ViewModel 通过 `state = state.copyWith(...)` 更新状态,
/// View 通过 `ref.watch(loginViewModelProvider)` 自动响应变化。
///
/// ## 状态流转
///
/// ```
/// 初始
/// → LoginState() step: phone, isLoading: false
/// 点击"获取验证码"
/// → state.copyWith(isLoading: true)
/// → 成功: state.copyWith(step: otp, contact: phone, isLoading: false)
/// → 失败: state.copyWith(error: '...', isLoading: false)
/// 点击"登录"
/// → state.copyWith(isLoading: true)
/// → 成功: authNotifierProvider.login() → 路由守卫重定向
/// → 失败: state.copyWith(error: '...', isLoading: false)
/// ```
@freezed
sealed class LoginState with _$LoginState {
const LoginState._();
const factory LoginState({
/// 当前步骤(手机号输入 or 验证码输入)
@Default(LoginStep.phone) LoginStep step,
/// 国家代码(默认 +65暂不支持切换
@Default('+65') String countryCode,
/// 已提交的手机号(步骤 2 用于显示和构建请求)
@Default('') String contact,
/// 是否正在请求中
@Default(false) bool isLoading,
/// 错误信息null = 无错误)
String? error,
}) = _LoginState;
/// 步骤 2 显示的脱敏手机号,如 "138****0000"
String get maskedContact {
if (contact.length <= 4) return contact;
final tail = contact.substring(contact.length - 4);
final stars = '*' * (contact.length - 4);
return '$stars$tail';
}
}