using Furion; using Furion.Logging; using Furion.RemoteRequest.Extensions; using Microsoft.Extensions.Logging; using Myshipping.Application.ConfigOption; using Myshipping.Application.Entity; using Myshipping.Application.Helper; using Myshipping.Core; using Myshipping.Core.Entity; using Myshipping.Core.Helper; using Myshipping.Core.Service; using Newtonsoft.Json.Linq; using NPOI.HSSF.UserModel; using SqlSugar; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Myshipping.Application.EDI { /// /// 下货纸辅助类 /// public static class XiahuozhiHelpler { private static readonly string EdiFilePath = "XHZ"; public static async Task> Send( long bookingId, string filerole) { var repUser = App.GetService>(); var repOrder = App.GetService>(); var repCtn = App.GetService>(); var repBookingFile = App.GetService>(); var repUserMail = App.GetService>(); var cacheService = App.GetService(); var order = repOrder.FirstOrDefault(o => o.Id == bookingId); if (order == null) { return new KeyValuePair(false, "订舱信息未找到"); } var ctns = repCtn.Where(c => c.BILLID == bookingId).ToList(); var dictData = await cacheService.GetAllDictData(); var yardCodeSetList = dictData.Where(x => x.TypeCode == "XiaHuoZhiYardCodeSet").ToList(); //所有支持下货纸的场站代码配置 var gljEdiCarrierSetList = dictData.Where(x => x.TypeCode == "XiaHuoZhiGLJEdiCarrierSet").ToList();//港联捷通过EDI发送下货纸船司配置 var gljExcelMailCarrierSetList = dictData.Where(x => x.TypeCode == "XiaHuoZhiGLJExcelMailCarrierSet").ToList();//港联捷通过邮件Excel下货纸船司配置 var yardArr = yardCodeSetList.Select(x => x.Value).ToArray(); if (!yardArr.Contains(order.YARDID)) { return new KeyValuePair(false, "不支持的场站"); } if (string.IsNullOrEmpty(order.MBLNO)) { return new KeyValuePair(false, "主提单号不能为空"); } if (string.IsNullOrEmpty(order.VESSEL)) { return new KeyValuePair(false, "船名不能为空"); } if (string.IsNullOrEmpty(order.VOYNO)) { return new KeyValuePair(false, "海关航次不能为空"); } //2023年7月12日,下货纸为冻柜,需填写温度和通风,危险品需填写等级和编号 if (order.CARGOID == "R" && (string.IsNullOrEmpty(order.TEMPSET) || string.IsNullOrEmpty(order.REEFERF))) { return new KeyValuePair(false, "冻柜的温度和通风必须填写"); } if (order.CARGOID == "D" && (string.IsNullOrEmpty(order.DUNNO) || string.IsNullOrEmpty(order.DCLASS))) { return new KeyValuePair(false, "危险品的等级和编号必须填写"); } var fileOpt = App.GetOptions(); if (string.IsNullOrEmpty(fileOpt.basePath)) { fileOpt.basePath = App.WebHostEnvironment.WebRootPath; } var yardCodeGLJ = yardCodeSetList.FirstOrDefault(x => x.Code == "YardGLJ"); if (yardCodeGLJ == null) { return new KeyValuePair(false, "港联捷场站代码未配置"); } var yardCodeGJF = yardCodeSetList.FirstOrDefault(x => x.Code == "YardGJF"); if (yardCodeGJF == null) { return new KeyValuePair(false, "港捷丰场站代码未配置"); } var yardCodeJieFeng = yardCodeSetList.FirstOrDefault(x => x.Code == "YardJieFeng"); if (yardCodeJieFeng == null) { return new KeyValuePair(false, "捷丰场站代码未配置"); } var yardCodeGLX = yardCodeSetList.FirstOrDefault(x => x.Code == "YardGLX"); if (yardCodeGLX == null) { return new KeyValuePair(false, "港联欣站代码未配置"); } var yardCodeZhongChuang = yardCodeSetList.FirstOrDefault(x => x.Code == "YardZhongChuang"); if (yardCodeZhongChuang == null) { return new KeyValuePair(false, "中创站代码未配置"); } #region 港联捷场站 if (order.YARDID == yardCodeGLJ.Value) { var ediPathAbs = Path.Combine(fileOpt.basePath, fileOpt.relativePath, EdiFilePath); if (!Directory.Exists(ediPathAbs)) { Directory.CreateDirectory(ediPathAbs); } //通过EDI发送下货纸的船司 if (gljEdiCarrierSetList.Select(x => x.Value).ToList().Contains(order.CARRIERID)) { //租户参数-港联捷下货纸代号 var paraXHZ = (await cacheService.GetAllTenantParam()).FirstOrDefault(p => p.TenantId == order.TenantId && p.ParaCode == "CODE_GLJ_XHZ"); if (paraXHZ == null || string.IsNullOrEmpty(paraXHZ.ItemCode)) { return new KeyValuePair(false, $"{order.TenantName} 港联捷场站 下货纸代号未找到或配置有误"); } var ediFileName = $"{paraXHZ.ItemCode}_{order.MBLNO}_{DateTime.Now.Ticks}.txt"; var ediFileRela = Path.Combine(fileOpt.relativePath, EdiFilePath, ediFileName); var ediFileAbs = Path.Combine(ediPathAbs, ediFileName); var ediSettints = await cacheService.GetAllEdiSetting(); var dicData = await cacheService.GetAllDictData(); //港联捷所有用户使用一个ftp用户名和密码发送报文,使用文件名中的下货纸代号进行区分 var paraServer = dicData.FirstOrDefault(x => x.TypeCode == "booking_ftp_setting_glj" && x.Code == "ftp_server"); var paraUser = dicData.FirstOrDefault(x => x.TypeCode == "booking_ftp_setting_glj" && x.Code == "username"); var paraPwd = dicData.FirstOrDefault(x => x.TypeCode == "booking_ftp_setting_glj" && x.Code == "pwd"); if (paraServer == null || paraUser == null || paraPwd == null) { return new KeyValuePair(false, $"港联捷下货纸FTP服务地址参数未配置"); } StringBuilder sbData = new StringBuilder(); sbData.AppendLine($"01:{order.VESSEL}:{order.VOYNO}"); //船名 航次 // 12:提单号:中转港:目的港:货代代码:船公司:HPL参考号:特殊说明 sbData.AppendLine($"12:{order.MBLNO}:{order.TRANSPORTID}:{order.PORTDISCHARGEID}:{paraXHZ.ItemCode}:{order.CARRIERID}:{(order.CARRIERID == "HLC" ? order.CUSTNO : "")}:{ExchangeStr(order.YARDREMARK)}"); //主提单 中转港代码 目的港代码 货代代码 船公司 HPL参考号 备注 //2021-8-17,报文中不能体现英文字符①【:】②【,】,以空格代替 /* * 表象:QDAC064651 客户毛重28600 EDI进来28  港联捷回复:是前面货名太长,后面内容截断了,每行不超过255字符就行 解决方案:每行不超过255,品名只取前100就行 */ var despStr = ExchangeStr(order.DESCRIPTION.Replace(":", " ").Replace(",", " ")).Replace("\r\n", " ").Replace("\n", " "); if (despStr.Length > 100) { despStr = despStr.Substring(0, 100); } //22:货名:件数:包装:重量:体积:危品标志:危品等级:危规号:副危品等级:副危规号:海污:温度:通风:湿度 sbData.AppendLine($"22:{despStr}:{order.PKGS}:{order.KINDPKGS}:{order.KGS}:{order.CBM}:{(order.CARGOID == "D" ? "Y" : "N")}:{order.DCLASS}:{order.DUNNO}::::{order.TEMPSET}:{order.REEFERF}:{order.HUMIDITY}");//货名 件数 包装代码 总重量 总体积 危品标志 危品等级 危规号 副危品等级 副危规号 温度 通风度 湿度 var ctnCodes = (await GetAllCodeCtn()).Select(x => new { x.Code, x.Size }).ToList(); var ctnEdiList = (await GetAllMappingCtn()).AsQueryable().Where(x => x.Module == "XHZ_GLJ").ToList(); foreach (var ctn in ctns) { var ctnFind = ctnCodes.FirstOrDefault(c => c.Code == ctn.CTNCODE); if (ctnFind == null) { return new KeyValuePair(false, $"未找到箱型 {ctn.CTNALL},请联系管理员"); } var ctnEdi = ctnEdiList.FirstOrDefault(cc => cc.Code == ctn.CTNCODE); if (ctnEdi == null) { return new KeyValuePair(false, $"箱型({ctn.CTNALL})不匹配(EDI类型:XHZ_GLJ),无法发送下货纸,请联系管理员"); } sbData.AppendLine($"13:{(order.ISCONTAINERSOC.HasValue && order.ISCONTAINERSOC.Value ? "SOC" : order.CARRIERID)}:{ctnFind.Size}:{ctnEdi.MapCode}:{ctn.CTNNUM}:{ExchangeStr(ctn.REMARK)}:N");//箱经营人代码 尺寸 箱型 箱数 备注 加重箱 } Log.Information($"生成下货纸报文:{sbData.ToString()}"); File.WriteAllText(ediFileAbs, sbData.ToString()); //挂载附件 var attFile = new BookingFile(); attFile.BookingId = order.Id; attFile.FileName = ediFileName; attFile.FilePath = ediFileRela; attFile.TypeCode = "xiahuozhi"; attFile.TypeName = "下货纸"; attFile.TenantName = order.TenantName; repBookingFile.Insert(attFile); //发送ftp SplitFtpServerAndPort(paraServer.Value, out string server, out int port); var ftpSpiderUrl = dicData.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "booking_edi_ftp_server").Value; NameValueCollection par = new NameValueCollection(); par.Add("host", server); par.Add("port", port.ToString()); par.Add("username", paraUser.Value); par.Add("pwd", paraPwd.Value); par.Add("path", "/"); Log.Information($"准备请求发送ftp:{ftpSpiderUrl} ,参数:{par.ToJsonString()},文件:{ediFileName}"); var res = FTPHelper.TransmitFtpFile(ftpSpiderUrl, par, new { file = "file", fileName = Path.GetFileName(ediFileName), fileBytes = Encoding.UTF8.GetBytes(sbData.ToString()) }); Log.Information($"发送ftp返回:{res}"); var jobjRetn = JObject.Parse(res); if (jobjRetn.GetStringValue("status") != "1") { return new KeyValuePair(false, $"ftp发送失败:{jobjRetn.GetStringValue("message")}"); } return new KeyValuePair(true, $"已发送"); } //通过邮件发送Excel的船司 else if (gljExcelMailCarrierSetList.Select(x => x.Value).ToList().Contains(order.CARRIERID)) { var ediFileName = $"{order.CARRIERID}_{order.VESSEL}_{order.VOYNO}_{DateTime.Now.Ticks}.xls"; var ediFileRela = Path.Combine(fileOpt.relativePath, EdiFilePath, ediFileName); var ediFileAbs = Path.Combine(ediPathAbs, ediFileName); var templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "XhzGljTemplate.xls"); if (!File.Exists(templateFile)) { return new KeyValuePair(false, $"模板EXCEL文件未找到,请联系管理员"); } if (string.IsNullOrEmpty(order.YARDCONTRACTEMAIL)) { return new KeyValuePair(false, $"场站联系人邮箱未填写"); } var userMail = repUserMail.FirstOrDefault(x => x.CreatedUserId == order.CreatedUserId); if (userMail == null || string.IsNullOrEmpty(userMail.SmtpServer) || userMail.SmtpPort == 0) { return new KeyValuePair(false, $"发件邮箱未配置"); } MemoryStream ms = new MemoryStream(File.ReadAllBytes(templateFile)); var workbook = new HSSFWorkbook(ms); var sheet = workbook.GetSheetAt(0); //第一行标题 var title = $"下货纸清单-{order.LANENAME} SERVICE"; sheet.GetRow(0).GetCell(0).SetCellValue(title); //船期B2 sheet.GetRow(1).GetCell(1).SetCellValue(order.ETD.HasValue ? order.ETD.Value.ToString("yyyy.MM.dd") : ""); //船名B3 sheet.GetRow(2).GetCell(1).SetCellValue(order.VESSEL); //航次F3 sheet.GetRow(2).GetCell(5).SetCellValue(order.VOYNO); //代理B4 sheet.GetRow(3).GetCell(1).SetCellValue(order.TenantName); //联系电话F4 var usr = repUser.AsQueryable().Filter(null, true).First(u => u.Id == order.CreatedUserId); if (!string.IsNullOrEmpty(usr.Tel)) { sheet.GetRow(3).GetCell(5).SetCellValue(usr.Tel); } else if (!string.IsNullOrEmpty(usr.Phone)) { sheet.GetRow(3).GetCell(5).SetCellValue(usr.Phone); } else { sheet.GetRow(3).GetCell(5).SetCellValue(""); } //订舱号B7 sheet.GetRow(6).GetCell(1).SetCellValue(order.CUSTNO); //目的港C7 sheet.GetRow(6).GetCell(2).SetCellValue(order.PORTDISCHARGE); //中转港D7 sheet.GetRow(6).GetCell(3).SetCellValue(order.TRANSPORTID); //货名E7 sheet.GetRow(6).GetCell(4).SetCellValue(order.DESCRIPTION); //件数F7 sheet.GetRow(6).GetCell(5).SetCellValue(order.PKGS.Value.ToString()); //重量G7 sheet.GetRow(6).GetCell(6).SetCellValue(Convert.ToDouble(order.KGS.Value).ToString()); //尺码H7 sheet.GetRow(6).GetCell(7).SetCellValue(Convert.ToDouble(order.CBM.Value).ToString()); //冻柜信息 温度C I7 if (order.CARGOID == "R") { sheet.GetRow(6).GetCell(8).SetCellValue(order.TEMPSET); } else { sheet.GetRow(6).GetCell(8).SetCellValue(""); } //冻柜信息 通风CBM/H J7 if (order.CARGOID == "R") { sheet.GetRow(6).GetCell(9).SetCellValue(order.REEFERF); } else { sheet.GetRow(6).GetCell(9).SetCellValue(""); } //冻柜信息 湿度% K7 if (order.CARGOID == "R") { sheet.GetRow(6).GetCell(10).SetCellValue(order.HUMIDITY); } else { sheet.GetRow(6).GetCell(10).SetCellValue(""); } //整理箱型箱量 var groupList = ctns.Where(x => x.CTNNUM > 0).GroupBy(c => c.CTNALL).Select(g => new { CTNALL = g.Key.Replace("'", ""), CTNNUM = g.Sum(gg => gg.CTNNUM) }); //箱量 20GP L7 var findCtn = groupList.FirstOrDefault(x => x.CTNALL == "20GP"); if (findCtn != null) { sheet.GetRow(6).GetCell(11).SetCellValue(findCtn.CTNNUM.Value.ToString()); } else { sheet.GetRow(6).GetCell(11).SetCellValue(""); } //箱量 40GP M7 findCtn = groupList.FirstOrDefault(x => x.CTNALL == "40GP"); if (findCtn != null) { sheet.GetRow(6).GetCell(12).SetCellValue(findCtn.CTNNUM.Value.ToString()); } else { sheet.GetRow(6).GetCell(12).SetCellValue(""); } //箱量 40HC N7 findCtn = groupList.FirstOrDefault(x => x.CTNALL == "40HC"); if (findCtn != null) { sheet.GetRow(6).GetCell(13).SetCellValue(findCtn.CTNNUM.Value.ToString()); } else { sheet.GetRow(6).GetCell(13).SetCellValue(""); } //箱量 20RF O7 findCtn = groupList.FirstOrDefault(x => x.CTNALL == "20RF"); if (findCtn != null) { sheet.GetRow(6).GetCell(14).SetCellValue(findCtn.CTNNUM.Value.ToString()); } else { sheet.GetRow(6).GetCell(14).SetCellValue(""); } //箱量 40RH P7 findCtn = groupList.FirstOrDefault(x => x.CTNALL == "40RH"); if (findCtn != null) { sheet.GetRow(6).GetCell(15).SetCellValue(findCtn.CTNNUM.Value.ToString()); } else { sheet.GetRow(6).GetCell(15).SetCellValue(""); } //备注 场站/特殊要求 Q7 sheet.GetRow(6).GetCell(16).SetCellValue(order.YARDREMARK); MemoryStream msResult = new MemoryStream(); workbook.Write(msResult); File.WriteAllBytes(ediFileAbs, msResult.GetBuffer()); //挂载附件 var attFile = new BookingFile(); attFile.BookingId = order.Id; attFile.FileName = ediFileName; attFile.FilePath = ediFileRela; attFile.TypeCode = "xiahuozhi"; attFile.TypeName = "下货纸"; attFile.TenantName = order.TenantName; repBookingFile.Insert(attFile); //发送邮件 var sendResult = await MailSendHelper.SendMail(userMail, title, "", order.YARDCONTRACTEMAIL, new KeyValuePair(ediFileName, msResult.GetBuffer())); if (!sendResult.Key) { return new KeyValuePair(false, sendResult.Value); } return new KeyValuePair(true, $"已发送"); } else { return new KeyValuePair(false, "该船司不支持发送港联捷下货纸"); } } #endregion #region 港捷丰场站 捷丰场站 NOTE:港捷丰场站和捷丰场站下货纸功能,根据东胜7同功能模块代码翻译而来 else if (order.YARDID == yardCodeGJF.Value || order.YARDID == yardCodeJieFeng.Value) { if (!order.PKGS.HasValue || order.PKGS.Value == 0) { return new KeyValuePair(false, $"件数不能为空"); } if (string.IsNullOrEmpty(order.KINDPKGS)) { return new KeyValuePair(false, $"件数包装不能为空"); } if (!order.KGS.HasValue || order.KGS.Value == 0) { return new KeyValuePair(false, $"重量不能为空"); } if (!order.CBM.HasValue || order.CBM.Value == 0) { return new KeyValuePair(false, $"尺码不能为空"); } var ediFileName = $"{order.VESSEL}_{order.VOYNO}_{order.MBLNO}_{DateTime.Now.Ticks}.txt"; var ediFileRela = Path.Combine(fileOpt.relativePath, EdiFilePath, ediFileName); var ediPathAbs = Path.Combine(fileOpt.basePath, fileOpt.relativePath, EdiFilePath); var ediFileAbs = Path.Combine(ediPathAbs, ediFileName); if (!Directory.Exists(ediPathAbs)) { Directory.CreateDirectory(ediPathAbs); } DjyEdiSetting ftpset = null; if (order.YARDID == yardCodeGJF.Value) { ftpset = (await cacheService.GetAllEdiSetting()).FirstOrDefault(f => f.EDICODE == "XHZ_GJF" && f.TenantId == order.TenantId); } else if (order.YARDID == yardCodeJieFeng.Value) { ftpset = (await cacheService.GetAllEdiSetting()).FirstOrDefault(f => f.EDICODE == "XHZ_JIEFENG" && f.TenantId == order.TenantId); } if (ftpset == null) { return new KeyValuePair(false, $"ftp设置未找到"); } var ediParaName = "XHZ_GJF"; if (order.YARDID == yardCodeJieFeng.Value) { ediParaName = "XHZ_JIEFENG"; } List listJoinStr = new List(); listJoinStr.Add("00:IFCSUM:BK:" + filerole + ":" + ftpset.SENDCODE + ":" + ftpset.RECEIVECODE + ":" + DateTime.Now.ToString("yyyyMMddHHmm") + ":2.1'"); //提单号 listJoinStr.Add("02:" + order.Id.ToString() + ":" + order.MBLNO.Trim() + ":" + order.SERVICE + ":" + ftpset.SENDNAME + ":" + ftpset.RECEIVECODE + "::::::::::" + order.CONTRACTNO + "::'"); //提单地址 var ISSUETYPE = ""; if (order.ISSUETYPE == "正本") { ISSUETYPE = "ORI"; } else { ISSUETYPE = "EXP"; } listJoinStr.Add("03:" + ISSUETYPE + ":" + order.ISSUEPLACEID + ":" + order.ISSUEPLACE + ":" + GetDateStr(order.ISSUEDATE, "yyyyMMdd") + ":" + GetBillNum2(order.NOBILL) + ":" + order.PORTLOADID + ":" + order.PREPARDAT + ":" + order.PAYABLEAT + "::'");//美国AMS标志、加拿大AMS标志 //船 listJoinStr.Add("11:" + GetVesselEDICode(order.VESSEL, ediParaName) + ":" + order.VESSEL + ":" + order.VOYNO + ":::" + GetCarrierEDICode(order.CARRIERID, ediParaName) + "::" + GetDateStr(order.ETD, "yyyyMMdd") + "::::::" + order.YARDCONTRACT + ":" + formatEdiStr("txt", order.YARDREMARK) + ":'"); //港口 (咨询韩工,代码不转换,直接传原始代码) //listJoinStr.Add("12:" + GetPortEDICode(commonData, order.PLACERECEIPTID, type) + ":" + order.PLACERECEIPT + ":" + GetPortEDICode(order.PORTLOADID, type) + ":" + order.PORTLOAD + ":" + GetPortEDICode(order.PORTDISCHARGEID, type) + ":" + order.PORTDISCHARGE + ":::" + GetPortEDICode(order.PLACEDELIVERYID, type) + ":" + order.PLACEDELIVERY + ":" + GetPortEDICode(order.DESTINATIONID, type) + ":" + order.DESTINATION + "'"); listJoinStr.Add("12:" + order.PLACERECEIPTID + ":" + order.PLACERECEIPT + ":" + order.PORTLOADID + ":" + order.PORTLOAD + ":" + order.PORTDISCHARGEID + ":" + order.PORTDISCHARGE + ":::" + order.PLACEDELIVERYID + ":" + order.PLACEDELIVERY + ":" + order.DESTINATIONID + ":" + order.DESTINATION + "'"); //付费方式 var frtstr = GetFrtEDICode(order.BLFRT); if (frtstr != "") { listJoinStr.Add("14:" + frtstr + ":" + order.BLFRT + "'"); listJoinStr.Add("15:::" + frtstr + ":::::::'"); } else { listJoinStr.Add("14:P:" + order.BLFRT + "'"); listJoinStr.Add("15:::P:::::::'"); } var Shipping = ""; List ShippingList = null; //2021年9月1日修改,17行取消,放到11行原FAX位置(于斐) ////EDI备注 //if (!string.IsNullOrWhiteSpace(order.YardRemark)) //{ // Shipping = formatEdiStr("txt", order.YardRemark); // ShippingList = formatlengthStr(Shipping, 70); // if (Shipping != "") // { // listJoinStr.Add("17:" + formatListStr(ShippingList, 5) + "'"); // } //} //发货人 Shipping = formatEdiStr("txt", order.SHIPPER); ShippingList = formatlengthStr(Shipping, 35); if (ShippingList.Count != 0 && Shipping.Length > 0) { listJoinStr.Add("18::" + formatListStr(ShippingList, 6) + "'"); } //收货人 Shipping = formatEdiStr("txt", order.CONSIGNEE); ShippingList = formatlengthStr(Shipping, 35); if (ShippingList.Count != 0 && Shipping.Length > 0) { listJoinStr.Add("19::" + formatListStr(ShippingList, 6) + "'"); } //通知人 Shipping = formatEdiStr("txt", order.NOTIFYPARTY); ShippingList = formatlengthStr(Shipping, 35); if (ShippingList.Count != 0 && Shipping.Length > 0) { listJoinStr.Add("20::" + formatListStr(ShippingList, 6) + "'"); } //货物标识 var cargoid = order.CARGOID; if (string.IsNullOrWhiteSpace(cargoid)) { cargoid = "S"; } listJoinStr.Add("41:1::" + cargoid + ":" + order.PKGS.ToString() + ":" + order.KINDPKGS + ":" + order.KINDPKGS + ":" + order.KGS.ToString() + ":" + order.CBM.ToString() + "::::::" + order.KGS.ToString() + ":::'");//bill.HSCODE if (cargoid == "R") { listJoinStr.Add("43:::::::::::" + order.REEFERF + ":C:" + order.TEMPSET + ":" + order.TEMPMIN + ":" + order.TEMPMAX + "::::::" + order.HUMIDITY + "::::'"); } else if (cargoid == "D") { listJoinStr.Add("43:" + order.DCLASS + ":" + order.DPAGE + ":" + order.DUNNO + ":" + order.DLABEL + "::::::::::::::::::::'"); } //唛头 Shipping = formatEdiStr("txt", order.MARKS); ShippingList = formatlengthStr(Shipping, 35); for (var i = 0; i < Math.Ceiling(Convert.ToDecimal(Convert.ToDecimal(ShippingList.Count) / Convert.ToDecimal(9))); i++) { var tempstr = "44:"; for (var z = 0; z < 9; z++) { if ((i * 9 + z) < ShippingList.Count) tempstr = tempstr + ShippingList[i * 9 + z]; if (z < 8) tempstr = tempstr + ":"; } if (tempstr != "44:") { listJoinStr.Add(tempstr + "'"); } } //货物描述 Shipping = formatEdiStr("txt", order.DESCRIPTION); ShippingList = formatlengthStr(Shipping, 70); var m = 1; var strtemp = ""; if (ShippingList.Count != 0 && Shipping.Length > 0) { for (var i = 0; i < ShippingList.Count; i++) { if (m <= 5) { if (m == 1) strtemp = "47:" + ShippingList[i] + ":"; else { if (m == 5) strtemp = strtemp + ShippingList[i]; else strtemp = strtemp + ShippingList[i] + ":"; } } else { m = 1; listJoinStr.Add(strtemp + "'"); strtemp = "47:" + ShippingList[i] + ":"; } m = m + 1; } } if (strtemp != "") { listJoinStr.Add(strtemp + "'"); } //集装箱 var groupList = ctns.Where(c => c.CTNNUM.HasValue).GroupBy(c => c.CTNCODE).Select(c => new { c.Key, CTNNUM = c.Sum(cc => cc.CTNNUM) }).ToList(); foreach (var g in groupList) { listJoinStr.Add("48:" + GetCtnEDICode(g.Key, ediParaName) + ":" + g.CTNNUM + $":F:::::{(order.ISCONTAINERSOC.HasValue && order.ISCONTAINERSOC.Value ? "Y" : "N")}'"); } foreach (var ctn in ctns) { if (ctn.CNTRNO != "") { listJoinStr.Add("51:" + ctn.CNTRNO + ":" + GetCtnEDICode(ctn.CTNCODE, ediParaName) + ":" + ctn.SEALNO + ":M:CA:F:" + ctn.PKGS.ToString() + ":" + ctn.KGS.ToString() + "::" + ctn.CBM + "'"); } } listJoinStr.Add("99:" + listJoinStr.Count + 1 + "'"); var strJoin = string.Join(Environment.NewLine, listJoinStr); Log.Information($"生成下货纸报文:{strJoin}"); File.WriteAllText(ediFileAbs, strJoin, Encoding.Default); //挂载附件 var attFile = new BookingFile(); attFile.BookingId = order.Id; attFile.FileName = ediFileName; attFile.FilePath = ediFileRela; attFile.TypeCode = "xiahuozhi"; attFile.TypeName = "下货纸"; attFile.TenantName = order.TenantName; await repBookingFile.InsertAsync(attFile); //发送ftp SplitFtpServerAndPort(ftpset.SERVERIP, out string server, out int port); var ftpSpiderUrl = (await cacheService.GetAllDictData()).FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "booking_edi_ftp_server").Value; NameValueCollection par = new NameValueCollection(); par.Add("host", server); par.Add("port", port.ToString()); par.Add("username", ftpset.USERNAME); par.Add("pwd", ftpset.PASSWORD); par.Add("path", ftpset.FOLDERNAME); par.Add("pasv", (!ftpset.FtpModeActive).ToString()); Log.Information($"准备请求发送ftp:{ftpSpiderUrl} ,参数:{par.ToJsonString()},文件:{ediFileName}"); var res = FTPHelper.TransmitFtpFile(ftpSpiderUrl, par, new { file = "file", fileName = Path.GetFileName(ediFileName), fileBytes = Encoding.UTF8.GetBytes(strJoin) }); Log.Information($"发送ftp返回:{res}"); var jobjRetn = JObject.Parse(res); if (jobjRetn.GetStringValue("status") != "1") { return new KeyValuePair(false, $"ftp发送失败:{jobjRetn.GetStringValue("message")}"); } return new KeyValuePair(true, $"完成"); } #endregion #region 港联欣场站 else if (order.YARDID == yardCodeGLX.Value || order.YARDID == yardCodeZhongChuang.Value) { //2022年6月15日增加:港联欣场站若配置了通过港联捷EDI发送,则使用港联捷报文格式 var tenantParam = await cacheService.GetAllTenantParam(); var pGlxEdi = tenantParam.FirstOrDefault(p => p.TenantId == order.TenantId && p.ParaCode == "XIAHUOZHI_GLX_SEND_TYPE"); if (order.YARDID == yardCodeGLX.Value && pGlxEdi != null && pGlxEdi.ItemCode == "EDI_GLX") { var glxCarrierList = dictData.Where(x => x.TypeCode == "XiaHuoZhiGLXCarrierConfig").Select(x => x.Value).ToList();//港联欣支持的船司 if (!glxCarrierList.Contains(order.CARRIERID)) { return new KeyValuePair(false, $"港联欣下货纸当前不支持此船公司"); } var ftpset = (await cacheService.GetAllEdiSetting()).FirstOrDefault(f => f.EDICODE == "XHZ_GLX" && f.TenantId == order.TenantId); if (ftpset == null) { return new KeyValuePair(false, $"港联欣下货纸ftp设置未找到"); } var paraXHZ = tenantParam.FirstOrDefault(p => p.TenantId == order.TenantId && p.ParaCode == "CODE_GLX_XHZ"); if (paraXHZ == null || string.IsNullOrEmpty(paraXHZ.ItemCode)) { return new KeyValuePair(false, $"下货纸代号未找到或配置有误"); } var ediFileName = $"{paraXHZ.ItemCode}_{order.MBLNO}_{DateTime.Now.Ticks}.txt"; var ediFileRela = Path.Combine(fileOpt.relativePath, EdiFilePath, ediFileName); var ediPathAbs = Path.Combine(fileOpt.basePath, fileOpt.relativePath, EdiFilePath); var ediFileAbs = Path.Combine(ediPathAbs, ediFileName); if (!Directory.Exists(ediPathAbs)) { Directory.CreateDirectory(ediPathAbs); } StringBuilder sbData = new StringBuilder(); sbData.AppendLine($"01:{order.VESSEL}:{order.VOYNO}"); //船名 航次 sbData.AppendLine($"12:{order.MBLNO}:{order.TRANSPORTID}:{order.PORTDISCHARGEID}:{paraXHZ.ItemCode}:{order.CARRIERID}::{order.PORTDISCHARGE}"); //主提单 中转港代码 目的港代码 货代代码 船公司 HPL参考号 备注 var despStr = ExchangeStr(order.DESCRIPTION.Replace(":", " ").Replace(",", " ")).Replace("\r\n", " ").Replace("\n", " "); if (despStr.Length > 100) { despStr = despStr.Substring(0, 100); } /** “22” 2 字符 货物信息开始 货名 20 字符 必填 件数 10 字符 必填 包装代码 6 字符 必填 总重量 11 字符 公斤 必填 总体积 6 字符 立方米 必填 危品标志 1 字符 Y/N 必填 危品等级 5 字符 危规号 5 字符 副危品等级 5 字符 副危规号 5 字符 温度 5 字符 不带单位,默认C 通风度 5 字符 不带单位,默认CBM/H 湿度 5 字符 不带单位,默认% 回车换行 2 ASC码 ASC码“0D”“0A” */ sbData.AppendLine($"22:{despStr}:{order.PKGS}:{order.KINDPKGS}:{order.KGS}:{order.CBM}:{(order.CARGOID == "D" ? "Y" : "N")}:{order.DCLASS}:{order.DUNNO}:::{order.TEMPSET}:{order.REEFERF}:{order.HUMIDITY}");//货名 件数 包装代码 总重量 总体积 危品标志 危品等级 危规号 副危品等级 副危规号 温度 通风度 湿度 var ctnCodes = (await GetAllCodeCtn()).Select(x => new { x.Code, x.Size }).ToList(); var ctnEdiList = (await GetAllMappingCtn()).AsQueryable().Where(x => x.Module == "XHZ_GLX").ToList(); foreach (var ctn in ctns) { var ctnFind = ctnCodes.FirstOrDefault(c => c.Code == ctn.CTNCODE); if (ctnFind == null) { return new KeyValuePair(false, $"未找到箱型 {ctn.CTNALL},请联系管理员"); } var ctnEdi = ctnEdiList.FirstOrDefault(cc => cc.Code == ctn.CTNCODE); if (ctnEdi == null) { return new KeyValuePair(false, $"箱型({ctn.CTNALL})不匹配(EDI类型:XHZ_GLX),无法发送下货纸,请联系管理员"); } sbData.AppendLine($"13:{(order.ISCONTAINERSOC.HasValue && order.ISCONTAINERSOC.Value ? "SOC" : order.CARRIERID)}:{ctnFind.Size}:{ctnEdi.MapCode}:{ctn.CTNNUM}:{ExchangeStr(ctn.REMARK)}:N");//箱经营人代码 尺寸 箱型 箱数 备注 加重箱 } Log.Information($"生成下货纸报文:{sbData.ToString()}"); File.WriteAllText(ediFileAbs, sbData.ToString()); //挂载附件 var attFile = new BookingFile(); attFile.BookingId = order.Id; attFile.FileName = ediFileName; attFile.FilePath = ediFileRela; attFile.TypeCode = "xiahuozhi"; attFile.TypeName = "下货纸"; attFile.TenantName = order.TenantName; repBookingFile.Insert(attFile); //发送ftp SplitFtpServerAndPort(ftpset.SERVERIP, out string server, out int port); var ftpSpiderUrl = (await cacheService.GetAllDictData()).FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "booking_edi_ftp_server").Value; NameValueCollection par = new NameValueCollection(); par.Add("host", server); par.Add("port", port.ToString()); par.Add("username", ftpset.USERNAME); par.Add("pwd", ftpset.PASSWORD); par.Add("path", ftpset.FOLDERNAME); par.Add("pasv", (!ftpset.FtpModeActive).ToString()); Log.Information($"准备请求发送ftp:{ftpSpiderUrl} ,参数:{par.ToJsonString()},文件:{ediFileName}"); var res = FTPHelper.TransmitFtpFile(ftpSpiderUrl, par, new { file = "file", fileName = Path.GetFileName(ediFileName), fileBytes = Encoding.UTF8.GetBytes(sbData.ToString()) }); Log.Information($"发送ftp返回:{res}"); var jobjRetn = JObject.Parse(res); if (jobjRetn.GetStringValue("status") != "1") { return new KeyValuePair(false, $"ftp发送失败:{jobjRetn.GetStringValue("message")}"); } } else //邮件方式 { if (string.IsNullOrEmpty(order.YARDCONTRACTEMAIL)) { return new KeyValuePair(false, $"场站联系人邮箱不能为空"); } var userMail = repUserMail.FirstOrDefault(x => x.CreatedUserId == order.CreatedUserId); if (userMail == null || string.IsNullOrEmpty(userMail.SmtpServer) || userMail.SmtpPort == 0) { return new KeyValuePair(false, $"发件邮箱未配置"); } var userbase = repUser.FirstOrDefault(u => u.Id == order.CreatedUserId); var title = $"下货纸:{order.MBLNO}/{order.CARRIER}/{order.VESSEL}/{order.VOYNO}/{order.TenantName}"; var bodyExt = string.Empty; if (order.CARGOID == "R") { bodyExt = $@"温度:{order.TEMPSET}{order.TEMPID}
通风:{order.REEFERF}
湿度:{order.HUMIDITY}
"; } else if (order.CARGOID == "D") { bodyExt = $@"危险品等级:{order.DCLASS}
危险品编号:{order.DUNNO}
危险品联系方式:{order.LINKMAN}
"; } var body = $@"提单号:{order.MBLNO}
船名航次:{order.VESSEL}/{order.VOYNO}
起运港:{order.PORTLOAD},{order.PORTLOADID}
目的港:{order.PORTDISCHARGE},{order.PORTDISCHARGEID}
目的地:{order.DESTINATION},{order.DESTINATIONID}
预计船期:{(order.ETD.HasValue ? order.ETD.Value.ToString("yyyy-MM-dd") : "")}
箱型箱量:{order.CNTRTOTAL}
件重尺:{order.PKGS} {order.KINDPKGS}/{order.KGS}KGS/{order.CBM}CBM
货物描述:{order.DESCRIPTION}
{bodyExt} 备注:{order.YARDREMARK}

订舱代理:{order.TenantName}
联系人:{order.CreatedUserName}
电话:{userbase.Tel} 手机:{userbase.Phone}
邮箱:{userbase.Email}
"; var sendResult = await MailSendHelper.SendMail(userMail, title, body, order.YARDCONTRACTEMAIL); if (!sendResult.Key) { return new KeyValuePair(false, sendResult.Value); } } return new KeyValuePair(true, "已发送"); } #endregion else { return new KeyValuePair(false, "不支持的场站"); } } //转义处理字符串中的特殊字符 private static string ExchangeStr(string str) { if (string.IsNullOrEmpty(str)) { return string.Empty; } return str.Replace("?", "??").Replace("'", "?'").Replace("+", "?+").Replace(":", "?:"); } //根据船名,获取船名edi代码(根据东胜7同功能模块代码翻译而成) public static string GetVesselEDICode(string vessel, string EDINAME) { string EDICODE = ""; vessel = vessel.Replace("'", "''"); var codeVesselEdi = GetAllMappingVessel().Result.FirstOrDefault(v => v.Name == vessel && v.Module == EDINAME); if (codeVesselEdi != null) { EDICODE = codeVesselEdi.MapName.Trim(); } if (string.IsNullOrEmpty(EDICODE)) { var codeVessel = GetAllCodeVessel().Result.FirstOrDefault(v => v.Name == vessel); if (codeVessel != null && !string.IsNullOrEmpty(codeVessel.EdiCode)) { EDICODE = codeVessel.EdiCode.Trim(); } else { EDICODE = vessel; } } return EDICODE; } //获取时间字符串 public static string GetDateStr(DateTime? dt, string dateformat) { var result = ""; if (!dt.HasValue) { result = ""; } else { result = dt.Value.ToString(dateformat); } return result; } //获取客户edi代码(根据东胜7同功能模块代码翻译而成) public static string GetCarrierEDICode(string carrierCode, string EDINAME) { string EDICODE = ""; var custEdi = GetAllMappingCarrier().Result.FirstOrDefault(c => c.Code == carrierCode && c.Module == EDINAME); if (custEdi != null) { EDICODE = custEdi.MapCode.Trim(); } if (string.IsNullOrEmpty(EDICODE)) { var infoclient = GetAllCodeCarrier().Result.FirstOrDefault(c => c.Code == carrierCode); if (infoclient != null) { EDICODE = infoclient.EdiCode.Trim(); } } return EDICODE; } //获取付费方式edi代码(根据东胜7同功能模块代码翻译而成) public static string GetFrtEDICode(string FRT) { string EDICODE = "P"; var ediFRT = GetAllMappingFrt().Result.FirstOrDefault(c => c.Code == FRT); if (ediFRT != null) { EDICODE = ediFRT.MapCode.Trim(); } return EDICODE; } //获取edi代码(根据东胜7同功能模块移植) public static string GetBillNum2(string str) { if (str == "ZERO") return "00"; if (str == "ONE") return "01"; if (str == "TWO") return "02"; if (str == "THREE") return "03"; if (str == "FOUR") return "04"; if (str == "FIVE") return "05"; if (str == "SIX") return "06"; if (str == "SERVEN") return "07"; if (str == "EIGHT") return "08"; if (str == "NINE") return "09"; if (str == "TEN") return "10"; else return ""; } /// /// 各种文本转义字符(东胜7移植) /// /// 文件类型(例如:txt、xml) /// 文本字符串 /// public static string formatEdiStr(string fileType, string str) { if (str == null) str = string.Empty; if (str == null) { return string.Empty; } if (fileType == "txt") { return str.Replace("?", "??").Replace(":", "?:").Replace("+", "?+").Replace("'", "?'"); } else if (fileType == "xml") { return str.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("\"", """).Replace("'", "'"); } else if (fileType == "sitc") { return str.Replace("?", "??").Replace(":", "?:").Replace("'", "?'"); } else { return str; } } //东胜7移植 public static List formatlengthStr(string str, int length, bool formatstr = false, bool nodelsp = false) { str = str.Replace("\r\n", "\\"); str = str.Replace("\n", "\\"); str = str.Replace("\r", " "); string[] StrList = str.Split('\\'); //List StrListtmp = new List(); //for (var i = StrList.Length - 1; i >=0; i--) //{ //} var strtemp = ""; var strnewline = ""; var strtempnewline = ""; char[] spstring = { ' ', ';', ',', '.', ':', '/', '(', ')', '?', '+', '-' }; List DestList = new List(); for (var i = 0; i <= StrList.Length - 1; i++) { if (StrList[i].Length <= length) { if (formatstr) DestList.Add(formatEdiStr("txt", StrList[i])); else DestList.Add(StrList[i]); } else { strtemp = StrList[i] + " "; strtempnewline = ""; strnewline = ""; for (var j = 0; j < strtemp.Length; j++) { strtempnewline = strtempnewline + strtemp[j]; if (strtemp[j] == ' ' || strtemp[j] == ':' || strtemp[j] == ',' || strtemp[j] == '.' || strtemp[j] == ':' || strtemp[j] == '/' || strtemp[j] == '?' || strtemp[j] == ')' || strtemp[j] == '}' || strtemp[j] == '+' || strtemp[j] == '-') { if ((strnewline.Length + strtempnewline.Length) <= length) strnewline = strnewline + strtempnewline; else { if (formatstr) DestList.Add(formatEdiStr("txt", strnewline)); else DestList.Add(strnewline); strnewline = strtempnewline; } strtempnewline = ""; } } if (nodelsp) { if (formatstr) DestList.Add(formatEdiStr("txt", strnewline)); else DestList.Add(strnewline); } else if (strnewline.Trim() != "") { if (formatstr) DestList.Add(formatEdiStr("txt", strnewline)); else DestList.Add(strnewline); } } } return DestList; } //东胜7移植 public static string formatListStr(List DestList, int lineCount) { var result = ""; for (var i = 0; i < lineCount; i++) { if (DestList.Count > i) { result = result + DestList[i]; } if (i != (lineCount - 1)) result = result + ":"; } return result; } /// /// 获取箱型的EDI代码 /// /// /// /// public static string GetCtnEDICode(string ctnCode, string EDINAME) { string EDICODE = ""; var ctnEdi = GetAllMappingCtn().Result.FirstOrDefault(c => c.Code == ctnCode && c.Module == EDINAME); if (ctnEdi != null) { EDICODE = ctnEdi.MapCode.Trim(); } if (string.IsNullOrEmpty(EDICODE)) { var infoclient = GetAllCodeCtn().Result.FirstOrDefault(c => c.Code == ctnCode); if (infoclient != null) { EDICODE = infoclient.EdiCode.Trim(); } } return EDICODE; } /// /// 获取所有箱型(使用缓存) /// /// private static async Task> GetAllCodeCtn() { var cacheService = App.GetService(); var ctnList = await cacheService.GetAllCodeCtn(); if (ctnList == null || ctnList.Count == 0) { var rep = App.GetService>(); ctnList = await rep.ToListAsync(); await cacheService.SetAllCodeCtn(ctnList); } return ctnList; } /// /// 获取所有船司(使用缓存) /// /// private static async Task> GetAllCodeCarrier() { var cacheService = App.GetService(); var list = await cacheService.GetAllCodeCarrier(); if (list == null || list.Count == 0) { var rep = App.GetService>(); list = await rep.ToListAsync(); await cacheService.SetAllCodeCarrier(list); } return list; } /// /// 获取所有箱型映射(使用缓存) /// /// private static async Task> GetAllMappingCtn() { var cacheService = App.GetService(); var ctnList = await cacheService.GetAllMappingCtn(); if (ctnList == null || ctnList.Count == 0) { var rep = App.GetService>(); ctnList = await rep.ToListAsync(); await cacheService.SetAllMappingCtn(ctnList); } return ctnList; } /// /// 获取所有船司映射(使用缓存) /// /// private static async Task> GetAllMappingCarrier() { var cacheService = App.GetService(); var list = await cacheService.GetAllMappingCarrier(); if (list == null || list.Count == 0) { var rep = App.GetService>(); list = await rep.ToListAsync(); await cacheService.SetAllMappingCarrier(list); } return list; } /// /// 获取所有付费方式(使用缓存) /// /// private static async Task> GetAllCodeFrt() { var cacheService = App.GetService(); var list = await cacheService.GetAllCodeFrt(); if (list == null || list.Count == 0) { var rep = App.GetService>(); list = await rep.ToListAsync(); await cacheService.SetAllCodeFrt(list); } return list; } /// /// 获取所有付费方式映射(使用缓存) /// /// private static async Task> GetAllMappingFrt() { var cacheService = App.GetService(); var list = await cacheService.GetAllMappingFrt(); if (list == null || list.Count == 0) { var rep = App.GetService>(); list = await rep.ToListAsync(); await cacheService.SetAllMappingFrt(list); } return list; } ///// ///// 获取所有公司参数(使用缓存) ///// ///// //private static async Task> GetAllTenantParam() //{ // var cacheService = App.GetService(); // var list = await cacheService.GetAllTenantParam(); // if (list == null || list.Count == 0) // { // var rep = App.GetService>(); // list = await sugerClient.Queryable().ToListAsync(); // await cacheService.SetAllTenantParam(list); // } // return list; //} /// /// 获取所有船名(使用缓存) /// /// private static async Task> GetAllCodeVessel() { var cacheService = App.GetService(); var list = await cacheService.GetAllCodeVessel(); if (list == null || list.Count == 0) { var rep = App.GetService>(); list = await rep.ToListAsync(); await cacheService.SetAllCodeVessel(list); } return list; } /// /// 获取所有船名映射(使用缓存) /// /// private static async Task> GetAllMappingVessel() { var cacheService = App.GetService(); var list = await cacheService.GetAllMappingVessel(); if (list == null || list.Count == 0) { var rep = App.GetService>(); list = await rep.ToListAsync(); await cacheService.SetAllMappingVessel(list); } return list; } /// /// 分割ftp服务器地址和端口 /// /// private static void SplitFtpServerAndPort(string str, out string server, out int port) { if (str.IndexOf(':') > -1) { var arr = str.Split(':'); server = arr[0]; port = Convert.ToInt32(arr[1]); } else { server = str; port = 21; } } } }