using NPOI.HSSF.Record.Chart; using NPOI.OpenXmlFormats.Dml; using NPOI.SS.Formula.Functions; using OfficeOpenXml.VBA; using Org.BouncyCastle.Crypto.EC; using ProductionLineMonitor.Core.Models; using ProductionLineMonitor.Core.Utils; using ProductionLineMonitor.Web.Services; using ProductionLineMonitor.Web.Services.LineService; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using static OfficeOpenXml.ExcelErrorValue; namespace ProductionLineMonitor.Application.Services.HomeService.Dtos { public class MonthOverview { public MonthOverview( string mark, int year, int month, string moduleType, IList lst) { _year = year; _month = month; _rangeEndDate = Convert.ToDateTime($"{_year}-{_month}-20 08:00:00"); _startDate = _rangeEndDate.AddMonths(-1).AddDays(+1); DateTime _date = DateTime.Now; if (_date <= _rangeEndDate) _endDate = Convert.ToDateTime($"{_date.AddDays(-1):yyyy-MM-dd} 08:00:00"); else _endDate = _rangeEndDate; Dates = DateTimeHelper.GetDateString(_startDate, _rangeEndDate).ToArray(); _planCapacities = new int[Dates.Length]; _capacities = new int[Dates.Length]; NewDates = new string[Dates.Length]; PlanCapacities = new string[Dates.Length]; Capacities = new string[Dates.Length]; Differences = new string[Dates.Length]; for (int i = 0; i < lst.Count; i++) { var plans = MesApiService.GetProductionPlanByTimelotV1(lst[i].Floor, lst[i].Line, _startDate.ToString("yyyy-MM-dd"), _rangeEndDate.ToString("yyyy-MM-dd")) .Where(x => string.IsNullOrEmpty(moduleType) != true && x.ModuleType.Length >= 10 && x.ModuleType[..10] == moduleType); var outs = MesApiService.GetOutPutPerHours(lst[i].HourDataTopic, _startDate.ToString("yyyy-MM-dd"), _endDate.ToString("yyyy-MM-dd")) .Where(x => string.IsNullOrEmpty(moduleType) != true && x.ModuleType.Length >= 10 && x.ModuleType[..10] == moduleType); for (int j = 0; j < Dates.Length; j++) { NewDates[j] = $"{Dates[j].Substring(8, 2)}"; _planCapacities[j] += plans.Where(x => x.ShiftDate == Dates[j]).Sum(x => x.PlanCapacity); if (_planCapacities[j] == 0) PlanCapacities[j] = ""; else PlanCapacities[j] = _planCapacities[j].ToString(); _capacities[j] += GetOuts(Dates[j], outs).Sum(x => x.OutPut); if (_capacities[j] == 0) Capacities[j] = ""; else Capacities[j] = _capacities[j].ToString(); if (_planCapacities[j] == 0 || _capacities[j] == 0) { Differences[j] = ""; } else { int d = _planCapacities[j] - _capacities[j]; Differences[j] = d > 0 ? d.ToString() : ""; } } } } public MonthOverview(int year, int month, string moduleType, IList lst, IList moduleTypes, int line) { _year = year; _month = month; _rangeEndDate = Convert.ToDateTime($"{_year}-{_month}-20 08:00:00"); _startDate = _rangeEndDate.AddMonths(-1).AddDays(+1); DateTime _date = DateTime.Now; if (_date < _rangeEndDate.AddDays(1)) _endDate = Convert.ToDateTime($"{_date.AddDays(-1):yyyy-MM-dd} 08:00:00"); else _endDate = _rangeEndDate; Dates = DateTimeHelper.GetDateString(_startDate, _rangeEndDate).ToArray(); _planCapacities = new int[Dates.Length]; _capacities = new int[Dates.Length]; NewDates = new string[Dates.Length]; PlanCapacities = new string[Dates.Length]; Capacities = new string[Dates.Length]; Differences = new string[Dates.Length]; AddX(); AddLinePlans(line, lst, moduleType, moduleTypes); _ps = new List(); _os = new List(); GetPsOrOsByLine(line, lst); GetPsOrOsByModuleType(moduleType, moduleTypes); AddY(); Difference = _os.Sum(x => x.OutPut) - _ps.Where(x => Convert.ToDateTime($"{x.ShiftDate} 08:00:00") <= _endDate) .Sum(x => x.PlanCapacity); AddKeyInInfos(line, lst); AddDifferenceInfosTop5(); } private void AddLinePlans(int line, IList lines, string moduleType, IList moduleTypes) { List ps = new List(); if (moduleType != "ALL" && line != 0) { var l = lines.FirstOrDefault(x => x.Line == line); if (l == null) { return; } ps = MesApiService.GetProductionPlanByTimelotV1(l.Floor, l.Line, _startDate.ToString("yyyy-MM-dd"), _rangeEndDate.ToString("yyyy-MM-dd")); ps = ps.Where(x => string.IsNullOrEmpty(moduleType) != true && x.ModuleType.Length >= 10 && x.ModuleType == moduleType).ToList(); LinePlans.Add(new LinePlan(Dates, ps, l.Line)); return; } if (moduleType != "ALL" && line == 0) { for (int i = 0; i < lines.Count; i++) { ps = MesApiService.GetProductionPlanByTimelotV1(lines[i].Floor, lines[i].Line, _startDate.ToString("yyyy-MM-dd"), _rangeEndDate.ToString("yyyy-MM-dd")); ps = ps.Where(x => string.IsNullOrEmpty(moduleType) != true && x.ModuleType.Length >= 10 && x.ModuleType == moduleType).ToList(); LinePlans.Add(new LinePlan(Dates, ps, lines[i].Line)); } return; } if (moduleType == "ALL" && line == 0) { for (int i = 0; i < lines.Count; i++) { foreach (var item in moduleTypes) { ps = MesApiService.GetProductionPlanByTimelotV1(lines[i].Floor, lines[i].Line, _startDate.ToString("yyyy-MM-dd"), _rangeEndDate.ToString("yyyy-MM-dd")); ps = ps.Where(x => string.IsNullOrEmpty(item) != true && x.ModuleType.Length >= 10 && x.ModuleType == item).ToList(); LinePlans.Add(new LinePlan(Dates, ps, lines[i].Line)); } } return; } if (moduleType == "ALL" && line != 0) { var l1 = lines.FirstOrDefault(x => x.Line == line); if (l1 == null) { return; } foreach (var item in moduleTypes) { ps = MesApiService.GetProductionPlanByTimelotV1(l1.Floor, l1.Line, _startDate.ToString("yyyy-MM-dd"), _rangeEndDate.ToString("yyyy-MM-dd")); ps = ps.Where(x => string.IsNullOrEmpty(item) != true && x.ModuleType.Length >= 10 && x.ModuleType == item).ToList(); LinePlans.Add(new LinePlan(Dates, ps, l1.Line)); } return; } } private void AddKeyInInfos(int line, IList lines) { for (int i = 0; i < Differences.Length; i++) { if (Differences[i] != "") { DateTime start = Convert.ToDateTime($"{Dates[i]} 8:00:00"); if (line == 0) { foreach (var item in lines) { KeyInInfos.AddRange(MesApiService.GetAlarmByKeyIn(item.Floor, item.Line, start, start.AddDays(1))); } } else { var l = lines.FirstOrDefault(x => x.Line == line); if (l != null) { KeyInInfos.AddRange(MesApiService.GetAlarmByKeyIn(l.Floor, l.Line, start, start.AddDays(1))); } } } } } private void GetPsOrOsByLine(int line, IList lines) { if (line == 0) { for (int i = 0; i < lines.Count(); i++) { List ps = MesApiService.GetProductionPlanByTimelotV1(lines[i].Floor, lines[i].Line, _startDate.ToString("yyyy-MM-dd"), _rangeEndDate.ToString("yyyy-MM-dd")); _ps.AddRange(ps); _os.AddRange(MesApiService.GetOutPutPerHours(lines[i].HourDataTopic, _startDate.ToString("yyyy-MM-dd"), _endDate.ToString("yyyy-MM-dd"))); } return; } var l = lines.FirstOrDefault(x => x.Line == line); if (l == null) { return; } List ps1 = MesApiService.GetProductionPlanByTimelotV1(l.Floor, l.Line, _startDate.ToString("yyyy-MM-dd"), _rangeEndDate.ToString("yyyy-MM-dd")); _ps.AddRange(ps1); _os.AddRange(MesApiService.GetOutPutPerHours(l.HourDataTopic, _startDate.ToString("yyyy-MM-dd"), _endDate.ToString("yyyy-MM-dd"))); } private void GetPsOrOsByModuleType(string moduleType, IList moduleTypes) { if (moduleType != "ALL") { _ps = _ps.Where(x => string.IsNullOrEmpty(moduleType) != true && x.ModuleType.Length >= 10 && x.ModuleType[..moduleType.Length] == moduleType).ToList(); _os = _os.Where(x => string.IsNullOrEmpty(moduleType) != true && x.ModuleType.Length >= 10 && x.ModuleType[..moduleType.Length] == moduleType).ToList(); } else { List p1 = _ps.ToList(); List o1 = _os.ToList(); _ps.Clear(); _os.Clear(); foreach (var item in moduleTypes) { _ps.AddRange(p1.Where(x => string.IsNullOrEmpty(item) != true && x.ModuleType.Length >= 10 && x.ModuleType == item).ToList()); _os.AddRange(o1.Where(x => string.IsNullOrEmpty(item) != true && x.ModuleType.Length >= 10 && x.ModuleType.Length >= item.Length && x.ModuleType[..item.Length] == item).ToList()); } } } private void AddX() { for (int j = 0; j < Dates.Length; j++) { NewDates[j] = $"{Dates[j].Substring(8, 2)}"; DateTime d = Convert.ToDateTime(Dates[j]); if (d.DayOfWeek == DayOfWeek.Sunday) { NewDates[j] += "\n周日"; } } } private void AddY() { for (int j = 0; j < Dates.Length; j++) { int plan = _ps.Where(x => x.ShiftDate == Dates[j]).Sum(x => x.PlanCapacity); _planCapacities[j] += plan; if (_planCapacities[j] == 0) PlanCapacities[j] = ""; else PlanCapacities[j] = _planCapacities[j].ToString(); _capacities[j] += GetOuts(Dates[j], _os).Sum(x => x.OutPut); if (_capacities[j] == 0) Capacities[j] = ""; else Capacities[j] = _capacities[j].ToString(); if (_planCapacities[j] == 0 || _capacities[j] == 0) { Differences[j] = ""; } else { int d = _planCapacities[j] - _capacities[j]; Differences[j] = d > 0 ? d.ToString() : ""; } } } private void AddDifferenceInfosTop5() { List differenceInfos = new List(); foreach (var item in KeyInInfos) { var d = differenceInfos.FirstOrDefault(x => x.Description == item.Description); if (d == null) { differenceInfos.Add(new DifferenceInfo() { Description = item.Description, Frequency = 1, DifferenceTime = item.AffectTime, TypeName = item.KeyInTypeName }); } else { d.Frequency += 1; d.DifferenceTime += item.AffectTime; } } DifferenceInfos = differenceInfos.OrderByDescending(o => o.DifferenceTime).Take(5).ToList(); } private IEnumerable GetOuts(string date, IEnumerable HourOuts) { DateTime sTime = Convert.ToDateTime($"{date} 08:00:00"); DateTime eTime = sTime.AddHours(24); return HourOuts.Where(x => x.DataTime >= sTime && x.DataTime < eTime); } private readonly DateTime _startDate; private readonly DateTime _endDate; private readonly DateTime _rangeEndDate; private readonly int _year; private readonly int _month; private readonly int[] _planCapacities; private readonly int[] _capacities; private List _ps; private List _os; public string[] Dates { get; set; } public string[] NewDates { get; set; } public string[] PlanCapacities { get; set; } public string[] Capacities { get; set; } public string[] Differences { get; set; } public int Difference { get; set; } public List KeyInInfos { get; set; } = new List(); public List DifferenceInfos { get; set; } = new List(); public List LinePlans { get; set; } = new List(); } public class DifferenceInfo { public string TypeName { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public string MachineType { get; set; } = string.Empty; public int Frequency { get; set; } public int DifferenceTime { get; set; } } public class LinePlan { public LinePlan(string[] dates, List plans, int line) { Line = line; PlanDates = new string[dates.Length]; PlanCapacity = 0; int[] values = new int[dates.Length + 2]; for (int i = 1; i <= dates.Length; i++) { int plan = plans.Where(x => x.ShiftDate == dates[i - 1]).Sum(x => x.PlanCapacity); PlanCapacity += plan; values[i] = plan == 0 ? 0 : 1; } // 平滑过渡周日无排程 for (int i = 0; i < values.Length; i++) { if (values[i] == 1) { continue; } if (i - 1 < 0 || i + 1 >= values.Length) { continue; } if (values[i - 1] == 1 && values[i + 1] == 1) { values[i] = 1; } } for (int i = 1; i < values.Length - 1; i++) { if (values[i] == 1) { PlanDates[i - 1] = "1"; } else { PlanDates[i - 1] = ""; } } Start = Array.IndexOf(PlanDates, "1"); } public int Line { get; set; } public int PlanCapacity { get; set; } public string[] PlanDates { get; set; } public int Start { get; set; } } }