泛型单例管理器
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();
///
/// // 获取当前数据
/// final user = manager.current;
/// ```
class SingleUserManager<T> {
/// 单例实例映射,使用类型字符串作为 key
static final Map<String, SingleUserManager> _instances = {};
/// 存储键名
final String storageKey;
/// 从 JSON 创建实例的函数
final T Function(Map<String, dynamic>) fromJson;
/// SharedPreferences 实例
SharedPreferences? _prefs;
/// 当前存储的数据
T? _currentData;
/// 是否已初始化
bool _isInitialized = false;
/// 私有构造函数
SingleUserManager._internal({
required this.storageKey,
required this.fromJson,
});
/// 获取单例实例
/// [storageKey] 存储键名,用于区分不同的管理器实例
/// [fromJson] 从 JSON 创建实例的函数
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>;
}
/// 获取当前存储的数据
T? get current => _currentData;
/// 检查是否已初始化
bool get isInitialized => _isInitialized;
/// 检查是否有数据
bool get hasData => _currentData != null;
/// 从本地存储初始化数据
/// 返回 true 表示成功加载数据,false 表示没有本地数据
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;
}
}
/// 更新当前数据
/// [data] 新的数据对象
Future<void> update(T data) async {
_currentData = data;
}
/// 保存当前数据到本地存储
/// 如果当前没有数据,则不会执行保存操作
Future<void> save() async {
if (_currentData == null) {
print('没有数据可保存 ($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('保存数据失败 ($storageKey): $e');
rethrow;
}
}
/// 更新并保存数据(便捷方法)
/// [data] 新的数据对象
Future<void> updateAndSave(T data) async {
await update(data);
await save();
}
/// 清除本地存储的数据
/// [clearCurrent] 是否同时清除当前内存中的数据,默认为 true
Future<void> clear({bool clearCurrent = true}) async {
try {
_prefs ??= await SharedPreferences.getInstance();
await _prefs!.remove(storageKey);
if (clearCurrent) {
_currentData = null;
}
} catch (e) {
print('清除数据失败 ($storageKey): $e');
rethrow;
}
}
/// 将数据转换为 JSON
/// 尝试动态调用 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 必须实现 toJson() 方法以支持序列化: $e');
}
}
}
/// 扩展方法:为实现了 toJson 的类型提供便捷的序列化支持
extension JsonSerializableExtension on Object {
/// 尝试将对象转换为 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. 初始化并加载本地数据
/// 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. 获取当前用户
/// final currentUser = userManager.current;
/// if (currentUser != null) {
/// print('当前用户: ${currentUser.name}');
/// }
///
/// // 5. 清除数据
/// 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);
/// ```