From b80d7855877f0607591a6a60d22a44906cec76da Mon Sep 17 00:00:00 2001 From: jianghaiqing Date: Wed, 17 May 2023 16:04:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9PIL=20EDI=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E5=A6=82=E6=9E=9C=E6=97=B6=E8=AE=A2=E8=88=B1?= =?UTF-8?q?=E4=B8=8D=E5=86=99=E5=95=86=E5=93=81=E7=B1=BB=E5=9E=8B=E5=90=8D?= =?UTF-8?q?=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BookingOrder/BookingOrderService.cs | 30 ++- .../BookingOrder/BookingValueAddedService.cs | 229 +++++++++++++++++- .../BookingOrder/IBookingValueAddedService.cs | 4 +- 3 files changed, 239 insertions(+), 24 deletions(-) diff --git a/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs b/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs index 093300b5..346f8536 100644 --- a/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs +++ b/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs @@ -4286,24 +4286,32 @@ namespace Myshipping.Application //primaryModel.GOODSNAME = ediExtModel.GoodsName; */ - if (ediRouteEnum == EDIRouteEnum.PIL && model.sendType.Equals("E", StringComparison.OrdinalIgnoreCase)) + if (ediRouteEnum == EDIRouteEnum.PIL) { - if (!string.IsNullOrWhiteSpace(order.GOODSCODE)) + if (model.sendType.Equals("E", StringComparison.OrdinalIgnoreCase)) { - var pGoods = _paraGoodsInfoRepository.AsQueryable().First(x => x.GOODS_CODE == order.GOODSCODE); - if (pGoods == null) + if (!string.IsNullOrWhiteSpace(order.GOODSCODE)) { - _logger.LogInformation("批次={no} 提取商品名称失败 GOODSCODE={code}", batchNo, order.GOODSCODE); + var pGoods = _paraGoodsInfoRepository.AsQueryable().First(x => x.GOODS_CODE == order.GOODSCODE); + if (pGoods == null) + { + _logger.LogInformation("批次={no} 提取商品名称失败 GOODSCODE={code}", batchNo, order.GOODSCODE); - throw Oops.Bah($"商品分类编码{order.GOODSCODE}对应商品名称未找到"); - } - else - { - primaryModel.GOODSNAME = pGoods.GOODS_NAME_EN; + throw Oops.Bah($"商品分类编码{order.GOODSCODE}对应商品名称未找到"); + } + else + { + primaryModel.GOODSNAME = pGoods.GOODS_NAME_EN; - _logger.LogInformation("批次={no} 提取商品名称失败 code={code} name={name}", batchNo, order.GOODSCODE, pGoods.GOODS_NAME_EN); + _logger.LogInformation("批次={no} 提取商品名称失败 code={code} name={name}", batchNo, order.GOODSCODE, pGoods.GOODS_NAME_EN); + } } } + else if (model.sendType.Equals("B", StringComparison.OrdinalIgnoreCase)) + { + //2023-05-17 PIL订舱时不提供GOODSNAME,这里默认赋空 + primaryModel.GOODSNAME = string.Empty; + } } primaryModel.cKHI = ediExtModel.CKHI; diff --git a/Myshipping.Application/Service/BookingOrder/BookingValueAddedService.cs b/Myshipping.Application/Service/BookingOrder/BookingValueAddedService.cs index 161b5b5e..e0a7f0ad 100644 --- a/Myshipping.Application/Service/BookingOrder/BookingValueAddedService.cs +++ b/Myshipping.Application/Service/BookingOrder/BookingValueAddedService.cs @@ -15,6 +15,7 @@ using Myshipping.Core.Service; using Org.BouncyCastle.Crypto; using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; @@ -43,7 +44,7 @@ namespace Myshipping.Application const string CONST_FORMAT_BC_URL = "{0}_bc_down_url"; const string CONST_FORMAT_DRAFT_URL = "{0}_draft_down_url"; - const string CONST_TSL_BC_WEB = "TslWeb"; + const string CONST_FORMAT_WEB = "{0}_Web"; public BookingValueAddedService(ISysCacheService cache, ILogger logger, SqlSugarRepository bookingOrderRepository, SqlSugarRepository bookingfile, @@ -60,7 +61,7 @@ namespace Myshipping.Application /// - /// 批量下载BC + /// 批量BC下载 /// /// 订舱主键数组 /// 返回回执 @@ -189,13 +190,13 @@ namespace Myshipping.Application } //获取个人对应的账户,这里GetAccountConfig逻辑优先取个人,个人没有配置取公司对应配置 - var userWebAccountConfig = _webAccountConfig.GetAccountConfig(CONST_TSL_BC_WEB, UserManager.UserId).GetAwaiter() + var userWebAccountConfig = _webAccountConfig.GetAccountConfig(CONST_FORMAT_WEB, UserManager.UserId).GetAwaiter() .GetResult(); _logger.LogInformation("批次={no} 获取获取网站的账户完成,result={Num}", batchNo, JSON.Serialize(userWebAccountConfig)); if (userWebAccountConfig == null) - throw Oops.Bah($"个人/公司网站【{CONST_TSL_BC_WEB}】获取失败,请维护个人/公司网站账户信息"); + throw Oops.Bah($"个人/公司网站【{CONST_FORMAT_WEB}】获取失败,请维护个人/公司网站账户信息"); BCOrDraftRequestDto requestDto = new BCOrDraftRequestDto { @@ -325,7 +326,7 @@ namespace Myshipping.Application } /// - /// 批量下载Draft + /// 批量Draft下载 /// /// 订舱主键数组 /// @@ -333,6 +334,9 @@ namespace Myshipping.Application public async Task DownloadDraft([FromBody]long[] bookingIds) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + List> taskList = new List>(); + + string batchNo = IDGen.NextID().ToString(); try { @@ -345,9 +349,50 @@ namespace Myshipping.Application 6、等待所有请求完成返回统计结果。 */ + var list = _bookingOrderRepository.AsQueryable() + .Where(a => bookingIds.Contains(a.Id)).ToList(); + + if (list.Count != bookingIds.Length) + throw Oops.Oh($"订舱信息获取失败,订舱信息不存在或已作废"); + + foreach (var bk in list) + { + taskList.Add(InnerDownloadBookingConfirm(bk, batchNo)); + } + + Task.WaitAll(taskList.ToArray()); + result.succ = true; - result.msg = "批量下载Draft成功"; - //result.ext = id; + 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) { @@ -358,13 +403,175 @@ namespace Myshipping.Application return result; } + #region 单票下载BC + /// + /// 单票下载BC + /// + /// 订舱详情 + /// 批次号 + /// 返回回执 + private async Task InnerDownloadDraft(BookingOrder bookingOrder, string batchNo) + { + TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + + result.bno = bookingOrder.MBLNO; + + try + { + /* + 1、根据船公司代码匹配船公司映射。 + 2、BC和DRAFT是分别2个请求地址。 + 3、生成请求报文。 + 4、请求相应的链接。 + 5、返回成功写入附件。 + */ + var bcOrDraftRouteCfg = _cache.GetAllMappingCarrier().GetAwaiter().GetResult() + .FirstOrDefault(t => t.Module.Equals(CONST_MAPPING_CARRIER_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("提单号={mbl} 船公司={ca} 未配置BC和DRAFT下载路由请联系管理员配置", bookingOrder.MBLNO, bookingOrder.CARRIERID); + } + + 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("提单号【{mbl}】根据订舱的船公司代码{ca} 提取BC下载URL失败,未取到配置key={key}", + bookingOrder.MBLNO, bookingOrder.CARRIERID, urlKey); + } + + string accountTypeCode = string.Empty; + + + //获取个人对应的账户,这里GetAccountConfig逻辑优先取个人,个人没有配置取公司对应配置 + var userWebAccountConfig = _webAccountConfig.GetAccountConfig(CONST_FORMAT_WEB, UserManager.UserId).GetAwaiter() + .GetResult(); + + _logger.LogInformation("批次={no} 获取获取网站的账户完成,result={Num}", batchNo, JSON.Serialize(userWebAccountConfig)); + + if (userWebAccountConfig == null) + throw Oops.Bah($"个人/公司网站【{CONST_FORMAT_WEB}】获取失败,请维护个人/公司网站账户信息"); + + 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.path; + + string fileTypeCode = "bc"; + string fileTypeName = "Booking Confirmation"; + + //读取文件配置 + var fileCfg = App.GetOptions(); + + string relativePath = $"{fileCfg.relativePath}\\bcfiles\\{bookingOrder.Id}"; + string filePath = $"{(!string.IsNullOrWhiteSpace(fileCfg.basePath) ? fileCfg.basePath : App.WebHostEnvironment.WebRootPath)}\\{relativePath}"; - #region 请求规则平台 + 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 + + #region 请求远端下载 /// - /// 请求规则平台 + /// 请求远端下载 /// - /// - /// + /// 请求URL + /// 请求详情 + /// 批次号 + /// 返回结果 [NonAction] private async Task> ExcuteBCDownload(string url, BCOrDraftRequestDto info, string batchNo) { diff --git a/Myshipping.Application/Service/BookingOrder/IBookingValueAddedService.cs b/Myshipping.Application/Service/BookingOrder/IBookingValueAddedService.cs index b317f9e3..acab88dd 100644 --- a/Myshipping.Application/Service/BookingOrder/IBookingValueAddedService.cs +++ b/Myshipping.Application/Service/BookingOrder/IBookingValueAddedService.cs @@ -12,7 +12,7 @@ namespace Myshipping.Application public interface IBookingValueAddedService { /// - /// 批量下载BC + /// 批量BC下载 /// /// 订舱主键数组 /// 返回回执 @@ -20,7 +20,7 @@ namespace Myshipping.Application /// - /// 批量下载Draft + /// 批量Draft下载 /// /// 订舱主键数组 /// 返回回执