/// 文档模型 class Document { final String id; final String name; final String? description; final DocumentType type; final DocumentStatus status; final DateTime createdAt; final DateTime? updatedAt; final int? fileSize; // bytes final String? fileUrl; final String? parsedText; final Map? metadata; Document({ required this.id, required this.name, this.description, required this.type, required this.status, required this.createdAt, this.updatedAt, this.fileSize, this.fileUrl, this.parsedText, this.metadata, }); /// 从JSON创建 factory Document.fromJson(Map json) { return Document( id: json['id'] as String, name: json['name'] as String, description: json['description'] as String?, type: DocumentType.values.firstWhere( (e) => e.toString().split('.').last == json['type'], orElse: () => DocumentType.other, ), status: DocumentStatus.values.firstWhere( (e) => e.toString().split('.').last == json['status'], orElse: () => DocumentStatus.pending, ), createdAt: DateTime.parse(json['createdAt'] as String), updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt'] as String) : null, fileSize: json['fileSize'] as int?, fileUrl: json['fileUrl'] as String?, parsedText: json['parsedText'] as String?, metadata: json['metadata'] as Map?, ); } /// 转换为JSON Map toJson() { return { 'id': id, 'name': name, 'description': description, 'type': type.toString().split('.').last, 'status': status.toString().split('.').last, 'createdAt': createdAt.toIso8601String(), 'updatedAt': updatedAt?.toIso8601String(), 'fileSize': fileSize, 'fileUrl': fileUrl, 'parsedText': parsedText, 'metadata': metadata, }; } /// 复制并更新 Document copyWith({ String? id, String? name, String? description, DocumentType? type, DocumentStatus? status, DateTime? createdAt, DateTime? updatedAt, int? fileSize, String? fileUrl, String? parsedText, Map? metadata, }) { return Document( id: id ?? this.id, name: name ?? this.name, description: description ?? this.description, type: type ?? this.type, status: status ?? this.status, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, fileSize: fileSize ?? this.fileSize, fileUrl: fileUrl ?? this.fileUrl, parsedText: parsedText ?? this.parsedText, metadata: metadata ?? this.metadata, ); } /// 格式化文件大小 String get formattedFileSize { if (fileSize == null) return '未知'; if (fileSize! < 1024) return '${fileSize}B'; if (fileSize! < 1024 * 1024) return '${(fileSize! / 1024).toStringAsFixed(2)}KB'; return '${(fileSize! / (1024 * 1024)).toStringAsFixed(2)}MB'; } } /// 文档类型 enum DocumentType { pdf, word, image, markdown, other } /// 文档状态 enum DocumentStatus { pending, // 待处理 uploading, // 上传中 parsing, // 解析中 processing, // 处理中 completed, // 已完成 failed, // 失败 } extension DocumentStatusExtension on DocumentStatus { String get label { switch (this) { case DocumentStatus.pending: return '待处理'; case DocumentStatus.uploading: return '上传中'; case DocumentStatus.parsing: return '解析中'; case DocumentStatus.processing: return '处理中'; case DocumentStatus.completed: return '已完成'; case DocumentStatus.failed: return '失败'; } } }