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.
BookingHeChuan/Myshipping.Application/Service/TaskManagePlat/TaskDraftCompareService.cs

985 lines
41 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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.Entity.DraftCompare;
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;
private readonly SqlSugarRepository<DraftCompareFeedBackRecord> _draftCompareFeedBackRecordRepository;
private readonly IBookingValueAddedService _bookingValueAddedService;
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,
SqlSugarRepository<DraftCompareFeedBackRecord> draftCompareFeedBackRecordRepository, IBookingValueAddedService bookingValueAddedService)
{
_cache = cache;
_logger = logger;
_bookingOrderRepository = bookingOrderRepository;
_bookingOrderContaRepository = bookingOrderContaRepository;
_bookingFileRepository = bookingFileRepository;
_sysUserRepository = sysUserRepository;
_bookingOrderService = bookingOrderService;
_draftCompareFeedBackRecordRepository = draftCompareFeedBackRecordRepository;
_bookingValueAddedService = bookingValueAddedService;
}
#region 执行邮件Draft比对
/// <summary>
/// 执行邮件Draft比对
/// </summary>
/// <param name="file">请求文件</param>
/// <param name="jsonData">邮件Draft比对请求报文</param>
/// <returns>返回回执</returns>
[AllowAnonymous, HttpPost("/TaskDraftCompare/ExcuteEmailDraftCompare"), ApiUser(ApiCode = "BCTaskManage")]
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 == UserManager.TENANT_ID);
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 = UserManager.UserId.ToString();
mainInfo.UserName = UserManager.Name;
mainInfo.UserEmail = UserManager.Email;
var contaList = _bookingOrderContaRepository.AsQueryable().Filter(null, true)
.Where(x => x.BILLID == bookingOrder.Id && !x.IsDeleted && x.TenantId == UserManager.TENANT_ID).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 == UserManager.TENANT_ID);
var oldEntity = entity.Adapt<BookingOrder>();
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();
// 保存日志
await _bookingOrderService.SaveLog(entity, oldEntity, "核对格式单");
if (entity.LstDraftCompareRlt == "NO DIFF")
{
//推送状态 HDGSD-核对格式单
await _bookingOrderService.SetGoodsStatusPush("HDGSD", bookingOrder.Id, true);
//写日志
_logger.LogInformation("批次={no} 推送状态 HDGSD-核对格式单 id={id}", batchNo, bookingOrder.Id);
}
//如果确认文件读取成功
var bookFilePath = await FileAttachHelper.MoveFile(bookingOrder.Id.ToString(), fileFullName, batchNo, false, "draftfiles");
//将格式单附件写入订舱的附件
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;
if (result != null && result.extra != null && !string.IsNullOrWhiteSpace(result.extra.TaskCompareId))
{
var feedBack = _draftCompareFeedBackRecordRepository.AsQueryable().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.CreatedTime.Value,
OperUser = feedBack.CreatedUserName,
Reason = (feedBack.IS_OCR_ERROR?"识别问题 ":"")+ (feedBack.IS_EDIT_ERROR ? "录入问题 " : "")+ (feedBack.IS_AGENT_ERROR ? "代理录入问题 " : "")
};
}
}
}
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"), ApiUser(ApiCode = "BCTaskManage")]
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 = UserManager.UserId.ToString();
mainInfo.UserName = UserManager.Name;
mainInfo.UserEmail = UserManager.Email;
var contaList = _bookingOrderContaRepository.AsQueryable().Filter(null, true)
.Where(x => x.BILLID == bookingOrder.Id && !x.IsDeleted && x.TenantId == UserManager.TENANT_ID)
.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 == UserManager.TENANT_ID);
var oldEntity = entity.Adapt<BookingOrder>();
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();
// 添加日志
await _bookingOrderService.SaveLog(entity, oldEntity, "核对格式单");
if (entity.LstDraftCompareRlt == "NO DIFF")
{
//推送状态 HDGSD-核对格式单
await _bookingOrderService.SetGoodsStatusPush("HDGSD", bookingOrder.Id, true);
//写日志
_logger.LogInformation("批次={no} 推送状态 HDGSD-核对格式单 id={id}", batchNo, bookingOrder.Id);
}
//如果确认文件读取成功
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
#region 保存格式单比对反馈
/// <summary>
/// 保存格式单比对反馈
/// </summary>
/// <param name="model">请求详情</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskDraftCompare/SaveDraftCompareManual")]
public async Task SaveDraftCompareManual(TaskDraftCompareFeedBackDto model)
{
if (model.bookingId <= 0)
throw Oops.Oh($"订舱ID不能为空");
var order = _bookingOrderRepository.AsQueryable().First(a => a.Id == model.bookingId);
if (order == null)
throw Oops.Oh($"订舱详情获取失败,订舱信息不存在或已作废");
if (!model.isOCRError && !model.isEditError && !model.isAgentError)
{
throw Oops.Oh($"至少选择一个原因");
}
_logger.LogInformation("请求比对反馈model={msg}", JSON.Serialize(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,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name,
CreatedTime = nowDate,
UpdatedTime = nowDate
};
//新增完记录
await _draftCompareFeedBackRecordRepository.InsertAsync(entity);
_logger.LogInformation("请求比对反馈写入表完成id={id}", model.bookingId);
var oldOrder = _bookingOrderRepository.AsQueryable().First(a => a.Id == model.bookingId);
//更新订舱相关的格式单比对状态
if (model.compareType.Equals("DRAFT", StringComparison.OrdinalIgnoreCase))
{
_logger.LogInformation("请求比对反馈选择修正 compareType={compare}id={id}", model.compareType, model.bookingId);
order.LstDraftCompareRlt = "NO DIFF";
order.UpdatedTime = nowDate;
order.UpdatedUserId = UserManager.UserId;
order.UpdatedUserName = UserManager.Name;
await _bookingOrderRepository.AsUpdateable(order).UpdateColumns(t => new
{
t.LstDraftCompareRlt,
t.UpdatedUserId,
t.UpdatedUserName,
t.UpdatedTime,
}).ExecuteCommandAsync();
_logger.LogInformation("请求比对反馈更新订舱状态完成id={id}", model.bookingId);
// 保存日志
await _bookingOrderService.SaveLog(order, oldOrder, "格式单比对反馈回写");
}
else if (model.compareType.Equals("SHIPORDER", StringComparison.OrdinalIgnoreCase))
{
_logger.LogInformation("请求比对反馈选择修正 compareType={compare}id={id}", model.compareType, model.bookingId);
order.LstShipOrderCompareRlt = "NO_DIFF";
order.LstShipOrderCompareRltName = "正常";
order.UpdatedTime = nowDate;
order.UpdatedUserId = UserManager.UserId;
order.UpdatedUserName = UserManager.Name;
await _bookingOrderRepository.AsUpdateable(order).UpdateColumns(t => new
{
t.LstShipOrderCompareRlt,
t.LstShipOrderCompareRltName,
t.UpdatedUserId,
t.UpdatedUserName,
t.UpdatedTime,
}).ExecuteCommandAsync();
// 保存日志
await _bookingOrderService.SaveLog(order, oldOrder, "格式单比对反馈回写");
_logger.LogInformation("请求比对反馈更新订舱状态完成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" } }
});
_logger.LogInformation("异步推送下货纸比对状态完成,结果={rlt}", JSON.Serialize(saveStatusRlt));
}
}
#endregion
}
}