using HMI.Core.Manager;
using HMI.Core.Setting;
using HMI.Core.Util;
using HMI.UI.Util;
using HMI.Util;
using Panuon.WPF.UI;
using Plugin.TestResult.Lixun;
using Plugin.TestResult.Model;
using Plugin.TestResult.Util;
using Plugin.TestResult_WPF.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Ports;
using System.Windows;
using System.Windows.Input;
namespace Plugin.TestResult_WPF
{
public class BarcodeEventArg
{
public string name { get; private set; }
public string positionCode { get; private set; }
public string snrCode { get; private set; }
public CellInfo lastInfo { get; private set; }
public BarcodeEventArg(string name, string positionCode, string snrCode, CellInfo lastInfo)
{
this.name = name;
this.positionCode = positionCode;
this.snrCode = snrCode;
this.lastInfo = lastInfo;
}
}
///
/// Scanner.xaml 的交互逻辑
///
public partial class Scanner : WindowX
{
private string _title;
public string title
{
get { return _title; }
set => Set(ref _title, value);
}
public event EventHandler FinishBarcode;
public event EventHandler ComplateClick;
private static Dictionary snrCache = new Dictionary();
SerialPort serialPort;
private string model;
private int columns;
private int rows;
private int ovenIndex;
private CellInfo targetCellInfo;
public Scanner(int index, string title, string model, int columns, int rows)
{
this.ovenIndex = index;
this.title = title;
this.model = model;
this.columns = columns;
this.rows = rows;
this.DataContext = this;
InitializeComponent();
Loaded += Scanner_Loaded;
}
private void Scanner_Loaded(object sender, RoutedEventArgs e)
{
try
{
InitScanner();
Loaded -= Scanner_Loaded;
}
catch (Exception ex)
{
ViewControl.Logger.Error("Open Scanner Window Error.", ex);
MsgBoxHelper.Error(this, $"{ex.Message}");
}
}
///
/// 设置扫码枪
///
private void InitScanner()
{
string comStr = "";
if (serialPort != null) return;
string section = this.Tag.ToString();
ScannerConfig common = ScannerConfig.ReadFromIni(ViewControl.SannerIniFile, "Config");
string portName = IniFileHelper.ReadIniData(section, "PortName", "", ViewControl.SannerIniFile);
if (string.IsNullOrEmpty(portName))
{
if (section.StartsWith("A"))
{
portName = "COM1";
}
else
{
portName = "COM2";
}
}
common.PortName = portName;
// 配置串口
serialPort = new SerialPort
{
PortName = common.PortName,
BaudRate = common.BaudRate,
Parity = Parity.None,
DataBits = common.DataBits,
StopBits = common.StopBits,
Handshake = Handshake.None,
DtrEnable = common.DtrEnable,
RtsEnable = common.RtsEnable
//ReadTimeout = 500,
//WriteTimeout = 500,
//ReciveBufferSize=4096
};
try
{
// 打开串口
serialPort.Open();
// 注册接收数据事件
serialPort.DataReceived += SerialPort_DataReceived;
}
catch (Exception ex)
{
ViewControl.Logger.Error("Init Scan Gun Failed.", ex);
MsgBoxHelper.Error(this, $"{this.lang("Tr.InitGunFailed")}: {ex.StackTrace}");
}
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
SerialPort sp = (SerialPort)sender;
string barcode = ReadDataFrom(sp).Trim();
//string barcode =
Dispatcher.Invoke(() =>
{
if (snrText.IsFocused)
{
snrText.Text = barcode;
Con_Click(null, null);
}
else
{
try
{
this.targetCellInfo = ScannerParser.GetCellInfoByCode(this.model, this.columns, this.rows, barcode);
if (!TestResultView.nameTables.ContainsKey(targetCellInfo.OvenName))
{
MsgBoxHelper2.Error($"老化炉 [{targetCellInfo.OvenName}] 不存在,请检查配置");
return;
}
positionText.Text = barcode;
//positionText.Focus();
//snrText.Text = "";
snrText.Focus();
}
catch (Exception ex)
{
ViewControl.Logger.Error("Parse Position Code Error.", ex);
MsgBoxHelper2.Error($"穴位号 [{barcode}] 解析失败: {ex.Message}");
}
}
});
}
catch (Exception ex)
{
ViewControl.Logger.Error("Get Scan Gun Data Failed.", ex);
MessageBox.Show($"{this.lang("Tr.GetGunData")}: {ex.StackTrace}");
}
}
public static void InsertNewCode(string snr, CellInfo info)
{
snrCache[snr] = info;
}
public static void RemoveSNR(string snr)
{
snrCache.Remove(snr);
}
private void SendCode(string tag, string position, string snr)
{
if (snrCache.ContainsKey(snr))
{
string oldPosition = snrCache[snr].OriginCode;
if (MsgBoxHelper2.WarnChoose($"条码[{snr}]已放置于[{oldPosition}]中,是否清除?") == MessageBoxResult.OK)
{
try
{
FinishBarcode.Invoke(this, new BarcodeEventArg(tag, position, null, snrCache[snr]));
snrCache.Remove(snr);
FinishBarcode.Invoke(this, new BarcodeEventArg(tag, position, snr, null));
}
catch (Exception ex)
{
ToastHelper.Error(ex.Message);
}
}
}
else
{
FinishBarcode.Invoke(this, new BarcodeEventArg(tag, position, snr, null));
}
}
private void Con_Click(object sender, RoutedEventArgs e)
{
Dispatcher.Invoke(() =>
{
string position = positionText.Text, snr = snrText.Text;
try
{
var EnableMes = ParameterManager.GetCommonParameterByName("EnableMes", false);
if (ParamSetting.CustomerCode == "LIXUN" && EnableMes)
{
var table = TestResultView.tables[this.ovenIndex];
string currentPn = table.CbProduct.Text;
/// 检查格式
if (!SNValidator.ValidateSN(currentPn, snr, out string msg))
{
TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"检查产品条码异常:{msg}");
snrText.Text = string.Empty;
snrText.Focus();
return;
}
/// 获取站名
string stationName = ProductManager.GetParameterByProductAndName(currentPn, "MES站位")?.Value;
if (string.IsNullOrEmpty(stationName))
{
TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"检查产品条码异常,当前产品[{currentPn}]未设置参数MES站位");
snrText.Text = string.Empty;
snrText.Focus();
return;
}
/// 检查PN
if (PNUtil.GetPN(ParamSetting.MesAddress, stationName, snr, out string pn, out msg))
{
if (pn != currentPn)
{
TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"当前测试料号为 [{currentPn}],扫码产品料号为 [{pn}] 不允许测试");
snrText.Text = string.Empty;
snrText.Focus();
return;
}
}
else
{
TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"检查产品条码异常:{msg}");
snrText.Text = string.Empty;
snrText.Focus();
return;
}
/// 检查工序
if (PNUtil.CheckIn(ViewControl.Logger, ParamSetting.MesAddress, stationName, snr, out bool needCheckIn, out msg))
{
if (needCheckIn != true)
{
TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"条码[{snr}]工序不在本站:{msg}");
snrText.Text = string.Empty;
snrText.Focus();
return;
}
}
else
{
TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"条码[{snr}]CheckIn失败:{msg}");
snrText.Text = string.Empty;
snrText.Focus();
return;
}
}
//var _ = ScannerParser.GetCellInfoByCode(this.model, this.columns, this.rows, snr);
//ToastHelper.Warning(this, "产品码格式异常");
//snrText.Text = string.Empty;
//snrText.Focus();
//return;
}
catch (Exception ex)
{
ViewControl.Logger.Error("Scanner Check Error.", ex);
MsgBoxHelper2.Error($"扫码检查异常:{ex.Message}");
return;
}
if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr))
{
ToastHelper.Warning(this, this.lang("Tr.PleaseInputSnrs"));
return;
}
try
{
SendCode(Tag.ToString(), position, snr);
positionText.Text = "";
snrText.Text = "";
positionText.Focus();
}
catch (Exception ex)
{
ViewControl.Logger.Error("Con_Click Failed.", ex);
ToastHelper.Warning(this, ex.Message);
}
});
}
///
/// 原来的完成扫描逻辑
///
///
///
//private void Ok_Click(object sender, RoutedEventArgs e)
//{
// string position = positionText.Text, snr = snrText.Text;
// if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr))
// {
// ToastHelper.Warning(this, this.lang("Tr.PleaseInputSnrs"));
// return;
// }
// try
// {
// SendCode(Tag.ToString(), position, snr);
// this.Close();
// }
// catch (Exception ex)
// {
// ViewControl.Logger.Error("Con_Click Failed.", ex);
// ToastHelper.Warning(this, ex.Message);
// }
//}
private void Ok_Click(object sender, RoutedEventArgs e)
{
ComplateClick?.Invoke(this, e);
this.Close();
}
private string ReadDataFrom(SerialPort sp)
{
string barcode = "";
while (sp.BytesToRead > 0)
{
byte[] buffer = new byte[sp.BytesToRead];
sp.Read(buffer, 0, buffer.Length);
barcode += System.Text.Encoding.ASCII.GetString(buffer);
System.Threading.Thread.Sleep(50);
}
return barcode;
}
private void Window_Closing(object sender, CancelEventArgs e)
{
try
{
targetCellInfo = null;
serialPort.Dispose();
serialPort = null;
}
catch (Exception ex)
{
}
}
private void TextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
//string barcode =
Dispatcher.Invoke(() =>
{
if (snrText.IsFocused)
{
Con_Click(null, null);
}
else
{
if (ParamSetting.CustomerCode != "LIXUN")
{
snrText.Focus();
return;
}
string barcode = positionText.Text;
try
{
targetCellInfo = ScannerParser.GetCellInfoByCode(this.model, this.columns, this.rows, barcode);
if (!TestResultView.nameTables.ContainsKey(targetCellInfo.OvenName))
{
MsgBoxHelper2.Error($"老化炉 [{targetCellInfo.OvenName}] 不存在,请检查配置");
positionText.Text = string.Empty;
positionText.Focus();
targetCellInfo = null;
return;
}
var oven = TestResultView.nameTables[targetCellInfo.OvenName];
if (oven.cells.Length < targetCellInfo.Index + 1)
{
MsgBoxHelper2.Error($"穴位下标 [{targetCellInfo.Index}] 超出索引");
positionText.Text = string.Empty;
positionText.Focus();
targetCellInfo = null;
return;
}
snrText.Focus();
}
catch (Exception ex)
{
positionText.Text = string.Empty;
positionText.Focus();
ViewControl.Logger.Error("Parse Position Code Error.", ex);
MsgBoxHelper2.Error($"穴位号 [{barcode}] 解析失败: {ex.Message}");
}
}
});
}
}
}
}