generated from dellevin/template
epub阅读+关联书籍
This commit is contained in:
@@ -39,7 +39,7 @@ class DatabaseHelper {
|
||||
|
||||
return await openDatabase(
|
||||
path,
|
||||
version: 23,
|
||||
version: 24,
|
||||
onCreate: _createDB,
|
||||
onUpgrade: _onUpgrade,
|
||||
);
|
||||
@@ -194,6 +194,13 @@ class DatabaseHelper {
|
||||
'CREATE INDEX IF NOT EXISTS idx_book_annotations_type ON book_annotations(book_id, type)',
|
||||
);
|
||||
}
|
||||
if (oldVersion < 24) {
|
||||
// reader_books 添加 book_id 列(关联 books 表)
|
||||
final cols = await db.rawQuery('PRAGMA table_info(reader_books)');
|
||||
if (!cols.any((col) => col['name'] == 'book_id')) {
|
||||
await db.execute("ALTER TABLE reader_books ADD COLUMN book_id TEXT DEFAULT ''");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 升级books表到V11(添加ISBN和出版时间字段)
|
||||
@@ -696,6 +703,7 @@ class DatabaseHelper {
|
||||
file_extension TEXT NOT NULL DEFAULT 'epub',
|
||||
last_read_cfi TEXT DEFAULT '',
|
||||
reading_percentage REAL DEFAULT 0.0,
|
||||
book_id TEXT DEFAULT '',
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
is_deleted INTEGER DEFAULT 0
|
||||
|
||||
@@ -11,15 +11,10 @@ class EpubParser {
|
||||
Future<EpubBookInfo?> parseFromFile(String filePath,
|
||||
{String? fileName}) async {
|
||||
try {
|
||||
debugPrint('[EpubParser] 开始解析: $filePath');
|
||||
final bytes = await File(filePath).readAsBytes();
|
||||
debugPrint('[EpubParser] 读取 ${bytes.length} 字节');
|
||||
final archive = ZipDecoder().decodeBytes(bytes);
|
||||
debugPrint('[EpubParser] ZIP 解码成功, ${archive.files.length} 个文件');
|
||||
return _parseFromArchive(archive, fileName: fileName);
|
||||
} catch (e, stack) {
|
||||
debugPrint('[EpubParser] 解析失败: $e');
|
||||
debugPrint('[EpubParser] $stack');
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,42 @@ class ReaderDao {
|
||||
);
|
||||
}
|
||||
|
||||
// ─── 关联 books 表 ─────────────────────────────────────────────
|
||||
|
||||
/// 关联 EPUB 到 books 表中的书籍
|
||||
Future<int> linkToBook(String readerBookId, String bookId) async {
|
||||
final db = await _db.database;
|
||||
return db.update(
|
||||
'reader_books',
|
||||
{'book_id': bookId, 'updated_at': DateTime.now().toIso8601String()},
|
||||
where: 'id = ?',
|
||||
whereArgs: [readerBookId],
|
||||
);
|
||||
}
|
||||
|
||||
/// 取消关联
|
||||
Future<int> unlinkBook(String readerBookId) async {
|
||||
final db = await _db.database;
|
||||
return db.update(
|
||||
'reader_books',
|
||||
{'book_id': '', 'updated_at': DateTime.now().toIso8601String()},
|
||||
where: 'id = ?',
|
||||
whereArgs: [readerBookId],
|
||||
);
|
||||
}
|
||||
|
||||
/// 通过 books.id 查找关联的 reader_book
|
||||
Future<Map<String, dynamic>?> getReaderBookByBookId(String bookId) async {
|
||||
final db = await _db.database;
|
||||
final results = await db.query(
|
||||
'reader_books',
|
||||
where: 'book_id = ? AND is_deleted = 0',
|
||||
whereArgs: [bookId],
|
||||
limit: 1,
|
||||
);
|
||||
return results.isNotEmpty ? results.first : null;
|
||||
}
|
||||
|
||||
// ─── book_annotations ─────────────────────────────────────────────
|
||||
|
||||
/// 获取某本书的所有批注
|
||||
|
||||
@@ -75,9 +75,9 @@ String generateSkeletonHtml(
|
||||
</head>
|
||||
<body>
|
||||
<div id="frame-container">
|
||||
<iframe id="frame-prev" sandbox="allow-same-origin" scrolling="no" style="z-index: 1; opacity: 0;"></iframe>
|
||||
<iframe id="frame-curr" sandbox="allow-same-origin" scrolling="no" style="z-index: 2; opacity: 1;"></iframe>
|
||||
<iframe id="frame-next" sandbox="allow-same-origin" scrolling="no" style="z-index: 1; opacity: 0;"></iframe>
|
||||
<iframe id="frame-prev" sandbox="allow-same-origin allow-scripts" scrolling="no" style="z-index: 1; opacity: 0;"></iframe>
|
||||
<iframe id="frame-curr" sandbox="allow-same-origin allow-scripts" scrolling="no" style="z-index: 2; opacity: 1;"></iframe>
|
||||
<iframe id="frame-next" sandbox="allow-same-origin allow-scripts" scrolling="no" style="z-index: 1; opacity: 0;"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -207,4 +207,8 @@ class UserPrefs {
|
||||
/// EPUB 阅读器字体大小
|
||||
double get epubFontSize => prefs.getDouble('epubFontSize') ?? 18.0;
|
||||
Future<bool> setEpubFontSize(double value) => prefs.setDouble('epubFontSize', value);
|
||||
|
||||
/// EPUB 书架视图模式: 0=宽松, 1=紧凑
|
||||
int get epubViewMode => prefs.getInt('epubViewMode') ?? 0;
|
||||
Future<bool> setEpubViewMode(int value) => prefs.setInt('epubViewMode', value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user