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); LGWEB_DispatchResult dispatchResult = DispatchAGV(request); result.code = dispatchResult.Success ? 200 : 500; result.message = dispatchResult.Message; result.Data = dispatchResult; } 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搬运任务,供 WebAPI 和 Function 直接复用。 /// public static LGWEB_DispatchResult DispatchAGV(LGWEB_DispatchRequest request, string defaultTriggerMode = "WEB", bool requireProductPoint = false) { if (request == null) { throw new Exception("请求参数格式不正确"); } if (IsPointToPointDispatch(request)) { return DispatchPointToPoint(request, defaultTriggerMode); } if (string.IsNullOrWhiteSpace(request.routeCode)) { throw new Exception("路线编码(routeCode)不能为空"); } LGWEB_RouteInfo route = GetRouteInfo(request); if (requireProductPoint && route.ProductPointMatched != "1") { throw new Exception($"未匹配产品点位配置:routeCode={request.routeCode}, 产品型号代码={request.productModelCode}, 产品型号={request.productModel}, 动作={request.actionCode}, 过程点={request.processPointType}, 工位={request.workStation}"); } 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, defaultTriggerMode); return new LGWEB_DispatchResult { Success = agvResult.Success, Message = agvResult.Success ? "AGV调度成功" : $"AGV调度失败:{agvResult.Message}", DispatchMode = "ROUTE", RequestTaskId = requestTaskId, RouteCode = request.routeCode, StartPosition = startPosition, MidPosition = midPosition, EndPosition = endPosition, OriginalEndPosition = route.OriginalEndPosition, ProductPointMatched = route.ProductPointMatched, ProcessPointType = route.ProcessPointType, RouteMessage = route.RouteMessage, AgvResponse = agvResult.Response }; } private static LGWEB_DispatchResult DispatchPointToPoint(LGWEB_DispatchRequest request, string defaultTriggerMode) { if (string.IsNullOrWhiteSpace(request.startPosition)) { throw new Exception("点到点模式起点位置(startPosition)不能为空"); } if (string.IsNullOrWhiteSpace(request.endPosition)) { throw new Exception("点到点模式终点位置(endPosition)不能为空"); } if (!string.IsNullOrWhiteSpace(request.midPosition)) { throw new Exception("点到点模式不支持中间位置(midPosition)"); } if (string.Equals(request.startPosition.Trim(), request.endPosition.Trim(), StringComparison.OrdinalIgnoreCase)) { throw new Exception("点到点模式起点和终点不能相同"); } if (string.IsNullOrWhiteSpace(request.productCode)) { throw new Exception("点到点模式产品编码(productCode)不能为空"); } request.routeCode = FirstText(request.routeCode, "MANUAL_POINT_TO_POINT"); string requestTaskId = string.IsNullOrWhiteSpace(request.requestTaskId) ? Guid.NewGuid().ToString() : request.requestTaskId; string materialCode = FirstText(request.materialCode, request.productCode, request.containerNo); string triggerMode = string.IsNullOrWhiteSpace(defaultTriggerMode) ? "WEB" : defaultTriggerMode; DataRow validateRow = ValidatePointToPoint(request); LGWEB_RouteInfo route = new LGWEB_RouteInfo { RouteCode = request.routeCode, StartPosition = request.startPosition, MidPosition = "", OriginalEndPosition = request.endPosition, ActualEndPosition = request.endPosition, InterfaceName = "AddTaskFromMes", BusinessType = "点到点搬运", TriggerMode = triggerMode, SourceWorkStation = ReadColumn(validateRow, "起点工位号"), TargetWorkStation = ReadColumn(validateRow, "终点工位号"), ProductPointMatched = "0", ProcessPointType = "", RouteMessage = ReadColumn(validateRow, "msg") }; LGAGV_CallResult agvResult = LGAGV_BusinessLogic.CallAddTask(new LGAGV_AddTaskRequest { requestTaskId = requestTaskId, startPosition = request.startPosition, endPosition = request.endPosition, materialCode = materialCode }); SaveDispatchResult(request, route, requestTaskId, request.startPosition, "", request.endPosition, materialCode, agvResult, triggerMode); return new LGWEB_DispatchResult { Success = agvResult.Success, Message = agvResult.Success ? "AGV点到点调度成功" : $"AGV点到点调度失败:{agvResult.Message}", DispatchMode = "POINT_TO_POINT", RequestTaskId = requestTaskId, RouteCode = request.routeCode, StartPosition = request.startPosition, MidPosition = "", EndPosition = request.endPosition, OriginalEndPosition = request.endPosition, ProductPointMatched = "0", ProcessPointType = "", RouteMessage = route.RouteMessage, AgvResponse = agvResult.Response }; } /// /// 网页按钮放行临工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 bool IsPointToPointDispatch(LGWEB_DispatchRequest request) { if (string.Equals((request.dispatchMode ?? "").Trim(), "POINT_TO_POINT", StringComparison.OrdinalIgnoreCase)) { return true; } return !string.IsNullOrWhiteSpace(request.startPosition) && !string.IsNullOrWhiteSpace(request.endPosition); } private static DataRow ValidatePointToPoint(LGWEB_DispatchRequest request) { var param = new SqlParameter[] { new SqlParameter("@起点位置", request.startPosition ?? ""), new SqlParameter("@终点位置", request.endPosition ?? ""), new SqlParameter("@产品编码", request.productCode ?? "") }; DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("LG_AGV_库位Moby_点到点校验", 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 row; } private static LGWEB_RouteInfo GetRouteInfo(LGWEB_DispatchRequest request) { var param = new SqlParameter[] { new SqlParameter("@路线编码", request.routeCode ?? ""), new SqlParameter("@产品型号代码", request.productModelCode ?? ""), new SqlParameter("@产品型号", request.productModel ?? ""), new SqlParameter("@动作编码", request.actionCode ?? ""), new SqlParameter("@过程点大类", request.processPointType ?? ""), new SqlParameter("@工位号", request.workStation ?? "") }; 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, "目标工位号"), ProductPointMatched = ReadColumn(row, "是否匹配型号点位"), ProductModelCode = ReadColumn(row, "产品型号代码"), ProductModel = ReadColumn(row, "产品型号"), ActionCode = ReadColumn(row, "动作编码"), ProcessPointType = 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, string defaultTriggerMode) { var param = new SqlParameter[] { new SqlParameter("@路线编码", request.routeCode ?? ""), new SqlParameter("@业务类型", route.BusinessType ?? ""), new SqlParameter("@触发方式", string.IsNullOrWhiteSpace(route.TriggerMode) ? (defaultTriggerMode ?? "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 ProductPointMatched { get; set; } public string ProductModelCode { get; set; } public string ProductModel { get; set; } public string ActionCode { get; set; } public string ProcessPointType { get; set; } public string RouteMessage { get; set; } } } }