|
|
|
|
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 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();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
1、接收报文里的文件信息,优先写入本地文件暂存。
|
|
|
|
|
2、判断对应的订舱提单号。如果没有对应的订舱提单号,则写入任务表失败记录。
|
|
|
|
|
3、写入任务表。
|
|
|
|
|
4、异步请求格式单比对接口。
|
|
|
|
|
5、接收比对结果更新任务表。
|
|
|
|
|
6、更新订舱表,并更新状态。
|
|
|
|
|
*/
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var model = GetJsonMessageInfo(jsonData, batchNo);
|
|
|
|
|
|
|
|
|
|
var bookingOrder = _bookingOrderRepository.AsQueryable().Filter(null, true)
|
|
|
|
|
.First(a => a.MBLNO.Equals(model.Main.MBlNo));
|
|
|
|
|
|
|
|
|
|
if (model == null)
|
|
|
|
|
throw Oops.Oh($"提单号{model.Main.MBlNo}无法获取业务信息");
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("批次={no}获取订舱数据完成", batchNo);
|
|
|
|
|
|
|
|
|
|
//附件暂存
|
|
|
|
|
var fileFullName = await FileAttachHelper.TempSaveWebFile(bookingOrder.Id.ToString(), file, batchNo, CONST_DRAFT_FILE_CODE);
|
|
|
|
|
|
|
|
|
|
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",
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//请求格式单比对接口
|
|
|
|
|
var mainInfo = bookingOrder.Adapt<TaskDraftMessageMainInfo>();
|
|
|
|
|
|
|
|
|
|
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 = await _bookingOrderContaRepository.AsQueryable().Filter(null,true)
|
|
|
|
|
.Where(x => x.BILLID == bookingOrder.Id).ToListAsync();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("批次={no} 提取箱完成 数量={total}", batchNo, contaList.Count);
|
|
|
|
|
|
|
|
|
|
if (contaList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
mainInfo.ContaList = contaList.Adapt<List<TaskDraftMessageCtnInfo>>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
msgModel.Main = mainInfo;
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("批次={no} 对应请求报文完成 msg={msg}", batchNo, JSON.Serialize(msgModel));
|
|
|
|
|
|
|
|
|
|
NameValueCollection par = new NameValueCollection();
|
|
|
|
|
par.Add("jsonMessage", JSON.Serialize(msgModel));
|
|
|
|
|
|
|
|
|
|
byte[] bytes = file.ToByteArray();
|
|
|
|
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
var compareResult = await ExcuteCompare(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} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, compareResult.succ ? "成功" : "失败");
|
|
|
|
|
|
|
|
|
|
//如果确认文件读取成功
|
|
|
|
|
var bookFilePath = await FileAttachHelper.MoveFile(bookingOrder.Id.ToString(), fileFullName, batchNo);
|
|
|
|
|
|
|
|
|
|
//new System.IO.FileInfo(bookFilePath).Name
|
|
|
|
|
//将格式单附件写入订舱的附件
|
|
|
|
|
await SaveEDIFile(bookingOrder.Id, bookFilePath, new System.IO.FileInfo(fileFullName).Name, CONST_DRAFT_FILE_CODE, CONST_DRAFT_FILE_NAME);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
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<TaskManageExcuteResultDto> ExcuteCompare(NameValueCollection nameValueCollection, dynamic fileInfo,
|
|
|
|
|
string contentType = "application/json")
|
|
|
|
|
{
|
|
|
|
|
TaskManageExcuteResultDto 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["DraftCompareUrl"], reduceAttach).Result;
|
|
|
|
|
result = response.Content.ReadAsStringAsync().Result;
|
|
|
|
|
|
|
|
|
|
model = JSON.Deserialize<TaskManageExcuteResultDto>(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("请求Draft比对异常,原因:{error}", ex.Message);
|
|
|
|
|
|
|
|
|
|
throw Oops.Oh($"请求Draft比对异常,原因:{ex.Message}");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return model;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 异步写入订舱附件表
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 异步写入订舱附件表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="boookId">订舱ID</param>
|
|
|
|
|
/// <param name="FilePath">文件路径</param>
|
|
|
|
|
/// <param name="fileName">文件名</param>
|
|
|
|
|
/// <param name="fileTypeCode">附件类型代码</param>
|
|
|
|
|
/// <param name="fileTypeName">附件类型名称</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[NonAction]
|
|
|
|
|
private async Task SaveEDIFile(long boookId, string FilePath, string fileName, 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,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
BusiPKId = bookingId.ToString()
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
model = JSON.Deserialize<TaskManageExcuteResultDto>(userResult);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
//写日志
|
|
|
|
|
if (ex is HttpRequestException)
|
|
|
|
|
throw Oops.Oh(10000002);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return model;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|