312 lines
12 KiB
C#
312 lines
12 KiB
C#
using Infrastructure;
|
||
using Infrastructure.Attribute;
|
||
using Newtonsoft.Json;
|
||
using NLog;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Globalization;
|
||
using System.Linq;
|
||
using System.Net;
|
||
using System.Net.Http;
|
||
using System.Threading.Tasks;
|
||
using U8Server.Util;
|
||
using ZR.Model.MES.wms;
|
||
using ZR.Service.mes.wms_u8.IService;
|
||
|
||
namespace ZR.Service.mes.wms_u8
|
||
{
|
||
[AppService(ServiceType = typeof(IERP_WMS_interactive), ServiceLifetime = LifeTime.Transient)]
|
||
public class ERP_WMS_interactiveService : IERP_WMS_interactive
|
||
{
|
||
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||
// 假设接口密钥(需根据实际文档填写)
|
||
//private const string ApiSecret = "your_api_secret"; // 替换为实际密钥
|
||
|
||
#region 同步方法
|
||
public ERP_WMS_interactiveModelResult Inbounded(string urlBase, List<ERP_WMS_interactiveModelQuery> models)
|
||
{
|
||
return ProcessSyncRequest(urlBase, models, "inbounded", isInbound: true);
|
||
}
|
||
|
||
public ERP_WMS_interactiveModelResult Outbounded(string urlBase, List<ERP_WMS_interactiveModelQuery> models)
|
||
{
|
||
return ProcessSyncRequest(urlBase, models, "outbounded", isInbound: false);
|
||
}
|
||
#endregion
|
||
|
||
#region 异步方法
|
||
public async Task<ERP_WMS_interactiveModelResult> InboundedAsync(string urlBase, List<ERP_WMS_interactiveModelQuery> models)
|
||
{
|
||
return await ProcessAsyncRequest(urlBase, models, "inbounded", isInbound: true);
|
||
}
|
||
|
||
public async Task<ERP_WMS_interactiveModelResult> OutboundedAsync(string urlBase, List<ERP_WMS_interactiveModelQuery> models)
|
||
{
|
||
return await ProcessAsyncRequest(urlBase, models, "outbounded", isInbound: false);
|
||
}
|
||
#endregion
|
||
|
||
#region 公共处理方法
|
||
/// <summary>
|
||
/// 同步请求处理(抽取公共逻辑)
|
||
/// </summary>
|
||
private ERP_WMS_interactiveModelResult ProcessSyncRequest(string urlBase, List<ERP_WMS_interactiveModelQuery> models, string action, bool isInbound)
|
||
{
|
||
var operation = isInbound ? "入库" : "出库";
|
||
_logger.Info($"开始处理{operation}请求 - URL基础: {urlBase}, 记录数: {models?.Count ?? 0}");
|
||
|
||
// 1. 基础参数校验
|
||
if (!ValidateBaseParams(urlBase, models, operation, out var errorMsg))
|
||
{
|
||
_logger.Error($"{operation}请求失败: {errorMsg}");
|
||
return null;
|
||
}
|
||
|
||
// 2. 构建URL和请求数据
|
||
string url = BuildUrl(urlBase, action);
|
||
string requestData = JsonConvert.SerializeObject(models);
|
||
_logger.Debug($"{operation}请求数据: {requestData}");
|
||
|
||
// 3. 构建headers(含签名)
|
||
var headers = BuildHeaders(requestData);
|
||
|
||
try
|
||
{
|
||
_logger.Trace($"发送{operation}同步HTTP请求 - URL: {url}");
|
||
object result = HttpHelper.HttpPost(url, requestData, "application/json", 5, headers);
|
||
|
||
// 4. 处理响应(同步方法假设HttpPost返回已反序列化对象,需根据实际HttpHelper调整)
|
||
return ProcessSyncResponse(result, operation, url);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return HandleException(ex, operation, url, requestData);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 异步请求处理(抽取公共逻辑)
|
||
/// </summary>
|
||
private async Task<ERP_WMS_interactiveModelResult> ProcessAsyncRequest(string urlBase, List<ERP_WMS_interactiveModelQuery> models, string action, bool isInbound)
|
||
{
|
||
var operation = isInbound ? "异步入库" : "异步出库";
|
||
_logger.Info($"开始处理{operation}请求 - URL基础: {urlBase}, 记录数: {models?.Count ?? 0}");
|
||
|
||
// 1. 基础参数校验
|
||
if (!ValidateBaseParams(urlBase, models, operation, out var errorMsg))
|
||
{
|
||
_logger.Error($"{operation}请求失败: {errorMsg}");
|
||
return null;
|
||
}
|
||
|
||
// 2. 构建URL和请求数据
|
||
string url = BuildUrl(urlBase, action);
|
||
string requestData = JsonConvert.SerializeObject(models);
|
||
_logger.Debug($"{operation}请求数据: {requestData}");
|
||
|
||
// 3. 构建headers(含签名)
|
||
var headers = BuildHeaders(requestData);
|
||
|
||
try
|
||
{
|
||
_logger.Trace($"发送{operation}异步HTTP请求 - URL: {url}");
|
||
string resultJson = await HttpHelper.HttpPostAsync(url, requestData, "application/json", 5, headers);
|
||
|
||
// 4. 处理响应(先校验JSON格式,再反序列化)
|
||
return await ProcessAsyncResponse(resultJson, operation, url);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return HandleException(ex, operation, url, requestData);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 工具方法
|
||
/// <summary>
|
||
/// 构建URL(避免双斜杠问题)
|
||
/// </summary>
|
||
private string BuildUrl(string urlBase, string action)
|
||
{
|
||
// 移除urlBase结尾的斜杠,再拼接路径
|
||
return $"{urlBase.TrimEnd('/')}/wms/mes/{action}";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 构建请求头(含签名生成)
|
||
/// </summary>
|
||
private Dictionary<string, string> BuildHeaders(string requestData)
|
||
{
|
||
string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture);
|
||
string appid = "gN9yId!!lfwaRoi3";
|
||
|
||
// 签名生成规则:通常为appid + timestamp + requestData + secret的MD5(需根据接口文档调整)
|
||
//string signSource = $"{appid}{timestamp}{requestData}{ApiSecret}";
|
||
string sign = GetSign.GetBy16Md5(); // 修正签名生成逻辑
|
||
|
||
return new Dictionary<string, string>
|
||
{
|
||
{ "appid", appid },
|
||
{ "timestamp", timestamp },
|
||
{ "sign", sign },
|
||
{ "Content-Type", "application/json" }
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 基础参数校验
|
||
/// </summary>
|
||
private bool ValidateBaseParams(string urlBase, List<ERP_WMS_interactiveModelQuery> models, string operation, out string errorMsg)
|
||
{
|
||
if (string.IsNullOrEmpty(urlBase))
|
||
{
|
||
errorMsg = "基础URL为空";
|
||
return false;
|
||
}
|
||
|
||
if (models == null || !models.Any())
|
||
{
|
||
errorMsg = "请求数据为空";
|
||
return false;
|
||
}
|
||
|
||
errorMsg = string.Empty;
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理同步响应(假设HttpHelper返回已反序列化对象,需根据实际情况调整)
|
||
/// </summary>
|
||
private ERP_WMS_interactiveModelResult ProcessSyncResponse(object result, string operation, string url)
|
||
{
|
||
if (result == null)
|
||
{
|
||
_logger.Warn($"{operation}请求返回空结果 - URL: {url}");
|
||
return null;
|
||
}
|
||
|
||
if (result is ERP_WMS_interactiveModelResult modelResult)
|
||
{
|
||
_logger.Info($"{operation}请求处理成功 - 结果: {modelResult.result}, 消息: {modelResult.message}");
|
||
return modelResult;
|
||
}
|
||
|
||
_logger.Error($"{operation}请求返回意外类型 - 类型: {result.GetType().FullName}, URL: {url}");
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理异步响应(先校验JSON格式)
|
||
/// </summary>
|
||
private async Task<ERP_WMS_interactiveModelResult> ProcessAsyncResponse(string resultJson, string operation, string url)
|
||
{
|
||
if (string.IsNullOrEmpty(resultJson))
|
||
{
|
||
_logger.Warn($"{operation}请求返回空结果 - URL: {url}");
|
||
return null;
|
||
}
|
||
|
||
// 检查是否为已知异常标识
|
||
if (resultJson == "异常:*")
|
||
{
|
||
_logger.Warn($"{operation}请求返回异常标识 - URL: {url}");
|
||
return null;
|
||
}
|
||
|
||
// 验证JSON格式
|
||
if (!IsValidJson(resultJson))
|
||
{
|
||
_logger.Error($"{operation}请求返回非JSON数据 - URL: {url}, 响应内容: {resultJson}");
|
||
return new ERP_WMS_interactiveModelResult
|
||
{
|
||
result = "fail",
|
||
message = $"{operation}响应格式错误,非JSON数据"
|
||
};
|
||
}
|
||
|
||
// 反序列化
|
||
try
|
||
{
|
||
var result = JsonConvert.DeserializeObject<ERP_WMS_interactiveModelResult>(resultJson);
|
||
if (result != null)
|
||
{
|
||
_logger.Info($"{operation}请求处理成功 - 结果: {result.result}, 消息: {result.message}");
|
||
return result;
|
||
}
|
||
else
|
||
{
|
||
_logger.Warn($"{operation}请求反序列化结果为空 - URL: {url}");
|
||
return null;
|
||
}
|
||
}
|
||
catch (JsonReaderException ex)
|
||
{
|
||
_logger.Error(ex, $"{operation}请求JSON解析失败 - URL: {url}, 响应内容: {resultJson}");
|
||
return new ERP_WMS_interactiveModelResult
|
||
{
|
||
result = "fail",
|
||
message = $"{operation}响应解析错误: {ex.Message}"
|
||
};
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 异常处理(细化异常类型)
|
||
/// </summary>
|
||
private ERP_WMS_interactiveModelResult HandleException(Exception ex, string operation, string url, string requestData)
|
||
{
|
||
var errorMsg = $"{operation}处理异常";
|
||
|
||
// 区分异常类型
|
||
if (ex is HttpRequestException httpEx)
|
||
{
|
||
_logger.Error(httpEx, $"{operation}HTTP请求失败 - URL: {url}, 请求数据: {requestData}");
|
||
errorMsg += $": HTTP请求失败: {httpEx.Message}";
|
||
}
|
||
else if (ex is JsonReaderException jsonEx)
|
||
{
|
||
_logger.Error(jsonEx, $"{operation}JSON解析失败 - URL: {url}, 请求数据: {requestData}");
|
||
errorMsg += $": 数据解析失败: {jsonEx.Message}";
|
||
}
|
||
else
|
||
{
|
||
_logger.Error(ex, $"{operation}未知异常 - URL: {url}, 请求数据: {requestData}");
|
||
errorMsg += $": 未知错误: {ex.Message}";
|
||
}
|
||
|
||
return new ERP_WMS_interactiveModelResult
|
||
{
|
||
result = "fail",
|
||
message = errorMsg
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证JSON格式是否有效
|
||
/// </summary>
|
||
private bool IsValidJson(string json)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(json))
|
||
return false;
|
||
|
||
json = json.Trim();
|
||
// 基本格式校验:以{或[开头,以}或]结尾
|
||
if ((json.StartsWith("{") && json.EndsWith("}")) || (json.StartsWith("[") && json.EndsWith("]")))
|
||
{
|
||
try
|
||
{
|
||
// 尝试解析验证
|
||
JsonConvert.DeserializeObject(json);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
#endregion
|
||
}
|
||
} |