chore: update
This commit is contained in:
@@ -184,16 +184,21 @@ func tryAssignCommandWithPriority(
|
||||
|
||||
// 8. Notifier le livreur de la nouvelle commande
|
||||
notifMsg := fmt.Sprintf("Nouvelle commande #%d assignée - Livraison dans ~%d min (%.2f km)", commandID, travelTime, distance)
|
||||
var clientUsername string
|
||||
if cmd, err := database.GetCommandByID(commandID); err == nil {
|
||||
if ru, ok := cmd["referral_used"].(float64); ok && ru > 0 {
|
||||
notifMsg += fmt.Sprintf(" | Parrainage client: -%.2f€", ru)
|
||||
}
|
||||
clientUsername, _ = cmd["username"].(string)
|
||||
}
|
||||
if notifErr := database.NotifyLivreur(nearest.Username, commandID, "new_assignment", notifMsg); notifErr != nil {
|
||||
log.Printf("⚠️ [CRON] Erreur notification livreur %s: %v", nearest.Username, notifErr)
|
||||
}
|
||||
|
||||
// 9. Notifier le client
|
||||
if cmd, err := database.GetCommandByID(commandID); err == nil {
|
||||
if clientUsername, ok := cmd["username"].(string); ok && clientUsername != "" {
|
||||
clientMsg := fmt.Sprintf("Votre commande #%d est confirmée ! Livraison prévue dans ~%d min", commandID, travelTime)
|
||||
database.NotifyClient(clientUsername, commandID, "assigned", clientMsg)
|
||||
}
|
||||
if clientUsername != "" {
|
||||
clientMsg := fmt.Sprintf("Votre commande #%d est confirmée ! Un livreur est en route.", commandID)
|
||||
database.NotifyClient(clientUsername, commandID, "assigned", clientMsg)
|
||||
}
|
||||
|
||||
log.Printf("✅ [CRON] Cmd %d → %s (%.2f km) | Priorité #%d | Attente: %d min",
|
||||
|
||||
@@ -5,30 +5,20 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"gestion/db"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ============================================
|
||||
// WORKER PRINCIPAL
|
||||
// ============================================
|
||||
|
||||
// StartRedisWorkers démarre tous les workers Redis
|
||||
func StartRedisWorkers(database *db.Database) {
|
||||
log.Println("🚀 Démarrage des workers Redis...")
|
||||
|
||||
// Worker pour les notifications programmées
|
||||
go NotificationWorker(database)
|
||||
|
||||
// Worker pour l'auto-assignation des commandes
|
||||
go AutoAssignWorker(database)
|
||||
|
||||
// Worker pour le nettoyage des réservations expirées
|
||||
go StockCleanupWorker(database)
|
||||
|
||||
// Worker pour la synchronisation des points
|
||||
go PointsSyncWorker(database)
|
||||
|
||||
log.Println("✅ Tous les workers Redis sont démarrés")
|
||||
@@ -174,142 +164,3 @@ func PointsSyncWorker(database *db.Database) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// WORKER MISE À JOUR ETA
|
||||
// ============================================
|
||||
|
||||
// ETAUpdateWorker met à jour automatiquement les ETAs
|
||||
func ETAUpdateWorker(database *db.Database) {
|
||||
ticker := time.NewTicker(2 * time.Minute)
|
||||
defer ticker.Stop()
|
||||
|
||||
log.Println("⏱️ Worker Mise à Jour ETA démarré (check toutes les 2 min)")
|
||||
|
||||
for range ticker.C {
|
||||
// Récupérer toutes les commandes en cours de livraison
|
||||
commands, err := database.GetAllCommands("support", "")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, command := range commands {
|
||||
commandID := command["id"].(int)
|
||||
|
||||
// Recalculer l'ETA basé sur la position du livreur
|
||||
// (logique à implémenter selon vos besoins)
|
||||
|
||||
// Exemple: réduire l'ETA de 2 minutes
|
||||
// database.SetCommandETA(commandID, newETA)
|
||||
|
||||
log.Printf("🔄 ETA mis à jour pour commande %d", commandID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// WORKER ALERTES RETARD
|
||||
// ============================================
|
||||
|
||||
// DelayAlertWorker envoie des alertes en cas de retard
|
||||
func DelayAlertWorker(database *db.Database) {
|
||||
ticker := time.NewTicker(3 * time.Minute)
|
||||
defer ticker.Stop()
|
||||
|
||||
log.Println("⚠️ Worker Alertes Retard démarré (check toutes les 3 min)")
|
||||
|
||||
for range ticker.C {
|
||||
// Récupérer les ETAs de toutes les commandes
|
||||
keys, err := db.Redis.Keys(db.RedisCtx, "command:eta:*").Result()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
data, err := db.Redis.Get(db.RedisCtx, key).Result()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Désérialiser le JSON dans eta
|
||||
var eta map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(data), &eta); err != nil {
|
||||
log.Printf("⚠️ Impossible de parser ETA pour %s: %v", key, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Extraire l'heure d'arrivée
|
||||
arrivalTimeFloat, ok := eta["arrival_time"].(float64)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
arrivalTime := int64(arrivalTimeFloat)
|
||||
|
||||
// Vérifier retard
|
||||
now := time.Now().Unix()
|
||||
if now > arrivalTime {
|
||||
commandIDFloat, ok := eta["command_id"].(float64)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
commandID := int(commandIDFloat)
|
||||
delay := (now - arrivalTime) / 60 // en minutes
|
||||
|
||||
log.Printf("⚠️ ALERTE: Commande %d en retard de %d minutes", commandID, delay)
|
||||
|
||||
// Notifier l'admin
|
||||
database.PublishCommandEvent(commandID, "delay_alert", "Commande en retard")
|
||||
|
||||
if delay > 15 {
|
||||
command, _ := database.GetCommandByID(commandID)
|
||||
if livreur, ok := command["livreur_assign"].(string); ok {
|
||||
log.Printf("⚠️ Pénalité appliquée au livreur %s", livreur)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// WORKER STATISTIQUES TEMPS RÉEL
|
||||
// ============================================
|
||||
|
||||
// StatsWorker calcule des statistiques en temps réel
|
||||
func StatsWorker(database *db.Database) {
|
||||
ticker := time.NewTicker(5 * time.Minute)
|
||||
defer ticker.Stop()
|
||||
|
||||
log.Println("📊 Worker Statistiques démarré (check toutes les 5 min)")
|
||||
|
||||
for range ticker.C {
|
||||
// Nombre de commandes en attente
|
||||
queueSize, _ := db.Redis.ZCard(db.RedisCtx, "queue:pending:sorted").Result()
|
||||
|
||||
// Nombre de livreurs disponibles
|
||||
livreurs, _ := database.GetAvailableDeliveryPersonsRedis()
|
||||
availableCount := len(livreurs)
|
||||
|
||||
// Nombre de livraisons en cours
|
||||
commands, _ := database.GetAllCommands("support", "")
|
||||
inProgressCount := len(commands)
|
||||
|
||||
stats := map[string]interface{}{
|
||||
"queue_size": queueSize,
|
||||
"available_drivers": availableCount,
|
||||
"in_progress": inProgressCount,
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
|
||||
// Stocker dans Redis
|
||||
db.Redis.HSet(db.RedisCtx, "stats:realtime",
|
||||
"queue_size", stats["queue_size"],
|
||||
"available_drivers", stats["available_drivers"],
|
||||
"in_progress", stats["in_progress"],
|
||||
"timestamp", stats["timestamp"],
|
||||
)
|
||||
|
||||
log.Printf("📊 Stats: %d en attente | %d livreurs dispo | %d en cours",
|
||||
queueSize, availableCount, inProgressCount)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user