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.
 
 
 
 
 
 

135 lines
3.3 KiB

import 'package:uuid/uuid.dart';
class Problem {
final String id;
final String description;
final String location;
final String imageUrl;
final DateTime createdAt;
final DateTime updatedAt;
static final Uuid _uuid = const Uuid();
Problem._({
required this.id,
required this.description,
required this.location,
required this.imageUrl,
required this.createdAt,
required this.updatedAt,
});
// 主工厂构造函数
factory Problem({
required String description,
required String location,
required String imageUrl,
String? id,
DateTime? createdAt,
DateTime? updatedAt,
}) {
// 参数验证
_validateParameters(description, location, imageUrl);
final now = DateTime.now();
return Problem._(
id: id ?? _uuid.v4(),
description: description.trim(),
location: location.trim(),
imageUrl: imageUrl,
createdAt: createdAt ?? now,
updatedAt: updatedAt ?? now,
);
}
// 参数验证
static void _validateParameters(
String description,
String location,
String imageUrl,
) {
if (description.isEmpty) {
throw ArgumentError('Description cannot be empty');
}
if (location.isEmpty) {
throw ArgumentError('Location cannot be empty');
}
if (imageUrl.isEmpty) {
throw ArgumentError('Image URL cannot be empty');
}
// 验证 URL 格式(简单验证)
if (!imageUrl.startsWith('http')) {
throw ArgumentError('Image URL must be a valid URL');
}
}
// 从 JSON 反序列化
factory Problem.fromJson(Map<String, dynamic> json) {
return Problem(
id: json['id'],
description: json['description'],
location: json['location'],
imageUrl: json['imageUrl'],
createdAt: json['createdAt'] != null
? DateTime.parse(json['createdAt'])
: null,
updatedAt: json['updatedAt'] != null
? DateTime.parse(json['updatedAt'])
: null,
);
}
// 转换为 JSON
Map<String, dynamic> toJson() {
return {
'id': id,
'description': description,
'location': location,
'imageUrl': imageUrl,
'createdAt': createdAt.toIso8601String(),
'updatedAt': updatedAt.toIso8601String(),
};
}
// 复制方法
Problem copyWith({
String? id,
String? description,
String? location,
String? imageUrl,
DateTime? createdAt,
DateTime? updatedAt,
}) {
return Problem(
id: id ?? this.id,
description: description ?? this.description,
location: location ?? this.location,
imageUrl: imageUrl ?? this.imageUrl,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? DateTime.now(), // 更新时间为当前时间
);
}
// 检查是否有效
bool get isValid => description.isNotEmpty && location.isNotEmpty;
// 获取简短描述
String get shortDescription {
if (description.length <= 50) return description;
return '${description.substring(0, 47)}...';
}
@override
String toString() {
return 'Problem(id: $id, description: $shortDescription, location: $location)';
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Problem && runtimeType == other.runtimeType && id == other.id;
@override
int get hashCode => id.hashCode;
}