using Furion; using Furion.Logging; using Furion.RemoteRequest.Extensions; using Myshipping.Application.Entity; using Myshipping.Application.Helper; using Myshipping.Core; using Myshipping.Core.Entity; using Myshipping.Core.Service; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Myshipping.Application.EDI { /// /// 中远API订舱 /// public static class ZhongYuanSoApiHelper { public async static Task> DoPost(long custOrderId) { var repCustOrder = App.GetService>(); var repOrder = App.GetService>(); var repCtn = App.GetService>(); var repCustomer = App.GetService>(); var repContact = App.GetService>(); var repTemplate = App.GetService>(); var cache = App.GetService(); var cacheService = App.GetService(); var custOrder = await repCustOrder.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == custOrderId); if (custOrder == null) { return new KeyValuePair(false, "客户订舱信息未找到"); } var sysConfigList = await cache.GetAllSysConfig(); var sCfgSpiderUrl = sysConfigList.FirstOrDefault(x => x.Code == "ZhongYuanApiSpiderUrl" && x.GroupCode == "DJY_CONST"); if (sCfgSpiderUrl == null) { return new KeyValuePair(false, "中远订舱API的爬虫URL地址未配置,请联系管理员"); } var sCfgUserKey = sysConfigList.FirstOrDefault(x => x.Code == "ZhongYuanApiSpiderKey" && x.GroupCode == "DJY_CONST"); var sCfgUserSecret = sysConfigList.FirstOrDefault(x => x.Code == "ZhongYuanApiSpiderSecret" && x.GroupCode == "DJY_CONST"); if (sCfgUserKey == null || sCfgUserSecret == null) { return new KeyValuePair(false, "中远订舱API的KEY和密钥未配置,请联系管理员"); } BookingSoTemplate template = null; DjyCustomerContact custContact = null; var postModel = new ZhongYuanSoApiModel(); postModel.webAccount = custOrder.BookingAccount; postModel.webPassword = custOrder.BookingPassword; //查找模板: //1.根据客户订舱信息中的BookingUserId和BookingTenantId,去客户信息中根据CustSysId查找客户(公司)及联系人(员工)信息 //2.根据找到的客户及联系人信息,查找中远订舱模板 if (custOrder.BookingUserId > 0 && custOrder.BookingTenantId > 0) { custContact = await repCustomer.AsQueryable().Filter(null, true) .InnerJoin((cust, contact) => cust.Id == contact.CustomerId) .Where((cust, contact) => cust.CustSysId == custOrder.BookingTenantId && contact.CustSysId == custOrder.BookingUserId) .Select((cust, contact) => contact) .SingleAsync(); if (custContact == null) { return new KeyValuePair(false, "未找到客户及联系人信息"); } //根据:用户+船司+船司账号+约号,找到启用的模板 template = await repTemplate.AsQueryable().Filter(null, true).FirstAsync(x => x.IsDeleted == false && x.CarrierId == custOrder.CARRIERID && x.UserId == custContact.Id && x.IsEnable); if (template == null) { return new KeyValuePair(false, "未找到订舱模板"); } } else { return new KeyValuePair(false, "未找到客户端公司和用户ID"); } var mappingCtn = await cache.GetAllMappingCtn(); var mappingFrt = await cache.GetAllMappingFrt(); var mappingPortLoad = await cache.GetAllMappingPortLoad(); var mappingPort = await cache.GetAllMappingPort(); postModel.userKey = sCfgUserKey.Value; postModel.userSecret = sCfgUserSecret.Value; postModel.uploadType = template.Category; //DRAFT, TEMPLATE, BOOKING分别对应:草稿, 模板, 订舱 postModel.saveName = template.TemplateName; //起运港 var mapPortLoad = mappingPortLoad.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == CarrierCodeConst.COSCO && x.Code == custOrder.PORTLOADCODE); if (mapPortLoad == null) { return new KeyValuePair(false, $"未找到起运港映射信息:{custOrder.PORTLOADCODE}"); } //目的地,2024-5-9,衣国豪需求,由目的港改为目的地 var mapDestination = mappingPort.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == CarrierCodeConst.COSCO && x.Code == custOrder.DESTINATIONCODE); if (mapDestination == null) { return new KeyValuePair(false, $"未找到目的地映射信息:{custOrder.DESTINATIONCODE}"); } //运输条款 var mappingService = await cacheService.GetAllMappingService(); var mappService = mappingService.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == CarrierCodeConst.COSCO && x.Code == custOrder.SERVICE); if (mappService == null) { return new KeyValuePair(false, $"未找到运输条款映射信息:{custOrder.SERVICE}"); } if (!Regex.IsMatch(mappService.MapCode, "^[A-Za-z]+-[A-Za-z]+$")) { return new KeyValuePair(false, $"映射配置不正确:{mappService.MapCode}"); } string[] arrService = null; if (mappService == null) { arrService = custOrder.SERVICE.Split('-'); } else { arrService = mappService.MapCode.Split('-'); } //var startDay = template.StartDay.HasValue ? template.StartDay.Value : 1; //var endWeek = template.EndWeek.HasValue ? template.EndWeek.Value : 2; // 路线数据 //postModel.routes = new ZhongYuanSoApiRoute() //{ // originCity = mapPortLoad.MapCode, // destinationCity = mapPort.MapCode, // polPortName = custOrder.PolPortName, // podPortName = custOrder.PodPortName, // vesselName = custOrder.VESSEL, // voyageNumber = custOrder.VOYNO, // serviceCode = custOrder.LANECODE, // //sailSchedulePriority = template.Priority.Split(',').ToList(), // outboundHaulage = mapServArr[0], // inboundHaulage = mapServArr[1], // searchConditionDate = custOrder.ETD.Value.AddDays(-2).ToString("yyyy-MM-dd"), // numberOfWeeks = 2, // etd = custOrder.ETD.Value.ToString("yyyy-MM-dd"), //}; #region 收发通及货代 //发货人 ZhongYuanSoApiPhone shipperPhone = null; //if (string.IsNullOrEmpty(template.ShipperName)) //{ shipperPhone = new ZhongYuanSoApiPhone() { countryCode = custOrder.ShipperPhoneCountryCode, areaCode = custOrder.ShipperPhoneCode, number = custOrder.ShipperPhone }; //} //else //{ // shipperPhone = new ZhongYuanSoApiPhone() // { // countryCode = template.ShipperPhoneCountryCode, // areaCode = template.ShipperPhoneCode, // number = template.ShipperPhone // }; //} shipperPhone.countryCode = shipperPhone.countryCode == null ? "" : shipperPhone.countryCode; shipperPhone.areaCode = shipperPhone.areaCode == null ? "" : shipperPhone.areaCode; shipperPhone.number = shipperPhone.number == null ? "" : shipperPhone.number; postModel.shipperInfo = new ZhongYuanSoApiSFT() { firstName = custOrder.ShipperFirstName, lastName = custOrder.ShipperLastName, country = custOrder.ShipperCountry, state = custOrder.ShipperProvince, city = custOrder.ShipperCity, partyName = custOrder.ShipperName, addressDes = custOrder.ShipperAddress, phone = shipperPhone, postalCode = custOrder.ShipperPostCode }; //收货人 ZhongYuanSoApiPhone consigneePhone = null; //if (string.IsNullOrEmpty(template.ConsigneeName)) //{ consigneePhone = new ZhongYuanSoApiPhone() { countryCode = custOrder.ConsigneePhoneCountryCode, areaCode = custOrder.ConsigneePhoneCode, number = custOrder.ConsigneePhone }; //} //else //{ // consigneePhone = new ZhongYuanSoApiPhone() // { // countryCode = template.ConsigneePhoneCountryCode, // areaCode = template.ConsigneePhoneCode, // number = template.ConsigneePhone // }; //} consigneePhone.countryCode = consigneePhone.countryCode == null ? "" : consigneePhone.countryCode; consigneePhone.areaCode = consigneePhone.areaCode == null ? "" : consigneePhone.areaCode; consigneePhone.number = consigneePhone.number == null ? "" : consigneePhone.number; postModel.consigneeInfo = new ZhongYuanSoApiSFT() { firstName = custOrder.ConsigneeFirstName, lastName = custOrder.ConsigneeLastName, country = custOrder.ConsigneeCountry, state = custOrder.ConsigneeProvince, city = custOrder.ConsigneeCity, partyName = custOrder.ConsigneeName, addressDes = custOrder.ConsigneeAddress, phone = consigneePhone, postalCode = custOrder.ConsigneePostCode }; //通知人 ZhongYuanSoApiPhone notifyPhone = null; //if (string.IsNullOrEmpty(template.NotifypartName)) //{ notifyPhone = new ZhongYuanSoApiPhone() { countryCode = custOrder.NotifypartPhoneCountryCode, areaCode = custOrder.NotifypartPhoneCode, number = custOrder.NotifypartPhone }; //} //else //{ // notifyPhone = new ZhongYuanSoApiPhone() // { // countryCode = template.NotifypartPhoneCountryCode, // areaCode = template.NotifypartPhoneCode, // number = template.NotifypartPhone // }; //} notifyPhone.countryCode = notifyPhone.countryCode == null ? "" : notifyPhone.countryCode; notifyPhone.areaCode = notifyPhone.areaCode == null ? "" : notifyPhone.areaCode; notifyPhone.number = notifyPhone.number == null ? "" : notifyPhone.number; postModel.notifyInfo = new ZhongYuanSoApiSFT() { firstName = custOrder.NotifypartFirstName, lastName = custOrder.NotifypartLastName, country = custOrder.NotifypartCountry, state = custOrder.NotifypartProvince, city = custOrder.NotifypartCity, partyName = custOrder.NotifypartName, addressDes = custOrder.NotifypartAddress, phone = notifyPhone, postalCode = custOrder.NotifypartPostCode }; //货代 ZhongYuanSoApiPhone forwarderPhone = null; //if (string.IsNullOrEmpty(template.BookingName)) //{ forwarderPhone = new ZhongYuanSoApiPhone() { countryCode = custOrder.BookingPhoneCountryCode, areaCode = custOrder.BookingPhoneCode, number = custOrder.BookingPhone }; //} //else //{ // forwarderPhone = new ZhongYuanSoApiPhone() // { // countryCode = template.BookingPhoneCountryCode, // areaCode = template.BookingPhoneCode, // number = template.BookingPhone // }; //} forwarderPhone.countryCode = forwarderPhone.countryCode == null ? "" : forwarderPhone.countryCode; forwarderPhone.areaCode = forwarderPhone.areaCode == null ? "" : forwarderPhone.areaCode; forwarderPhone.number = forwarderPhone.number == null ? "" : forwarderPhone.number; postModel.forwarderInfo = new ZhongYuanSoApiSFT() { firstName = custOrder.BookingFirstName, lastName = custOrder.BookingLastName, country = custOrder.BookingCountry, state = custOrder.BookingProvince, city = custOrder.BookingCity, partyName = custOrder.BookingName, addressDes = custOrder.BookingAddress, phone = forwarderPhone, postalCode = custOrder.BookingPostCode, }; #endregion postModel.cargoInfo = new ZhongYuanSoApiCargoInfo() { cargoName = CargoIdZhongyuan(custOrder.CARGOID), cargoDes = custOrder.DESCRIPTION, hsCode = custOrder.HSCODE, }; var ctns = await repCtn.AsQueryable().Filter(null, true).Where(x => x.BILLID == custOrder.Id).ToListAsync(); postModel.boxInfos = new List(); // 箱型转换:用于订舱参数“路线信息”里的箱型数据 var mapCtnCodeList = new List(); foreach (var ctn in ctns) { if (!ctn.CTNNUM.HasValue || !ctn.KGS.HasValue) { return new KeyValuePair(false, $"所有箱的箱量和毛重都不能为空"); } var mapCtn = mappingCtn.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == CarrierCodeConst.COSCO && x.Code == ctn.CTNCODE); if (mapCtn == null) { return new KeyValuePair(false, $"未找箱型映射信息:{ctn.CTNCODE}"); } mapCtnCodeList.Add(mapCtn.MapName); var apiBox = new ZhongYuanSoApiBoxInfo() { boxType = mapCtn.MapCode, boxNum = ctn.CTNNUM.Value, weight = ctn.KGS.Value.ToString(), weightUnit = "KGS" }; postModel.boxInfos.Add(apiBox); } var mapFrt = mappingFrt.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == CarrierCodeConst.COSCO && x.Code == custOrder.FRTCODE); if (mapFrt == null) { return new KeyValuePair(false, $"未找到付款方式映射信息:{custOrder.FRTCODE}"); } postModel.truckingContacts = new ZhongYuanSoApiTruckingContacts() { isDoorAdvised = true }; postModel.rateInfos = new ZhongYuanSoApiRateInfo() { paymentMethod = mapFrt.MapCode, serviceContractNum = custOrder.CONTRACTNO }; //大简云客户订舱接收BC邮箱 var djyBookMail = sysConfigList.FirstOrDefault(x => x.Code == "DjyCustomerBookReceiveBcMail"); var bcMail = ""; if (!string.IsNullOrEmpty(custOrder.OpMail)) //优先使用东胜上传的邮箱 { bcMail = custOrder.OpMail; } else if (!string.IsNullOrEmpty(custContact.Email)) { bcMail = custContact.Email; } //else //{ // bcMail = template.BcReceiveEmail; //} if (djyBookMail != null) { bcMail += ";" + djyBookMail.Value; } postModel.special = new ZhongYuanSoApiSpecial() { emailAddresses = bcMail, remarksForEntireBooking = custOrder.SOREMARK }; // 船期数据 if (string.IsNullOrEmpty(custOrder.ExtendData)) { return new KeyValuePair(false, $"船期数据信息不存在,请选择船期"); } var extData = JObject.Parse(custOrder.ExtendData); postModel.shipInfo = extData.GetJObjectValue("shipInfo"); // 路线数据(中远-新格式) postModel.routes = new { numberOfWeeks = 2, searchConditionDate = custOrder.ETD.Value.AddDays(-2).ToString("yyyy-MM-dd"), originName = mapPortLoad.MapName, destinationName = mapDestination.MapName, outboundHaulage = arrService[0], inboundHaulage = arrService[1], contractNo = custOrder.CONTRACTNO, cargoNature = custOrder.CARGOID switch { "S" => "General", "R" => "Reefer", "D" => "Dangerous", _ => "" }, containerTypeList = mapCtnCodeList }; var postModelJson = postModel.ToJsonString(); Log.Information($"发送API数据给爬虫({sCfgSpiderUrl.Value}):{postModelJson}"); var rtn = await sCfgSpiderUrl.Value.SetBody(postModelJson).PostAsStringAsync(); //var rtn = await "http://www.baidu323.com".SetBody(postModel).PostAsStringAsync(); Log.Information($"爬虫返回:{rtn}"); var jobjRtn = JObject.Parse(rtn); if (jobjRtn.GetIntValue("code") == 200) { var jdata = jobjRtn.GetJObjectValue("data"); if (jdata != null) { JObject extObj = null; if (!string.IsNullOrEmpty(custOrder.ExtendData)) { extObj = JObject.Parse(custOrder.ExtendData); } else { extObj = new JObject(); } var bookingNo = jdata.GetStringValue("bookingNo"); if (!string.IsNullOrEmpty(bookingNo)) { extObj["CustNO"] = bookingNo; custOrder.ExtendData = extObj.ToJsonString(); await repCustOrder.AsUpdateable(custOrder).UpdateColumns(x => new { x.ExtendData }).ExecuteCommandAsync(); Log.Information($"回写CC号:{bookingNo} {custOrder.Id} {custOrder.BOOKINGNO}"); } } return new KeyValuePair(true, "发送成功"); } else { return new KeyValuePair(false, jobjRtn.GetStringValue("msg")); } } /// /// 获取中远货物类型 /// /// /// private static string CargoIdZhongyuan(string cargoId) { if (cargoId is "S") { return "General"; } else if (cargoId is "R") { return "Reefer"; } else if (cargoId is "D") { return "Dangerous"; } return null; } } /// /// 中远API订舱传输对象 /// public class ZhongYuanSoApiModel { /// /// 用户key /// public string userKey { get; set; } /// /// 用户secret /// public string userSecret { get; set; } /// /// 网站账户 /// public string webAccount { get; set; } /// /// 网站密码 /// public string webPassword { get; set; } /// /// 上传类型 /// public string uploadType { get; set; } /// /// 在选择草稿及模板时, 保存时填写的名称 /// public string saveName { get; set; } /// /// 在选择草稿及模板时的描述 /// public string saveDes { get; set; } /// /// 路线信息 /// public object routes { get; set; } //public ZhongYuanSoApiRoute routes { get; set; } /// /// 发货人信息 /// public ZhongYuanSoApiSFT shipperInfo { get; set; } /// /// 收货人信息 /// public ZhongYuanSoApiSFT consigneeInfo { get; set; } /// /// 通知人信息 /// public ZhongYuanSoApiSFT notifyInfo { get; set; } /// /// 货代信息 /// public ZhongYuanSoApiSFT forwarderInfo { get; set; } /// /// 货物信息 /// public ZhongYuanSoApiCargoInfo cargoInfo { get; set; } /// /// 箱信息 /// public List boxInfos { get; set; } /// /// 拖运方式:到门卸货预约 /// public ZhongYuanSoApiTruckingContacts truckingContacts { get; set; } /// /// 费率相关信息 /// public ZhongYuanSoApiRateInfo rateInfos { get; set; } /// /// 特殊要求及备注 /// public ZhongYuanSoApiSpecial special { get; set; } /// /// 船期数据 /// public object shipInfo { get; set; } } /// /// 路线信息 /// public class ZhongYuanSoApiRoute { /// /// 出发城市 /// public string originCity { get; set; } /// /// 目的城市 /// public string destinationCity { get; set; } /// /// 起始港名 /// public string polPortName { get; set; } /// /// 目的港名 /// public string podPortName { get; set; } /// /// 船名 /// public string vesselName { get; set; } /// /// 航次 /// public string voyageNumber { get; set; } /// /// 航线代码 /// public string serviceCode { get; set; } ///// ///// 船期选择优先级 ///// //public List sailSchedulePriority { get; set; } /// /// 出发地运输条款 /// public string outboundHaulage { get; set; } /// /// 目的地运输条款 /// public string inboundHaulage { get; set; } /// /// 起运时间 /// public string searchConditionDate { get; set; } /// /// 时间范围,按周计算, 默认为2 /// public int numberOfWeeks { get; set; } = 2; /// /// etd /// public string etd { get; set; } } /// /// 收发通信息 /// public class ZhongYuanSoApiSFT { /// /// 名字 /// public string partyName { get; set; } /// /// 国家 /// public string country { get; set; } /// /// 省 /// public string state { get; set; } /// /// 城市名 /// public string city { get; set; } /// /// 区 /// public string county { get; set; } /// /// 详细地址 /// public string addressDes { get; set; } /// /// 邮编 /// public string postalCode { get; set; } /// /// 姓 /// public string firstName { get; set; } /// /// 名 /// public string lastName { get; set; } /// /// 电话 /// public ZhongYuanSoApiPhone phone { get; set; } } /// /// 收发通电话 /// public class ZhongYuanSoApiPhone { /// /// 国家代码 /// public string countryCode { get; set; } /// /// 区号 /// public string areaCode { get; set; } /// /// 电话号码 /// public string number { get; set; } } /// /// 货物信息 /// public class ZhongYuanSoApiCargoInfo { /// /// 货物类型 /// public string cargoName { get; set; } /// /// 货物描述 /// public string cargoDes { get; set; } /// /// HS代码 /// public string hsCode { get; set; } } /// /// 箱信息 /// public class ZhongYuanSoApiBoxInfo { /// /// 箱量 /// public int boxNum { get; set; } /// /// 箱型 /// public string boxType { get; set; } /// /// 毛重 /// public string weight { get; set; } /// /// 重量单位 /// public string weightUnit { get; set; } } /// /// 费率 /// public class ZhongYuanSoApiRateInfo { /// /// 付款方式 /// public string paymentMethod { get; set; } /// /// 服务合同号 /// public string serviceContractNum { get; set; } } /// /// 托运方式 /// public class ZhongYuanSoApiTruckingContacts { /// /// 是否进一步通知 /// public bool isDoorAdvised { get; set; } } /// /// 特殊要求及备注 /// public class ZhongYuanSoApiSpecial { /// /// 备注信息 /// public string remarksForEntireBooking { get; set; } /// /// 邮箱地址 /// public string emailAddresses { get; set; } } }