///高亮模型 /// 不同颜色的高亮 enum HighlightColor { yellow, // 黄色 - 默认高亮 orange, // 橙色 - 重要内容 green, // 绿色 - 已理解内容 blue, // 蓝色 - 需要复习 pink // 粉色 - 个人感想 } /// 批注类型枚举 /// 用于分类不同类型的批注内容 enum AnnotationType { note, // 笔记 - 记录知识点 thought, // 感想 - 个人想法 summary, // 摘要 - 内容总结 question // 问题 - 疑问记录 } ///高亮模型 // 关联书籍和章节 // 记录选中的文本范围 // 支持不同颜色的高亮 // 记录创建时间 class Highlight { //唯一标识符 - 使用UUID确保全局唯一 final String id; //对应的书籍id final String bookId; // 对应章节id final String? chapterId; // 选中文本 final String selectedText; // 开始索引 final int startIndex; // 结尾索引 final int endIndex; // 高亮颜色 final HighlightColor color; // 创建时间 final DateTime createdTime; /// 批注内容 - 可选字段,用于存储用户对高亮的注释 final String? annotation; /// 批注类型 - 可选字段,用于分类批注 final AnnotationType? annotationType; /// 批注添加时间 - 可选字段,记录批注的最后修改时间 final DateTime? annotationTime; const Highlight({ required this.id, required this.bookId, this.chapterId, required this.selectedText, required this.startIndex, required this.endIndex, required this.color, required this.createdTime, this.annotation, // 批注内容 this.annotationType, // 批注类型 this.annotationTime, // 批注时间 }); /// copyWith方法 - 创建对象的副本 Highlight copyWith({ String? id, String? bookId, String? chapterId, String? selectedText, int? startIndex, int? endIndex, HighlightColor? color, DateTime? createdTime, String? annotation, AnnotationType? annotationType, DateTime? annotationTime, }) { return Highlight( id: id ?? this.id, bookId: bookId ?? this.bookId, chapterId: chapterId ?? this.chapterId, selectedText: selectedText ?? this.selectedText, startIndex: startIndex ?? this.startIndex, endIndex: endIndex ?? this.endIndex, color: color ?? this.color, createdTime: createdTime ?? this.createdTime, annotation: annotation ?? this.annotation, annotationType: annotationType ?? this.annotationType, annotationTime: annotationTime ?? this.annotationTime, ); } /// toMap方法 - 将对象转换为Map Map toMap() { return { 'id': id, 'bookId': bookId, 'chapterId': chapterId, 'selectedText': selectedText, 'startIndex': startIndex, 'endIndex': endIndex, 'color': color.name, // 枚举值转换为字符串 'createdTime': createdTime.toIso8601String(), // DateTime转换为字符串 'annotation': annotation, 'annotationType': annotationType?.name, // 枚举转换为字符串,注意可能是null 'annotationTime': annotationTime?.toIso8601String(), // DateTime转换为字符串,注意可能是null }; } /// fromMap构造函数 - 从Map创建Highlight对象 factory Highlight.fromMap(Map map) { return Highlight( id: map['id'], bookId: map['bookId'], chapterId: map['chapterId'], selectedText: map['selectedText'], startIndex: map['startIndex'], endIndex: map['endIndex'], color: HighlightColor.values.firstWhere((e) => e.name == map['color']), createdTime: DateTime.parse(map['createdTime']), annotation: map['annotation'], // 批注内容直接取值 annotationType: map['annotationType'] != null ? AnnotationType.values.firstWhere((e) => e.name == map['annotationType']) : null, // 处理可选的枚举字段 annotationTime: map['annotationTime'] != null ? DateTime.parse(map['annotationTime']) : null, // 处理可选的DateTime字段 ); } /// 创建一个新Highlight实例的工厂方法 /// 这是一个便利方法,用于创建基本的高亮对象 /// 通常在用户选中文本时使用 factory Highlight.create({ required String bookId, required String selectedText, required int startIndex, required int endIndex, HighlightColor color = HighlightColor.yellow, // 默认颜色 String? chapterId, }) { return Highlight( id: _generateId(), // 生成唯一ID bookId: bookId, chapterId: chapterId, selectedText: selectedText, startIndex: startIndex, endIndex: endIndex, color: color, createdTime: DateTime.now(), // 当前时间作为创建时间 ); } /// 生成唯一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 Highlight && other.id == id; } @override int get hashCode => id.hashCode; /// 计算属性:检查是否有批注 bool get hasAnnotation => annotation != null && annotation!.isNotEmpty; /// 计算属性:获取批注文本长度 int get annotationLength => annotation?.length ?? 0; /// 添加批注的方法 /// 返回一个新的Highlight对象,包含指定的批注内容 Highlight addAnnotation(String content, AnnotationType type) { return copyWith( annotation: content, annotationType: type, annotationTime: DateTime.now(), // 设置当前时间为批注时间 ); } /// 更新批注内容的方法 /// 返回一个新的Highlight对象,包含更新的批注内容 Highlight updateAnnotation(String content, AnnotationType type) { return copyWith( annotation: content, annotationType: type, annotationTime: DateTime.now(), // 更新批注时间 ); } /// 移除批注的方法 /// 返回一个新的Highlight对象,移除所有批注相关字段 Highlight removeAnnotation() { return copyWith( annotation: null, annotationType: null, annotationTime: null, ); } /// 重写toString方法,增加批注信息显示 @override String toString() { final annotationInfo = hasAnnotation ? ' [批注: $annotation]' : ''; return 'Highlight(id: $id, bookId: $bookId, text: "$selectedText"$annotationInfo)'; } }