using Microsoft.AspNetCore.SignalR; using RobotNet.Script.Shares.Dashboard; using RobotNet.ScriptManager.Data; using RobotNet.ScriptManager.Hubs; using System; using static System.Runtime.InteropServices.JavaScript.JSType; namespace RobotNet.ScriptManager.Services; public class DashboardPublisher(DashboardConfig Config, IServiceProvider ServiceProvider, IConfiguration Configuration, IHubContext DashboardHub, ILogger Logger) : BackgroundService { private readonly int UpdateTime = Configuration.GetValue("Dashboard:UpdateTimeMilliSeconds", 5000); private readonly int CycleDate = Configuration.GetValue("Dashboard:CycleDate", 7); private static TaktTimeMissionDto GetTaktTime(InstanceMission[] missions, DateTime date) { TaktTimeMissionDto taktTime = new() { Label = date.ToString("dd/MM/yyyy") }; if (missions.Length > 0) { double TaktTimeAll = 0; foreach (var mission in missions) { var time = mission.StopedAt - mission.CreatedAt; if (time.TotalMinutes > 0) { TaktTimeAll += time.TotalMinutes; if (time.TotalMinutes < taktTime.Min || taktTime.Min == 0) taktTime.Min = time.TotalMinutes; if (time.TotalMinutes > taktTime.Max || taktTime.Max == 0) taktTime.Max = time.TotalMinutes; } } taktTime.Average = TaktTimeAll / missions.Length; } return taktTime; } private bool IsMissionInConfig(string missionName) { return Config.MissionNames.Length == 0 || Config.MissionNames.Contains(missionName); } public DashboardDto GetData() { using var scope = ServiceProvider.CreateScope(); var MissionDb = scope.ServiceProvider.GetRequiredService(); List TotalMissionPerformance = []; List TaktTimeMissions = []; var startDate = DateTime.Today.Date.AddDays(-CycleDate); for (var i = startDate; i <= DateTime.Today.Date; i = i.AddDays(1)) { var missions = MissionDb.InstanceMissions.Where(im => im.CreatedAt.Date == i.Date).ToList(); missions = [.. missions.Where(im => IsMissionInConfig(im.MissionName))]; var completedMissions = missions.Where(im => im.Status == Script.Shares.MissionStatus.Completed).ToList(); var errorMissions = missions.Where(im => im.Status == Script.Shares.MissionStatus.Error).ToList(); TotalMissionPerformance.Add(new DailyPerformanceDto { Label = i.ToString("dd/MM/yyyy"), Completed = completedMissions.Count, Error = errorMissions.Count, Other = missions.Count - completedMissions.Count - errorMissions.Count, }); TaktTimeMissions.Add(GetTaktTime([.. completedMissions], i)); } DailyPerformanceDto TodayPerformance = TotalMissionPerformance[^1]; DailyPerformanceDto ThisWeekPerformance = new() { Completed = TotalMissionPerformance.Sum(dp => dp.Completed), Error = TotalMissionPerformance.Sum(dp => dp.Error), Other = TotalMissionPerformance.Sum(dp => dp.Other), }; var toDayMissions = MissionDb.InstanceMissions.Where(im => im.CreatedAt.Date == DateTime.Today.Date).ToList(); toDayMissions = [.. toDayMissions.Where(im => IsMissionInConfig(im.MissionName))]; var toDaycompletedMissions = toDayMissions.Where(im => im.Status == Script.Shares.MissionStatus.Completed).ToList(); var toDayerrorMissions = toDayMissions.Where(im => im.Status == Script.Shares.MissionStatus.Error).ToList(); var toDayTaktTime = GetTaktTime([.. toDaycompletedMissions], DateTime.Today); DailyMissionDto DailyMission = new() { Completed = toDaycompletedMissions.Count, Error = toDayerrorMissions.Count, Total = toDayMissions.Count, CompletedRate = toDayMissions.Count > 0 ? (int)((toDaycompletedMissions.Count * 100.0 / toDayMissions.Count) + 0.5) : 0, TaktTimeMin = toDayTaktTime.Min, TaktTimeAverage = toDayTaktTime.Average, TaktTimeMax = toDayTaktTime.Max, RobotOnline = 1, }; return new() { TaktTimeMissions = [.. TaktTimeMissions], ThisWeekPerformance = ThisWeekPerformance, TodayPerformance = TodayPerformance, TotalMissionPerformance = [.. TotalMissionPerformance], DailyMission = DailyMission, }; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Yield(); while (!stoppingToken.IsCancellationRequested) { try { await Task.WhenAll(DashboardHub.Clients.All.SendAsync("DashboardDataUpdated", GetData(), cancellationToken: stoppingToken), Task.Delay(UpdateTime, stoppingToken)); } catch (Exception ex) { Logger.LogWarning("Dashboard Publisher xảy ra lỗi: {ex}", ex.Message); } } } }