- 添加 Web/Windows 平台支持 (flutter create --platforms) - 下载字体资源 (NotoSansSC/Caveat Regular+Bold) - Isar 3.x Web 不兼容:添加 kIsWeb 守卫,Web 上跳过 Isar 初始化 - IsarJournalRepository: instance 返回 nullable,Web 上使用 RemoteJournalRepository - SyncEngine: persistPendingQueue/restorePendingQueue Web 安全 - SettingsBloc: 从 RepositoryProvider 改为 ListenableProvider - ApiClient base URL: 8080 → 3000 匹配后端端口 - Isar .g.dart: 64 位 ID 替换为 JS 安全范围值
89 lines
2.7 KiB
Dart
89 lines
2.7 KiB
Dart
// Isar 数据库初始化 — 本地持久化存储
|
||
//
|
||
// Isar 3.x 要求 open() 时传入 List<CollectionSchema>。
|
||
// 通过 build_runner 生成 Schema,在 main.dart 启动时调用 init()。
|
||
//
|
||
// ⚠️ Web 平台限制:Isar 3.x 暂不支持 Web。
|
||
// 在 Web 上跳过 Isar 初始化,使用纯内存/远程模式。
|
||
// 生产环境以移动端 (Android/iOS) 为主。
|
||
|
||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||
import 'package:isar/isar.dart';
|
||
import 'package:path_provider/path_provider.dart';
|
||
|
||
import 'collections/journal_entry_collection.dart';
|
||
import 'collections/journal_element_collection.dart';
|
||
import 'collections/pending_operation_collection.dart';
|
||
|
||
/// Isar 数据库单例管理
|
||
class IsarDatabase {
|
||
IsarDatabase._();
|
||
|
||
static Isar? _instance;
|
||
static bool _initialized = false;
|
||
|
||
/// 所有 Collection Schema(由 build_runner 生成)
|
||
static final List<CollectionSchema<dynamic>> schemas = [
|
||
JournalEntryCollectionSchema,
|
||
JournalElementCollectionSchema,
|
||
PendingOperationCollectionSchema,
|
||
];
|
||
|
||
/// 是否已初始化
|
||
static bool get isInitialized => _initialized;
|
||
|
||
/// Web 平台上 Isar 不可用,使用纯远程模式
|
||
static bool get isAvailable => !kIsWeb;
|
||
|
||
/// 初始化数据库
|
||
///
|
||
/// 在 main() 中调用,open 之前需确保 WidgetsFlutterBinding 已初始化。
|
||
/// Web 平台跳过 Isar 初始化(3.x 不支持 Web),仅使用远程 API。
|
||
static Future<void> init() async {
|
||
if (_initialized) return;
|
||
|
||
// Web 平台:Isar 3.x 不支持 Web,跳过本地数据库初始化
|
||
if (kIsWeb) {
|
||
_initialized = true;
|
||
return;
|
||
}
|
||
|
||
// 桌面/移动端:使用文件系统
|
||
final dir = await getApplicationDocumentsDirectory();
|
||
_instance = await Isar.open(
|
||
schemas,
|
||
directory: dir.path,
|
||
inspector: true, // 开发模式,发布时关闭
|
||
);
|
||
_initialized = true;
|
||
}
|
||
|
||
/// 获取 Isar 实例(必须先调用 [init])
|
||
///
|
||
/// Web 平台不可用时返回 null,调用方需检查 [isAvailable]。
|
||
static Isar? get instance {
|
||
if (kIsWeb) return null;
|
||
if (_instance == null || !_instance!.isOpen) {
|
||
throw StateError('IsarDatabase 未初始化,请先调用 IsarDatabase.init()');
|
||
}
|
||
return _instance!;
|
||
}
|
||
|
||
/// 关闭数据库连接
|
||
static Future<void> close() async {
|
||
if (_instance != null && _instance!.isOpen) {
|
||
await _instance!.close();
|
||
_instance = null;
|
||
_initialized = false;
|
||
}
|
||
}
|
||
|
||
/// 清空所有数据(仅用于测试)
|
||
static Future<void> clearAll() async {
|
||
if (_instance == null || !_instance!.isOpen) return;
|
||
await _instance!.writeTxn(() async {
|
||
await _instance!.clear();
|
||
});
|
||
}
|
||
}
|