Flutter 数据层 (Phase F1): - journal_entry.dart: 日记数据模型 (Mood/Weather/tags/version) - journal_element.dart: 元素模型 (text/image/sticker/handwriting_ref/tape) - school_class.dart: 班级模型 - user_settings.dart: 用户设置 (主题/画笔/字号) - isar_database.dart: Isar 初始化 - api_client.dart: Dio + JWT注入 + 离线感知 + 401处理 - journal_repository.dart: 抽象接口 + InMemory实现 (乐观锁) - sync_engine.dart: WiFi同步 + 操作队列 + 重试(5次) + 快照持久化 Rust 班级系统 (Phase B3): - class_service.rs: 创建班级(6位码) + 加入班级 + 成员管理 - topic_service.rs: 老师布置主题 + 主题列表 - comment_service.rs: 老师点评 + 评语列表 - class_handler.rs: 5个API端点 + 权限守卫 - topic_handler.rs: 2个API端点 - comment_handler.rs: 2个API端点 - dto.rs: 新增5个DTO (ClassMemberResp/CreateTopicReq/TopicResp/CreateCommentReq/CommentResp) - 6条新路由注册 验证: cargo check 通过, 433测试全绿, flutter analyze 1 warning
83 lines
2.5 KiB
Dart
83 lines
2.5 KiB
Dart
// Isar 数据库初始化 — 本地持久化存储
|
||
//
|
||
// Isar 3.x 要求 open() 时传入 List<CollectionSchema> 位置参数。
|
||
// 由于我们使用手写不可变类而非 isar_generator 代码生成,
|
||
// 需要在调用 [init] 时传入 schema 列表。
|
||
// 当前阶段使用 [ensureInitialized] 占位,待后续添加 Isar Collection 后正式注册。
|
||
|
||
import 'package:isar/isar.dart';
|
||
import 'package:path_provider/path_provider.dart';
|
||
|
||
/// Isar 数据库单例管理
|
||
///
|
||
/// 使用方式(Phase 1 — 无 schema 时):
|
||
/// ```dart
|
||
/// // 直接使用,不初始化 Isar(内存仓库模式)
|
||
/// ```
|
||
///
|
||
/// 使用方式(Phase 2 — 有 schema 后):
|
||
/// ```dart
|
||
/// final isar = await IsarDatabase.init(schemas: [JournalEntrySchema]);
|
||
/// ```
|
||
class IsarDatabase {
|
||
IsarDatabase._();
|
||
|
||
static Isar? _instance;
|
||
static bool _initialized = false;
|
||
|
||
/// 是否已初始化
|
||
static bool get isInitialized => _initialized;
|
||
|
||
/// 初始化数据库(需在 app 启动时调用,传入所有 CollectionSchema)
|
||
///
|
||
/// - [schemas]: Isar Collection Schema 列表(由 isar_generator 生成)
|
||
/// - 在应用文档目录下创建 isar 数据库文件
|
||
/// - 开发模式开启 inspector(flutter pub global run isar_inspector)
|
||
static Future<Isar> init({
|
||
required List<CollectionSchema<dynamic>> schemas,
|
||
}) async {
|
||
if (_instance != null && _instance!.isOpen) return _instance!;
|
||
|
||
final dir = await getApplicationDocumentsDirectory();
|
||
|
||
_instance = await Isar.open(
|
||
schemas,
|
||
directory: dir.path,
|
||
inspector: true, // 开发模式,发布时关闭
|
||
);
|
||
_initialized = true;
|
||
return _instance!;
|
||
}
|
||
|
||
/// 获取 Isar 实例(必须先调用 [init])
|
||
///
|
||
/// 如果未初始化会抛出 [StateError]。
|
||
static Isar get instance {
|
||
if (_instance == null || !_instance!.isOpen) {
|
||
throw StateError(
|
||
'IsarDatabase 未初始化,请先调用 IsarDatabase.init(schemas: [...])',
|
||
);
|
||
}
|
||
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 {
|
||
// TODO: 清空所有 collection
|
||
});
|
||
}
|
||
}
|