readful/lib/models/bookmark.dart
ddshi 02010ff972 feat: 完成数据持久化阶段并规划UI开发
📊 数据持久化阶段完成:
- 完成4个数据模型的Hive集成(Book, Bookshelf, Bookmark, Highlight)
- 实现4个Repository数据访问层
- 生成5个TypeAdapter自动序列化文件
- 完成所有模型的CRUD操作和测试验证

📚 项目文档更新:
- 新增数据持久化阶段完成总结文档
- 更新CLAUDE.md项目主文档
- 完善项目结构说明和开发进度

🚀 UI开发阶段规划:
- 定义产品定位:类似微信读书的Material Design电子书阅读器
- 制定4阶段开发计划:UI基础架构→顶部导航→首页内容→数据集成
- 明确页面结构:底部Tab导航(首页/书库/统计/我的)
- 规划核心功能:搜索、导入、最近阅读、摘录列表

🎯 下一里程碑:
- 开始UI基础架构搭建
- 实现底部Tab导航和Material Design主题系统

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 17:34:50 +08:00

181 lines
4.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:hive/hive.dart';
part 'bookmark.g.dart';
/// 书签模型
/// 用于记录和管理阅读位置标记
@HiveType(typeId: 5)
class Bookmark {
@HiveField(0)
final String id;
@HiveField(1)
final String bookId;
@HiveField(2)
final String? chapterId;
@HiveField(3)
final String title;
@HiveField(4)
final String? description;
@HiveField(5)
final int pageIndex;
@HiveField(6)
final double position; // 0.0-1.0之间的值,表示在文档中的相对位置
@HiveField(7)
final String? previewText;
@HiveField(8)
final DateTime createdTime;
@HiveField(9)
final int sortOrder;
// 构造函数...
const Bookmark(
{required this.id,
required this.bookId,
this.chapterId,
required this.title,
this.description,
required this.pageIndex,
required this.position,
this.previewText,
required this.createdTime,
required this.sortOrder});
// copyWith方法...
Bookmark copyWith(
{String? id,
String? bookId,
String? chapterId,
String? title,
String? description,
int? pageIndex,
double? position,
String? previewText,
DateTime? createdTime,
int? sortOrder}) {
return Bookmark(
id: id ?? this.id, // 如果id不为null就使用新值否则保持原值
bookId: bookId ?? this.bookId,
chapterId: chapterId ?? this.chapterId,
title: title ?? this.title,
description: description ?? this.description,
pageIndex: pageIndex ?? this.pageIndex,
position: position ?? this.position,
previewText: previewText ?? this.previewText,
createdTime: createdTime ?? this.createdTime,
sortOrder: sortOrder ?? this.sortOrder);
}
// toMap/fromMap方法...
/// toMap方法 - 将对象转换为Map
Map<String, dynamic> toMap() {
return {
'id': id,
'bookId': bookId,
'chapterId': chapterId,
'title': title,
'description': description,
'pageIndex': pageIndex,
'position': position,
'previewText': previewText,
'createdTime': createdTime.toIso8601String(),
'sortOrder': sortOrder
};
}
/// fromMap构造函数
///
/// 这是toMap的逆操作用于
/// 1. 从本地存储中读取数据
/// 2. 从网络请求中解析数据
/// 3. 从保存的状态中恢复对象
factory Bookmark.fromMap(Map<String, dynamic> map) {
return Bookmark(
id: map['id'],
bookId: map['bookId'],
chapterId: map['chapterId'],
title: map['title'],
description: map['description'],
pageIndex: map['pageIndex'],
position: map['position'],
previewText: map['previewText'],
createdTime: DateTime.parse(map['createdTime']),
sortOrder: map['sortOrder']);
}
// 工厂方法...
factory Bookmark.create({
required String bookId,
required String title,
required int pageIndex,
required double position,
String? chapterId,
String? description,
String? previewText,
}) {
return Bookmark(
id: _generateId(), // 生成唯一ID
bookId: bookId,
chapterId: chapterId,
title: title,
pageIndex: pageIndex,
position: position,
description: description,
previewText: previewText,
createdTime: DateTime.now(),
sortOrder: 0);
}
// 计算属性和实用方法...
/// 生成唯一ID的私有方法
static String _generateId() {
return '${DateTime.now().millisecondsSinceEpoch}_${(DateTime.now().microsecond).toString()}';
}
/// 重写equals和hashCode用于对象比较
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is Bookmark && other.id == id;
}
@override
int get hashCode => id.hashCode;
/// 重写toString方法便于调试
@override
String toString() {
return 'Bookmark(id: $id, title: $title, bookId: $bookId, sortOrder: $sortOrder)';
}
// 更新位置
Bookmark updatePosition(int newPageIndex, double newPosition) {
return copyWith(
pageIndex: newPageIndex,
position: newPosition,
);
}
// 更新标题和描述
Bookmark updateInfo({String? title, String? description}) {
return copyWith(
title: title ?? this.title,
description: description ?? this.description,
);
}
// 格式化位置显示
String get positionDisplay => '${(position * 100).toInt()}%';
// 检查位置是否有效
bool get isValidPosition => position >= 0.0 && position <= 1.0;
}