Update: 2026-07-02 16:52:25
This commit is contained in:
@@ -371,9 +371,17 @@ function dispatchRideToDrivers($driversData, $rideId, $payloadTemplate, $startNa
|
|||||||
'DriverList' => $payloadForDriver,
|
'DriverList' => $payloadForDriver,
|
||||||
'order_id' => (string)$rideId
|
'order_id' => (string)$rideId
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 🆕 Destination Match Indicator
|
||||||
|
$title = "طلب جديد 🔔";
|
||||||
|
if (!empty($driver['is_destination_match'])) {
|
||||||
|
$title = "في طريقك! 📍";
|
||||||
|
$fcmData['is_destination_match'] = "1";
|
||||||
|
}
|
||||||
|
|
||||||
$fcmResult = sendFcmNotification(
|
$fcmResult = sendFcmNotification(
|
||||||
$driverToken,
|
$driverToken,
|
||||||
"طلب جديد 🔔",
|
$title,
|
||||||
"هناك رحلة جديدة من " . $startNameLoc,
|
"هناك رحلة جديدة من " . $startNameLoc,
|
||||||
$fcmData,
|
$fcmData,
|
||||||
"Order",
|
"Order",
|
||||||
|
|||||||
@@ -52,15 +52,31 @@ function notifySocketServerDestination($userId, $hasDestination, $destLat = '',
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if ($action === 'get') {
|
if ($action === 'get') {
|
||||||
$stmtGet = $con->prepare("
|
// 🟥 Read from Redis FIRST
|
||||||
SELECT target_latitude, target_longitude, destination_name, created_at
|
$activeDest = null;
|
||||||
FROM driver_destinations
|
if (isset($redis)) {
|
||||||
WHERE driver_id = :did
|
try {
|
||||||
AND is_active = 1
|
$cached = $redis->get("driver:destination:{$user_id}");
|
||||||
LIMIT 1
|
if ($cached) {
|
||||||
");
|
$activeDest = json_decode($cached, true);
|
||||||
$stmtGet->execute([':did' => $user_id]);
|
}
|
||||||
$activeDest = $stmtGet->fetch(PDO::FETCH_ASSOC);
|
} catch (Exception $e) {
|
||||||
|
error_log("[save_driver_destination] Redis GET error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🟦 Fallback to SQL if Redis miss
|
||||||
|
if (!$activeDest) {
|
||||||
|
$stmtGet = $con->prepare("
|
||||||
|
SELECT target_latitude, target_longitude, destination_name, created_at
|
||||||
|
FROM driver_destinations
|
||||||
|
WHERE driver_id = :did
|
||||||
|
AND is_active = 1
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmtGet->execute([':did' => $user_id]);
|
||||||
|
$activeDest = $stmtGet->fetch(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
if ($activeDest) {
|
if ($activeDest) {
|
||||||
jsonSuccess($activeDest, "Active destination retrieved.");
|
jsonSuccess($activeDest, "Active destination retrieved.");
|
||||||
@@ -71,6 +87,18 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($action === 'clear') {
|
if ($action === 'clear') {
|
||||||
|
// 🟥 Clear from Redis FIRST
|
||||||
|
if (isset($redis)) {
|
||||||
|
try {
|
||||||
|
$redis->del("driver:destination:{$user_id}");
|
||||||
|
// Remove from the Geo Index (used by GEORADIUS search in pricing engine)
|
||||||
|
$redis->zRem("geo:driver:destinations", (string)$user_id);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log("[save_driver_destination] Redis DEL error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🟦 Then clear from SQL
|
||||||
$stmtDeactivate = $con->prepare("
|
$stmtDeactivate = $con->prepare("
|
||||||
UPDATE driver_destinations
|
UPDATE driver_destinations
|
||||||
SET is_active = 0
|
SET is_active = 0
|
||||||
@@ -79,7 +107,7 @@ try {
|
|||||||
");
|
");
|
||||||
$stmtDeactivate->execute([':did' => $user_id]);
|
$stmtDeactivate->execute([':did' => $user_id]);
|
||||||
|
|
||||||
// Sync with Redis on Socket Server
|
// Sync with Socket Server
|
||||||
notifySocketServerDestination($user_id, 0);
|
notifySocketServerDestination($user_id, 0);
|
||||||
|
|
||||||
jsonSuccess(null, "تم إلغاء تفعيل الوجهة الشخصية بنجاح.");
|
jsonSuccess(null, "تم إلغاء تفعيل الوجهة الشخصية بنجاح.");
|
||||||
@@ -130,7 +158,36 @@ try {
|
|||||||
");
|
");
|
||||||
$stmtDeactivate->execute([':did' => $user_id]);
|
$stmtDeactivate->execute([':did' => $user_id]);
|
||||||
|
|
||||||
// 5. Insert new destination
|
// 🟥 5a. Write to Redis FIRST (primary read path for pricing engine)
|
||||||
|
if (isset($redis)) {
|
||||||
|
try {
|
||||||
|
$destData = [
|
||||||
|
'driver_id' => $user_id,
|
||||||
|
'target_latitude' => (float)$destLat,
|
||||||
|
'target_longitude' => (float)$destLng,
|
||||||
|
'destination_name' => $destName,
|
||||||
|
'is_active' => 1,
|
||||||
|
'usage_date' => date('Y-m-d')
|
||||||
|
];
|
||||||
|
// TTL: end of day (midnight)
|
||||||
|
$secondsUntilMidnight = strtotime('tomorrow') - time();
|
||||||
|
|
||||||
|
// A) Store details as JSON string (for reading driver info)
|
||||||
|
$redis->setex("driver:destination:{$user_id}", $secondsUntilMidnight, json_encode($destData));
|
||||||
|
|
||||||
|
// B) Add to Geo Index for ultra-fast GEORADIUS proximity search
|
||||||
|
// GEOADD key longitude latitude member
|
||||||
|
$redis->geoAdd("geo:driver:destinations", (float)$destLng, (float)$destLat, (string)$user_id);
|
||||||
|
// Geo index has no native TTL per-member, so we set TTL on the whole key if not already set
|
||||||
|
if ($redis->ttl("geo:driver:destinations") < 0) {
|
||||||
|
$redis->expire("geo:driver:destinations", $secondsUntilMidnight);
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log("[save_driver_destination] Redis SET error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🟦 5b. Insert into SQL as secondary (persistent store)
|
||||||
$stmtInsert = $con->prepare("
|
$stmtInsert = $con->prepare("
|
||||||
INSERT INTO driver_destinations
|
INSERT INTO driver_destinations
|
||||||
(driver_id, target_latitude, target_longitude, destination_name, is_active, usage_date)
|
(driver_id, target_latitude, target_longitude, destination_name, is_active, usage_date)
|
||||||
@@ -143,12 +200,12 @@ try {
|
|||||||
':name' => $destName
|
':name' => $destName
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Sync with Redis on Socket Server
|
// Sync with Socket Server
|
||||||
notifySocketServerDestination($user_id, 1, $destLat, $destLng, $destName);
|
notifySocketServerDestination($user_id, 1, $destLat, $destLng, $destName);
|
||||||
|
|
||||||
// Increment local Redis counter
|
// Increment local Redis counter
|
||||||
if (isset($redis)) {
|
if (isset($redis)) {
|
||||||
$redisKey = "driver:dest_count:" . $user_id;
|
$redisKey = "driver:dest_count:{$user_id}";
|
||||||
$redis->incr($redisKey);
|
$redis->incr($redisKey);
|
||||||
$redis->expire($redisKey, 86400); // 24 hours TTL
|
$redis->expire($redisKey, 86400); // 24 hours TTL
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -449,6 +449,86 @@ if (!empty($passenger_id)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🆕 المطابقة الذكية للوجهة (Destination Matching)
|
||||||
|
// Architecture: GEORADIUS (O(log N+K)) → detail fetch → SQL fallback
|
||||||
|
$isDestinationMatch = false;
|
||||||
|
$matchedDriverId = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$bestDriverId = 0;
|
||||||
|
$foundViaRedis = false;
|
||||||
|
|
||||||
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
// 🟥 Step 1: Redis GEORADIUS — ultra-fast O(log N + K) search
|
||||||
|
// Finds all drivers whose destination is within 3.5 km of
|
||||||
|
// the passenger's drop-off point. No PHP math. No full scan.
|
||||||
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
if (isset($redis)) {
|
||||||
|
try {
|
||||||
|
// geoRadius(key, longitude, latitude, radius, unit, [options])
|
||||||
|
$nearbyDriverIds = $redis->geoRadius(
|
||||||
|
'geo:driver:destinations',
|
||||||
|
(float)$destLng,
|
||||||
|
(float)$destLat,
|
||||||
|
3.5,
|
||||||
|
'km',
|
||||||
|
['COUNT' => 1, 'ASC'] // closest first, stop after 1
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!empty($nearbyDriverIds)) {
|
||||||
|
$candidateId = (string)$nearbyDriverIds[0];
|
||||||
|
// Verify destination is still active today (read detail JSON)
|
||||||
|
$detailJson = $redis->get("driver:destination:{$candidateId}");
|
||||||
|
$detail = $detailJson ? json_decode($detailJson, true) : null;
|
||||||
|
|
||||||
|
if ($detail
|
||||||
|
&& !empty($detail['is_active'])
|
||||||
|
&& ($detail['usage_date'] ?? '') === date('Y-m-d')
|
||||||
|
) {
|
||||||
|
$bestDriverId = $candidateId;
|
||||||
|
$foundViaRedis = true;
|
||||||
|
} else {
|
||||||
|
// Stale entry — clean up from geo index
|
||||||
|
$redis->zRem('geo:driver:destinations', $candidateId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log("[Destination Matching] Redis GEORADIUS error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
// 🟦 Step 2: SQL Fallback (only if Redis unavailable or empty)
|
||||||
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
if (!$foundViaRedis) {
|
||||||
|
$stmtDest = $con->prepare("
|
||||||
|
SELECT driver_id,
|
||||||
|
( 6371 * acos( cos( radians(:endLat) ) * cos( radians( target_latitude ) )
|
||||||
|
* cos( radians( target_longitude ) - radians(:endLng) ) + sin( radians(:endLat) )
|
||||||
|
* sin( radians( target_latitude ) ) ) ) AS dest_distance
|
||||||
|
FROM driver_destinations
|
||||||
|
WHERE is_active = 1 AND usage_date = CURDATE()
|
||||||
|
HAVING dest_distance <= 3.5
|
||||||
|
ORDER BY dest_distance ASC
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmtDest->execute([':endLat' => $destLat, ':endLng' => $destLng]);
|
||||||
|
$destMatch = $stmtDest->fetch(PDO::FETCH_ASSOC);
|
||||||
|
if ($destMatch) {
|
||||||
|
$bestDriverId = $destMatch['driver_id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($bestDriverId) {
|
||||||
|
$isDestinationMatch = true;
|
||||||
|
$matchedDriverId = $bestDriverId;
|
||||||
|
// Passenger gets 14% discount for Destination Match
|
||||||
|
$discount = max((float)$discount, 14.0);
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log("[Destination Matching] Error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate prices for all categories
|
// Calculate prices for all categories
|
||||||
foreach ($categories as $key => $carType) {
|
foreach ($categories as $key => $carType) {
|
||||||
$result = calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng, $carType);
|
$result = calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng, $carType);
|
||||||
@@ -497,6 +577,8 @@ if (isset($encryptionHelper)) {
|
|||||||
// ✅ FIX R6: تضمين distance و duration في الـ token لمنع التلاعب
|
// ✅ FIX R6: تضمين distance و duration في الـ token لمنع التلاعب
|
||||||
'distance' => $distance,
|
'distance' => $distance,
|
||||||
'duration' => $duration,
|
'duration' => $duration,
|
||||||
|
'is_destination_match' => $isDestinationMatch ? 1 : 0,
|
||||||
|
'matched_driver_id' => $matchedDriverId,
|
||||||
'expires' => time() + 420, // Valid for 7 minutes
|
'expires' => time() + 420, // Valid for 7 minutes
|
||||||
'prices' => $pricesRaw
|
'prices' => $pricesRaw
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -160,6 +160,10 @@ $price = $tokenData['prices'][$tokenCarType]['price'];
|
|||||||
$price_for_driver = $tokenData['prices'][$tokenCarType]['driver_price'];
|
$price_for_driver = $tokenData['prices'][$tokenCarType]['driver_price'];
|
||||||
$price_for_passenger = $price;
|
$price_for_passenger = $price;
|
||||||
|
|
||||||
|
// 🆕 Destination Matching
|
||||||
|
$is_destination_match = isset($tokenData['is_destination_match']) ? (int)$tokenData['is_destination_match'] : 0;
|
||||||
|
$matched_driver_id = isset($tokenData['matched_driver_id']) ? $tokenData['matched_driver_id'] : 0;
|
||||||
|
|
||||||
// ── 2. تنسيق التواريخ ─────────────────────────────────────────
|
// ── 2. تنسيق التواريخ ─────────────────────────────────────────
|
||||||
$date_formatted = date("Y-m-d");
|
$date_formatted = date("Y-m-d");
|
||||||
$time_formatted = date("H:i:s");
|
$time_formatted = date("H:i:s");
|
||||||
@@ -191,16 +195,17 @@ $insertData = [
|
|||||||
':price_for_driver' => $price_for_driver,
|
':price_for_driver' => $price_for_driver,
|
||||||
':price_for_passenger' => $price_for_passenger,
|
':price_for_passenger' => $price_for_passenger,
|
||||||
':distance' => $distance,
|
':distance' => $distance,
|
||||||
|
':is_destination_match' => $is_destination_match,
|
||||||
];
|
];
|
||||||
|
|
||||||
$sqlInsert = "INSERT INTO `ride`
|
$sqlInsert = "INSERT INTO `ride`
|
||||||
(`start_location`,`end_location`,`date`,`time`,`endtime`,
|
(`start_location`,`end_location`,`date`,`time`,`endtime`,
|
||||||
`price`,`passenger_id`,`driver_id`,`status`,`carType`,
|
`price`,`passenger_id`,`driver_id`,`status`,`carType`,
|
||||||
`price_for_driver`,`price_for_passenger`,`distance`)
|
`price_for_driver`,`price_for_passenger`,`distance`,`is_destination_match`)
|
||||||
VALUES
|
VALUES
|
||||||
(:start_location,:end_location,:date,:time,:endtime,
|
(:start_location,:end_location,:date,:time,:endtime,
|
||||||
:price,:passenger_id,:driver_id,:status,:carType,
|
:price,:passenger_id,:driver_id,:status,:carType,
|
||||||
:price_for_driver,:price_for_passenger,:distance)";
|
:price_for_driver,:price_for_passenger,:distance,:is_destination_match)";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// ═══════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════
|
||||||
@@ -224,11 +229,11 @@ try {
|
|||||||
$sqlInsertWithId = "INSERT INTO `ride`
|
$sqlInsertWithId = "INSERT INTO `ride`
|
||||||
(`id`,`start_location`,`end_location`,`date`,`time`,`endtime`,
|
(`id`,`start_location`,`end_location`,`date`,`time`,`endtime`,
|
||||||
`price`,`passenger_id`,`driver_id`,`status`,`carType`,
|
`price`,`passenger_id`,`driver_id`,`status`,`carType`,
|
||||||
`price_for_driver`,`price_for_passenger`,`distance`)
|
`price_for_driver`,`price_for_passenger`,`distance`,`is_destination_match`)
|
||||||
VALUES
|
VALUES
|
||||||
(:id,:start_location,:end_location,:date,:time,:endtime,
|
(:id,:start_location,:end_location,:date,:time,:endtime,
|
||||||
:price,:passenger_id,:driver_id,:status,:carType,
|
:price,:passenger_id,:driver_id,:status,:carType,
|
||||||
:price_for_driver,:price_for_passenger,:distance)";
|
:price_for_driver,:price_for_passenger,:distance,:is_destination_match)";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$primaryData = $insertData;
|
$primaryData = $insertData;
|
||||||
@@ -285,6 +290,36 @@ try {
|
|||||||
|
|
||||||
// Direct dispatch للسائقين القريبين
|
// Direct dispatch للسائقين القريبين
|
||||||
$driversData = findBestDrivers($con, $startLat, $startLng, $carType, $endLat, $endLng);
|
$driversData = findBestDrivers($con, $startLat, $startLng, $carType, $endLat, $endLng);
|
||||||
|
|
||||||
|
// 🆕 Destination Matching Priority
|
||||||
|
if ($is_destination_match && $matched_driver_id) {
|
||||||
|
$found = false;
|
||||||
|
foreach ($driversData as $k => $d) {
|
||||||
|
if ($d['captain_id'] == $matched_driver_id) {
|
||||||
|
// Remove from current position and move to the very front
|
||||||
|
unset($driversData[$k]);
|
||||||
|
$d['is_destination_match'] = 1;
|
||||||
|
array_unshift($driversData, $d);
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If driver wasn't nearby but we still want to give it to them because it's their route
|
||||||
|
if (!$found) {
|
||||||
|
$stmtD = $con->prepare("SELECT token FROM driverToken WHERE captain_id = :d");
|
||||||
|
$stmtD->execute([':d' => $matched_driver_id]);
|
||||||
|
$dT = $stmtD->fetchColumn();
|
||||||
|
if ($dT) {
|
||||||
|
array_unshift($driversData, [
|
||||||
|
'captain_id' => $matched_driver_id,
|
||||||
|
'token' => $dT,
|
||||||
|
'is_destination_match' => 1
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($driversData)) {
|
if (!empty($driversData)) {
|
||||||
dispatchRideToDrivers($driversData, $insertedId, $payload, $start_name_loc, $encryptionHelper);
|
dispatchRideToDrivers($driversData, $insertedId, $payload, $start_name_loc, $encryptionHelper);
|
||||||
error_log("[add_ride] Dispatched RideID=$insertedId to " . count($driversData) . " drivers.");
|
error_log("[add_ride] Dispatched RideID=$insertedId to " . count($driversData) . " drivers.");
|
||||||
|
|||||||
@@ -1458,6 +1458,7 @@ CREATE TABLE `ride` (
|
|||||||
`carType` varchar(20) NOT NULL DEFAULT 'Speed',
|
`carType` varchar(20) NOT NULL DEFAULT 'Speed',
|
||||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`is_destination_match` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
`DriverIsGoingToPassenger` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`DriverIsGoingToPassenger` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`rideTimeStart` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`rideTimeStart` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`rideTimeFinish` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`rideTimeFinish` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|||||||
@@ -1361,6 +1361,7 @@ CREATE TABLE `ride` (
|
|||||||
`carType` varchar(20) NOT NULL DEFAULT 'Speed',
|
`carType` varchar(20) NOT NULL DEFAULT 'Speed',
|
||||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`is_destination_match` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
`DriverIsGoingToPassenger` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`DriverIsGoingToPassenger` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`rideTimeStart` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`rideTimeStart` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`rideTimeFinish` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`rideTimeFinish` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|||||||
@@ -157,7 +157,8 @@ class FirebaseMessagesController extends GetxController {
|
|||||||
Get.toNamed('/OrderRequestPage', arguments: {
|
Get.toNamed('/OrderRequestPage', arguments: {
|
||||||
'myListString': myListString,
|
'myListString': myListString,
|
||||||
'DriverList': myList,
|
'DriverList': myList,
|
||||||
'body': body
|
'body': body,
|
||||||
|
'is_destination_match': message.data['is_destination_match'] ?? '0',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -405,7 +405,8 @@ class LocationController extends GetxController with WidgetsBindingObserver {
|
|||||||
Get.toNamed('/OrderRequestPage', arguments: {
|
Get.toNamed('/OrderRequestPage', arguments: {
|
||||||
'myListString': jsonEncode(driverList),
|
'myListString': jsonEncode(driverList),
|
||||||
'DriverList': driverList,
|
'DriverList': driverList,
|
||||||
'body': 'New Trip Request via Socket ⚡'
|
'body': 'New Trip Request via Socket ⚡',
|
||||||
|
'is_destination_match': rideData['is_destination_match'] ?? '0',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Log.print(
|
Log.print(
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class OrderRequestController extends GetxController
|
|||||||
String totalTripDistance = "--";
|
String totalTripDistance = "--";
|
||||||
String totalTripDuration = "--";
|
String totalTripDuration = "--";
|
||||||
String tripPrice = "--";
|
String tripPrice = "--";
|
||||||
|
bool isDestinationMatch = false; // 🆕 Destination Match flag
|
||||||
|
|
||||||
String timeToPassenger = "Calculating...".tr;
|
String timeToPassenger = "Calculating...".tr;
|
||||||
String distanceToPassenger = "--";
|
String distanceToPassenger = "--";
|
||||||
@@ -158,6 +159,12 @@ class OrderRequestController extends GetxController
|
|||||||
print("Error decoding DriverList: $e");
|
print("Error decoding DriverList: $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 🆕 Check for Destination Match flag from FCM data
|
||||||
|
if (args['is_destination_match'] == '1' ||
|
||||||
|
args['is_destination_match'] == 1 ||
|
||||||
|
args['is_destination_match'] == true) {
|
||||||
|
isDestinationMatch = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ب) هل هي قادمة من Socket بالمفاتيح الرقمية ("0", "1", ...)؟
|
// ب) هل هي قادمة من Socket بالمفاتيح الرقمية ("0", "1", ...)؟
|
||||||
else {
|
else {
|
||||||
|
|||||||
Reference in New Issue
Block a user