Files
intaleq_driver/lib/readme.md
Hamza-Ayed 3c0ae4cf2f 26-1-20/1
2026-01-20 10:11:10 +03:00

9.1 KiB

إليك التوثيق التقني العميق (Deep Technical Documentation) لتطبيق السائق (Driver App) في منصة انطلق (Intaleq). تم إعداد هذا التقرير بناءً على تحليل الكود المصدري، مع التركيز على البنية التحتية، تدفق البيانات، والخدمات الخلفية.


📘 Intaleq Driver App - Technical Documentation

الإصدار: 1.0 المعمارية: MVC using GetX اللغة: Dart (Flutter) إدارة الحالة: GetX (Reactive State Management)


1. 🔐 التسجيل والتحقق (Onboarding & KYC)

نظام التسجيل في تطبيق السائق معقد لأنه يتطلب التحقق من الهوية والأهلية قبل السماح للسائق بالعمل.

أ. دورة تسجيل السائق (Driver Registration Flow)

  • المسار: lib/controller/auth/captin/register_captin_controller.dart
  • الآلية:
    1. التحقق من الهاتف: يتم استخدام SmsEgyptController أو PhoneAuthHelper لإرسال OTP. يتم التحقق مما إذا كان الرقم مسجلاً مسبقاً عبر checkPhoneNumberISVerfiedDriver.
    2. إدخال البيانات الأساسية: (الاسم، البريد، تاريخ الميلاد) يتم جمعها في RegistrationView.
    3. إنشاء الحساب: يتم استدعاء signUpCaptin.php لإنشاء سجل أولي للسائق بحالة yet (بانتظار التوثيق).

ب. نظام رفع الوثائق والمعالجة بالذكاء الاصطناعي (AI & OCR)

  • المسؤوليـة: lib/controller/functions/gemeni.dart (الكلاس AI).
  • العملية التقنية:
    1. التقاط الصورة: يتم استخدام ImagePicker و ImageCropper لضمان جودة الصورة.
    2. الضغط: يتم ضغط الصورة باستخدام FlutterImageCompress لتقليل استهلاك البيانات.
    3. التحليل (AI Extraction):
      • يتم رفع الصورة إلى uploadImageToAi.
      • يتم تمرير prompt هندسي دقيق لنموذج الذكاء الاصطناعي (مثل Gemini أو نماذج OCR مخصصة) لاستخراج البيانات كـ JSON (مثل: vin, make, model, plate_number).
    4. التعبئة التلقائية: البيانات المستخرجة تُعبأ تلقائياً في RegisterCaptainController ليقوم السائق بمراجعتها فقط، مما يقلل أخطاء الإدخال اليدوي.

ج. حالة "بانتظار الموافقة" (Pending Approval)

  • المسؤوليـة: LoginDriverController و DriverVerificationScreen.
  • المنطق:
    • عند تسجيل الدخول، يتحقق النظام من الحقل status و is_verified في استجابة الـ login.
    • إذا كانت الحالة yet، يتم توجيه السائق إجبارياً إلى شاشة DriverVerificationScreen التي تعرض رسالة "Your Application is Under Review" وتمنع الوصول للخريطة.

2. 📡 الخدمات الخلفية والتتبع (Background Services & Tracking)

يعتمد التطبيق على نظام تتبع ذكي (Batch Tracking) لتقليل استهلاك البطارية والبيانات مع الحفاظ على الدقة.

أ. محرك الموقع (LocationController)

  • المسار: lib/controller/functions/location_controller.dart.
  • آلية العمل في الخلفية:
    1. التهيئة: يتم تفعيل location.enableBackgroundMode(enable: true) لضمان استمرار الخدمة عند إغلاق الشاشة.
    2. التخزين المؤقت (Buffering): بدلاً من إرسال كل نقطة GPS للسيرفر، يتم تخزين النقاط في قائمة محلية _trackBuffer.
    3. التصفية الذكية (Smart Filtering): لا يتم تسجيل النقطة إلا إذا تحرك السائق مسافة معينة (onMoveMetersNormal = 15m) أو مرّ وقت محدد (30 ثانية) لضمان تسجيل التوقفات.

ب. إرسال البيانات (Batch Upload)

  • يوجد مؤقت _uploadTimer يعمل كل دقيقتين (في الوضع العادي).
  • يقوم هذا المؤقت بجمع كل النقاط في _trackBuffer، تحويلها لـ JSON، وإرسالها بطلب واحد POST إلى add_batch.php. هذا يقلل الحمل على السيرفر بنسبة كبيرة جداً.

ج. وضع توفير الطاقة (Power Saving Mode)

  • يراقب التطبيق حالة البطارية عبر BatteryNotifier. إذا انخفضت عن 20%، يتم تقليل معدل التحديث (تسجيل كل 6 ثواني ورفع كل 4 دقائق).

3. 🔔 استقبال الطلبات (Request Handling)

أ. النافذة العائمة (Overlay Window)

  • التقنية: flutter_overlay_window.
  • المسار: lib/main.dart (Background Handler) و lib/views/home/Captin/orderCaptin/order_over_lay.dart.
  • كيفية العمل:
    1. عند وصول إشعار FCM من نوع Order والتطبيق في الخلفية، يتم استدعاء backgroundMessageHandler.
    2. يتم التحقق من إذن الرسم فوق التطبيقات. إذا مُنح، يتم استدعاء FlutterOverlayWindow.showOverlay وتمرير بيانات الطلب (DriverList).
    3. ملف order_over_lay.dart هو تطبيق Flutter مصغر يعمل بشكل مستقل فوق التطبيقات الأخرى. يحتوي على منطق قبول/رفض خاص به ويتصل بالسيرفر مباشرة.

ب. منطق القبول والرفض (OrderRequestController)

  • المسار: lib/controller/home/captin/order_request_controller.dart.
  • العداد التنازلي: يتم تشغيل startTimer لمدة 15-20 ثانية. إذا انتهى الوقت، يتم رفض الطلب تلقائياً.
  • القبول: عند الضغط على "قبول"، يتم استدعاء updateStausFromSpeed.php لحجز الطلب ومنع تضارب السائقين (Race Condition).

4. 🚗 تنفيذ الرحلة (Trip Execution Workflow)

يدير MapDriverController دورة حياة الرحلة بالكامل.

أ. الذهاب للراكب (Going to Passenger)

  • عند قبول الطلب، تتغير الحالة إلى Apply.
  • يتم عرض موقع الراكب على الخريطة ورسم المسار باستخدام getRoute (يعتمد على OSRM أو Google Directions).
  • يمكن للسائق فتح خرائط جوجل الخارجية عبر openGoogleMapFromDriverToPassenger.

ب. الوصول (Arrived)

  • الزر: I Arrive.
  • المنطق البرمجي: يتحقق الكود أولاً من المسافة بين السائق والراكب. إذا كانت أقل من 140 متر (distance < 140)، يتم إرسال إشعار Hi ,I Arrive your site للراكب وتفعيل عداد الانتظار.

ج. بدء وإنهاء الرحلة

  • البدء (Begin): يطلب النظام تأكيداً "Is the Passenger in your Car?". عند الموافقة، يتم إرسال status: Begin للسيرفر ويبدأ عداد الرحلة الفعلي rideIsBeginPassengerTimer.
  • الإنهاء (Finish):
    • يتم حساب المسافة المقطوعة والوقت.
    • يتم استدعاء finishRideFromDriver1 التي تقوم بإرسال طلبين متزامنين: تحديث حالة الرحلة وتنفيذ عملية الدفع process_ride_payments.php.
    • يتم تحويل السائق لصفحة تقييم الراكب RatePassenger.

5. 💰 المحفظة والأرباح (Wallet & Earnings)

  • المسار: lib/controller/home/payment/captain_wallet_controller.dart.

أ. عرض الرصيد والديون

  • يتم جلب البيانات المالية عبر getCaptainWalletFromRide (للأرباح من الرحلات) و getCaptainWalletFromBuyPoints (للنقاط المشتراة).
  • الحظر المالي: إذا انخفض رصيد النقاط عن حد معين (مثل -300)، يتم منع السائق من استقبال الطلبات ويظهر زر Charge your Account.

ب. آلية الشحن

  • يتم دعم بوابات دفع متعددة مثل Syriatel Cash و MTN Cash.
  • عند الشحن، يتم إنشاء Invoice وانتظار الـ Callback أو التحقق الدوري (polling) من حالة الدفع.

6. ⚙️ الإعدادات والميزات الإضافية

  • إعدادات السيارة: تدار عبر DriverCarController و CarsInsertingPage، حيث يمكن إضافة سيارات جديدة ورفع وثائقها.
  • اللغة: LocaleController يدير التبديل بين العربية والإنجليزية ويحفظ التفضيل في GetStorage.
  • التقييم: يتم جلب تقييم السائق عبر getDriverRate وعرضه في القائمة الجانبية أو الرأسية.