diff --git a/backend/ride/location/add_batch.php b/backend/ride/location/add_batch.php new file mode 100755 index 00000000..4a4d107c --- /dev/null +++ b/backend/ride/location/add_batch.php @@ -0,0 +1,129 @@ +prepare("SELECT created_at FROM car_tracks WHERE driver_id = ? ORDER BY created_at DESC LIMIT 1"); + $stmtLast->execute([$driver_id]); + $lastRow = $stmtLast->fetch(PDO::FETCH_ASSOC); + + if ($lastRow) { + $last_db_time = strtotime($lastRow['created_at']); + $diff_from_db = $first_point_time - $last_db_time; + + // إذا كان الفرق منطقياً (أقل من 5 دقائق) وموجباً، نحسبه + if ($diff_from_db > 0 && $diff_from_db < 300) { + $batch_added_seconds += $diff_from_db; + } + } + + // ج. حساب الفروقات داخل الباتش نفسه + $prev_time = $first_point_time; + + // نحدد تاريخ هذا الباتش (لنعرف أي يوم نحدث في الجدول اليومي) + $batch_date = date('Y-m-d', $first_point_time); + + foreach ($points as $key => $point) { + if ($key === 0) continue; // تخطي النقطة الأولى لأننا قارناها مع الداتابيز + + $current_time = strtotime($point['ts']); + $diff = $current_time - $prev_time; + + // تجاهل القفزات الكبيرة (أكثر من 5 دقائق) + if ($diff > 0 && $diff < 300) { + $batch_added_seconds += $diff; + } + $prev_time = $current_time; + } + + // --------------------------------------------------------- + // الجزء الثاني: إدخال التراكات (Bulk Insert) - كودك الأصلي + // --------------------------------------------------------- + + $values = []; + $placeholders = []; + + foreach ($points as $point) { + $lat = $point['lat'] ?? 0; + $lng = $point['lng'] ?? 0; + $spd = $point['spd'] ?? 0; + $head = $point['head'] ?? 0; + $dist = $point['dst'] ?? 0; + $stat = $point['st'] ?? 'off'; + $time = $point['ts'] ?? date('Y-m-d H:i:s'); + + $placeholders[] = "(?, ?, ?, ?, ?, ?, ?, ?)"; + array_push($values, $driver_id, $lat, $lng, $head, $spd, $dist, $stat, $time); + } + + $sql = "INSERT INTO `car_tracks` + (`driver_id`, `latitude`, `longitude`, `heading`, `speed`, `distance`, `status`, `created_at`) + VALUES " . implode(', ', $placeholders); + + $stmt = $con->prepare($sql); + $ok = $stmt->execute($values); + + // --------------------------------------------------------- + // الجزء الثالث: تحديث جدول الملخص اليومي (The Smart Update) + // --------------------------------------------------------- + + if ($ok && $batch_added_seconds > 0) { + // نستخدم ON DUPLICATE KEY UPDATE: + // إذا كان السائق موجوداً لهذا اليوم، أضف الثواني للرصيد الموجود + // إذا لم يكن موجوداً، أنشئ سجلاً جديداً + + $sqlSummary = "INSERT INTO `driver_daily_summary` (`driver_id`, `date`, `total_seconds`) + VALUES (?, ?, ?) + ON DUPLICATE KEY UPDATE `total_seconds` = `total_seconds` + VALUES(`total_seconds`)"; + + $stmtSum = $con->prepare($sqlSummary); + $stmtSum->execute([$driver_id, $batch_date, $batch_added_seconds]); + } + + if ($ok) { + echo json_encode(array( + "status" => "success", + "count" => count($points), + "added_seconds" => $batch_added_seconds // للتتبع فقط + )); + } else { + printFailure("Failed to insert batch"); + } + +} catch (PDOException $e) { + error_log("Batch insert error: " . $e->getMessage()); + printFailure("Database error"); +} catch (Throwable $e) { + printFailure("Server error"); +} +?> \ No newline at end of file diff --git a/siro_driver/lib/controller/functions/location_controller.dart b/siro_driver/lib/controller/functions/location_controller.dart index a65f641f..9681a51d 100755 --- a/siro_driver/lib/controller/functions/location_controller.dart +++ b/siro_driver/lib/controller/functions/location_controller.dart @@ -266,6 +266,12 @@ class LocationController extends GetxController with WidgetsBindingObserver { if (sid != null || eid != null) { isSocketConnected = true; + + if (myLocation.latitude != 0) { + print("🚀 Sending initial location to socket after connect..."); + emitLocationToSocket(myLocation, heading, speed); + } + _startHeartbeat(); // 🆕 طلب أي رحلات انتظار فاتتنا أثناء انقطاع الاتصال @@ -444,10 +450,6 @@ class LocationController extends GetxController with WidgetsBindingObserver { void _startHeartbeat() { _socketHeartbeat?.cancel(); _socketHeartbeat = Timer.periodic(const Duration(seconds: 25), (timer) { - // [Fix 6] تخطي الإرسال إذا كان stream الموقع نشطاً. - // الـ _locSub يرسل update_location عند كل تحرك (كل 5-10 ثوانٍ) تلقائياً. - // الـ heartbeat يكون مفيداً فقط عندما يتوقف الـ stream (الجهاز ثابت أو أوقف الخدمة). - if (_locSub != null) return; if (socket == null || !isSocketConnected || myLocation.latitude == 0) return; if (isBusMode) {