using Estsh.Client.Common.HttpClientUtil;
using System.Collections;
using System.Data;
using System.Text;
namespace Estsh.Client.StepLibrary
{
class RouteHelper
{
private HttpClientHelper httpClient = null;
public RouteHelper(HttpClientHelper _httpClient)
{
httpClient = _httpClient;
}
///
/// 错误信息
///
public string ErrorMessage { get; private set; }
///
/// 检查过程条码的当前流程是否正确
///
/// 过程条码
/// 工位 ID
/// 流程是否正确
public bool CheckRoute(string sn, int terminalID)
{
ErrorMessage = string.Empty;
DataRow SNRow = GetSerialNumberData(sn);
if (SNRow == null)
{
ErrorMessage = "条码 " + sn + " 不存在";
return false;
}
int routeID = Convert.ToInt32(SNRow["route_id"].ToString());
if (routeID == 0)
{
ErrorMessage = "未查询到 " + sn + " 对应的流程";
return false;
}
int status = Convert.ToInt32(SNRow["current_status"]);
if (status == 1)
{
ErrorMessage = "条码 " + sn + " 属于不良品";
return false;
}
int ProcessID = GetProcessID(terminalID);
if (ProcessID == 0)
{
ErrorMessage = "未查询到 " + terminalID + " 对应的制程编号";
return false;
}
int LastProcessID = GetRouteLastProcessID(routeID);
if (LastProcessID == 0)
{
ErrorMessage = "获取流程 " + routeID + " 的最后一站失败";
return false;
}
int FirstProcessID = GetRouteFirstProcessID(routeID);
if (FirstProcessID == 0)
{
ErrorMessage = "获取流程 " + routeID + " 的第一站失败";
return false;
}
// 上线
if (ProcessID == FirstProcessID)
{
if (SNRow["process_id"].ToString() != "0")
{
ErrorMessage = "条码已经上线," + sn;
return false;
}
}
// 条码的当前制程
int CurrentProcessID = Convert.ToInt32(SNRow["process_id"]);
if (!CheckRouteProcessID(routeID, ProcessID, CurrentProcessID))
{
string CurrentProcessName = GetProcessName(CurrentProcessID);
if (CurrentProcessID == 0)
CurrentProcessName = "待上线";
ErrorMessage = "流程错误,最后工站: " + CurrentProcessName;
return false;
}
// 下线
if (ProcessID == LastProcessID)
{
if (SNRow["next_process"].ToString() == "0" && SNRow["process_id"].ToString() != "0")
{
ErrorMessage = "条码已经下线," + sn;
return false;
}
}
return true;
}
///
/// 良品,走到下一个流程
///
/// 过程条码
/// 工站编号
/// 执行结果
public bool RouteGO(string sn, int terminalID)
{
DataRow SNRow = GetSerialNumberData(sn);
if (SNRow == null)
{
ErrorMessage = "条码 " + sn + " 不存在";
return false;
}
int routeID = Convert.ToInt32(SNRow["route_id"].ToString());
if (routeID == 0)
{
ErrorMessage = "未查询到 " + sn + " 对应的流程";
return false;
}
int status = Convert.ToInt32(SNRow["current_status"]);
if (status == 1)
{
ErrorMessage = "条码 " + sn + " 属于不良品";
return false;
}
int ProcessID = GetProcessID(terminalID);
if (ProcessID == 0)
{
ErrorMessage = "未查询到 " + terminalID + " 对应的制程编号";
return false;
}
int LastProcessID = GetRouteLastProcessID(routeID);
if (LastProcessID == 0)
{
ErrorMessage = "获取流程 " + routeID + " 的最后一站失败";
return false;
}
int FirstProcessID = GetRouteFirstProcessID(routeID);
if (FirstProcessID == 0)
{
ErrorMessage = "获取流程 " + routeID + " 的第一站失败";
return false;
}
// 上线
if (ProcessID == FirstProcessID)
{
if (SNRow["process_id"].ToString() != "0")
{
ErrorMessage = "条码已经上线," + sn;
return false;
}
return SNGo(sn, terminalID, routeID, ProcessID, 0);
}
// 条码的当前制程
int CurrentProcessID = Convert.ToInt32(SNRow["process_id"]);
if (!CheckRouteProcessID(routeID, ProcessID, CurrentProcessID))
{
string CurrentProcessName = GetProcessName(CurrentProcessID);
if (CurrentProcessID == 0)
CurrentProcessName = "待上线";
ErrorMessage = "流程错误,最后工站: " + CurrentProcessName;
return false;
}
// 下线
if (ProcessID == LastProcessID)
{
if (SNRow["next_process"].ToString() == "0" && SNRow["process_id"].ToString() != "0")
{
ErrorMessage = "条码已经下线," + sn;
return false;
}
return SNGo(sn, terminalID, routeID, ProcessID, 2);
}
// 下一站
return SNGo(sn, terminalID, routeID, ProcessID, 1);
}
///
/// 更新条码相关的数据
///
/// 条码
/// 工站编号
/// 流程编号
/// 制程编号
/// 状态, 0=上线,1=下一站,2=下线
/// 是否更新成功
private bool SNGo(string sn, int terminalID, int routeID, int ProcessID, int status)
{
List SqlStrings = new List();
List> Parameters = new List>();
string Sql;
Dictionary Params = new Dictionary(1);
// 更新条码状态
Sql = GetSqlForUpdateSNStatus(sn, terminalID, routeID, ProcessID, status == 2);
if (string.IsNullOrEmpty(Sql))
return false;
SqlStrings.Add(Sql);
Parameters.Add(Params);
// 插入历史记录
SqlStrings.Add("insert into g_sn_travel select * from g_sn_status where serial_number=@sn");
Params.Add("@sn", sn);
Parameters.Add(Params);
if (status != 1)
{
int WorkorderID = GetWorkorderIDBySN(sn);
if (WorkorderID == -1)
return false;
// 更新工单的上线时间
SqlStrings.Add(GetSqlForUpdateWorkorder(WorkorderID, status == 0));
Params = new Dictionary(1);
Params.Add("@workorder_id", WorkorderID);
Parameters.Add(Params);
}
// 由事务批次执行方式改为单个 SQL 执行,解决偶发性死锁的问题
for (int i = 0; i < SqlStrings.Count; i++)
{
httpClient.Execute(SqlStrings[i], Parameters[i]);
}
return true;
}
///
/// 获取更新工单的 SQL 语句(带有 @workorder_id 变量,需要填充)
///
/// 工单编号
/// true=上线时间,false=下线时间
/// UPDATE SQL 语句
private string GetSqlForUpdateWorkorder(int workorderID, bool inPDLine)
{
Dictionary Values = new Dictionary();
DateTime time = DateTime.Parse(httpClient.GetServerTime());
// 上线
if (inPDLine)
{
Values.Add("in_pdline_ymd", time.ToString("yyyy-MM-dd"));
Values.Add("in_pdline_hms", time.ToString("HH:mm:ss"));
}
else // 下线
{
Values.Add("out_pdline_ymd", time.ToString("yyyy-MM-dd"));
Values.Add("out_pdline_hms", time.ToString("HH:mm:ss"));
}
return httpClient.Update("g_workorder", Values, " where ruid=@workorder_id",false);
}
///
/// 根据过程条码查询对应的工单编号
///
/// 过程条码
/// 工单编号
private int GetWorkorderIDBySN(string sn)
{
string SqlString =
"select c.ruid from g_sn_status a, g_workorder_detail b, g_workorder c " +
"where a.wo_detail_id=b.ruid and b.workorder_id=c.ruid and a.serial_number=@sn";
Dictionary Params = new Dictionary(1);
Params.Add("@sn", sn);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
{
StringBuilder SqlStringBuilder = new StringBuilder(1024);
SqlStringBuilder.Append("select b.ruid from g_sn_status a, g_workorder_base b ");
SqlStringBuilder.Append("where a.workorder=b.workorder_no and a.serial_number=@sn ");
dt = httpClient.GetEntityList(SqlStringBuilder.ToString(), Params);
if (!CheckDataTableInvalid(dt))
{
ErrorMessage = "根据过程条码查询工单编号失败, " + sn;
return -1;
}
}
return Convert.ToInt32(dt[0][0].ToString());
}
///
/// 获取更新过程条码的 SQL 语句(带有 @sn 变量,需要填充)
///
/// 过程条码
/// 工站编号
/// 流程编号
/// 制程编号
/// 下线标志,下线时 next_process = 0
/// UPDATE SQL 语句
private string GetSqlForUpdateSNStatus(string sn, int terminalID, int routeID, int ProcessID, bool isOutPDLine)
{
List TerminalData = GetTerminalData(terminalID);
if (!CheckDataTableInvalid(TerminalData))
{
ErrorMessage = "UpdateSNStatus(), 获取工站数据失败";
return string.Empty;
}
Dictionary Values = new Dictionary();
Values.Add("pdline_id", Convert.ToInt32(TerminalData[0]["pdline_id"].ToString()));
Values.Add("stage_id", Convert.ToInt32(TerminalData[0]["stage_id"].ToString()));
Values.Add("terminal_id", terminalID);
Values.Add("process_id", ProcessID);
Values.Add("in_process_time", GetOutProcessTime(sn));
Values.Add("out_process_time", httpClient.GetServerTime().ToString());
if (isOutPDLine)
Values.Add("next_process", 0);
else
Values.Add("next_process", GetRouteNextProcessID(routeID, ProcessID));
return httpClient.Update("g_sn_status", Values, " where serial_number=@sn", false);
}
///
/// 获取工站数据
///
/// 工站编号
/// 工站数据
private List GetTerminalData(int terminalID)
{
string SqlString =
"select * from sys_terminal where terminal_id=@terminal_id";
Dictionary Params = new Dictionary(1);
Params.Add("@terminal_id", terminalID);
return httpClient.GetEntityList(SqlString, Params);
}
///
/// 获取过程条码的出站时间
///
/// 过程条码
/// 出站时间
private string GetOutProcessTime(string sn)
{
string SqlString =
"select out_process_time from g_sn_status where serial_number=@sn";
Dictionary Params = new Dictionary(1);
Params.Add("@sn", sn);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return string.Empty;
return dt[0][0].ToString();
}
///
/// 获取流程中下一站的 ID
///
/// 流程编号
/// 当前站的 process id
/// 下一站的 process id
public int GetRouteNextProcessID(int routeID, int processID)
{
string SqlString =
"select next_process_id from sys_route_detail where route_id=@route_id and process_id=@process_id";
Dictionary Params = new Dictionary(1);
Params.Add("@route_id", routeID);
Params.Add("@process_id", processID);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return 0;
return Convert.ToInt32(dt[0][0].ToString());
}
///
/// 获取过程条码的信息
///
/// 过程条码
/// 过程条码信息
public DataRow GetSerialNumberData(string sn)
{
string SqlString =
"select * from g_sn_status where serial_number=@serial_number";
Dictionary Params = new Dictionary(1);
Params.Add("@serial_number", sn);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return null;
return dt[0];
}
///
/// 检查数据表是否有效
///
///
///
public bool CheckDataTableInvalid(List dt)
{
if (dt == null)
return false;
if (dt.Count == 0)
return false;
return true;
}
///
/// 根据 TerminalID 获取 ProcessID
///
/// Terminal ID
/// Process ID
public int GetProcessID(int terminalID)
{
string SqlString =
"select process_id from sys_terminal where terminal_id=@terminal_id";
Dictionary Params = new Dictionary(1);
Params.Add("@terminal_id", terminalID);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return 0;
return Convert.ToInt32(dt[0][0].ToString());
}
///
/// 获取流程中最后一站的 ID
///
/// 流程编号
/// 最后一站的 process id
public int GetRouteLastProcessID(int routeID)
{
string SqlString =
"select top 1 next_process_id from sys_route_detail where route_id=@route_id order by seq desc";
Dictionary Params = new Dictionary(1);
Params.Add("@route_id", routeID);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return 0;
return Convert.ToInt32(dt[0][0].ToString());
}
///
/// 获取流程中第一站的 ID
///
/// 流程编号
/// 第一站的 process id
public int GetRouteFirstProcessID(int routeID)
{
string SqlString =
"select top 1 next_process_id from sys_route_detail where route_id=@route_id order by seq";
Dictionary Params = new Dictionary(1);
Params.Add("@route_id", routeID);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return 0;
return Convert.ToInt32(dt[0][0].ToString());
}
///
/// 判断当前的制程是否在流程允许通过的范围内
///
/// 流程编号
/// 工站对应的制程编号
/// 条码对应的制程编号
/// 是否可以通过
public bool CheckRouteProcessID(int routeID, int processID, int currentProcessID)
{
string SqlString =
"select process_id from sys_route_detail where route_id=@route_id and next_process_id=@process_id and result=0 order by seq";
Dictionary Params = new Dictionary(2);
Params.Add("@route_id", routeID);
Params.Add("@process_id", processID);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return false;
int PreviousProcessID = Convert.ToInt32(dt[0][0].ToString());
if (IsNecessaryProcess(routeID, PreviousProcessID))
{
if (currentProcessID == PreviousProcessID)
return true;
else
return false;
}
else
{
if (currentProcessID == PreviousProcessID)
return true;
}
return CheckRouteProcessID(routeID, PreviousProcessID, currentProcessID);
}
///
/// 判断流程中的某一制程是否为 必须经过 制程
///
/// 流程编号
/// 制程编号
/// true=必须,false=不必须
public bool IsNecessaryProcess(int routeID, int processID)
{
string SqlString =
"select necessary from sys_route_detail where route_id=@route_id and next_process_id=@process_id and result=0 order by seq";
Dictionary Params = new Dictionary(2);
Params.Add("@route_id", routeID);
Params.Add("@process_id", processID);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return false;
return dt[0][0].ToString() == "Y" ? true : false;
}
///
/// 获取制程名称
///
/// 制程编号
/// 制程名称
public string GetProcessName(int processID)
{
string SqlString =
"select process_name from sys_process where process_id=@process_id";
Dictionary Params = new Dictionary(1);
Params.Add("@process_id", processID);
List dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return string.Empty;
return dt[0][0].ToString();
}
///
/// 根据工位ID和条码查询当前工位是否需要流程管控
///
///
///
///
public bool GetProcessIsNecessary(int terminalID, string sn)
{
StringBuilder querySen = new StringBuilder(1024);
querySen.AppendLine("SELECT necessary ");
querySen.AppendLine("FROM dbo.sys_route_detail ");
querySen.AppendLine("WHERE next_process_id = ( SELECT process_id ");
querySen.AppendLine(" FROM sys_terminal ");
querySen.AppendLine(" WHERE terminal_id = @terminal_id ");
querySen.AppendLine(" ) ");
querySen.AppendLine(" AND route_id = ( SELECT route_id ");
querySen.AppendLine(" FROM dbo.g_sn_status ");
querySen.AppendLine(" WHERE serial_number = @sn ");
querySen.AppendLine(" ) ");
Dictionary Params = new Dictionary(2);
Params.Add("@terminal_id", terminalID);
Params.Add("@sn", sn);
List dt = httpClient.GetEntityList(querySen.ToString(), Params);
if (!CheckDataTableInvalid(dt))
return false;
return dt[0][0].ToString().ToUpper() == "Y" ? true : false;
}
}
}