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

530 lines
21 KiB
C#

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.Core;
using Myshipping.Core.Entity;
using Myshipping.Core.Service;
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;
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)
{
_cache = cache;
_logger = logger;
_bookingOrderRepository = bookingOrderRepository;
_bookingOrderContaRepository = bookingOrderContaRepository;
_bookingFileRepository = bookingFileRepository;
_sysUserRepository = sysUserRepository;
}
#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
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 = 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
});
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));
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).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);
entity.LstDraftCompareRlt = compareResult.extra2.Any(a => a.IsDiff) ? "DIFF" : "";
entity.LstDraftCompareDate = nowDate;
//更新订舱相关
await _bookingOrderRepository.AsUpdateable(entity).UpdateColumns(it => new
{
it.LstDraftCompareDate,
it.LstDraftCompareRlt
}).ExecuteCommandAsync();
//如果确认文件读取成功
var bookFilePath = await FileAttachHelper.MoveFile(bookingOrder.Id.ToString(), fileFullName, batchNo);
//将格式单附件写入订舱的附件
await SaveEDIFile(bookingOrder.Id, bookFilePath, new System.IO.FileInfo(fileFullName).Name, entity.TenantId.Value,
CONST_DRAFT_FILE_CODE, CONST_DRAFT_FILE_NAME);
result = compareResult;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"请求Draft比对异常,{ex.Message}";
}
return result;
}
#endregion
#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="contentType">请求类型</param>
/// <returns>返回回执</returns>
[NonAction]
private async Task<TaskManageExcuteCommonResultDto> ExcuteReadPDF(NameValueCollection nameValueCollection, dynamic fileInfo,
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.ContentDisposition = new ContentDispositionHeaderValue("form-data")
//{
// Name = fileInfo.file.ToString(),
// FileName = fileInfo.fileName.ToString(),
//};
Content.Headers.Add("Content-Type", contentType);
reduceAttach.Add(Content, fileInfo.file.ToString(), HttpUtility.UrlEncode(fileInfo.fileName.ToString()));
}
#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 请求格式单比对
/// <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
}
}