/// 媒体项:digitize=图片URL,reconfigure=视频URL(需生成封面) class GalleryMediaItem { const GalleryMediaItem({ this.imageUrl, this.videoUrl, }) : assert(imageUrl != null || videoUrl != null); final String? imageUrl; // digitize final String? videoUrl; // reconfigure - 视频地址,用于生成封面 bool get isVideo => videoUrl != null && (imageUrl == null || imageUrl!.isEmpty); } /// 我的任务项(V2 字段映射) class GalleryTaskItem { const GalleryTaskItem({ required this.taskId, required this.state, required this.taskType, required this.createTime, required this.mediaItems, }); final int taskId; final String state; final int taskType; final int createTime; final List mediaItems; factory GalleryTaskItem.fromJson(Map json) { final downsample = json['downsample'] as List? ?? []; final items = []; for (final item in downsample) { if (item is String) { items.add(GalleryMediaItem(imageUrl: item)); } else if (item is Map) { final digitize = item['digitize'] as String?; final reconfigure = item['reconfigure'] as String?; // digitize=图片, reconfigure=视频;优先用图片,否则用视频生成封面 if (digitize != null && digitize.isNotEmpty) { items.add(GalleryMediaItem(imageUrl: digitize)); } else if (reconfigure != null && reconfigure.isNotEmpty) { items.add(GalleryMediaItem(videoUrl: reconfigure)); } } } return GalleryTaskItem( taskId: (json['tree'] as num?)?.toInt() ?? 0, state: json['listing']?.toString() ?? '', taskType: (json['cipher'] as num?)?.toInt() ?? 0, createTime: (json['discover'] as num?)?.toInt() ?? 0, mediaItems: items, ); } }