You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

656 lines
22 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage { get; private set; }
/// <summary>
/// 检查过程条码的当前流程是否正确
/// </summary>
/// <param name="sn">过程条码</param>
/// <param name="terminalID">工位 ID</param>
/// <returns>流程是否正确</returns>
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;
}
/// <summary>
/// 良品,走到下一个流程
/// </summary>
/// <param name="sn">过程条码</param>
/// <param name="terminalID">工站编号</param>
/// <returns>执行结果</returns>
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);
}
/// <summary>
/// 更新条码相关的数据
/// </summary>
/// <param name="sn">条码</param>
/// <param name="terminalID">工站编号</param>
/// <param name="routeID">流程编号</param>
/// <param name="ProcessID">制程编号</param>
/// <param name="status">状态, 0=上线1=下一站2=下线</param>
/// <returns>是否更新成功</returns>
private bool SNGo(string sn, int terminalID, int routeID, int ProcessID, int status)
{
List<string> SqlStrings = new List<string>();
List<Dictionary<string, object>> Parameters = new List<Dictionary<string, object>>();
string Sql;
Dictionary<string, object> Params = new Dictionary<string, object>(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<string, object>(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;
}
/// <summary>
/// 获取更新工单的 SQL 语句(带有 @workorder_id 变量,需要填充)
/// </summary>
/// <param name="workorderID">工单编号</param>
/// <param name="inPDLine">true=上线时间false=下线时间</param>
/// <returns>UPDATE SQL 语句</returns>
private string GetSqlForUpdateWorkorder(int workorderID, bool inPDLine)
{
Dictionary<string, object> Values = new Dictionary<string, object>();
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);
}
/// <summary>
/// 根据过程条码查询对应的工单编号
/// </summary>
/// <param name="sn">过程条码</param>
/// <returns>工单编号</returns>
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<string, object> Params = new Dictionary<string, object>(1);
Params.Add("@sn", sn);
List<dynamic> 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());
}
/// <summary>
/// 获取更新过程条码的 SQL 语句(带有 @sn 变量,需要填充)
/// </summary>
/// <param name="sn">过程条码</param>
/// <param name="terminalID">工站编号</param>
/// <param name="routeID">流程编号</param>
/// <param name="ProcessID">制程编号</param>
/// <param name="isOutPDLine">下线标志,下线时 next_process = 0</param>
/// <returns>UPDATE SQL 语句</returns>
private string GetSqlForUpdateSNStatus(string sn, int terminalID, int routeID, int ProcessID, bool isOutPDLine)
{
List<dynamic> TerminalData = GetTerminalData(terminalID);
if (!CheckDataTableInvalid(TerminalData))
{
ErrorMessage = "UpdateSNStatus(), 获取工站数据失败";
return string.Empty;
}
Dictionary<string, object> Values = new Dictionary<string, object>();
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);
}
/// <summary>
/// 获取工站数据
/// </summary>
/// <param name="terminalID">工站编号</param>
/// <returns>工站数据</returns>
private List<dynamic> GetTerminalData(int terminalID)
{
string SqlString =
"select * from sys_terminal where terminal_id=@terminal_id";
Dictionary<string, object> Params = new Dictionary<string, object>(1);
Params.Add("@terminal_id", terminalID);
return httpClient.GetEntityList(SqlString, Params);
}
/// <summary>
/// 获取过程条码的出站时间
/// </summary>
/// <param name="sn">过程条码</param>
/// <returns>出站时间</returns>
private string GetOutProcessTime(string sn)
{
string SqlString =
"select out_process_time from g_sn_status where serial_number=@sn";
Dictionary<string, object> Params = new Dictionary<string, object>(1);
Params.Add("@sn", sn);
List<dynamic> dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return string.Empty;
return dt[0][0].ToString();
}
/// <summary>
/// 获取流程中下一站的 ID
/// </summary>
/// <param name="routeID">流程编号</param>
/// <param name="processID">当前站的 process id</param>
/// <returns>下一站的 process id</returns>
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<string, object> Params = new Dictionary<string, object>(1);
Params.Add("@route_id", routeID);
Params.Add("@process_id", processID);
List<dynamic> dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return 0;
return Convert.ToInt32(dt[0][0].ToString());
}
/// <summary>
/// 获取过程条码的信息
/// </summary>
/// <param name="sn">过程条码</param>
/// <returns>过程条码信息</returns>
public DataRow GetSerialNumberData(string sn)
{
string SqlString =
"select * from g_sn_status where serial_number=@serial_number";
Dictionary<string, object> Params = new Dictionary<string, object>(1);
Params.Add("@serial_number", sn);
List<dynamic> dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return null;
return dt[0];
}
/// <summary>
/// 检查数据表是否有效
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public bool CheckDataTableInvalid(List<dynamic> dt)
{
if (dt == null)
return false;
if (dt.Count == 0)
return false;
return true;
}
/// <summary>
/// 根据 TerminalID 获取 ProcessID
/// </summary>
/// <param name="terminalID">Terminal ID</param>
/// <returns>Process ID</returns>
public int GetProcessID(int terminalID)
{
string SqlString =
"select process_id from sys_terminal where terminal_id=@terminal_id";
Dictionary<string, object> Params = new Dictionary<string, object>(1);
Params.Add("@terminal_id", terminalID);
List<dynamic> dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return 0;
return Convert.ToInt32(dt[0][0].ToString());
}
/// <summary>
/// 获取流程中最后一站的 ID
/// </summary>
/// <param name="routeID">流程编号</param>
/// <returns>最后一站的 process id</returns>
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<string, object> Params = new Dictionary<string, object>(1);
Params.Add("@route_id", routeID);
List<dynamic> dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return 0;
return Convert.ToInt32(dt[0][0].ToString());
}
/// <summary>
/// 获取流程中第一站的 ID
/// </summary>
/// <param name="routeID">流程编号</param>
/// <returns>第一站的 process id</returns>
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<string, object> Params = new Dictionary<string, object>(1);
Params.Add("@route_id", routeID);
List<dynamic> dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return 0;
return Convert.ToInt32(dt[0][0].ToString());
}
/// <summary>
/// 判断当前的制程是否在流程允许通过的范围内
/// </summary>
/// <param name="routeID">流程编号</param>
/// <param name="processID">工站对应的制程编号</param>
/// <param name="currentProcessID">条码对应的制程编号</param>
/// <returns>是否可以通过</returns>
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<string, object> Params = new Dictionary<string, object>(2);
Params.Add("@route_id", routeID);
Params.Add("@process_id", processID);
List<dynamic> 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);
}
/// <summary>
/// 判断流程中的某一制程是否为 必须经过 制程
/// </summary>
/// <param name="routeID">流程编号</param>
/// <param name="processID">制程编号</param>
/// <returns>true=必须false=不必须</returns>
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<string, object> Params = new Dictionary<string, object>(2);
Params.Add("@route_id", routeID);
Params.Add("@process_id", processID);
List<dynamic> dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return false;
return dt[0][0].ToString() == "Y" ? true : false;
}
/// <summary>
/// 获取制程名称
/// </summary>
/// <param name="processID">制程编号</param>
/// <returns>制程名称</returns>
public string GetProcessName(int processID)
{
string SqlString =
"select process_name from sys_process where process_id=@process_id";
Dictionary<string, object> Params = new Dictionary<string, object>(1);
Params.Add("@process_id", processID);
List<dynamic> dt = httpClient.GetEntityList(SqlString, Params);
if (!CheckDataTableInvalid(dt))
return string.Empty;
return dt[0][0].ToString();
}
/// <summary>
/// 根据工位ID和条码查询当前工位是否需要流程管控
/// </summary>
/// <param name="terminalID"></param>
/// <param name="sn"></param>
/// <returns></returns>
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<string, object> Params = new Dictionary<string, object>(2);
Params.Add("@terminal_id", terminalID);
Params.Add("@sn", sn);
List<dynamic> dt = httpClient.GetEntityList(querySen.ToString(), Params);
if (!CheckDataTableInvalid(dt))
return false;
return dt[0][0].ToString().ToUpper() == "Y" ? true : false;
}
}
}