119 lines
3.6 KiB
Dart
119 lines
3.6 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
|
|
class Pet {
|
|
final String id;
|
|
final String ownerId;
|
|
final String name;
|
|
final String species; // "강아지", "고양이", etc.
|
|
final String breed; // "말티즈", "코숏", etc.
|
|
final String gender; // "남아", "여아"
|
|
final bool isNeutered;
|
|
final DateTime? birthDate;
|
|
final bool isDateUnknown;
|
|
final String? registrationNumber;
|
|
final String? profileImageUrl;
|
|
final double? weight; // 체중 (kg)
|
|
final List<String> diseases;
|
|
final List<String> pastDiseases;
|
|
final List<String> healthConcerns;
|
|
final DateTime createdAt;
|
|
|
|
Pet({
|
|
required this.id,
|
|
required this.ownerId,
|
|
required this.name,
|
|
required this.species,
|
|
required this.breed,
|
|
required this.gender,
|
|
required this.isNeutered,
|
|
this.birthDate,
|
|
required this.isDateUnknown,
|
|
this.registrationNumber,
|
|
this.profileImageUrl,
|
|
this.weight,
|
|
required this.diseases,
|
|
required this.pastDiseases,
|
|
required this.healthConcerns,
|
|
required this.createdAt,
|
|
});
|
|
|
|
Map<String, dynamic> toMap() {
|
|
return {
|
|
'id': id,
|
|
'ownerId': ownerId,
|
|
'name': name,
|
|
'species': species,
|
|
'breed': breed,
|
|
'gender': gender,
|
|
'isNeutered': isNeutered,
|
|
'birthDate': birthDate != null ? Timestamp.fromDate(birthDate!) : null,
|
|
'isDateUnknown': isDateUnknown,
|
|
'registrationNumber': registrationNumber,
|
|
'profileImageUrl': profileImageUrl,
|
|
'weight': weight,
|
|
'diseases': diseases,
|
|
'pastDiseases': pastDiseases,
|
|
'healthConcerns': healthConcerns,
|
|
'createdAt': Timestamp.fromDate(createdAt),
|
|
};
|
|
}
|
|
|
|
factory Pet.fromMap(Map<String, dynamic> map) {
|
|
DateTime? parseDate(dynamic value) {
|
|
if (value is Timestamp) return value.toDate();
|
|
if (value is String) return DateTime.tryParse(value);
|
|
return null;
|
|
}
|
|
|
|
// Helper to safely parse List<String>
|
|
List<String> parseList(dynamic list) {
|
|
if (list == null) return [];
|
|
if (list is! List) return [];
|
|
|
|
return list.map((e) {
|
|
if (e is String) return e;
|
|
if (e is Map) return e['name']?.toString() ?? e.toString();
|
|
return e.toString();
|
|
}).toList();
|
|
}
|
|
|
|
return Pet(
|
|
id: map['id']?.toString() ?? '',
|
|
ownerId:
|
|
map['userId']?.toString() ??
|
|
map['ownerId']?.toString() ??
|
|
'', // Backend sends userId
|
|
name: map['name'] ?? '',
|
|
species: map['species'] ?? '',
|
|
breed: map['breed'] ?? '',
|
|
gender: map['gender'] ?? '',
|
|
isNeutered:
|
|
map['isNeutered'] == true ||
|
|
map['isNeutered'] == 'true', // Handle string/bool
|
|
birthDate: parseDate(map['birthDate']),
|
|
isDateUnknown:
|
|
map['isDateUnknown'] == true || map['isDateUnknown'] == 'true',
|
|
registrationNumber: map['registrationNumber'],
|
|
profileImageUrl: _parseImageUrl(
|
|
map['profileImageUrl'] ?? map['profileImagePath'],
|
|
),
|
|
weight: map['weight'] is int
|
|
? (map['weight'] as int).toDouble()
|
|
: map['weight']?.toDouble(),
|
|
diseases: parseList(map['diseases']),
|
|
pastDiseases: parseList(map['pastDiseases']),
|
|
healthConcerns: parseList(map['healthConcerns']),
|
|
createdAt: parseDate(map['createdAt']) ?? DateTime.now(),
|
|
);
|
|
}
|
|
|
|
static String? _parseImageUrl(String? url) {
|
|
if (url == null || url.isEmpty) return null;
|
|
if (url.startsWith('http')) return url;
|
|
// Prepend Backend URL for relative paths (MySQL/Multer)
|
|
// TODO: Improve architecture to not hardcode interactions in Model
|
|
const baseUrl = 'http://10.0.2.2:3000';
|
|
return '$baseUrl$url';
|
|
}
|
|
}
|