RobotNet/RobotNet.ScriptManager/Services/DashboardPublisher.cs
2025-10-15 15:15:53 +07:00

116 lines
5.2 KiB
C#

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> DashboardHub, ILogger<DashboardPublisher> Logger) : BackgroundService
{
private readonly int UpdateTime = Configuration.GetValue<int>("Dashboard:UpdateTimeMilliSeconds", 5000);
private readonly int CycleDate = Configuration.GetValue<int>("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<ScriptManagerDbContext>();
List<DailyPerformanceDto> TotalMissionPerformance = [];
List<TaktTimeMissionDto> 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);
}
}
}
}