Files
RollMarking/LargeSquareOne/FrmHistory.cs
T
2026-09-07 08:07:08 +08:00

1308 lines
52 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
/// <summary>
/// 查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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<DataResult<DataTable>> 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<BGearEntity> queryProcessListB;
public List<AGearEntity> queryProcessListA;
/// <summary>
/// DataTable-->List
/// 获取三语切换的DataTable.ColumnName
/// </summary>
/// <param name="selectType"></param>
/// <param name="dataTable"></param>
/// <returns></returns>
public DataTable GetHistoryOutData(int selectType, DataTable dataTable)
{
string selectTypeStr = "";
//出站数据保存成List
switch (selectType)
{
case 0:
case 2:
case 4:
queryProcessListA = dataTable.ToList<AGearEntity>();
selectTypeStr = "FrmHistory_dgv_Main_";
break;
case 1:
case 3:
case 5:
case 6:
queryProcessListB = dataTable.ToList<BGearEntity>();
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<string, string> GetNewColumnName = originalName =>
{
// 这里可以根据具体需求实现自定义逻辑
return LanguageManager.GetString($"{selectTypeStr + originalName}"); ;
};
// 使用自定义方法替换列名
dataTable = dataTable.ReplaceColumnNamesWithCustomMethod(GetNewColumnName);
return dataTable;
}
private PLCCommunication.Common.DataConvert.DataResult<DataTable> 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<DataTable>("开始时间不能大于结束时间".Translated());
}
TimeSpan timeSpan = endTime - startTime;
if (timeSpan.TotalDays > 7.0)
{
return DataResult.CreateFailResult<DataTable>("查询时间不能超过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>(dataTable);
}
else
{
return DataResult.CreateFailResult<DataTable>("未能查到数据,请检测".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();
}
}
}
/// <summary>
/// 显示序列号
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dgv_Main_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
DataGridViewHelper.DgvRowPostPaint((DataGridView)sender, e);
}
/// <summary>
/// 给DataGridView绘制边框
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dgv_Main_Paint(object sender, PaintEventArgs e)
{
DataGridViewHelper.DgvRowPaint((DataGridView)sender, e, Color.FromArgb(1, 146, 235));
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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 统计查询
/// <summary>
/// 班次
/// </summary>
private DataTable dtClasses = null;
/// <summary>
/// 日
/// </summary>
private DataTable dtDays = null;
/// <summary>
/// 周
/// </summary>
private DataTable dtWeeks = null;
/// <summary>
/// 月
/// </summary>
private DataTable dtMonths = null;
#region 1、按班次查询
/// <summary>
/// 按班次查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
}
}
/// <summary>
/// 按班次导出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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<object>.ExportDataTableToCSV(dtClasses, saveFileDialog.FileName, out msg))
{
MessageBox.Show("导出成功!");
}
}
#endregion
# region 2、按日查询
/// <summary>
/// 按日查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
}
}
/// <summary>
/// 按日导出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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<object>.ExportDataTableToCSV(dtDays, saveFileDialog.FileName, out msg))
{
MessageBox.Show("导出成功!");
}
}
#endregion
#region 3、按周查询
/// <summary>
/// 按周查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
}
}
/// <summary>
/// 按周导出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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<object>.ExportDataTableToCSV(dtWeeks, saveFileDialog.FileName, out msg))
{
MessageBox.Show("导出成功!");
}
}
#endregion
#region 4、按月查询
/// <summary>
/// 按月查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
}
}
/// <summary>
/// 按月导出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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<object>.ExportDataTableToCSV(dtMonths, saveFileDialog.FileName, out msg))
{
MessageBox.Show("导出成功!");
}
}
#endregion
#endregion
/// <summary>
/// 选择班次时间变更
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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 报警查询
/// <summary>
/// 查询数据
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <param name="alarmType"></param>
/// <returns></returns>
private DataResult<DataTable> QueryProcess(string start, string end, int alarmType)
{
DateTime startDateTime = Convert.ToDateTime(start);
DateTime endDateTime = Convert.ToDateTime(end);
if (startDateTime >= endDateTime)
{
return DataResult.CreateFailResult<DataTable>("开始时间不能大于结束时间".Translated());
}
TimeSpan timeSpan = endDateTime - startDateTime;
if (timeSpan.TotalDays > 1.0)
{
return DataResult.CreateFailResult<DataTable>("查询范围不能超过1天".Translated());
}
DataTable dataTable = CommonMethods.db.QueryDataTable(CommonMethods.dBSQL.SelectHostAlarmData(start, end, alarmType));
if (dataTable != null)
{
dataTable = GetHistoryOutData(11, dataTable);
return DataResult.CreateSuccessResult<DataTable>(dataTable);
}
else
{
return DataResult.CreateFailResult<DataTable>("未能查到数据,请检测".Translated());
}
}
/// <summary>
/// 报警信息查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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<DataResult<DataTable>> 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();
}
}));
});
}
/// <summary>
/// 报警信息导出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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
/// <summary>
/// 进出站补传Mes
/// </summary>
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<DataGridViewRow>();
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;
}
}
/// <summary>
/// 安全获取单元格值,防止空值报错
/// </summary>
private string GetSafeValue(DataGridViewCell cell)
{
if (cell == null || cell.Value == null || cell.Value == DBNull.Value)
return "";
return cell.Value.ToString().Trim();
}
/// <summary>
/// 补传进站
/// </summary>
private async Task ReUpInStationAsync(List<DataGridViewRow> 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<AGearEntity>();
var failList = new List<AGearEntity>();
var processedCount = 0;
var failDetails = new List<string>();
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<string> { 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}", "补传日志");
}
/// <summary>
/// 补传出站
/// </summary>
private async Task ReUpOutStationAsync(List<DataGridViewRow> 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<BGearEntity>();
var failDetails = new List<string>();
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<BGearEntity> { 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}", "补传日志");
}
/// <summary>
/// 补传结果参数
/// </summary>
private async Task ReUpProducResultParam(List<DataGridViewRow> 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<BGearEntity>();
var failDetails = new List<string>();
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}", "补传日志");
}
/// <summary>
/// 更新数据库字段值
/// </summary>
/// <param name="barcode"></param>
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<T> GetList<T>(int num, T data)
{
List<T> list = new List<T>();
for (int i = 0; i < num; i++)
{
list.Add(data);
}
return list;
}
public List<MesResType> GetMesType(int Num)
{
List<MesResType> mesResTypes = new List<MesResType>();
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
}
}