feat: استيراد كود سيرو إلى تريبز (سيرو @ecfe7568) — بلا تعديل
قرار المالك 2026-07-27: باك إند سيرو PHP هو المعتمد، وتطبيقاته المجرّبة ميدانياً تحل محل إعادة البناء المؤرشفة. سيرو نفسه لم يُمسّ. الخريطة: backend · payment_server · loction_server · ride_server · passenger_server · docker · dashboard · stress_test → الجذر siro_rider → apps/rider siro_driver → apps/driver siro_admin → dashboards/admin siro_service → dashboards/service android_bot → apps/android_bot socialBot → apps/socialBot نُسخ المتعقَّب في git سيرو فقط عبر `git archive` (3,198 ملفاً / ~169 م.ب) لا `cp -r` — فاستُثنيت مخلفات البناء تلقائياً. بلا أي تعديل محتوى عمداً: كل ما يلي يصير فرقاً مقروءاً مقابل المصدر. لم يُستورد وسببه: siromove.com (الموقع التسويقي يبقى marketing/ في تريبز، سيرو فيه 8 ملفات) · docs و planning (تريبز له docs/ الخاص) · deploy.sh (ليس نشراً على سيرفر بل `git add . && git push origin --all` — فخّ في مستودع آخر) · transit_dashboard (بانتظار قرار مصير backend-transit و dashboards/transit-web). ⚠️ لا يبني بعد — ثلاثة نواقص متوقعة ومقصودة: 1. `.env` و `lib/env/env.g.dart` غير متعقَّبين في سيرو (أسرار لكل مستأجر): كل تطبيق فلاتر يحتاج .env خاصاً ثم توليد env.g.dart بـ build_runner. 2. إعدادات Firebase (9 ملفات google-services.json و GoogleService-Info.plist) يستبعدها .gitignore تريبز — ولكل مستأجر مشروع Firebase خاص أصلاً. 3. apps/driver في سيرو يشير إلى `../../Intaleq/packages/get` خارج المستودع → يجب ضمّ الحزم داخله أسوة بـ apps/rider. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9909d9b4c1
commit
4d8414c96b
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
// getRealTimeHeatmap.php
|
||||
require_once __DIR__ . '/../../get_connect.php';
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
try {
|
||||
$precision = 2; // دقة الشبكة (تقريباً 1 كم)
|
||||
|
||||
// الأوزان
|
||||
$WEIGHT_WAITING = 5; // طلب انتظار = 5 نقاط
|
||||
$WEIGHT_MISSED = 8; // طلب ضائع = 8 نقاط (أهمية قصوى)
|
||||
$WEIGHT_ACTIVE = 1; // طلب نشط = 1 نقطة
|
||||
|
||||
$grid = [];
|
||||
|
||||
// 1. طلبات الانتظار (Waiting)
|
||||
$stmtW = $con->prepare("SELECT start_lat, start_lng FROM waitingRides WHERE status IN ('wait', 'waiting')");
|
||||
$stmtW->execute();
|
||||
while ($row = $stmtW->fetch(PDO::FETCH_ASSOC)) {
|
||||
addToGrid($grid, $row['start_lat'], $row['start_lng'], $precision, $WEIGHT_WAITING);
|
||||
}
|
||||
|
||||
// 2. طلبات ضائعة (Timeout)
|
||||
$stmtM = $con->prepare("SELECT start_location FROM ride WHERE (status = 'timeout' OR status = 'cancelled_no_driver_found') AND created_at >= DATE_SUB(NOW(), INTERVAL 20 MINUTE)");
|
||||
$stmtM->execute();
|
||||
while ($row = $stmtM->fetch(PDO::FETCH_ASSOC)) {
|
||||
$parts = explode(',', $row['start_location']);
|
||||
if (count($parts) == 2) addToGrid($grid, $parts[0], $parts[1], $precision, $WEIGHT_MISSED);
|
||||
}
|
||||
|
||||
// 3. طلبات نشطة (Active)
|
||||
$stmtA = $con->prepare("SELECT start_location FROM ride WHERE created_at >= DATE_SUB(NOW(), INTERVAL 15 MINUTE) AND status NOT IN ('timeout', 'cancelled_no_driver_found')");
|
||||
$stmtA->execute();
|
||||
while ($row = $stmtA->fetch(PDO::FETCH_ASSOC)) {
|
||||
$parts = explode(',', $row['start_location']);
|
||||
if (count($parts) == 2) addToGrid($grid, $parts[0], $parts[1], $precision, $WEIGHT_ACTIVE);
|
||||
}
|
||||
|
||||
// تجهيز البيانات النهائية
|
||||
$finalData = [];
|
||||
foreach ($grid as $cell) {
|
||||
$score = $cell['score']; // مجموع النقاط (الوزن)
|
||||
$count = $cell['count']; // العدد الحقيقي للطلبات
|
||||
|
||||
// 🧠 المنطق المزدوج: نحدد اللون بناءً على النقاط أو العدد
|
||||
$intensity = "low";
|
||||
$surge = 1.0;
|
||||
|
||||
// المعادلة: منطقة حمراء إذا كان السكور عالي جداً (مشاكل) أو العدد كبير جداً (زحمة)
|
||||
if ($score >= 15 || $count >= 5) {
|
||||
$intensity = "high"; // أحمر (خطر/فرصة ذهبية)
|
||||
$surge = 1.5;
|
||||
} elseif ($score >= 8 || $count >= 3) {
|
||||
$intensity = "medium"; // برتقالي
|
||||
$surge = 1.2;
|
||||
} elseif ($score >= 3 || $count >= 1) {
|
||||
$intensity = "normal"; // أصفر
|
||||
}
|
||||
|
||||
if ($score > 0) {
|
||||
$finalData[] = [
|
||||
'lat' => $cell['lat'],
|
||||
'lng' => $cell['lng'],
|
||||
'count' => $count, // ✅ العدد الحقيقي (مهم للعرض)
|
||||
'intensity' => $intensity, // ✅ التصنيف الذكي
|
||||
'surge' => $surge
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents('heatmap_live.json', json_encode($finalData)); // الكاش
|
||||
|
||||
echo json_encode(["status" => "success", "data" => $finalData]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("[getRealTimeHeatmap] Error: " . $e->getMessage());
|
||||
echo json_encode(["status" => "failure", "message" => "An internal error occurred."]);
|
||||
}
|
||||
|
||||
function addToGrid(&$grid, $lat, $lng, $precision, $weight) {
|
||||
if (empty($lat) || empty($lng)) return;
|
||||
$rLat = round(floatval($lat), $precision);
|
||||
$rLng = round(floatval($lng), $precision);
|
||||
$key = "$rLat,$rLng";
|
||||
|
||||
if (!isset($grid[$key])) {
|
||||
$grid[$key] = ['lat' => $rLat, 'lng' => $rLng, 'count' => 0, 'score' => 0];
|
||||
}
|
||||
$grid[$key]['count']++; // زيادة العدد (+1 دائماً)
|
||||
$grid[$key]['score'] += $weight; // زيادة الوزن (حسب نوع الطلب)
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user