Update: 2026-08-03 13:10:56
This commit is contained in:
@@ -59,7 +59,13 @@ SELECT
|
|||||||
(SELECT COUNT(*) FROM ride WHERE carType = 'Lady') AS lady,
|
(SELECT COUNT(*) FROM ride WHERE carType = 'Lady') AS lady,
|
||||||
|
|
||||||
-- حالة الرحلات (تغطي عائلتي الحالات: القديمة CamelCase والجديدة lowercase)
|
-- حالة الرحلات (تغطي عائلتي الحالات: القديمة CamelCase والجديدة lowercase)
|
||||||
(SELECT COUNT(*) FROM ride WHERE LOWER(status) IN ('wait','waiting','new','nothing','pending','searching')) AS ongoing_rides,
|
-- الحالات الفعلية في قاعدة الإنتاج (فحص 2026-08-03): nothing 930،
|
||||||
|
-- Begin 624، start 170، waiting 2. كانت Begin و start خارج كل الدلاء
|
||||||
|
-- الثلاثة، أي أن 794 رحلة (46% من الإجمالي) لا تظهر في أي إحصائية.
|
||||||
|
-- 'جارية' تشمل المنتظرة للسائق والمنفَّذة فعلياً معاً.
|
||||||
|
(SELECT COUNT(*) FROM ride WHERE LOWER(status) IN
|
||||||
|
('wait','waiting','new','nothing','pending','searching',
|
||||||
|
'begin','start','arrived','apply')) AS ongoing_rides,
|
||||||
(SELECT COUNT(*) FROM ride WHERE LOWER(status) IN ('finished','completed')) AS completed_rides,
|
(SELECT COUNT(*) FROM ride WHERE LOWER(status) IN ('finished','completed')) AS completed_rides,
|
||||||
(SELECT COUNT(*) FROM ride WHERE LOWER(status) LIKE 'cancel%' OR LOWER(status) IN ('timeout','refused')) AS cancelled_rides,
|
(SELECT COUNT(*) FROM ride WHERE LOWER(status) LIKE 'cancel%' OR LOWER(status) IN ('timeout','refused')) AS cancelled_rides,
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,19 @@ class CaptainAdminController extends GetxController {
|
|||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
Map captainData = {};
|
Map captainData = {};
|
||||||
Map captain = {};
|
Map captain = {};
|
||||||
|
|
||||||
|
/// قائمة الكباتن مهما كان شكل الغلاف.
|
||||||
|
/// AdminCaptain/get.php يُرجع {"message":{"data":[...]}} بينما نقاط أخرى
|
||||||
|
/// تُرجع {"message":[...]} مباشرة. الاعتماد على شكل واحد كان يجعل
|
||||||
|
/// `captainData['message'].length` تقرأ عدد مفاتيح الخريطة (1) بدل عدد
|
||||||
|
/// الكباتن، و`[0]['id']` تنهار على null.
|
||||||
|
List<dynamic> get captains {
|
||||||
|
final m = captainData['message'];
|
||||||
|
if (m is List) return m;
|
||||||
|
if (m is Map && m['data'] is List) return m['data'] as List;
|
||||||
|
if (m is Map) return [m];
|
||||||
|
return const [];
|
||||||
|
}
|
||||||
final captainController = TextEditingController();
|
final captainController = TextEditingController();
|
||||||
final captainPrizeController = TextEditingController();
|
final captainPrizeController = TextEditingController();
|
||||||
final titleNotify = TextEditingController();
|
final titleNotify = TextEditingController();
|
||||||
@@ -70,16 +83,16 @@ class CaptainAdminController extends GetxController {
|
|||||||
Future addCaptainPrizeToWallet() async {
|
Future addCaptainPrizeToWallet() async {
|
||||||
String? paymentId;
|
String? paymentId;
|
||||||
//todo link to add wallet to captain
|
//todo link to add wallet to captain
|
||||||
for (var i = 0; i < captainData['message'].length; i++) {
|
for (var i = 0; i < captains.length; i++) {
|
||||||
await CRUD().post(link: AppLink.addDriverPaymentPoints, payload: {
|
await CRUD().post(link: AppLink.addDriverPaymentPoints, payload: {
|
||||||
'driverID': captainData['message'][i]['id'],
|
'driverID': captains[i]['id'],
|
||||||
'amount': captainPrizeController.text,
|
'amount': captainPrizeController.text,
|
||||||
'paymentMethod': 'Prize',
|
'paymentMethod': 'Prize',
|
||||||
}).then((value) {
|
}).then((value) {
|
||||||
paymentId = value['message'].toString();
|
paymentId = value['message'].toString();
|
||||||
});
|
});
|
||||||
await CRUD().post(link: AppLink.addPassengersWallet, payload: {
|
await CRUD().post(link: AppLink.addPassengersWallet, payload: {
|
||||||
'driverID': captainData['message'][i]['id'],
|
'driverID': captains[i]['id'],
|
||||||
'amount': captainPrizeController.text,
|
'amount': captainPrizeController.text,
|
||||||
'paymentMethod': 'Prize',
|
'paymentMethod': 'Prize',
|
||||||
'paymentID': paymentId.toString(),
|
'paymentID': paymentId.toString(),
|
||||||
|
|||||||
@@ -40,8 +40,22 @@ class CaptainsPage extends StatelessWidget {
|
|||||||
return _buildEmptyState(cs);
|
return _buildEmptyState(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<dynamic> captains =
|
// AdminCaptain/get.php يغلّف النتيجة مرّتين:
|
||||||
message is List ? message : [message];
|
// {"status":"success","message":{"data":[ ...الكباتن... ]}}
|
||||||
|
// الشرط السابق كان `message is List ? message : [message]`،
|
||||||
|
// فيلفّ الخريطة نفسها في قائمة من عنصر واحد. النتيجة بطاقة
|
||||||
|
// واحدة كل حقولها null — وهو سبب اختفاء الاسم والهاتف،
|
||||||
|
// لا خطأ في فك التشفير.
|
||||||
|
final List<dynamic> captains;
|
||||||
|
if (message is List) {
|
||||||
|
captains = message;
|
||||||
|
} else if (message is Map && message['data'] is List) {
|
||||||
|
captains = message['data'];
|
||||||
|
} else if (message is Map) {
|
||||||
|
captains = [message];
|
||||||
|
} else {
|
||||||
|
captains = const [];
|
||||||
|
}
|
||||||
|
|
||||||
if (captains.isEmpty) {
|
if (captains.isEmpty) {
|
||||||
return _buildEmptyState(cs);
|
return _buildEmptyState(cs);
|
||||||
|
|||||||
@@ -35,7 +35,12 @@ class _HeatmapPageState extends State<HeatmapPage> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_fetchHeatmapData();
|
// _fetchHeatmapData يقرأ Theme.of(context) لتلوين العلامات، وهذا ممنوع
|
||||||
|
// قبل اكتمال initState (يرمي dependOnInheritedWidgetOfExactType).
|
||||||
|
// التأجيل إلى ما بعد أول إطار يضمن جاهزية الشجرة.
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mounted) _fetchHeatmapData();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _fetchHeatmapData() async {
|
Future<void> _fetchHeatmapData() async {
|
||||||
|
|||||||
Reference in New Issue
Block a user