/// 照片分类类型 enum PhotoImageClassifyType { similar, people, screenshot, blurry, } /// 分类进度信息 class ClassificationProgress { /// 总批次数 final int totalBatches; /// 当前批次 final int currentBatch; /// 是否已完成 final bool isLastBatch; /// 完成百分比 (0.0-1.0) final double rate; /// 当前批次处理时间(秒) final double batchDuration; /// 总耗时(秒) final double totalDuration; /// 是否已完成 bool get isCompleted => isLastBatch; ClassificationProgress({ required this.totalBatches, required this.currentBatch, required this.isLastBatch, required this.rate, required this.batchDuration, required this.totalDuration, }); static double _toDouble(dynamic v) => v is int ? v.toDouble() : (v as double); static ClassificationProgress fromJson(Map json) { return ClassificationProgress( totalBatches: json['totalBatches'], currentBatch: json['currentBatch'], isLastBatch: json['isLastBatch'], rate: _toDouble(json['rate']), batchDuration: _toDouble(json['batchDuration']), totalDuration: _toDouble(json['totalDuration']), ); } } class ClassifiedImageGroup { final List images; int get groupFileSize => images.fold(0, (sum, image) => sum + image.fileSize); int get groupImageCount => images.length; ClassifiedImageGroup({ required this.images, }); static ClassifiedImageGroup fromList(List images) { return ClassifiedImageGroup( images: images, ); } } class ImageLocation { final double latitude; // 纬度 final double longitude; // 经度 ImageLocation({ required this.latitude, required this.longitude, }); static ImageLocation fromJson(Map json) { return ImageLocation( latitude: json['latitude'], longitude: json['longitude'], ); } } class ClassifiedImage { final String assetsId; final double createdAt; final ImageLocation? location; final int fileSize; final int pixelWidth; final int pixelHeight; ClassifiedImage({ required this.assetsId, required this.createdAt, this.location, required this.fileSize, required this.pixelWidth, required this.pixelHeight, }); static ClassifiedImage fromJson(Map json) { return ClassifiedImage( assetsId: json['assetsId'], createdAt: json['createdAt'], location: json['location'] != null ? ImageLocation.fromJson(Map.from(json['location'])) : null, fileSize: json['fileSize'], pixelWidth: json['pixelWidth'], pixelHeight: json['pixelHeight'], ); } } class ClassificationResult { final List? similarGroups; final List? peopleGroups; final List? screenshotGroups; final List? blurryGroups; ClassificationResult({ required this.similarGroups, required this.peopleGroups, required this.screenshotGroups, required this.blurryGroups, }); static ClassificationResult fromJson(Map json) { List processedImages(dynamic images) { var imageList = List>.from(images ?? []); return imageList.map((image) => ClassifiedImage.fromJson(Map.from(image))).toList(); } return ClassificationResult( similarGroups: json['similarGroups']?['groups']?.isEmpty ?? true ? null : List.from((json['similarGroups']?['groups'] ?? []).map((group) => ClassifiedImageGroup.fromList( processedImages(group) ) )), peopleGroups: json['peopleImages']?.isEmpty ?? true ? null : processedImages(json['peopleImages']), screenshotGroups: json['screenshotImages']?.isEmpty ?? true ? null : processedImages(json['screenshotImages']), blurryGroups: json['blurryImages']?.isEmpty ?? true ? null : processedImages(json['blurryImages']), ); } } /// 分类事件,包含进度和结果 class ClassificationEvent { /// 分类进度 final ClassificationProgress? progress; /// 分类结果 final ClassificationResult? result; ClassificationEvent({ required this.progress, this.result, }); }