using Model; using StandardLibrary; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; namespace YangjieTester { public class BatchReport { public static string GenerateBatchReport(Batch batch) { StringBuilder sb = new StringBuilder(); sb.AppendLine($"批次开始时间:{batch.StartTime}"); if (!batch.Finished) sb.AppendLine($"批次当前时间:{DateTime.Now}"); else sb.AppendLine($"批次结束时间:{batch.EndTime - batch.StartTime}"); if (!batch.Finished) sb.AppendLine($"开批次时间:{DateTime.Now - batch.StartTime}"); else sb.AppendLine($"开批次时间:{batch.EndTime - batch.StartTime}"); sb.AppendLine($"\t配方:{batch.RecipeName}"); sb.AppendLine($"\t批次:{batch.BatchID}"); sb.AppendLine($"\tMTBA:{PlcDataConvert.FormatDWordSpanToDHMS(batch.MTBA)}"); sb.AppendLine($"\tMTBF:{PlcDataConvert.FormatDWordSpanToDHMS(batch.MTBF)}"); sb.AppendLine($"\tMTTR:{PlcDataConvert.FormatDWordSpanToDHMS(batch.MTTR)}"); sb.AppendLine($"\t正常生产时间:{PlcDataConvert.FormatDWordSpanToDHMS(batch.NormalWorkingTimeSpan)}"); sb.AppendLine($"\tMUBA:{batch.MUBA}"); sb.AppendLine($"\tUPH:{batch.UPH:f2}"); sb.AppendLine($"\t报警次数:{batch.AlarmCount}"); sb.AppendLine($"\t故障时间:{batch.ErrorTimeSpan}"); sb.AppendLine($"\t设备使用率:{batch.WorkingTimeRate:f1}%"); sb.AppendLine($"批次总数量:{batch.TotalNumOfBatch}"); sb.AppendLine($"编带总数量:{batch.TapedNumOfBatch}"); sb.AppendLine("-------------------------------------------------"); /******************************测试结果信息**********************************************/ var testResults = PropertyFinder.FindPropertiesOfType(batch); List rows = new List(); string[] row = new string[] { "项目", "状态", "良率", "时间", "良品", "不良品", "总数量" }; rows.Add(row); foreach (var tr in testResults) { row = new string[] { tr.Name, tr.TestEnable ? "开" : "关", tr.OkRate.ToString("f2") + "%", tr.Time.ToString(), tr.OkNum.ToString(), tr.NgNum.ToString(), tr.TotalNum.ToString() }; rows.Add(row); } sb.AppendLine(FormatTableForMonospace(rows, 12)); sb.AppendLine("-------------------------------------------------"); /******************************Bin盒信息**********************************************/ rows = new List(); row = new string[] { "项目", "数量", "上限", "总数量" }; rows.Add(row); var binBoxNum = PropertyFinder.FindPropertiesOfType(batch); foreach (var bbn in binBoxNum) { row = new string[] { bbn.Name, bbn.Count.ToString(), bbn.UpLimit.ToString(), bbn.TotalCount.ToString() }; rows.Add(row); } sb.AppendLine(FormatTableForMonospace(rows, 12)); sb.AppendLine("------------------报警信息---------------------------"); DateTime endTime; if (!batch.Finished) endTime = DateTime.Now; else endTime = batch.EndTime; var alarmList = AlarmService.GetAlarmsByTimeRange(batch.StartTime, endTime) .Select((item, index) => { item.RowNumber = index + 1; return item; }) .ToList(); //alarmList.Add( new AlarmDisplay(){ Timestamp = DateTime.Now.AddDays(0), AlarmType = "Error", Username = "op1", AlarmMessage = "Alarm01" }); //alarmList.Add(new AlarmDisplay() { Timestamp = DateTime.Now.AddDays(2), AlarmType = "Error", Username = "op1", AlarmMessage = "Alarm02" }); //alarmList.Add(new AlarmDisplay() { Timestamp = DateTime.Now.AddDays(2.1), AlarmType = "Error", Username = "op1", AlarmMessage = "Alarm03" }); //alarmList.Add(new AlarmDisplay() { Timestamp = DateTime.Now.AddDays(1), AlarmType = "Cleared", Username = "op1", AlarmMessage = "Alarm01" }); //alarmList.Add(new AlarmDisplay() { Timestamp = DateTime.Now.AddDays(3), AlarmType = "Cleared", Username = "op1", AlarmMessage = "Alarm02" }); var palms = PairedAlarm.PairAlarms(alarmList); sb.AppendLine($"报警总数:{palms.Count}"); sb.AppendLine("发生时间,结束时间,经过时间,停机类别,报警内容"); foreach (var item in palms) { sb.AppendLine($"{item.StartTime},{item.EndTime},{item.EndTime - item.StartTime},{item.Type},{item.AlarmMessage}"); } return sb.ToString(); } static int GetDisplayWidth(string s) { if (string.IsNullOrEmpty(s)) return 0; int width = 0; foreach (char c in s) { // 常见中文字符范围(包括中文标点) if (char.IsLetterOrDigit(c) || char.IsPunctuation(c) || char.IsSymbol(c)) { // 判断是否为全角字符(通常汉字、中文标点是全角) if (c >= 0x4E00 && c <= 0x9FFF || // CJK Unified Ideographs c >= 0x3000 && c <= 0x303F || // CJK Symbols and Punctuation c >= 0xFF00 && c <= 0xFFEF) // Fullwidth forms { width += 2; } else { width += 1; } } else { width += 1; // 默认按半角处理 } } return width; } static string FormatTableForMonospace(List rows, int columnWidth = 0) { if (rows == null || rows.Count == 0) return ""; int colCount = rows[0].Length; // 计算每列的最大显示宽度(以英文字符位为单位) var maxWidths = new int[colCount]; for (int i = 0; i < colCount; i++) { if (columnWidth > 0) { maxWidths[i] = columnWidth; } else maxWidths[i] = rows.Max(row => GetDisplayWidth(row[i] ?? "")); } var result = new List(); foreach (var row in rows) { var cells = new string[colCount]; for (int i = 0; i < colCount; i++) { string cell = row[i] ?? ""; int padding = maxWidths[i] - GetDisplayWidth(cell); cells[i] = cell + new string(' ', Math.Max(0, padding)); // 左对齐 } result.Add(string.Join(" ", cells)); } return string.Join(Environment.NewLine, result); } } }