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
{
///
/// 请求Draft比对
///
[ApiDescriptionSettings("Application", Name = "TaskDraftCompare", Order = 10)]
public class TaskDraftCompareService : ITaskDraftCompareService, IDynamicApiController, ITransient
{
private readonly ISysCacheService _cache;
private readonly ILogger _logger;
private readonly SqlSugarRepository _bookingOrderRepository;
private readonly SqlSugarRepository _bookingOrderContaRepository;
private readonly SqlSugarRepository _bookingFileRepository;
private readonly SqlSugarRepository _sysUserRepository;
private readonly IBookingOrderService _bookingOrderService;
private readonly SqlSugarRepository _draftCompareFeedBackRecordRepository;
private readonly IBookingValueAddedService _bookingValueAddedService;
const string CONST_DRAFT_FILE_CODE = "draft";
const string CONST_DRAFT_FILE_NAME = "格式单";
public TaskDraftCompareService(ISysCacheService cache, ILogger logger,
SqlSugarRepository bookingOrderRepository, SqlSugarRepository bookingOrderContaRepository,
SqlSugarRepository bookingFileRepository, SqlSugarRepository sysUserRepository, IBookingOrderService bookingOrderService,
SqlSugarRepository draftCompareFeedBackRecordRepository, IBookingValueAddedService bookingValueAddedService)
{
_cache = cache;
_logger = logger;
_bookingOrderRepository = bookingOrderRepository;
_bookingOrderContaRepository = bookingOrderContaRepository;
_bookingFileRepository = bookingFileRepository;
_sysUserRepository = sysUserRepository;
_bookingOrderService = bookingOrderService;
_draftCompareFeedBackRecordRepository = draftCompareFeedBackRecordRepository;
_bookingValueAddedService = bookingValueAddedService;
}
#region 执行邮件Draft比对
///
/// 执行邮件Draft比对
///
/// 请求文件
/// 邮件Draft比对请求报文
/// 返回回执
[AllowAnonymous, HttpPost("/TaskDraftCompare/ExcuteEmailDraftCompare"), ApiUser(ApiCode = "BCTaskManage")]
public async Task 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(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();
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>();
}
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();
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 反序列化请求参数报文
///
/// 反序列化请求参数报文
///
/// 请求参数报文
/// 批次号
/// 返回反序列化结果
private TaskEmailDraftCompareMessageInfo GetJsonMessageInfo(string jsonMessage, string batchNo)
{
try
{
return JSON.Deserialize(jsonMessage);
}
catch
{
_logger.LogInformation("批次号{0} jsonMessage请求参数转换失败", batchNo);
throw Oops.Oh($"jsonMessage请求参数转换失败");
}
}
#endregion
#region 解析格式单文件
///
/// 解析格式单文件
///
/// 请求参数
/// 文件
/// 附页文件
/// 请求类型
/// 返回回执
[NonAction]
private async Task 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(result);
}
}
catch (Exception ex)
{
_logger.LogInformation("请求Draft比对异常,原因:{error}", ex.Message);
throw Oops.Oh($"请求Draft比对异常,原因:{ex.Message}");
}
}
return model;
}
#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 请求格式单比对
///
/// 请求格式单比对
///
/// 请求报文
///
private async Task 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(userResult);
}
}
catch (Exception ex)
{
//写日志
if (ex is HttpRequestException)
throw Oops.Oh(10000002);
}
return model;
}
#endregion
#region 异步写入订舱附件表
///
/// 异步写入订舱附件表
///
/// 订舱ID
/// 文件路径
/// 文件名
/// 租户ID
/// 附件类型代码
/// 附件类型名称
///
[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比对结果详情
///
/// 获取Draft比对结果详情
///
/// 订舱主键
/// 返回回执
[HttpPost("/TaskDraftCompare/GetDraftCompareResultInfo")]
public async Task 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比对结果
///
/// 获取Draft比对结果
///
/// 请求报文
/// 返回回执
[NonAction]
private async Task 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(userResult);
}
}
catch (Exception ex)
{
//写日志
if (ex is HttpRequestException)
throw Oops.Oh(10000002);
}
return model;
}
#endregion
#region 执行邮件Draft比对(含有附件文件-针对TSL货描附件处理)
///
/// 执行邮件Draft比对(含有附件文件-针对TSL货描附件处理)
///
/// 请求文件
/// 请求附件文件
/// 邮件Draft比对请求报文
/// 返回回执
[AllowAnonymous, HttpPost("/TaskDraftCompare/ExcuteEmailAttachedSheetDraftCompare"), ApiUser(ApiCode = "BCTaskManage")]
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);
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(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();
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>();
}
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();
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 保存格式单比对反馈
///
/// 保存格式单比对反馈
///
/// 请求详情
/// 返回回执
[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,
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 {
new ModifyServiceProjectStatusDetailDto { StatusCode = "XHZBDCHG" } }
});
_logger.LogInformation("异步推送下货纸比对状态完成,结果={rlt}", JSON.Serialize(saveStatusRlt));
}
}
#endregion
}
}