泛型單例管理器
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
/// 泛型單例管理器
/// 用于管理不同類型用戶模型的本地存儲和更新
///
/// 使用示例:
/// ```dart
/// class UserModel {
/// final String id;
/// final String name;
///
/// UserModel({required this.id, required this.name});
///
/// factory UserModel.fromJson(Map<String, dynamic> json) {
/// return UserModel(
/// id: json['id'] as String,
/// name: json['name'] as String,
/// );
/// }
///
/// Map<String, dynamic> toJson() {
/// return {'id': id, 'name': name};
/// }
/// }
///
/// // 使用
/// final manager = SingleUserManager<UserModel>(
/// storageKey: 'user_manager',
/// fromJson: (json) => UserModel.fromJson(json),
/// );
///
/// // 初始化
/// await manager.initFromLocal();
///
/// // 更新
/// await manager.update(UserModel(id: '1', name: 'New Name'));
///
/// // 保存
/// await manager.save();
///
/// // 獲取當(dāng)前數(shù)據(jù)
/// final user = manager.current;
/// ```
class SingleUserManager<T> {
/// 單例實例映射,使用類型字符串作為 key
static final Map<String, SingleUserManager> _instances = {};
/// 存儲鍵名
final String storageKey;
/// 從 JSON 創(chuàng)建實例的函數(shù)
final T Function(Map<String, dynamic>) fromJson;
/// SharedPreferences 實例
SharedPreferences? _prefs;
/// 當(dāng)前存儲的數(shù)據(jù)
T? _currentData;
/// 是否已初始化
bool _isInitialized = false;
/// 私有構(gòu)造函數(shù)
SingleUserManager._internal({
required this.storageKey,
required this.fromJson,
});
/// 獲取單例實例
/// [storageKey] 存儲鍵名,用于區(qū)分不同的管理器實例
/// [fromJson] 從 JSON 創(chuàng)建實例的函數(shù)
factory SingleUserManager({
required String storageKey,
required T Function(Map<String, dynamic>) fromJson,
}) {
final key = '$T$storageKey';
return _instances.putIfAbsent(
key,
() => SingleUserManager._internal(
storageKey: storageKey,
fromJson: fromJson,
),
)
as SingleUserManager<T>;
}
/// 獲取當(dāng)前存儲的數(shù)據(jù)
T? get current => _currentData;
/// 檢查是否已初始化
bool get isInitialized => _isInitialized;
/// 檢查是否有數(shù)據(jù)
bool get hasData => _currentData != null;
/// 從本地存儲初始化數(shù)據(jù)
/// 返回 true 表示成功加載數(shù)據(jù),false 表示沒有本地數(shù)據(jù)
Future<bool> initFromLocal() async {
try {
_prefs ??= await SharedPreferences.getInstance();
final jsonString = _prefs?.getString(storageKey);
if (jsonString != null && jsonString.isNotEmpty) {
final json = jsonDecode(jsonString) as Map<String, dynamic>;
_currentData = fromJson(json);
_isInitialized = true;
return true;
}
_isInitialized = true;
return false;
} catch (e) {
print('從本地初始化失敗 ($storageKey): $e');
_isInitialized = true;
_currentData = null;
return false;
}
}
/// 更新當(dāng)前數(shù)據(jù)
/// [data] 新的數(shù)據(jù)對象
Future<void> update(T data) async {
_currentData = data;
}
/// 保存當(dāng)前數(shù)據(jù)到本地存儲
/// 如果當(dāng)前沒有數(shù)據(jù),則不會執(zhí)行保存操作
Future<void> save() async {
if (_currentData == null) {
print('沒有數(shù)據(jù)可保存 ($storageKey)');
return;
}
try {
_prefs ??= await SharedPreferences.getInstance();
final json = _toJson(_currentData as T);
final jsonString = jsonEncode(json);
await _prefs!.setString(storageKey, jsonString);
} catch (e) {
print('保存數(shù)據(jù)失敗 ($storageKey): $e');
rethrow;
}
}
/// 更新并保存數(shù)據(jù)(便捷方法)
/// [data] 新的數(shù)據(jù)對象
Future<void> updateAndSave(T data) async {
await update(data);
await save();
}
/// 清除本地存儲的數(shù)據(jù)
/// [clearCurrent] 是否同時清除當(dāng)前內(nèi)存中的數(shù)據(jù),默認為 true
Future<void> clear({bool clearCurrent = true}) async {
try {
_prefs ??= await SharedPreferences.getInstance();
await _prefs!.remove(storageKey);
if (clearCurrent) {
_currentData = null;
}
} catch (e) {
print('清除數(shù)據(jù)失敗 ($storageKey): $e');
rethrow;
}
}
/// 將數(shù)據(jù)轉(zhuǎn)換為 JSON
/// 嘗試動態(tài)調(diào)用 toJson 方法
Map<String, dynamic> _toJson(T data) {
try {
final result = (data as dynamic).toJson();
if (result is Map<String, dynamic>) {
return result;
}
throw StateError('類型 $T 的 toJson() 方法必須返回 Map<String, dynamic>');
} catch (e) {
if (e is StateError) {
rethrow;
}
throw StateError('類型 $T 必須實現(xiàn) toJson() 方法以支持序列化: $e');
}
}
}
/// 擴展方法:為實現(xiàn)了 toJson 的類型提供便捷的序列化支持
extension JsonSerializableExtension on Object {
/// 嘗試將對象轉(zhuǎn)換為 JSON Map
Map<String, dynamic>? tryToJson() {
try {
final result = (this as dynamic).toJson();
if (result is Map<String, dynamic>) {
return result;
}
return null;
} catch (e) {
return null;
}
}
}
// ==================== 使用示例 ====================
/// 示例 1: 普通用戶模型
class ExampleUser {
final String id;
final String name;
final String? email;
ExampleUser({required this.id, required this.name, this.email});
factory ExampleUser.fromJson(Map<String, dynamic> json) {
return ExampleUser(
id: json['id'] as String,
name: json['name'] as String,
email: json['email'] as String?,
);
}
Map<String, dynamic> toJson() {
return {'id': id, 'name': name, if (email != null) 'email': email};
}
/// 獲取用戶管理器單例
static SingleUserManager<ExampleUser> get manager =>
SingleUserManager<ExampleUser>(
storageKey: 'example_user',
fromJson: (json) => ExampleUser.fromJson(json),
);
}
/// 示例 2: 商戶用戶模型
class ExampleMerchant {
final String merchantId;
final String merchantName;
final List<String> permissions;
final DateTime? lastLoginTime;
ExampleMerchant({
required this.merchantId,
required this.merchantName,
required this.permissions,
this.lastLoginTime,
});
factory ExampleMerchant.fromJson(Map<String, dynamic> json) {
return ExampleMerchant(
merchantId: json['merchantId'] as String,
merchantName: json['merchantName'] as String,
permissions: List<String>.from(json['permissions'] as List),
lastLoginTime: json['lastLoginTime'] != null
? DateTime.parse(json['lastLoginTime'] as String)
: null,
);
}
Map<String, dynamic> toJson() {
return {
'merchantId': merchantId,
'merchantName': merchantName,
'permissions': permissions,
if (lastLoginTime != null)
'lastLoginTime': lastLoginTime!.toIso8601String(),
};
}
/// 獲取商戶管理器單例
static SingleUserManager<ExampleMerchant> get manager =>
SingleUserManager<ExampleMerchant>(
storageKey: 'example_merchant',
fromJson: (json) => ExampleMerchant.fromJson(json),
);
}
/// 使用示例代碼(在實際項目中可以這樣使用):
///
/// ```dart
/// // 1. 初始化并加載本地數(shù)據(jù)
/// final userManager = ExampleUser.manager;
/// final hasLocalData = await userManager.initFromLocal();
/// if (hasLocalData) {
/// final user = userManager.current;
/// print('加載用戶: ${user?.name}');
/// }
///
/// // 2. 更新用戶信息
/// final newUser = ExampleUser(
/// id: '123',
/// name: '張三',
/// email: 'zhangsan@example.com',
/// );
/// await userManager.update(newUser);
///
/// // 3. 保存到本地
/// await userManager.save();
///
/// // 或者直接更新并保存
/// await userManager.updateAndSave(newUser);
///
/// // 4. 獲取當(dāng)前用戶
/// final currentUser = userManager.current;
/// if (currentUser != null) {
/// print('當(dāng)前用戶: ${currentUser.name}');
/// }
///
/// // 5. 清除數(shù)據(jù)
/// await userManager.clear();
///
/// // 6. 管理多個不同的用戶類型
/// final merchantManager = ExampleMerchant.manager;
/// await merchantManager.initFromLocal();
///
/// final merchant = ExampleMerchant(
/// merchantId: 'm001',
/// merchantName: '測試商戶',
/// permissions: ['read', 'write'],
/// lastLoginTime: DateTime.now(),
/// );
/// await merchantManager.updateAndSave(merchant);
/// ```