|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.ComponentModel;
|
|
|
using System.Drawing;
|
|
|
using System.Data;
|
|
|
using System.Text;
|
|
|
using System.Windows.Forms;
|
|
|
using Estsh.Client.Base;
|
|
|
using System.Configuration;
|
|
|
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
namespace Estsh.Client.StepLibrary
|
|
|
{
|
|
|
public partial class KPSNStep2 : StepBase
|
|
|
{
|
|
|
private StepLibraryAPP app = null;
|
|
|
private List<dynamic> _kpsnTable = null; //绑定数据
|
|
|
private delegate void DeleGrdBind(List<dynamic> dt);
|
|
|
int _terminalID = 0;
|
|
|
string _stationType = "";
|
|
|
|
|
|
////PASS上一次成功扫描时间
|
|
|
//private DateTime _lastPassDatetime;
|
|
|
|
|
|
//PASS扫描间隔
|
|
|
private int _passIntervalValue = 2000;
|
|
|
|
|
|
//PASS间隔限制工位集合
|
|
|
private string _passIntervalLimit = string.Empty;
|
|
|
|
|
|
|
|
|
public KPSNStep2()
|
|
|
{
|
|
|
InitializeComponent();
|
|
|
|
|
|
// 有用户界面的工步在初始化时需要设置为不可见
|
|
|
// 开始执行此工步后再置为可见
|
|
|
this.Visible = false;
|
|
|
}
|
|
|
|
|
|
private void txtSN_KeyPress(object sender, KeyPressEventArgs e)
|
|
|
{
|
|
|
if (e.KeyChar == (char)13)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(txtSN.Text))
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
string el_no = Context["serial_number"].ToString();
|
|
|
string input = txtSN.Text.Trim().ToUpper();
|
|
|
txtSN.Text = string.Empty;
|
|
|
|
|
|
if (_kpsnTable == null || _kpsnTable.Count == 0)
|
|
|
{
|
|
|
if (input == "PASS")
|
|
|
{
|
|
|
if (IsAllowPass())
|
|
|
{
|
|
|
_lastPassDatetime = DateTime.Now;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ShowMessage(this, "red|扫描太快,请等待!");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
string pdlineID = app.pdLineID(Context["terminal_id"].ToString());
|
|
|
if (Context["station_type"].ToString() == "B")
|
|
|
{
|
|
|
app.updateOnLineStatus(Context["serial_number"].ToString(), pdlineID);
|
|
|
}
|
|
|
|
|
|
dgbKPItems.AutoGenerateColumns = false;
|
|
|
dgbKPItems.DataSource = null;
|
|
|
|
|
|
Complate(this, e);
|
|
|
ShowMessage(this, "green|上一个已完成,请继续操作!");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
////校验关键零部件条码的唯一性
|
|
|
//if (kpsnData != null && kpsnData.Count > 0)
|
|
|
//{
|
|
|
// foreach (DataRow dr in kpsnData)
|
|
|
// {
|
|
|
// string sn = dr["serial_number"].ToString();
|
|
|
// if (sn != el_no)
|
|
|
// {
|
|
|
// ShowMessage(this, "条码已经绑定在:" + sn + "不可重复绑定");
|
|
|
// return;
|
|
|
// }
|
|
|
// }
|
|
|
//}
|
|
|
|
|
|
|
|
|
// KPSNStep2 的类型
|
|
|
string KPType = string.Empty;
|
|
|
int RowID = 0;
|
|
|
try
|
|
|
{
|
|
|
RowID = MatchKPSNRule(input, out KPType);
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
ShowMessage(this, "red|条码输入错误!");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (RowID < 0)
|
|
|
{
|
|
|
if (RowID != -1)
|
|
|
{
|
|
|
ShowMessage(this, "red|特征码匹配错误");
|
|
|
txtSN.SelectAll();
|
|
|
txtSN.Focus();
|
|
|
}
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (IsBindFull(RowID))
|
|
|
{
|
|
|
ShowMessage(this, "red|关键零件[" + _kpsnTable[RowID]["part_no"].ToString() + "]重复匹配!");
|
|
|
txtSN.SelectAll();
|
|
|
txtSN.Focus();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (!UpdateKPSNTable(RowID, input))
|
|
|
{
|
|
|
txtSN.SelectAll();
|
|
|
txtSN.Focus();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (IsAllBindFull())
|
|
|
{
|
|
|
//需要绑定的关键零部件都绑定完成后再进行KPSNStep2的数据插入
|
|
|
for (int i = 0; i < _kpsnTable.Count; i++)
|
|
|
{
|
|
|
bool insert_kpsn = false;
|
|
|
// 插入 KPSNStep2 数据
|
|
|
insert_kpsn = app.InsertKPSN(el_no, _kpsnTable[i]["KPSN"].ToString().Trim(), Convert.ToInt32(_kpsnTable[i]["item_part_id"]),
|
|
|
_kpsnTable[i]["version"].ToString(), _kpsnTable[i]["location"].ToString(), _terminalID);
|
|
|
|
|
|
if (!insert_kpsn)
|
|
|
{
|
|
|
ShowMessage(this, "red|插入 KPSN " + _kpsnTable[i]["KPSN"].ToString() + "数据失败,请重试");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
ShowMessage(this, "green|扫描成功");
|
|
|
|
|
|
// 工步执行完成后调用此方法
|
|
|
Complate(this, e);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ShowMessage(this, "green|请扫描下一个关键零件");
|
|
|
txtSN.SelectAll();
|
|
|
txtSN.Focus();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public override bool Do()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
ShowMessage(this, "green|请扫描关键零部件条码进行匹配操作!");
|
|
|
|
|
|
// 置为可见并加载到最前端
|
|
|
this.Visible = true;
|
|
|
this.BringToFront();
|
|
|
|
|
|
// 从配置文件中加载工位编号
|
|
|
_terminalID = Convert.ToInt32(Context["terminal_id"].ToString());
|
|
|
_stationType = Convert.ToString(Context["station_type"].ToString());
|
|
|
string _sn = Context["serial_number"].ToString();
|
|
|
|
|
|
app = new StepLibraryAPP(httpClient);
|
|
|
string _PartNo = app.GetPartNo(_sn);
|
|
|
string rule = app.GetRuleNo(_PartNo);
|
|
|
string partLocation = app.GetPartLoc(_PartNo);
|
|
|
|
|
|
_kpsnTable = app.GetStep2BindData(_PartNo, _terminalID);
|
|
|
if (_kpsnTable.Count <= 0)
|
|
|
{
|
|
|
|
|
|
Complate(this, new EventArgs());
|
|
|
return base.Do();
|
|
|
|
|
|
}
|
|
|
|
|
|
//PASS码两次扫描时间
|
|
|
try
|
|
|
{
|
|
|
_passIntervalValue = Convert.ToInt32(app.validataLimit("PassIntervalValue"));
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
_passIntervalValue = 2000;
|
|
|
}
|
|
|
//PASS码间隔限制工位集合
|
|
|
_passIntervalLimit = app.validataLimit("PassIntervalLimit");
|
|
|
|
|
|
WriteGrdBind(_kpsnTable);
|
|
|
|
|
|
// 执行父类的 Do 方法并返回
|
|
|
return base.Do();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
// 记录日志
|
|
|
using (StreamWriter sw = new StreamWriter("Error_Log_" + DateTime.Now.ToString("yyyyMM") + ".txt", true))
|
|
|
{
|
|
|
sw.WriteLine(string.Format("{0} {1}", "["
|
|
|
+ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
|
|
+ "] ", ex.ToString()));
|
|
|
sw.Flush();
|
|
|
sw.Close();
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public void WriteGrdBind(List<dynamic> dt)
|
|
|
{
|
|
|
if (!dgbKPItems.InvokeRequired)
|
|
|
{
|
|
|
dgbKPItems.AutoGenerateColumns = false;
|
|
|
dgbKPItems.DataSource = dt;
|
|
|
bool theNext = true;
|
|
|
for (int i = 0; i < dgbKPItems.Rows.Count; i++)
|
|
|
{
|
|
|
if (dgbKPItems.Rows[i].Cells["sno"].Value != null && dgbKPItems.Rows[i].Cells["sno"].Value.ToString().Length > 0)
|
|
|
{
|
|
|
dgbKPItems.Rows[i].DefaultCellStyle.BackColor = Color.Green;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (theNext)
|
|
|
{
|
|
|
theNext = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
dgbKPItems.Update();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
DeleGrdBind de = new DeleGrdBind(WriteGrdBind);
|
|
|
this.Invoke(de, new object[] { dt });
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 更新 KPSNStep2 TABLE
|
|
|
/// </summary>
|
|
|
/// <param name="rowID">行号</param>
|
|
|
/// <param name="KPSNStep2">KPSNStep2</param>
|
|
|
private bool UpdateKPSNTable(int rowID, string KPSN)
|
|
|
{
|
|
|
int BindQty = Convert.ToInt16(_kpsnTable[rowID]["BindQty"].ToString());
|
|
|
_kpsnTable[rowID]["BindQty"] = BindQty + 1;
|
|
|
_kpsnTable[rowID]["KPSN"] = _kpsnTable[rowID]["KPSN"].ToString() + " " + KPSN;
|
|
|
if (dgbKPItems.RowCount >= rowID)
|
|
|
{
|
|
|
dgbKPItems.Rows[rowID].DefaultCellStyle.BackColor = Color.Green;
|
|
|
dgbKPItems.Rows[rowID].DefaultCellStyle.SelectionBackColor = Color.Green;
|
|
|
dgbKPItems.Rows[rowID].DefaultCellStyle.SelectionForeColor = Color.Black;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 匹配 KPSNStep2 RULE
|
|
|
/// </summary>
|
|
|
/// <param name="KPSNStep2">KPSNStep2</param>
|
|
|
/// <param name="kpType">关键零件的类型(取自 sys_part_sn_rule.type)</param>
|
|
|
/// <returns>匹配成功返回 KPSNStep2 RULE 的行号,失败返回 -1</returns>
|
|
|
private int MatchKPSNRule(string KPSNStep2, out string kpType)
|
|
|
{
|
|
|
kpType = string.Empty;
|
|
|
for (int i = 0; i < _kpsnTable.Count; i++)
|
|
|
{
|
|
|
int lenght = Convert.ToInt16(_kpsnTable[i]["lenght"].ToString());
|
|
|
string isValidateUnique = _kpsnTable[i]["is_validate_unique"].ToString();
|
|
|
string isValidateLength = _kpsnTable[i]["is_validate_length"].ToString();
|
|
|
|
|
|
int startPos1 = Convert.ToInt16(_kpsnTable[i]["from1"].ToString());
|
|
|
int endPos1 = Convert.ToInt16(_kpsnTable[i]["to1"].ToString());
|
|
|
string fix1 = _kpsnTable[i]["fix1"].ToString();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
// 匹配 RULE1
|
|
|
if (startPos1 > 0 && endPos1 >= startPos1)
|
|
|
{
|
|
|
string subStr = "";
|
|
|
try
|
|
|
{
|
|
|
subStr = KPSNStep2.Substring(startPos1 - 1, endPos1 - startPos1 + 1);
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
string[] fixArr = fix1.Split('/');
|
|
|
if (Array.Exists(fixArr, str => str.Equals(subStr)) == false)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
ShowMessage(this, "red|条码输入错误!");
|
|
|
return -2;
|
|
|
}
|
|
|
|
|
|
//if (isValidateUnique.ToUpper() == "Y")
|
|
|
//{
|
|
|
// if (app.ExistsKPSN(KPSNStep2, _terminalID))
|
|
|
// {
|
|
|
// continue;
|
|
|
// }
|
|
|
//}
|
|
|
if (isValidateUnique.ToUpper() == "Y")
|
|
|
{
|
|
|
if (app.ExistsKPSN(KPSNStep2, _terminalID))
|
|
|
{
|
|
|
ShowMessage(this, string.Format("red|{0}", KPSNStep2 + ":条码重复绑定!"));
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
if (isValidateLength.ToUpper() == "Y")
|
|
|
{
|
|
|
if (lenght != KPSNStep2.Length)
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
return i;
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < _kpsnTable.Count; i++)
|
|
|
{
|
|
|
if (!IsBindFull(i))
|
|
|
{
|
|
|
kpType = _kpsnTable[i]["part_spec"].ToString().Trim();
|
|
|
ShowMessage(this, string.Format("red|请扫描[{0}!]", kpType));
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
return -2;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断 KPSNStep2 是否绑满
|
|
|
/// </summary>
|
|
|
/// <param name="rowID">KPSNStep2 RULE 的行号</param>
|
|
|
/// <returns>是否绑满</returns>
|
|
|
private bool IsBindFull(int rowID)
|
|
|
{
|
|
|
int Qty = (int)Convert.ToDouble(_kpsnTable[rowID]["item_count"].ToString());
|
|
|
int BindQty = (int)Convert.ToDouble(_kpsnTable[rowID]["BindQty"].ToString());
|
|
|
|
|
|
return Qty == BindQty;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断所有的 KPSNStep2 是否都绑满了
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private bool IsAllBindFull()
|
|
|
{
|
|
|
for (int i = 0; i < _kpsnTable.Count; i++)
|
|
|
{
|
|
|
if (!IsBindFull(i))
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
//判断是否允许扫描"PASS"码,通过时间间隔
|
|
|
private bool IsAllowPass()
|
|
|
{
|
|
|
//如果不在限制的工位集合范围则返回TRUE
|
|
|
if (_passIntervalLimit.IndexOf(_terminalID.ToString() + ",") < 0)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
try
|
|
|
{
|
|
|
TimeSpan ts1 = new TimeSpan(DateTime.Now.Ticks);
|
|
|
TimeSpan ts2 = new TimeSpan(_lastPassDatetime.Ticks);
|
|
|
TimeSpan ts = ts1.Subtract(ts2).Duration();
|
|
|
|
|
|
long diffValue = Convert.ToInt64(ts.TotalMilliseconds);
|
|
|
if (diffValue >= _passIntervalValue)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
private void KPSN_VisibleChanged(object sender, EventArgs e)
|
|
|
{
|
|
|
txtSN.Focus();
|
|
|
}
|
|
|
|
|
|
private void KPSN_Load(object sender, EventArgs e)
|
|
|
{
|
|
|
txtSN.Focus();
|
|
|
}
|
|
|
|
|
|
private void txtSN_Enter(object sender, EventArgs e)
|
|
|
{
|
|
|
txtSN.SelectAll();
|
|
|
txtSN.BackColor = Color.PeachPuff;
|
|
|
}
|
|
|
|
|
|
private void txtSN_Leave(object sender, EventArgs e)
|
|
|
{
|
|
|
txtSN.BackColor = Color.White;
|
|
|
}
|
|
|
|
|
|
private void dgbKPItems_SelectionChanged(object sender, EventArgs e)
|
|
|
{
|
|
|
dgbKPItems.ClearSelection();
|
|
|
txtSN.Focus();
|
|
|
}
|
|
|
|
|
|
//lvf 2021/03/05 定时刷新sn焦点
|
|
|
private void timRefreshFocus_Tick(object sender, EventArgs e)
|
|
|
{
|
|
|
txtSN.Focus();
|
|
|
}
|
|
|
}
|
|
|
}
|