package db import ( "encoding/json" "fmt" "gestion/models" "time" ) // GetDeliverymanQueueInfo récupère les infos de queue d'un livreur func (d *Database) GetDeliverymanQueueInfo(deliveryman string) (map[string]any, error) { queueKey := fmt.Sprintf("queue:deliveryman:%s", deliveryman) queueSize, _ := Redis.ZCard(RedisCtx, queueKey).Result() commandIDs, _ := Redis.ZRange(RedisCtx, queueKey, 0, -1).Result() activeCount, _ := d.CountActiveDeliverymen() var commands []map[string]any for i, cmdIDStr := range commandIDs { commandID := extractCommandID(cmdIDStr) if commandID <= 0 { continue } commandKey := fmt.Sprintf("queue:pending:%d", commandID) data, err := Redis.Get(RedisCtx, commandKey).Result() if err != nil { continue } var queueItem models.CommandQueue if err := json.Unmarshal([]byte(data), &queueItem); err != nil { continue } commands = append(commands, map[string]any{ "position": i + 1, "command_id": commandID, "address": queueItem.Address, "estimated_eta": queueItem.EstimatedETA, "created_at": queueItem.CreatedAt, "lat": queueItem.Lat, "lng": queueItem.Lng, }) } canAcceptMore := true if activeCount > 1 { canAcceptMore = queueSize < MAX_COMMANDS_PER_DELIVERYMAN } return map[string]any{ "deliveryman": deliveryman, "queue_size": queueSize, "commands": commands, "can_accept_more": canAcceptMore, "max_commands": MAX_COMMANDS_PER_DELIVERYMAN, "active_deliverymen": activeCount, }, nil } func (d *Database) GetAllQueuesOverview() (map[string]any, error) { overview := make(map[string]any) generalQueueSize, _ := Redis.ZCard(RedisCtx, "queue:pending:sorted").Result() overview["general_queue"] = generalQueueSize deliverymanQueues := make(map[string]any) keys, _ := scanRedisKeys("queue:deliveryman:*") var totalPending int64 = generalQueueSize for _, key := range keys { if len(key) > 6 && key[len(key)-6:] == ":count" { continue } username := key[len("queue:deliveryman:"):] queueSize, _ := Redis.ZCard(RedisCtx, key).Result() deliverymanQueues[username] = map[string]any{ "queue_size": queueSize, "can_accept_more": queueSize < MAX_COMMANDS_PER_DELIVERYMAN, "capacity": fmt.Sprintf("%d/%d", queueSize, MAX_COMMANDS_PER_DELIVERYMAN), } totalPending += queueSize } overview["total_pending"] = totalPending return overview, nil } // GetQueueStats - Statistiques détaillées func (d *Database) GetQueueStats() (map[string]any, error) { normalCount, _ := Redis.ZCard(RedisCtx, "queue:pending:sorted").Result() priorityCount, _ := Redis.ZCard(RedisCtx, "queue:priority:sorted").Result() var deliverymanQueueCount int64 keys, _ := scanRedisKeys("queue:deliveryman:*") for _, key := range keys { if len(key) > 6 && key[len(key)-6:] == ":count" { continue } count, _ := Redis.ZCard(RedisCtx, key).Result() deliverymanQueueCount += count } var totalWaitTime int64 var commandCount int64 // Limité aux 100 premières entrées pour ne pas bloquer Redis sur une grande queue normalResults, _ := Redis.ZRangeWithScores(RedisCtx, "queue:pending:sorted", 0, 99).Result() for _, result := range normalResults { commandID := extractCommandID(result.Member) if commandID <= 0 { continue } key := fmt.Sprintf("queue:pending:%d", commandID) data, _ := Redis.Get(RedisCtx, key).Result() var item models.CommandQueue if json.Unmarshal([]byte(data), &item) == nil { waitMinutes := int64(time.Since(item.CreatedAt).Minutes()) totalWaitTime += waitMinutes commandCount++ } } avgWaitTime := 0 if commandCount > 0 { avgWaitTime = int(totalWaitTime / commandCount) } stats := map[string]any{ "total_pending": normalCount + priorityCount, "general_queue": normalCount, "priority_queue": priorityCount, "deliveryman_queues": deliverymanQueueCount, "avg_wait_time_min": avgWaitTime, "max_commands_per_driver": MAX_COMMANDS_PER_DELIVERYMAN, "avg_delivery_time": AVG_DELIVERY_TIME, "last_updated": time.Now().Format("2006-01-02 15:04:05"), } return stats, nil }