You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1118 lines
48 KiB
C#

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.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 Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NLog;
using NPOI.SS.Formula.Functions;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Mapster;
using System.Net.Http.Headers;
using DS.Module.Core.Extensions;
using Microsoft.Extensions.DependencyInjection;
4 months ago
using DS.WMS.Core.Sys.Interface;
using DS.WMS.Core.Sys.Method;
using NPOI.HPSF;
using DS.WMS.Core.Code.Interface;
using DS.WMS.Core.Map.Interface;
namespace DS.WMS.Core.TaskPlat.Method
{
public class TaskDraftCompareService : ITaskDraftCompareService
{
private readonly IServiceProvider _serviceProvider;
private readonly ISqlSugarClient db;
private readonly IUser user;
private readonly ISaasDbService saasService;
private readonly IDjyServiceStatusService _djyServiceStatusService;
4 months ago
private readonly ISysFileService _sysFileService;
private readonly IMappingYardService _mappingYardService;
private readonly IMappingCarrierService _mappingCarrierService;
private readonly ICodePortService _codePortService;
private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger();
private readonly string draftReadUrl;
private readonly string draftCompareUrl;
private readonly string draftResultUrl;
const string CONST_DRAFT_FILE_CODE = "draft";
const string CONST_DRAFT_FILE_NAME = "格式单";
const string CONST_MAPPING_YARD_MODULE = "BillTrace";
const string CONST_MAPPING_CARRIER_MODULE = "CarrierBaseMapping";
public TaskDraftCompareService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
user = _serviceProvider.GetRequiredService<IUser>();
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
_djyServiceStatusService = _serviceProvider.GetRequiredService<IDjyServiceStatusService>();
4 months ago
_sysFileService = _serviceProvider.GetRequiredService<ISysFileService>();
_mappingYardService = _serviceProvider.GetRequiredService<IMappingYardService>();
_mappingCarrierService = _serviceProvider.GetRequiredService<IMappingCarrierService>();
_codePortService = _serviceProvider.GetRequiredService<ICodePortService>();
draftReadUrl = AppSetting.app(new string[] { "DraftCompare", "ReadUrl" });
draftCompareUrl = AppSetting.app(new string[] { "DraftCompare", "Url" });
draftResultUrl = AppSetting.app(new string[] { "DraftCompare", "ResultUrl" });
}
#region 执行邮件Draft比对
/// <summary>
/// 执行邮件Draft比对
/// </summary>
/// <param name="file">请求文件</param>
/// <param name="jsonData">邮件Draft比对请求报文</param>
/// <returns>返回回执</returns>
public async Task<TaskManageExcuteResultDto> ExcuteEmailDraftCompareAsync(IFormFile file, [FromForm] string jsonData)
{
string batchNo = GuidHelper.GetSnowflakeId();
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
TaskManageExcuteResultDto result = new TaskManageExcuteResultDto();
DateTime nowDate = DateTime.Now;
/*
1
2Draft
3
4
5
6
7
*/
try
{
var model = GetJsonMessageInfo(jsonData, batchNo);
TaskDraftCompareMessageInfo readFileMessageInfo = new TaskDraftCompareMessageInfo
{
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",
}
};
4 months ago
var fileRlt = await _sysFileService.SaveFileDirect(model.Head.GID, file.ToByteArray(), batchNo, file.FileName, "bcfiles");
var fileFullName = fileRlt.Data.Item1;
4 months ago
//附件暂存
4 months ago
//var fileFullName = "";//await FileAttachHelper.TempSaveWebFile(model.Head.GID, file, batchNo, CONST_DRAFT_FILE_CODE);
//Draft文件解析
NameValueCollection par = new NameValueCollection();
par.Add("jsonMessage", JsonConvert.SerializeObject(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.Log(NLog.LogLevel.Info, string.Format("批次={0} 请求Draft文件解析完成,耗时:{1}ms. 结果{2} 报文={3}", batchNo, timeDiff,
readResult.succ ? "成功" : "失败",
JsonConvert.SerializeObject(readResult)));
if (!readResult.succ)
{
Logger.Log(NLog.LogLevel.Info, "批次={no} 请求Draft文件解析失败 原因={reason}", batchNo, readResult.msg);
throw new Exception($"请求Draft文件解析失败 原因={readResult.msg}");
}
//通过解析提单号匹配订舱的详情
var readModel = JsonConvert.DeserializeObject<CompareDraftDataInfo>(JsonConvert.SerializeObject(readResult.extra));
string billNo = string.Empty;
if (!string.IsNullOrWhiteSpace(readModel.MasterBlNo))
{
billNo = readModel.MasterBlNo;
}
if (string.IsNullOrWhiteSpace(billNo))
{
Logger.Log(NLog.LogLevel.Info, "批次={no} 请求Draft文件解析未获取到有效提单号", batchNo);
throw new Exception($"请求Draft文件解析未获取到有效提单号");
}
var bookingOrder = tenantDb.Queryable<SeaExport>().First(a => a.MBLNO.Equals(billNo));
if (bookingOrder == null)
{
Logger.Log(NLog.LogLevel.Info, "批次={no} 提单号{billNo}无法获取业务信息", batchNo, billNo);
throw new Exception($"提单号{billNo}无法获取业务信息");
}
Logger.Log(NLog.LogLevel.Info, "批次={no}获取订舱数据完成", batchNo);
TaskDraftCompareMessageInfo msgModel = new TaskDraftCompareMessageInfo
{
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 TaskDraftMessageMainInfo()
};
//请求格式单比对接口
var mainInfo = bookingOrder.Adapt<BusinessInfo>();
//这里需要对场站进行映射翻译
var mapYardList = _mappingYardService.GetAllList().GetAwaiter().GetResult().Data;
if (mapYardList.Count > 0)
mapYardList = mapYardList.Where(a => a.Module.Equals(CONST_MAPPING_YARD_MODULE, StringComparison.OrdinalIgnoreCase)).ToList();
if (mapYardList.Any(a => a.LinkId == bookingOrder.YardId))
{
mainInfo.YardCode = mapYardList.FirstOrDefault(a => a.LinkId == bookingOrder.YardId).MapCode;
}
var codePortList = _codePortService.GetAllList().GetAwaiter().GetResult().Data;
if (codePortList.Any(a => a.Id == bookingOrder.LoadPortId))
mainInfo.PortLoadId = codePortList.FirstOrDefault(a => a.Id == bookingOrder.LoadPortId).EdiCode;
if (codePortList.Any(a => a.Id == bookingOrder.DischargePortId))
mainInfo.PortDischargeId = codePortList.FirstOrDefault(a => a.Id == bookingOrder.DischargePortId).EdiCode;
if (codePortList.Any(a => a.Id == bookingOrder.DeliveryPlaceId))
mainInfo.PlaceDeliveryId = codePortList.FirstOrDefault(a => a.Id == bookingOrder.DeliveryPlaceId).EdiCode;
if (codePortList.Any(a => a.Id == bookingOrder.DestinationId))
mainInfo.DestinationId = codePortList.FirstOrDefault(a => a.Id == bookingOrder.DestinationId).EdiCode;
//var mapCarrierList = _mappingCarrierService.GetAllList().GetAwaiter().GetResult().Data;
//if (mapCarrierList.Count > 0)
// mapCarrierList = mapCarrierList.Where(a => a.Module.Equals(CONST_MAPPING_CARRIER_MODULE, StringComparison.OrdinalIgnoreCase)).ToList();
//if (mapYardList.Any(a => a.LinkId == bookingOrder.CarrierId))
//{
// mainInfo.CarrierCode = mapYardList.FirstOrDefault(a => a.LinkId == model.CarrierId).MapCode;
//}
//var userInfo = _sysUserRepository.AsQueryable().First(a => a.Id == bookingOrder.CreatedUserId);
mainInfo.BusiPKId = bookingOrder.Id.ToString();
mainInfo.UserId = user.UserId;
mainInfo.UserName = user.UserName;
//mainInfo.UserEmail = UserManager.Email;
var contaList = tenantDb.Queryable<OpCtn>()
.Where(x => long.Parse(x.BSNO) == bookingOrder.Id).ToList();
Logger.Log(NLog.LogLevel.Info, "批次={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.Log(NLog.LogLevel.Info, string.Format("批次={0} 请求Draft比对完成,耗时:{1}ms. 结果{2} 报文={3}", batchNo, timeDiffCompare,
compareResult.succ ? "成功" : "失败",
JsonConvert.SerializeObject(compareResult)));
Logger.Log(NLog.LogLevel.Info, "批次={no} 对应请求报文完成 msg={msg}", batchNo, JsonConvert.SerializeObject(msgModel));
var entity = tenantDb.Queryable<SeaExport>()
.First(a => a.Id == bookingOrder.Id);
var oldEntity = entity.Adapt<SeaExport>();
entity.LstDraftCompareRlt = compareResult.extra2.Any(a => a.IsDiff) ? "DIFF" : "NO DIFF";
entity.LstDraftCompareDate = nowDate;
//更新订舱相关
await tenantDb.Updateable(entity).UpdateColumns(it => new
{
it.LstDraftCompareDate,
it.LstDraftCompareRlt
}).ExecuteCommandAsync();
// 保存日志
//await _bookingOrderService.SaveLog(entity, oldEntity, "核对格式单");
if (entity.LstDraftCompareRlt == "NO DIFF")
{
//推送状态 HDGSD-核对格式单
//await _bookingOrderService.SetGoodsStatusPush("HDGSD", bookingOrder.Id, true);
4 months ago
//比对成功后触发下货纸比对状态
var pushModel = new EmbedServiceProjectStatusDto
{
businessId = bookingOrder.Id.ToString(),
SourceType = 1,
StatusCodes = new List<EmbedServiceProjectStatusDetailDto> {
new EmbedServiceProjectStatusDetailDto{
StatusCode = "HDGSD"
}
}
};
var saveStatusRlt = await _djyServiceStatusService.SaveServiceStatus(pushModel);
//写日志
Logger.Log(NLog.LogLevel.Info, "批次={no} 推送状态 HDGSD-核对格式单 id={id}", batchNo, bookingOrder.Id);
}
//如果确认文件读取成功
4 months ago
var bookFilePath = await _sysFileService.MoveFile(bookingOrder.Id.ToString(), fileFullName, batchNo, false, "draftfiles");
//将格式单附件写入订舱的附件
4 months ago
await SaveEDIFile(bookingOrder.Id, bookFilePath.Data.Item2, new System.IO.FileInfo(fileFullName).Name, long.Parse(user.TenantId), bookFilePath.Data.Item4,
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 JsonConvert.DeserializeObject<TaskEmailDraftCompareMessageInfo>(jsonMessage);
}
catch
{
Logger.Log(NLog.LogLevel.Info, "批次号{0} jsonMessage请求参数转换失败", batchNo);
throw new Exception($"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(draftReadUrl, reduceAttach).Result;
result = response.Content.ReadAsStringAsync().Result;
model = JsonConvert.DeserializeObject<TaskManageExcuteCommonResultDto>(result);
}
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, "请求Draft比对异常原因{error}", ex.Message);
throw new Exception($"请求Draft比对异常原因{ex.Message}");
4 months ago
//model = new TaskManageExcuteCommonResultDto
//{
// succ = false,
// msg = $"请求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();
string res = string.Empty;
if (!string.IsNullOrWhiteSpace(res))
{
//var result = response.Content.ReadAsStringAsync().Result;
//if (string.IsNullOrWhiteSpace(result))
//{
// throw new Exception($"请求格式单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 = JsonConvert.DeserializeObject<PDFReadFileResultDto>(res);
}
}
catch (Exception ex)
{
//_logger.LogInformation("{name} 发送BC文件解析请求 url={url} 异常,原因={error}", nameof(TransmitFile),
//requestUrl, ex.Message);
throw new Exception($"{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();
var jsonBody = JsonConvert.SerializeObject(info);
var res = RequestHelper.Post(jsonBody, draftCompareUrl);
Logger.Log(NLog.LogLevel.Info, "批次={no} 对应请求报文完成 res={res}", info.Head.GID, res);
if (!string.IsNullOrWhiteSpace(res))
{
//var userResult = await res.Content.ReadAsStringAsync();
//_logger.LogInformation("对应请求报文 userResult={userResult}", userResult);
model = JsonConvert.DeserializeObject<TaskManageExcuteResultDto>(res);
}
}
catch (Exception ex)
{
//写日志
if (ex is HttpRequestException)
throw new Exception("查询失败");
}
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>
4 months ago
private async Task<DataResult<string>> SaveEDIFile(long boookId, string FilePath, string fileName, long tenantId, int fileSize,
string fileTypeCode = "bc", string fileTypeName = "Booking Confirmation")
{
4 months ago
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var newFile = new OpFile
{
//Id = SnowFlakeSingle.Instance.NextId(),
FileName = fileName,
FilePath = FilePath,
TypeCode = fileTypeCode,
TypeName = fileTypeName,
LinkId = boookId,
FileSize = fileSize,
FileType = Path.GetExtension(fileName),
Extension = Path.GetExtension(fileName),
OrgId = user.OrgId
};
await tenantDb.Insertable<OpFile>(newFile).ExecuteCommandAsync();
return DataResult<string>.Success(string.Empty);
}
#endregion
#region 获取Draft比对结果详情
/// <summary>
/// 获取Draft比对结果详情
/// </summary>
/// <param name="bookingId">订舱主键</param>
/// <returns>返回回执</returns>
public async Task<TaskManageExcuteResultDto> GetDraftCompareResultInfo([FromQuery] long bookingId)
{
string batchNo = GuidHelper.GetSnowflakeId();
TaskManageExcuteResultDto result = new TaskManageExcuteResultDto();
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
try
{
DateTime nowDate = DateTime.Now;
TaskDraftCompareMessageInfo msgModel = new TaskDraftCompareMessageInfo
{
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 TaskDraftMessageMainInfo
{
BusinessInfo = new BusinessInfo
{
BusiPKId = bookingId.ToString()
}
}
};
Logger.Log(NLog.LogLevel.Info, $"开始请求查询 msg={JsonConvert.SerializeObject
(msgModel)}");
result = await GetDraftCompareResult(msgModel);
Logger.Log(NLog.LogLevel.Info, "获取用户信息 userid={uid} userid={username} tendid={tid} OrgId={OrgId}", user.UserId,user.UserName,user.TenantId,user.OrgId);
var lastFileInfo = tenantDb.Queryable<OpFile>().Where(a => a.LinkId == bookingId &&
a.TypeCode.Equals(CONST_DRAFT_FILE_CODE))
.OrderByDescending(a => a.CreateTime).First();
if (lastFileInfo != null)
result.extra3 = lastFileInfo.Id;
if (result != null && result.extra != null && !string.IsNullOrWhiteSpace(result.extra.TaskCompareId))
{
var feedBack = tenantDb.Queryable<DraftCompareFeedBackRecord>().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比对结果
/// <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();
var jsonBody = JsonConvert.SerializeObject(info);
var res = RequestHelper.Post(jsonBody, draftResultUrl);
Logger.Log(NLog.LogLevel.Info, "批次={no} 对应请求报文完成 res={res}", info.Head.GID, res);
if (!string.IsNullOrWhiteSpace(res))
{
//var userResult = await res.Content.ReadAsStringAsync();
//_logger.LogInformation("对应请求报文 userResult={userResult}", userResult);
model = JsonConvert.DeserializeObject<TaskManageExcuteResultDto>(res);
}
}
catch (Exception ex)
{
//写日志
if (ex is HttpRequestException)
throw new Exception("查询失败");
}
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>
public async Task<TaskManageExcuteResultDto> ExcuteEmailAttachedSheetDraftCompareAsync(IFormFile file, IFormFile fileAttach, string jsonData)
{
string batchNo = GuidHelper.GetSnowflakeId();
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
TaskManageExcuteResultDto result = new TaskManageExcuteResultDto();
DateTime nowDate = DateTime.Now;
/*
1
2Draft
3
4
5
6
7
*/
try
{
var model = GetJsonMessageInfo(jsonData, batchNo);
TaskDraftCompareMessageInfo readFileMessageInfo = new TaskDraftCompareMessageInfo
{
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",
}
};
var fileRlt = await _sysFileService.SaveFileDirect(model.Head.GID, file.ToByteArray(), batchNo, file.FileName, "bcfiles");
var fileFullName = fileRlt.Data.Item1;
//附件暂存
string fileAttchedFullName = string.Empty;
if (fileAttach != null)
{
var fileAttachRlt = await _sysFileService.SaveFileDirect(model.Head.GID, fileAttach.ToByteArray(), batchNo, file.FileName, "bcfiles");
fileAttchedFullName = fileAttachRlt.Data.Item1;
}
//Draft文件解析
NameValueCollection par = new NameValueCollection();
par.Add("jsonMessage", JsonConvert.SerializeObject(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.Log(NLog.LogLevel.Info, "批次={no} 请求Draft文件解析完成,耗时:{timeDiff}ms. 结果{msg} 报文={message}", batchNo, timeDiff,
readResult.succ ? "成功" : "失败",
JsonConvert.SerializeObject(readResult));
if (!readResult.succ)
{
Logger.Log(NLog.LogLevel.Info, "批次={no} 请求Draft文件解析失败 原因={reason}", batchNo, readResult.msg);
throw new Exception($"请求Draft文件解析失败 原因={readResult.msg}");
}
//通过解析提单号匹配订舱的详情
var readModel = JsonConvert.DeserializeObject<CompareDraftDataInfo>(JsonConvert.SerializeObject(readResult.extra));
string billNo = string.Empty;
if (!string.IsNullOrWhiteSpace(readModel.MasterBlNo))
{
billNo = readModel.MasterBlNo;
}
if (string.IsNullOrWhiteSpace(billNo))
{
Logger.Log(NLog.LogLevel.Info, "批次={no} 请求Draft文件解析未获取到有效提单号", batchNo);
throw new Exception($"请求Draft文件解析未获取到有效提单号");
}
var bookingOrder = tenantDb.Queryable<SeaExport>().First(a => a.MBLNO.Equals(billNo));
if (bookingOrder == null)
{
Logger.Log(NLog.LogLevel.Info, "批次={no} 提单号{billNo}无法获取业务信息", batchNo, billNo);
throw new Exception($"提单号{billNo}无法获取业务信息");
}
Logger.Log(NLog.LogLevel.Info, "批次={no}获取订舱数据完成", batchNo);
TaskDraftCompareMessageInfo msgModel = new TaskDraftCompareMessageInfo
{
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 TaskDraftMessageMainInfo()
};
//请求格式单比对接口
var mainInfo = bookingOrder.Adapt<BusinessInfo>();
//var userInfo = _sysUserRepository.AsQueryable().First(a => a.Id == bookingOrder.CreatedUserId);
//这里需要对场站进行映射翻译
var mapYardList = _mappingYardService.GetAllList().GetAwaiter().GetResult().Data;
if (mapYardList.Count > 0)
mapYardList = mapYardList.Where(a => a.Module.Equals(CONST_MAPPING_YARD_MODULE, StringComparison.OrdinalIgnoreCase)).ToList();
if (mapYardList.Any(a => a.LinkId == bookingOrder.YardId))
{
mainInfo.YardCode = mapYardList.FirstOrDefault(a => a.LinkId == bookingOrder.YardId).MapCode;
}
var codePortList = _codePortService.GetAllList().GetAwaiter().GetResult().Data;
if (codePortList.Any(a => a.Id == bookingOrder.LoadPortId))
mainInfo.PortLoadId = codePortList.FirstOrDefault(a => a.Id == bookingOrder.LoadPortId).EdiCode;
if (codePortList.Any(a => a.Id == bookingOrder.DischargePortId))
mainInfo.PortDischargeId = codePortList.FirstOrDefault(a => a.Id == bookingOrder.DischargePortId).EdiCode;
if (codePortList.Any(a => a.Id == bookingOrder.DeliveryPlaceId))
mainInfo.PlaceDeliveryId = codePortList.FirstOrDefault(a => a.Id == bookingOrder.DeliveryPlaceId).EdiCode;
if (codePortList.Any(a => a.Id == bookingOrder.DestinationId))
mainInfo.DestinationId = codePortList.FirstOrDefault(a => a.Id == bookingOrder.DestinationId).EdiCode;
mainInfo.BusiPKId = bookingOrder.Id.ToString();
mainInfo.UserId = user.UserId;
mainInfo.UserName = user.UserName;
//mainInfo.UserEmail = UserManager.Email;
var contaList = tenantDb.Queryable<OpCtn>()
.Where(x => long.Parse(x.BSNO) == bookingOrder.Id)
.ToList();
Logger.Log(NLog.LogLevel.Info, "批次={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.Log(NLog.LogLevel.Info, "批次={no} 请求Draft比对完成,耗时:{timeDiff}ms. 结果{msg} 报文={message}", batchNo, timeDiffCompare,
compareResult.succ ? "成功" : "失败",
JsonConvert.SerializeObject(compareResult));
Logger.Log(NLog.LogLevel.Info, "批次={no} 对应请求报文完成 msg={msg}", batchNo, JsonConvert.SerializeObject(msgModel));
var entity = tenantDb.Queryable<SeaExport>()
.First(a => a.Id == bookingOrder.Id);
var oldEntity = entity.Adapt<SeaExport>();
entity.LstDraftCompareRlt = compareResult.extra2.Any(a => a.IsDiff) ? "DIFF" : "NO DIFF";
entity.LstDraftCompareDate = nowDate;
//更新订舱相关
await tenantDb.Updateable(entity).UpdateColumns(it => new
{
it.LstDraftCompareDate,
it.LstDraftCompareRlt
}).ExecuteCommandAsync();
// 添加日志
//await _bookingOrderService.SaveLog(entity, oldEntity, "核对格式单");
if (entity.LstDraftCompareRlt == "NO DIFF")
{
//推送状态 HDGSD-核对格式单
//await _bookingOrderService.SetGoodsStatusPush("HDGSD", bookingOrder.Id, true);
var pushModel = new EmbedServiceProjectStatusDto
{
businessId = bookingOrder.Id.ToString(),
SourceType = 1,
StatusCodes = new List<EmbedServiceProjectStatusDetailDto> {
new EmbedServiceProjectStatusDetailDto{
StatusCode = "HDGSD"
}
}
};
var saveStatusRlt = await _djyServiceStatusService.SaveServiceStatus(pushModel);
//写日志
Logger.Log(NLog.LogLevel.Info, "批次={no} 推送状态 HDGSD-核对格式单 id={id}", batchNo, bookingOrder.Id);
}
//如果确认文件读取成功
var bookFilePath = await _sysFileService.MoveFile(bookingOrder.Id.ToString(), fileFullName, batchNo);
//将格式单附件写入订舱的附件
await SaveEDIFile(bookingOrder.Id, bookFilePath.Data.Item2, new System.IO.FileInfo(fileFullName).Name, long.Parse(user.TenantId), bookFilePath.Data.Item4,
CONST_DRAFT_FILE_CODE, CONST_DRAFT_FILE_NAME);
if (!string.IsNullOrWhiteSpace(fileAttchedFullName))
{
var currBookFilePath = await _sysFileService.MoveFile(bookingOrder.Id.ToString(), fileAttchedFullName, batchNo);
//将格式单附件写入订舱的附件
await SaveEDIFile(bookingOrder.Id, currBookFilePath.Data.Item2, new System.IO.FileInfo(fileAttchedFullName).Name, long.Parse(user.TenantId), currBookFilePath.Data.Item4,
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="model">请求详情</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskDraftCompare/SaveDraftCompareManual")]
public async Task SaveDraftCompareManual(TaskDraftCompareFeedBackDto model)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
if (model.bookingId <= 0)
throw new Exception($"订舱ID不能为空");
var order = tenantDb.Queryable<SeaExport>().First(a => a.Id == model.bookingId);
if (order == null)
throw new Exception($"订舱详情获取失败,订舱信息不存在或已作废");
if (!model.isOCRError && !model.isEditError && !model.isAgentError)
{
throw new Exception($"至少选择一个原因");
}
Logger.Log(NLog.LogLevel.Info, "请求比对反馈model={msg}", JsonConvert.SerializeObject(model));
DateTime nowDate = DateTime.Now;
DraftCompareFeedBackRecord entity = new DraftCompareFeedBackRecord
{
BOOKING_ID = model.bookingId,
IS_AGENT_ERROR = model.isAgentError,
IS_OCR_ERROR = model.isOCRError,
IS_EDIT_ERROR = model.isEditError,
NOTES = model.notes,
COMPARE_TYPE = model.compareType,
COMPARE_TIME = model.compareTime,
TASK_COMPARE_ID = model.taskCompareId,
CreateBy = long.Parse(user.UserId),
CreateUserName = user.UserName,
CreateTime = nowDate,
UpdateTime = nowDate
};
//新增完记录
await tenantDb.Insertable<DraftCompareFeedBackRecord>(entity).ExecuteCommandAsync();
Logger.Log(NLog.LogLevel.Info, "请求比对反馈写入表完成id={id}", model.bookingId);
var oldOrder = tenantDb.Queryable<SeaExport>().First(a => a.Id == model.bookingId);
//更新订舱相关的格式单比对状态
if (model.compareType.Equals("DRAFT", StringComparison.OrdinalIgnoreCase))
{
Logger.Log(NLog.LogLevel.Info, "请求比对反馈选择修正 compareType={compare}id={id}", model.compareType, model.bookingId);
order.LstDraftCompareRlt = "NO DIFF";
order.UpdateTime = nowDate;
order.UpdateBy = long.Parse(user.UserId);
order.UpdateUserName = user.UserName;
await tenantDb.Updateable<SeaExport>(order).UpdateColumns(t => new
{
t.LstDraftCompareRlt,
t.UpdateBy,
t.UpdateUserName,
t.UpdateTime,
}).ExecuteCommandAsync();
Logger.Log(NLog.LogLevel.Info, "请求比对反馈更新订舱状态完成id={id}", model.bookingId);
// 保存日志
//await _bookingOrderService.SaveLog(order, oldOrder, "格式单比对反馈回写");
}
else if (model.compareType.Equals("SHIPORDER", StringComparison.OrdinalIgnoreCase))
{
Logger.Log(NLog.LogLevel.Info, "请求比对反馈选择修正 compareType={compare}id={id}", model.compareType, model.bookingId);
order.LstShipOrderCompareRlt = "NO_DIFF";
order.LstShipOrderCompareRltName = "正常";
order.UpdateTime = nowDate;
order.UpdateBy = long.Parse(user.UserId);
order.UpdateUserName = user.UserName;
await tenantDb.Updateable<SeaExport>(order).UpdateColumns(t => new
{
t.LstShipOrderCompareRlt,
t.LstShipOrderCompareRltName,
t.UpdateBy,
t.UpdateUserName,
t.UpdateTime,
}).ExecuteCommandAsync();
// 保存日志
//await _bookingOrderService.SaveLog(order, oldOrder, "格式单比对反馈回写");
Logger.Log(NLog.LogLevel.Info, "请求比对反馈更新订舱状态完成id={id}", model.bookingId);
////比对成功后触发下货纸比对状态
//var saveStatusRlt = await _bookingValueAddedService.SaveServiceStatus(new ModifyServiceProjectStatusDto
//{
// BookingId = model.bookingId,
// SourceType = TrackingSourceTypeEnum.AUTO,
// StatusCodes = new List<ModifyServiceProjectStatusDetailDto> {
// new ModifyServiceProjectStatusDetailDto { StatusCode = "XHZBDCHG" } }
//});
var pushModel = new EmbedServiceProjectStatusDto
{
businessId = model.bookingId.ToString(),
SourceType = 1,
StatusCodes = new List<EmbedServiceProjectStatusDetailDto> {
new EmbedServiceProjectStatusDetailDto{
StatusCode = "XHZBDCHG"
}
}
};
var saveStatusRlt = await _djyServiceStatusService.SaveServiceStatus(pushModel);
Logger.Log(NLog.LogLevel.Info, "异步推送下货纸比对状态完成,结果={rlt}", JsonConvert.SerializeObject(saveStatusRlt));
}
}
#endregion
}
}