import 'package:flutter/material.dart'; /// 批注模型 class Annotation { final String id; final String text; final Offset start; final Offset end; final AnnotationType type; final String? suggestion; final String? documentId; final DateTime createdAt; Annotation({ required this.id, required this.text, required this.start, required this.end, required this.type, this.suggestion, this.documentId, required this.createdAt, }); /// 从JSON创建 factory Annotation.fromJson(Map json) { return Annotation( id: json['id'] as String, text: json['text'] as String, start: Offset( (json['start'] as Map)['x'] as double, (json['start'] as Map)['y'] as double, ), end: Offset( (json['end'] as Map)['x'] as double, (json['end'] as Map)['y'] as double, ), type: AnnotationType.values.firstWhere( (e) => e.toString().split('.').last == json['type'], orElse: () => AnnotationType.highlight, ), suggestion: json['suggestion'] as String?, documentId: json['documentId'] as String?, createdAt: DateTime.parse(json['createdAt'] as String), ); } /// 转换为JSON Map toJson() { return { 'id': id, 'text': text, 'start': {'x': start.dx, 'y': start.dy}, 'end': {'x': end.dx, 'y': end.dy}, 'type': type.toString().split('.').last, 'suggestion': suggestion, 'documentId': documentId, 'createdAt': createdAt.toIso8601String(), }; } /// 复制并更新 Annotation copyWith({ String? id, String? text, Offset? start, Offset? end, AnnotationType? type, String? suggestion, String? documentId, DateTime? createdAt, }) { return Annotation( id: id ?? this.id, text: text ?? this.text, start: start ?? this.start, end: end ?? this.end, type: type ?? this.type, suggestion: suggestion ?? this.suggestion, documentId: documentId ?? this.documentId, createdAt: createdAt ?? this.createdAt, ); } } /// 批注类型 enum AnnotationType { highlight, // 高亮 strikethrough, // 删除线 suggestion, // 建议 } extension AnnotationTypeExtension on AnnotationType { String get label { switch (this) { case AnnotationType.highlight: return '高亮'; case AnnotationType.strikethrough: return '删除线'; case AnnotationType.suggestion: return '建议'; } } }