主要功能: - ✅ 完成4个核心数据模型(Book、Highlight、Bookmark、Bookshelf) - ✅ 实现7个枚举类型,提供类型安全的数据分类 - ✅ 建立完整的数据模型设计标准和最佳实践 - ✅ 创建5篇详细学习文档,涵盖Flutter数据模型开发 技术成就: - 不可变对象设计模式 mastered - 空值安全语法熟练应用 - 工厂构造函数模式实践 - 序列化/反序列化机制完整实现 - 计算属性和便利方法优化 业务价值: - 完整支持电子书管理需求 - 高亮+批注功能集成设计 - 灵活的书架分类系统 - 可扩展的数据架构设计 文档体系: - 📚 项目概览和技术架构(CLAUDE.md) - 📓 数据模型完成度检查报告 - 📖 阶段性学习成果总结 - 💡 Flutter开发最佳实践指导 代码统计: - 4个核心模型文件,约1200行代码 - 7个枚举类型,45个数据字段 - 80+个方法,完整的对象生命周期管理 下一阶段:Hive数据库集成和Repository模式实现 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
253 lines
7.4 KiB
Dart
253 lines
7.4 KiB
Dart
///书架类型
|
||
enum BookshelfType {
|
||
system, //系统默认书架
|
||
custom //用户自定义书架
|
||
}
|
||
|
||
/// 书架数据模型
|
||
class Bookshelf {
|
||
final String id; // 唯一标识
|
||
final String name; // 书架名称
|
||
final String? description; // 书架描述
|
||
final String? coverImagePath; // 书架封面
|
||
final DateTime createdTime; // 创建时间
|
||
final DateTime lastModifiedTime; // 最后修改时间
|
||
final int bookCount; // 书籍数量
|
||
final BookshelfType type; // 书架类型
|
||
final bool isDefault; // 是否为默认书架
|
||
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: '计划阅读的书籍',
|
||
),
|
||
];
|
||
}
|
||
}
|