|
|
|
|
using Furion;
|
|
|
|
|
using Furion.DependencyInjection;
|
|
|
|
|
using Furion.DistributedIDGenerator;
|
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
|
using Furion.Extensions;
|
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
|
using Furion.JsonSerialization;
|
|
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
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;
|
|
|
|
|
using NPOI.SS.Formula.Functions;
|
|
|
|
|
using Org.BouncyCastle.Asn1.X9;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
using System.Net.Http.Headers;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Web;
|
|
|
|
|
using Yitter.IdGenerator;
|
|
|
|
|
|
|
|
|
|
namespace Myshipping.Application
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 请求Draft比对
|
|
|
|
|
/// </summary>
|
|
|
|
|
[ApiDescriptionSettings("Application", Name = "TaskDraftCompare", Order = 10)]
|
|
|
|
|
public class TaskDraftCompareService : ITaskDraftCompareService, IDynamicApiController, ITransient
|
|
|
|
|
{
|
|
|
|
|
private readonly ISysCacheService _cache;
|
|
|
|
|
private readonly ILogger<TaskDraftCompareService> _logger;
|
|
|
|
|
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingCtn> _bookingOrderContaRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingFile> _bookingFileRepository;
|
|
|
|
|
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
|
|
|
|
|
private readonly IBookingOrderService _bookingOrderService;
|
|
|
|
|
|
|
|
|
|
const string CONST_DRAFT_FILE_CODE = "draft";
|
|
|
|
|
const string CONST_DRAFT_FILE_NAME = "格式单";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public TaskDraftCompareService(ISysCacheService cache, ILogger<TaskDraftCompareService> logger,
|
|
|
|
|
SqlSugarRepository<BookingOrder> bookingOrderRepository, SqlSugarRepository<BookingCtn> bookingOrderContaRepository,
|
|
|
|
|
SqlSugarRepository<BookingFile> bookingFileRepository, SqlSugarRepository<SysUser> sysUserRepository, IBookingOrderService bookingOrderService)
|
|
|
|
|
{
|
|
|
|
|
_cache = cache;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
|
|
|
|
|
_bookingOrderRepository = bookingOrderRepository;
|
|
|
|
|
_bookingOrderContaRepository = bookingOrderContaRepository;
|
|
|
|
|
_bookingFileRepository = bookingFileRepository;
|
|
|
|
|
_sysUserRepository = sysUserRepository;
|
|
|
|
|
_bookingOrderService = bookingOrderService;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 执行邮件Draft比对
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 执行邮件Draft比对
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="file">请求文件</param>
|
|
|
|
|
/// <param name="jsonData">邮件Draft比对请求报文</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[AllowAnonymous,HttpPost("/TaskDraftCompare/ExcuteEmailDraftCompare")]
|
|
|
|
|
public async Task<TaskManageExcuteResultDto> ExcuteEmailDraftCompareAsync(IFormFile file, [FromForm] 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;
|
|
|
|
|
|
|
|
|
|
var 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<CompareDraftDataInfo>(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) && !a.IsDeleted && a.TenantId == long.Parse(model.Main.TenantId));
|
|
|
|
|
|
|
|
|
|
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<BusinessInfo>();
|
|
|
|
|
|
|
|
|
|
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 && !x.IsDeleted && x.TenantId == long.Parse(model.Main.TenantId)).ToList();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("批次={no} 提取箱完成 数量={total}", batchNo, contaList.Count);
|
|
|
|
|
|
|
|
|
|
if (contaList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
mainInfo.ContaList = contaList.Adapt<List<TaskDraftMessageCtnInfo>>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 && !a.IsDeleted && a.TenantId == long.Parse(model.Main.TenantId));
|
|
|
|
|
|
|
|
|
|
entity.LstDraftCompareRlt = compareResult.extra2.Any(a => a.IsDiff) ? "DIFF" : "NO DIFF";
|
|
|
|
|
entity.LstDraftCompareDate = nowDate;
|
|
|
|
|
|
|
|
|
|
//更新订舱相关
|
|
|
|
|
await _bookingOrderRepository.AsUpdateable(entity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.LstDraftCompareDate,
|
|
|
|
|
it.LstDraftCompareRlt
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
if (entity.LstDraftCompareRlt == "NO DIFF")
|
|
|
|
|
{
|
|
|
|
|
//推送状态 HDGSD-核对格式单
|
|
|
|
|
await _bookingOrderService.SetGoodsStatusPush("HDGSD", bookingOrder.Id, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//如果确认文件读取成功
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
#region 反序列化请求参数报文
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 反序列化请求参数报文
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="jsonMessage">请求参数报文</param>
|
|
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
|
|
/// <returns>返回反序列化结果</returns>
|
|
|
|
|
private TaskEmailDraftCompareMessageInfo GetJsonMessageInfo(string jsonMessage, string batchNo)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return JSON.Deserialize<TaskEmailDraftCompareMessageInfo>(jsonMessage);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("批次号{0} jsonMessage请求参数转换失败", batchNo);
|
|
|
|
|
|
|
|
|
|
throw Oops.Oh($"jsonMessage请求参数转换失败");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 解析格式单文件
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 解析格式单文件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="nameValueCollection">请求参数</param>
|
|
|
|
|
/// <param name="fileInfo">文件</param>
|
|
|
|
|
/// <param name="fileAttach">附页文件</param>
|
|
|
|
|
/// <param name="contentType">请求类型</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[NonAction]
|
|
|
|
|
private async Task<TaskManageExcuteCommonResultDto> ExcuteReadPDF(NameValueCollection nameValueCollection, dynamic fileInfo,
|
|
|
|
|
dynamic fileAttach, string contentType = "application/json")
|
|
|
|
|
{
|
|
|
|
|
TaskManageExcuteCommonResultDto model = null;
|
|
|
|
|
var result = string.Empty;
|
|
|
|
|
|
|
|
|
|
using (var httpClient = new HttpClient())
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using (var reduceAttach = new MultipartFormDataContent())
|
|
|
|
|
{
|
|
|
|
|
string[] allKeys = nameValueCollection.AllKeys;
|
|
|
|
|
foreach (string key in allKeys)
|
|
|
|
|
{
|
|
|
|
|
var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(nameValueCollection[key]));
|
|
|
|
|
|
|
|
|
|
dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue($"form-data")
|
|
|
|
|
{
|
|
|
|
|
Name = key
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
reduceAttach.Add(dataContent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 文件参数
|
|
|
|
|
if (fileInfo != null)
|
|
|
|
|
{
|
|
|
|
|
var Content = new ByteArrayContent(fileInfo.fileBytes);
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
//请求
|
|
|
|
|
var response = httpClient.PostAsync(App.Configuration["DraftReadUrl"], reduceAttach).Result;
|
|
|
|
|
result = response.Content.ReadAsStringAsync().Result;
|
|
|
|
|
|
|
|
|
|
model = JSON.Deserialize<TaskManageExcuteCommonResultDto>(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("请求Draft比对异常,原因:{error}", ex.Message);
|
|
|
|
|
|
|
|
|
|
throw Oops.Oh($"请求Draft比对异常,原因:{ex.Message}");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return model;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 请求Draft的PDF解析
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 请求Draft的PDF解析
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="requestUrl">请求地址</param>
|
|
|
|
|
/// <param name="fileInfo">文件详情</param>
|
|
|
|
|
/// <returns>返回BC解析详情</returns>
|
|
|
|
|
private async Task<PDFReadFileResultDto> 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<PDFReadFileResultDto>(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 请求格式单比对
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 请求格式单比对
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="info">请求报文</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task<TaskManageExcuteResultDto> ExcuteDraftCompare(TaskDraftCompareMessageInfo info)
|
|
|
|
|
{
|
|
|
|
|
TaskManageExcuteResultDto model = null;
|
|
|
|
|
|
|
|
|
|
var url = App.Configuration["DraftCompareUrl"];
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var res = await url.SetHttpMethod(HttpMethod.Post)
|
|
|
|
|
.SetBody(JSON.Serialize(info), "application/json")
|
|
|
|
|
.SetContentEncoding(Encoding.UTF8)
|
|
|
|
|
.PostAsync();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("批次={no} 对应请求报文完成 res={res}", info.Head.GID, JSON.Serialize(res));
|
|
|
|
|
|
|
|
|
|
if (res.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
|
|
{
|
|
|
|
|
var userResult = await res.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("对应请求报文 userResult={userResult}", userResult);
|
|
|
|
|
|
|
|
|
|
model = JSON.Deserialize<TaskManageExcuteResultDto>(userResult);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
//写日志
|
|
|
|
|
if (ex is HttpRequestException)
|
|
|
|
|
throw Oops.Oh(10000002);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return model;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 异步写入订舱附件表
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 异步写入订舱附件表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="boookId">订舱ID</param>
|
|
|
|
|
/// <param name="FilePath">文件路径</param>
|
|
|
|
|
/// <param name="fileName">文件名</param>
|
|
|
|
|
/// <param name="tenantId">租户ID</param>
|
|
|
|
|
/// <param name="fileTypeCode">附件类型代码</param>
|
|
|
|
|
/// <param name="fileTypeName">附件类型名称</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[NonAction]
|
|
|
|
|
private async Task SaveEDIFile(long boookId, string FilePath, string fileName, long tenantId,
|
|
|
|
|
string fileTypeCode = "bc", string fileTypeName = "Booking Confirmation")
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
直接将附件信息写入附件表
|
|
|
|
|
*/
|
|
|
|
|
//EDI文件
|
|
|
|
|
var bookFile = new BookingFile
|
|
|
|
|
{
|
|
|
|
|
Id = YitIdHelper.NextId(),
|
|
|
|
|
FileName = fileName,
|
|
|
|
|
FilePath = FilePath,
|
|
|
|
|
TypeCode = fileTypeCode,
|
|
|
|
|
TypeName = fileTypeName,
|
|
|
|
|
BookingId = boookId,
|
|
|
|
|
TenantId = tenantId
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await _bookingFileRepository.InsertAsync(bookFile);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取Draft比对结果详情
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取Draft比对结果详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="bookingId">订舱主键</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpPost("/TaskDraftCompare/GetDraftCompareResultInfo")]
|
|
|
|
|
public async Task<TaskManageExcuteResultDto> GetDraftCompareResultInfo([FromQuery] long bookingId)
|
|
|
|
|
{
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
|
|
|
|
TaskManageExcuteResultDto result = new TaskManageExcuteResultDto();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
BusinessInfo = new BusinessInfo {
|
|
|
|
|
BusiPKId = bookingId.ToString()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"开始请求查询 msg={JSON.Serialize(msgModel)}");
|
|
|
|
|
|
|
|
|
|
result = await GetDraftCompareResult(msgModel);
|
|
|
|
|
|
|
|
|
|
var lastFileInfo = _bookingFileRepository.AsQueryable().Filter(null,true).Where(a=>a.BookingId == bookingId &&
|
|
|
|
|
a.TypeCode.Equals(CONST_DRAFT_FILE_CODE))
|
|
|
|
|
.OrderByDescending(a=>a.CreatedTime).First();
|
|
|
|
|
|
|
|
|
|
if (lastFileInfo != null)
|
|
|
|
|
result.extra3 = lastFileInfo.Id;
|
|
|
|
|
}
|
|
|
|
|
catch(Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("获取Draft比对结果异常,原因:{error}", ex.Message);
|
|
|
|
|
|
|
|
|
|
throw Oops.Oh($"获取Draft比对结果异常,原因:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取Draft比对结果
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取Draft比对结果
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="info">请求报文</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[NonAction]
|
|
|
|
|
private async Task<TaskManageExcuteResultDto> GetDraftCompareResult(TaskDraftCompareMessageInfo info)
|
|
|
|
|
{
|
|
|
|
|
TaskManageExcuteResultDto model = null;
|
|
|
|
|
|
|
|
|
|
var url = App.Configuration["GetDraftCompareUrl"];
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var res = await url.SetHttpMethod(HttpMethod.Post)
|
|
|
|
|
.SetBody(JSON.Serialize(info), "application/json")
|
|
|
|
|
.SetContentEncoding(Encoding.UTF8)
|
|
|
|
|
.PostAsync();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("批次={no} 对应请求报文完成 res={res}", info.Head.GID, JSON.Serialize(res));
|
|
|
|
|
|
|
|
|
|
if (res.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
|
|
{
|
|
|
|
|
var userResult = await res.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("对应请求报文 userResult={userResult}", userResult);
|
|
|
|
|
|
|
|
|
|
model = JSON.Deserialize<TaskManageExcuteResultDto>(userResult);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
//写日志
|
|
|
|
|
if (ex is HttpRequestException)
|
|
|
|
|
throw Oops.Oh(10000002);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return model;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 执行邮件Draft比对(含有附件文件-针对TSL货描附件处理)
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 执行邮件Draft比对(含有附件文件-针对TSL货描附件处理)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="file">请求文件</param>
|
|
|
|
|
/// <param name="fileAttach">请求附件文件</param>
|
|
|
|
|
/// <param name="jsonData">邮件Draft比对请求报文</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[AllowAnonymous, HttpPost("/TaskDraftCompare/ExcuteEmailAttachedSheetDraftCompare")]
|
|
|
|
|
public async Task<TaskManageExcuteResultDto> 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);
|
|
|
|
|
|
|
|
|
|
string fileAttchedFullName = string.Empty;
|
|
|
|
|
|
|
|
|
|
if(fileAttach != null)
|
|
|
|
|
{
|
|
|
|
|
fileAttchedFullName = await FileAttachHelper.TempSaveWebFile(model.Head.GID, fileAttach, 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<CompareDraftDataInfo>(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) && !a.IsDeleted && a.TenantId == long.Parse(model.Main.TenantId));
|
|
|
|
|
|
|
|
|
|
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<BusinessInfo>();
|
|
|
|
|
|
|
|
|
|
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 && !x.IsDeleted && x.TenantId == long.Parse(model.Main.TenantId))
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("批次={no} 提取箱完成 数量={total}", batchNo, contaList.Count);
|
|
|
|
|
|
|
|
|
|
if (contaList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
mainInfo.ContaList = contaList.Adapt<List<TaskDraftMessageCtnInfo>>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 && !a.IsDeleted && a.TenantId == long.Parse(model.Main.TenantId));
|
|
|
|
|
|
|
|
|
|
entity.LstDraftCompareRlt = compareResult.extra2.Any(a => a.IsDiff) ? "DIFF" : "NO DIFF";
|
|
|
|
|
entity.LstDraftCompareDate = nowDate;
|
|
|
|
|
|
|
|
|
|
//更新订舱相关
|
|
|
|
|
await _bookingOrderRepository.AsUpdateable(entity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.LstDraftCompareDate,
|
|
|
|
|
it.LstDraftCompareRlt
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
if (entity.LstDraftCompareRlt == "NO DIFF")
|
|
|
|
|
{
|
|
|
|
|
//推送状态 HDGSD-核对格式单
|
|
|
|
|
await _bookingOrderService.SetGoodsStatusPush("HDGSD", bookingOrder.Id, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//如果确认文件读取成功
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
if(!string.IsNullOrWhiteSpace(fileAttchedFullName))
|
|
|
|
|
{
|
|
|
|
|
var currBookFilePath = await FileAttachHelper.MoveFile(bookingOrder.Id.ToString(), fileAttchedFullName, batchNo);
|
|
|
|
|
|
|
|
|
|
//将格式单附件写入订舱的附件
|
|
|
|
|
await SaveEDIFile(bookingOrder.Id, currBookFilePath, new System.IO.FileInfo(fileAttchedFullName).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
|
|
|
|
|
}
|
|
|
|
|
}
|