diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskDraftCompareMessageInfo.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskDraftCompareMessageInfo.cs index c6f141b8..621ba736 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskDraftCompareMessageInfo.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskDraftCompareMessageInfo.cs @@ -33,6 +33,11 @@ namespace Myshipping.Application /// 业务详情 /// public BusinessInfo BusinessInfo { get; set; } + + /// + /// 附页识别原始文本 + /// + public string AttchedSheetText { get; set; } } public class BusinessInfo diff --git a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskDraftCompareService.cs b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskDraftCompareService.cs index cd925a9f..7a8c6202 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskDraftCompareService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskDraftCompareService.cs @@ -28,5 +28,15 @@ namespace Myshipping.Application /// 返回回执 Task GetDraftCompareResultInfo(long bookingId); + + + /// + /// 执行邮件Draft比对(含有附件文件-针对TSL货描附件处理) + /// + /// 请求文件 + /// 请求附件文件 + /// 邮件Draft比对请求报文 + /// 返回回执 + Task ExcuteEmailAttachedSheetDraftCompareAsync(IFormFile file, IFormFile fileAttach, string jsonData); } } diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskDraftCompareService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskDraftCompareService.cs index e0819be4..f4a81e9d 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskDraftCompareService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskDraftCompareService.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Myshipping.Application.Entity; +using Myshipping.Application.Service; using Myshipping.Core; using Myshipping.Core.Entity; using Myshipping.Core.Service; @@ -121,7 +122,7 @@ namespace Myshipping.Application file = "file", fileName = file.FileName, fileBytes = bytes - }); + },null); DateTime eDate = DateTime.Now; TimeSpan ts = eDate.Subtract(bDate); @@ -283,11 +284,12 @@ namespace Myshipping.Application /// /// 请求参数 /// 文件 + /// 附页文件 /// 请求类型 /// 返回回执 [NonAction] private async Task ExcuteReadPDF(NameValueCollection nameValueCollection, dynamic fileInfo, - string contentType = "application/json") + dynamic fileAttach, string contentType = "application/json") { TaskManageExcuteCommonResultDto model = null; var result = string.Empty; @@ -316,16 +318,18 @@ namespace Myshipping.Application { var Content = new ByteArrayContent(fileInfo.fileBytes); - //Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") - //{ - // Name = fileInfo.file.ToString(), - // FileName = fileInfo.fileName.ToString(), - - //}; - Content.Headers.Add("Content-Type", contentType); reduceAttach.Add(Content, fileInfo.file.ToString(), HttpUtility.UrlEncode(fileInfo.fileName.ToString())); + + if(fileAttach != null) + { + var Content2 = new ByteArrayContent(fileAttach.fileBytes); + + Content2.Headers.Add("Content-Type", contentType); + + reduceAttach.Add(Content2, fileAttach.file.ToString(), HttpUtility.UrlEncode(fileAttach.fileName.ToString())); + } } #endregion @@ -349,6 +353,55 @@ namespace Myshipping.Application } #endregion + #region 请求Draft的PDF解析 + /// + /// 请求Draft的PDF解析 + /// + /// 请求地址 + /// 文件详情 + /// 返回BC解析详情 + private async Task TransmitFile(string requestUrl, dynamic fileInfo) + { + PDFReadFileResultDto model = null; + + try + { + var response = await requestUrl.SetContentType("multipart/form-data") + .SetBodyBytes(fileInfo.file.ToString(), + fileInfo.fileBytes, + HttpUtility.UrlEncode(fileInfo.fileName.ToString())) + .PostAsync(); + + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + var result = response.Content.ReadAsStringAsync().Result; + + if (string.IsNullOrWhiteSpace(result)) + { + throw Oops.Bah($"请求格式单PDF文件解析失败,未获取到有效信息"); + } + + /* + System.Text.Json.JsonSerializerOptions jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new DateTimeJsonConverter("yyyy-MM-dd HH:mm:ss")); + jsonOptions.Converters.Add(new IntegerJsonConverter()); + jsonOptions.Converters.Add(new DecimalJsonConverter()); + */ + + model = JSON.Deserialize(result); + } + } + catch (Exception ex) + { + //_logger.LogInformation("{name} 发送BC文件解析请求 url={url} 异常,原因={error}", nameof(TransmitFile), + //requestUrl, ex.Message); + + throw Oops.Bah($"{nameof(TransmitFile)} {requestUrl} 请求格式单PDF文件解析异常,{ex.Message}"); + } + return model; + } + #endregion + #region 请求格式单比对 /// /// 请求格式单比对 @@ -525,5 +578,222 @@ namespace Myshipping.Application return model; } #endregion + + #region 执行邮件Draft比对(含有附件文件-针对TSL货描附件处理) + /// + /// 执行邮件Draft比对(含有附件文件-针对TSL货描附件处理) + /// + /// 请求文件 + /// 请求附件文件 + /// 邮件Draft比对请求报文 + /// 返回回执 + [AllowAnonymous, HttpPost("/TaskDraftCompare/ExcuteEmailAttachedSheetDraftCompare")] + public async Task ExcuteEmailAttachedSheetDraftCompareAsync(IFormFile file, IFormFile fileAttach, string jsonData) + { + string batchNo = IDGen.NextID().ToString(); + + TaskManageExcuteResultDto result = new TaskManageExcuteResultDto(); + + DateTime nowDate = DateTime.Now; + /* + 1、接收报文里的文件信息,优先写入本地文件暂存。 + 2、请求解析Draft文件解析,并等待解析结果。 + 3、判断对应的订舱提单号。如果没有对应的订舱提单号,则写入任务表失败记录。 + 4、写入任务表。 + 5、异步请求格式单比对接口。 + 6、接收比对结果更新任务表。 + 7、更新订舱表,并更新状态。 + */ + try + { + var model = GetJsonMessageInfo(jsonData, batchNo); + + TaskDraftCompareMessageInfo readFileMessageInfo = new TaskDraftCompareMessageInfo + { + Head = new TaskMessageHead + { + GID = batchNo, + MessageType = "DRAFT_COMPARE", + SenderId = App.Configuration["RulesEngineSender"], + SenderName = App.Configuration["RulesEngineSenderName"], + ReceiverId = "RulesEngine", + ReceiverName = "大简云规则引擎", + Version = "1.0", + RequestDate = nowDate.ToString("yyyy-MM-dd HH:mm:ss"), + RequestAction = "Compare", + } + }; + + //附件暂存 + var fileFullName = await FileAttachHelper.TempSaveWebFile(model.Head.GID, file, batchNo, CONST_DRAFT_FILE_CODE); + + //Draft文件解析 + NameValueCollection par = new NameValueCollection(); + par.Add("jsonMessage", JSON.Serialize(readFileMessageInfo)); + + byte[] bytes = file.ToByteArray(); + + DateTime bDate = DateTime.Now; + + TaskManageExcuteCommonResultDto readResult = null; + if (fileAttach != null) + { + byte[] bytesAttach = fileAttach.ToByteArray(); + + readResult = await ExcuteReadPDF(par, new + { + file = "file", + fileName = file.FileName, + fileBytes = bytes + }, + new + { + file = "fileAttach", + fileName = fileAttach.FileName, + fileBytes = bytesAttach + }); + } + else + { + readResult = await ExcuteReadPDF(par, new + { + file = "file", + fileName = file.FileName, + fileBytes = bytes + },null); + } + + DateTime eDate = DateTime.Now; + TimeSpan ts = eDate.Subtract(bDate); + var timeDiff = ts.TotalMilliseconds; + + _logger.LogInformation("批次={no} 请求Draft文件解析完成,耗时:{timeDiff}ms. 结果{msg} 报文={message}", batchNo, timeDiff, + readResult.succ ? "成功" : "失败", + JSON.Serialize(readResult)); + + + if (!readResult.succ) + { + _logger.LogInformation("批次={no} 请求Draft文件解析失败 原因={reason}", batchNo, readResult.msg); + + throw Oops.Oh($"请求Draft文件解析失败 原因={readResult.msg}"); + } + + //通过解析提单号匹配订舱的详情 + var readModel = JSON.Deserialize(JSON.Serialize(readResult.extra)); + + string billNo = string.Empty; + + if (!string.IsNullOrWhiteSpace(readModel.MasterBlNo)) + { + billNo = readModel.MasterBlNo; + } + + if (string.IsNullOrWhiteSpace(billNo)) + { + _logger.LogInformation("批次={no} 请求Draft文件解析未获取到有效提单号", batchNo); + + throw Oops.Oh($"请求Draft文件解析未获取到有效提单号"); + } + + var bookingOrder = _bookingOrderRepository.AsQueryable().Filter(null, true) + .First(a => a.MBLNO.Equals(billNo)); + + if (bookingOrder == null) + { + _logger.LogInformation("批次={no} 提单号{billNo}无法获取业务信息", batchNo, billNo); + + throw Oops.Oh($"提单号{billNo}无法获取业务信息"); + } + + _logger.LogInformation("批次={no}获取订舱数据完成", batchNo); + + TaskDraftCompareMessageInfo msgModel = new TaskDraftCompareMessageInfo + { + Head = new TaskMessageHead + { + GID = batchNo, + MessageType = "DRAFT_COMPARE", + SenderId = App.Configuration["RulesEngineSender"], + SenderName = App.Configuration["RulesEngineSenderName"], + ReceiverId = "RulesEngine", + ReceiverName = "大简云规则引擎", + Version = "1.0", + RequestDate = nowDate.ToString("yyyy-MM-dd HH:mm:ss"), + RequestAction = "Compare", + }, + Main = new TaskDraftMessageMainInfo() + }; + + //请求格式单比对接口 + var mainInfo = bookingOrder.Adapt(); + + var userInfo = _sysUserRepository.AsQueryable().First(a => a.Id == bookingOrder.CreatedUserId); + + mainInfo.BusiPKId = bookingOrder.Id.ToString(); + mainInfo.UserId = bookingOrder.CreatedUserId.ToString(); + mainInfo.UserName = bookingOrder.CreatedUserName; + mainInfo.UserEmail = userInfo?.Email; + + var contaList = _bookingOrderContaRepository.AsQueryable().Filter(null, true) + .Where(x => x.BILLID == bookingOrder.Id).ToList(); + + _logger.LogInformation("批次={no} 提取箱完成 数量={total}", batchNo, contaList.Count); + + if (contaList.Count > 0) + { + mainInfo.ContaList = contaList.Adapt>(); + } + + msgModel.Main.BusinessInfo = mainInfo; + msgModel.Main.DraftInfo = readModel; + + //推送Draft比对 + DateTime bCompareDate = DateTime.Now; + + var compareResult = await ExcuteDraftCompare(msgModel); + + DateTime eCompareDate = DateTime.Now; + TimeSpan tsCompare = bCompareDate.Subtract(eCompareDate); + var timeDiffCompare = tsCompare.TotalMilliseconds; + + _logger.LogInformation("批次={no} 请求Draft比对完成,耗时:{timeDiff}ms. 结果{msg} 报文={message}", batchNo, timeDiffCompare, + compareResult.succ ? "成功" : "失败", + JSON.Serialize(compareResult)); + + _logger.LogInformation("批次={no} 对应请求报文完成 msg={msg}", batchNo, JSON.Serialize(msgModel)); + + var entity = _bookingOrderRepository.AsQueryable().Filter(null, true) + .First(a => a.Id == bookingOrder.Id); + + entity.LstDraftCompareRlt = compareResult.extra2.Any(a => a.IsDiff) ? "DIFF" : ""; + entity.LstDraftCompareDate = nowDate; + + //更新订舱相关 + await _bookingOrderRepository.AsUpdateable(entity).UpdateColumns(it => new + { + it.LstDraftCompareDate, + it.LstDraftCompareRlt + + }).ExecuteCommandAsync(); + + //如果确认文件读取成功 + var bookFilePath = await FileAttachHelper.MoveFile(bookingOrder.Id.ToString(), fileFullName, batchNo); + + //将格式单附件写入订舱的附件 + await SaveEDIFile(bookingOrder.Id, bookFilePath, new System.IO.FileInfo(fileFullName).Name, entity.TenantId.Value, + CONST_DRAFT_FILE_CODE, CONST_DRAFT_FILE_NAME); + + result = compareResult; + } + catch (Exception ex) + { + result.succ = false; + result.msg = $"请求Draft比对异常,{ex.Message}"; + } + + return result; + } + #endregion } }