using Infrastructure.Attribute; using Infrastructure.Extensions; using Microsoft.AspNetCore.Components.Forms; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DOAN.Model.MES.dev; using DOAN.Model.MES.dev.Dto; using DOAN.Model.System; using DOAN.Service.MES.dev.IService; namespace DOAN.Service.MES.dev { /// /// 设备数据分析 /// [AppService(ServiceType = typeof(IDeviceDataAnalysisServcie), ServiceLifetime = LifeTime.Transient)] public class DeviceDataAnalysisService : BaseService, IDeviceDataAnalysisServcie { public static List FindAllLeafNodes(List nodeList, int targetId) { List childIds = new List { targetId }; List result = new List(); while (childIds.Any()) { int parentId = childIds.First(); childIds.RemoveAt(0); List children = nodeList.Where(n => n.ParentId == parentId).Select(n => n.Id).ToList(); if (children.Any()) { childIds.AddRange(children); } else { result.Add(nodeList.First(n => n.Id == parentId)); } } return result; } /// /// 故障类型 pie /// /// /// public List DefaultTypePie(DeviceDefaultDto devicedefault) { List resultList = new List(); int[] all_device_type_array = null; if (devicedefault.DevicetTypeId > 0) { List all_device_type_list = FindAllLeafNodes(Context.Queryable().ToList(), devicedefault.DevicetTypeId ?? 0); all_device_type_array = all_device_type_list.Select(it => it.Id).ToArray(); } var predicate = Expressionable.Create() .AndIF(all_device_type_array != null && all_device_type_array.Length > 0, (r, a, d) => all_device_type_array.Contains(a.FkDeviceType)) .AndIF(!string.IsNullOrEmpty(devicedefault.DeviceName), (r, a, d) => a.DeviceName.Contains(devicedefault.DeviceName)) .AndIF(!string.IsNullOrEmpty(devicedefault.DeviceCode), (r, a, d) => a.DeviceCode.Contains(devicedefault.DeviceCode)) .AndIF(devicedefault.searchTime[0] > new DateTime(1991, 1, 1), (r, a, d) => r.CreatedTime >= devicedefault.searchTime[0]) .AndIF(devicedefault.searchTime[1] > new DateTime(1991, 1, 1), (r, a, d) => r.CreatedTime <= devicedefault.searchTime[1]) .And((r, a, d) => d.DictType == "mes_device_fault_type") ; List deviceRepair_list = Context.Queryable() .LeftJoin((r, a) => r.FkDeviceId == a.Id) .LeftJoin((r, a, d) => r.Type == d.DictValue) .Where(predicate.ToExpression()) .Select((r, a, d) => new DeviceRepair_chart { Type = r.Type, TypeName = d.DictLabel, }).ToList(); if (deviceRepair_list.Count > 0) { var TypeGroups = deviceRepair_list.GroupBy(it => it.TypeName); foreach (var group in TypeGroups) { DeviceStatusAnalysisResultDto result = new DeviceStatusAnalysisResultDto(); result.name = group.Key; result.value = group.Count(); resultList.Add(result); } } return resultList; } /// /// 每日故障数量统计 /// /// /// public DeviceFaultBarResultDto FaultTypeBar(DeviceDefaultDto devicedefault) { DeviceFaultBarResultDto result = new DeviceFaultBarResultDto(); int[] all_device_type_array = null; if (devicedefault.DevicetTypeId > 0) { List all_device_type_list = FindAllLeafNodes(Context.Queryable().ToList(), devicedefault.DevicetTypeId ?? 0); all_device_type_array = all_device_type_list.Select(it => it.Id).ToArray(); } var predicate = Expressionable.Create() .AndIF(all_device_type_array != null && all_device_type_array.Length > 0, (r, a, d) => all_device_type_array.Contains(a.FkDeviceType)) .AndIF(!string.IsNullOrEmpty(devicedefault.DeviceName), (r, a, d) => a.DeviceName.Contains(devicedefault.DeviceName)) .AndIF(!string.IsNullOrEmpty(devicedefault.DeviceCode), (r, a, d) => a.DeviceCode.Contains(devicedefault.DeviceCode)) .AndIF(devicedefault.searchTime[0] > new DateTime(1991, 1, 1), (r, a, d) => r.CreatedTime >= devicedefault.searchTime[0]) .AndIF(devicedefault.searchTime[1] > new DateTime(1991, 1, 1), (r, a, d) => r.CreatedTime <= devicedefault.searchTime[1]) .And((r, a, d) => d.DictType == "mes_device_fault_type") ; List deviceRepair_list = Context.Queryable() .LeftJoin((r, a) => r.FkDeviceId == a.Id) .LeftJoin((r, a, d) => r.Type == d.DictValue) .Where(predicate.ToExpression()) .Select((r, a, d) => new DeviceRepair_chart { Type = r.Type, TypeName = d.DictLabel, CreatedTime = (DateTime)r.CreatedTime }).ToList(); //获取所有故障类型 List all_fault_type = Context.Queryable().Where(it => it.DictType == "mes_device_fault_type").ToList(); // 先按照天进行上卷聚合,然后按照故障种类进行上卷聚合 var first_groups = deviceRepair_list.GroupBy(it => it.CreatedTime.Date); string[] Xdata = new string[first_groups.Count()]; int index = 0; foreach (var group in first_groups) { Xdata[index] = group.Key.ToString("yyyy-MM-dd"); index++; } List SeriesData = new List(); foreach (SysDictData dict in all_fault_type) { SeriesData_Item seriesData_Item = new SeriesData_Item(); seriesData_Item.Name = dict.DictLabel; //这种故障在每天的值 int[] values = new int[first_groups.Count()]; int index2 = 0; foreach (var group in first_groups) { //凌晨 DateTime startOfDay = group.Key; //午夜(23:59:59) DateTime endOfDay = group.Key.AddDays(1).AddSeconds(-1); values[index2] = deviceRepair_list .Where(it => it.CreatedTime >= startOfDay && it.CreatedTime <= endOfDay) .Where(it => it.Type == dict.DictValue).Count(); index2++; } seriesData_Item.Data = values; SeriesData.Add(seriesData_Item); } result.XData = Xdata; result.SeriesData = SeriesData; return result; } /// /// 获取设备故障类别累计次数折线图 /// /// /// public DeviceFaultLineResultDto FaultTypeLine(DeviceDefaultDto devicedefault) { DeviceFaultLineResultDto result = new DeviceFaultLineResultDto(); int[] all_device_type_array = null; if (devicedefault.DevicetTypeId > 0) { List all_device_type_list = FindAllLeafNodes(Context.Queryable().ToList(), devicedefault.DevicetTypeId ?? 0); all_device_type_array = all_device_type_list.Select(it => it.Id).ToArray(); } var predicate = Expressionable.Create() .AndIF(all_device_type_array != null && all_device_type_array.Length > 0, (r, a, d) => all_device_type_array.Contains(a.FkDeviceType)) .AndIF(!string.IsNullOrEmpty(devicedefault.DeviceName), (r, a, d) => a.DeviceName.Contains(devicedefault.DeviceName)) .AndIF(!string.IsNullOrEmpty(devicedefault.DeviceCode), (r, a, d) => a.DeviceCode.Contains(devicedefault.DeviceCode)) .AndIF(devicedefault.searchTime[0] > new DateTime(1991, 1, 1), (r, a, d) => r.CreatedTime >= devicedefault.searchTime[0]) .AndIF(devicedefault.searchTime[1] > new DateTime(1991, 1, 1), (r, a, d) => r.CreatedTime <= devicedefault.searchTime[1]) .And((r, a, d) => d.DictType == "mes_device_fault_type") ; List deviceRepair_list = Context.Queryable() .LeftJoin((r, a) => r.FkDeviceId == a.Id) .LeftJoin((r, a, d) => r.Type == d.DictValue) .Where(predicate.ToExpression()) .Select((r, a, d) => new DeviceRepair_chart { Id = r.Id, Type = r.Type, TypeName = d.DictLabel, CreatedTime = (DateTime)r.CreatedTime }) .ToList(); foreach (var repair in deviceRepair_list) { repair.AccValue_SameType = Context.Queryable().Where(it => it.Type == repair.Type) .Where(it => it.CreatedTime <= repair.CreatedTime).Count(); } //获取所有故障类型 List all_fault_type = Context.Queryable().Where(it => it.DictType == "mes_device_fault_type").ToList(); // 先按照天进行上卷聚合,然后按照故障种类进行上卷聚合 var first_groups = deviceRepair_list.GroupBy(it => it.CreatedTime.Date); string[] Xdata = new string[first_groups.Count()]; int index = 0; foreach (var group in first_groups) { Xdata[index] = group.Key.ToString("yyyy-MM-dd"); index++; } //处理纵坐标 List SeriesData = new List(); foreach (SysDictData dict in all_fault_type) { SeriesData_Item_line seriesData_Item = new SeriesData_Item_line(); seriesData_Item.Name = dict.DictLabel; seriesData_Item.Type = "line"; int[] values = new int[first_groups.Count()]; int index2 = 0; foreach (var group in first_groups) { //凌晨 DateTime startOfDay = group.Key; //午夜(23:59:59) DateTime endOfDay = group.Key.AddDays(1).AddSeconds(-1); values[index2] = deviceRepair_list .Where(it => it.CreatedTime <= endOfDay) .Where(it => it.Type == dict.DictValue) .Sum(it => it.AccValue_SameType); index2++; } seriesData_Item.Data = values; SeriesData.Add(seriesData_Item); } result.XData = Xdata; result.SeriesData = SeriesData; return result; } /// /// 获取每日设备故障总数与维修完成数柱状图 /// /// /// public DeviceRepairBarResultDto FaultTypeBarByDay(DeviceDefaultDto devicedefault) { DeviceRepairBarResultDto result = new DeviceRepairBarResultDto(); int[] all_device_type_array = null; if (devicedefault.DevicetTypeId > 0) { List all_device_type_list = FindAllLeafNodes(Context.Queryable().ToList(), devicedefault.DevicetTypeId ?? 0); all_device_type_array = all_device_type_list.Select(it => it.Id).ToArray(); } var predicate = Expressionable.Create() .AndIF(all_device_type_array != null && all_device_type_array.Length > 0, (r, a) => all_device_type_array.Contains(a.FkDeviceType)) .AndIF(!string.IsNullOrEmpty(devicedefault.DeviceName), (r, a) => a.DeviceName.Contains(devicedefault.DeviceName)) .AndIF(!string.IsNullOrEmpty(devicedefault.DeviceCode), (r, a) => a.DeviceCode.Contains(devicedefault.DeviceCode)) .AndIF(devicedefault.searchTime[0] > new DateTime(1991, 1, 1), (r, a) => r.CreatedTime >= devicedefault.searchTime[0]) .AndIF(devicedefault.searchTime[1] > new DateTime(1991, 1, 1), (r, a) => r.CreatedTime <= devicedefault.searchTime[1]) ; List deviceRepair_list = Context.Queryable() .LeftJoin((r, a) => r.FkDeviceId == a.Id) .Where(predicate.ToExpression()) .Select((r, a) => new DeviceRepair_chart { Id = r.Id, Type = r.Type, Status = r.Status ?? 0, CreatedTime = (DateTime)r.CreatedTime }) .ToList(); // 先按照天进行上卷聚合 var first_groups = deviceRepair_list.GroupBy(it => it.CreatedTime.Date); string[] Xdata = new string[first_groups.Count()]; int index = 0; foreach (var group in first_groups) { Xdata[index] = group.Key.ToString("yyyy-MM-dd"); index++; } result.XData = Xdata; List SeriesData = new List(); SeriesData_Item_line2 faultAll = new SeriesData_Item_line2(); faultAll.Name = "报修数"; int[] Data1 = new int[first_groups.Count()]; int index1 = 0; foreach (var group in first_groups) { Data1[index1] = group.Count(); index1++; } faultAll.Data = Data1; SeriesData.Add(faultAll); SeriesData_Item_line2 repair_success_all = new SeriesData_Item_line2(); repair_success_all.Name = "维修数"; List deviceRepair_list_success = Context.Queryable() .LeftJoin((r, a) => r.FkDeviceId == a.Id) .Where(predicate.ToExpression()) .Where((r, a) => r.Status == 2) .Select((r, a) => new DeviceRepair_chart { Id = r.Id, Type = r.Type, Status = r.Status ?? 0, CreatedTime = (DateTime)r.CreatedTime }) .ToList(); // 先按照天进行上卷聚合 var first_groups_success = deviceRepair_list.GroupBy(it => it.CreatedTime.Date); int[] Data2 = new int[first_groups_success.Count()]; int index2 = 0; foreach (var group in first_groups_success) { Data2[index2] = group.Count(); index2++; } repair_success_all.Data = Data2; SeriesData.Add(repair_success_all); result.SeriesData = SeriesData; return result; } /// /// 获取每日点检巡检总数折线图 /// /// /// public TaskLineResultDto TaskLinebyDay(DeviceDefaultDto devicedefault) { TaskLineResultDto taskLine = new TaskLineResultDto(); var predicate = Expressionable.Create() .AndIF(devicedefault.searchTime[0] > new DateTime(1991, 1, 1), (r) => r.CreatedTime >= devicedefault.searchTime[0]) .AndIF(devicedefault.searchTime[1] > new DateTime(1991, 1, 1), (r) => r.CreatedTime <= devicedefault.searchTime[1]) .ToExpression(); List InitDataCollection = Context.Queryable().Where(predicate).ToList(); List SeriesData = new List(); var SecondDataCollection = InitDataCollection.GroupBy(it => ((DateTime)it.CreatedTime).Date); string[] Xdata = new string[SecondDataCollection.Count()]; int index = 0; foreach (var group in SecondDataCollection) { Xdata[index] = group.Key.ToString("yyyy-MM-dd"); index++; } taskLine.XData = Xdata; SeriesData_Item_line3 line3 = new SeriesData_Item_line3(); int[] Data = new int[SecondDataCollection.Count()]; int index2 = 0; foreach (var group in SecondDataCollection) { Data[index2] = group.Count(); index2++; } line3.Data = Data; SeriesData.Add(line3); taskLine.SeriesData = SeriesData; return taskLine; } private PersonnelResponseResultDto dataAnalysis(DeviceDefaultDto devicedefault) { PersonnelResponseResultDto personnelResponseResultDto = new PersonnelResponseResultDto(); personnelResponseResultDto.XData = []; personnelResponseResultDto.SeriesData = null; // 任务接受响应系列 PersonnelResponse_Series task_accept_series = new PersonnelResponse_Series(); var predicate = Expressionable.Create() .AndIF(devicedefault.searchTime[0] > new DateTime(1991, 1, 1), (r) => r.CreatedTime >= devicedefault.searchTime[0]) .AndIF(devicedefault.searchTime[1] > new DateTime(1991, 1, 1), (r) => r.CreatedTime <= devicedefault.searchTime[1]) .And(it => it.DistributedTime != DateTime.MinValue) .And(it => it.StartTime != DateTime.MinValue) .And(it => it.EndTime != DateTime.MinValue) .ToExpression(); List InitDataCollection = Context .Queryable() .Where(predicate) .ToList(); if (InitDataCollection.Count == 0) { personnelResponseResultDto.TaskTotal = 0; personnelResponseResultDto.TaskMax = new TimeSpan(0); personnelResponseResultDto.TaskMin = new TimeSpan(0); personnelResponseResultDto.TaskAvg = new TimeSpan(0); return personnelResponseResultDto; } personnelResponseResultDto.TaskTotal = InitDataCollection.Count; PersonnelResponseDto[] SecondDataCollection = new PersonnelResponseDto[InitDataCollection.Count]; string[] XData = new string[InitDataCollection.Count]; double[] resultDate = new double[InitDataCollection.Count]; if (InitDataCollection.Count > 0) { int index = 0; foreach (var item in InitDataCollection) { XData[index] = item.TaskName; PersonnelResponseDto temp = new PersonnelResponseDto(); temp.Id = item.Id; temp.TaskName = item.TaskName; temp.Accept_response = (item.StartTime ?? DateTime.Now) - (item.DistributedTime ?? DateTime.Now); temp.Action_response = (item.EndTime ?? DateTime.Now) - (item.StartTime ?? DateTime.Now); SecondDataCollection[index] = temp; index++; } } #region 固定配置 MarkPoint_ markPoint_ = new MarkPoint_(); TypeName[] data = new TypeName[2]; TypeName item1 = new TypeName(); item1.Type = "max"; item1.Name = "最大值"; data[0] = item1; TypeName item2 = new TypeName(); item2.Type = "min"; item2.Name = "最小值"; data[1] = item2; markPoint_.data = data; task_accept_series.markPoint = markPoint_; MarkPoint_ markLine = new MarkPoint_(); TypeName[] data2 = new TypeName[1]; TypeName item3 = new TypeName(); item3.Type = "average"; item3.Name = "平均值"; data2[0] = item3; markLine.data = data2; task_accept_series.markLine = markLine; #endregion if (devicedefault.searchType == 1) { task_accept_series.Name = "人员接受任务响应时间"; personnelResponseResultDto.TaskMax = SecondDataCollection.Max(it => it.Accept_response); personnelResponseResultDto.TaskMin = SecondDataCollection.Min(it => it.Accept_response); personnelResponseResultDto.TaskAvg = CalculateAverageTimeSpan(SecondDataCollection.Select(it => it.Action_response).ToArray()); personnelResponseResultDto.SeriesData = task_accept_series; resultDate = SecondDataCollection.Select(it => Math.Round(it.Accept_response.TotalMinutes, 2)).ToArray(); } else if (devicedefault.searchType == 2) { task_accept_series.Name = "人员处理任务响应时间"; personnelResponseResultDto.TaskMax = SecondDataCollection.Max(it => it.Action_response); personnelResponseResultDto.TaskMin = SecondDataCollection.Min(it => it.Action_response); personnelResponseResultDto.TaskAvg = CalculateAverageTimeSpan(SecondDataCollection.Select(it => it.Action_response).ToArray()); personnelResponseResultDto.SeriesData = task_accept_series; resultDate = SecondDataCollection.Select(it => Math.Round(it.Action_response.TotalMinutes, 2)).ToArray(); } personnelResponseResultDto.XData = XData; personnelResponseResultDto.SeriesData.Data = resultDate; return personnelResponseResultDto; } /// /// 获取人员响应折线图 /// /// /// public PersonnelResponseResultDto PersonResponse(DeviceDefaultDto devicedefault) { PersonnelResponseResultDto crount = dataAnalysis(devicedefault); DeviceDefaultDto devicedefault_last = new DeviceDefaultDto(); devicedefault_last.searchType = devicedefault.searchType; DateTime lastMondayMidnight, lastSundayMidnight; GetLastWeekBoundaries(devicedefault.searchTime[0], out lastMondayMidnight, out lastSundayMidnight); devicedefault_last.searchTime = new DateTime[2] { lastMondayMidnight, lastSundayMidnight }; PersonnelResponseResultDto last = dataAnalysis(devicedefault_last); crount.lastTotalPer = CalculatePercentageIncrease(crount.TaskTotal, last.TaskTotal); crount.lastMaxPer = CalculatePercentageIncrease(crount.TaskMax, last.TaskMax); crount.lastMinPer = CalculatePercentageIncrease(crount.TaskMin, last.TaskMin); crount.lastAvgPer = CalculatePercentageIncrease(crount.TaskAvg, last.TaskAvg); return crount; } private static double CalculatePercentageIncrease(int number1, int number2) { if (number2 == 0) { return 100; } return ((double)(number1 - number2) / number2) * 100; } private static double CalculatePercentageIncrease(TimeSpan timeSpan1, TimeSpan timeSpan2) { double totalSeconds1 = timeSpan1.TotalSeconds; double totalSeconds2 = timeSpan2.TotalSeconds; if (totalSeconds2 == 0) { return 100; } return ((totalSeconds1 - totalSeconds2) / totalSeconds2) * 100; } public static TimeSpan CalculateAverageTimeSpan(TimeSpan[] timeSpans) { // 将 TimeSpan 数组中的每个 TimeSpan 值转换为总秒数 double totalSeconds = timeSpans.Sum(ts => ts.TotalSeconds); // 计算平均总秒数 double averageSeconds = totalSeconds / timeSpans.Length; // 将平均总秒数转换为 TimeSpan 格式 TimeSpan averageTimeSpan = TimeSpan.FromSeconds(averageSeconds); return averageTimeSpan; } public static void GetLastWeekBoundaries(DateTime inputDateTime, out DateTime lastMondayMidnight, out DateTime lastSundayMidnight) { DayOfWeek currentDayOfWeek = inputDateTime.DayOfWeek; int daysToSubtract = (int)currentDayOfWeek + 6; // 6 days to subtract to get to last Monday lastMondayMidnight = inputDateTime.Date.AddDays(-daysToSubtract).AddDays(-7).Date; // Last Monday midnight lastSundayMidnight = lastMondayMidnight.AddDays(6).AddHours(23).AddMinutes(59).AddSeconds(59); // Last Sunday midnight } /// /// 获取大屏总数 /// /// /// public FullScreenTotal GetAllTotal() { FullScreenTotal screenTotal = new FullScreenTotal(); //设备可用数 screenTotal.UseDeviceTotal = Context.Queryable().Where(it => it.Status == 1).Count(); //设备停机数 screenTotal.UnUseDeviceTotal = Context.Queryable().Where(it => it.Status == 0).Count(); // 累计任务数 screenTotal.TaskTotal = Context.Queryable().Count(); //累计任务完成数 screenTotal.FinishTaskTotal= Context.Queryable().Where(it => it.Status == 2).Count(); //累计报修数 screenTotal.RepairTotal = Context.Queryable().Count(); //累计维护数 screenTotal.FinishRepairTotal = Context.Queryable().Where(it=>it.Status==2).Count(); return screenTotal; } } }