228 lines
6.3 KiB
Dart
228 lines
6.3 KiB
Dart
|
||
import 'dart:convert';
|
||
import 'package:flutter/foundation.dart';
|
||
import 'package:novyronst/common/api/user_request.dart';
|
||
import 'package:shared_preferences/shared_preferences.dart';
|
||
|
||
class HelpToken {
|
||
static final HelpToken _instance = HelpToken._internal();
|
||
factory HelpToken() => _instance;
|
||
HelpToken._internal();
|
||
|
||
static const String _keyToken = 'SKY_STORE_TOKEN';
|
||
static const String _keyUserInfo = 'SKY_STORE_USER_INFO';
|
||
|
||
String? _cachedToken;
|
||
Map<String, dynamic>? _cachedUserInfo;
|
||
|
||
|
||
/// 获取 Token(从内存或存储)
|
||
String get() {
|
||
if (_cachedToken != null) {
|
||
return _cachedToken!;
|
||
}
|
||
// 如果内存中没有,从存储中加载
|
||
_cachedToken = _getFromStorage(_keyToken);
|
||
return _cachedToken ?? '';
|
||
}
|
||
|
||
/// 保存 Token(到内存和存储)
|
||
void save(String token) {
|
||
if (token.isNotEmpty) {
|
||
_cachedToken = token;
|
||
_saveToStorage(_keyToken, token);
|
||
}
|
||
}
|
||
|
||
/// 清除 Token(从内存和存储)
|
||
void clear() {
|
||
_cachedToken = null;
|
||
_removeFromStorage(_keyToken);
|
||
_cachedUserInfo = null;
|
||
_removeFromStorage(_keyUserInfo);
|
||
}
|
||
|
||
/// 刷新 Token(调用注册接口获取新 Token)
|
||
/// 注意:这里需要传入一个刷新函数,因为原项目依赖 GlimzoRequestUser
|
||
Future<void> update() async {
|
||
try {
|
||
final res = await UserRequest.register();
|
||
if (res == null) return;
|
||
final newToken = res.token;
|
||
if (newToken.isNotEmpty ?? false) {
|
||
// 保存新 Token
|
||
save(newToken);
|
||
// 如果返回了用户信息,也一并保存
|
||
// if (res['userInfo'] != null) {
|
||
// saveUserInfo(res['userInfo']);
|
||
// }
|
||
} else {
|
||
throw Exception('Invalid token response');
|
||
}
|
||
} catch (e) {
|
||
debugPrint('[TokenManager] Error updating token: $e');
|
||
rethrow;
|
||
}
|
||
}
|
||
|
||
// ============ 便捷属性 ============
|
||
|
||
/// 判断 Token 是否为空
|
||
bool get isEmpty => get().isEmpty;
|
||
|
||
/// 判断 Token 是否不为空
|
||
bool get isNotEmpty => !isEmpty;
|
||
|
||
/// 获取完整 Authorization 头
|
||
String? get authorizationHeader {
|
||
final token = get();
|
||
if (token.isNotEmpty) {
|
||
return 'Bearer $token';
|
||
}
|
||
return null;
|
||
}
|
||
|
||
// ============ 用户信息扩展(原项目没有,但建议加上) ============
|
||
|
||
/// 保存用户信息
|
||
void saveUserInfo(Map<String, dynamic> userInfo) {
|
||
_cachedUserInfo = userInfo;
|
||
_saveToStorage(_keyUserInfo, jsonEncode(userInfo));
|
||
}
|
||
|
||
/// 获取用户信息
|
||
Map<String, dynamic>? getUserInfo() {
|
||
if (_cachedUserInfo != null) {
|
||
return _cachedUserInfo;
|
||
}
|
||
final stored = _getFromStorage(_keyUserInfo);
|
||
if (stored != null && stored.isNotEmpty) {
|
||
try {
|
||
_cachedUserInfo = jsonDecode(stored) as Map<String, dynamic>;
|
||
return _cachedUserInfo;
|
||
} catch (_) {
|
||
return null;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
// ============ 私有存储方法 ============
|
||
|
||
String? _getFromStorage(String key) {
|
||
try {
|
||
// 使用 SharedPreferences 同步获取(但 SharedPreferences 是异步的)
|
||
// 为了保持与原项目一致的同步接口,这里使用异步转同步
|
||
// 但更好的方式是在初始化时预加载
|
||
return _getFromStorageSync(key);
|
||
} catch (e) {
|
||
debugPrint('[TokenManager] Error reading from storage: $e');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 同步读取(注意:SharedPreferences 本身是异步的,这里用同步方式需要谨慎)
|
||
String? _getFromStorageSync(String key) {
|
||
// 由于 SharedPreferences 是异步的,我们使用一个全局缓存
|
||
// 实际项目中建议在 main 中调用 init() 预加载
|
||
try {
|
||
// 这里为了简化,直接返回 null,实际应该用异步方式
|
||
// 建议使用下面的异步版本
|
||
return null;
|
||
} catch (_) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
void _saveToStorage(String key, String value) {
|
||
// 异步保存,不等待结果
|
||
_saveToStorageAsync(key, value);
|
||
}
|
||
|
||
void _removeFromStorage(String key) {
|
||
// 异步移除,不等待结果
|
||
_removeFromStorageAsync(key);
|
||
}
|
||
|
||
// ============ 异步存储方法(推荐使用) ============
|
||
|
||
/// 初始化:从存储中加载 Token
|
||
Future<void> init() async {
|
||
try {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
_cachedToken = prefs.getString(_keyToken);
|
||
|
||
final userInfoStr = prefs.getString(_keyUserInfo);
|
||
if (userInfoStr != null && userInfoStr.isNotEmpty) {
|
||
try {
|
||
_cachedUserInfo = jsonDecode(userInfoStr) as Map<String, dynamic>;
|
||
} catch (_) {
|
||
_cachedUserInfo = null;
|
||
}
|
||
}
|
||
} catch (e) {
|
||
debugPrint('[TokenManager] Init error: $e');
|
||
}
|
||
}
|
||
|
||
/// 异步获取 Token
|
||
Future<String> getAsync() async {
|
||
if (_cachedToken != null) {
|
||
return _cachedToken!;
|
||
}
|
||
try {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
_cachedToken = prefs.getString(_keyToken);
|
||
return _cachedToken ?? '';
|
||
} catch (e) {
|
||
debugPrint('[TokenManager] Get token error: $e');
|
||
return '';
|
||
}
|
||
}
|
||
|
||
/// 异步保存 Token
|
||
Future<void> saveAsync(String token) async {
|
||
if (token.isNotEmpty) {
|
||
_cachedToken = token;
|
||
try {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
await prefs.setString(_keyToken, token);
|
||
} catch (e) {
|
||
debugPrint('[TokenManager] Save token error: $e');
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 异步清除 Token
|
||
Future<void> clearAsync() async {
|
||
_cachedToken = null;
|
||
_cachedUserInfo = null;
|
||
try {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
await prefs.remove(_keyToken);
|
||
await prefs.remove(_keyUserInfo);
|
||
} catch (e) {
|
||
debugPrint('[TokenManager] Clear token error: $e');
|
||
}
|
||
}
|
||
|
||
// 异步保存到存储
|
||
Future<void> _saveToStorageAsync(String key, String value) async {
|
||
try {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
await prefs.setString(key, value);
|
||
} catch (e) {
|
||
debugPrint('[TokenManager] Save to storage error: $e');
|
||
}
|
||
}
|
||
|
||
// 异步从存储移除
|
||
Future<void> _removeFromStorageAsync(String key) async {
|
||
try {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
await prefs.remove(key);
|
||
} catch (e) {
|
||
debugPrint('[TokenManager] Remove from storage error: $e');
|
||
}
|
||
}
|
||
} |