readful/lib/models/bookshelf.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

280 lines
7.7 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 'bookshelf.g.dart';
@HiveType(typeId: 3)
///书架类型
enum BookshelfType {
@HiveField(0)
system, //系统默认书架
@HiveField(1)
custom //用户自定义书架
}
@HiveType(typeId: 4)
/// 书架数据模型
class Bookshelf {
@HiveField(0)
final String id; // 唯一标识
@HiveField(1)
final String name; // 书架名称
@HiveField(2)
final String? description; // 书架描述
@HiveField(3)
final String? coverImagePath; // 书架封面
@HiveField(4)
final DateTime createdTime; // 创建时间
@HiveField(5)
final DateTime lastModifiedTime; // 最后修改时间
@HiveField(6)
final int bookCount; // 书籍数量
@HiveField(7)
final BookshelfType type; // 书架类型
@HiveField(8)
final bool isDefault; // 是否为默认书架
@HiveField(9)
final int sortOrder; // 排序顺序
// 构造函数
const Bookshelf(
{required this.id,
required this.name,
this.description,
this.coverImagePath,
required this.createdTime,
required this.lastModifiedTime,
required this.bookCount,
required this.type,
required this.isDefault,
required this.sortOrder});
// copyWith方法...
Bookshelf copyWith(
{String? id,
String? name,
String? description,
String? coverImagePath,
DateTime? createdTime,
DateTime? lastModifiedTime,
int? bookCount,
BookshelfType? type,
bool? isDefault,
int? sortOrder}) {
return Bookshelf(
id: id ?? this.id, // 如果id不为null就使用新值否则保持原值
name: name ?? this.name,
description: description ?? this.description,
coverImagePath: coverImagePath ?? this.coverImagePath,
createdTime: createdTime ?? this.createdTime,
lastModifiedTime: lastModifiedTime ?? this.lastModifiedTime,
bookCount: bookCount ?? this.bookCount,
type: type ?? this.type,
isDefault: isDefault ?? this.isDefault,
sortOrder: sortOrder ?? this.sortOrder);
}
// toMap、fromMap、
/// toMap方法 - 将对象转换为Map
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'description': description,
'coverImagePath': coverImagePath,
'createdTime': createdTime.toIso8601String(),
'lastModifiedTime': lastModifiedTime.toIso8601String(),
'bookCount': bookCount,
'type': type.name,
'isDefault': isDefault,
'sortOrder': sortOrder
};
}
/// fromMap构造函数
factory Bookshelf.fromMap(Map<String, dynamic> map) {
return Bookshelf(
id: map['id'],
name: map['name'],
description: map['description'],
coverImagePath: map['coverImagePath'],
createdTime: DateTime.parse(map['createdTime']),
lastModifiedTime: DateTime.parse(map['lastModifiedTime']),
bookCount: map['bookCount'],
type: BookshelfType.values.firstWhere((e) => e.name == map['type']),
isDefault: map['isDefault'],
sortOrder: map['sortOrder']);
}
// 工厂方法
factory Bookshelf.create({
required String name,
BookshelfType type = BookshelfType.custom,
String? description,
}) {
return Bookshelf(
id: _generateId(),
name: name,
type: type,
createdTime: DateTime.now(),
lastModifiedTime: DateTime.now(),
bookCount: 0,
sortOrder: 0,
isDefault: false,
description: description,
);
}
// 创建系统书架的便利方法
factory Bookshelf.createSystem({
required String name,
String? description,
}) {
return Bookshelf(
id: _generateSystemId(name),
name: name,
type: BookshelfType.system,
isDefault: true,
createdTime: DateTime.now(),
lastModifiedTime: DateTime.now(),
bookCount: 0,
sortOrder: 0,
description: description,
);
}
/// 生成唯一ID的私有方法
/// 用于用户自定义书架
static String _generateId() {
return 'shelf_${DateTime.now().millisecondsSinceEpoch}_${DateTime.now().microsecond}';
}
/// 生成系统书架ID的私有方法
/// 基于书架名称生成可预测的ID确保应用重启后ID保持一致
static String _generateSystemId(String name) {
// 清理名称:移除空格和特殊字符,保留中文、英文、数字
final cleanName = name
.replaceAll(RegExp(r'[^a-zA-Z0-9\u4e00-\u9fff]'), '') // 保留中文、英文、数字
.toLowerCase();
return 'system_$cleanName'; // 添加前缀区分系统书架
}
/// 重写equals和hashCode用于对象比较
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is Bookshelf && other.id == id;
}
@override
int get hashCode => id.hashCode;
/// 重写toString方法便于调试
@override
String toString() {
final typeInfo = type == BookshelfType.system ? '[系统]' : '[自定义]';
return 'Bookshelf$typeInfo(id: $id, name: $name, books: $bookCount)';
}
/// 计算属性:检查是否为系统书架
bool get isSystemShelf => type == BookshelfType.system;
/// 计算属性:检查是否为用户自定义书架
bool get isCustomShelf => type == BookshelfType.custom;
/// 计算属性:检查是否有描述
bool get hasDescription => description != null && description!.isNotEmpty;
/// 计算属性:检查是否有封面图片
bool get hasCoverImage => coverImagePath != null && coverImagePath!.isNotEmpty;
/// 计算属性:检查书架是否为空
bool get isEmpty => bookCount == 0;
/// 计算属性:获取书籍数量的显示文本
String get bookCountDisplay {
if (bookCount == 0) return '暂无书籍';
if (bookCount == 1) return '1本书';
return '$bookCount本书';
}
/// 便利方法:更新书籍数量
/// 通常在添加或删除书籍时调用
Bookshelf updateBookCount(int newCount) {
return copyWith(
bookCount: newCount,
lastModifiedTime: DateTime.now(), // 更新修改时间
);
}
/// 便利方法:增加书籍数量
Bookshelf incrementBookCount({int increment = 1}) {
return copyWith(
bookCount: bookCount + increment,
lastModifiedTime: DateTime.now(),
);
}
/// 便利方法:减少书籍数量
Bookshelf decrementBookCount({int decrement = 1}) {
final newCount = (bookCount - decrement).clamp(0, bookCount);
return copyWith(
bookCount: newCount,
lastModifiedTime: DateTime.now(),
);
}
/// 便利方法:更新书架信息
Bookshelf updateInfo({
String? name,
String? description,
String? coverImagePath,
}) {
return copyWith(
name: name ?? this.name,
description: description ?? this.description,
coverImagePath: coverImagePath ?? this.coverImagePath,
lastModifiedTime: DateTime.now(),
);
}
/// 静态方法:创建默认的系统书架集合
/// 应用启动时调用,创建必要的系统书架
static List<Bookshelf> createDefaultSystemShelves() {
return [
Bookshelf.createSystem(
name: '全部书籍',
description: '包含所有导入的电子书',
),
Bookshelf.createSystem(
name: '最近阅读',
description: '最近打开过的书籍',
),
Bookshelf.createSystem(
name: '收藏',
description: '用户收藏的书籍',
),
Bookshelf.createSystem(
name: '阅读中',
description: '正在阅读的书籍',
),
Bookshelf.createSystem(
name: '已完成',
description: '已经读完的书籍',
),
Bookshelf.createSystem(
name: '待阅读',
description: '计划阅读的书籍',
),
];
}
}