You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

123 lines
4.0 KiB

// problem_model.dart
import 'dart:convert';
import 'package:problem_check_system/data/models/operation.dart';
import 'package:problem_check_system/data/models/sync_status.dart';
import 'package:problem_check_system/data/models/image_metadata_model.dart';
/// 问题的数据模型。
/// 用于表示系统中的一个具体问题,包含了问题的描述、位置、图片等信息。
class Problem {
/// 问题的唯一标识符,可空。
final String? id;
/// 问题的详细描述。
final String description;
/// 问题发生的位置。
final String location;
/// 问题的图片元数据列表。
final List<ImageMetadata> imageUrls;
/// 问题创建的时间。
final DateTime creationTime;
/// 问题的同步状态,默认为未同步。
final SyncStatus syncStatus;
/// 对问题的操作类型,默认为创建。
final Operation operation;
/// 相关的审查任务ID,可空。
final String? censorTaskId;
/// 绑定的附加数据,可空。
final String? bindData;
/// 问题是否已被检查,默认为false。
final bool isChecked;
/// Problem 类的构造函数。
const Problem({
this.id,
required this.description,
required this.location,
required this.imageUrls,
required this.creationTime,
this.syncStatus = SyncStatus.notSynced,
this.operation = Operation.create,
this.censorTaskId,
this.bindData,
this.isChecked = false,
});
/// 创建一个新实例,并可以选择性地更新某些字段。
/// 采用不可变设计模式,返回一个新对象而不是修改现有对象。
Problem copyWith({
String? id,
String? description,
String? location,
List<ImageMetadata>? imageUrls,
DateTime? creationTime,
SyncStatus? syncStatus,
Operation? operation,
String? censorTaskId,
String? bindData,
bool? isChecked,
}) {
return Problem(
id: id ?? this.id,
description: description ?? this.description,
location: location ?? this.location,
imageUrls: imageUrls ?? this.imageUrls,
creationTime: creationTime ?? this.creationTime,
syncStatus: syncStatus ?? this.syncStatus,
operation: operation ?? this.operation,
censorTaskId: censorTaskId ?? this.censorTaskId,
bindData: bindData ?? this.bindData,
isChecked: isChecked ?? this.isChecked,
);
}
/// 将 Problem 实例序列化为 Map,便于存储到数据库或发送到服务器。
Map<String, dynamic> toMap() {
return {
'id': id,
'description': description,
'location': location,
// 使用 jsonEncode 将图片元数据列表转换为 JSON 字符串
'imageUrls': jsonEncode(imageUrls.map((meta) => meta.toMap()).toList()),
'creationTime': creationTime.millisecondsSinceEpoch,
'syncStatus': syncStatus.index,
'operation': operation.index, // 增加对 operation 字段的序列化
'censorTaskId': censorTaskId,
'bindData': bindData,
'isChecked': isChecked, // 增加对 isChecked 字段的序列化
};
}
/// 从 Map 中反序列化创建一个 Problem 实例。
factory Problem.fromMap(Map<String, dynamic> map) {
return Problem(
id: map['id'],
description: map['description'],
location: map['location'],
// jsonDecode 将 JSON 字符串转换为列表,然后映射为 ImageMetadata 对象
imageUrls: (jsonDecode(map['imageUrls']) as List)
.map((item) => ImageMetadata.fromMap(item as Map<String, dynamic>))
.toList(),
creationTime: DateTime.fromMillisecondsSinceEpoch(
map['creationTime'] as int,
),
syncStatus: SyncStatus.values[map['syncStatus'] as int],
operation:
map.containsKey('operation') // 检查 operation 字段是否存在
? Operation.values[map['operation'] as int]
: Operation.create, // 兼容旧数据
censorTaskId: map['censorTaskId'],
bindData: map['bindData'],
isChecked: map['isChecked'] as bool? ?? false, // 增加对 isChecked 字段的反序列化
);
}
}