using ProductionLineMonitor.Core.Models; using ProductionLineMonitor.Core.Utils; using ProductionLineMonitor.Web.Services; using ProductionLineMonitor.Web.Services.LineService; using System; using System.Collections.Generic; using System.Linq; namespace ProductionLineMonitor.Application.Services.LineService.Dtos { public class LineMonthData { public LineMonthData(ProductionLine line, DateTime date, int moduleTypeLen, string moduleType) { DateTimeHelper.GetStartEndTime(date, out _startDate, out _endDate); Plans = MesApiService.GetProductionPlanByTimelotV1( line.Floor, line.Line, _startDate.ToString("yyyy-MM-dd"), _endDate.ToString("yyyy-MM-dd")); // 兼容 8/20日之前机种为8码数据 if (date <= Convert.ToDateTime("2023-08-20 08:00:00")) { foreach (var item in Plans) { if (item.ModuleType != "" && item.ModuleType.Length > 10) { item.ModuleType = item.ModuleType[..10]; } } } HourOuts = MesApiService.GetOutPutPerHours( line.HourDataTopic, _startDate.ToString("yyyy-MM-dd"), _endDate.ToString("yyyy-MM-dd")); Dates = DateTimeHelper.GetDateString(_startDate, _endDate).ToArray(); NewDates = new string[Dates.Length]; PlanCapacities = new string[Dates.Length]; Capacities = new string[Dates.Length]; Differences = new string[Dates.Length]; AccumulatedDifferences = new string[Dates.Length]; ModuleTypes = Plans .Where(x => x.ModuleType != "") .Select(x => x.ModuleType) .Distinct().ToArray(); if (moduleType != "ALL") { Plans = Plans.Where( x => x.ModuleType != "" && x.ModuleType.Length >= moduleType.Length && x.ModuleType[..moduleType.Length] == moduleType) .OrderBy(o => o.ShiftDate) .ToList(); HourOuts = HourOuts.Where( x => x.ModuleType != "" && x.ModuleType.Length >= moduleType.Length && x.ModuleType[..moduleType.Length] == moduleType) .ToList(); var ts = Plans.OrderBy(o => o.ShiftDate) .ToList(); var sValues = GetPlanGanttChart(ts); foreach (var item in sValues) { Serie serie = new Serie(Dates.Length) { Name = moduleType, Start = item.Start, End = item.End, Values = item.Values, PlanCapacities = item.Value, StartDate = item.StartDate, EndDate = item.EndDate }; Series.Add(serie); } } else { foreach (var module in ModuleTypes) { var ts = Plans.Where(x => x.ModuleType == module) .OrderBy(o => o.ShiftDate) .ToList(); if (ts.Count() == 0) { continue; } var sValues = GetPlanGanttChart(ts); foreach (var item in sValues) { Serie serie = new Serie(Dates.Length) { Name = module, Start = item.Start, End = item.End, Values = item.Values, PlanCapacities = item.Value, StartDate = item.StartDate, EndDate = item.EndDate }; Series.Add(serie); } } } Series = Series.OrderBy(o => o.Start).ToList(); for (int i = 0; i < Dates.Length; i++) { NewDates[i] = $"{Dates[i].Substring(8, 2)}"; DateTime day = Convert.ToDateTime(Dates[i]); if (day.DayOfWeek == DayOfWeek.Sunday) { NewDates[i] += "\n周日"; } int v1 = Plans.Where(x => x.ShiftDate == Dates[i]).Sum(x => x.PlanCapacity); PlanCapacities[i] = v1 == 0 ? "" : v1.ToString(); DateTime d = Convert.ToDateTime(Dates[i]); if (d < DateTime.Now.AddDays(-1)) { var outs = GetOuts(Dates[i]); int v2 = outs.Sum(x => x.OutPut); if (v1 == 0 && v2 == 0) Capacities[i] = ""; else Capacities[i] = v2.ToString(); int v3 = v2 - v1; if (v3 < 0) Differences[i] = Math.Abs(v3).ToString(); else Differences[i] = ""; if (i == 0) AccumulatedDifferences[i] = v3.ToString(); else AccumulatedDifferences[i] = (Convert.ToInt32(AccumulatedDifferences[i - 1]) + v3).ToString(); AccumulatedDifference = Convert.ToInt32(AccumulatedDifferences[i]); } } } private List GetPlanGanttChart(List ts) { int[] values = new int[Dates.Length + 2]; int[] values1 = new int[Dates.Length + 2]; // 生产:1 不生产:0 for (int i = 1; i <= Dates.Length; i++) { int v1 = ts.Where(x => x.ShiftDate == Dates[i - 1]).Sum(x => x.PlanCapacity); values[i] = v1 == 0 ? 0 : 1; values1[i] = v1; } // 平滑过渡周日无排程 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; } } // 循环查找 0-1 或 1-0 变化坐标 List xs = new List(); for (int i = 1; i <= values.Length - 1; i++) { if (values[i] == 1 && values[i - 1] == 0) { for (int j = i; j <= values.Length - 1; j++) { if (values[j] == 0 && values[j - 1] == 1) { Position position = new Position(Dates.Length) { Start = i - 1, End = j - 2, }; for (int k = position.Start; k <= position.End; k++) { position.Values[k] = "1"; position.Value += values1[k + 1]; } position.StartDate = (string)Dates.GetValue(position.Start); position.EndDate = (string)Dates.GetValue(position.End); xs.Add(position); i = j; break; } } } } return xs; } public string MonthTitle { get { return $"{_startDate:MM/dd} ~ {_endDate:MM/dd}"; } } private IEnumerable GetOuts(string date) { 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 IList Plans { get; set; } = new List(); private IList HourOuts { get; set; } = new List(); /// /// 日期 /// public string[] Dates { get; set; } /// /// 日期图表显示 /// public string[] NewDates { get; set; } /// /// 计划产能 /// public string[] PlanCapacities { get; set; } /// /// 差异产能 /// public string[] Differences { get; set; } /// /// 实际产能 /// public string[] Capacities { get; set; } /// /// 机种 /// public string[] ModuleTypes { get; set; } /// /// 累计差异趋势 /// public string[] AccumulatedDifferences { get; set; } /// /// 累计差异 /// public int AccumulatedDifference { get; set; } public IList Series { get; set; } = new List(); } public class Serie { public Serie(int len) { Values = new string[len]; } public string Name { get; set; } = string.Empty; public string[] Values { get; set; } public List Indexs { get; set; } = new List(); public int Start { get; set; } public int End { get; set; } public int PlanCapacities { get; set; } public string StartDate { get; set; } = string.Empty; public string EndDate { get; set; } = string.Empty; } public class Position { public Position(int len) { Values = new string[len]; } public int Start { get; set; } public int End { get; set; } public string[] Values { get; set; } public int Value { get; set; } public string StartDate { get; set; } = string.Empty; public string EndDate { get; set; } = string.Empty; } }