diff --git a/Common/09MesDataFunction/MesDataFunction/14MisDataFunctionDB/MisDataFun.DB.cs b/Common/09MesDataFunction/MesDataFunction/14MisDataFunctionDB/MisDataFun.DB.cs index 6047738..5810bc1 100644 --- a/Common/09MesDataFunction/MesDataFunction/14MisDataFunctionDB/MisDataFun.DB.cs +++ b/Common/09MesDataFunction/MesDataFunction/14MisDataFunctionDB/MisDataFun.DB.cs @@ -212,13 +212,14 @@ namespace MisDataFunDll /// /// /// - public static DataTable IOT_ReqData_UpLoad_IsSend(string opName, string OrderFrom, string reqType) + public static DataTable IOT_ReqData_UpLoad_IsSend(string opName, string OrderFrom, string reqType, string engineID = "") { string produceName = "接口_IOT接口_报工记录_是否报工判断"; - SqlParameter[] thisParms = new SqlParameter[3]; + SqlParameter[] thisParms = new SqlParameter[4]; thisParms[0] = new System.Data.SqlClient.SqlParameter("@工位号", opName); thisParms[1] = new System.Data.SqlClient.SqlParameter("@订单号", OrderFrom); thisParms[2] = new System.Data.SqlClient.SqlParameter("@报工类型", reqType); + thisParms[3] = new System.Data.SqlClient.SqlParameter("@工件编号", engineID ?? ""); DataAccess.ExecuteStoredProcedure(produceName, ref thisParms, out DataTable dt); return dt; } @@ -1772,6 +1773,19 @@ namespace MisDataFunDll return dt; } + /// + /// 根据工件编号查询派工订单执行计划信息 + /// + public static DataTable XD_GetPlanInfoByEngineID(string engineID) + { + DataTable dt = new DataTable(); + string procedureName = "XD_派工订单执行计划_按工件编号查询"; + SqlParameter[] thisParms = new SqlParameter[1]; + thisParms[0] = new System.Data.SqlClient.SqlParameter("@工件编号", engineID ?? ""); + DataAccess.ExecuteStoredProcedure(procedureName, ref thisParms, out dt); + return dt; + } + /// /// 报警工位记录表_MOBY_查询 /// diff --git a/DatabaseScripts/CallWebApi_FactoryMes_JobFinished_断路器质量聚合.sql b/DatabaseScripts/CallWebApi_FactoryMes_JobFinished_断路器质量聚合.sql new file mode 100644 index 0000000..7169610 --- /dev/null +++ b/DatabaseScripts/CallWebApi_FactoryMes_JobFinished_断路器质量聚合.sql @@ -0,0 +1,177 @@ +ALTER PROCEDURE [dbo].[CallWebApi_FactoryMes_JobFinished] + @订单号 nvarchar(50) = null, + @工序号 nvarchar(50) = null, + @工件编号 nvarchar(100) = null +AS +BEGIN + SET NOCOUNT ON + + declare @开工时间 datetime + declare @结束时间 datetime + declare @操作时间 datetime + declare @节拍 int + declare @是否合格 int=0 + declare @是否断路器聚合 bit = 0 + + if(@工序号 like 'AC06%' and charindex('-', @工序号) = 0) + begin + set @是否断路器聚合 = 1 + end + + -- 1、获取当前触发报工工件的开完工时间 + select top(1) + @开工时间=[到达时间], + @结束时间=[离开时间], + @节拍=[在线时间], + @操作时间=操作时间, + @是否合格=是否合格 + from [测量数据发动机在线状态] + where 发动机号=@工件编号 and 工位号=@工序号 + order by ID desc + + -- 如果开完工数据没有,手动报工使用当前时间兜底 + if(@开工时间 is null or @开工时间 = '') + begin + SET @开工时间 = GETDATE() + SET @结束时间 = GETDATE() + SET @节拍 = 0 + SET @操作时间 = GETDATE() + SET @是否合格 = 1 + end + + -- 表1:订单任务信息 + SELECT TOP(1) a.[订单ID],[任务ID],[工序ID],[工序编号],[工序名称],产品编号,1 as 完工数量, + FORMAT(@开工时间, 'yyyy-MM-dd HH:mm:ss') as 开工时间, + FORMAT(@结束时间, 'yyyy-MM-dd HH:mm:ss') as 结束时间, + @节拍 as 节拍, + FORMAT(@操作时间, 'yyyy-MM-dd HH:mm:ss') as 最后修改时间, + b.产品型号 + FROM [生产计划_派工订单_工序任务] a + inner join [生产计划_派工订单_执行计划] b on a.workOrderNo=b.订单号 + where a.workOrderNo=@订单号 and a.工序编号=@工序号 + order by [任务号] + + -- 2、获取检验信息 + declare @Id_tagCF int=0 + select top(1) @Id_tagCF=Id_tagCF + from [测量数据合格索引] + where EngineID=@工件编号 and 工位号=@工序号 + order by Id_tagCF desc + + -- 获取当前订单的物料号(产品编号) + declare @物料号 nvarchar(100) = '' + select top(1) @物料号 = 产品编号 + from [生产计划_派工订单_工序任务] + where workOrderNo=@订单号 and 工序编号=@工序号 + order by [任务号] + + -- 获取该物料号+工序号下最新下发的模板ID + declare @最新模板ID nvarchar(100) = '' + select top(1) @最新模板ID = Id + from [MOM_检验模板] + where MaterialCode = @物料号 and ProcedureCode = @工序号 + order by [操作时间] desc + + if(@是否断路器聚合 = 1) + begin + declare @聚合是否合格 int = 1 + + ;with 最新索引 as + ( + select + i.Id_tagCF, + i.EngineID, + i.工位号, + i.合格标志, + row_number() over(partition by i.EngineID, i.工位号 order by i.Id_tagCF desc) as rn + from [测量数据合格索引] i + inner join [生产计划_派工订单_执行计划] p on p.工件编号 = i.EngineID + where p.订单号 = @订单号 + and i.工位号 = @工序号 + and isnull(p.小机型, '') in ('1','2','3') + ) + select @聚合是否合格 = case when count(1) = 0 then @是否合格 else min(isnull(合格标志, 1)) end + from 最新索引 + where rn = 1 + + ;with 最新索引 as + ( + select + i.Id_tagCF, + i.EngineID, + i.工位号, + row_number() over(partition by i.EngineID, i.工位号 order by i.Id_tagCF desc) as rn + from [测量数据合格索引] i + inner join [生产计划_派工订单_执行计划] p on p.工件编号 = i.EngineID + where p.订单号 = @订单号 + and i.工位号 = @工序号 + and isnull(p.小机型, '') in ('1','2','3') + ) + SELECT a.[工位号],a.[Id_tagCF],a.[EngineID], + @聚合是否合格 as 是否合格, + a.[测量项目],a.测量位置 as 质检项目名称, + CASE + WHEN TRY_CAST(a.[TagValue] AS FLOAT) IS NOT NULL + THEN CAST(ROUND(CAST(a.[TagValue] AS FLOAT), 2) AS NVARCHAR(100)) + ELSE a.[TagValue] + END AS TagValue, + [IsGoodBad] as 检测结果,上限值,下限值,理论值,a.测量单位, + c.TemplateId as 检验项目ID, t.Code as 模板编号, c.LineNum as 检验项目编号 + FROM 最新索引 x + inner join [测量数据合格] a on a.Id_tagCF = x.Id_tagCF + LEFT JOIN MOM_检验模板_关联表 b ON a.TagID = b.TagID + LEFT JOIN MOM_检验模板_检验项目 c ON c.TemplateId = @最新模板ID AND c.InspectionItemName = b.模板项名称 + LEFT JOIN MOM_检验模板 t ON t.Id = @最新模板ID + where x.rn = 1 + and a.测量项目 != '备用' + and a.TagValue != '0' + order by a.EngineID, a.id desc + end + else if(@Id_tagCF = 0 or @Id_tagCF is null) -- 前端手动报工用 + begin + SELECT [工位号],[Id_tagCF],[EngineID],@是否合格 as 是否合格,[测量项目],测量位置 as 质检项目名称, + CASE + WHEN TRY_CAST([TagValue] AS FLOAT) IS NOT NULL + THEN CAST(ROUND(CAST([TagValue] AS FLOAT), 2) AS NVARCHAR(100)) + ELSE [TagValue] + END AS TagValue, + [IsGoodBad] as 检测结果,上限值,下限值,理论值,测量单位, + '' as 检验项目ID, '' as 模板编号, '' as 检验项目编号 + FROM [测量数据合格] + where Id_tagCF=2 + order by id desc + end + else + begin + SELECT a.[工位号],[Id_tagCF],[EngineID],@是否合格 as 是否合格,a.[测量项目],a.测量位置 as 质检项目名称, + CASE + WHEN TRY_CAST(a.[TagValue] AS FLOAT) IS NOT NULL + THEN CAST(ROUND(CAST(a.[TagValue] AS FLOAT), 2) AS NVARCHAR(100)) + ELSE a.[TagValue] + END AS TagValue, + [IsGoodBad] as 检测结果,上限值,下限值,理论值,a.测量单位, + c.TemplateId as 检验项目ID, t.Code as 模板编号, c.LineNum as 检验项目编号 + FROM [测量数据合格] a + LEFT JOIN MOM_检验模板_关联表 b ON a.TagID = b.TagID + LEFT JOIN MOM_检验模板_检验项目 c ON c.TemplateId = @最新模板ID AND c.InspectionItemName = b.模板项名称 + LEFT JOIN MOM_检验模板 t ON t.Id = @最新模板ID + where EngineID=@工件编号 and a.工位号=@工序号 and Id_tagCF=@Id_tagCF and a.测量项目 != '备用' and TagValue != '0' + order by a.id desc + end + + -- 3、获取物料信息(从PLC扫码物料记录读取) + SELECT [工位号] + ,[产品编号] as [工件编号] + ,[工单号] as [订单号] + ,'' as [任务号] + ,[物料代码] as 物料编号 + ,[物料批次号] + ,[物料流水号] + ,[物料名称] + ,1 as [数量] + FROM [dbo].[XD_物料记录] + where [工位号]=@工序号 and [产品编号]=@工件编号 and isnull([物料代码], '') != '' + order by [操作时间] + + -- 4、获取工时信息 +END diff --git a/DatabaseScripts/接口_IOT接口_报工记录_是否报工判断_断路器规则.sql b/DatabaseScripts/接口_IOT接口_报工记录_是否报工判断_断路器规则.sql new file mode 100644 index 0000000..c7aa0c9 --- /dev/null +++ b/DatabaseScripts/接口_IOT接口_报工记录_是否报工判断_断路器规则.sql @@ -0,0 +1,63 @@ +ALTER PROCEDURE [dbo].[接口_IOT接口_报工记录_是否报工判断] +@工位号 nvarchar(50) = 'OP10', +@订单号 nvarchar(50) = 'SA10025', +@报工类型 nvarchar(50) = '开工', +@工件编号 nvarchar(100) = null +AS +SET NOCOUNT ON + +-- 已成功报工的工序不重复报工 +declare @成功次数 int +select @成功次数 = count(1) +from 接口_IOT接口_报工记录 +where 工位号 = @工位号 + and 订单号 = @订单号 + and 报工类型 = @报工类型 + and 报工结果 = 1 + +if(@成功次数 > 0) +begin + select 2 as result,@工位号 + '订单号:'+@订单号+'产品工序已'+@报工类型+',无需二次报工' as msg + return +end + +-- 断路器主工位:静端进站开工,拐臂箱出站完工;副工位如 AC0603-1 不参与此判断 +if(@工位号 like 'AC06%' and charindex('-', @工位号) = 0) +begin + declare @当前工件编号 nvarchar(100) = null + declare @小机型 int = null + + set @当前工件编号 = nullif(@工件编号, '') + + if(@当前工件编号 is null) + begin + select top 1 @当前工件编号 = 变速器序列号 + from 北汽福田工位状态监控MOBY + where 工位号 = @工位号 + order by ID desc + end + + select top 1 @小机型 = try_convert(int, 小机型) + from 生产计划_派工订单_执行计划 + where 工件编号 = @当前工件编号 + + if(@小机型 is null) + begin + select 2 as result,@工位号 + '订单号:'+@订单号+'产品工序'+@报工类型+',未查询到工件编号['+isnull(@当前工件编号,'')+']对应的小机型' as msg + return + end + + if(@报工类型 = '开工' and @小机型 <> 1) + begin + select 2 as result,@工位号 + '订单号:'+@订单号+'产品工序开工,非静端不进行报工' as msg + return + end + + if(@报工类型 = '完工' and @小机型 <> 3) + begin + select 2 as result,@工位号 + '订单号:'+@订单号+'产品工序完工,非拐臂箱不进行报工' as msg + return + end +end + +select 1 as result,'' as msg diff --git a/Interface_WebAPI/SlMesDbIterface/ExternalDataSync.csproj b/Interface_WebAPI/SlMesDbIterface/ExternalDataSync.csproj index 812ee07..d7ba396 100644 --- a/Interface_WebAPI/SlMesDbIterface/ExternalDataSync.csproj +++ b/Interface_WebAPI/SlMesDbIterface/ExternalDataSync.csproj @@ -212,8 +212,12 @@ + + + + @@ -519,4 +523,4 @@ - \ No newline at end of file + diff --git a/Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/LGAGV_BusinessLogic.cs b/Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/LGAGV_BusinessLogic.cs new file mode 100644 index 0000000..d1503ec --- /dev/null +++ b/Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/LGAGV_BusinessLogic.cs @@ -0,0 +1,364 @@ +using System; +using System.Configuration; +using System.Data; +using System.Data.SqlClient; +using System.Web.Http; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using MisDataSaveDate.Helper; +using static MisDataSaveDate.Helper.ApiLogHelper; +using WebApi; + +namespace MisDataSaveDate +{ + /// + /// 临工AGV接口业务处理。 + /// + public class LGAGV_BusinessLogic + { + private const string DirectionMesToAgv = "MES_TO_AGV"; + private const string DirectionAgvToMes = "AGV_TO_MES"; + + /// + /// MES调用临工AGV两点任务接口。 + /// + public static LGAGV_CallResult CallAddTask(LGAGV_AddTaskRequest request) + { + if (request == null) + { + throw new Exception("AGV任务参数不能为空"); + } + if (string.IsNullOrWhiteSpace(request.requestTaskId)) + { + throw new Exception("任务ID(requestTaskId)不能为空"); + } + if (string.IsNullOrWhiteSpace(request.startPosition)) + { + throw new Exception("起点位置(startPosition)不能为空"); + } + if (string.IsNullOrWhiteSpace(request.endPosition)) + { + throw new Exception("终点位置(endPosition)不能为空"); + } + + return PostToAgv("AddTaskFromMes", "/api/mes/AddTaskFromMes", request, + request.requestTaskId, null, request.endPosition, null, request.materialCode, null); + } + + /// + /// MES调用临工AGV三点任务接口。 + /// + public static LGAGV_CallResult CallAddTask2(LGAGV_AddTask2Request request) + { + if (request == null) + { + throw new Exception("AGV任务参数不能为空"); + } + if (string.IsNullOrWhiteSpace(request.requestTaskId)) + { + throw new Exception("任务ID(requestTaskId)不能为空"); + } + if (string.IsNullOrWhiteSpace(request.startPosition)) + { + throw new Exception("起点位置(startPosition)不能为空"); + } + if (string.IsNullOrWhiteSpace(request.midPosition)) + { + throw new Exception("中间位置(midPosition)不能为空"); + } + if (string.IsNullOrWhiteSpace(request.endPosition)) + { + throw new Exception("终点位置(endPosition)不能为空"); + } + + return PostToAgv("AddTaskFromMes2", "/api/mes/AddTaskFromMes2", request, + request.requestTaskId, null, request.endPosition, null, request.materialCode, null); + } + + /// + /// MES调用临工AGV放行接口。 + /// + public static LGAGV_CallResult CallAllowLeave(LGAGV_AllowLeaveRequest request) + { + if (request == null) + { + throw new Exception("放行参数不能为空"); + } + if (string.IsNullOrWhiteSpace(request.requestId)) + { + throw new Exception("请求ID(requestId)不能为空"); + } + if (string.IsNullOrWhiteSpace(request.position)) + { + throw new Exception("位置(position)不能为空"); + } + + request.allowLeave = 1; + return PostToAgv("AllowLeave", "/api/mes/AllowLeave", request, + null, request.requestId, request.position, null, null, request.agvNo); + } + + /// + /// 处理临工AGV到达/离开回调。 + /// + public static string ProcessStatusUpdate(string url, [FromBody] JObject jobj) + { + var result = LGAGV_Response.Success(); + string requestText = jobj?.ToString() ?? ""; + SaveLog_Interface_Request(url, 2, requestText, out int aid); + + LGAGV_StatusUpdateRequest request = null; + try + { + if (jobj == null) + { + throw new Exception("请求参数不能为空"); + } + + request = JsonConvert.DeserializeObject(requestText); + if (request == null) + { + throw new Exception("请求参数格式不正确"); + } + if (string.IsNullOrWhiteSpace(request.requestId)) + { + throw new Exception("请求ID(requestId)不能为空"); + } + if (string.IsNullOrWhiteSpace(request.position)) + { + throw new Exception("位置(position)不能为空"); + } + if (request.type != 1 && request.type != 2) + { + throw new Exception("类型(type)只支持1到达、2离开"); + } + + string procedureName = request.type == 1 ? "LG_AGV_库位Moby_AGV到达" : "LG_AGV_库位Moby_AGV离开"; + var param = new SqlParameter[] + { + new SqlParameter("@requestId", request.requestId ?? ""), + new SqlParameter("@position", request.position ?? ""), + new SqlParameter("@materialCode", request.materialCode ?? ""), + new SqlParameter("@agvNo", request.agvNo ?? "") + }; + ExecuteResultProcedure(procedureName, ref param); + + SaveInterfaceRecord("StatusUpdate", DirectionAgvToMes, request.position, request.position, + null, request.requestId, request.position, request.type, request.materialCode, request.agvNo, + "", requestText, "", 1, ""); + + string typeDesc = request.type == 1 ? "到达" : "离开"; + SaveMesLog("LGAGV_StatusUpdate", $"临工AGV{typeDesc}:位置={request.position}, requestId={request.requestId}, AGV={request.agvNo}", MesLogType.INFO); + } + catch (Exception ex) + { + result = LGAGV_Response.Fail(ex.Message); + SaveInterfaceRecord("StatusUpdate", DirectionAgvToMes, request?.position, request?.position, + null, request?.requestId, request?.position, request?.type, request?.materialCode, request?.agvNo, + "", requestText, "", 2, ex.Message); + SaveMesLog("LGAGV_StatusUpdate", ex.Message, MesLogType.ERROR); + } + + string responseText = JsonConvert.SerializeObject(result); + SaveLog_Interface_Response(responseText, aid); + return responseText; + } + + /// + /// 处理临工AGV任务结果回调。 + /// + public static string ProcessTaskResult(string url, [FromBody] JObject jobj) + { + var result = LGAGV_Response.Success(); + string requestText = jobj?.ToString() ?? ""; + SaveLog_Interface_Request(url, 2, requestText, out int aid); + + LGAGV_TaskResultRequest request = null; + try + { + if (jobj == null) + { + throw new Exception("请求参数不能为空"); + } + + request = JsonConvert.DeserializeObject(requestText); + if (request == null) + { + throw new Exception("请求参数格式不正确"); + } + if (string.IsNullOrWhiteSpace(request.requestTaskId)) + { + throw new Exception("任务ID(requestTaskId)不能为空"); + } + + bool isSuccess = IsAgvSuccess(request.status); + var param = new SqlParameter[] + { + new SqlParameter("@requestTaskId", request.requestTaskId ?? ""), + new SqlParameter("@status", request.status ?? ""), + new SqlParameter("@agvNo", request.agvNo ?? ""), + new SqlParameter("@message", request.message ?? ""), + new SqlParameter("@materialCode", request.materialCode ?? "") + }; + ExecuteResultProcedure("LG_AGV_库位Moby_任务结果", ref param); + + SaveInterfaceRecord("TaskResult", DirectionAgvToMes, null, null, + request.requestTaskId, null, null, null, request.materialCode, request.agvNo, request.status, + requestText, "", isSuccess ? 1 : 2, request.message ?? ""); + + SaveMesLog("LGAGV_TaskResult", $"临工AGV任务结果:requestTaskId={request.requestTaskId}, status={request.status}, AGV={request.agvNo}, message={request.message}", MesLogType.INFO); + } + catch (Exception ex) + { + result = LGAGV_Response.Fail(ex.Message); + SaveInterfaceRecord("TaskResult", DirectionAgvToMes, null, null, + request?.requestTaskId, null, null, null, request?.materialCode, request?.agvNo, request?.status, + requestText, "", 2, ex.Message); + SaveMesLog("LGAGV_TaskResult", ex.Message, MesLogType.ERROR); + } + + string responseText = JsonConvert.SerializeObject(result); + SaveLog_Interface_Response(responseText, aid); + return responseText; + } + + public static void SaveInterfaceRecord(string interfaceName, string direction, string positionCode, string workStation, + string requestTaskId, string requestId, string position, int? type, string materialCode, string agvNo, string status, + string requestText, string responseText, int isSuccess, string errorMessage) + { + var param = new SqlParameter[] + { + new SqlParameter("@库位号", positionCode ?? ""), + new SqlParameter("@工位号", workStation ?? ""), + new SqlParameter("@接口名称", interfaceName ?? ""), + new SqlParameter("@接口方向", direction ?? ""), + new SqlParameter("@requestTaskId", requestTaskId ?? ""), + new SqlParameter("@requestId", requestId ?? ""), + new SqlParameter("@position", position ?? ""), + new SqlParameter("@type", type.HasValue ? (object)type.Value : DBNull.Value), + new SqlParameter("@materialCode", materialCode ?? ""), + new SqlParameter("@agvNo", agvNo ?? ""), + new SqlParameter("@status", status ?? ""), + new SqlParameter("@message", errorMessage ?? ""), + new SqlParameter("@请求报文", requestText ?? ""), + new SqlParameter("@响应报文", responseText ?? ""), + new SqlParameter("@是否成功", isSuccess), + new SqlParameter("@错误信息", errorMessage ?? "") + }; + DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("LG_AGV_接口记录_增加", ref param, out string errMessage); + if (!string.IsNullOrEmpty(errMessage)) + { + SaveMesLog("LGAGV_InterfaceRecord", errMessage, MesLogType.ERROR); + } + } + + public static bool IsAgvSuccess(string codeOrStatus) + { + string value = (codeOrStatus ?? "").Trim().ToLower(); + return value == "0" || value == "200" || value == "true" || value == "success" || value == "成功"; + } + + private static LGAGV_CallResult PostToAgv(string interfaceName, string path, object request, + string requestTaskId, string requestId, string position, int? type, string materialCode, string agvNo) + { + string baseUrl = ConfigurationManager.AppSettings["LGAGV_BaseUrl"]; + if (string.IsNullOrWhiteSpace(baseUrl)) + { + throw new Exception("未配置 LGAGV_BaseUrl"); + } + + string interfaceUrl = baseUrl.TrimEnd('/') + path; + string requestText = JsonConvert.SerializeObject(request); + SaveLog_Interface_Request("LGAGV_" + interfaceName, 1, requestText, out int aid); + + string responseText = Post.Post_Auto(interfaceUrl, requestText); + SaveLog_Interface_Response(responseText, aid); + + JObject response = ParseResponse(responseText); + string codeText = response["code"]?.ToString() ?? response["result"]?.ToString() ?? ""; + string message = response["desc"]?.ToString() ?? response["message"]?.ToString() ?? response["msg"]?.ToString() ?? ""; + bool success = IsAgvSuccess(codeText); + if (response["success"] != null) + { + if (bool.TryParse(response["success"].ToString(), out bool successValue)) + { + success = successValue; + } + } + + SaveInterfaceRecord(interfaceName, DirectionMesToAgv, position, position, requestTaskId, requestId, position, + type, materialCode, agvNo, codeText, requestText, responseText, success ? 1 : 2, success ? "" : message); + + if (success) + { + SaveMesLog("LGAGV_" + interfaceName, $"临工AGV接口调用成功:{interfaceName}, position={position}, requestTaskId={requestTaskId}", MesLogType.INFO); + } + else + { + SaveMesLog("LGAGV_" + interfaceName, $"临工AGV接口调用失败:{interfaceName}, code={codeText}, message={message}", MesLogType.ERROR); + } + + return new LGAGV_CallResult + { + Success = success, + Code = ToInt(codeText, success ? 0 : 500), + Message = message, + InterfaceUrl = interfaceUrl, + RequestText = requestText, + ResponseText = responseText, + Response = response + }; + } + + private static JObject ParseResponse(string responseText) + { + if (string.IsNullOrWhiteSpace(responseText)) + { + return new JObject + { + { "code", 500 }, + { "message", "AGV返回空响应" }, + { "success", false } + }; + } + + try + { + return JObject.Parse(responseText); + } + catch (Exception ex) + { + return new JObject + { + { "code", 500 }, + { "message", "AGV返回非JSON响应:" + ex.Message }, + { "raw", responseText }, + { "success", false } + }; + } + } + + private static int ToInt(string value, int defaultValue) + { + if (int.TryParse(value, out int intValue)) + { + return intValue; + } + return defaultValue; + } + + private static void ExecuteResultProcedure(string procedureName, ref SqlParameter[] param) + { + DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure(procedureName, ref param, out DataTable dt, out string errMessage); + if (!string.IsNullOrEmpty(errMessage)) + { + throw new Exception(errMessage); + } + if (dt != null && dt.Rows.Count > 0 && dt.Columns.Contains("result") && dt.Rows[0]["result"].ToString() != "1") + { + string msg = dt.Columns.Contains("msg") ? dt.Rows[0]["msg"].ToString() : "存储过程执行失败"; + throw new Exception(msg); + } + } + } +} diff --git a/Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/LGAGV_Models.cs b/Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/LGAGV_Models.cs new file mode 100644 index 0000000..db77b26 --- /dev/null +++ b/Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/LGAGV_Models.cs @@ -0,0 +1,106 @@ +using Newtonsoft.Json.Linq; + +namespace MisDataSaveDate +{ + /// + /// 临工AGV两点任务请求。 + /// + public class LGAGV_AddTaskRequest + { + public string requestTaskId { get; set; } + public string startPosition { get; set; } + public string endPosition { get; set; } + public string materialCode { get; set; } + } + + /// + /// 临工AGV三点任务请求。 + /// + public class LGAGV_AddTask2Request + { + public string requestTaskId { get; set; } + public string startPosition { get; set; } + public string midPosition { get; set; } + public string endPosition { get; set; } + public string materialCode { get; set; } + } + + /// + /// 临工AGV放行请求。 + /// + public class LGAGV_AllowLeaveRequest + { + public string requestId { get; set; } + public string position { get; set; } + public string agvNo { get; set; } + public int allowLeave { get; set; } = 1; + } + + /// + /// 临工AGV到达/离开回调。 + /// + public class LGAGV_StatusUpdateRequest + { + public string requestId { get; set; } + public string position { get; set; } + public int type { get; set; } + public string materialCode { get; set; } + public string agvNo { get; set; } + } + + /// + /// 临工AGV任务执行结果回调。 + /// + public class LGAGV_TaskResultRequest + { + public string requestTaskId { get; set; } + public string status { get; set; } + public string agvNo { get; set; } + public string message { get; set; } + public string materialCode { get; set; } + } + + /// + /// 返回给临工AGV的通用响应。 + /// + public class LGAGV_Response + { + public int code { get; set; } + public string desc { get; set; } + public bool success { get; set; } + + public static LGAGV_Response Success(string desc = "成功") + { + return new LGAGV_Response + { + code = 0, + desc = desc, + success = true + }; + } + + public static LGAGV_Response Fail(string desc) + { + return new LGAGV_Response + { + code = 1, + desc = desc, + success = false + }; + } + } + + /// + /// MES调用临工AGV接口后的内部结果。 + /// + public class LGAGV_CallResult + { + public bool Success { get; set; } + public int Code { get; set; } + public string Message { get; set; } + public string InterfaceUrl { get; set; } + public string RequestText { get; set; } + public string ResponseText { get; set; } + public JObject Response { get; set; } + } +} diff --git a/Interface_WebAPI/SlMesDbIterface/WebAPI/Controller/AGVController.cs b/Interface_WebAPI/SlMesDbIterface/WebAPI/Controller/AGVController.cs index e2c2be2..17a652b 100644 --- a/Interface_WebAPI/SlMesDbIterface/WebAPI/Controller/AGVController.cs +++ b/Interface_WebAPI/SlMesDbIterface/WebAPI/Controller/AGVController.cs @@ -40,5 +40,35 @@ namespace MisDataSaveDate }; } + /// + /// 临工AGV到达/离开状态回调接口。 + /// + /// 临工AGV状态回调数据 + /// 处理结果 + [HttpPost] + [Route("agv/lgagv/statusUpdate")] + public HttpResponseMessage LGAGV_StatusUpdate([FromBody] JObject jobj) + { + return new HttpResponseMessage + { + Content = new StringContent(LGAGV_BusinessLogic.ProcessStatusUpdate(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json") + }; + } + + /// + /// 临工AGV任务结果回调接口。 + /// + /// 临工AGV任务结果数据 + /// 处理结果 + [HttpPost] + [Route("agv/lgagv/taskResult")] + public HttpResponseMessage LGAGV_TaskResult([FromBody] JObject jobj) + { + return new HttpResponseMessage + { + Content = new StringContent(LGAGV_BusinessLogic.ProcessTaskResult(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json") + }; + } + } } diff --git a/Interface_WebAPI/SlMesDbIterface/WebAPI/Controller/WEBController.cs b/Interface_WebAPI/SlMesDbIterface/WebAPI/Controller/WEBController.cs index ba93382..b640c57 100644 --- a/Interface_WebAPI/SlMesDbIterface/WebAPI/Controller/WEBController.cs +++ b/Interface_WebAPI/SlMesDbIterface/WebAPI/Controller/WEBController.cs @@ -99,6 +99,36 @@ namespace MisDataSaveDate }; } + /// + /// 临工AGV网页按钮调度接口。 + /// + /// 调度请求数据 + /// 处理结果 + [HttpPost] + [Route("web/LGAGV_Dispatch")] + public HttpResponseMessage LGAGV_Dispatch([FromBody] JObject jobj) + { + return new HttpResponseMessage + { + Content = new StringContent(LGWEB_BusinessLogic.WEB_DispatchAGV(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json") + }; + } + + /// + /// 临工AGV网页按钮放行接口。 + /// + /// 放行请求数据 + /// 处理结果 + [HttpPost] + [Route("web/LGAGV_AllowLeave")] + public HttpResponseMessage LGAGV_AllowLeave([FromBody] JObject jobj) + { + return new HttpResponseMessage + { + Content = new StringContent(LGWEB_BusinessLogic.WEB_AllowLeave(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json") + }; + } + /// /// 批量读取PLC点位值接口 /// 前端传递TagTypeCodeID数组和工位号,返回对应点位的值 @@ -131,4 +161,4 @@ namespace MisDataSaveDate }; } } -} \ No newline at end of file +} diff --git a/Interface_WebAPI/SlMesDbIterface/WebAPI/FactoryMES/CALL_Inerface_DataHandle.cs b/Interface_WebAPI/SlMesDbIterface/WebAPI/FactoryMES/CALL_Inerface_DataHandle.cs index e03c662..a7cfd56 100644 --- a/Interface_WebAPI/SlMesDbIterface/WebAPI/FactoryMES/CALL_Inerface_DataHandle.cs +++ b/Interface_WebAPI/SlMesDbIterface/WebAPI/FactoryMES/CALL_Inerface_DataHandle.cs @@ -24,6 +24,17 @@ namespace WebApi { public class CALL_Inerface_DataHandle { + private static bool TryCheckProcessReportAllowed(string opName, string engineID, string orderForm, string reqType) + { + DataTable isSendDT = MisDataFun.IOT_ReqData_UpLoad_IsSend(opName, orderForm, reqType, engineID); + if (isSendDT.Rows[0]["result"].ToString() != "1") + { + SaveMesLog($"工序{reqType}", isSendDT.Rows[0]["msg"].ToString(), MesLogType.ERROR); + return false; + } + return true; + } + /// /// 开工(工序) /// @@ -32,10 +43,8 @@ namespace WebApi /// public static void CALL_Inerface_JobStart(string OpName, string EngineID, string OrderForm) { - DataTable IsSendDT = MisDataFun.IOT_ReqData_UpLoad_IsSend(OpName, OrderForm, "完工"); - if (IsSendDT.Rows[0]["result"].ToString() != "1") + if (!TryCheckProcessReportAllowed(OpName, EngineID, OrderForm, "开工")) { - SaveMesLog("工序完工", IsSendDT.Rows[0]["msg"].ToString(), MesLogType.ERROR); return; } @@ -101,10 +110,8 @@ namespace WebApi /// public static void CALL_Inerface_JobFinished(string OpName, string EngineID, string OrderForm) { - DataTable IsSendDT = MisDataFun.IOT_ReqData_UpLoad_IsSend(OpName, OrderForm, "完工"); - if (IsSendDT.Rows[0]["result"].ToString() != "1") + if (!TryCheckProcessReportAllowed(OpName, EngineID, OrderForm, "完工")) { - SaveMesLog("工序完工", IsSendDT.Rows[0]["msg"].ToString(), MesLogType.ERROR); return; } diff --git a/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/LGWEB_BusinessLogic.cs b/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/LGWEB_BusinessLogic.cs new file mode 100644 index 0000000..dddc90d --- /dev/null +++ b/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/LGWEB_BusinessLogic.cs @@ -0,0 +1,319 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using System.Web.Http; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using MisDataSaveDate.Helper; +using static MisDataSaveDate.Helper.ApiLogHelper; + +namespace MisDataSaveDate +{ + /// + /// 临工AGV网页按钮业务处理。 + /// + public class LGWEB_BusinessLogic + { + /// + /// 网页按钮下发临工AGV搬运任务。 + /// + public static string WEB_DispatchAGV(string url, [FromBody] JObject jobj) + { + var result = new MsgResHeader + { + code = 200, + message = "", + Data = null + }; + + if (jobj == null) + { + result.code = 500; + result.message = "参数格式不正确!"; + return JsonConvert.SerializeObject(result); + } + + string requestText = jobj.ToString(); + SaveLog_Interface_Request(url, 2, requestText, out int aid); + + try + { + LGWEB_DispatchRequest request = JsonConvert.DeserializeObject(requestText); + if (request == null) + { + throw new Exception("请求参数格式不正确"); + } + if (string.IsNullOrWhiteSpace(request.routeCode)) + { + throw new Exception("路线编码(routeCode)不能为空"); + } + + LGWEB_RouteInfo route = GetRouteInfo(request.routeCode); + string startPosition = string.IsNullOrWhiteSpace(request.startPosition) ? route.StartPosition : request.startPosition; + string midPosition = string.IsNullOrWhiteSpace(request.midPosition) ? route.MidPosition : request.midPosition; + string endPosition = route.ActualEndPosition; + string requestTaskId = string.IsNullOrWhiteSpace(request.requestTaskId) ? Guid.NewGuid().ToString() : request.requestTaskId; + string materialCode = FirstText(request.materialCode, request.productCode, request.containerNo); + + if (string.IsNullOrWhiteSpace(startPosition)) + { + throw new Exception("起点位置不能为空,请检查路线配置或请求参数"); + } + if (string.IsNullOrWhiteSpace(endPosition)) + { + throw new Exception("终点位置不能为空,请检查路线配置"); + } + + LGAGV_CallResult agvResult; + if (string.Equals(route.InterfaceName, "AddTaskFromMes2", StringComparison.OrdinalIgnoreCase)) + { + agvResult = LGAGV_BusinessLogic.CallAddTask2(new LGAGV_AddTask2Request + { + requestTaskId = requestTaskId, + startPosition = startPosition, + midPosition = midPosition, + endPosition = endPosition, + materialCode = materialCode + }); + } + else + { + agvResult = LGAGV_BusinessLogic.CallAddTask(new LGAGV_AddTaskRequest + { + requestTaskId = requestTaskId, + startPosition = startPosition, + endPosition = endPosition, + materialCode = materialCode + }); + } + + SaveDispatchResult(request, route, requestTaskId, startPosition, midPosition, endPosition, materialCode, agvResult); + + result.code = agvResult.Success ? 200 : 500; + result.message = agvResult.Success ? "AGV调度成功" : $"AGV调度失败:{agvResult.Message}"; + result.Data = new + { + requestTaskId = requestTaskId, + routeCode = request.routeCode, + startPosition = startPosition, + midPosition = midPosition, + endPosition = endPosition, + originalEndPosition = route.OriginalEndPosition, + routeMessage = route.RouteMessage, + agvResponse = agvResult.Response + }; + } + catch (Exception ex) + { + result.code = 500; + result.message = ex.Message; + SaveMesLog("LGWEB_DispatchAGV", ex.Message, MesLogType.ERROR); + } + + string responseText = JsonConvert.SerializeObject(result); + SaveLog_Interface_Response(responseText, aid); + return responseText; + } + + /// + /// 网页按钮放行临工AGV离开。 + /// + public static string WEB_AllowLeave(string url, [FromBody] JObject jobj) + { + var result = new MsgResHeader + { + code = 200, + message = "", + Data = null + }; + + if (jobj == null) + { + result.code = 500; + result.message = "参数格式不正确!"; + return JsonConvert.SerializeObject(result); + } + + string requestText = jobj.ToString(); + SaveLog_Interface_Request(url, 2, requestText, out int aid); + + try + { + LGWEB_AllowLeaveRequest request = JsonConvert.DeserializeObject(requestText); + if (request == null) + { + throw new Exception("请求参数格式不正确"); + } + if (string.IsNullOrWhiteSpace(request.requestId)) + { + throw new Exception("请求ID(requestId)不能为空"); + } + if (string.IsNullOrWhiteSpace(request.position)) + { + throw new Exception("位置(position)不能为空"); + } + + LGAGV_CallResult agvResult = LGAGV_BusinessLogic.CallAllowLeave(new LGAGV_AllowLeaveRequest + { + requestId = request.requestId, + position = request.position, + agvNo = request.agvNo, + allowLeave = 1 + }); + + var param = new SqlParameter[] + { + new SqlParameter("@requestId", request.requestId ?? ""), + new SqlParameter("@position", request.position ?? ""), + new SqlParameter("@agvNo", request.agvNo ?? ""), + new SqlParameter("@操作人工号", request.operatorCode ?? ""), + new SqlParameter("@操作人姓名", request.operatorName ?? ""), + new SqlParameter("@备注", request.remark ?? ""), + new SqlParameter("@是否成功", agvResult.Success ? 1 : 2), + new SqlParameter("@错误信息", agvResult.Success ? "" : (agvResult.Message ?? "")) + }; + ExecuteResultProcedure("LG_AGV_库位Moby_允许离开", ref param); + + result.code = agvResult.Success ? 200 : 500; + result.message = agvResult.Success ? "AGV放行成功" : $"AGV放行失败:{agvResult.Message}"; + result.Data = new + { + requestId = request.requestId, + position = request.position, + agvResponse = agvResult.Response + }; + } + catch (Exception ex) + { + result.code = 500; + result.message = ex.Message; + SaveMesLog("LGWEB_AllowLeave", ex.Message, MesLogType.ERROR); + } + + string responseText = JsonConvert.SerializeObject(result); + SaveLog_Interface_Response(responseText, aid); + return responseText; + } + + private static LGWEB_RouteInfo GetRouteInfo(string routeCode) + { + var param = new SqlParameter[] + { + new SqlParameter("@路线编码", routeCode ?? "") + }; + DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("LG_AGV_路线_实际终点解析", ref param, out DataTable dt, out string errMessage); + if (!string.IsNullOrEmpty(errMessage)) + { + throw new Exception(errMessage); + } + if (dt == null || dt.Rows.Count == 0) + { + throw new Exception("路线解析无返回结果"); + } + + DataRow row = dt.Rows[0]; + string resultText = row.Table.Columns.Contains("result") ? row["result"].ToString() : "2"; + if (resultText != "1") + { + string msg = ReadColumn(row, "msg", "message"); + throw new Exception(string.IsNullOrWhiteSpace(msg) ? "路线不可用" : msg); + } + + return new LGWEB_RouteInfo + { + RouteCode = ReadColumn(row, "路线编码"), + StartPosition = ReadColumn(row, "起点位置"), + MidPosition = ReadColumn(row, "中间位置"), + OriginalEndPosition = ReadColumn(row, "原终点位置", "终点位置"), + ActualEndPosition = ReadColumn(row, "实际终点位置"), + InterfaceName = FirstText(ReadColumn(row, "调用接口"), "AddTaskFromMes"), + BusinessType = ReadColumn(row, "业务类型"), + TriggerMode = ReadColumn(row, "触发方式"), + SourceWorkStation = ReadColumn(row, "源工位号"), + TargetWorkStation = ReadColumn(row, "目标工位号"), + RouteMessage = ReadColumn(row, "msg", "message") + }; + } + + private static void SaveDispatchResult(LGWEB_DispatchRequest request, LGWEB_RouteInfo route, string requestTaskId, + string startPosition, string midPosition, string endPosition, string materialCode, LGAGV_CallResult agvResult) + { + var param = new SqlParameter[] + { + new SqlParameter("@路线编码", request.routeCode ?? ""), + new SqlParameter("@业务类型", route.BusinessType ?? ""), + new SqlParameter("@触发方式", string.IsNullOrWhiteSpace(route.TriggerMode) ? "WEB" : route.TriggerMode), + new SqlParameter("@订单号", request.orderNo ?? ""), + new SqlParameter("@产品编码", FirstText(request.productCode, request.materialCode)), + new SqlParameter("@产品型号", request.productModel ?? ""), + new SqlParameter("@器具号", request.containerNo ?? ""), + new SqlParameter("@requestTaskId", requestTaskId ?? ""), + new SqlParameter("@起点位置", startPosition ?? ""), + new SqlParameter("@中间位置", midPosition ?? ""), + new SqlParameter("@终点位置", endPosition ?? ""), + new SqlParameter("@原终点位置", route.OriginalEndPosition ?? ""), + new SqlParameter("@materialCode", materialCode ?? ""), + new SqlParameter("@调用接口", route.InterfaceName ?? ""), + new SqlParameter("@操作人工号", request.operatorCode ?? ""), + new SqlParameter("@操作人姓名", request.operatorName ?? ""), + new SqlParameter("@备注", request.remark ?? ""), + new SqlParameter("@是否成功", agvResult.Success ? 1 : 2), + new SqlParameter("@错误信息", agvResult.Success ? "" : (agvResult.Message ?? "")) + }; + ExecuteResultProcedure("LG_AGV_库位Moby_下发任务", ref param); + } + + private static string ReadColumn(DataRow row, params string[] columnNames) + { + foreach (string columnName in columnNames) + { + if (row.Table.Columns.Contains(columnName)) + { + return row[columnName]?.ToString() ?? ""; + } + } + return ""; + } + + private static string FirstText(params string[] values) + { + foreach (string value in values) + { + if (!string.IsNullOrWhiteSpace(value)) + { + return value; + } + } + return ""; + } + + private static void ExecuteResultProcedure(string procedureName, ref SqlParameter[] param) + { + DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure(procedureName, ref param, out DataTable dt, out string errMessage); + if (!string.IsNullOrEmpty(errMessage)) + { + throw new Exception(errMessage); + } + if (dt != null && dt.Rows.Count > 0 && dt.Columns.Contains("result") && dt.Rows[0]["result"].ToString() != "1") + { + string msg = dt.Columns.Contains("msg") ? dt.Rows[0]["msg"].ToString() : "存储过程执行失败"; + throw new Exception(msg); + } + } + + private class LGWEB_RouteInfo + { + public string RouteCode { get; set; } + public string StartPosition { get; set; } + public string MidPosition { get; set; } + public string OriginalEndPosition { get; set; } + public string ActualEndPosition { get; set; } + public string InterfaceName { get; set; } + public string BusinessType { get; set; } + public string TriggerMode { get; set; } + public string SourceWorkStation { get; set; } + public string TargetWorkStation { get; set; } + public string RouteMessage { get; set; } + } + } +} diff --git a/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/LGWEB_Models.cs b/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/LGWEB_Models.cs new file mode 100644 index 0000000..1c6261c --- /dev/null +++ b/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/LGWEB_Models.cs @@ -0,0 +1,34 @@ +namespace MisDataSaveDate +{ + /// + /// 临工AGV网页按钮调度请求。 + /// + public class LGWEB_DispatchRequest + { + public string routeCode { get; set; } + public string requestTaskId { get; set; } + public string startPosition { get; set; } + public string midPosition { get; set; } + public string materialCode { get; set; } + public string productCode { get; set; } + public string productModel { get; set; } + public string containerNo { get; set; } + public string orderNo { get; set; } + public string operatorCode { get; set; } + public string operatorName { get; set; } + public string remark { get; set; } + } + + /// + /// 临工AGV网页按钮放行请求。 + /// + public class LGWEB_AllowLeaveRequest + { + public string requestId { get; set; } + public string position { get; set; } + public string agvNo { get; set; } + public string operatorCode { get; set; } + public string operatorName { get; set; } + public string remark { get; set; } + } +} diff --git a/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/WEB_BusinessLogic.cs b/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/WEB_BusinessLogic.cs index 1631abc..4443eee 100644 --- a/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/WEB_BusinessLogic.cs +++ b/Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/WEB_BusinessLogic.cs @@ -80,7 +80,7 @@ namespace MisDataSaveDate throw new Exception("OperAtion_JobStart 缺少必要参数:工位号、订单号或工件编号"); } - CALL_Inerface_DataHandle.CALL_Inerface_JobStart(workStation1, orderNo1, workpieceNo1); + CALL_Inerface_DataHandle.CALL_Inerface_JobStart(workStation1, workpieceNo1, orderNo1); break; case "OperAtion_JobFinished": @@ -98,7 +98,7 @@ namespace MisDataSaveDate throw new Exception("OperAtion_JobFinished 缺少必要参数:工位号、订单号或工件编号"); } - CALL_Inerface_DataHandle.CALL_Inerface_JobFinished(workStation2, orderNo2, workpieceNo2); + CALL_Inerface_DataHandle.CALL_Inerface_JobFinished(workStation2, workpieceNo2, orderNo2); break; default: @@ -408,4 +408,4 @@ namespace MisDataSaveDate return retString; } } -} \ No newline at end of file +} diff --git a/MisDataFun_Exe/09MesDataFunction.dll b/MisDataFun_Exe/09MesDataFunction.dll index 930dbe5..004d241 100644 Binary files a/MisDataFun_Exe/09MesDataFunction.dll and b/MisDataFun_Exe/09MesDataFunction.dll differ diff --git a/MisDataFun_Exe/09MesDataFunction.pdb b/MisDataFun_Exe/09MesDataFunction.pdb index 96306ca..55d49df 100644 Binary files a/MisDataFun_Exe/09MesDataFunction.pdb and b/MisDataFun_Exe/09MesDataFunction.pdb differ diff --git a/MisDataFun_Exe/ExternalDataSync.exe b/MisDataFun_Exe/ExternalDataSync.exe index fe26901..54f97c8 100644 Binary files a/MisDataFun_Exe/ExternalDataSync.exe and b/MisDataFun_Exe/ExternalDataSync.exe differ diff --git a/MisDataFun_Exe/ExternalDataSync.pdb b/MisDataFun_Exe/ExternalDataSync.pdb index 49ce525..45cc53c 100644 Binary files a/MisDataFun_Exe/ExternalDataSync.pdb and b/MisDataFun_Exe/ExternalDataSync.pdb differ diff --git a/MisDataFun_Exe/Function1051.dll b/MisDataFun_Exe/Function1051.dll index ed0fecd..2a770a8 100644 Binary files a/MisDataFun_Exe/Function1051.dll and b/MisDataFun_Exe/Function1051.dll differ diff --git a/MisDataFun_Exe/Function1051.pdb b/MisDataFun_Exe/Function1051.pdb index b4c9576..34d6ab6 100644 Binary files a/MisDataFun_Exe/Function1051.pdb and b/MisDataFun_Exe/Function1051.pdb differ diff --git a/MisDataFun_Exe/Function1052.dll b/MisDataFun_Exe/Function1052.dll index 9d094b6..6ad31d1 100644 Binary files a/MisDataFun_Exe/Function1052.dll and b/MisDataFun_Exe/Function1052.dll differ diff --git a/MisDataFun_Exe/Function1052.pdb b/MisDataFun_Exe/Function1052.pdb index ca30208..761652d 100644 Binary files a/MisDataFun_Exe/Function1052.pdb and b/MisDataFun_Exe/Function1052.pdb differ diff --git a/MisDataFun_Exe/Function1053.dll b/MisDataFun_Exe/Function1053.dll index 9c4a5bb..2963e17 100644 Binary files a/MisDataFun_Exe/Function1053.dll and b/MisDataFun_Exe/Function1053.dll differ diff --git a/MisDataFun_Exe/Function1053.pdb b/MisDataFun_Exe/Function1053.pdb index eded3bb..0b060a5 100644 Binary files a/MisDataFun_Exe/Function1053.pdb and b/MisDataFun_Exe/Function1053.pdb differ diff --git a/MisDataFun_Exe/Function1054.dll b/MisDataFun_Exe/Function1054.dll index 5c7d86f..4827dcd 100644 Binary files a/MisDataFun_Exe/Function1054.dll and b/MisDataFun_Exe/Function1054.dll differ diff --git a/MisDataFun_Exe/Function1054.pdb b/MisDataFun_Exe/Function1054.pdb index bd2ba4a..159dcbd 100644 Binary files a/MisDataFun_Exe/Function1054.pdb and b/MisDataFun_Exe/Function1054.pdb differ diff --git a/MisDataFun_Exe/MisDataFun.exe b/MisDataFun_Exe/MisDataFun.exe index 3df2e95..8ad633b 100644 Binary files a/MisDataFun_Exe/MisDataFun.exe and b/MisDataFun_Exe/MisDataFun.exe differ diff --git a/MisDataFun_Exe/MisDataFun.pdb b/MisDataFun_Exe/MisDataFun.pdb index 3c8efb6..8412b8a 100644 Binary files a/MisDataFun_Exe/MisDataFun.pdb and b/MisDataFun_Exe/MisDataFun.pdb differ diff --git a/MisDataFun_Exe/MyLog4Net.dll b/MisDataFun_Exe/MyLog4Net.dll index 6271052..1bbb822 100644 Binary files a/MisDataFun_Exe/MyLog4Net.dll and b/MisDataFun_Exe/MyLog4Net.dll differ diff --git a/MisDataFun_Exe/MyLog4Net.pdb b/MisDataFun_Exe/MyLog4Net.pdb index c1669be..ea5e8a4 100644 Binary files a/MisDataFun_Exe/MyLog4Net.pdb and b/MisDataFun_Exe/MyLog4Net.pdb differ diff --git a/MisDataFunction/Function1051/OpcServer/EngineGetOver.cs b/MisDataFunction/Function1051/OpcServer/EngineGetOver.cs index ae34da7..07ad047 100644 --- a/MisDataFunction/Function1051/OpcServer/EngineGetOver.cs +++ b/MisDataFunction/Function1051/OpcServer/EngineGetOver.cs @@ -18,6 +18,7 @@ namespace MesServerFunctions /// private void EngineTypeGetOver_PLC(object e) { + string opName = ""; lock(lockBarcodeEngineTypeGetOver) { @@ -25,6 +26,7 @@ namespace MesServerFunctions { DeviceDriver_BasicData.CustomeEvetnArgs msgEvent = (DeviceDriver_BasicData.CustomeEvetnArgs)e; string OpName = Convert.ToString(msgEvent.OpName); + opName = OpName; int tagValue = Convert.ToInt32(msgEvent.TagValue); //判断PLC机型与MES机型是否一致 if (tagValue == 1) @@ -123,7 +125,10 @@ namespace MesServerFunctions } catch (Exception err) { - ////ApplicationLog.WriteLog(err, "Function08:EngineTypeGetOver_PLC"); + string logOpName = string.IsNullOrWhiteSpace(opName) ? "Function1051_EngineGetOver" : opName; + string logText = $"EngineTypeGetOver异常:异常={err.Message}"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(logOpName, logText, MisDataSaveDate.Helper.MesLogType.ERROR); + MyLog4Net.MyLogHelper.Error("Function1051_EngineGetOver", $"{logText}{Environment.NewLine}{err}"); } } diff --git a/MisDataFunction/Function1051/OpcServer/MaterialsVerify.cs b/MisDataFunction/Function1051/OpcServer/MaterialsVerify.cs index 51130ff..043341c 100644 --- a/MisDataFunction/Function1051/OpcServer/MaterialsVerify.cs +++ b/MisDataFunction/Function1051/OpcServer/MaterialsVerify.cs @@ -27,12 +27,33 @@ namespace MesServerFunctions //判断PLC机型与MES机型是否一致 if (tagValue == 1) { - int EngineTypeID;//机型代码 - int PartPallet_Code;//托盘编号 - string EngineType;//机型 - string EngineID;//工件编号 - string OrderForm; - MIS_BASE.GetEngineTypeFromPLC(OpName, out EngineTypeID, out EngineType, out EngineID, out PartPallet_Code, out OrderForm); + int EngineTypeID = 0;//机型代码 + int PartPallet_Code = 0;//托盘编号 + string EngineType = "";//机型 + string OrderForm = ""; + MIS_BASE.Read_EngineID(OpName, out string PLCEngineID); + MIS_BASE.Read_EngineID_MES(OpName, out string MESEngineID); + string EngineID = string.IsNullOrEmpty(PLCEngineID) ? MESEngineID : PLCEngineID; + + if (string.IsNullOrEmpty(EngineID)) + { + string msg = $"【{OpName}】PLC与MES产品编号点位均为空,继续按空产品信息保存物料扫码记录!"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(OpName, "MaterialsVerify " + msg, MisDataSaveDate.Helper.MesLogType.ERROR); + } + else + { + DataTable planDt = MisDataFun.XD_GetPlanInfoByEngineID(EngineID); + if (planDt.Rows.Count > 0) + { + OrderForm = planDt.Rows[0]["订单号"].ToString(); + EngineType = planDt.Rows[0]["产品型号"].ToString(); + } + else + { + string msg = $"【{OpName}】产品:{EngineID} 未在生产计划_派工订单_执行计划中查询到记录,继续保存物料扫码记录!"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(OpName, "MaterialsVerify " + msg, MisDataSaveDate.Helper.MesLogType.ERROR); + } + } int MaterialsTypeCode = Convert.ToInt32(MIS_BASE.ReadPLC(201, OpName)); string MaterialsCode = MIS_BASE.ReadPLC(40, OpName).ToString(); diff --git a/MisDataFunction/Function1051/OpcServer/MesRead.cs b/MisDataFunction/Function1051/OpcServer/MesRead.cs index 80abd35..e976f2b 100644 --- a/MisDataFunction/Function1051/OpcServer/MesRead.cs +++ b/MisDataFunction/Function1051/OpcServer/MesRead.cs @@ -16,6 +16,9 @@ namespace MesServerFunctions /// private void MesRead(object e) { + string opName = ""; + string engineID = ""; + string orderForm = ""; try { int EngineTypeID; @@ -32,12 +35,15 @@ namespace MesServerFunctions { DeviceDriver_BasicData.CustomeEvetnArgs msgEvent = (DeviceDriver_BasicData.CustomeEvetnArgs)e; string OpName = Convert.ToString(msgEvent.OpName); + opName = OpName; int tagValue = Convert.ToInt32(msgEvent.TagValue); if (tagValue == 1) { int qualityMask; MIS_BASE.GetEngineTypeFromPLC(OpName, out EngineTypeID, out EngineType, out EngineID,out PartPallet_Code, out OrderForm); + engineID = EngineID; + orderForm = OrderForm; //保存数据到线首表 先保存到 北汽福田变速器序列号总线上线 用于之前判断是否重号 // 保存质量数据 @@ -76,7 +82,10 @@ namespace MesServerFunctions } catch (Exception err) { - ////ApplicationLog.WriteLog(err, "Function08:MesReadOver"); + string logOpName = string.IsNullOrWhiteSpace(opName) ? "Function1051_MesRead" : opName; + string logText = $"MesRead异常:订单号={orderForm}, 工件编号={engineID}, 异常={err.Message}"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(logOpName, logText, MisDataSaveDate.Helper.MesLogType.ERROR); + MyLog4Net.MyLogHelper.Error("Function1051_MesRead", $"{logText}{Environment.NewLine}{err}"); } } diff --git a/MisDataFunction/Function1052/OpcServer/EngineGetOver.cs b/MisDataFunction/Function1052/OpcServer/EngineGetOver.cs index 276639f..d8c1d5f 100644 --- a/MisDataFunction/Function1052/OpcServer/EngineGetOver.cs +++ b/MisDataFunction/Function1052/OpcServer/EngineGetOver.cs @@ -14,12 +14,14 @@ namespace MesServerFunctions /// private void EngineTypeGetOver_PLC(object e) { + string opName = ""; { try { DeviceDriver_BasicData.CustomeEvetnArgs msgEvent = (DeviceDriver_BasicData.CustomeEvetnArgs)e; string OpName = Convert.ToString(msgEvent.OpName); + opName = OpName; int tagValue = Convert.ToInt32(msgEvent.TagValue); //判断PLC机型与MES机型是否一致 if (tagValue == 1) @@ -108,7 +110,10 @@ namespace MesServerFunctions } catch (Exception err) { - ////ApplicationLog.WriteLog(err, "Function08:EngineTypeGetOver_PLC"); + string logOpName = string.IsNullOrWhiteSpace(opName) ? "Function1052_EngineGetOver" : opName; + string logText = $"EngineTypeGetOver异常:异常={err.Message}"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(logOpName, logText, MisDataSaveDate.Helper.MesLogType.ERROR); + MyLog4Net.MyLogHelper.Error("Function1052_EngineGetOver", $"{logText}{Environment.NewLine}{err}"); } } diff --git a/MisDataFunction/Function1052/OpcServer/MaterialsVerify.cs b/MisDataFunction/Function1052/OpcServer/MaterialsVerify.cs index 51130ff..043341c 100644 --- a/MisDataFunction/Function1052/OpcServer/MaterialsVerify.cs +++ b/MisDataFunction/Function1052/OpcServer/MaterialsVerify.cs @@ -27,12 +27,33 @@ namespace MesServerFunctions //判断PLC机型与MES机型是否一致 if (tagValue == 1) { - int EngineTypeID;//机型代码 - int PartPallet_Code;//托盘编号 - string EngineType;//机型 - string EngineID;//工件编号 - string OrderForm; - MIS_BASE.GetEngineTypeFromPLC(OpName, out EngineTypeID, out EngineType, out EngineID, out PartPallet_Code, out OrderForm); + int EngineTypeID = 0;//机型代码 + int PartPallet_Code = 0;//托盘编号 + string EngineType = "";//机型 + string OrderForm = ""; + MIS_BASE.Read_EngineID(OpName, out string PLCEngineID); + MIS_BASE.Read_EngineID_MES(OpName, out string MESEngineID); + string EngineID = string.IsNullOrEmpty(PLCEngineID) ? MESEngineID : PLCEngineID; + + if (string.IsNullOrEmpty(EngineID)) + { + string msg = $"【{OpName}】PLC与MES产品编号点位均为空,继续按空产品信息保存物料扫码记录!"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(OpName, "MaterialsVerify " + msg, MisDataSaveDate.Helper.MesLogType.ERROR); + } + else + { + DataTable planDt = MisDataFun.XD_GetPlanInfoByEngineID(EngineID); + if (planDt.Rows.Count > 0) + { + OrderForm = planDt.Rows[0]["订单号"].ToString(); + EngineType = planDt.Rows[0]["产品型号"].ToString(); + } + else + { + string msg = $"【{OpName}】产品:{EngineID} 未在生产计划_派工订单_执行计划中查询到记录,继续保存物料扫码记录!"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(OpName, "MaterialsVerify " + msg, MisDataSaveDate.Helper.MesLogType.ERROR); + } + } int MaterialsTypeCode = Convert.ToInt32(MIS_BASE.ReadPLC(201, OpName)); string MaterialsCode = MIS_BASE.ReadPLC(40, OpName).ToString(); diff --git a/MisDataFunction/Function1052/OpcServer/MesRead.cs b/MisDataFunction/Function1052/OpcServer/MesRead.cs index 17a29af..c2e84ab 100644 --- a/MisDataFunction/Function1052/OpcServer/MesRead.cs +++ b/MisDataFunction/Function1052/OpcServer/MesRead.cs @@ -16,6 +16,9 @@ namespace MesServerFunctions /// private void MesRead(object e) { + string opName = ""; + string engineID = ""; + string orderForm = ""; { try { @@ -33,6 +36,7 @@ namespace MesServerFunctions { DeviceDriver_BasicData.CustomeEvetnArgs msgEvent = (DeviceDriver_BasicData.CustomeEvetnArgs)e; string OpName = Convert.ToString(msgEvent.OpName); + opName = OpName; int tagValue = Convert.ToInt32(msgEvent.TagValue); if (tagValue == 1) @@ -40,6 +44,8 @@ namespace MesServerFunctions int qualityMask; MIS_BASE.GetEngineTypeFromPLC(OpName, out EngineTypeID, out EngineType, out EngineID, out PartPallet_Code, out OrderForm); + engineID = EngineID; + orderForm = OrderForm; //MIS_BASE.GetEngineTypeFromPLC_MES(OpName, out EngineTypeID_MES, out EngineType_MES, out EngineID_MES, out OrderForm_MES); //保存数据到线首表 先保存到 北汽福田变速器序列号总线上线 用于之前判断是否重号 // 保存质量数据 @@ -79,7 +85,10 @@ namespace MesServerFunctions } catch (Exception err) { - ////ApplicationLog.WriteLog(err, "Function08:MesReadOver"); + string logOpName = string.IsNullOrWhiteSpace(opName) ? "Function1052_MesRead" : opName; + string logText = $"MesRead异常:订单号={orderForm}, 工件编号={engineID}, 异常={err.Message}"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(logOpName, logText, MisDataSaveDate.Helper.MesLogType.ERROR); + MyLog4Net.MyLogHelper.Error("Function1052_MesRead", $"{logText}{Environment.NewLine}{err}"); } } diff --git a/MisDataFunction/Function1053/OpcServer/MaterialsVerify.cs b/MisDataFunction/Function1053/OpcServer/MaterialsVerify.cs index 51130ff..043341c 100644 --- a/MisDataFunction/Function1053/OpcServer/MaterialsVerify.cs +++ b/MisDataFunction/Function1053/OpcServer/MaterialsVerify.cs @@ -27,12 +27,33 @@ namespace MesServerFunctions //判断PLC机型与MES机型是否一致 if (tagValue == 1) { - int EngineTypeID;//机型代码 - int PartPallet_Code;//托盘编号 - string EngineType;//机型 - string EngineID;//工件编号 - string OrderForm; - MIS_BASE.GetEngineTypeFromPLC(OpName, out EngineTypeID, out EngineType, out EngineID, out PartPallet_Code, out OrderForm); + int EngineTypeID = 0;//机型代码 + int PartPallet_Code = 0;//托盘编号 + string EngineType = "";//机型 + string OrderForm = ""; + MIS_BASE.Read_EngineID(OpName, out string PLCEngineID); + MIS_BASE.Read_EngineID_MES(OpName, out string MESEngineID); + string EngineID = string.IsNullOrEmpty(PLCEngineID) ? MESEngineID : PLCEngineID; + + if (string.IsNullOrEmpty(EngineID)) + { + string msg = $"【{OpName}】PLC与MES产品编号点位均为空,继续按空产品信息保存物料扫码记录!"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(OpName, "MaterialsVerify " + msg, MisDataSaveDate.Helper.MesLogType.ERROR); + } + else + { + DataTable planDt = MisDataFun.XD_GetPlanInfoByEngineID(EngineID); + if (planDt.Rows.Count > 0) + { + OrderForm = planDt.Rows[0]["订单号"].ToString(); + EngineType = planDt.Rows[0]["产品型号"].ToString(); + } + else + { + string msg = $"【{OpName}】产品:{EngineID} 未在生产计划_派工订单_执行计划中查询到记录,继续保存物料扫码记录!"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(OpName, "MaterialsVerify " + msg, MisDataSaveDate.Helper.MesLogType.ERROR); + } + } int MaterialsTypeCode = Convert.ToInt32(MIS_BASE.ReadPLC(201, OpName)); string MaterialsCode = MIS_BASE.ReadPLC(40, OpName).ToString(); diff --git a/MisDataFunction/Function1054/OpcServer/RequestReturnMaterial.cs b/MisDataFunction/Function1054/OpcServer/RequestReturnMaterial.cs index 2f4088a..5823712 100644 --- a/MisDataFunction/Function1054/OpcServer/RequestReturnMaterial.cs +++ b/MisDataFunction/Function1054/OpcServer/RequestReturnMaterial.cs @@ -42,7 +42,6 @@ namespace MesServerFunctions string targetProcessCode = nextDT.Rows[0]["目标工序号"].ToString(); string targetProcess = nextDT.Rows[0]["目标工序"].ToString(); - // 1. 调用AGV转序接口 var agvResult = CALL_Inerface_DataHandle.CALL_Inerface_MaterialTransfer(OpName, targetStoreCode); int agvCode = 500;