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