- 同步商城 H5 登录态与原生 token - 完善商城/原生 tab 切换、动画及返回交互 - 修复七鱼客服键盘避让和状态栏恢复 - 调整开屏跳过按钮与登录入口交互
93 lines
2.7 KiB
Dart
93 lines
2.7 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
|
|
import '../../../common/network/auth_interceptor.dart';
|
|
import '../../../common/storage/storage_keys.dart';
|
|
import '../../../common/storage/storage_service.dart';
|
|
import '../../../common/network/dio_provider.dart';
|
|
import '../data/auth_models.dart';
|
|
import '../data/auth_api.dart';
|
|
import '../data/one_key_login_api.dart';
|
|
|
|
final authProvider =
|
|
StateNotifierProvider<AuthController, AsyncValue<AuthState>>(
|
|
(ref) => AuthController(ref.read(dioProvider)),
|
|
);
|
|
|
|
class AuthController extends StateNotifier<AsyncValue<AuthState>> {
|
|
AuthController(this._dio) : super(const AsyncLoading()) {
|
|
_bootstrap();
|
|
}
|
|
|
|
final Dio _dio;
|
|
|
|
Future<void> _bootstrap() async {
|
|
final token = await loadJwt();
|
|
if (token == null || token.isEmpty) {
|
|
state = const AsyncData(GuestAuthState());
|
|
return;
|
|
}
|
|
final phone = StorageService.to.getString(storageJinzhiMockLoggedIn) ?? '';
|
|
state = AsyncData(
|
|
LoggedInAuthState(
|
|
user: JinzhiUser(
|
|
phone: phone.isEmpty ? '13800000000' : phone,
|
|
nickname: '金值用户',
|
|
createdAt: DateTime(2026, 6, 18),
|
|
),
|
|
token: token,
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> sendCode(String phone) async {
|
|
await AuthApi(_dio).sendSmsCode(phone);
|
|
}
|
|
|
|
Future<void> verifyCode(String phone, String code) async {
|
|
final reply = await AuthApi(_dio).verifySmsCode(phone, code);
|
|
await saveJwt(reply.accessToken);
|
|
await StorageService.to.setString(storageJinzhiMockLoggedIn, reply.phone);
|
|
state = AsyncData(
|
|
LoggedInAuthState(
|
|
user: JinzhiUser(
|
|
phone: reply.phone,
|
|
nickname: '金值用户',
|
|
createdAt: DateTime.now(),
|
|
),
|
|
token: reply.accessToken,
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Test environment reuses Yanting's one-key verification endpoint until
|
|
/// 金值 has its own account contract.
|
|
Future<void> verifyOneKeyLogin(String loginToken) async {
|
|
final reply = await OneKeyLoginApi(_dio).verify(loginToken);
|
|
await saveJwt(reply.token);
|
|
await StorageService.to.setString(storageJinzhiMockLoggedIn, reply.phone);
|
|
state = AsyncData(
|
|
LoggedInAuthState(
|
|
user: JinzhiUser(
|
|
phone: reply.phone,
|
|
nickname: '金值用户',
|
|
createdAt: DateTime.now(),
|
|
),
|
|
token: reply.token,
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> logout() async {
|
|
await clearJwt();
|
|
await StorageService.to.setString(storageJinzhiMockLoggedIn, '');
|
|
state = const AsyncData(GuestAuthState());
|
|
}
|
|
|
|
Future<void> deleteAccount([String? code]) async {
|
|
await logout();
|
|
}
|
|
|
|
bool get isLoggedIn => state.valueOrNull is LoggedInAuthState;
|
|
}
|