chore: 初始化合力差速器MES采集程序

This commit is contained in:
yexingqiang
2026-06-08 10:59:21 +08:00
commit 1591062eef
1379 changed files with 181389 additions and 0 deletions

View File

@@ -0,0 +1,211 @@
using Newtonsoft.Json;
using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WebApi.Helpers;
using WebApi.Models;
namespace WebApiCall
{
/// <summary>
/// WMS WebApi调用类
/// </summary>
public class AGVWebApiCall
{
private static readonly HttpClient httpClient;
static AGVWebApiCall()
{
httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(20); // 设置超时时间为20秒
}
/// <summary>
/// MES叫料接口 - 同步版本返回bool结果
/// </summary>
/// <param name="storageCode">叫料位置(库位号)</param>
/// <param name="goodsCode">物料号(型号)</param>
/// <returns>是否成功</returns>
public static bool MES_To_AGV_CallGoods(string storageCode, string goodsCode)
{
try
{
var task = MES_To_AGV_CallGoods_Async(storageCode, goodsCode);
task.Wait(); // 同步等待异步任务完成
return task.Result;
}
catch (Exception err)
{
string errorMsg = $"叫料同步调用异常 - 库位: {storageCode}, 物料号: {goodsCode}, 异常: {err.Message}";
LogHelper.ShowMsg(errorMsg);
Console.WriteLine($"错误: {MethodBase.GetCurrentMethod().Name} - {errorMsg}");
return false;
}
}
/// <summary>
/// MES叫料接口 - 内部异步实现
/// </summary>
private static async Task<bool> MES_To_AGV_CallGoods_Async(string storageCode, string goodsCode)
{
int AID = -1;
try
{
string WMSIPPort = ConfigurationManager.AppSettings["AGVIPPort"];
string url = $"http://{WMSIPPort}/wms/apiForThirdPartySys/callGoods";
var requestData = new MES_To_AGV_CallGoods_Req
{
storageCode = storageCode,
goodsCode = goodsCode
};
string json = JsonConvert.SerializeObject(requestData);
LogHelper.ShowMsg($"发起叫料请求 - 库位: {storageCode}, 物料号: {goodsCode} -> Send【{url}】{json}");
AID = LogHelper.SaveWebApiReqLogo(url, json);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(url, content);
var responseContent = await response.Content.ReadAsStringAsync();
LogHelper.ShowMsg($"叫料响应 - 库位: {storageCode}, 物料号: {goodsCode} -> Response【{url}】{responseContent}");
if (response.IsSuccessStatusCode)
{
// 解析WMS响应
var wmsResponse = JsonConvert.DeserializeObject<WmsApiResponse>(responseContent);
if (wmsResponse != null && wmsResponse.code == 200)
{
LogHelper.ShowMsg($"叫料成功 - 库位: {storageCode}, 物料号: {goodsCode}, 响应消息: {wmsResponse.msg}");
LogHelper.SaveWebApiResLogo(AID, JsonConvert.SerializeObject(wmsResponse));
return true;
}
else
{
LogHelper.ShowMsg($"叫料失败 - 库位: {storageCode}, 物料号: {goodsCode}, 错误信息: {wmsResponse?.msg ?? ""}");
LogHelper.SaveWebApiResLogo(AID, JsonConvert.SerializeObject(wmsResponse));
return false;
}
}
else
{
string msg = $"叫料HTTP请求失败 - 库位: {storageCode}, 物料号: {goodsCode}, 状态码: {response.StatusCode}, 响应: {responseContent}";
LogHelper.ShowMsg(msg);
LogHelper.SaveWebApiResLogo(AID, msg);
return false;
}
}
catch (Exception err)
{
string errorMsg = $"叫料异常 - 库位: {storageCode}, 物料号: {goodsCode}, 异常详情: {err.Message}";
LogHelper.ShowMsg(errorMsg);
Console.WriteLine($"错误: {MethodBase.GetCurrentMethod().Name} - {errorMsg}");
if (AID > 0)
{
LogHelper.SaveWebApiResLogo(AID, errorMsg);
}
return false;
}
}
/// <summary>
/// MES退料接口 - 同步版本返回bool结果
/// </summary>
/// <param name="storageCode">退料位置(库位号)</param>
/// <param name="goodsCode">物料号(型号)</param>
/// <param name="isEmpty">是否为空 0.空托 1.余料</param>
/// <returns>是否成功</returns>
public static bool MES_To_AGV_ReturnGoods(string storageCode, string goodsCode, int isEmpty)
{
try
{
var task = MES_To_AGV_ReturnGoods_Async(storageCode, goodsCode, isEmpty);
task.Wait(); // 同步等待异步任务完成
return task.Result;
}
catch (Exception err)
{
string emptyTypeDesc = isEmpty == 0 ? "空托" : "余料";
string errorMsg = $"退料同步调用异常 - 库位: {storageCode}, 物料号: {goodsCode}, 类型: {emptyTypeDesc}({isEmpty}), 异常: {err.Message}";
LogHelper.ShowMsg(errorMsg);
Console.WriteLine($"错误: {MethodBase.GetCurrentMethod().Name} - {errorMsg}");
return false;
}
}
/// <summary>
/// MES退料接口 - 内部异步实现
/// </summary>
private static async Task<bool> MES_To_AGV_ReturnGoods_Async(string storageCode, string goodsCode, int isEmpty)
{
int AID = -1;
try
{
string emptyTypeDesc = isEmpty == 0 ? "空托" : "余料";
string WMSIPPort = ConfigurationManager.AppSettings["AGVIPPort"];
string url = $"http://{WMSIPPort}/wms/apiForThirdPartySys/returnGoods";
var requestData = new MES_To_AGV_ReturnGoods_Req
{
storageCode = storageCode,
goodsCode = goodsCode,
isEmpty = isEmpty
};
string json = JsonConvert.SerializeObject(requestData);
LogHelper.ShowMsg($"发起退料请求 - 库位: {storageCode}, 物料号: {goodsCode}, 类型: {emptyTypeDesc}({isEmpty}) -> Send【{url}】{json}");
AID = LogHelper.SaveWebApiReqLogo(url, json);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(url, content);
var responseContent = await response.Content.ReadAsStringAsync();
LogHelper.ShowMsg($"退料响应 - 库位: {storageCode}, 物料号: {goodsCode}, 类型: {emptyTypeDesc}({isEmpty}) -> Response【{url}】{responseContent}");
if (response.IsSuccessStatusCode)
{
// 解析WMS响应
var wmsResponse = JsonConvert.DeserializeObject<WmsApiResponse>(responseContent);
if (wmsResponse != null && wmsResponse.code == 200)
{
LogHelper.ShowMsg($"退料成功 - 库位: {storageCode}, 物料号: {goodsCode}, 类型: {emptyTypeDesc}({isEmpty}), 响应消息: {wmsResponse.msg}");
LogHelper.SaveWebApiResLogo(AID, JsonConvert.SerializeObject(wmsResponse));
return true;
}
else
{
LogHelper.ShowMsg($"退料失败 - 库位: {storageCode}, 物料号: {goodsCode}, 类型: {emptyTypeDesc}({isEmpty}), 错误信息: {wmsResponse?.msg ?? ""}");
LogHelper.SaveWebApiResLogo(AID, JsonConvert.SerializeObject(wmsResponse));
return false;
}
}
else
{
string msg = $"退料HTTP请求失败 - 库位: {storageCode}, 物料号: {goodsCode}, 类型: {emptyTypeDesc}({isEmpty}), 状态码: {response.StatusCode}, 响应: {responseContent}";
LogHelper.ShowMsg(msg);
LogHelper.SaveWebApiResLogo(AID, msg);
return false;
}
}
catch (Exception err)
{
string emptyTypeDesc = isEmpty == 0 ? "空托" : "余料";
string errorMsg = $"退料异常 - 库位: {storageCode}, 物料号: {goodsCode}, 类型: {emptyTypeDesc}({isEmpty}), 异常详情: {err.Message}";
LogHelper.ShowMsg(errorMsg);
Console.WriteLine($"错误: {MethodBase.GetCurrentMethod().Name} - {errorMsg}");
if (AID > 0)
{
LogHelper.SaveWebApiResLogo(AID, errorMsg);
}
return false;
}
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataLinkMesWork;
namespace WebApi.Helpers
{
public class LogHelper
{
/// <summary>
/// UUID生成
/// </summary>
/// <returns></returns>
public static string UuidUtil()
{
string result = Guid.NewGuid().ToString();
return result;
}
public static void ShowMsg(string msg)
{
MyLog4Net.MyLogHelper.Error("WebApi", msg);
}
public static int SaveWebApiReqLogo(string url, string JSON)
{
int AID = -1;
try
{
//存储日志
var CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
string procedureName = "接口_IOT接口交互日志_请求记录";
SqlParameter[] thisParms = new SqlParameter[4];
thisParms[0] = new System.Data.SqlClient.SqlParameter("@接口地址", url);
thisParms[1] = new System.Data.SqlClient.SqlParameter("@接口类型", 2);
thisParms[2] = new System.Data.SqlClient.SqlParameter("@请求内容", JSON);
thisParms[3] = new System.Data.SqlClient.SqlParameter("@请求时间", CreateTime);
SQLCommon.ExecuteStoredProcedure(procedureName, ApplicationConfig.ConnectionString_MES, out DataTable dt, out string errorMessage);
// DataAccess.ExecuteStoredProcedure(procedureName, ref thisParms, out DataTable dt);
if (dt.Rows.Count > 0)
{
AID = Convert.ToInt32(dt.Rows[0]["AID"]);
}
}
catch (Exception ex)
{
}
return AID;
}
public static void SaveWebApiResLogo(int AID, string JSON)
{
try
{
//存储日志
var CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
string procedureName = "接口_IOT接口交互日志_响应记录";
SqlParameter[] thisParms = new SqlParameter[3];
thisParms[0] = new System.Data.SqlClient.SqlParameter("@AID", AID);
thisParms[1] = new System.Data.SqlClient.SqlParameter("@响应时间", CreateTime);
thisParms[2] = new System.Data.SqlClient.SqlParameter("@响应内容", JSON);
DataAccess.ExecuteStoredProcedure(procedureName, ref thisParms, out DataTable dt);
}
catch (Exception ex)
{
}
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace WebApi.Helpers
{
public class ValidationHelper
{
/// <summary>
/// 验证对象的必填字段
/// </summary>
/// <typeparam name="T">要验证的对象类型</typeparam>
/// <param name="obj">要验证的对象</param>
/// <param name="errorMessage">错误信息</param>
/// <returns>验证是否通过</returns>
public static bool ValidateRequired<T>(T obj, out string errorMessage)
{
errorMessage = string.Empty;
if (obj == null)
{
errorMessage = "对象不能为空";
return false;
}
var properties = typeof(T).GetProperties();
foreach (var prop in properties)
{
var value = prop.GetValue(obj);
if (value == null)
{
errorMessage = $"【{prop.Name}不能为空】";
return false;
}
//else if (prop.PropertyType == typeof(int) && (int)value == 0)
//{
// errorMessage = $"【{prop.Name}不能为0】";
// return false;
//}
else if (prop.PropertyType == typeof(string) && string.IsNullOrEmpty((string)value))
{
errorMessage = $"【{prop.Name}不能为空】";
return false;
}
else if (prop.PropertyType == typeof(object) && (object)value == null)
{
errorMessage = $"【{prop.Name}不能为空】";
return false;
}
}
return true;
}
/// <summary>
/// 验证对象的指定字段
/// </summary>
/// <typeparam name="T">要验证的对象类型</typeparam>
/// <param name="obj">要验证的对象</param>
/// <param name="propertyNames">要验证的属性名列表</param>
/// <param name="errorMessage">错误信息</param>
/// <returns>验证是否通过</returns>
public static bool ValidateProperties<T>(T obj, string[] propertyNames, out string errorMessage)
{
errorMessage = string.Empty;
if (obj == null)
{
errorMessage = "对象不能为空";
return false;
}
foreach (var propName in propertyNames)
{
var prop = typeof(T).GetProperty(propName);
if (prop == null) continue;
var value = prop.GetValue(obj);
if (value == null)
{
errorMessage = $"【{propName}不能为空】";
return false;
}
//else if (prop.PropertyType == typeof(int) && (int)value == 0)
//{
// errorMessage = $"【{propName}不能为0】";
// return false;
//}
else if (prop.PropertyType == typeof(string) && string.IsNullOrEmpty((string)value))
{
errorMessage = $"【{propName}不能为空】";
return false;
}
}
return true;
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace WebApi.Models
{
public class AGV_To_MES_AgvPass_Req
{
/// <summary>
/// 进入或离开
/// </summary>
public string agvStatus { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
namespace WebApi.Models
{
/// <summary>
/// MES叫料请求
/// </summary>
public class MES_To_AGV_CallGoods_Req
{
/// <summary>
/// 叫料位置(库位号)
/// </summary>
public string storageCode { get; set; }
/// <summary>
/// 物料号(型号)
/// </summary>
public string goodsCode { get; set; }
}
}

View File

@@ -0,0 +1,23 @@
namespace WebApi.Models
{
/// <summary>
/// MES退料请求
/// </summary>
public class MES_To_AGV_ReturnGoods_Req
{
/// <summary>
/// 退料位置(库位号)
/// </summary>
public string storageCode { get; set; }
/// <summary>
/// 物料号(型号)
/// </summary>
public string goodsCode { get; set; }
/// <summary>
/// 是否为空 0.空托 1.余料
/// </summary>
public int isEmpty { get; set; }
}
}

View File

@@ -0,0 +1,23 @@
namespace WebApi.Models
{
/// <summary>
/// WMS接口响应
/// </summary>
public class WmsApiResponse
{
/// <summary>
/// 状态码 200:成功 500:失败
/// </summary>
public int code { get; set; }
/// <summary>
/// 消息
/// </summary>
public string msg { get; set; }
/// <summary>
/// 返回数据
/// </summary>
public object data { get; set; }
}
}

View File

@@ -0,0 +1,23 @@
namespace WebApi.Models
{
public class msgResHeader
{
/// <summary>
/// 成功时反馈“200”失败时反馈“500”
/// </summary>
public string code
{
get;
set;
}
/// <summary>
/// 返回消息
/// </summary>
public string message
{
get;
set;
}
}
}