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/BookingOrder/BookingValueAddedService.cs

924 lines
37 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.FriendlyException;
using Furion.JsonSerialization;
using Furion.RemoteRequest.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Myshipping.Application.ConfigOption;
using Myshipping.Application.Entity;
using Myshipping.Core;
using Myshipping.Core.Service;
using Org.BouncyCastle.Crypto;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Yitter.IdGenerator;
namespace Myshipping.Application
{
/// <summary>
/// 订舱增值类服务
/// </summary>
[ApiDescriptionSettings("Application", Name = "BookingValueAdded", Order = 9)]
public class BookingValueAddedService : IBookingValueAddedService, IDynamicApiController, ITransient
{
private readonly ISysCacheService _cache;
private readonly IDjyWebsiteAccountConfigService _webAccountConfig;
private readonly ILogger<BookingTruckService> _logger;
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
private readonly SqlSugarRepository<BookingFile> _bookingfile;
const string CONST_MAPPING_BC_MODULE_ROUTE = "BC_DOWN_RT";
const string CONST_MAPPING_DRAFT_MODULE_ROUTE = "DRAFT_DOWN_RT";
const string CONST_FORMAT_BC_URL = "{0}_bc_down_url";
const string CONST_FORMAT_DRAFT_URL = "{0}_draft_down_url";
const string CONST_FORMAT_WEB = "{0}_Web";
public BookingValueAddedService(ISysCacheService cache, ILogger<BookingTruckService> logger,
SqlSugarRepository<BookingOrder> bookingOrderRepository, SqlSugarRepository<BookingFile> bookingfile,
IDjyWebsiteAccountConfigService webAccountConfig)
{
_cache = cache;
_logger = logger;
_bookingOrderRepository = bookingOrderRepository;
_bookingfile = bookingfile;
_webAccountConfig = webAccountConfig;
}
/// <summary>
/// 批量BC下载
/// </summary>
/// <param name="bookingIds">订舱主键数组</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingValueAdded/DownloadBookingConfirm")]
public async Task<TaskManageOrderResultDto> DownloadBookingConfirm([FromBody]long[] bookingIds)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
List<Task<TaskManageOrderResultDto>> taskList = new List<Task<TaskManageOrderResultDto>>();
string batchNo = IDGen.NextID().ToString();
try
{
/*
1、订舱主键提取提单号、订舱编号优先去提单号其次订舱编号
2、根据不同的船公司调取单独的配置账户。
3、不同船公司对应不同的接口。
4、轮询异步调取接口等待返回接口。
5、成功后将文件链接存入附件表。
6、等待所有请求完成返回统计结果。
*/
var list = _bookingOrderRepository.AsQueryable()
.Where(a => bookingIds.Contains(a.Id)).ToList();
if (list.Count != bookingIds.Length)
throw Oops.Oh($"订舱信息获取失败,订舱信息不存在或已作废");
var noList = bookingIds.Select((a, idx) => new { no = idx + 1, id = a }).ToList();
foreach (var bk in list)
{
var sortNo = noList.FirstOrDefault(a=>a.id == bk.Id).no;
taskList.Add(Task.Run(() => InnerDownloadBookingConfirm(bk, batchNo, sortNo)));
}
Task.WaitAll(taskList.ToArray());
result.succ = true;
result.msg = "批量下载BC成功";
var downResultList = taskList.Select(x => x.Result).ToList();
if (downResultList.Any(x => !x.succ))
{
result.succ = false;
result.msg = "BC下载失败";
}
else
{
result.succ = true;
result.msg = downResultList.FirstOrDefault().msg;
}
result.ext = downResultList;
var succ = downResultList.Count(x => x.succ);
var fail = downResultList.Count(x => !x.succ);
if (succ > 0)
result.batchTotal = succ.ToString();
if(fail > 0)
{
if (succ > 0)
result.batchTotal = result.batchTotal+"/"+ fail.ToString();
result.batchTotal = "/" + fail.ToString();
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"批量BC下载异常原因{ex.Message}";
}
return result;
}
#region 单票下载BC
/// <summary>
/// 单票下载BC
/// </summary>
/// <param name="bookingOrder">订舱详情</param>
/// <param name="batchNo">批次号</param>
/// <param name="sortNo">请求顺序号</param>
/// <returns>返回回执</returns>
private async Task<TaskManageOrderResultDto> InnerDownloadBookingConfirm(BookingOrder bookingOrder,string batchNo, int sortNo)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
result.bno = bookingOrder.MBLNO;
try
{
/*
1、根据船公司代码匹配船公司映射。
2、BC和DRAFT是分别2个请求地址。
3、生成请求报文。
4、请求相应的链接。
5、返回成功写入附件。
*/
if (string.IsNullOrWhiteSpace(bookingOrder.MBLNO))
{
if (!string.IsNullOrWhiteSpace(bookingOrder.CUSTNO))
{
result.bno = $"订 {bookingOrder.CUSTNO}";
}
else
{
result.bno = $"NO.{sortNo}";
}
throw Oops.Bah($"主提单号不能为空");
}
var bcOrDraftRouteCfg = _cache.GetAllMappingCarrier().GetAwaiter().GetResult()
.FirstOrDefault(t => t.Module.Equals(CONST_MAPPING_BC_MODULE_ROUTE, StringComparison.OrdinalIgnoreCase)
&& t.Code.Equals(bookingOrder.CARRIERID?.Trim(), StringComparison.OrdinalIgnoreCase));
_logger.LogInformation("提单号【{mbl}】根据订舱的船公司代码{ca} 提取船公司映射完成,结果={rlt}",
bookingOrder.MBLNO, bookingOrder.CARRIERID, bcOrDraftRouteCfg);
if (bcOrDraftRouteCfg == null)
{
_logger.LogInformation("提单号{mbl} 根据订舱的船公司代码{ca} 提取船公司映射失败",
bookingOrder.MBLNO, bookingOrder.CARRIERID);
throw Oops.Bah($"船公司={bookingOrder.CARRIERID} 暂不支持BC下载");
}
string urlKey = string.Format(CONST_FORMAT_BC_URL, bcOrDraftRouteCfg.MapCode.ToLower());
var bcUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code.Equals(urlKey, StringComparison.OrdinalIgnoreCase))?.Value;
_logger.LogInformation("提单号{mbl} 根据订舱的船公司代码{ca} 提取Draft下载URL完成结果={rlt}",
bookingOrder.MBLNO, bookingOrder.CARRIERID, bcUrl);
if (string.IsNullOrWhiteSpace(bcUrl))
{
_logger.LogInformation("提单号{0} 根据订舱的船公司代码{1} 提取BC下载URL失败未取到配置key={key}",
bookingOrder.MBLNO, bookingOrder.CARRIERID, urlKey);
throw Oops.Bah($"船公司={bookingOrder.CARRIERID} 未配置请求地址{urlKey} 请联系管理员");
}
string webKey = string.Format(CONST_FORMAT_WEB, bcOrDraftRouteCfg.MapCode.ToLower());
//获取个人对应的账户,这里GetAccountConfig逻辑优先取个人个人没有配置取公司对应配置
var userWebAccountConfig = _webAccountConfig.GetAccountConfig(webKey, UserManager.UserId).GetAwaiter()
.GetResult();
_logger.LogInformation("批次={no} 获取获取网站的账户完成result={Num}", batchNo, JSON.Serialize(userWebAccountConfig));
if (userWebAccountConfig == null)
throw Oops.Oh($" 未配置个人或公司网站账户,网站{webKey}");
BCOrDraftRequestDto requestDto = new BCOrDraftRequestDto
{
user_key = App.Configuration["BCOrDraftUserKey"],
user_secret = App.Configuration["BCOrDraftUserSecret"],
web_user = userWebAccountConfig.Account?.Trim(),
web_psw = userWebAccountConfig.Password?.Trim(),
bno = bookingOrder.MBLNO,
is_parse = false
};
_logger.LogInformation("批次={no} json={json} 请求BC远端下载开始", batchNo, JSON.Serialize(requestDto));
DateTime bDate = DateTime.Now;
//开始请求BC
var rlt = await ExcuteBCDownload(bcUrl, requestDto, batchNo);
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
_logger.LogInformation("批次={no} result={result} 请求BC远端下载结束 耗时:{timeDiff}ms. ", batchNo,
JSON.Serialize(rlt),timeDiff);
if (rlt.code == 200)
{
_logger.LogInformation("批次={no} 下载文件成功,转存本地", batchNo);
string currFilePath = rlt.data.FirstOrDefault().path;
string fileTypeCode = "bc";
string fileTypeName = "Booking Confirmation";
//读取文件配置
var fileCfg = App.GetOptions<BookingAttachOptions>();
string relativePath = $"{fileCfg.relativePath}\\bcfiles\\{bookingOrder.Id}";
string filePath = $"{(!string.IsNullOrWhiteSpace(fileCfg.basePath) ? fileCfg.basePath : App.WebHostEnvironment.WebRootPath)}\\{relativePath}";
string fileFullName = $"{filePath}\\{new System.IO.FileInfo(currFilePath).Name}";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
relativePath = relativePath.Replace("\\", "/");
filePath = filePath.Replace("\\", "/");
fileFullName = fileFullName.Replace("\\", "/");
}
_logger.LogInformation("批次={no} 生成文件保存路径完成 路由={filePath} 服务器系统={system}", batchNo, filePath, RuntimeInformation.OSDescription);
//预先创建目录
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
var bcStream = await currFilePath.GetAsStreamAsync();
using (var fileStream = File.Create(fileFullName))
{
await bcStream.CopyToAsync(fileStream);
}
_logger.LogInformation("批次={no} 完成文件保存 filepath={path}", batchNo, fileFullName);
string bookFilePath = string.Empty;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
bookFilePath = System.Text.RegularExpressions.Regex.Match(fileFullName, relativePath.Replace("/", "\\/") + ".*").Value;
}
else
{
bookFilePath = System.Text.RegularExpressions.Regex.Match(fileFullName, relativePath.Replace("\\", "\\\\") + ".*").Value;
}
//这里先写入附件表
await SaveEDIFile(bookingOrder.Id, bookFilePath, new System.IO.FileInfo(currFilePath).Name,
fileTypeCode, fileTypeName);
result.succ = true;
result.msg = "BC下载成功";
}
else
{
result.succ = false;
result.msg = $"BC下载失败{rlt.msg}";
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"BC下载失败{ex.Message}";
}
return result;
}
#endregion
/// <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 _bookingfile.InsertAsync(bookFile);
}
/// <summary>
/// 批量Draft下载
/// </summary>
/// <param name="bookingIds">订舱主键数组</param>
/// <returns></returns>
[HttpPost("/BookingValueAdded/DownloadDraft")]
public async Task<TaskManageOrderResultDto> DownloadDraft([FromBody]long[] bookingIds)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
List<Task<TaskManageOrderResultDto>> taskList = new List<Task<TaskManageOrderResultDto>>();
string batchNo = IDGen.NextID().ToString();
try
{
/*
1、订舱主键提取提单号、订舱编号优先去提单号其次订舱编号
2、根据不同的船公司调取单独的配置账户。
3、不同船公司对应不同的接口。
4、轮询异步调取接口等待返回接口。
5、成功后将文件链接存入附件表。
6、等待所有请求完成返回统计结果。
*/
var list = _bookingOrderRepository.AsQueryable()
.Where(a => bookingIds.Contains(a.Id)).ToList();
if (list.Count != bookingIds.Length)
throw Oops.Oh($"订舱信息获取失败,订舱信息不存在或已作废");
var noList = bookingIds.Select((a, idx) => new { no = idx + 1, id = a }).ToList();
foreach (var bk in list)
{
var sortNo = noList.FirstOrDefault(a=>a.id == bk.Id).no;
taskList.Add(Task.Run(() => InnerDownloadDraft(bk, batchNo, sortNo)));
}
Task.WaitAll(taskList.ToArray());
result.succ = true;
result.msg = "下载Draft成功";
var downResultList = taskList.Select(x => x.Result).ToList();
if (downResultList.Any(x => !x.succ))
{
result.succ = false;
result.msg = "Draft下载失败";
}
else
{
result.succ = true;
result.msg = downResultList.FirstOrDefault().msg;
}
result.ext = downResultList;
var succ = downResultList.Count(x => x.succ);
var fail = downResultList.Count(x => !x.succ);
if (succ > 0)
result.batchTotal = succ.ToString();
if (fail > 0)
{
if (succ > 0)
result.batchTotal = result.batchTotal + "/" + fail.ToString();
result.batchTotal = "/" + fail.ToString();
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"下载Draft异常原因{ex.Message}";
}
return result;
}
#region 单票下载BC
/// <summary>
/// 单票下载BC
/// </summary>
/// <param name="bookingOrder">订舱详情</param>
/// <param name="batchNo">批次号</param>
/// <param name="sortNo">请求顺序号</param>
/// <returns>返回回执</returns>
private async Task<TaskManageOrderResultDto> InnerDownloadDraft(BookingOrder bookingOrder, string batchNo,int sortNo)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
result.bno = bookingOrder.MBLNO;
try
{
/*
1、根据船公司代码匹配船公司映射。
2、BC和DRAFT是分别2个请求地址。
3、生成请求报文。
4、请求相应的链接。
5、返回成功写入附件。
*/
if(bookingOrder.CARRIERID.Equals("ESL", StringComparison.OrdinalIgnoreCase))
{
if(string.IsNullOrWhiteSpace(bookingOrder.TMBLNO))
{
if (!string.IsNullOrWhiteSpace(bookingOrder.CUSTNO))
{
result.bno = $"订 {bookingOrder.CUSTNO}";
}
else if (string.IsNullOrWhiteSpace(bookingOrder.MBLNO))
{
result.bno = $"NO.{sortNo}";
}
throw Oops.Bah($"EP号不能为空");
}
}
else
{
if (string.IsNullOrWhiteSpace(bookingOrder.MBLNO))
{
if (!string.IsNullOrWhiteSpace(bookingOrder.CUSTNO))
{
result.bno = $"订 {bookingOrder.CUSTNO}";
}
else
{
result.bno = $"NO.{sortNo}";
}
throw Oops.Bah($"主提单号不能为空");
}
}
var bcOrDraftRouteCfg = _cache.GetAllMappingCarrier().GetAwaiter().GetResult()
.FirstOrDefault(t => t.Module.Equals(CONST_MAPPING_DRAFT_MODULE_ROUTE, StringComparison.OrdinalIgnoreCase)
&& t.Code.Equals(bookingOrder.CARRIERID?.Trim(), StringComparison.OrdinalIgnoreCase));
_logger.LogInformation("提单号{mbl} 根据订舱的船公司代码{ca} 提取船公司映射完成,结果={rlt}",
bookingOrder.MBLNO, bookingOrder.CARRIERID, bcOrDraftRouteCfg);
if (bcOrDraftRouteCfg == null)
{
_logger.LogInformation("提单号{0} 根据订舱的船公司代码{1} 提取船公司映射失败",
bookingOrder.MBLNO, bookingOrder.CARRIERID);
throw Oops.Bah($"船公司={bookingOrder.CARRIERID} 暂不支持Draft下载");
}
string urlKey = string.Format(CONST_FORMAT_DRAFT_URL, bcOrDraftRouteCfg.MapCode.ToLower());
var bcUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code.Equals(urlKey, StringComparison.OrdinalIgnoreCase))?.Value;
_logger.LogInformation("提单号{mbl} 根据订舱的船公司代码{ca} 提取DRAFT下载URL完成结果={rlt}",
bookingOrder.MBLNO, bookingOrder.CARRIERID, bcUrl);
if (string.IsNullOrWhiteSpace(bcUrl))
{
_logger.LogInformation("提单号{0} 根据订舱的船公司代码{1} 提取BC下载URL失败未取到配置key={key}",
bookingOrder.MBLNO, bookingOrder.CARRIERID, urlKey);
throw Oops.Bah($"船公司={bookingOrder.CARRIERID} 未配置请求地址{urlKey} 请联系管理员");
}
string webKey = string.Format(CONST_FORMAT_WEB, bcOrDraftRouteCfg.MapCode.ToLower());
//获取个人对应的账户,这里GetAccountConfig逻辑优先取个人个人没有配置取公司对应配置
var userWebAccountConfig = _webAccountConfig.GetAccountConfig(webKey, UserManager.UserId).GetAwaiter()
.GetResult();
_logger.LogInformation("批次={no} 获取获取网站的账户完成result={Num}", batchNo, JSON.Serialize(userWebAccountConfig));
if (userWebAccountConfig == null)
throw Oops.Oh($" 未配置个人或公司网站账户,网站{webKey}");
string downloadFilePathRlt = string.Empty;
string erroMsg = string.Empty;
if(bcOrDraftRouteCfg.MapCode.Trim().Equals("ESL", StringComparison.OrdinalIgnoreCase))
{
ESLDraftRequestDto requestDto = new ESLDraftRequestDto
{
u = userWebAccountConfig.Account?.Trim(),
p = userWebAccountConfig.Password?.Trim(),
ep_code = bookingOrder.TMBLNO?.Trim().ToUpper(),
};
_logger.LogInformation("批次={no} json={json} 请求Draft远端下载开始", batchNo, JSON.Serialize(requestDto));
DateTime bDate = DateTime.Now;
//开始请求BC
var rlt = await ExcuteESLDraftDownload(bcUrl, requestDto, batchNo);
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
_logger.LogInformation("批次={no} result={result} 请求Draft远端下载结束 耗时:{timeDiff}ms. ", batchNo,
JSON.Serialize(rlt), timeDiff);
if (rlt.status == 1)
{
downloadFilePathRlt = rlt.data.api_path;
}
else
{
erroMsg = rlt.message;
}
}
else
{
BCOrDraftRequestDto requestDto = new BCOrDraftRequestDto
{
user_key = App.Configuration["BCOrDraftUserKey"],
user_secret = App.Configuration["BCOrDraftUserSecret"],
web_user = userWebAccountConfig.Account?.Trim(),
web_psw = userWebAccountConfig.Password?.Trim(),
bno = bookingOrder.MBLNO,
is_parse = false
};
_logger.LogInformation("批次={no} json={json} 请求Draft远端下载开始", batchNo, JSON.Serialize(requestDto));
DateTime bDate = DateTime.Now;
//开始请求BC
var rlt = await ExcuteDraftDownload(bcUrl, requestDto, batchNo);
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
_logger.LogInformation("批次={no} result={result} 请求Draft远端下载结束 耗时:{timeDiff}ms. ", batchNo,
JSON.Serialize(rlt), timeDiff);
if (rlt.code == 200)
{
downloadFilePathRlt = rlt.data.FirstOrDefault().path;
}
else
{
erroMsg = rlt.msg;
}
}
if (!string.IsNullOrWhiteSpace(downloadFilePathRlt))
{
_logger.LogInformation("批次={no} 下载文件成功,转存本地", batchNo);
string currFilePath = downloadFilePathRlt;
string fileTypeCode = "draft";
string fileTypeName = "Draft";
//读取文件配置
var fileCfg = App.GetOptions<BookingAttachOptions>();
string relativePath = $"{fileCfg.relativePath}\\draftfiles\\{bookingOrder.Id}";
string filePath = $"{(!string.IsNullOrWhiteSpace(fileCfg.basePath) ? fileCfg.basePath : App.WebHostEnvironment.WebRootPath)}\\{relativePath}";
string fileFullName = $"{filePath}\\{new System.IO.FileInfo(currFilePath).Name}";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
relativePath = relativePath.Replace("\\", "/");
filePath = filePath.Replace("\\", "/");
fileFullName = fileFullName.Replace("\\", "/");
}
_logger.LogInformation("批次={no} 生成文件保存路径完成 路由={filePath} 服务器系统={system}", batchNo, filePath, RuntimeInformation.OSDescription);
//预先创建目录
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
var bcStream = await currFilePath.GetAsStreamAsync();
using (var fileStream = File.Create(fileFullName))
{
await bcStream.CopyToAsync(fileStream);
}
_logger.LogInformation("批次={no} 完成文件保存 filepath={path}", batchNo, fileFullName);
string bookFilePath = string.Empty;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
bookFilePath = System.Text.RegularExpressions.Regex.Match(fileFullName, relativePath.Replace("/", "\\/") + ".*").Value;
}
else
{
bookFilePath = System.Text.RegularExpressions.Regex.Match(fileFullName, relativePath.Replace("\\", "\\\\") + ".*").Value;
}
//这里先写入附件表
await SaveEDIFile(bookingOrder.Id, bookFilePath, new System.IO.FileInfo(currFilePath).Name,
fileTypeCode, fileTypeName);
result.succ = true;
result.msg = "Draft下载成功";
}
else
{
result.succ = false;
result.msg = $"Draft下载失败原因={erroMsg}";
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"Draft下载失败原因{ex.Message}";
}
return result;
}
#endregion
#region BC请求远端下载
/// <summary>
/// BC请求远端下载
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="info">请求详情</param>
/// <param name="batchNo">批次号</param>
/// <returns>返回结果</returns>
[NonAction]
private async Task<BCAPIBaseResult> ExcuteBCDownload(string url, BCOrDraftRequestDto info, string batchNo)
{
BCAPIBaseResult model = null;
/*
1、填充请求的类并生成JSON报文
2、POST请求接口并记录回执。
3、返回信息。
*/
try
{
_logger.LogInformation("批次={no} 对应请求报文 request={res}", batchNo, JSON.Serialize(info));
var res = await url.OnClientCreating(client => {
// client 为 HttpClient 对象
client.Timeout = TimeSpan.FromMinutes(15); // 设置超时时间 15分钟
}).SetHttpMethod(HttpMethod.Post)
.SetBody(JSON.Serialize(info), "application/json")
.SetContentEncoding(Encoding.UTF8)
.PostAsync();
_logger.LogInformation("批次={no} 对应请求报文完成 res={res}", batchNo, JSON.Serialize(res));
if (res.StatusCode == System.Net.HttpStatusCode.OK)
{
var userResult = await res.Content.ReadAsStringAsync();
System.Text.Json.JsonSerializerOptions jsonOptions = new JsonSerializerOptions();
jsonOptions.Converters.Add(new DateTimeJsonConverter("yyyy-MM-dd HH:mm:ss"));
model = JSON.Deserialize<BCAPIBaseResult>(userResult, jsonOptions);
}
}
catch (Exception ex)
{
//写日志
if (ex is HttpRequestException)
throw Oops.Oh(10000002);
}
return model;
}
#endregion
#region Draft请求远端下载
/// <summary>
/// Draft请求远端下载
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="info">请求详情</param>
/// <param name="batchNo">批次号</param>
/// <returns>返回结果</returns>
[NonAction]
private async Task<DraftAPIBaseResult> ExcuteDraftDownload(string url, BCOrDraftRequestDto info, string batchNo)
{
DraftAPIBaseResult model = null;
/*
1、填充请求的类并生成JSON报文
2、POST请求接口并记录回执。
3、返回信息。
*/
try
{
_logger.LogInformation("批次={no} 对应请求报文 request={res}", batchNo, JSON.Serialize(info));
var res = await url.OnClientCreating(client => {
// client 为 HttpClient 对象
client.Timeout = TimeSpan.FromMinutes(15); // 设置超时时间 15分钟
}).SetHttpMethod(HttpMethod.Post)
.SetBody(JSON.Serialize(info), "application/json")
.SetContentEncoding(Encoding.UTF8)
.PostAsync();
_logger.LogInformation("批次={no} 对应请求报文完成 res={res}", batchNo, JSON.Serialize(res));
if (res.StatusCode == System.Net.HttpStatusCode.OK)
{
var userResult = await res.Content.ReadAsStringAsync();
System.Text.Json.JsonSerializerOptions jsonOptions = new JsonSerializerOptions();
jsonOptions.Converters.Add(new DateTimeJsonConverter("yyyy-MM-dd HH:mm:ss"));
model = JSON.Deserialize<DraftAPIBaseResult>(userResult, jsonOptions);
}
}
catch (Exception ex)
{
//写日志
if (ex is HttpRequestException)
throw Oops.Oh(10000002);
}
return model;
}
#endregion
#region ESL Draft请求远端下载
/// <summary>
/// ESL Draft请求远端下载
/// 由于现有的ESL和TSL接口不一致需要提供单独的POST方法
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="info">请求详情</param>
/// <param name="batchNo">批次号</param>
/// <returns>返回结果</returns>
[NonAction]
private async Task<ESLDraftAPIBaseResult> ExcuteESLDraftDownload(string url, ESLDraftRequestDto info, string batchNo)
{
ESLDraftAPIBaseResult model = null;
/*
1、填充请求的类并生成JSON报文
2、POST请求接口并记录回执。
3、返回信息。
*/
try
{
_logger.LogInformation("批次={no} 对应请求报文 request={res}", batchNo, JSON.Serialize(info));
var res = await url.OnClientCreating(client => {
// client 为 HttpClient 对象
client.Timeout = TimeSpan.FromMinutes(15); // 设置超时时间 15分钟
}).SetHttpMethod(HttpMethod.Post)
.SetBody(JSON.Serialize(info), "application/json")
.SetContentEncoding(Encoding.UTF8)
.PostAsync();
_logger.LogInformation("批次={no} 对应请求报文完成 res={res}", batchNo, JSON.Serialize(res));
if (res.StatusCode == System.Net.HttpStatusCode.OK)
{
var userResult = await res.Content.ReadAsStringAsync();
model = JSON.Deserialize<ESLDraftAPIBaseResult>(userResult);
}
}
catch (Exception ex)
{
//写日志
if (ex is HttpRequestException)
throw Oops.Oh(10000002);
}
return model;
}
#endregion
/// <summary>
/// 到港时间更新
/// </summary>
/// <param name="bookingIds">订舱主键数组</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingValueAdded/CheckUpdateETA")]
public async Task<TaskManageOrderResultDto> CheckUpdateETA([FromBody] long[] bookingIds)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
/*
1、订舱主键提取提单号、订舱编号优先去提单号其次订舱编号
2、根据不同的船公司调取单独的配置账户。
3、不同船公司对应不同的接口。
4、轮询异步调取接口等待返回接口。
5、成功后将文件链接存入附件表。
6、等待所有请求完成返回统计结果。
*/
result.succ = true;
result.msg = "批量执行成功";
//result.ext = id;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"批量下载Draft异常原因{ex.Message}";
}
return result;
}
/// <summary>
/// 舱位分配查询
/// </summary>
/// <param name="bookingIds">订舱主键数组</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingValueAdded/CheckUpdateManifestNo")]
public async Task<TaskManageOrderResultDto> CheckUpdateManifestNo([FromBody] long[] bookingIds)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
/*
1、订舱主键提取提单号、订舱编号优先去提单号其次订舱编号
2、根据不同的船公司调取单独的配置账户。
3、不同船公司对应不同的接口。
4、轮询异步调取接口等待返回接口。
5、成功后将文件链接存入附件表。
6、等待所有请求完成返回统计结果。
*/
result.succ = true;
result.msg = "批量执行成功";
//result.ext = id;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"批量下载Draft异常原因{ex.Message}";
}
return result;
}
}
public class DateTimeJsonConverter : System.Text.Json.Serialization.JsonConverter<DateTime>
{
private readonly string _dateFormatString;
public DateTimeJsonConverter()
{
_dateFormatString = "yyyy-MM-dd HH:mm:ss";
}
public DateTimeJsonConverter(string dateFormatString)
{
_dateFormatString = dateFormatString;
}
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateTime.Parse(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToUniversalTime().ToString(_dateFormatString));
}
}
}