|
|
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 GYKPSNP : StepBase
|
|
|
{
|
|
|
private StepLibraryAPP app = null;
|
|
|
private List<dynamic> _kpsnTable = null; //绑定数据
|
|
|
private delegate void DeleGrdBind(List<dynamic> dt);
|
|
|
int _terminalID = 0;
|
|
|
|
|
|
////PASS上一次成功扫描时间
|
|
|
//private DateTime _lastPassDatetime;
|
|
|
|
|
|
//PASS扫描间隔
|
|
|
private int _passIntervalValue = 2000;
|
|
|
|
|
|
//PASS间隔限制工位集合
|
|
|
private string _passIntervalLimit = string.Empty;
|
|
|
|
|
|
|
|
|
public GYKPSNP()
|
|
|
{
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
dgbKPItems.AutoGenerateColumns = false;
|
|
|
dgbKPItems.DataSource = null;
|
|
|
|
|
|
Complate(this, e);
|
|
|
ShowMessage(this, "green|上一个已完成,请继续操作!");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// KPSN 的类型
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
List<dynamic> dtTemp = app.keyDataTemp(input);
|
|
|
if (dtTemp.Count > 0)
|
|
|
{
|
|
|
string terIDTemp = dtTemp[0]["terminal_id"].ToString();
|
|
|
string snTemp = dtTemp[0]["serial_number"].ToString();
|
|
|
bool resultV = app.moveKeyPasts(terIDTemp, snTemp, el_no);
|
|
|
}
|
|
|
|
|
|
if (IsAllBindFull())
|
|
|
{
|
|
|
//需要绑定的关键零部件都绑定完成后再进行KPSN的数据插入
|
|
|
for (int i = 0; i < _kpsnTable.Count; i++)
|
|
|
{
|
|
|
bool insert_kpsn = false;
|
|
|
// 插入 KPSN 数据
|
|
|
insert_kpsn = app.InsertKPSNTemp(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());
|
|
|
string _sn = Context["serial_number"].ToString();
|
|
|
|
|
|
app = new StepLibraryAPP(httpClient);
|
|
|
|
|
|
////清除之前此工位绑定的关键零部件
|
|
|
//app.deleteKeyPart(_sn, _terminalID.ToString());
|
|
|
|
|
|
string _PartNo = app.GetPartNo(_sn);
|
|
|
string rule = app.GetRuleNo(_PartNo);
|
|
|
string partLocation = app.GetPartLoc(_PartNo);
|
|
|
|
|
|
_kpsnTable = app.GetBindData(_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>
|
|
|
/// 更新 KPSN TABLE
|
|
|
/// </summary>
|
|
|
/// <param name="rowID">行号</param>
|
|
|
/// <param name="kpsn">KPSN</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>
|
|
|
/// 匹配 KPSN RULE
|
|
|
/// </summary>
|
|
|
/// <param name="kpsn">KPSN</param>
|
|
|
/// <param name="kpType">关键零件的类型(取自 sys_part_sn_rule.type)</param>
|
|
|
/// <returns>匹配成功返回 KPSN RULE 的行号,失败返回 -1</returns>
|
|
|
private int MatchKPSNRule(string kpsn, 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().ToUpper().Trim();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
// 匹配 RULE1
|
|
|
if (startPos1 > 0 && endPos1 >= startPos1)
|
|
|
{
|
|
|
string subStr = "";
|
|
|
try
|
|
|
{
|
|
|
subStr = kpsn.Substring(startPos1 - 1, endPos1 - startPos1 + 1);
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
//条码长度不够自动补10位
|
|
|
kpsn = kpsn + "0001230045";
|
|
|
subStr = kpsn.Substring(startPos1 - 1, endPos1 - startPos1 + 1);
|
|
|
}
|
|
|
string[] fixArr = fix1.Split('/');
|
|
|
if (Array.Exists(fixArr, str => str.Equals(subStr)) == false)
|
|
|
{
|
|
|
if (kpsn.Contains("0001230045"))
|
|
|
{
|
|
|
kpsn = kpsn.Replace("0001230045", "");
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
ShowMessage(this, "red|条码输入错误!");
|
|
|
|
|
|
return -2;
|
|
|
}
|
|
|
|
|
|
int startPos2 = Convert.ToInt16(_kpsnTable[i]["from2"].ToString());
|
|
|
int endPos2 = Convert.ToInt16(_kpsnTable[i]["to2"].ToString());
|
|
|
string fix2 = _kpsnTable[i]["fix2"].ToString().ToUpper().Trim();
|
|
|
|
|
|
// 匹配 RULE2
|
|
|
if (startPos2 > 0 && endPos2 >= startPos2)
|
|
|
{
|
|
|
string subStr = kpsn.Substring(startPos2 - 1, endPos2 - startPos2 + 1);
|
|
|
string[] fixArr = fix2.Split('/');
|
|
|
if (Array.Exists(fixArr, str => str.Equals(subStr)) == false)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//获取不需要校验关键零部件条码唯一性的工位集合
|
|
|
string terminalIDList = app.validataLimit("DoNotCheckKPSNUnique");
|
|
|
if (!terminalIDList.Contains(_terminalID.ToString()))
|
|
|
{
|
|
|
if (isValidateUnique.ToUpper() == "Y")
|
|
|
{
|
|
|
if (app.ExistsKPSN(kpsn,_terminalID))
|
|
|
{
|
|
|
ShowMessage(this, "red|此关键零部件条码已经绑定在其他产品!");
|
|
|
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (isValidateLength.ToUpper() == "Y")
|
|
|
{
|
|
|
if (lenght != kpsn.Length)
|
|
|
{
|
|
|
ShowMessage(this, "red|此关键零部件条码长度不一致!(" + lenght + ")");
|
|
|
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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>
|
|
|
/// 判断 KPSN 是否绑满
|
|
|
/// </summary>
|
|
|
/// <param name="rowID">KPSN 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>
|
|
|
/// 判断所有的 KPSN 是否都绑满了
|
|
|
/// </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();
|
|
|
}
|
|
|
}
|
|
|
}
|