using JinYuan.Helper; using JinYuan.MES.Enums; using JinYuan.Models; using JinYuan.VirtualDataLibrary; using Language; using MathNet.Numerics.LinearAlgebra.Factorization; using MiniExcelLibs; using PLCCommunication.Common.DataConvert; using SqlSugar; using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace LargeSquareOne { public partial class FrmHistory : MultiLanguageForm { public static FrmHistory _Form;// 单例模式 public FrmHistory() { InitializeComponent(); this.cmb_SelectType.Items.AddRange(new string[] { "进站".Translated(), "出站".Translated(), "进站失败".Translated(), "出站失败".Translated(), "MES进站断连".Translated(), "产品结果参数".Translated() , "产品结果参数失败".Translated() }); this.cmb_SelectType.SelectedIndex = 0; this.dtp_Start.Value = DateTime.Now.AddHours(-2.0f); this.dtp_End.Value = DateTime.Now; this.cmb_AlarmType.Items.AddRange(new string[] { "全天".Translated(), "白班".Translated(), "夜班".Translated() }); this.cmb_AlarmType.SelectedIndex = 0; this.cmbClass.Items.AddRange(new string[] { "白班".Translated(), "夜班".Translated() }); this.cmbClass.SelectedIndex = 0; _Form = this; } /// /// 查询 /// /// /// private void btn_Query_Click(object sender, EventArgs e) { string str = this.cmb_SelectType.Text; if (string.Compare(str, "进站".Translated()) == 0) { this.cmb_SelectType.SelectedIndex = 0; } else if (string.Compare(str, "出站".Translated()) == 0) { this.cmb_SelectType.SelectedIndex = 1; } string rfid = this.txtBarCodeORRfid.Text.Trim(); string barCode = this.txtSteelShellCode.Text.Trim(); string start = this.dtp_Start.Text; string end = this.dtp_End.Text; int selectType = this.cmb_SelectType.SelectedIndex; Task> task1 = Task.Run(() => { return QueryProcess(selectType, rfid, barCode, start, end); }); var task2 = task1.ContinueWith(task => { this.Invoke(new Action(() => { if (task.Result.IsSuccess) { this.dgv_Main.DataSource = null; this.dgv_Main.DataSource = task.Result.Content; } else { new FrmMsgBoxOutWithAck(2, "查询失败:".Translated() + task.Result.Message, "错误提示".Translated()).Show(); } })); }); } public List queryProcessListB; public List queryProcessListA; /// /// DataTable-->List /// 获取三语切换的DataTable.ColumnName /// /// /// /// public DataTable GetHistoryOutData(int selectType, DataTable dataTable) { string selectTypeStr = ""; //出站数据保存成List switch (selectType) { case 0: case 2: case 4: queryProcessListA = dataTable.ToList(); selectTypeStr = "FrmHistory_dgv_Main_"; break; case 1: case 3: case 5: case 6: queryProcessListB = dataTable.ToList(); selectTypeStr = "FrmHistory_dgv_Main_"; break; case 7: selectTypeStr = "FrmHistory_dgvClass_"; break; case 8: selectTypeStr = "FrmHistory_dgvDays_"; break; case 9: selectTypeStr = "FrmHistory_dgvMonth_"; break; case 10: selectTypeStr = "FrmHistory_dgvWeek_"; break; case 11: selectTypeStr = "FrmHistory_dgv_AlarmData_"; break; } // 自定义获取新列名的方法 钩子函数 Func GetNewColumnName = originalName => { // 这里可以根据具体需求实现自定义逻辑 return LanguageManager.GetString($"{selectTypeStr + originalName}"); ; }; // 使用自定义方法替换列名 dataTable = dataTable.ReplaceColumnNamesWithCustomMethod(GetNewColumnName); return dataTable; } private PLCCommunication.Common.DataConvert.DataResult QueryProcess(int selectType, string rfid, string barCode, string start, string end) { //判断时间 DateTime startTime = Convert.ToDateTime(start); DateTime endTime = Convert.ToDateTime(end); if (startTime > endTime) { return DataResult.CreateFailResult("开始时间不能大于结束时间".Translated()); } TimeSpan timeSpan = endTime - startTime; if (timeSpan.TotalDays > 7.0) { return DataResult.CreateFailResult("查询时间不能超过7天".Translated()); } DataTable dataTable = CommonMethods.db.QueryDataTable(CommonMethods.dBSQL.SelectHostData(selectType, rfid, barCode, start, end)); if (dataTable != null) { dataTable = GetHistoryOutData(selectType, dataTable); return DataResult.CreateSuccessResult(dataTable); } else { return DataResult.CreateFailResult("未能查到数据,请检测".Translated()); } } private void btn_ExPort_Click(object sender, EventArgs e) { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "XLSX文件(*.xlsx)|*.xlsx|所有文件|*.*"; saveFileDialog.Title = "导出历史数据"; saveFileDialog.FileName = "历史数据".Translated() + DateTime.Now.ToString("yyyyMMddHHmmss"); saveFileDialog.DefaultExt = "xlsx"; saveFileDialog.AddExtension = true; if (saveFileDialog.ShowDialog() == DialogResult.OK) { MiniExcel.SaveAs(saveFileDialog.FileName, this.dgv_Main.DataSource); if (new FrmMsgBoxWithAck("导出报表成功,是否立即打开?".Translated(), "打开报表记录".Translated()).ShowDialog() == DialogResult.OK) { Process.Start(saveFileDialog.FileName); } else { new FrmMsgBoxOutWithAck(2, "导出报表失败".Translated(), "数据报表导出".Translated()).ShowDialog(); } } } /// /// 显示序列号 /// /// /// private void dgv_Main_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) { DataGridViewHelper.DgvRowPostPaint((DataGridView)sender, e); } /// /// 给DataGridView绘制边框 /// /// /// private void dgv_Main_Paint(object sender, PaintEventArgs e) { DataGridViewHelper.DgvRowPaint((DataGridView)sender, e, Color.FromArgb(1, 146, 235)); } /// /// /// /// /// private void dgv_Main_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (e.RowIndex != -1 && e.ColumnIndex >= 5) { object value = this.dgv_Main.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; if (value == null || value?.ToString().Length == 0) { e.Value = "--"; } } } #region 减少闪烁 protected override CreateParams CreateParams { get { CreateParams parss = base.CreateParams; parss.ExStyle |= 0x02000000; return parss; } } #endregion #region 统计查询 /// /// 班次 /// private DataTable dtClasses = null; /// /// 日 /// private DataTable dtDays = null; /// /// 周 /// private DataTable dtWeeks = null; /// /// 月 /// private DataTable dtMonths = null; #region 1、按班次查询 /// /// 按班次查询 /// /// /// private void btn_ClassQuery_Click(object sender, EventArgs e) { dtClasses = null; DateTime strDate = dtClass.Value; int strClass = cmbClass.SelectedIndex; dtClasses = CommonMethods.db.QueryDataTable(CommonMethods.dBSQL.GetStaticByShift(strDate, strClass, CommonMethods.ChangeClassTime)); //if (dtClasses != null)//&& dtClasses.Rows.Count > 0 //{ // this.dgvClass.DataSource = null; // this.dgvClass.DataSource = dtClasses; //} if (dtClasses != null) { dtClasses = GetHistoryOutData(7, dtClasses); this.dgvClass.DataSource = null; this.dgvClass.DataSource = dtClasses; } } /// /// 按班次导出 /// /// /// private void btn_ClassExPort_Click(object sender, EventArgs e) { if (dgvClass.Columns.Count <= 0) { MessageBox.Show("导出失败,无查询结果"); return; } SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.FileName = $"产能统计_按班次统计_{DateTime.Now.ToString("yyyyMMddHHmmss")}"; saveFileDialog.Filter = "*|*.csv"; if (saveFileDialog.ShowDialog() == DialogResult.Cancel) return; string msg = ""; if (CSVHelper.ExportDataTableToCSV(dtClasses, saveFileDialog.FileName, out msg)) { MessageBox.Show("导出成功!"); } } #endregion # region 2、按日查询 /// /// 按日查询 /// /// /// private void btn_DaysQuery_Click(object sender, EventArgs e) { dtDays = null; string startDateTime = dtpDays.Value.ToString("yyyy-MM-dd 00:00:00"); string endDateTime = dtpDays.Value.ToString("yyyy-MM-dd 23:59:59"); dtDays = CommonMethods.db.QueryDataTable(CommonMethods.dBSQL.GetStaticByDay(startDateTime, endDateTime)); //if (dtDays != null )//&& dtDays.Rows.Count > 0 //{ // this.dgvDays.DataSource = null; // this.dgvDays.DataSource = dtDays; //} if (dtDays != null) { dtDays = GetHistoryOutData(8, dtDays); this.dgvDays.DataSource = null; this.dgvDays.DataSource = dtDays; } } /// /// 按日导出 /// /// /// private void btn_DaysExPort_Click(object sender, EventArgs e) { if (dgvDays.Columns.Count <= 0) { MessageBox.Show("导出失败,无查询结果"); return; } SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.FileName = $"产能统计_按日统计_{DateTime.Now.ToString("yyyyMMddHHmmss")}"; saveFileDialog.Filter = "*|*.csv"; if (saveFileDialog.ShowDialog() == DialogResult.Cancel) return; string msg = ""; if (CSVHelper.ExportDataTableToCSV(dtDays, saveFileDialog.FileName, out msg)) { MessageBox.Show("导出成功!"); } } #endregion #region 3、按周查询 /// /// 按周查询 /// /// /// private void btn_WeekQuery_Click(object sender, EventArgs e) { dtWeeks = null; //确定星期几 var index = (int)dtpWeek.Value.DayOfWeek; index = index == 0 ? 7 : index; //当前周的范围 string retStartDay = dtpWeek.Value.AddDays(-(index - 1)).ToString(); string retEndDay = dtpWeek.Value.AddDays(7 - index).ToString(); dtWeeks = CommonMethods.db.QueryDataTable(CommonMethods.dBSQL.GetStaticByWeek(retStartDay, retEndDay)); //if (dtWeeks != null)//&& dtWeeks.Rows.Count > 0 //{ // this.dgvWeek.DataSource = null; // this.dgvWeek.DataSource = dtWeeks; //} if (dtWeeks != null) { dtWeeks = GetHistoryOutData(10, dtWeeks); this.dgvWeek.DataSource = null; this.dgvWeek.DataSource = dtWeeks; } } /// /// 按周导出 /// /// /// private void btn_WeekExPort_Click(object sender, EventArgs e) { if (dgvWeek.Columns.Count <= 0) { MessageBox.Show("导出失败,无查询结果"); return; } SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.FileName = $"产能统计_按周统计_{DateTime.Now.ToString("yyyyMMddHHmmss")}"; saveFileDialog.Filter = "*|*.csv"; if (saveFileDialog.ShowDialog() == DialogResult.Cancel) return; string msg = ""; if (CSVHelper.ExportDataTableToCSV(dtWeeks, saveFileDialog.FileName, out msg)) { MessageBox.Show("导出成功!"); } } #endregion #region 4、按月查询 /// /// 按月查询 /// /// /// private void btn_MonthQuery_Click(object sender, EventArgs e) { dtMonths = null; string startDateTime = dtMonth.Value.ToString("yyyy-MM-01 00:00:00"); string endDateTime = new DateTime(dtMonth.Value.Year, dtMonth.Value.Month, DateTime.DaysInMonth(dtMonth.Value.Year, dtMonth.Value.Month)).ToString("yyyy-MM-dd 23:59:59");//通过指定日期计算当月最后一天 dtMonths = CommonMethods.db.QueryDataTable(CommonMethods.dBSQL.GetStaticByMonth(startDateTime, endDateTime)); //if (dtMonths != null)// && dtMonths.Rows.Count > 0 //{ // this.dgvMonth.DataSource = null; // this.dgvMonth.DataSource = dtMonths; //} if (dtMonths != null) { dtMonths = GetHistoryOutData(9, dtMonths); this.dgvMonth.DataSource = null; this.dgvMonth.DataSource = dtMonths; } } /// /// 按月导出 /// /// /// private void btn_MonthExPort_Click(object sender, EventArgs e) { if (dgvMonth.Columns.Count <= 0) { MessageBox.Show("导出失败,无查询结果"); return; } SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.FileName = $"产能统计_按月统计_{DateTime.Now.ToString("yyyyMMddHHmmss")}"; saveFileDialog.Filter = "*|*.csv"; if (saveFileDialog.ShowDialog() == DialogResult.Cancel) return; string msg = ""; if (CSVHelper.ExportDataTableToCSV(dtMonths, saveFileDialog.FileName, out msg)) { MessageBox.Show("导出成功!"); } } #endregion #endregion /// /// 选择班次时间变更 /// /// /// private void cmb_AlarmType_SelectedIndexChanged(object sender, EventArgs e) { if (cmb_AlarmType.SelectedIndex == 1) //白班 { DateTime baiClassStart = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 8:30:00")); DateTime baiClassEnd = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 20:29:59")); dtp_AlarmTimeStart.Value = baiClassStart; dtp_AlarmTimeEnd.Value = baiClassEnd; } else if (cmb_AlarmType.SelectedIndex == 2) //夜班 { DateTime yeClassStart = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 20:30:00")); DateTime yeClassEnd = Convert.ToDateTime(DateTime.Now.AddDays(1).ToString("yyyy-MM-dd 8:29:59")); dtp_AlarmTimeStart.Value = yeClassStart; dtp_AlarmTimeEnd.Value = yeClassEnd; } else { DateTime baiClassStart = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:00:00")); DateTime baiClassEnd = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 23:59:59")); dtp_AlarmTimeStart.Value = baiClassStart; dtp_AlarmTimeEnd.Value = baiClassEnd; } } #region 报警查询 /// /// 查询数据 /// /// /// /// /// private DataResult QueryProcess(string start, string end, int alarmType) { DateTime startDateTime = Convert.ToDateTime(start); DateTime endDateTime = Convert.ToDateTime(end); if (startDateTime >= endDateTime) { return DataResult.CreateFailResult("开始时间不能大于结束时间".Translated()); } TimeSpan timeSpan = endDateTime - startDateTime; if (timeSpan.TotalDays > 1.0) { return DataResult.CreateFailResult("查询范围不能超过1天".Translated()); } DataTable dataTable = CommonMethods.db.QueryDataTable(CommonMethods.dBSQL.SelectHostAlarmData(start, end, alarmType)); if (dataTable != null) { dataTable = GetHistoryOutData(11, dataTable); return DataResult.CreateSuccessResult(dataTable); } else { return DataResult.CreateFailResult("未能查到数据,请检测".Translated()); } } /// /// 报警信息查询 /// /// /// private void btn_AlarmQuery_Click(object sender, EventArgs e) { string start = this.dtp_AlarmTimeStart.Text; string end = this.dtp_AlarmTimeEnd.Text; int alarmType = this.cmb_AlarmType.SelectedIndex; Task> task1 = Task.Run(() => { return QueryProcess(start, end, alarmType); }); var task2 = task1.ContinueWith(task => { this.Invoke(new Action(() => { if (task.Result.IsSuccess) { this.dgv_AlarmData.DataSource = null; this.dgv_AlarmData.DataSource = task.Result.Content; } else { new FrmMsgBoxOutWithAck(2, "查询失败:".Translated() + task.Result.Message, "报警查询".Translated()).Show(); } })); }); } /// /// 报警信息导出 /// /// /// private void btn_AlarmExport_Click(object sender, EventArgs e) { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "XLSX文件(*.xlsx)|*.xlsx|所有文件|*.*"; saveFileDialog.Title = "导出历史报警"; saveFileDialog.FileName = "历史报警".Translated() + DateTime.Now.ToString("yyyyMMddHHmmss"); saveFileDialog.DefaultExt = "xlsx"; saveFileDialog.AddExtension = true; if (saveFileDialog.ShowDialog() == DialogResult.OK) { MiniExcel.SaveAs(saveFileDialog.FileName, this.dgv_AlarmData.DataSource); if (new FrmMsgBoxWithAck("导出报警成功,是否立即打开?".Translated(), "打开报警记录".Translated()).ShowDialog() == DialogResult.OK) { Process.Start(saveFileDialog.FileName); } } } private void dgv_AlarmData_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) { DataGridViewHelper.DgvRowPostPaint((DataGridView)sender, e); } #endregion #region 进出站补传Mes /// /// 进出站补传Mes /// private async void btn_ReUpMes_Click(object sender, EventArgs e) { this.btn_ReUpMes.Text = "补传中……".Translated(); this.btn_ReUpMes.Enabled = false; try { if (!CommonMethods.sysConfig.MesModeSwitching || !CommonMethods.mesConfig.isConnected) { new FrmMsgBoxOutWithAck(2, "请先开启MES模式并登陆MES", "提示").Show(); return; } var checkRows = new List(); foreach (DataGridViewRow row in dgv_Main.SelectedRows) { if (row.IsNewRow) continue; checkRows.Add(row); } if (checkRows.Count == 0) { new FrmMsgBoxOutWithAck(2, "请先勾选需要补传的数据行", "提示").Show(); return; } int selectedIndex = 0; this.Invoke(new Action(() => { selectedIndex = cmb_SelectType.SelectedIndex; })); switch (selectedIndex) { case 0: await ReUpInStationAsync(checkRows); break; case 1: await ReUpOutStationAsync(checkRows); break; case 2: await ReUpInStationAsync(checkRows); break; case 3: await ReUpOutStationAsync(checkRows); break; case 5: await ReUpProducResultParam(checkRows); break; case 6: await ReUpProducResultParam(checkRows); break; default: break; } } catch (Exception ex) { LogHelper.Instance.WriteError($"补传操作异常->[{ex.Message}]"); new FrmMsgBoxOutWithAck(2, $"补传操作异常:{ex.Message}", "错误").Show(); } finally { this.btn_ReUpMes.Text = "补传".Translated(); this.btn_ReUpMes.Enabled = true; } } /// /// 安全获取单元格值,防止空值报错 /// private string GetSafeValue(DataGridViewCell cell) { if (cell == null || cell.Value == null || cell.Value == DBNull.Value) return ""; return cell.Value.ToString().Trim(); } /// /// 补传进站 /// private async Task ReUpInStationAsync(List checkRows) { int successCount = 0; int failCount = 0; int skipCount = 0; var errorMsg = new StringBuilder(); int total = checkRows.Count; int processed = 0; // 1. 收集条码 var barCodes = checkRows .Select(row => GetSafeValue(row.Cells["钢壳码"])) .Where(code => !string.IsNullOrEmpty(code)) .ToList(); if (barCodes.Count == 0) { new FrmMsgBoxOutWithAck(2, "没有有效的钢壳码数据", "提示").Show(); return; } // 3. 分批处理 int batchSize = 100; var successList = new List(); var failList = new List(); var processedCount = 0; var failDetails = new List(); for (int i = 0; i < checkRows.Count; i += batchSize) { var batch = checkRows.Skip(i).Take(batchSize).ToList(); foreach (var row in batch) { processedCount++; try { string barCode = GetSafeValue(row.Cells["钢壳码"]); if (string.IsNullOrEmpty(barCode)) { failCount++; failDetails.Add($"条码为空,跳过处理"); continue; } // 检查是否已上传(Flag == "1" 表示已上传) if (row.Cells["是否上传状态"].Value.ToString() == "True") { skipCount++; continue; } AGearEntity entity = new AGearEntity () { BarCode = barCode, Remark = GetSafeValue(row.Cells["备注"]) }; // 调用MES接口 var (success, message, mesResType) = await CommonMethods.hbgMes.ManyCellInStationAsync( CommonMethods.mesConfig.ProductInStation, CommonMethods.mesConfig.siteCode, CommonMethods.mesConfig.lineCode, CommonMethods.mesConfig.equipNum, CommonMethods.mesConfig.MaterialCode, CommonMethods.mesConfig.mesUserName, new List { barCode }); if (success) { entity.Flag = "1"; entity.Remark += ";补传成功"; successList.Add(entity); row.Cells["上传状态"].Value = "1"; successCount++; } else { entity.Flag = "2"; entity.Remark = message?.FirstOrDefault() ?? "MES接口返回失败"; failList.Add(entity); failCount++; errorMsg.AppendLine($"条码【{barCode}】: {message?.FirstOrDefault() ?? "未知错误"}"); } } catch (Exception ex) { LogHelper.Instance.WriteError($"补传MES数据出错->[{ex.Message}]", "补传日志"); failCount++; errorMsg.AppendLine($"条码【{GetSafeValue(row.Cells["钢壳码"])}】: {ex.Message}"); } // 更新进度 if (processed % 5 == 0 || processed == total) { this.Invoke(new Action(() => { this.btn_ReUpMes.Text = $"补传进站中…… {processed}/{total}"; })); } } // 每批处理后更新数据库 try { if (successList.Any()) { await CommonMethods.db.Updateable(successList.ToList()) .UpdateColumns(it => new { it.Flag, it.Remark }) .WhereColumns(it => new { it.BarCode }) .ExecuteCommandAsync(); successList.Clear(); } if (failList.Any()) { await CommonMethods.db.Updateable(failList.ToList()) .UpdateColumns(it => new { it.Flag, it.Remark }) .WhereColumns(it => new { it.BarCode }) .ExecuteCommandAsync(); failList.Clear(); } } catch (Exception ex) { LogHelper.Instance.WriteError($"批量更新数据库失败->[{ex.Message}]", "补传日志"); } } // 显示结果 string result = $"补传完成!成功{successCount}条,失败{failCount}条,已跳过{skipCount}条;"; if (errorMsg.Length > 0) { result += Environment.NewLine + "失败详情:" + errorMsg.ToString().TrimEnd(); } new FrmMsgBoxOutWithAck(failCount == 0 ? 1 : 2, result, failCount == 0 ? "补传成功" : "补传完成(含失败)").Show(); LogHelper.Instance.WriteLog($"补传进站结束,详情:{result}", "补传日志"); } /// /// 补传出站 /// private async Task ReUpOutStationAsync(List checkRows) { int successCount = 0; int failCount = 0; int skipCount = 0; var errorMsg = new StringBuilder(); int total = checkRows.Count; int processed = 0; // 1. 收集条码 var barCodes = checkRows .Select(row => GetSafeValue(row.Cells["钢壳码"])) .Where(code => !string.IsNullOrEmpty(code) && code != "NG" && code != "ERROR") .ToList(); if (barCodes.Count == 0) { new FrmMsgBoxOutWithAck(2, "没有有效的钢壳码数据", "提示").Show(); return; } // 3. 准备批量更新的数据 var updateList = new List(); var failDetails = new List(); foreach (var row in checkRows) { processed++; try { string barCode = GetSafeValue(row.Cells["钢壳码"]); if (string.IsNullOrEmpty(barCode) || barCode == "NG" || barCode == "ERROR") { failCount++; failDetails.Add($"条码为空,跳过处理"); continue; } BGearEntity entity = new BGearEntity(); // 检查是否已上传(Flag == "1" 表示已上传) if (row.Cells["出站是否上传MES"].Value.ToString() == "True") { skipCount++; continue; } // 更新实体中的其他字段 entity.ChannelNo = GetSafeValue(row.Cells["通道"]); entity.TestTime = GetSafeValue(row.Cells["时间"]); entity.RFID = GetSafeValue(row.Cells["托杯码"]); entity.BarCode = barCode; entity.JetCode = GetSafeValue(row.Cells["喷码"]); entity.Result = GetSafeValue(row.Cells["综合结果"]); entity.Remark = GetSafeValue(row.Cells["备注"]); entity.WindSpeed = GetSafeValue(row.Cells["除尘风速"]); entity.BarCodeLength = GetSafeValue(row.Cells["电芯码长度"]); entity.BarCodeWidth = GetSafeValue(row.Cells["电芯码宽度"]); entity.GBCodeBottomToCoverPlateHeight = GetSafeValue(row.Cells["GB码底部距盖板高度"]); entity.InsulationFilmToBottemHeight1 = GetSafeValue(row.Cells["绝缘膜距底部高度1"]); entity.InsulationFilmToBottemHeight2 = GetSafeValue(row.Cells["绝缘膜距底部高度2"]); entity.InsulationFilmToBottemHeight3 = GetSafeValue(row.Cells["绝缘膜距底部高度3"]); entity.InsulationFilmToBottemHeight4 = GetSafeValue(row.Cells["绝缘膜距底部高度4"]); entity.InsulationFilmToBottemHeight5 = GetSafeValue(row.Cells["包膜对齐度1"]); entity.InsulationFilmToBottemHeight6 = GetSafeValue(row.Cells["包膜对齐度2"]); entity.Station = GetSafeValue(row.Cells["工位"]); entity.stationA1 = GetSafeValue(row.Cells["滚标位"]); entity.CCDAfterCoatedApperanceTestResult = GetSafeValue(row.Cells["贴膜后外观检测结果"]); entity.CCDAfterCoatedApperanceTestReson = GetSafeValue(row.Cells["贴膜后外观NG原因"]); entity.CCDAfterCoatedAlignmentTestResult = GetSafeValue(row.Cells["包膜后对齐度检测结果"]); entity.TOPiameter = GetSafeValue(row.Cells["顶部直径"]); entity.MidDiameter = GetSafeValue(row.Cells["中间直径"]); entity.LOWiameter = GetSafeValue(row.Cells["底部直径"]); entity.ShuttleActuator = GetSafeValue(row.Cells["穿梭动子"]); entity.Info = GetSafeValue(row.Cells["NG详情"]); // 调用MES接口 var (success, message, mesResType) = await CommonMethods.hbgMes.ManyCellOutStationAsync( CommonMethods.mesConfig.ProductOutStation, CommonMethods.mesConfig.siteCode, CommonMethods.mesConfig.lineCode, CommonMethods.mesConfig.equipNum, CommonMethods.mesConfig.MaterialCode, CommonMethods.mesConfig.ModelName, CommonMethods.mesConfig.mesUserName, new List { entity }, // 使用完整实体 1, CommonMethods.mesConfig.materialLotCodeLocator); if (success) { entity.Flag = "1"; entity.Remark += ";补传成功"; updateList.Add(entity); row.Cells["出站是否上传MES"].Value = "1"; successCount++; LogHelper.Instance.WriteLog($"补传出站成功,条码:{barCode}", "补传日志"); } else { entity.Flag = "2"; string errorDetail = message?.FirstOrDefault() ?? "MES接口返回失败"; entity.Remark = !string.IsNullOrEmpty(entity.Remark) ? $"{entity.Remark}; MES失败:{errorDetail}" : $"MES失败:{errorDetail}"; updateList.Add(entity); failDetails.Add($"钢壳码【{barCode}】: {errorDetail}"); failCount++; LogHelper.Instance.WriteError($"补传出站失败,钢壳码:{barCode},原因:{errorDetail}", "补传日志"); } // 更新进度 if (processed % 5 == 0 || processed == total) { this.Invoke(new Action(() => { this.btn_ReUpMes.Text = $"补传出站中…… {processed}/{total}"; })); } } catch (Exception ex) { LogHelper.Instance.WriteError($"补传出站出错->[{ex.Message}]", "补传日志"); failCount++; failDetails.Add($"钢壳码【{GetSafeValue(row.Cells["钢壳码"])}】: {ex.Message}"); } } // 4. 批量更新数据库 if (updateList.Any()) { try { await CommonMethods.db.Updateable(updateList) .UpdateColumns(it => new { it.Flag, it.Remark }) .WhereColumns(it => new { it.BarCode }) .ExecuteCommandAsync(); LogHelper.Instance.WriteLog($"补传出站批量更新成功,共{updateList.Count}条", "补传日志"); } catch (Exception ex) { LogHelper.Instance.WriteError($"补传出站批量更新数据库失败->[{ex.Message}]", "补传日志"); new FrmMsgBoxOutWithAck(2, $"数据库更新失败:{ex.Message}", "错误").Show(); return; } } // 5. 显示结果 string result = $"补传出站完成!成功{successCount}条,失败{failCount}条,已跳过{skipCount}条;"; if (failDetails.Any()) { result += Environment.NewLine + "失败详情:" + string.Join("; ", failDetails.Take(5)); if (failDetails.Count > 5) result += $"... 共{failDetails.Count}条失败"; } new FrmMsgBoxOutWithAck(failCount == 0 ? 1 : 2, result, failCount == 0 ? "补传出站成功" : "补传出站完成(含失败)").Show(); LogHelper.Instance.WriteError($"补传出站结束,详情:{result}", "补传日志"); } /// /// 补传结果参数 /// private async Task ReUpProducResultParam(List checkRows) { int successCount = 0; int failCount = 0; int skipCount = 0; var errorMsg = new StringBuilder(); int total = checkRows.Count; int processed = 0; // 1. 收集条码(排除 NG 和 ERROR) var barCodes = checkRows .Select(row => GetSafeValue(row.Cells["钢壳码"])) .Where(code => !string.IsNullOrEmpty(code) && code != "NG" && code != "ERROR") .ToList(); if (barCodes.Count == 0) { new FrmMsgBoxOutWithAck(2, "没有有效的钢壳码数据(NG/ERROR已被排除)", "提示").Show(); return; } // 3. 准备批量更新的数据 var updateList = new List(); var failDetails = new List(); string dateStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); foreach (var row in checkRows) { processed++; try { string barCode = GetSafeValue(row.Cells["钢壳码"]); if (string.IsNullOrEmpty(barCode) || barCode == "NG" || barCode == "ERROR") { if (barCode == "NG" || barCode == "ERROR") { skipCount++; } continue; } BGearEntity entity = new BGearEntity(); // 检查是否已上传(Flag1 == "1" 表示已上传) if (row.Cells["是否上传MES"].Value.ToString() == "True") { skipCount++; continue; } // 更新实体中的其他字段 entity.ChannelNo = GetSafeValue(row.Cells["通道"]); entity.TestTime = GetSafeValue(row.Cells["时间"]); entity.BarCode = barCode; entity.Result = GetSafeValue(row.Cells["综合结果"]); entity.BarCodeLength = GetSafeValue(row.Cells["电芯码长度"]); entity.BarCodeWidth = GetSafeValue(row.Cells["电芯码宽度"]); entity.GBCodeBottomToCoverPlateHeight = GetSafeValue(row.Cells["GB码底部距盖板高度"]); entity.InsulationFilmToBottemHeight1 = GetSafeValue(row.Cells["绝缘膜距底部高度1"]); entity.InsulationFilmToBottemHeight2 = GetSafeValue(row.Cells["绝缘膜距底部高度2"]); entity.InsulationFilmToBottemHeight3 = GetSafeValue(row.Cells["绝缘膜距底部高度3"]); entity.InsulationFilmToBottemHeight4 = GetSafeValue(row.Cells["绝缘膜距底部高度4"]); entity.InsulationFilmToBottemHeight5 = GetSafeValue(row.Cells["包膜对齐度1"]); entity.InsulationFilmToBottemHeight6 = GetSafeValue(row.Cells["包膜对齐度2"]); entity.Station = GetSafeValue(row.Cells["工位"]); entity.stationA1 = GetSafeValue(row.Cells["滚标位"]); entity.CCDAfterCoatedApperanceTestResult = GetSafeValue(row.Cells["贴膜后外观检测结果"]); entity.CCDAfterCoatedApperanceTestReson = GetSafeValue(row.Cells["贴膜后外观NG原因"]); entity.TOPiameter = GetSafeValue(row.Cells["顶部直径"]); entity.MidDiameter = GetSafeValue(row.Cells["中间直径"]); entity.LOWiameter = GetSafeValue(row.Cells["底部直径"]); entity.ShuttleActuator = GetSafeValue(row.Cells["穿梭动子"]); // 调用MES接口 var (success, message) = await CommonMethods.hbgMes.ProducResultParamAsync( CommonMethods.mesConfig.ProductResultParams, CommonMethods.mesConfig.siteCode, CommonMethods.mesConfig.lineCode, CommonMethods.mesConfig.equipNum, CommonMethods.mesConfig.MaterialCode, CommonMethods.mesConfig.mesUserName, entity, MesUploadType.DD); if (success) { entity.Flag1 = "1"; entity.Remark += ";结果参数补传成功"; updateList.Add(entity); row.Cells["是否上传MES"].Value = "1"; successCount++; LogHelper.Instance.WriteLog($"补传结果参数成功,条码:{barCode}", "补传日志"); } else { entity.Flag1 = "2"; string errorDetail = message ?? "MES接口返回失败"; entity.Remark = !string.IsNullOrEmpty(entity.Remark) ? $"{entity.Remark}; MES失败:{errorDetail}" : $"MES失败:{errorDetail}"; updateList.Add(entity); failDetails.Add($"钢壳码【{barCode}】: {errorDetail}"); failCount++; LogHelper.Instance.WriteError($"补传结果参数失败,条码:{barCode},原因:{errorDetail}", "补传日志"); CommonMethods.AddDataMonitorLog(1, $"Code: {barCode}, 补传结果数据上传失败"); } // 更新进度 if (processed % 5 == 0 || processed == total) { this.Invoke(new Action(() => { this.btn_ReUpMes.Text = $"补传结果参数中…… {processed}/{total}"; })); } } catch (Exception ex) { LogHelper.Instance.WriteError($"补传结果参数出错->[{ex.Message}],条码:{GetSafeValue(row.Cells["钢壳码"])}", "补传日志"); failCount++; failDetails.Add($"钢壳码【{GetSafeValue(row.Cells["钢壳码"])}】: {ex.Message}"); } } // 4. 批量更新数据库 if (updateList.Any()) { try { await CommonMethods.db.Updateable(updateList) .UpdateColumns(it => new { it.Flag1, it.Remark }) .WhereColumns(it => new { it.BarCode }) .ExecuteCommandAsync(); LogHelper.Instance.WriteLog($"补传结果参数批量更新成功,共{updateList.Count}条", "补传日志"); } catch (Exception ex) { LogHelper.Instance.WriteError($"补传结果参数批量更新数据库失败->[{ex.Message}]", "补传日志"); new FrmMsgBoxOutWithAck(2, $"数据库更新失败:{ex.Message}", "错误").Show(); return; } } // 5. 显示结果 string result = $"补传结果参数完成!成功{successCount}条,失败{failCount}条,已跳过{skipCount}条;"; if (failDetails.Any()) { result += Environment.NewLine + "失败详情:" + string.Join("; ", failDetails.Take(5)); if (failDetails.Count > 5) result += $"... 共{failDetails.Count}条失败"; } new FrmMsgBoxOutWithAck(failCount == 0 ? 1 : 2, result, failCount == 0 ? "补传结果参数成功" : "补传结果参数完成(含失败)").Show(); LogHelper.Instance.WriteError($"补传结果参数结束,详情:{result}", "补传日志"); } /// /// 更新数据库字段值 /// /// private async void UpdateIsUpMES(int type, string flag, string result, string remark, string barcode) { switch (type) { case 0://结果,备注,进站是否上传MES AGearEntity m = new AGearEntity { BarCode = barcode, Flag = flag, Result = result, Remark = remark, }; int a = await CommonMethods.db.UpdateSingleAsync(m, it => new AGearEntity() { Flag = m.Flag, Result = m.Result, Remark = m.Remark }, it => it.BarCode == m.BarCode); break; case 1://结果,备注,出站是否上传MES BGearEntity m1 = new BGearEntity { BarCode = barcode, Flag = flag, Result = result, Remark = remark, }; int b = await CommonMethods.db.UpdateSingleAsync(m1, it => new BGearEntity() { Flag = m1.Flag, Result = m1.Result, Remark = m1.Remark }, it => it.BarCode == m1.BarCode); break; default: break; } } #region 创建空的数组List public List GetList(int num, T data) { List list = new List(); for (int i = 0; i < num; i++) { list.Add(data); } return list; } public List GetMesType(int Num) { List mesResTypes = new List(); for (int i = 0; i < Num; i++) { mesResTypes.Add(MesResType.B); } return mesResTypes; } #endregion #region 数据组合 private bool GetDataCombine(BGearEntity m, MesResType mesResType, string mesMesage, ref short res, ref string result, ref string remark, ref string flag) { #region 数据组合 // 本地判断OK,MES判断OK if (result == "OK" && mesResType == MesResType.D) { result += ",MES OK"; m.Info = "良品".Translated(); res = 1; } // 本地判断OK,MES判断NG else if (result == "OK" && mesResType != MesResType.D) { switch (mesResType) { case MesResType.A: // 停线,设备报警停机 result += ",MES NG"; remark += $"A,{mesMesage}"; res = 3;//10 break; case MesResType.B: // MES不良 result += ",MES NG"; remark += $"B,{mesMesage}"; res = 3;//9 break; case MesResType.C: // 警示 result += ",MES OK"; // MES认为是可以当成良品流下去的 remark += $"Alarm:{mesMesage}"; res = 1; break; case MesResType.D: // 条码上传OK result += ",MES OK"; remark += $"D,{mesMesage}"; res = 1; break; default: result += ",MES NG"; remark += $"{mesMesage}"; res = 3;//9 break; } } // 本地判断NG,MES判断OK else if (result == "NG" && mesResType == MesResType.D) { result += ",MES OK"; remark += $"D,{mesMesage}"; res = 1; } // 本地判断NG,MES判断NG else if (result == "NG" && mesResType != MesResType.D) { result += ",MES NG"; remark += $"{mesResType.ToString()},{mesMesage}"; res = 3;//9 } // 其他情况 else { result += ",MES NG"; remark += mesMesage; res = 3;//9 } #endregion return true; } #endregion #endregion } }