chore: update

This commit is contained in:
2026-03-11 19:57:34 +01:00
parent f6b3948839
commit 375aa38454
62 changed files with 2714 additions and 1981 deletions
+10 -5
View File
@@ -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",
-149
View File
@@ -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)
}
}