303 lines
18 KiB
Markdown
303 lines
18 KiB
Markdown
# تقرير فني: دورة حياة الرحلة وتتبع نظام الموقع في تطبيق السائق (Siro Driver)
|
|
|
|
## 1. منطق الاتصال بالشبكة وفحوصات السلامة (Connection & Safety Logic)
|
|
|
|
<div dir="rtl" align="right">
|
|
يتم التحكم في حالة اتصال السائق بالشبكة وتفعيل استقبال الطلبات في ملف التحكم
|
|
</div>
|
|
|
|
[HomeCaptainController](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/home_captain_controller.dart)
|
|
|
|
<div dir="rtl" align="right">
|
|
من خلال الدالة
|
|
</div>
|
|
|
|
[onButtonSelected](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/home_captain_controller.dart#L278)
|
|
|
|
<div dir="rtl" align="right">
|
|
والتي تقوم بإجراء الفحوصات المتتالية التالية قبل السماح للسائق بالدخول في حالة النشاط (`isActive = true`):
|
|
</div>
|
|
|
|
### أ. فحص عقوبة إلغاء الرحلات (Cancellation Penalty Check)
|
|
<div dir="rtl" align="right">
|
|
تتحقق الدالة
|
|
</div>
|
|
|
|
[checkAndShowBlockDialog](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/home_captain_controller.dart#L347)
|
|
|
|
<div dir="rtl" align="right">
|
|
من وجود تاريخ حظر نشط مخزن في الذاكرة المحلية تحت المفتاح `blockUntilDate`. إذا كان الوقت الحالي قبل وقت انتهاء الحظر، يتم إجبار السائق على وضع عدم الاتصال وعرض نافذة حوار مانعة تعرض عداداً تنازلياً لوقت فك الحظر. تفرض هذه العقوبة تلقائياً لمدة 4 ساعات عند إلغاء السائق لـ 3 رحلات في اليوم الواحد.
|
|
</div>
|
|
|
|
### ب. فحص حد الإرهاق اليومي (Fatigue Monitoring Check)
|
|
<div dir="rtl" align="right">
|
|
يقوم النظام بمراقبة ساعات القيادة المتواصلة للسائق لمنع الحوادث عبر الدالة
|
|
</div>
|
|
|
|
[_checkFatigueBeforeOnline](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/home_captain_controller.dart#L222)
|
|
|
|
<div dir="rtl" align="right">
|
|
إذا بلغ مجموع ثواني النشاط المخزنة في `fatigue_total_seconds` ما يعادل 12 ساعة عمل، يتم استدعاء الدالة
|
|
</div>
|
|
|
|
[_forceOfflineDueToFatigue](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/home_captain_controller.dart#L242)
|
|
|
|
<div dir="rtl" align="right">
|
|
والتي تقطع الاتصال فوراً وتمنع السائق من العمل. لا يتم تصفير هذا العداد إلا إذا بقي السائق في وضع عدم الاتصال بشكل مستمر لمدة لا تقل عن 6 ساعات متواصلة (يتم تتبعها عبر قراءة تاريخ `fatigue_last_offline`).
|
|
</div>
|
|
|
|
### ج. فحص الحد الأدنى لنقاط المحفظة (Wallet Points Threshold)
|
|
<div dir="rtl" align="right">
|
|
يتم استدعاء خاصية
|
|
</div>
|
|
|
|
[minPointsThreshold](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/home_captain_controller.dart#L267)
|
|
|
|
<div dir="rtl" align="right">
|
|
والتي تعتمد على الدولة الحالية المخزنة في إعدادات التطبيق. إذا كان الرصيد الحالي للنقاط أدنى من الحد المسموح به (والذي يساوي `-200` نقطة في سوريا ومصر، و `-3` نقاط في الأردن)، يتم منع السائق من استقبال الطلبات وإيقاف تحديثات الموقع فوراً.
|
|
</div>
|
|
|
|
---
|
|
|
|
## 2. نظام التتبع وتحسين استهلاك البطارية والمعالج (GPS & Performance Optimization)
|
|
|
|
<div dir="rtl" align="right">
|
|
لمعالجة مشاكل استنزاف البطارية وارتفاع حرارة الأجهزة الضعيفة، تم تطبيق استراتيجيات تحسين الأداء التالية في
|
|
</div>
|
|
|
|
[MapDriverController](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart)
|
|
|
|
<div dir="rtl" align="right">
|
|
و
|
|
</div>
|
|
|
|
[HomeCaptainController](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/home_captain_controller.dart)
|
|
|
|
### أ. تجميع قنوات البث ومستمع الحركة الموحد (Centralized GPS Stream & 500ms Timer Polling)
|
|
<div dir="rtl" align="right">
|
|
بدلاً من فتح قنوات بث (Streams) متعددة ومستقلة للـ GPS، تم تركيز البث في كلاس مركزي موحد هو
|
|
</div>
|
|
|
|
[LocationController](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/functions/location_controller.dart)
|
|
|
|
<div dir="rtl" align="right">
|
|
حيث يقوم مستمع التوجيه والملاحة في الدالة
|
|
</div>
|
|
|
|
[startListeningStepNavigation](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart#L306)
|
|
|
|
<div dir="rtl" align="right">
|
|
بعمل استعلام دوري خفيف (Polling) كل 500 ملي ثانية لقراءة إحداثيات `locationController.myLocation` الجاهزة مسبقاً، مما يمنع استدعاء العتاد المادي لجهاز الاستقبال عدة مرات متزامنة.
|
|
</div>
|
|
|
|
### ب. فلترة ضجيج الإحداثيات (Jitter Noise Filtering)
|
|
<div dir="rtl" align="right">
|
|
لمنع التحديثات المتكررة وغير المفيدة التي تنتج عن عدم دقة حساس الـ GPS عند الوقوف، يقوم الكود بمقارنة إحداثيات الموقع الجديد مع آخر موقع تم تسجيله عبر الدالة
|
|
</div>
|
|
|
|
`Geolocator.distanceBetween`
|
|
|
|
<div dir="rtl" align="right">
|
|
فإذا كانت المسافة المقطوعة أقل من 3 أمتار، يتم تجاهل التحديث بالكامل وعدم تعديل المسار أو إرسال بيانات للسيرفر.
|
|
</div>
|
|
|
|
### ج. التحكم الذكي في حركة الكاميرا والـ UI Throttling
|
|
<div dir="rtl" align="right">
|
|
يتم التحكم في حركة الكاميرا لمتابعة حركة السائق على الخريطة الرئيسية عبر مؤقت دوري يعمل كل 8 ثوانٍ:
|
|
</div>
|
|
|
|
```dart
|
|
_cameraFollowTimer = Timer.periodic(const Duration(seconds: 8), (timer) { ... });
|
|
```
|
|
<div dir="rtl" align="right">
|
|
وتشترط الدالة تحرك السائق لمسافة تزيد عن 15 متراً عن آخر موقع تحركت إليه الكاميرا لتنفيذ الحركة الدائرية والتقريب، مما يقلل بشكل كبير من استهلاك معالج الرسوميات (GPU) في عمليات إعادة رسم الخريطة (Re-rendering) أثناء الوقوف. كذلك، تم تفعيل وسيلة
|
|
</div>
|
|
|
|
`_uiThrottleMs = 400`
|
|
|
|
<div dir="rtl" align="right">
|
|
لكبح تكرار استدعاء الدالة `update()` المسؤولة عن تحديث الواجهات.
|
|
</div>
|
|
|
|
---
|
|
|
|
## 3. استقبال وإدارة الطلبات ونافذة الواجهة العائمة (Order Requests & Overlay System)
|
|
|
|
<div dir="rtl" align="right">
|
|
يتم استقبال إشعارات الرحلات الجديدة إما عبر سوكيت الويب (WebSockets) أو إشعارات Firebase (FCM). عند وصول إشعار والبرنامج في الخلفية، يتم تفعيل شاشة الواجهة العائمة المفتوحة عبر حزمة
|
|
</div>
|
|
|
|
`FlutterOverlayWindow`
|
|
|
|
<div dir="rtl" align="right">
|
|
والتي تظهر للسائق تفاصيل الطلب بشكل مباشر.
|
|
</div>
|
|
|
|
### أ. تهيئة البيانات ودعم الصيغ المتعددة (Smart Data Handling)
|
|
<div dir="rtl" align="right">
|
|
يقوم الكلاس
|
|
</div>
|
|
|
|
[OrderRequestController](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/order_request_controller.dart)
|
|
|
|
<div dir="rtl" align="right">
|
|
بتحليل البيانات المستقبلة في الدالة
|
|
</div>
|
|
|
|
[_initializeData](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/order_request_controller.dart#L126)
|
|
|
|
<div dir="rtl" align="right">
|
|
حيث تدعم بشكل مرن استقبال البيانات سواء كانت على شكل قائمة مرتبة (List) قادمة من إشعارات Firebase، أو على شكل خريطة مفاتيح (Map) قادمة من سوكيت الويب.
|
|
</div>
|
|
|
|
### ب. مؤقت قبول الطلب وصوت التنبيه
|
|
<div dir="rtl" align="right">
|
|
عند فتح شاشة الطلب، يتم تشغيل صوت تنبيه متكرر وتفعيل مؤقت تنازلي مدته 15 ثانية عبر الدالة
|
|
</div>
|
|
|
|
[startTimer](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/order_request_controller.dart#L555)
|
|
|
|
<div dir="rtl" align="right">
|
|
إذا انتهت الـ 15 ثانية دون استجابة السائق، يتم إيقاف الصوت وإغلاق الشاشة تلقائياً.
|
|
</div>
|
|
|
|
### ج. فحص القبول المسبق للطلب (Socket ride_taken Listening)
|
|
<div dir="rtl" align="right">
|
|
لتفادي قبول طلب تم أخذه بالفعل من قبل كابتن آخر، يقوم الكنترولر في الدالة
|
|
</div>
|
|
|
|
[_listenForRideTaken](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/order_request_controller.dart#L587)
|
|
|
|
<div dir="rtl" align="right">
|
|
بالاستماع لحدث السوكيت `ride_taken`. عند استقبال الحدث ومطابقة معرف الرحلة، يتم إلغاء إشعار النظام فوراً، وإغلاق شاشة الطلب وعرض تنبيه للسائق بأن "الطلب تم قبوله من قبل سائق آخر".
|
|
</div>
|
|
|
|
---
|
|
|
|
## 4. نظام الملاحة التفاعلي ورسم المسارات (Interactive Navigation & Mapping)
|
|
|
|
<div dir="rtl" align="right">
|
|
يعتمد تطبيق السائق على خرائط انطلق المبنية على محرك مابليبرا (MapLibre)، ويتم استدعاء مسار الملاحة من سيرفر SaaS عبر الدالة
|
|
</div>
|
|
|
|
[getRoute](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart#L1885)
|
|
|
|
### أ. تفادي انهيار الخرائط عند المسافات الصفرية (Same-Device Crash Protection)
|
|
<div dir="rtl" align="right">
|
|
عند تشغيل اختبارات الرحلة وكون موقع السائق والراكب متطابقين تماماً (مسافة أقل من 10 أمتار)، ينهار محرك الملاحة المكتوب بلغة C++ بسبب إحداثيات الصندوق المحيط (Bounds) ذات العرض الصفرى مطلقةً استثناء `std::domain_error`. لمنع ذلك، يقوم الكود بفحص المسافة، وفي حال كانت متطابقة يقوم بإظهار نافذة تنبيه
|
|
</div>
|
|
|
|
[_showSameDeviceWarning](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart#L2171)
|
|
|
|
<div dir="rtl" align="right">
|
|
ثم الانتقال قسرياً لتطبيق زوم تقريبي آمن بدلاً من احتواء الحدود الصفرية.
|
|
</div>
|
|
|
|
### ب. تحديث المسار المقطوع بنظام النافذة المنزلقة (Bidirectional Sliding Window)
|
|
<div dir="rtl" align="right">
|
|
لمنع إعادة رسم كامل خط المسار (Polyline) عند كل إرسال للموقع، يتم استخدام نافذة بحث منزلقة ثنائية الاتجاه تتكون من 60 نقطة (30 للخلف و 30 للأمام) في الدالة
|
|
</div>
|
|
|
|
[_updateTraveledPolylineSmart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart#L2743)
|
|
|
|
<div dir="rtl" align="right">
|
|
تحدد الدالة أقرب نقطة لموقع السائق الحالي على المسار المخزن، وتقوم بقطع الـ Polyline إلى جزأين: مسار مقطوع بلون رمادي ومسار متبقي بلون أزرق/أصفر، وتحديث الخريطة فقط عند تجاوز إزاحة تزيد عن 50 متراً.
|
|
</div>
|
|
|
|
### ج. رسم خطوط المشي المنقطة (Passenger Walk Dotted Line)
|
|
<div dir="rtl" align="right">
|
|
عندما يكون موقع الراكب الفعلي بعيداً عن أقرب طريق إسفلتي متاح للسيارات، يتم استدعاء الدالة
|
|
</div>
|
|
|
|
[_updatePassengerWalkLine](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart#L2857)
|
|
|
|
<div dir="rtl" align="right">
|
|
والتي تقوم برسم خط منقط بلون أزرق رمادي مميز يمتد من نهاية طريق السيارات الإسفلتي إلى موقع الراكب الحقيقي لتوجيه السائق سيراً على الأقدام إذا لزم الأمر.
|
|
</div>
|
|
|
|
---
|
|
|
|
## 5. محرك تسعير الرحلة الديناميكي (Dynamic Pricing Engine)
|
|
|
|
<div dir="rtl" align="right">
|
|
أثناء سير الرحلة، يعمل مؤقت دوري كل ثانية لحساب السعر الفعلي بشكل لحظي وعرضه في واجهة السائق عبر الدالة
|
|
</div>
|
|
|
|
[rideIsBeginPassengerTimer](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart#L1570)
|
|
|
|
<div dir="rtl" align="right">
|
|
ويعتمد الحساب على القواعد البرمجية التالية:
|
|
</div>
|
|
|
|
### أ. تجميد الأسعار للرحلات الثابتة (Fixed Price Protection)
|
|
<div dir="rtl" align="right">
|
|
إذا كان نوع الرحلة من الفئات ذات السعر الثابت مثل `Speed` أو `Fixed Price` أو `Awfar Car`، يتم إيقاف الحساب الديناميكي وتثبيت السعر المعروض على القيمة المتفق عليها مسبقاً في عرض السعر الأولي للراكب.
|
|
</div>
|
|
|
|
### ب. تسعير الفئات المتغيرة (Comfort / Electric / Van / Delivery)
|
|
<div dir="rtl" align="right">
|
|
للفئات المتغيرة، يتم حساب السعر التراكمي عبر دمج المسافة الفعلية المقطوعة مع وقت الرحلة الفعلي طبقاً للمعادلة:
|
|
</div>
|
|
|
|
```
|
|
Price = (Distance_KM * Per_KM_Rate) + (Duration_Minutes * Per_Minute_Rate)
|
|
```
|
|
<div dir="rtl" align="right">
|
|
حيث يتم تطبيق تسعيرة الدقيقة بناءً على ساعة الرحلة الحالية لمراعاة أوقات الذروة (طبيعي، متأخر، أو حركة مرورية كثيفة)، بالإضافة إلى ضرب الناتج في عمولة السيرفر (كازان) المحددة بنسبة مئوية.
|
|
</div>
|
|
|
|
### ج. تخفيضات المسافات الطويلة (Long Distance Reduction Rules)
|
|
<div dir="rtl" align="right">
|
|
إذا تجاوزت المسافة المقطوعة 35 كم أو 40 كم، يطبق محرك التسعير قواعد خاصة:
|
|
- يتم تجميد تسعيرة الدقيقة وتثبيتها على قيمة ثابتة للرحلات الطويلة تعادل 600 ل.س/دقيقة.
|
|
- يتم تطبيق نسبة خصم ديناميكية (تصل إلى 35%) على تسعيرة الكيلومتر لتخفيض الأعباء على الراكب مع الحفاظ على ربحية السائق.
|
|
- يضمن الكود دائماً عدم نزول السعر الفعلي النهائي عن السعر المتفق عليه مسبقاً (Quoted Price).
|
|
</div>
|
|
|
|
---
|
|
|
|
## 6. حماية الرحلة من الإنهاء المبكر الخاطئ (Anti-Fraud & Exit Validation)
|
|
|
|
<div dir="rtl" align="right">
|
|
عندما يسحب السائق شريط إنهاء الرحلة، يمر الطلب بفحص أمني دقيق للتأكد من عدم وجود تلاعب أو إنهاء وهمي للرحلة.
|
|
</div>
|
|
|
|
### أ. شرط الإزاحة الأمنية (Displacement Validation Check)
|
|
<div dir="rtl" align="right">
|
|
يتم استدعاء الدالة
|
|
</div>
|
|
|
|
[_validateTripDistance](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart#L1458)
|
|
|
|
<div dir="rtl" align="right">
|
|
والتي تقوم بحساب المسافة المستقيمة الفاصلة بين موقع انطلاق الرحلة (موقع الراكب الأصلي) والموقع الجغرافي الحالي للسائق. يشترط النظام أن تتجاوز هذه المسافة قيمة **خُمس المسافة الإجمالية المخططة للرحلة** (`plannedDistance / 5`).
|
|
</div>
|
|
|
|
### ب. التنبيه الصوتي المانع والتراجع (TTS Rejection Alert)
|
|
<div dir="rtl" align="right">
|
|
إذا حاول السائق إنهاء الرحلة قبل قطع حد الخُمس المسموح، يتم رفض الطلب فوراً وإغلاق أي نوافذ تحميل، وتفعيل قارئ النصوص الصوتي لإصدار تنبيه صوتي باللغة الإنجليزية عبر الهاتف:
|
|
</div>
|
|
|
|
> "You haven't moved sufficiently!"
|
|
|
|
<div dir="rtl" align="right">
|
|
مع إظهار رسالة خطأ تحذيرية في الواجهة وإعادة زر إنهاء الرحلة لوضعه النشط للسماح بإكمال الرحلة.
|
|
</div>
|
|
|
|
### ج. إتمام المعاملة المالية الموازية (Parallel Transaction Completion)
|
|
<div dir="rtl" align="right">
|
|
عند اجتياز فحص المسافة بنجاح، يتم تفعيل دالة الإنهاء الفعلي
|
|
</div>
|
|
|
|
[finishRideFromDriver1](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart#L1363)
|
|
|
|
<div dir="rtl" align="right">
|
|
والتي تقوم بإرسال طلبات التحديث المالي وإغلاق الرحلة في آن واحد إلى سيرفر العمليات وسيرفر المحفظة المالي بالتوازي عبر استدعاء
|
|
</div>
|
|
|
|
`Future.wait([...])`
|
|
|
|
<div dir="rtl" align="right">
|
|
مما يقلل وقت المعاملة على أجهزة السائقين ويمنع تعليق التطبيق. بعد نجاح المعاملات، يتم توجيه السائق تلقائياً إلى صفحة تقييم الراكب وإرسال تقرير السلوك الفني.
|
|
</div>
|