Update: 2026-08-07 01:53:09
This commit is contained in:
@@ -28,7 +28,16 @@ class OrderData {
|
||||
final double? driverEarningsExtra;
|
||||
final String? driverEarningsCurrency;
|
||||
|
||||
/// نوع الطلب: 'exclusive' خلال السبق الحصري، 'public' بعده، و null في
|
||||
/// وضع البثّ الحر (عندها لا تُعرض شارة ويعمل المؤقّت بمدته العادية).
|
||||
final String? offerType;
|
||||
|
||||
/// ثواني السبق الحصري كما حددها الخادم (DISPATCH_HEAD_START_SECONDS).
|
||||
final int offerExpiresIn;
|
||||
|
||||
OrderData({
|
||||
this.offerType,
|
||||
this.offerExpiresIn = 0,
|
||||
required this.customerName,
|
||||
required this.customerToken,
|
||||
required this.tripDistanceKm,
|
||||
@@ -135,9 +144,83 @@ class OrderData {
|
||||
list.length > 36 && list[36].toString().isNotEmpty
|
||||
? list[36].toString()
|
||||
: null,
|
||||
|
||||
// مسار FCM لا يحمل هذين اليوم — يبقيان محايدَين فلا تظهر شارة.
|
||||
offerType: list.length > 37 && list[37].toString().isNotEmpty
|
||||
? list[37].toString()
|
||||
: null,
|
||||
offerExpiresIn:
|
||||
list.length > 38 ? (int.tryParse(list[38].toString()) ?? 0) : 0,
|
||||
);
|
||||
}
|
||||
|
||||
/// بناء من حمولة السوكِت (خريطة). أسماء الحقول تطابق buildMarketPayload()
|
||||
/// في backend/ride/rides/add_ride.php — أي تغيير هناك يجب أن ينعكس هنا.
|
||||
///
|
||||
/// ملاحظة: حمولة السوق لا تحمل اسم الراكب ولا توكنه عمداً (تصل سائقين لن
|
||||
/// يقودوا الرحلة)، فتبقى القيم الافتراضية حتى يُقبل الطلب.
|
||||
factory OrderData.fromSocketMap(Map<dynamic, dynamic> map) {
|
||||
String str(String key, [String fallback = '']) =>
|
||||
map[key]?.toString().isNotEmpty == true ? map[key].toString() : fallback;
|
||||
|
||||
final distanceToPassengerMeters =
|
||||
double.tryParse(str('distanceToPassenger', '0')) ?? 0.0;
|
||||
|
||||
return OrderData(
|
||||
customerName: str('passengerName', 'Unknown Customer'),
|
||||
customerToken: str('passengerToken', 'Unknown token'),
|
||||
tripDistanceKm: double.tryParse(str('distance', '0')) ?? 0.0,
|
||||
price: str('price', '0').split('.')[0],
|
||||
startLocationAddress: str('startName', 'Unknown Address'),
|
||||
endLocationAddress: str('endName', 'Unknown Address'),
|
||||
distanceToPassengerKm: distanceToPassengerMeters / 1000.0,
|
||||
tripDurationMinutes: _secondsToRoundedUpMinutes(str('duration', '0')),
|
||||
durationToPassengerMinutes:
|
||||
_secondsToRoundedUpMinutes(str('durationToPassenger', '0')),
|
||||
rideType: _getRideType(str('carType', 'Unknown')),
|
||||
orderId: str('id', 'N/A'),
|
||||
passengerId: str('passengerId', 'N/A'),
|
||||
passengerRate: str('passengerRate', 'N/A'),
|
||||
rawStartCoordinates: str('start_location').isNotEmpty
|
||||
? str('start_location')
|
||||
: (str('start_lat').isNotEmpty
|
||||
? '${str('start_lat')},${str('start_lng')}'
|
||||
: null),
|
||||
rawEndCoordinates: str('end_location').isNotEmpty
|
||||
? str('end_location')
|
||||
: (str('end_lat').isNotEmpty
|
||||
? '${str('end_lat')},${str('end_lng')}'
|
||||
: null),
|
||||
driverEarningsExtra: double.tryParse(str('driver_earnings_extra')),
|
||||
driverEarningsCurrency: str('driver_earnings_currency').isNotEmpty
|
||||
? str('driver_earnings_currency')
|
||||
: null,
|
||||
offerType: str('offer_type').isNotEmpty ? str('offer_type') : null,
|
||||
offerExpiresIn: int.tryParse(str('offer_expires_in', '0')) ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
/// الموحِّد: FCM يصل قائمةً مفهرسة، والسوكِت يصل خريطة JSON. النافذة
|
||||
/// الواحدة تخدم المسارين، فالتمييز يتم هنا لا في كل مستدعٍ.
|
||||
/// يرجع null على أي شكل غير معروف بدل أن يرمي — النافذة تبقى صامتة
|
||||
/// بدل أن تنهار على حمولة غريبة.
|
||||
static OrderData? fromAny(dynamic event) {
|
||||
if (event is List) return OrderData.fromList(event);
|
||||
|
||||
if (event is Map) {
|
||||
// خريطتان مختلفتان تصلان هنا: حمولة السوكِت (أسماء الخادم: id،
|
||||
// carType، startName) وخريطة toMap() الداخلية (orderId، rideType).
|
||||
// نميّز بالمفتاح لا بالنوع، وإلا قرأنا إحداهما بقواعد الأخرى فخرجت
|
||||
// كل الحقول فارغة بصمت.
|
||||
if (event.containsKey('orderId') || event.containsKey('rideType')) {
|
||||
return OrderData.fromMap(Map<String, dynamic>.from(event));
|
||||
}
|
||||
return OrderData.fromSocketMap(event);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String _getRideType(String type) {
|
||||
switch (type) {
|
||||
case 'Comfort':
|
||||
|
||||
Reference in New Issue
Block a user