didvan-app/lib/models/user.dart

128 lines
4.1 KiB
Dart

// lib/models/user.dart
//
// مدل کاربر. به‌روزرسانی شده برای پشتیبانی از بک‌اند جدید (Keycloak):
// - بک‌اند جدید id را به صورت UUID (string) برمی‌گرداند => `keycloakId`.
// - برای سازگاری با کدهای قدیمی پروژه که از `user.id` (int) استفاده می‌کنند،
// فیلد `id` نگه داشته شده است (0 در صورت نبود معادل عددی).
// - فیلدهای جدید بک‌اند: firstName, lastName, phone, avatar
// معادل قدیمی: fullName, phoneNumber, photo
// - متد `fromJson` هر دو شکل قدیمی و جدید را قبول می‌کند.
class User {
/// Identifier عددی قدیمی (سازگاری). در بک‌اند جدید معمولا 0 خواهد بود.
final int id;
/// شناسه کاربر در Keycloak (UUID). در بک‌اند جدید کلید اصلی است.
final String? keycloakId;
final String phoneNumber;
final String fullName;
final String? username;
final String? photo;
final String? email;
final String? firstName;
final String? lastName;
const User({
required this.id,
required this.username,
required this.phoneNumber,
required this.photo,
required this.fullName,
required this.email,
this.keycloakId,
this.firstName,
this.lastName,
});
/// سازنده‌ای که هم با شکل قدیمی (`{id, fullName, phoneNumber, photo, ...}`)
/// و هم با شکل جدید (`{id: <uuid>, firstName, lastName, phone, avatar, ...}`)
/// کار می‌کند.
factory User.fromJson(Map<String, dynamic> json) {
// id ممکن است int یا String (UUID) باشد.
final dynamic rawId = json['id'];
int intId = 0;
String? keycloakId;
if (rawId is int) {
intId = rawId;
} else if (rawId is String) {
keycloakId = rawId;
intId = int.tryParse(rawId) ?? 0;
}
// اولویت با فیلد جدید keycloakId اگر صریح ارسال شده باشد.
if (json['keycloakId'] is String) {
keycloakId = json['keycloakId'] as String;
}
// ساخت fullName: اگر مستقیم آمده استفاده می‌کنیم،
// وگرنه از firstName + lastName می‌سازیم.
final firstName = json['firstName'] as String?;
final lastName = json['lastName'] as String?;
String fullName;
if (json['fullName'] is String &&
(json['fullName'] as String).isNotEmpty) {
fullName = json['fullName'] as String;
} else {
fullName = [
firstName ?? '',
lastName ?? '',
].where((s) => s.isNotEmpty).join(' ');
}
// phoneNumber: قدیم `phoneNumber`، جدید `phone`.
final phone = (json['phoneNumber'] ?? json['phone'] ?? '') as String;
// photo: قدیم `photo`، جدید `avatar`.
final photo = (json['photo'] ?? json['avatar']) as String?;
return User(
id: intId,
keycloakId: keycloakId,
username: json['username'] as String?,
phoneNumber: phone,
photo: photo,
fullName: fullName,
email: json['email'] as String?,
firstName: firstName,
lastName: lastName,
);
}
Map<String, dynamic> toJson() => {
'id': id,
if (keycloakId != null) 'keycloakId': keycloakId,
'username': username,
'phoneNumber': phoneNumber,
'photo': photo,
'fullName': fullName,
'email': email,
if (firstName != null) 'firstName': firstName,
if (lastName != null) 'lastName': lastName,
};
User copyWith({
int? id,
String? keycloakId,
String? username,
String? phoneNumber,
String? photo,
String? fullName,
String? email,
String? firstName,
String? lastName,
}) {
return User(
id: id ?? this.id,
keycloakId: keycloakId ?? this.keycloakId,
username: username ?? this.username,
phoneNumber: phoneNumber ?? this.phoneNumber,
photo: photo,
fullName: fullName ?? this.fullName,
email: email ?? this.email,
firstName: firstName ?? this.firstName,
lastName: lastName ?? this.lastName,
);
}
}