using System; using System.Collections.Generic; using CncModels.Dto.Dashboard; using CncRepository.Interface; using CncService.Interface; namespace CncService.Impl { /// /// 仪表盘实现 /// public class DashboardService : IDashboardService { private readonly IDashboardRepository _dashboardRepository; private readonly ICollectorHeartbeatRepository _collectorHeartbeatRepository; private readonly IWindowsServiceChecker _serviceChecker; private readonly ISysConfigRepository _sysConfigRepository; public DashboardService(IDashboardRepository dashboardRepository, ICollectorHeartbeatRepository collectorHeartbeatRepository, ISysConfigRepository sysConfigRepository, IWindowsServiceChecker serviceChecker = null) { _dashboardRepository = dashboardRepository ?? throw new ArgumentNullException(nameof(dashboardRepository)); _collectorHeartbeatRepository = collectorHeartbeatRepository ?? throw new ArgumentNullException(nameof(collectorHeartbeatRepository)); _sysConfigRepository = sysConfigRepository ?? throw new ArgumentNullException(nameof(sysConfigRepository)); _serviceChecker = serviceChecker; } /// 从sys_config读取online_timeout,默认300秒 private int GetOnlineTimeout() { var cfg = _sysConfigRepository.GetByKey("online_timeout"); if (cfg != null && int.TryParse(cfg.ConfigValue, out var val) && val > 0) return val; return 300; } /// public DashboardSummaryResponse GetSummary() { return _dashboardRepository.GetSummary(GetOnlineTimeout()); } /// public List GetWorkshopProduction(DateTime? startDate, DateTime? endDate) { var s = startDate ?? DateTime.Today; var e = endDate ?? DateTime.Today; return _dashboardRepository.GetWorkshopProduction(s, e); } /// public List GetMachineRank(DateTime? startDate, DateTime? endDate, int top = 10, string sortOrder = "desc") { var s = startDate ?? DateTime.Today; var e = endDate ?? DateTime.Today; return _dashboardRepository.GetMachineRank(s, e, top, GetOnlineTimeout(), sortOrder); } /// public List GetWorkerRank(DateTime? startDate, DateTime? endDate, int top = 10, string sortOrder = "desc") { var s = startDate ?? DateTime.Today; var e = endDate ?? DateTime.Today; return _dashboardRepository.GetWorkerRank(s, e, top, sortOrder); } /// public object GetProductionTrend(int days = 7) { return _dashboardRepository.GetProductionTrend(days); } /// public object GetMachineStatusDistribution() { return _dashboardRepository.GetMachineStatusDistribution(GetOnlineTimeout()); } /// public List GetRecentAlerts(int count = 5) { return _dashboardRepository.GetRecentAlerts(count); } /// public object GetCollectorStatus() { var latest = _collectorHeartbeatRepository.GetLatest("collector-service"); // 心跳超时阈值:90秒(3个心跳间隔,采集服务默认每30秒上报一次) const int heartbeatTimeoutSeconds = 90; bool heartbeatRunning = false; long heartbeatUptime = 0; DateTime? lastCollectTime = latest?.LastCollectTime; if (latest != null && latest.Status == "running") { var lastHeartbeat = latest.CreatedAt; var elapsed = (DateTime.Now - lastHeartbeat).TotalSeconds; heartbeatRunning = elapsed <= heartbeatTimeoutSeconds; if (heartbeatRunning) heartbeatUptime = latest.UptimeSeconds ?? 0; } // 额外的 Windows 服务状态 string serviceStatusText = "NotInstalled"; if (_serviceChecker != null) { var svc = _serviceChecker.GetServiceStatus("CncCollector"); serviceStatusText = svc.ToString(); } // 组合状态:NotInstalled -> 停止,其他根据心跳决定 string status = (serviceStatusText == "NotInstalled") ? "stopped" : (heartbeatRunning ? "running" : "stopped"); return new { status, uptimeSeconds = heartbeatRunning ? heartbeatUptime : 0, lastCollectTime, serviceStatus = serviceStatusText, serviceName = "CncCollector", serviceMessage = (string)null }; } } }