## 新增功能 - EPUB文件导入功能:支持文件选择、解析和存储 - 文件重复检测:避免重复导入同一文件 - 导入状态反馈:成功/失败消息提示 ## 模型扩展 - Book模型新增多作者支持(authors字段) - 新增章节数统计(chapterCount字段) - 新增语言标识(language字段) - 新增EPUB标识符(identifier字段) - 优化TypeAdapter序列化支持 ## 服务优化 - 新增EpubParserService:EPUB文件解析服务 - 改进DatabaseService:错误处理和数据迁移 - 优化BookRepository:调试日志和错误追踪 ## 依赖更新 - 新增epubx ^4.0.0:EPUB电子书解析库 - 更新pubspec.lock:同步依赖版本 ## UI改进 - AppHeader组件集成完整导入功能 - SafeArea适配:避免系统状态栏重叠 - 优化测试数据结构 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
56 lines
1.7 KiB
Dart
56 lines
1.7 KiB
Dart
import 'package:epubx/epubx.dart';
|
||
import '../models/book.dart';
|
||
import 'dart:io';
|
||
|
||
//解析epub文件的服务类
|
||
class EpubParserService {
|
||
Future<EpubBook> parseEpubFile(String filePath) async {
|
||
try {
|
||
final bytes = await File(filePath).readAsBytes();
|
||
return await EpubReader.readBook(bytes);
|
||
} catch (e) {
|
||
throw Exception('EPUB解析失败: $e');
|
||
}
|
||
}
|
||
|
||
Future<Book> extractBookMetadata(EpubBook epubBook, String filePath) async {
|
||
try {
|
||
// 基本信息
|
||
final title = epubBook.Title ?? '未知标题';
|
||
|
||
// 处理作者列表
|
||
final authorList = epubBook.AuthorList?.map((author) => author.toString()).toList() ?? [];
|
||
final primaryAuthor = authorList.isNotEmpty ? authorList.first : '未知作者';
|
||
|
||
// 计算章节数
|
||
final chapters = epubBook.Chapters ?? [];
|
||
final chapterCount = chapters.isNotEmpty ? chapters.length : null;
|
||
|
||
// 如果有章节数,使用章节数作为totalPages
|
||
final totalPages = chapterCount ?? 0;
|
||
|
||
return Book.create(
|
||
title: title,
|
||
filePath: filePath,
|
||
format: BookFormat.epub,
|
||
fileSize: await File(filePath).length(),
|
||
author: primaryAuthor,
|
||
authors: authorList,
|
||
chapterCount: chapterCount,
|
||
totalPages: totalPages,
|
||
);
|
||
} catch (e) {
|
||
throw Exception('提取元数据失败: $e');
|
||
}
|
||
}
|
||
|
||
Future<String?> saveCoverImage(EpubBook epubBook, String bookId) async {
|
||
// 如果没有封面图片,返回null
|
||
if (epubBook.CoverImage == null) return null;
|
||
|
||
// TODO: 这里需要实现保存封面图片的逻辑
|
||
// 将封面图片保存到本地存储,并返回文件路径
|
||
return null; // 暂时返回null,后续完善
|
||
}
|
||
}
|