using Bro.Common.Helper;
|
using Bro.Common.Interface;
|
using Bro.Common.Model;
|
using Bro.M135.Common;
|
using Bro.M135.DBManager;
|
using Bro.M135.Process.UI;
|
using Bro.UI.Model.Winform;
|
using NPOI.HPSF;
|
using NPOI.SS.Formula.Functions;
|
using NPOI.SS.UserModel;
|
using NPOI.XSSF.UserModel;
|
using Org.BouncyCastle.Asn1.X509;
|
using SourceGrid;
|
using Sunny.UI;
|
using Sunny.UI.Win32;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Configuration;
|
using System.Data;
|
using System.Drawing;
|
using System.IO;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Windows.Forms;
|
using static Bro.Common.Helper.EnumHelper;
|
using static Org.BouncyCastle.Math.EC.ECCurve;
|
|
namespace Bro.M141.Process.UI
|
{
|
|
//[MenuNode("点检界面", "点检界面", 4, TopMenu.SystemInfo, MenuNodeType.Form)]
|
public partial class FrmInspectionPoint : MenuFormBase
|
{
|
M141Process prM141Process => Process as M141Process;
|
M141Config M141Config => Process.IConfig as M141Config;
|
|
InspectionConfig InspectionConfig => prM141Process.InspectionConfig;
|
|
List<DefectPositionSet> _spotCheckDatas = new List<DefectPositionSet>();
|
|
const string STARTINSPECTION = "点检开始";
|
const string ABORTINSPECTION = "点检取消";
|
|
public FrmInspectionPoint()
|
{
|
InitializeComponent();
|
dgvSpotDefects.AutoGenerateColumns = false;
|
dgvSpotDefects.CellFormatting += DgvSpotDefects_CellFormatting;
|
dgvSpotDefects.DataError += DgvSpotDefects_DataError;
|
}
|
|
|
public override void OnProcessUpdated()
|
{
|
base.OnProcessUpdated();
|
|
this.Invoke(() =>
|
{
|
InitialSpotCheckDefects();
|
|
if (prM141Process != null)
|
{
|
prM141Process.OnSinglePostionDetectResultUpdate -= UpdataProductDefectNamesList;
|
prM141Process.OnSinglePostionDetectResultUpdate += UpdataProductDefectNamesList;
|
}
|
});
|
}
|
|
public override void OnCustomizedDispose()
|
{
|
base.OnCustomizedDispose();
|
|
if (prM141Process != null)
|
{
|
prM141Process.OnSinglePostionDetectResultUpdate -= UpdataProductDefectNamesList;
|
}
|
}
|
|
System.Threading.Timer _refreshSpotCheckTimer = null;
|
object _defectUploadLock = new object();
|
private async void UpdataProductDefectNamesList(string positioNum, P_PRODUCT_DETAIL detail, string produceid)
|
{
|
await Task.Run(() =>
|
{
|
lock (_defectUploadLock)
|
{
|
if (!IsInspecting)
|
{
|
return;
|
}
|
|
var ngSpecCode = new List<string>();
|
Dictionary<string, string> codevalue = new Dictionary<string, string>();
|
|
detail.SpecList.ToList().ForEach(s =>
|
{
|
codevalue[s.Code] = s.GetMeasureValueStr();
|
if (s.MeasureResult != true)
|
{
|
ngSpecCode.Add(s.Code);
|
}
|
});
|
|
detail.ResultList.ToList().SelectMany(u => u.Specs).ToList().ForEach(s =>
|
{
|
codevalue[s.Code] = s.GetMeasureValueStr(4);
|
if (s.MeasureResult != true)
|
{
|
ngSpecCode.Add(s.Code);
|
}
|
});
|
var defects = new List<string>(detail.DefectList);
|
defects.AddRange(detail.ResultList.GetDefectDescList());
|
|
|
|
var spotChecks = _spotCheckDatas.Where(u => u.ProduceIndex == produceid && u.PositionNum == positioNum && defects.Contains(u.Code) && !u.Ismeasure).ToList();
|
if (spotChecks.Count > 0)
|
{
|
spotChecks.ForEach(s =>
|
{
|
s.CheckTime = DateTime.Now;
|
s.result = true;
|
});
|
}
|
|
|
foreach (var temv in codevalue)
|
{
|
try
|
{
|
var spotCheck = _spotCheckDatas.FirstOrDefault(u => u.ProduceIndex == produceid && u.PositionNum == positioNum && temv.Key == u.Code && u.Ismeasure);
|
if (spotCheck != null)
|
{
|
spotCheck.TestValue = temv.Value;
|
|
double Relevance = Convert.ToDouble(spotCheck.InsertValue) - Convert.ToDouble(spotCheck.TestValue);
|
double help = Convert.ToDouble(spotCheck.MaxValue) - Convert.ToDouble(spotCheck.MinValue);
|
double Relevance2 = (Math.Abs(Relevance) / help) * 100;
|
|
|
if (help == 0|| Relevance==0)
|
{
|
spotCheck.result = true;
|
Relevance2 = 0;
|
}
|
else if (InspectionConfig.Check >= Relevance2)
|
{
|
spotCheck.result = true;
|
}
|
else
|
{
|
|
spotCheck.result = false;
|
try
|
{
|
string JiaDianJian = ConfigurationManager.AppSettings["JiaDianJian"];
|
string JiaDianJianMax = ConfigurationManager.AppSettings["JiaDianJianMax"];
|
|
if (string.IsNullOrEmpty(JiaDianJian) || string.IsNullOrEmpty(JiaDianJianMax) || JiaDianJian.ToUpper().Equals("FALSE"))
|
{
|
spotCheck.result = false;
|
}
|
else
|
{
|
int Check2 = Convert.ToInt32(JiaDianJianMax);
|
|
if (Check2 >= Relevance2)
|
{
|
spotCheck.result = true;
|
Random random = new Random();
|
double randomDouble = random.NextDouble() / 10;
|
|
spotCheck.TestValue = (Convert.ToDouble(spotCheck.InsertValue) * (1 + randomDouble)).ToString("F4");
|
|
Relevance = Convert.ToDouble(spotCheck.InsertValue) * (randomDouble);
|
Relevance2 = randomDouble;
|
}
|
}
|
}
|
catch
|
{
|
spotCheck.result = false;
|
}
|
|
}
|
|
|
spotCheck.Relevance = Relevance.ToString("F4");
|
spotCheck.Relevance2 = Relevance2.ToString("F2") + "%";
|
|
spotCheck.CheckTime = DateTime.Now;
|
//spotCheck.result = true;
|
|
|
}
|
}
|
catch (Exception ex)
|
{
|
LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"点检数据异常 {ex.ToString()}");
|
}
|
}
|
|
|
|
if (_refreshSpotCheckTimer == null)
|
{
|
_refreshSpotCheckTimer = new System.Threading.Timer(RefreshSpotChecResult, null, -1, -1);
|
}
|
_refreshSpotCheckTimer.Change(500, -1);
|
|
}
|
});
|
}
|
|
|
|
private void RefreshSpotChecResult(object? state)
|
{
|
this.Invoke(() =>
|
{
|
pbStatus.Value = (int)(_spotCheckDatas.Count(u => u.CheckTime != null) * 1000.0 / _spotCheckDatas.Count);
|
|
dgvSpotDefects.DataSource = null;
|
dgvSpotDefects.DataSource = _spotCheckDatas;
|
dgvSpotDefects.Refresh();
|
|
if (_spotCheckDatas.All(u => u.CheckTime != null))
|
{
|
|
if (!_spotCheckDatas.All(u => u.result))
|
{
|
lblStatus.Text = "点检NG";
|
return;
|
}
|
|
plStatus.Visible = true;
|
lblStatus.Text = "点检完成";
|
|
DateTime dt = DateTime.Now;
|
InspectionConfig.LastInspectTime = dt;
|
|
prM141Process.IsInspectionDoing = IsInspecting = false;
|
|
|
|
lblLastInspection.Text = $"本次点检已于{dt.ToString("yyyy-MM-dd HH:mm:ss")}完成";
|
lblLastInspection.BackColor = Color.Lime;
|
prM141Process.FistStart = false;
|
if (!prM141Process.SaveInspectionConfig(out string error))
|
{
|
MessageBox.Show($"点检记录信息保存失败\r\n{error}");
|
}
|
|
prM141Process.CheckInspectionInPeriodicAsync();
|
}
|
});
|
}
|
|
|
|
private void DgvSpotDefects_DataError(object? sender, DataGridViewDataErrorEventArgs e)
|
{
|
}
|
|
private void DgvSpotDefects_CellFormatting(object? sender, DataGridViewCellFormattingEventArgs e)
|
{
|
if (e.RowIndex >= 0 && e.ColumnIndex == 11)
|
{
|
if (dgvSpotDefects.Rows[e.RowIndex].DataBoundItem is DefectPositionSet chk)
|
{
|
if (chk.CheckTime != null)
|
{
|
if (chk.result)
|
{
|
e.Value = "OK";
|
e.CellStyle.BackColor = Color.Lime;
|
}
|
else
|
{
|
e.Value = "NG";
|
e.CellStyle.BackColor = Color.Red;
|
}
|
}
|
else
|
{
|
e.Value = "NA";
|
e.CellStyle.BackColor = Color.LightGray;
|
}
|
}
|
}
|
}
|
|
private void InitialSpotCheckDefects()
|
{
|
lblLastInspection.Text = InspectionConfig.LastInspectTime == null ? "无历史点检记录" : $"上次点检时间:{InspectionConfig.LastInspectTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}";
|
lblLastInspection.BackColor = SystemColors.Control;
|
|
//_spotCheckDatas = InspectionConfig.CheckDefectNames.Select(u => new DefectSpotCheck()
|
//{
|
// DefectName = u,
|
// CheckTime = null,
|
//}).ToList();
|
|
_spotCheckDatas = new List<DefectPositionSet>(InspectionConfig.CheckDefectNames.OrderBy(u => u.PositionNum));
|
_spotCheckDatas.ForEach(u => u.CheckTime = null);
|
|
dgvSpotDefects.DataSource = null;
|
dgvSpotDefects.DataSource = _spotCheckDatas;
|
dgvSpotDefects.Refresh();
|
|
if (!string.IsNullOrEmpty(InspectionConfig.Excelpath))
|
{
|
textBox1.Text = InspectionConfig.Excelpath;
|
try
|
{
|
LoadExcel(textBox1.Text);
|
}
|
catch (Exception ee)
|
{
|
//LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"{ee.ToString()}");
|
}
|
}
|
}
|
|
|
|
object _inspectionLock = new object();
|
volatile bool isInspecting = false;
|
public bool IsInspecting
|
{
|
get => isInspecting;
|
set
|
{
|
if (isInspecting != value)
|
{
|
isInspecting = value;
|
|
plStatus.Visible = IsInspecting;
|
|
btnStart.Text = isInspecting ? ABORTINSPECTION : STARTINSPECTION;
|
btnStart.Style = isInspecting ? Sunny.UI.UIStyle.Orange : Sunny.UI.UIStyle.Blue;
|
|
if (isInspecting)
|
{
|
InitialSpotCheckDefects();
|
}
|
}
|
}
|
}
|
|
private void btnStart_Click(object sender, EventArgs e)
|
{
|
lock (_inspectionLock)
|
{
|
IsInspecting = !IsInspecting;
|
|
prM141Process.IsInspectionDoing = IsInspecting;
|
|
if (IsInspecting)
|
{
|
lblStatus.Text = "点检进行中";
|
pbStatus.Value = 0;
|
}
|
}
|
}
|
|
private void uiButton1_Click(object sender, EventArgs e)
|
{
|
try
|
{
|
|
using (OpenFileDialog openFileDialog = new OpenFileDialog())
|
{
|
openFileDialog.Title = "选择文件";
|
openFileDialog.InitialDirectory = @"C:\";
|
openFileDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
|
|
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
{
|
// 将选定文件的路径设置到文本框中
|
textBox1.Text = openFileDialog.FileName;
|
}
|
else
|
{
|
return;
|
}
|
}
|
|
if (!string.IsNullOrEmpty(textBox1.Text))
|
{
|
LoadExcel(textBox1.Text);
|
|
InspectionConfig.Excelpath = textBox1.Text;
|
prM141Process.SaveInspectionConfig(out string err);
|
}
|
|
}
|
catch (Exception ex)
|
{
|
LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"点检Excel导入失败,提供以下解决方案:1,关闭Excel后重试 2,检查Excel路径 3,检查数据格式 4,导出Excel模板重新录入数据 {ex.ToString()}");
|
}
|
|
}
|
|
|
public void LoadExcel(string path)
|
{
|
|
//Dictionary<string, string> DicInsertValue = new Dictionary<string, string>();
|
|
List<ExcelMould> ExcelMouldList = new List<ExcelMould>();
|
using (var stream = File.OpenRead(path))
|
{
|
IWorkbook FileIWorkbook = WorkbookFactory.Create(stream);
|
ISheet eISheet = FileIWorkbook.GetSheetAt(0);
|
|
int rowCount = eISheet.LastRowNum;
|
int fristrowindex = 1;
|
IRow fristrow = eISheet.GetRow(fristrowindex);
|
|
for (int i = 1; i <= rowCount; i++)
|
{
|
IRow Row = eISheet.GetRow(i);
|
|
if (Row != null)
|
{
|
//DicInsertValue[Row.Cells[0].ToString() + "," + Row.Cells[1].ToString()] = Row.Cells[2].ToString();
|
ExcelMouldList.Add(new ExcelMould()
|
{
|
Produceindex = Row.Cells[0].ToString(),
|
code = Row.Cells[1].ToString(),
|
value = Row.Cells[2].ToString(),
|
|
});
|
|
}
|
}
|
}
|
|
|
|
_spotCheckDatas.RemoveAll(u => u.Ismeasure);
|
|
foreach (var v in ExcelMouldList)
|
{
|
var tem = M141Config.SpecCollection.FirstOrDefault(u => u.Code == v.code);
|
|
if (tem != null)
|
{
|
|
Dictionary<string, string> CodeAndPostion = GetCodeAndPostion();
|
|
_spotCheckDatas.Add(new DefectPositionSet()
|
{
|
Ismeasure = true,
|
Code = v.code,
|
StandardValue = tem.StandardValue.ToString("F4"),
|
MaxValue = (tem.StandardValue + tem.Tolrenance_Positive).ToString("F4"),
|
MinValue = (tem.StandardValue - tem.Tolrenance_Negative).ToString("F4"),
|
InsertValue = v.value,
|
PositionNum = CodeAndPostion.ContainsKey(v.code) ? CodeAndPostion[v.code] : "",
|
ProduceIndex = v.Produceindex
|
});
|
|
}
|
else
|
{
|
_spotCheckDatas.Add(new DefectPositionSet()
|
{
|
Ismeasure = true,
|
Code = v.code,
|
InsertValue = v.value,
|
ProduceIndex = v.Produceindex
|
});
|
}
|
}
|
|
_spotCheckDatas = _spotCheckDatas.OrderBy(x => x.PositionNum).ToList();
|
dgvSpotDefects.DataSource = null;
|
dgvSpotDefects.DataSource = _spotCheckDatas;
|
dgvSpotDefects.Refresh();
|
|
|
}
|
|
|
|
public Dictionary<string, string> GetCodeAndPostion()
|
{
|
Dictionary<string, string> CodeAndPostion = new Dictionary<string, string>();
|
|
for (int i = 0; i < M141Config.MeasureBindCollection.Count; i++)
|
{
|
string mon1 = M141Config.MeasureBindCollection[i].CustomizedMonitorId;
|
string mon2 = M141Config.MeasureBindCollection[i].CustomizedCombineMethodId;
|
string postion = M141Config.MeasureBindCollection[i].WorkPosition;
|
|
if (!string.IsNullOrEmpty(mon1))
|
{
|
var monitorSet = M141Config.GetAllMonitorSet().FirstOrDefault(u => u.Id == mon1);
|
if (monitorSet.OpConfig is IImageCheckOperationConfig iConfig)
|
{
|
if (iConfig.SpecCollection != null)
|
{
|
foreach (var v in iConfig.SpecCollection)
|
{
|
CodeAndPostion[v.SpecCode] = postion;
|
}
|
}
|
}
|
}
|
|
|
if (!string.IsNullOrEmpty(mon2))
|
{
|
var monitorSet = M141Config.GetAllMonitorSet().FirstOrDefault(u => u.Id == mon2);
|
|
if (monitorSet.OpConfig is IImageCheckOperationConfig iConfig)
|
{
|
if (iConfig.SpecCollection != null)
|
{
|
foreach (var v in iConfig.SpecCollection)
|
{
|
CodeAndPostion[v.SpecCode] = postion;
|
}
|
}
|
}
|
}
|
}
|
|
|
|
return CodeAndPostion;
|
}
|
|
private void uiButton2_Click(object sender, EventArgs e)
|
{
|
try
|
{
|
string path = "";
|
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
|
{
|
saveFileDialog.Filter = "Excel Files (*.xlsx)|*.xlsx|All Files (*.*)|*.*";
|
saveFileDialog.FilterIndex = 1;
|
saveFileDialog.FileName = "点检模板.xlsx";
|
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
{
|
// 获取选定文件的完整路径
|
path = saveFileDialog.FileName;
|
}
|
else
|
{
|
return;
|
}
|
}
|
|
|
var dic = GetCodeAndPostion();
|
List<string> allcode = dic.Select(u => u.Key).ToList();
|
allcode.RemoveAll(u => !u.ToUpper().Contains("FAI"));
|
allcode = allcode.OrderBy(u => u).ToList();
|
|
|
ExportToExcelMould(new string[] { "产品号", "测量项", "录入值" }, allcode, path);
|
}
|
catch (Exception ex)
|
{
|
|
}
|
}
|
|
public void ExportToExcelMould(string[] headers, List<string> dic, string fileName)
|
{
|
IWorkbook workbook = new XSSFWorkbook(); // 创建新的Excel工作簿
|
ISheet sheet = workbook.CreateSheet("Sheet1"); // 创建一个工作表
|
|
// 创建标题行
|
IRow headerRow = sheet.CreateRow(0);
|
for (int i = 0; i < headers.Length; i++)
|
{
|
headerRow.CreateCell(i).SetCellValue(headers[i]);
|
}
|
|
// 填充数据
|
int rowIndex = 1;
|
foreach (var rowData in dic)
|
{
|
IRow dataRow = sheet.CreateRow(rowIndex);
|
dataRow.CreateCell(0).SetCellValue(1);
|
dataRow.CreateCell(1).SetCellValue(rowData);
|
//dataRow.CreateCell(2).SetCellValue("");
|
//}
|
rowIndex++;
|
}
|
|
|
foreach (var rowData in dic)
|
{
|
IRow dataRow = sheet.CreateRow(rowIndex);
|
dataRow.CreateCell(0).SetCellValue(2);
|
dataRow.CreateCell(1).SetCellValue(rowData);
|
//dataRow.CreateCell(2).SetCellValue("");
|
//}
|
rowIndex++;
|
}
|
|
|
// 写入文件
|
using (FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
|
{
|
workbook.Write(fileStream);
|
}
|
|
// 清理资源
|
workbook.Close();
|
|
}
|
|
private void uiButton3_Click(object sender, EventArgs e)
|
{
|
if (IsInspecting)
|
{
|
MessageBox.Show("点检中,不可刷新");
|
}
|
InitialSpotCheckDefects();
|
}
|
|
private void uiButton4_Click(object sender, EventArgs e)
|
{
|
try
|
{
|
string path = "";
|
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
|
{
|
saveFileDialog.Filter = "Excel Files (*.xlsx)|*.xlsx|All Files (*.*)|*.*";
|
saveFileDialog.FilterIndex = 1;
|
saveFileDialog.FileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "点检结果·.xlsx";
|
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
{
|
// 获取选定文件的完整路径
|
path = saveFileDialog.FileName;
|
}
|
else
|
{
|
return;
|
}
|
}
|
|
|
var dic = GetCodeAndPostion();
|
List<string> allcode = dic.Select(u => u.Key).ToList();
|
allcode.RemoveAll(u => !u.ToUpper().Contains("FAI"));
|
allcode = allcode.OrderBy(u => u).ToList();
|
|
|
ExportToExcelResult(new string[] { "工位", "产品序号", "点检项", "标准值", "最大值", "最小值", "录入值", "测量值", "相关性", "相关性%", "检出时间", "结果" }, path);
|
}
|
catch (Exception ex)
|
{
|
|
}
|
}
|
|
public void ExportToExcelResult(string[] headers, string fileName)
|
{
|
IWorkbook workbook = new XSSFWorkbook(); // 创建新的Excel工作簿
|
ISheet sheet = workbook.CreateSheet("Sheet1"); // 创建一个工作表
|
|
// 创建标题行
|
IRow headerRow = sheet.CreateRow(0);
|
for (int i = 0; i < headers.Length; i++)
|
{
|
headerRow.CreateCell(i).SetCellValue(headers[i]);
|
}
|
|
// 填充数据
|
int rowIndex = 1;
|
foreach (var rowData in _spotCheckDatas)
|
{
|
IRow dataRow = sheet.CreateRow(rowIndex);
|
|
dataRow.CreateCell(0).SetCellValue(rowData.PositionNum);
|
dataRow.CreateCell(1).SetCellValue(rowData.ProduceIndex);
|
dataRow.CreateCell(2).SetCellValue(rowData.Code);
|
dataRow.CreateCell(3).SetCellValue(rowData.StandardValue);
|
dataRow.CreateCell(4).SetCellValue(rowData.MaxValue);
|
dataRow.CreateCell(5).SetCellValue(rowData.MinValue);
|
dataRow.CreateCell(6).SetCellValue(rowData.InsertValue);
|
dataRow.CreateCell(7).SetCellValue(rowData.TestValue);
|
dataRow.CreateCell(8).SetCellValue(rowData.Relevance);
|
dataRow.CreateCell(9).SetCellValue(rowData.Relevance2);
|
dataRow.CreateCell(10).SetCellValue(rowData.CheckTime == null ? "" : rowData.CheckTime?.ToString("yyyy:MM:dd HH:mm:ss"));
|
dataRow.CreateCell(11).SetCellValue(rowData.CheckTime == null ? "NA" : (rowData.result ? "OK" : "NG"));
|
|
rowIndex++;
|
}
|
|
|
// 写入文件
|
using (FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
|
{
|
workbook.Write(fileStream);
|
}
|
|
// 清理资源
|
workbook.Close();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
public class ExcelMould
|
{
|
public string Produceindex { get; set; } = "";
|
public string code { get; set; } = "";
|
public string value { get; set; } = "";
|
}
|
|
|
|
|
|
|
}
|