feat(auth): 实现注册模块与登录页优化

1. 新增用户注册接口与页面,对齐Vue端业务逻辑
2. 新增居中Toast组件,替换原有SnackBar轻提示
3. 完善登录历史本地存储与下拉选择交互
4. 新增审核模式接口适配,动态控制注册入口显示
5. 优化登录页UI布局与交互细节
This commit is contained in:
崔宝新
2026-09-08 17:12:26 +08:00
parent f718749ad7
commit 955d6455d8
6 changed files with 1148 additions and 264 deletions
+68
View File
@@ -4,6 +4,44 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:new_learn/core/models/user_model.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
/// ============================================================
/// 【LoginHistoryItem】登录历史单条记录 —— 对齐 Vue loginHistory
///
/// account → 登录账号(唯一标识,重复登录时去重用)
/// userName → 登录后拿到的昵称(展示用,可能为空)
/// password → 记住的密码(明文,存在 secure_storage 里一条 JSON)
/// 空串 "" 表示本次没勾选记住密码
/// rememberPassword → 是否勾选了记住密码(决定密码是否回填)
/// ============================================================
class LoginHistoryItem {
const LoginHistoryItem({
required this.account,
required this.userName,
required this.password,
required this.rememberPassword,
});
final String account;
final String userName;
final String password;
final bool rememberPassword;
Map<String, dynamic> toJson() => {
'account': account,
'userName': userName,
'password': password,
'rememberPassword': rememberPassword,
};
factory LoginHistoryItem.fromJson(Map<String, dynamic> json) =>
LoginHistoryItem(
account: json['account'] as String? ?? '',
userName: json['userName'] as String? ?? '',
password: json['password'] as String? ?? '',
rememberPassword: json['rememberPassword'] as bool? ?? false,
);
}
/// ============================================================
/// 【UserStorage】用户本地存储(token 安全存储 + 用户信息缓存)
///
@@ -118,6 +156,36 @@ class UserStorage {
Future<void> clearRememberedPassword() =>
_secure.delete(key: _rememberedPasswordKey);
// ---------- 登录历史(多条,最多 3 条,对齐 Vue loginHistory) ----------
static const String _loginHistoryKey = 'login_history';
static const int _maxHistoryCount = 3;
/// 读取登录历史(没存过返回空列表)
Future<List<LoginHistoryItem>> readLoginHistory() async {
final raw = await _secure.read(key: _loginHistoryKey);
if (raw == null) return [];
try {
final list = jsonDecode(raw) as List<dynamic>;
return list
.map((e) => LoginHistoryItem.fromJson(e as Map<String, dynamic>))
.toList();
} catch (_) {
return []; // 缓存损坏时当没历史处理
}
}
/// 保存登录历史(整体替换存,最多保留 3 条)
Future<void> saveLoginHistory(List<LoginHistoryItem> items) async {
final trimmed = items.length > _maxHistoryCount
? items.sublist(0, _maxHistoryCount)
: items;
await _secure.write(
key: _loginHistoryKey,
value: jsonEncode(trimmed.map((e) => e.toJson()).toList()),
);
}
/// 一键退出登录:清 Token + 用户信息
/// (记住的账号密码保留,方便用户下次登录)
Future<void> clearAll() async {