|
|
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 KPSNP : StepBase
|
|
|
{
|
|
|
private StepLibraryAPP app = null;
|
|
|
private List<dynamic> _kpsnTable = null; //绑定数据
|
|
|
private delegate void DeleGrdBind(List<dynamic> dt);
|
|
|
private int _terminalID = 0;
|
|
|
private string _sn = "";
|
|
|
string _stationType = "";
|
|
|
|
|
|
////PASS上一次成功扫描时间
|
|
|
//private DateTime _lastPassDatetime;
|
|
|
|
|
|
//PASS扫描间隔
|
|
|
private int _passIntervalValue = 2000;
|
|
|
|
|
|
//PASS间隔限制工位集合
|
|
|
private string _passIntervalLimit = string.Empty;
|
|
|
|
|
|
|
|
|
public KPSNP()
|
|
|
{
|
|
|
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 = _sn;
|
|
|
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(_terminalID.ToString());
|
|
|
if (Context["station_type"].ToString() == "B")
|
|
|
{
|
|
|
app.updateOnLineStatus(_sn, pdlineID);
|
|
|
}
|
|
|
|
|
|
dgbKPItems.AutoGenerateColumns = false;
|
|
|
dgbKPItems.DataSource = null;
|
|
|
|
|
|
Complate(this, e);
|
|
|
ShowMessage(this, "green|上一个已完成,请继续操作!");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// KPSN 的类型
|
|
|
int RowNo = -1;
|
|
|
int ErrorNo = 0;
|
|
|
bool ErrorState = false;
|
|
|
try
|
|
|
{
|
|
|
ErrorNo = MatchKPSNRule(input, _terminalID, out RowNo);
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
ShowMessage(this, "red|条码输入错误!");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
|
|
|
switch (ErrorNo)
|
|
|
{
|
|
|
case 1:
|
|
|
case 4:
|
|
|
ShowMessage(this, "red|系统异常,请联系管理员并检查零件条码!");
|
|
|
resetFocus();
|
|
|
ErrorState = false;
|
|
|
break;
|
|
|
case 2:
|
|
|
ShowMessage(this, "red|零件条码长度不正确,请检查零件条码信息!");
|
|
|
resetFocus();
|
|
|
ErrorState = false;
|
|
|
break;
|
|
|
case 3:
|
|
|
ShowMessage(this, "red|零件条码重复绑定!");
|
|
|
resetFocus();
|
|
|
ErrorState = false;
|
|
|
break;
|
|
|
case 6:
|
|
|
ShowMessage(this, "red|零件条码特征码不正确,请检查零件条码信息!");
|
|
|
resetFocus();
|
|
|
ErrorState = false;
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if (RowNo == -1)
|
|
|
{
|
|
|
resetFocus();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//更新已扫描条码
|
|
|
if (!UpdateKPSNTable(RowNo, input))
|
|
|
{
|
|
|
resetFocus();
|
|
|
}
|
|
|
|
|
|
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() + "数据失败,请重试");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 工步执行完成后调用此方法
|
|
|
Complate(this, e);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ShowMessage(this, "green|请扫描下一个关键零件");
|
|
|
resetFocus();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 重置光标
|
|
|
/// </summary>
|
|
|
private void resetFocus()
|
|
|
{
|
|
|
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());
|
|
|
_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.GetBindData(_PartNo, _terminalID);
|
|
|
if (_kpsnTable.Count == 0)
|
|
|
{
|
|
|
if (_stationType != "A")
|
|
|
{
|
|
|
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, int terminalID, out int RowNo)
|
|
|
{
|
|
|
RowNo = -1; ;
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
|
|
|
for (; 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();
|
|
|
|
|
|
string subStr = "";
|
|
|
|
|
|
string kpsnSN = _kpsnTable[i]["kpsn"].ToString();
|
|
|
|
|
|
if (!string.IsNullOrEmpty(kpsnSN))
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
try
|
|
|
{
|
|
|
// 匹配 RULE1
|
|
|
if (startPos1 > 0 && endPos1 >= startPos1)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
subStr = kpsn.Substring(startPos1 - 1, endPos1 - startPos1 + 1);
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
if (isValidateLength.ToUpper() == "Y")
|
|
|
{
|
|
|
if (lenght != kpsn.Length)
|
|
|
{
|
|
|
return 2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
string[] fixArr = fix1.Split('/');
|
|
|
if (Array.Exists(fixArr, str => str.Equals(subStr)) == false)
|
|
|
{
|
|
|
return 6;
|
|
|
}
|
|
|
|
|
|
if (isValidateUnique.ToUpper() == "Y")
|
|
|
{
|
|
|
if (app.ExistsKPSN(kpsn, _terminalID))
|
|
|
{
|
|
|
return 3;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
RowNo = i;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
return 7;
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
return 4;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <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();
|
|
|
}
|
|
|
|
|
|
private void timRefreshFocus_Tick(object sender, EventArgs e)
|
|
|
{
|
|
|
txtSN.Focus();
|
|
|
}
|
|
|
|
|
|
private void dgbKPItems_SelectionChanged_1(object sender, EventArgs e)
|
|
|
{
|
|
|
dgbKPItems.ClearSelection();
|
|
|
}
|
|
|
}
|
|
|
}
|