| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:flutter_secure_storage/flutter_secure_storage.dart';
- import '../../core/network/dio_client.dart';
- import '../services/auth_service.dart';
- export '../services/auth_service.dart'
- show CheckAccountForRegisterResult, LoginResult;
- const _kToken = 'auth_token';
- const _kUid = 'auth_uid';
- const _kEmail = 'auth_email';
- /// 认证仓库:持久化 Token,对外暴露登录状态
- class AuthRepository {
- const AuthRepository(this._service, this._storage);
- final AuthService _service;
- final FlutterSecureStorage _storage;
- // ── Token 读写 ──────────────────────────────────────────
- Future<String?> getToken() => _storage.read(key: _kToken);
- Future<bool> get isLoggedIn async {
- final token = await _storage.read(key: _kToken);
- return token != null && token.isNotEmpty;
- }
- Future<void> _saveSession(LoginResult result) async {
- await Future.wait([
- _storage.write(key: _kToken, value: result.token),
- if (result.uid != null) _storage.write(key: _kUid, value: result.uid!),
- if (result.email != null)
- _storage.write(key: _kEmail, value: result.email!),
- ]);
- updateCachedToken(result.token); // 同步更新内存缓存
- }
- /// 清除本地登录态(session 过期时直接调用,不请求接口)
- Future<void> clearSession() => _clearSession();
- Future<void> _clearSession() async {
- updateCachedToken(null); // 立即清除内存缓存,防止并发请求带旧 token
- await Future.wait([
- _storage.delete(key: _kToken),
- _storage.delete(key: _kUid),
- _storage.delete(key: _kEmail),
- ]);
- }
- // ── 登录流程 ────────────────────────────────────────────
- /// 登录发码前校验密码
- Future<void> checkLoginPassword({
- required String email,
- required String password,
- }) =>
- _service.checkLoginPassword(username: email, password: password);
- /// 注册发码前校验账号是否已存在
- Future<CheckAccountForRegisterResult> checkAccountForRegister(
- String email,
- ) =>
- _service.checkAccountForRegister(email);
- /// 发送登录邮箱验证码
- Future<void> sendLoginCode(String email) =>
- _service.sendLoginEmailCode(email);
- /// 密码+验证码登录
- Future<LoginResult> loginWithPassword({
- required String email,
- required String password,
- required String code,
- String vtype = '2',
- }) async {
- final result = await _service.loginWithPassword(
- email: email,
- password: password,
- code: code,
- vtype: vtype,
- );
- await _saveSession(result);
- return result;
- }
- // ── 注册流程 ────────────────────────────────────────────
- /// 发送注册邮箱验证码
- Future<void> sendRegisterCode(String email) =>
- _service.sendRegisterEmailCode(email);
- /// 邮箱注册
- Future<void> registerWithEmail({
- required String email,
- required String password,
- required String code,
- String? inviteCode,
- }) async {
- await _service.registerWithEmail(
- email: email,
- password: password,
- code: code,
- inviteCode: inviteCode,
- );
- }
- // ── 忘记密码流程 ────────────────────────────────────────
- /// 发送重置密码邮箱验证码
- Future<void> sendResetCode(String email) =>
- _service.sendResetEmailCode(email);
- /// 重置密码
- Future<void> resetPassword({
- required String email,
- required String password,
- required String code,
- }) async {
- await _service.resetPassword(
- email: email,
- password: password,
- code: code,
- );
- }
- // ── 退出登录 ────────────────────────────────────────────
- Future<void> logout() async {
- // 先清除本地 token,防止 logout 接口返回 4000 时 Dio 拦截器误触发过期弹窗
- await _clearSession();
- try {
- await _service.logout();
- } catch (_) {
- // 接口失败不影响本地登出(token 可能已过期)
- }
- }
- /// 读取登录时保存在本地的 uid(登录时必定写入,可作可靠兜底)
- Future<String?> getSavedUid() => _storage.read(key: _kUid);
- // ── 获取用户信息 ────────────────────────────────────────
- Future<Map<String, dynamic>> getMyInfo() => _service.getMyInfo();
- }
- // ── Providers ──────────────────────────────────────────────
- final authServiceProvider = Provider<AuthService>((ref) {
- final dio = ref.watch(dioClientProvider);
- return AuthService(dio);
- });
- final authRepositoryProvider = Provider<AuthRepository>((ref) {
- final service = ref.watch(authServiceProvider);
- final storage = ref.watch(secureStorageProvider);
- return AuthRepository(service, storage);
- });
|