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; } } }