- 新增 ParentalConsentPage: 显示隐私政策要点 + 双重确认复选框 - 角色选择流程: 学生 → 家长同意确认 → 班级码输入 - Authenticated 状态: 添加 needsParentalConsent/parentalConsentAt/selectedRole - ParentalConsentAccepted 事件: 记录同意时间戳 - 路由守卫: 注册 /parental-consent 路径和重定向逻辑 - 非学生角色(老师/家长/独立用户)不需要经过同意流程 审计 ID: S-03
108 lines
2.8 KiB
Dart
108 lines
2.8 KiB
Dart
// 认证状态 — AuthBloc 输出的 UI 状态
|
||
|
||
part of 'auth_bloc.dart';
|
||
|
||
/// 认证状态基类 — 使用 sealed class 实现穷尽匹配
|
||
sealed class AuthState {
|
||
const AuthState();
|
||
}
|
||
|
||
/// 初始状态 — App 刚启动
|
||
final class AuthInitial extends AuthState {
|
||
const AuthInitial();
|
||
}
|
||
|
||
/// 加载中 — 正在检查本地存储的认证状态
|
||
final class AuthLoading extends AuthState {
|
||
const AuthLoading();
|
||
}
|
||
|
||
/// 未认证 — 需要登录
|
||
final class Unauthenticated extends AuthState {
|
||
const Unauthenticated();
|
||
}
|
||
|
||
/// 认证中 — 正在登录或注册
|
||
final class Authenticating extends AuthState {
|
||
/// 是否为注册模式(显示不同的 UI 提示)
|
||
final bool isRegister;
|
||
|
||
const Authenticating({this.isRegister = false});
|
||
}
|
||
|
||
/// 已认证 — 用户已登录
|
||
final class Authenticated extends AuthState {
|
||
final User user;
|
||
|
||
/// 是否需要角色选择(新注册用户还没有角色)
|
||
final bool needsRoleSelection;
|
||
|
||
/// 是否需要家长/监护人同意(PIPL 第28条 — 学生角色)
|
||
final bool needsParentalConsent;
|
||
|
||
/// 是否需要班级码加入(学生/家长角色)
|
||
final bool needsClassCode;
|
||
|
||
/// 是否正在加载(班级码验证中)
|
||
final bool isLoading;
|
||
|
||
/// 班级码验证错误信息
|
||
final String? classCodeError;
|
||
|
||
/// 已选择的角色(角色选择后暂存)
|
||
final UserRoleType? selectedRole;
|
||
|
||
/// 家长同意时间戳
|
||
final DateTime? parentalConsentAt;
|
||
|
||
const Authenticated({
|
||
required this.user,
|
||
this.needsRoleSelection = false,
|
||
this.needsParentalConsent = false,
|
||
this.needsClassCode = false,
|
||
this.isLoading = false,
|
||
this.classCodeError,
|
||
this.selectedRole,
|
||
this.parentalConsentAt,
|
||
});
|
||
|
||
Authenticated copyWith({
|
||
User? user,
|
||
bool? needsRoleSelection,
|
||
bool? needsParentalConsent,
|
||
bool? needsClassCode,
|
||
bool? isLoading,
|
||
String? classCodeError,
|
||
UserRoleType? selectedRole,
|
||
DateTime? parentalConsentAt,
|
||
}) =>
|
||
Authenticated(
|
||
user: user ?? this.user,
|
||
needsRoleSelection: needsRoleSelection ?? this.needsRoleSelection,
|
||
needsParentalConsent:
|
||
needsParentalConsent ?? this.needsParentalConsent,
|
||
needsClassCode: needsClassCode ?? this.needsClassCode,
|
||
isLoading: isLoading ?? this.isLoading,
|
||
classCodeError: classCodeError,
|
||
selectedRole: selectedRole ?? this.selectedRole,
|
||
parentalConsentAt: parentalConsentAt ?? this.parentalConsentAt,
|
||
);
|
||
}
|
||
|
||
/// 认证错误 — 登录/注册失败
|
||
final class AuthError extends AuthState {
|
||
final String message;
|
||
|
||
/// 是否可以重试
|
||
final bool retryable;
|
||
|
||
const AuthError(this.message, {this.retryable = true});
|
||
}
|
||
|
||
/// 需要家长授权 — 未满 14 岁用户需要家长确认
|
||
final class ParentAuthRequired extends AuthState {
|
||
final User user;
|
||
|
||
const ParentAuthRequired(this.user);
|
||
}
|