Files
tripz-llc/dashboards/admin/lib/controller/server/server_monitor_controller.dart
T
Hamza-AyedandClaude Opus 5 4d8414c96b 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>
2026-07-27 05:14:13 +03:00

150 lines
4.0 KiB
Dart

import 'dart:async';
import 'package:get/get.dart';
import 'package:siro_admin/constant/links.dart';
// --- Models ---
class ServerData {
final CpuInfo cpu;
final MemoryInfo memory;
final DiskInfo disk;
final Map<String, String> services;
final List<ProcessInfo> topProcesses;
final NetworkInfo network;
final UptimeInfo uptime;
final String timestamp;
ServerData({
required this.cpu,
required this.memory,
required this.disk,
required this.services,
required this.topProcesses,
required this.network,
required this.uptime,
required this.timestamp,
});
factory ServerData.fromJson(Map<String, dynamic> json) {
return ServerData(
cpu: CpuInfo.fromJson(json['cpu']),
memory: MemoryInfo.fromJson(json['memory']),
disk: DiskInfo.fromJson(json['disk']),
services: Map<String, String>.from(json['services']),
topProcesses: (json['top_processes'] as List)
.map((i) => ProcessInfo.fromJson(i))
.toList(),
network: NetworkInfo.fromJson(json['network']),
uptime: UptimeInfo.fromJson(json['uptime']),
timestamp: json['timestamp'],
);
}
}
class CpuInfo {
final double percent;
final int cores;
final double load1m;
CpuInfo({required this.percent, required this.cores, required this.load1m});
factory CpuInfo.fromJson(Map<String, dynamic> json) => CpuInfo(
percent: json['percent'].toDouble(),
cores: json['cores'],
load1m: json['load_1m'].toDouble());
}
class MemoryInfo {
final double percent;
final double usedGb;
final double totalGb;
MemoryInfo(
{required this.percent, required this.usedGb, required this.totalGb});
factory MemoryInfo.fromJson(Map<String, dynamic> json) => MemoryInfo(
percent: json['percent'].toDouble(),
usedGb: json['used_gb'].toDouble(),
totalGb: json['total_gb'].toDouble());
}
class DiskInfo {
final double percent;
final double usedGb;
final double totalGb;
DiskInfo(
{required this.percent, required this.usedGb, required this.totalGb});
factory DiskInfo.fromJson(Map<String, dynamic> json) => DiskInfo(
percent: json['percent'].toDouble(),
usedGb: json['used_gb'].toDouble(),
totalGb: json['total_gb'].toDouble());
}
class ProcessInfo {
final String name;
final String usage;
ProcessInfo({required this.name, required this.usage});
factory ProcessInfo.fromJson(Map<String, dynamic> json) =>
ProcessInfo(name: json['name'], usage: json['usage']);
}
class NetworkInfo {
final double receivedMb;
final double sentMb;
NetworkInfo({required this.receivedMb, required this.sentMb});
factory NetworkInfo.fromJson(Map<String, dynamic> json) => NetworkInfo(
receivedMb: json['received_mb'].toDouble(),
sentMb: json['sent_mb'].toDouble());
}
class UptimeInfo {
final String formatted;
UptimeInfo({required this.formatted});
factory UptimeInfo.fromJson(Map<String, dynamic> json) =>
UptimeInfo(formatted: json['formatted']);
}
// --- Controller ---
class ServerMonitorController extends GetxController {
var isLoading = false.obs;
var serverData = Rxn<ServerData>();
var errorMessage = ''.obs;
Timer? _timer; // تخزين التايمر
@override
void onInit() {
super.onInit();
fetchServerData();
// تحديث تلقائي كل 60 ثانية
_timer = Timer.periodic(Duration(seconds: 60), (_) {
fetchServerData();
});
}
@override
void onClose() {
// إلغاء التحديث عند إغلاق الصفحة
_timer?.cancel();
super.onClose();
}
Future<void> fetchServerData() async {
try {
isLoading(true);
errorMessage('');
final response = await GetConnect().get(AppLink.serverMonitor);
if (response.status.hasError) {
errorMessage.value = 'خطأ في الاتصال: ${response.statusText}';
} else {
serverData.value = ServerData.fromJson(response.body);
}
} catch (e) {
errorMessage.value = 'حدث خطأ: $e';
} finally {
isLoading(false);
}
}
}