diff --git a/ds-wms-service/DS.WMS.Core/DS.WMS.Core.csproj b/ds-wms-service/DS.WMS.Core/DS.WMS.Core.csproj index 17ef1a5b..93edfb6f 100644 --- a/ds-wms-service/DS.WMS.Core/DS.WMS.Core.csproj +++ b/ds-wms-service/DS.WMS.Core/DS.WMS.Core.csproj @@ -29,7 +29,6 @@ - diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/ShippingOrderCompareCallBackInfo.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/ShippingOrderCompareCallBackInfo.cs new file mode 100644 index 00000000..d9956974 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/ShippingOrderCompareCallBackInfo.cs @@ -0,0 +1,50 @@ +using DS.WMS.Core.Op.Dtos; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DS.WMS.Core.TaskPlat.Dtos +{ + /// + /// 下货纸比对回写 + /// + public class ShippingOrderCompareCallBackInfo + { + /// + /// 请求主键 + /// + public string reqBusiId { get; set; } + + /// + /// 比对ID + /// + public string compareId { get; set; } + + /// + /// 下货纸比对方式 MANUAL-手动 AUTO-自动 + /// + public string compareMode { get; set; } = "AUTO"; + + /// + /// 比对结果代码 + /// + public string compareRltCode { get; set; } + + /// + /// 比对结果名称 + /// + public string compareRltName { get; set; } + + /// + /// 比对日期 + /// + public DateTime compareDate { get; set; } + + /// + /// 比对详情 + /// + public List compareDetailList { get; set; } + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskMessageInfoDto.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskMessageInfoDto.cs new file mode 100644 index 00000000..8dd533df --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskMessageInfoDto.cs @@ -0,0 +1,359 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DS.WMS.Core.TaskPlat.Dtos +{ + public class TaskMessageInfoDto + { + /// + /// 表头 + /// + public TaskMessageHead Head { get; set; } + + /// + /// 表体 + /// + public TaskMessageMain Main { get; set; } + } + + /// + /// 报文表体 + /// + public class TaskMessageMain + { + /// + /// 业务惟一主键 + /// + public string BusiPKId { get; set; } + + /// + /// 比对ID + /// + public string TaskCompareId { get; set; } + + /// + /// 用户ID + /// + public string UserId { get; set; } + + /// + /// 用户名称 + /// + public string UserName { get; set; } + + /// + /// 用户邮件 + /// + public string UserEmail { get; set; } + + /// + /// 租户ID + /// + public string TenantId { get; set; } + + /// + /// 租户名称 + /// + public string TenantName { get; set; } + + /// + /// 场站代码 + /// + public string YardCode { get; set; } + + /// + /// 场站中文名称 + /// + public string YardCName { get; set; } + + /// + /// 船名英文名 + /// + public string VesselName { get; set; } + + /// + /// 船名中文名 + /// + public string VesselCName { get; set; } + + /// + /// 航次号 + /// + public string VoyNo { get; set; } + + /// + /// 主提单号 + /// + public string MasterBlNo { get; set; } + + /// + /// 分提单号 + /// + public string HouseBlNo { get; set; } + + /// + /// 订舱编号 + /// + public string BookingNo { get; set; } + + /// + /// 起运港代码 + /// + public string PortLoadId { get; set; } + + /// + /// 起运港 + /// + public string PortLoad { get; set; } + + /// + /// 卸货港代码 + /// + public string PortDischargeId { get; set; } + + /// + /// 卸货港 + /// + public string PortDischarge { get; set; } + + + /// + /// 中转港代码 + /// + public string TransportId { get; set; } + + /// + /// 中转港 + /// + public string Transport { get; set; } + + /// + /// 交货地代码 + /// + public string PlaceDeliveryId { get; set; } + + /// + /// 交货地 + /// + public string PlaceDelivery { get; set; } + + /// + /// 目的港代码 + /// + public string DestinationId { get; set; } + + /// + /// 目的港 + /// + public string Destination { get; set; } + + /// + /// 件数 + /// + public Int32 PKGs { get; set; } + + /// + /// 毛重 + /// + public Nullable KGs { get; set; } + + /// + /// 尺码 + /// + public Nullable CBM { get; set; } + + /// + /// 主等级(危险品) + /// + public string DClass { get; set; } + + /// + /// 国际危险品编号(危险品) + /// + public string DUNNo { get; set; } + + /// + /// 副等级(危险品) + /// + public string FuDClass { get; set; } + + /// + /// 副国际危险品编号(危险品) + /// + public string FuDUNNo { get; set; } + + /// + /// 海污(危险品) + /// + public string HaiWu { get; set; } + + /// + /// 温度(冻柜) + /// + public string TempSet { get; set; } + + /// + /// 通风(冻柜) + /// + public string Reeferf { get; set; } + + /// + /// 湿度(冻柜) + /// + public string Humidity { get; set; } + + /// + /// 货描 + /// + public string GoodsDescription { get; set; } + + /// + /// 船公司代码 + /// + public string CarrierCode { get; set; } + + /// + /// 箱信息列表 + /// + public List ContaList { get; set; } + } + + /// + /// 箱信息 + /// + public class TaskMessageCtnInfo + { + /// + /// 集装箱箱型代码 + /// + public string ContaType { get; set; } + + /// + /// 集装箱箱型名称 + /// + public string ContaTypeName { get; set; } + + /// + /// 集装箱箱号 + /// + public string ContaNo { get; set; } + + /// + /// 铅封号 + /// + public string SealNo { get; set; } + + /// + /// 包装 + /// + public string KindPKGs { get; set; } + + /// + /// 皮重 + /// + public string TareWeight { get; set; } + + /// + /// 件数 + /// + public Int32 PKGs { get; set; } + + /// + /// 毛重 + /// + public Nullable KGs { get; set; } + + /// + /// 尺码 + /// + public Nullable CBM { get; set; } + + /// + /// 箱量 + /// + public int CtnNum { get; set; } + } + + /// + /// 报文表头 + /// + public class TaskMessageHead : WebAPIHeadBase + { + + } + + public class WebAPIHeadBase + { + /// + /// 报文惟一主键 + /// + /// 08dab66c-96a1-4f90-8606-2626e06202ad + [Required(ErrorMessage = "必填")] + public string GID { get; set; } + + /// + /// 报文类型 BUSI_RULE-业务规则校验 + /// + /// BUSI_RULE + [Required(ErrorMessage = "必填")] + public string MessageType { get; set; } + + /// + /// 发送方代码 + /// + /// CUSTOMER1 + [Required(ErrorMessage = "必填")] + public string SenderId { get; set; } + + /// + /// 发送方名称 + /// + /// 企业A + [Required(ErrorMessage = "必填")] + public string SenderName { get; set; } + + /// + /// 接收方代码 + /// + /// RulesEngine + [Required(ErrorMessage = "必填")] + public string ReceiverId { get; set; } + + /// + /// 接收方名称 + /// + /// 大简云规则引擎 + [Required(ErrorMessage = "必填")] + public string ReceiverName { get; set; } + + /// + /// 请求方登录TOKEN(可以是真实的登录人TOKEN或者是服务模拟登录人TOKEN) + /// + /// eyJhbGciOiJSUzI1NiIsImtpZCI6IkQ1RTkxMDI5OUU0RURFNUZEM0EwNTJBMEFDRDUzMUQzIiwidHlwIjoiYXQrand0In0 + public string Token { get; set; } + + /// + /// 版本号 默认1.0 + /// + /// 1.0 + [Required(ErrorMessage = "必填")] + public string Version { get; set; } = "1.0"; + + /// + /// 请求时间 + /// + /// 2022-10-10 10:00:00 + public string RequestDate { get; set; } + + /// + /// 请求操作类型 + /// + /// Add + [Required(ErrorMessage = "必填")] + public string RequestAction { get; set; } = "Add"; + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ShippingOrderCompare/ITaskShippingOrderCompareService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ShippingOrderCompare/ITaskShippingOrderCompareService.cs new file mode 100644 index 00000000..63b30e77 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ShippingOrderCompare/ITaskShippingOrderCompareService.cs @@ -0,0 +1,53 @@ +using DS.WMS.Core.Op.Dtos; +using DS.WMS.Core.TaskPlat.Dtos; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DS.WMS.Core.TaskPlat.Interface +{ + /// + /// 下货纸比对 + /// + public interface ITaskShippingOrderCompareService + { + /// + /// 执行下货纸比对 + /// + /// 订舱主键 + /// 返回回执 + Task ExcuteShippingOrderCompareAsync(string bookingId); + + + /// + /// 批量执行下货纸比对 + /// + /// 订舱主键组 + /// 返回回执 + Task ExcuteShippingOrderCompareBatchAsync(string[] bookingIds); + + /// + /// 下货纸自动比对回写状态 + /// + /// 比对回写详情 + /// 返回回执 + Task AutoTaskShippingOrderCompareCallBackAsync(ShippingOrderCompareCallBackInfo model); + + /// + /// 自动执行下货纸比对 + /// + /// 订舱主键 + /// 返回回执 + Task ExcuteAutoShippingOrderCompareAsync(string bookingId); + + + /// + /// 获取下货纸比对结果 + /// + /// 订舱主键 + /// 返回回执 + Task GetShippingOrderCompareResult(long bookingId); + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/ShippingOrderCompare/TaskShippingOrderCompareService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/ShippingOrderCompare/TaskShippingOrderCompareService.cs new file mode 100644 index 00000000..c3938318 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/ShippingOrderCompare/TaskShippingOrderCompareService.cs @@ -0,0 +1,725 @@ +using DS.Module.Core; +using DS.Module.Core.Attributes; +using DS.Module.Core.Helpers; +using DS.Module.DjyServiceStatus; +using DS.Module.SqlSugar; +using DS.Module.UserModule; +using DS.WMS.Core.Invoice.Dtos; +using DS.WMS.Core.Op.Dtos; +using DS.WMS.Core.Op.Entity; +using DS.WMS.Core.TaskPlat.Dtos; +using DS.WMS.Core.TaskPlat.Entity; +using DS.WMS.Core.TaskPlat.Interface; +using Mapster; +using Masuit.Tools.Systems; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; +using NLog; +using NPOI.SS.Formula.Functions; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Nodes; +using System.Threading.Tasks; + +namespace DS.WMS.Core.TaskPlat.Method +{ + /// + /// + /// + public class TaskShippingOrderCompareService : ITaskShippingOrderCompareService + { + private readonly IServiceProvider _serviceProvider; + private readonly ISqlSugarClient db; + private readonly IUser user; + private readonly ISaasDbService saasService; + private readonly IDjyServiceStatusService _djyServiceStatusService; + + private readonly string shippingOrderCompareUrl; + private readonly string shippingOrderCompareResultUrl; + + private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger(); + + public TaskShippingOrderCompareService(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + db = _serviceProvider.GetRequiredService(); + user = _serviceProvider.GetRequiredService(); + saasService = _serviceProvider.GetRequiredService(); + _djyServiceStatusService = _serviceProvider.GetRequiredService(); + + shippingOrderCompareUrl = AppSetting.app(new string[] { "ShippingOrderCompare", "Url" }); + shippingOrderCompareResultUrl = AppSetting.app(new string[] { "ShippingOrderCompare", "ResultUrl" }); + } + + /// + /// 执行下货纸比对 + /// + /// 订舱主键 + /// 返回回执 + [HttpGet("/TaskShippingOrderCompare/ExcuteShippingOrderCompare")] + public async Task ExcuteShippingOrderCompareAsync(string bookingId) + { + string batchNo = GuidHelper.GetSnowflakeId(); + + Logger.Log(NLog.LogLevel.Info, "批次={no}获取订舱数据请求规则 {id}", batchNo, bookingId); + + /* + 处理逻辑 + 1、台账触发单票下货纸比对 + 2、调取订舱的详情。 + 3、对应请求报文。 + 4、请求比对接口。 + 5、返回回执。 + */ + + return await InnerExcuteShippingOrderCompareAsync(bookingId); + } + + #region 执行下货纸比对 + /// + /// 执行下货纸比对 + /// + /// 订舱主键 + /// 比对模式(MANUAL-手工 AUTO-自动) + /// 返回回执 + private async Task InnerExcuteShippingOrderCompareAsync(string bookingId, + string LstShipOrderCompareMode = "MANUAL") + { + string batchNo = GuidHelper.GetSnowflakeId(); + + Logger.Log(NLog.LogLevel.Info, "批次={no}获取订舱数据请求规则 {id}", batchNo, bookingId); + + /* + 处理逻辑 + 1、台账触发单票下货纸比对 + 2、调取订舱的详情。 + 3、对应请求报文。 + 4、请求比对接口。 + 5、返回回执。 + */ + + TaskManageExcuteResultDto result = new TaskManageExcuteResultDto(); + + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + + try + { + DateTime nowDate = DateTime.Now; + + long id = long.Parse(bookingId); + + var model = tenantDb.Queryable() + .First(a => a.Id == id); + + if (model == null) + throw new Exception($"订舱主键{bookingId}无法获取业务信息"); + + Logger.Log(NLog.LogLevel.Info, "批次={no}获取订舱数据完成", batchNo); + + + //附主信息 + var mainInfo = model.Adapt(); + + mainInfo.BusiPKId = model.Id.ToString(); + mainInfo.UserId = user.UserId; + mainInfo.UserName = user.UserName; + //mainInfo.UserEmail = user.; + + var contaList = await tenantDb.Queryable() + .Where(x => long.Parse(x.BSNO) == model.Id).ToListAsync(); + + Logger.Log(NLog.LogLevel.Info, "批次={no} 提取箱完成 数量={total}", batchNo, contaList.Count); + + if (contaList.Count > 0) + { + mainInfo.ContaList = contaList.Adapt>(); + } + + var msgModel = GetMessageInfo(batchNo, mainInfo); + + Logger.Log(NLog.LogLevel.Info, "批次={no} 对应请求报文完成 msg={msg}", batchNo, JsonConvert.SerializeObject(msgModel)); + + DateTime bDate = DateTime.Now; + + var compareResult = await ExcuteCompare(msgModel); + + DateTime eDate = DateTime.Now; + TimeSpan ts = eDate.Subtract(bDate); + var timeDiff = ts.TotalMilliseconds; + + Logger.Log(NLog.LogLevel.Info, "批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, compareResult.succ ? "成功" : "失败"); + + if (compareResult == null) + throw new Exception($"订舱主键{bookingId}请求下货纸比对失败,返回为空"); + + + var orderInfo = tenantDb.Queryable() + .First(x => x.Id == id); + + if (orderInfo != null) + { + var oldOrderInfo = orderInfo.Adapt(); + orderInfo.LstShipOrderCompareDate = bDate; + + if (compareResult.succ) + { + orderInfo.LstShipOrderCompareMode = LstShipOrderCompareMode; + + /* + isComplete标记当票是否满足截至要求 + 1、场站返回的记录里所有箱都有了返场日期。 + 2、或者当票的实际开船日期或者预计开船日期已到也可以截至。 + */ + bool isComplete = false; + bool isBefore = false; + + //需要细分状态,返场前和返场后 + if (compareResult.yardStatInfo != null) + { + var yardStatInfo = compareResult.yardStatInfo as YardStatInfo; + + //如果场站集装箱都有了返场时间,即认为下货纸自动任务结束 + if (yardStatInfo.LstReturnYardDate.HasValue && yardStatInfo.ContaNum >= 1 && + yardStatInfo.ContaNum == yardStatInfo.ExistsReturnYardDateCtnNum) + { + isComplete = true; + } + + //判断 有箱号的条数跟总计箱数量不一致 认为是反场前比对 + if ((yardStatInfo.ExistsCtnNo < yardStatInfo.ContaNum)) + isBefore = true; + } + + DateTime etd = DateTime.MinValue; + if (model.ATD.HasValue) + { + etd = model.ATD.Value; + } + else if (model.ETD.HasValue) + { + etd = model.ETD.Value; + } + + if (etd != DateTime.MinValue && etd <= DateTime.Now) + isComplete = true; + + if (compareResult.extra.IsExistsDiff) + { + if (isComplete) + { + orderInfo.LstShipOrderCompareRlt = "DIFF"; + orderInfo.LstShipOrderCompareRltName = "有差异"; + } + else + { + bool isBeforeEqual = false; + var checkList = compareResult.extra.ShowDetailList.Where(b => + (b.PCode == null || b.PCode == "") && b.IsDisplay && + (b.FieldCode.ToUpper() != "PKGS" && b.FieldCode.ToUpper() != "KGS" && b.FieldCode.ToUpper() != "CBM")) + .ToList(); + + if (!checkList.Any(t => t.IsDiff)) + { + isBeforeEqual = true; + } + + if (isBefore) + { + if (isBeforeEqual) + { + orderInfo.LstShipOrderCompareRlt = "BEFORE_EQUAL"; + orderInfo.LstShipOrderCompareRltName = "返场前比对正常"; + } + else + { + orderInfo.LstShipOrderCompareRlt = "BEFORE_DIFF"; + orderInfo.LstShipOrderCompareRltName = "返场前比对有差异"; + } + } + else + { + orderInfo.LstShipOrderCompareRlt = "DIFF_U"; + orderInfo.LstShipOrderCompareRltName = "有差异未结束"; + } + } + } + else + { + if (isComplete) + { + orderInfo.LstShipOrderCompareRlt = "NO_DIFF"; + orderInfo.LstShipOrderCompareRltName = "正常"; + + //比对成功后触发下货纸比对状态 + var pushModel = new EmbedServiceProjectStatusDto + { + businessId = bookingId, + SourceType = 1, + StatusCodes = new List { + new EmbedServiceProjectStatusDetailDto{ + StatusCode = "XHZBDCHG" + } + } + }; + + var saveStatusRlt = await _djyServiceStatusService.SaveServiceStatus(pushModel); + + Logger.Log(NLog.LogLevel.Info, "批次={no} 异步推送下货纸比对状态完成,结果={rlt}", batchNo, JsonConvert.SerializeObject(saveStatusRlt)); + } + else + { + if (isBefore) + { + orderInfo.LstShipOrderCompareRlt = "BEFORE_EQUAL"; + orderInfo.LstShipOrderCompareRltName = "返场前比对正常"; + } + else + { + orderInfo.LstShipOrderCompareRlt = "NO_DIFF_U"; + orderInfo.LstShipOrderCompareRltName = "正常未结束"; + + //比对成功后触发下货纸比对状态 + var pushModel = new EmbedServiceProjectStatusDto + { + businessId = bookingId, + SourceType = 1, + StatusCodes = new List { + new EmbedServiceProjectStatusDetailDto{ + StatusCode = "XHZBDCHG" + } + } + }; + + var saveStatusRlt = await _djyServiceStatusService.SaveServiceStatus(pushModel); + + Logger.Log(NLog.LogLevel.Info, "批次={no} 异步推送下货纸比对状态完成,结果={rlt}", batchNo, JsonConvert.SerializeObject(saveStatusRlt)); + } + } + } + } + else + { + orderInfo.LstShipOrderCompareRlt = "NO_YARD"; + orderInfo.LstShipOrderCompareRltName = "无动态"; + } + + if (compareResult.extra != null) + orderInfo.LstShipOrderCompareId = compareResult.extra.TaskCompareId; + + //更新 + await tenantDb.Updateable(orderInfo).UpdateColumns(it => new + { + it.LstShipOrderCompareId, + it.LstShipOrderCompareDate, + it.LstShipOrderCompareRlt, + it.LstShipOrderCompareRltName, + it.LstShipOrderCompareMode, + }).ExecuteCommandAsync(); + + // 记录日志 + //await _bookingOrderService.SaveLog(orderInfo, oldOrderInfo, "下货纸比对"); + } + + + result.succ = compareResult.succ; + result.msg = compareResult.msg; + result.extra = compareResult.extra; + result.extra2 = compareResult.extra2; + result.total = compareResult.total; + result.yardStatInfo = compareResult.yardStatInfo; + + Logger.Log(NLog.LogLevel.Info, "批次={no} 请求下货纸比对返回结果{msg}", batchNo, JsonConvert.SerializeObject(compareResult)); + + Logger.Log(NLog.LogLevel.Info, "批次={no} 返回结果{msg}", batchNo, JsonConvert.SerializeObject(result)); + } + catch (Exception ex) + { + result.succ = false; + result.msg = $"请求下货纸比对异常,{ex.Message}"; + } + + return result; + } + #endregion + + #region 生成请求规则报文 + /// + /// 生成请求规则报文 + /// + /// 批次号 + /// 订舱主业务信息 + /// 返回请求报文类 + private TaskMessageInfoDto GetMessageInfo(string batchNo, TaskMessageMain mainInfo) + { + DateTime nowDate = DateTime.Now; + + TaskMessageInfoDto msgModel = new TaskMessageInfoDto(); + + msgModel.Head = new TaskMessageHead + { + GID = batchNo, + MessageType = "SHIP_ORDER_COMPARE", + SenderId = AppSetting.app(new string[] { "ExcuteRuleService", "RulesEngineSender" }), + SenderName = AppSetting.app(new string[] { "ExcuteRuleService", "RulesEngineSenderName" }), + ReceiverId = "RulesEngine", + ReceiverName = "大简云规则引擎", + Version = "1.0", + RequestDate = nowDate.ToString("yyyy-MM-dd HH:mm:ss"), + RequestAction = "Compare", + }; + + msgModel.Main = mainInfo; + + return msgModel; + } + #endregion + + #region 请求下货纸比对 + /// + /// 请求下货纸比对 + /// + /// + /// + private async Task ExcuteCompare(TaskMessageInfoDto info) + { + TaskManageExcuteResultDto model = null; + /* + 1、读取配置文件中的规则引擎URL + 2、填充请求的类,并生成JSON报文 + 3、POST请求接口,并记录回执。 + 4、返回信息。 + */ + + try + { + //var res = await url.OnClientCreating(client => { + // // client 为 HttpClient 对象 + // client.Timeout = TimeSpan.FromMinutes(15); // 设置超时时间 15分钟 + //}).SetHttpMethod(HttpMethod.Post) + // .SetBody(JsonConvert.SerializeObject(info), "application/json") + // .SetContentEncoding(Encoding.UTF8) + //.PostAsync(); + + var jsonBody = JsonConvert.SerializeObject(info); + var res = RequestHelper.Post(jsonBody, shippingOrderCompareUrl); + + Logger.Log(NLog.LogLevel.Info, string.Format("批次={no} 对应请求报文完成 res={res}", info.Head.GID, res)); + + if (!string.IsNullOrWhiteSpace(res)) + { + //var userResult = await res.Content.ReadAsStringAsync(); + + model = JsonConvert.DeserializeObject(res); + } + } + catch (Exception ex) + { + //写日志 + if (ex is HttpRequestException) + throw new Exception("请求失败"); + } + + return model; + } + #endregion + + #region 请求下货纸比对结果 + /// + /// 请求下货纸比对结果 + /// + /// 订舱主键 + /// + /// + public async Task GetShippingOrderCompareResult(long bookingId) + { + string batchNo = GuidHelper.GetSnowflakeId(); + + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + + TaskManageExcuteResultDto result = new TaskManageExcuteResultDto(); + + try + { + var model = tenantDb.Queryable() + .First(a => a.Id == bookingId); + + DateTime nowDate = DateTime.Now; + + TaskMessageInfoDto msgModel = new TaskMessageInfoDto + { + Head = new TaskMessageHead + { + GID = batchNo, + MessageType = "DRAFT_COMPARE", + SenderId = AppSetting.app(new string[] { "ExcuteRuleService", "RulesEngineSender" }), + SenderName = AppSetting.app(new string[] { "ExcuteRuleService", "RulesEngineSenderName" }), + ReceiverId = "RulesEngine", + ReceiverName = "大简云规则引擎", + Version = "1.0", + RequestDate = nowDate.ToString("yyyy-MM-dd HH:mm:ss"), + RequestAction = "Compare", + }, + Main = new TaskMessageMain + { + BusiPKId = bookingId.ToString(), + TaskCompareId = model.LstShipOrderCompareId, + } + }; + + Logger.Log(NLog.LogLevel.Info, $"开始请求查询 msg={JsonConvert.SerializeObject(msgModel)}"); + + result = await GetCompareResult(msgModel); + + if (result != null && result.extra != null && !string.IsNullOrWhiteSpace(result.extra.TaskCompareId)) + { + var feedBack = tenantDb.Queryable().First(a => a.BOOKING_ID == bookingId + && a.TASK_COMPARE_ID == result.extra.TaskCompareId); + + if (feedBack != null) + { + result.extra.ManualFeedBackResult = new FeedBackResult + { + OperNote = feedBack.NOTES, + OperTime = feedBack.CreateTime, + OperUser = feedBack.CreateUserName, + Reason = (feedBack.IS_OCR_ERROR ? "识别问题 " : "") + (feedBack.IS_EDIT_ERROR ? "录入问题 " : "") + (feedBack.IS_AGENT_ERROR ? "代理录入问题 " : "") + }; + } + } + + } + catch (Exception ex) + { + Logger.Log(NLog.LogLevel.Info, "获取Draft比对结果异常,原因:{error}", ex.Message); + + throw new Exception($"获取Draft比对结果异常,原因:{ex.Message}"); + } + + return result; + } + #endregion + + #region 获取Draft比对结果 + /// + /// 获取Draft比对结果 + /// + /// 请求报文 + /// 返回回执 + private async Task GetCompareResult(TaskMessageInfoDto info) + { + TaskManageExcuteResultDto model = null; + + try + { + //var res = await url.SetHttpMethod(HttpMethod.Post) + // .SetBody(JSON.Serialize(info), "application/json") + // .SetContentEncoding(Encoding.UTF8) + //.PostAsync(); + + var jsonBody = JsonConvert.SerializeObject(info); + var res = RequestHelper.Post(jsonBody, shippingOrderCompareResultUrl); + + Logger.Log(NLog.LogLevel.Info, string.Format("批次={no} 对应请求报文完成 res={res}", info.Head.GID, res)); + + if (!string.IsNullOrWhiteSpace(res)) + { + //var userResult = await res.Content.ReadAsStringAsync(); + + Logger.Log(NLog.LogLevel.Info, "对应请求报文 userResult={userResult}", res); + + model = JsonConvert.DeserializeObject(res); + } + } + catch (Exception ex) + { + //写日志 + if (ex is HttpRequestException) + throw new Exception("请求失败"); + } + + return model; + } + #endregion + + public async Task ExcuteShippingOrderCompareBatchAsync([FromBody] string[] bookingIds) + { + TaskManageExcuteResultDto result = new TaskManageExcuteResultDto(); + + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + + try + { + var ids = bookingIds.Select(a => long.Parse(a)).Distinct().ToArray(); + + var list = tenantDb.Queryable().Where(t => ids.Contains(t.Id)).ToList(); + + if (list.Count != ids.Length) + { + var noRecord = string.Join(",", ids.GroupJoin(list, l => l, r => r.Id, (l, r) => + { + var currList = r.ToList(); + + if (r.Count() > 0) + return 0; + + return l; + }).Where(t => t > 0).ToArray()); + + throw new Exception($"以下主键信息 {noRecord} 检索失败或者已作废过"); + } + + //这里单票下货纸比对时,等待结果返回 + if (ids.Length == 1) + { + result = await InnerExcuteShippingOrderCompareAsync(list.FirstOrDefault().Id.ToString()); + } + else + { + List> listOfTasks = new List>(); + + list.ForEach(entity => + { + listOfTasks.Add(InnerExcuteShippingOrderCompareAsync(entity.Id.ToString())); + }); + + await Task.WhenAll(listOfTasks); + + result.succ = true; + result.msg = "比对完成"; + + string rltMsg = string.Empty; + + result.rows = listOfTasks.Select(a => + { + var origId = a.Result.extra.OrigPKId; + + var order = list.FirstOrDefault(x => x.Id == long.Parse(origId)); + + if (a.Result.succ) + { + if (a.Result.total > 0) + { + return new { MblNo = order.MBLNO, Msg = "比对异常", IsDiff = true, rlt = a.Result.succ }; + } + + return new { MblNo = order.MBLNO, Msg = "比对一致", IsDiff = false, rlt = a.Result.succ }; + } + + return new { MblNo = order?.MBLNO, Msg = "比对一致", IsDiff = false, rlt = a.Result.succ }; + }).ToList(); + } + + + + } + catch (Exception ex) + { + result.succ = false; + result.msg = $"请求下货纸比对异常,{ex.Message}"; + } + + return result; + } + + #region 下货纸自动比对回写状态 + /// + /// 下货纸自动比对回写状态 + /// + /// 比对回写详情 + /// 返回回执 + public async Task AutoTaskShippingOrderCompareCallBackAsync([FromBody] ShippingOrderCompareCallBackInfo model) + { + TaskManageExcuteResultDto result = new TaskManageExcuteResultDto(); + + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + + try + { + if (string.IsNullOrWhiteSpace(model.reqBusiId)) + throw new Exception($"订舱主键{model.reqBusiId}不能为空"); + + if (string.IsNullOrWhiteSpace(model.compareId)) + throw new Exception($"比对ID{model.compareId}不能为空"); + + if (string.IsNullOrWhiteSpace(model.compareMode)) + throw new Exception($"下货纸比对方式不能为空{model.compareMode}不能为空"); + + if (string.IsNullOrWhiteSpace(model.compareRltCode)) + throw new Exception($"比对结果代码{model.compareRltCode}不能为空"); + + if (string.IsNullOrWhiteSpace(model.compareRltName)) + throw new Exception($"比对结果名称{model.compareId}不能为空"); + + var bookingOrder = await tenantDb.Queryable() + .FirstAsync(a => a.Id == long.Parse(model.reqBusiId)); + + if (bookingOrder == null) + { + throw new Exception($"订舱信息检索失败,ID={model.reqBusiId}"); + } + var oldBookingOrder = bookingOrder.Adapt(); + + bookingOrder.LstShipOrderCompareId = model.compareId; + bookingOrder.LstShipOrderCompareDate = model.compareDate; + bookingOrder.LstShipOrderCompareRlt = model.compareRltCode; + bookingOrder.LstShipOrderCompareRltName = model.compareRltName; + bookingOrder.LstShipOrderCompareMode = model.compareMode; + + //更新 + await tenantDb.Updateable(bookingOrder).UpdateColumns(it => new + { + it.LstShipOrderCompareId, + it.LstShipOrderCompareDate, + it.LstShipOrderCompareRlt, + it.LstShipOrderCompareRltName, + it.LstShipOrderCompareMode, + }).ExecuteCommandAsync(); + + //await _bookingOrderService.SaveLog(bookingOrder, oldBookingOrder, "下货纸自动比对回写状态"); + + result.succ = true; + result.msg = "更新完成"; + } + catch (Exception ex) + { + result.succ = false; + result.msg = $"下货纸自动比对回写状态失败,{ex.Message}"; + } + + return result; + } + #endregion + + + #region 自动执行下货纸比对 + /// + /// 自动执行下货纸比对 + /// + /// 订舱主键 + /// 返回回执 + public async Task ExcuteAutoShippingOrderCompareAsync(string bookingId) + { + string batchNo = GuidHelper.GetSnowflakeId(); + + Logger.Log(NLog.LogLevel.Info, "批次={no}获取订舱数据请求规则 {id}", batchNo, bookingId); + + /* + 处理逻辑 + 1、台账触发单票下货纸比对 + 2、调取订舱的详情。 + 3、对应请求报文。 + 4、请求比对接口。 + 5、返回回执。 + */ + + return await InnerExcuteShippingOrderCompareAsync(bookingId, "AUTO"); + } + #endregion + } +}