diff --git a/Myshipping.Application/Entity/TaskManagePlat/TaskBaseInfo.cs b/Myshipping.Application/Entity/TaskManagePlat/TaskBaseInfo.cs index 8f3c36d3..3b594587 100644 --- a/Myshipping.Application/Entity/TaskManagePlat/TaskBaseInfo.cs +++ b/Myshipping.Application/Entity/TaskManagePlat/TaskBaseInfo.cs @@ -136,5 +136,30 @@ namespace Myshipping.Application.Entity /// 签单方式名称(来自订舱) /// public string ISSUE_TYPE_NAME { get; set; } + + /// + /// 任务请求人ID + /// + public long TASK_REQ_USERID { get; set; } + + /// + /// 任务请求人名称 + /// + public string TASK_REQ_USERNAME { get; set; } + + /// + /// 箱型箱量 + /// + public string CONTA_INFO { get; set; } + + /// + /// 船名航次 + /// + public string VESSEL_VOYNO { get; set; } + + /// + /// 场站 + /// + public string YARD_NAME { get; set; } } } diff --git a/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs b/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs index cf26d24f..093300b5 100644 --- a/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs +++ b/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs @@ -345,7 +345,7 @@ namespace Myshipping.Application .WhereIF(!string.IsNullOrWhiteSpace(input.FREIGHTPAYER), u => u.FREIGHTPAYER.Contains(input.FREIGHTPAYER)) .WhereIF(!string.IsNullOrWhiteSpace(input.DZRemark), u => u.DZRemark.Contains(input.DZRemark)) .WhereIF(!string.IsNullOrWhiteSpace(input.CZRemark), u => u.CZRemark.Contains(input.CZRemark)) - .WhereIF(!string.IsNullOrWhiteSpace(input.ZhanCangFlag), u => u.ZhanCangFlag==input.ZhanCangFlag) + .WhereIF(!string.IsNullOrWhiteSpace(input.ZhanCangFlag), u => u.ZhanCangFlag == input.ZhanCangFlag) .WhereIF(userlist != null && userlist.Count() > 0, u => userlist.Contains((long)u.CreatedUserId) || UserManager.UserId.ToString() == u.ROUTEID || UserManager.Name.ToString() == u.ROUTE || UserManager.UserId.ToString() == u.SALEID || UserManager.Name.ToString() == u.SALE || UserManager.UserId.ToString() == u.OPID || UserManager.Name.ToString() == u.OP || UserManager.UserId.ToString() == u.DOCID || UserManager.Name.ToString() == u.DOC || UserManager.UserId.ToString() == u.CUSTSERVICEID || UserManager.Name.ToString() == u.CUSTSERVICE) .OrderBy(PageInputOrder.OrderBuilder(input.SortField, input.DescSort)) .ToPagedListAsync(input.PageNo, input.PageSize); @@ -3110,10 +3110,10 @@ namespace Myshipping.Application await _repOrderUrl.InsertAsync(ordUrl); } - if (!string.IsNullOrEmpty(ordUrl.UrlTxxp)) - { - return ordUrl.UrlTxxp; - } + //if (!string.IsNullOrEmpty(ordUrl.UrlTxxp)) + //{ + // return ordUrl.UrlTxxp; + //} //校验船公司 if (string.IsNullOrEmpty(order.CARRIERID)) @@ -3136,10 +3136,16 @@ namespace Myshipping.Application } //场站转换 - var yardset = _cache.GetAllMappingYard().Result.FirstOrDefault(y => y.Code == order.YARDID && y.Module == "BookingTxxp"); + var yardsetList = _cache.GetAllMappingYard().Result.Where(y => y.Code == order.YARDID && y.Module == "BookingTxxp" && (y.CarrierCode == null || y.CarrierCode == "" || y.CarrierCode == order.CARRIERID)).ToList(); + if (yardsetList.Count == 0) + { + throw Oops.Bah(BookingErrorCode.BOOK120, $"{order.YARD} {order.CARRIER}(提箱小票)"); + } + + var yardset = yardsetList.FirstOrDefault(x => x.CarrierCode == order.CARRIERID); if (yardset == null) { - throw Oops.Bah(BookingErrorCode.BOOK120, $"{order.YARDID}(提箱小票)"); + yardset = yardsetList.FirstOrDefault(x => x.CarrierCode == null || x.CarrierCode == ""); } var ctns = await _repCtn.Where(x => x.BILLID == bookingId).ToListAsync(); @@ -3160,7 +3166,8 @@ namespace Myshipping.Application var expCode = ctns.Select(x => x.CTNCODE).Distinct().Except(ctnMapping.Select(y => y.Code)).ToList(); if (expCode.Count > 0) { - throw Oops.Bah(BookingErrorCode.BOOK123, $"{string.Join(',', expCode)}(提箱小票)"); + var expName = ctns.Where(x => expCode.Contains(x.CTNCODE)).Select(x => x.CTNALL).Distinct().ToList(); + throw Oops.Bah(BookingErrorCode.BOOK123, $"{string.Join(',', expName)}(提箱小票)"); } var user = await _repUser.FirstOrDefaultAsync(x => x.Id == UserManager.UserId); @@ -3211,6 +3218,7 @@ namespace Myshipping.Application throw Oops.Bah(BookingErrorCode.BOOK124, jobjResp.GetStringValue("message")); } + var addUrlFlag = string.IsNullOrEmpty(ordUrl.UrlTxxp) ? true : false; //新生成还是更新链接 //保存url var txxpUrl = jobjResp.GetStringValue("data"); ordUrl.UrlTxxp = txxpUrl; @@ -3219,7 +3227,7 @@ namespace Myshipping.Application //货运动态 var bsl = new BookingStatusLog(); bsl.BookingId = bookingId; - bsl.Status = $"生成提箱小票链接"; + bsl.Status = $"{(addUrlFlag ? "生成" : "更新")}提箱小票链接"; bsl.OpTime = DateTime.Now; bsl.Category = "ship"; bsl.MBLNO = order.MBLNO; @@ -3781,6 +3789,14 @@ namespace Myshipping.Application EDIRouteEnum ediRouteEnum = GetEDIRoute(order.CARRIERID); + if (ediRouteEnum == EDIRouteEnum.YT) + { + if (string.IsNullOrWhiteSpace(order.NOBILL)) + { + throw Oops.Bah("当前船公司{ca} EDI={name} 提单份数必填", order.CARRIERID, ediRouteEnum.ToString()); + } + } + //部分船公司EDI需要填写操作英文名称,这里预先预警,其他船公司如果也需要可以再此追加 if (ediRouteEnum == EDIRouteEnum.TSL) { @@ -5339,7 +5355,35 @@ namespace Myshipping.Application throw Oops.Bah(rtn.Value); } - return rtn.Value; + //场站引入的数据,转换为订舱箱型,且带上箱型代码 + var ctnList = await _cache.GetAllCodeCtn(); + var mapCtn = await _cache.GetAllMappingCtn(); + + var jData = JArray.Parse(rtn.Value); + foreach (JObject item in jData) + { + var ctnall = item.GetStringValue("CTNALL"); + var findMap = mapCtn.FirstOrDefault(x => x.Module == "YardData" && x.MapCode == ctnall); + var findCtn = ctnList.FirstOrDefault(x => x.Name == ctnall); + if (findMap != null) + { + item.Add("CtnCode", findMap.Code); + + findCtn = ctnList.First(c => c.Code == findMap.Code); + item["CTNALL"] = findCtn.Name; //名称显示维护的箱型 + } + else if (findCtn != null) + { + item.Add("CtnCode", findCtn.Code); + item["CTNALL"] = findCtn.Name; //名称显示维护的箱型 + } + else + { + throw Oops.Bah($"未找到箱型{ctnall}的场站引入配置"); + } + } + + return jData.ToString(); } /// diff --git a/Myshipping.Application/Service/BookingOrder/BookingValueAddedService.cs b/Myshipping.Application/Service/BookingOrder/BookingValueAddedService.cs new file mode 100644 index 00000000..c23c396b --- /dev/null +++ b/Myshipping.Application/Service/BookingOrder/BookingValueAddedService.cs @@ -0,0 +1,349 @@ +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 System; +using System.Collections.Generic; +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 +{ + /// + /// 订舱增值类服务 + /// + [ApiDescriptionSettings("Application", Name = "BookingValueAdded", Order = 9)] + public class BookingValueAddedService : IBookingValueAddedService, IDynamicApiController, ITransient + { + private readonly ISysCacheService _cache; + private readonly IDjyWebsiteAccountConfigService _webAccountConfig; + private readonly ILogger _logger; + private readonly SqlSugarRepository _bookingOrderRepository; + private readonly SqlSugarRepository _bookingfile; + + const string CONST_MAPPING_CARRIER_MODULE_ROUTE = "BC_OR_DRAFT_RT"; + 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"; + + public BookingValueAddedService(ISysCacheService cache, ILogger logger, + SqlSugarRepository bookingOrderRepository, SqlSugarRepository bookingfile, + IDjyWebsiteAccountConfigService webAccountConfig) + { + _cache = cache; + _logger = logger; + + _bookingOrderRepository = bookingOrderRepository; + _bookingfile = bookingfile; + + _webAccountConfig = webAccountConfig; + } + + + /// + /// 批量下载BC + /// + /// 订舱主键数组 + /// + [HttpPost("/BookingValueAdded/DownloadBookingConfirm")] + public async Task DownloadBookingConfirm([FromBody]long[] bookingIds) + { + TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + + List> taskList = new List>(); + + 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($"订舱信息获取失败,订舱信息不存在或已作废"); + + foreach (var bk in list) + { + taskList.Add(InnerDownloadBookingConfirm(bk, batchNo)); + } + + Task.WaitAll(taskList.ToArray()); + + result.succ = true; + result.msg = "批量下载BC成功"; + //result.ext = id; + } + catch (Exception ex) + { + result.succ = false; + result.msg = $"批量下载BC异常,原因:{ex.Message}"; + } + + return result; + } + + private async Task InnerDownloadBookingConfirm(BookingOrder bookingOrder,string batchNo) + { + TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + + 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_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} 提取BC下载URL完成,结果={rlt}", + bookingOrder.MBLNO, bookingOrder.CARRIERID, bcUrl); + + if (string.IsNullOrWhiteSpace(bcUrl)) + { + _logger.LogInformation("提单号【{mbl}】根据订舱的船公司代码{ca} 提取BC下载URL失败,未取到配置key={key}", + bookingOrder.MBLNO, bookingOrder.CARRIERID, urlKey); + } + + //获取个人对应的账户,这里GetAccountConfig逻辑优先取个人,个人没有配置取公司对应配置 + var userWebAccountConfig = _webAccountConfig.GetAccountConfig(CONST_TSL_BC_WEB, UserManager.UserId).GetAwaiter() + .GetResult(); + + _logger.LogInformation("批次={no} 获取获取网站的账户完成,result={Num}", batchNo, JSON.Serialize(userWebAccountConfig)); + + if (userWebAccountConfig == null) + throw Oops.Bah($"个人/公司网站【{CONST_TSL_BC_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 + }; + + //开始请求BC + + var rlt = await ExcuteBCDownload(bcUrl, requestDto, batchNo); + + if (rlt.code == 200) + { + 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}"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + relativePath = relativePath.Replace("\\", "/"); + filePath = filePath.Replace("\\", "/"); + } + + _logger.LogInformation("批次={no} 生成文件保存路径完成 路由={filePath} 服务器系统={system}", batchNo, filePath, RuntimeInformation.OSDescription); + //预先创建目录 + if (!Directory.Exists(filePath)) + { + Directory.CreateDirectory(filePath); + } + + var bcStream = await currFilePath.GetAsStreamAsync(); + + //这里先写入附件表 + await SaveEDIFile(bookingOrder.Id, currFilePath, new System.IO.FileInfo(currFilePath).Name, + fileTypeCode, fileTypeName); + + } + + result.succ = true; + result.msg = "下载BC成功"; + } + catch (Exception ex) + { + result.succ = false; + result.msg = $"下载BC失败,原因:{ex.Message}"; + } + + return result; + } + + [NonAction] + private async Task SaveEDIFile(long boookId, string FilePath, string fileName, string fileTypeCode = "edi", string fileTypeName = "EDI文件") + { + /* + 直接将附件信息写入附件表 + */ + //EDI文件 + var bookFile = new BookingFile + { + Id = YitIdHelper.NextId(), + FileName = fileName, + FilePath = FilePath, + TypeCode = fileTypeCode, + TypeName = fileTypeName, + BookingId = boookId, + }; + + await _bookingfile.InsertAsync(bookFile); + } + + /// + /// 批量下载Draft + /// + /// 订舱主键数组 + /// + public async Task DownloadDraft(long[] bookingIds) + { + TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + + try + { + /* + 1、订舱主键提取提单号、订舱编号,优先去提单号,其次订舱编号 + 2、根据不同的船公司调取单独的配置账户。 + 3、不同船公司对应不同的接口。 + 4、轮询异步调取接口等待返回接口。 + 5、成功后将文件链接存入附件表。 + 6、等待所有请求完成返回统计结果。 + */ + + result.succ = true; + result.msg = "批量下载Draft成功"; + //result.ext = id; + } + catch (Exception ex) + { + result.succ = false; + result.msg = $"批量下载Draft异常,原因:{ex.Message}"; + } + + return result; + } + + + #region 请求规则平台 + /// + /// 请求规则平台 + /// + /// + /// + [NonAction] + private async Task> 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.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>(userResult, jsonOptions); + } + } + catch (Exception ex) + { + //写日志 + if (ex is HttpRequestException) + throw Oops.Oh(10000002); + } + + return model; + } + #endregion + } + + public class DateTimeJsonConverter : System.Text.Json.Serialization.JsonConverter + { + 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)); + } + } +} + diff --git a/Myshipping.Application/Service/BookingOrder/Dto/BCAPIBaseResult.cs b/Myshipping.Application/Service/BookingOrder/Dto/BCAPIBaseResult.cs new file mode 100644 index 00000000..5e46e194 --- /dev/null +++ b/Myshipping.Application/Service/BookingOrder/Dto/BCAPIBaseResult.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + public class BCAPIBaseResult + { + /// + /// 回执代码 + /// + public int code { get; set; } + + /// + /// 提示信息 + /// + public string msg { get; set; } + + /// + /// 数据集 + /// + public BCAPIBaseData data { get; set; } + } + + public class BCAPIBaseData + { + /// + /// 文件下载路径 + /// + public string path { get; set; } + + /// + /// 解析详情 + /// + public T parse { get; set; } + } + + public class BCAPIBaseDataParse + { + /// + /// 解析回执代码 + /// + public int status { get; set; } + + /// + /// 解析提示信息 + /// + public string message { get; set; } + + /// + /// 解析提示信息 + /// + public BCAPIBaseDataParseModel data { get; set; } + } + + public class BCAPIBaseDataParseModel + { + /// + /// 模板ID + /// + public string ModelID { get; set; } + + /// + /// 模板名称 + /// + public string ModelName { get; set; } + + /// + /// BC解析明细 + /// + public List BCList { get; set; } + } + + +} diff --git a/Myshipping.Application/Service/BookingOrder/Dto/BCOrDraftRequestDto.cs b/Myshipping.Application/Service/BookingOrder/Dto/BCOrDraftRequestDto.cs new file mode 100644 index 00000000..05f7efc6 --- /dev/null +++ b/Myshipping.Application/Service/BookingOrder/Dto/BCOrDraftRequestDto.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// BC或DRAFT下载请求 + /// + public class BCOrDraftRequestDto + { + /// + /// 用户key + /// + public string user_key { get; set; } + /// + /// 用户secret + /// + public string user_secret { get; set; } + /// + /// 网站账号 + /// + public string web_user { get; set; } + /// + /// 网站密码 + /// + public string web_psw { get; set; } + /// + /// 单号(订舱编号) + /// + public string bno { get; set; } + /// + /// 是否解析,默认否 + /// + public bool is_parse { get; set; } = false; + } +} diff --git a/Myshipping.Application/Service/BookingOrder/Dto/BCReadModel.cs b/Myshipping.Application/Service/BookingOrder/Dto/BCReadModel.cs new file mode 100644 index 00000000..2e521999 --- /dev/null +++ b/Myshipping.Application/Service/BookingOrder/Dto/BCReadModel.cs @@ -0,0 +1,265 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// BC解析主信息 + /// + public class BCReadModel + { + /// + /// 订舱单位 + /// + public string BookingParty { get; set; } + + /// + /// 发货人 + /// + public string Shipper { get; set; } + + /// + /// 收货人 + /// + public string Consigner { get; set; } + + /// + /// 通知人 + /// + public string NotifyParty { get; set; } + + /// + /// BC更新次数 + /// + public Nullable BCUpdateTimes { get; set; } + + /// + /// BC更新时间 + /// + public Nullable BCUpdateTime { get; set; } + + /// + /// 提单号 + /// + public string BLNo { get; set; } + + /// + /// 船名 + /// + public string Vessel { get; set; } + + /// + /// 航次 + /// + public string Voyage { get; set; } + + /// + /// 船公司 + /// + public string ShippingCompany { get; set; } + + /// + /// 收货地 + /// + public string PlaceOfReceipt { get; set; } + + /// + /// 发货人 + /// + public string LoadingPort { get; set; } + + /// + /// 截关时间 + /// + public Nullable ClosingDate { get; set; } + + /// + /// 截VGM时间 + /// + public Nullable VGMCutOffTime { get; set; } + + /// + /// ETA + /// + public Nullable ETA { get; set; } + + /// + /// ETD + /// + public Nullable ETD { get; set; } + + /// + /// 目的港ETA + /// + public Nullable PortOfDestinationETA { get; set; } + + /// + /// 预付地点 + /// + public Nullable CutSingleTime { get; set; } + + /// + /// 截港时间 + /// + public Nullable CYCutOffTime { get; set; } + + /// + /// 卸货港 + /// + public string DischargingPort { get; set; } + + /// + /// 交货地 + /// + public string DeliveryPlace { get; set; } + + /// + /// 装运方式 + /// + public string ShippingWay { get; set; } + + /// + /// 运输条款 + /// + public string ShippingTerms { get; set; } + + /// + /// 港前运输形态 + /// + public string PreportTransportationMode { get; set; } + + /// + /// 品名 + /// + public string OfTheGoods { get; set; } + + /// + /// 签单地点 + /// + public string SignTheBillLocation { get; set; } + + /// + /// 集港码头 + /// + public string CollectionTerminal { get; set; } + + /// + /// 约号 + /// + public string AboutNo { get; set; } + + /// + /// 预付地点 + /// + public string PlaceInAdvance { get; set; } + + /// + /// 船代 + /// + public string ShipAgency { get; set; } + + /// + /// 场站 + /// + public string Station { get; set; } + + /// + /// 场站联系人 + /// + public string StationContact { get; set; } + + /// + /// 场站联系电话 + /// + public string StationContactNumber { get; set; } + + /// + /// 一代客服姓名 + /// + public string FirstCustomerServiceName { get; set; } + + /// + /// 一代客服电话 + /// + public string FirstCustomerServiceNumber { get; set; } + + /// + /// 一代客服邮箱 + /// + public string FirstCustomerServiceEmail { get; set; } + + /// + /// 备注1 + /// + public string Remark { get; set; } + + /// + /// 集装箱列表 + /// + public List Containers { get; set; } + } + + /// + /// 集装箱详情 + /// + public class BCReadContaModel + { + /// + /// 箱量 + /// + public Nullable CartonQuantity { get; set; } + + /// + /// 箱型 + /// + public string BoxPile { get; set; } + + /// + /// 件数 + /// + public Nullable Pieces { get; set; } + + /// + /// 尺寸 + /// + public Nullable Size { get; set; } + + /// + /// 毛重 + /// + public Nullable GrossWeight { get; set; } + + /// + /// 箱皮重 + /// + public Nullable TareWeight { get; set; } + + /// + /// 危品票标示 + /// + public string IODGT { get; set; } + + /// + /// 特殊装载需求 + /// + public string SpecialLoadingRequirement { get; set; } + + /// + /// 提箱场站 + /// + public string SuitcaseTterminal { get; set; } + + /// + /// 提箱时间 + /// + public Nullable SuitcaseTime { get; set; } + + /// + /// 还箱场站 + /// + public string ReturnDepot { get; set; } + } +} diff --git a/Myshipping.Application/Service/BookingOrder/IBookingValueAddedService.cs b/Myshipping.Application/Service/BookingOrder/IBookingValueAddedService.cs new file mode 100644 index 00000000..48fd97b0 --- /dev/null +++ b/Myshipping.Application/Service/BookingOrder/IBookingValueAddedService.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// 订舱增值类服务 + /// + public interface IBookingValueAddedService + { + /// + /// 批量下载BC + /// + /// 订舱主键数组 + /// + Task DownloadBookingConfirm(long[] bookingIds); + + + /// + /// 批量下载Draft + /// + /// 订舱主键数组 + /// + Task DownloadDraft(long[] bookingIds); + } +} diff --git a/Myshipping.Application/Service/BookingTruck/BookingTruckService.cs b/Myshipping.Application/Service/BookingTruck/BookingTruckService.cs index 476b9f99..9262672a 100644 --- a/Myshipping.Application/Service/BookingTruck/BookingTruckService.cs +++ b/Myshipping.Application/Service/BookingTruck/BookingTruckService.cs @@ -744,6 +744,9 @@ namespace Myshipping.Application if (model == null) throw Oops.Oh($"派车信息获取失败,派车信息不存在或已作废", typeof(InvalidOperationException)); + var bookingOrder = _bookingOrderRepository.AsQueryable().First(a => a.Id == model.BookingId); + + //校验 ValidateTruck(OperateTypeEnum.Submit, new BookingTruck[] { model }); @@ -769,9 +772,34 @@ namespace Myshipping.Application { TaskType = TaskBaseTypeEnum.TRUCK_DISPATCH, TruckInfo = model.Adapt(), + MBlNo = bookingOrder.MBLNO, + ETD = bookingOrder.ETD, + VesselVoyno = $"{bookingOrder.VESSEL}/{bookingOrder.VOYNO}", + TaskUserId = UserManager.UserId.ToString(), + TaskUserName = UserManager.Name, + ContaInfo = model.CntrTotal, + YardName = model.InYard } }; + if(string.IsNullOrWhiteSpace(messageInfo.Main.TruckInfo.Vessel) + && !string.IsNullOrWhiteSpace(bookingOrder.VESSEL)) + { + messageInfo.Main.TruckInfo.Vessel = bookingOrder.VESSEL; + } + + if (string.IsNullOrWhiteSpace(messageInfo.Main.TruckInfo.VoyNo) + && !string.IsNullOrWhiteSpace(bookingOrder.VOYNO)) + { + messageInfo.Main.TruckInfo.VoyNo = bookingOrder.VOYNO; + } + + if (string.IsNullOrWhiteSpace(messageInfo.Main.TruckInfo.MBLNo) + && !string.IsNullOrWhiteSpace(bookingOrder.MBLNO)) + { + messageInfo.Main.TruckInfo.MBLNo = bookingOrder.MBLNO; + } + if (contaList.Count > 0) messageInfo.Main.TruckInfo.ContaList = contaList.Adapt>(); diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderMessageMainInfo.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderMessageMainInfo.cs index 7c829afc..aff355ec 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderMessageMainInfo.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderMessageMainInfo.cs @@ -89,6 +89,26 @@ namespace Myshipping.Application /// public string TaskOrgName { get; set; } + /// + /// 开船日期 + /// + public Nullable ETD { get; set; } + + /// + /// 箱型箱量 + /// + public string ContaInfo { get; set; } + + /// + /// 船名航次 + /// + public string VesselVoyno { get; set; } + + /// + /// 场站 + /// + public string YardName { get; set; } + /// /// 费用明细(当业务类型是INVOICE_BILL_MAIL-航次账单 /// diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderTruckInfo.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderTruckInfo.cs index 5341def2..f4d74e96 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderTruckInfo.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderTruckInfo.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -177,6 +178,24 @@ namespace Myshipping.Application /// public string FactoryAddr { get; set; } + /// + /// 箱型箱量 + /// + public string CntrTotal { get; set; } + + /// + /// 船名 + /// + public string Vessel { get; set; } + /// + /// 航次 + /// + public string VoyNo { get; set; } + /// + /// 提单号 + /// + public string MBLNo { get; set; } + /// /// 集装箱列表 /// diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/Truck/TaskTruckPrintDto.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/Truck/TaskTruckPrintDto.cs index a5d69edb..75ebee56 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Dtos/Truck/TaskTruckPrintDto.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/Truck/TaskTruckPrintDto.cs @@ -52,6 +52,10 @@ namespace Myshipping.Application /// public string AttnFax { get; set; } /// + /// FROM手机号 + /// + public string FromMobile { get; set; } + /// /// FROM /// public string FromName { get; set; } diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs index f0d207a2..f42e4e6c 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs @@ -240,8 +240,23 @@ namespace Myshipping.Application TASK_DESP = info.Main.TaskDesp, TASK_SOURCE = info.Main.TaskSource.ToString(), TASK_TYPE = info.Main.TaskType.ToString(), + VESSEL_VOYNO = info.Main.VesselVoyno?.Trim(), + CONTA_INFO = info.Main.ContaInfo, + TASK_REQ_USERNAME = info.Main.TaskUserName, + YARD_NAME = info.Main.YardName, + ETD = info.Main.ETD }; + long taskReqUserId = 0; + + if (!string.IsNullOrWhiteSpace(info.Main.TaskUserId)) + { + if(long.TryParse(info.Main.TaskUserId,out taskReqUserId)) + { + taskInfo.TASK_REQ_USERID = taskReqUserId; + } + } + UserTendDto userTendInfo = GetUserTendInfo(info.Main.RecvUserId); taskInfo.CreatedUserId = userTendInfo.userId; @@ -477,6 +492,7 @@ namespace Myshipping.Application truckInfo.TenantName = taskInfo.TenantName; truckInfo.Status = BookingTruckStatus.TEMP.ToString(); + //异步写入 await _taskTruckInfoRepository.InsertAsync(truckInfo); @@ -685,13 +701,15 @@ namespace Myshipping.Application ActionKey = TaskStatLevelEnum.EXCPTION.ToString() }); + var nextList = new List(); + exceptList.GroupBy(t => t.Status) .Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) }) .ToList().ForEach(t => { TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key); - resultInfo.LevelNext.Add(new TaskUserStatItemNext + nextList.Add(new TaskUserStatItemNext { TopKey = TaskStatLevelEnum.EXCPTION.ToString(), Key = currEnum.ToString(), @@ -703,6 +721,9 @@ namespace Myshipping.Application }); + if (nextList.Count > 0) + resultInfo.LevelNext = nextList.OrderBy(t => t.SortNo).ToList(); + exceptList.GroupBy(t => new { t.Status, t.TaskType }) .Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) }) .ToList().ForEach(t => @@ -736,13 +757,14 @@ namespace Myshipping.Application ActionKey = TaskStatLevelEnum.PERSON.ToString() }); + var nextList = new List(); personList.GroupBy(t => t.Status) .Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) }) .ToList().ForEach(t => { TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key); - resultInfo.LevelNext.Add(new TaskUserStatItemNext + nextList.Add(new TaskUserStatItemNext { TopKey = TaskStatLevelEnum.PERSON.ToString(), Key = currEnum.ToString(), @@ -754,6 +776,9 @@ namespace Myshipping.Application }); + if (nextList.Count > 0) + resultInfo.LevelNext = nextList.OrderBy(t => t.SortNo).ToList(); + personList.GroupBy(t => new { t.Status, t.TaskType }) .Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) }) .ToList().ForEach(t => @@ -787,13 +812,15 @@ namespace Myshipping.Application ActionKey = TaskStatLevelEnum.PUBLIC.ToString() }); + var nextList = new List(); + publicList.GroupBy(t => t.Status) .Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) }) .ToList().ForEach(t => { TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key); - resultInfo.LevelNext.Add(new TaskUserStatItemNext + nextList.Add(new TaskUserStatItemNext { TopKey = TaskStatLevelEnum.PUBLIC.ToString(), Key = currEnum.ToString(), @@ -805,6 +832,9 @@ namespace Myshipping.Application }); + if (nextList.Count > 0) + resultInfo.LevelNext = nextList.OrderBy(t => t.SortNo).ToList(); + publicList.GroupBy(t => new { t.Status, t.TaskType }) .Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) }) .ToList().ForEach(t => @@ -825,7 +855,6 @@ namespace Myshipping.Application }); } #endregion - } catch (Exception ex) { @@ -916,7 +945,7 @@ namespace Myshipping.Application .WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskCategory) && QuerySearch.TaskCategory == TaskStatLevelEnum.PUBLIC.ToString(), t => t.IS_PUBLIC == 1) .WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskCategory) && QuerySearch.TaskCategory == TaskStatLevelEnum.PERSON.ToString(), t => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0) .WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.Status), t => t.STATUS.Equals(QuerySearch.Status, StringComparison.OrdinalIgnoreCase)) - .OrderBy(entityOrderCol + (QuerySearch.descSort ? " asc " : " desc ")) + .OrderBy(entityOrderCol + (QuerySearch.descSort ? " desc " : " asc ")) .ToPagedListAsync(QuerySearch.PageNo, QuerySearch.PageSize); diff --git a/Myshipping.Core/Entity/CommonDB/CodeYard.cs b/Myshipping.Core/Entity/CommonDB/CodeYard.cs index 8fa2d99f..a7018771 100644 --- a/Myshipping.Core/Entity/CommonDB/CodeYard.cs +++ b/Myshipping.Core/Entity/CommonDB/CodeYard.cs @@ -68,5 +68,10 @@ namespace Myshipping.Core.Entity /// public string Remark { get; set; } + /// + /// 船司代码 + /// + public string CarrierCode { get; set; } + } } diff --git a/Myshipping.Core/Extension/JsonExtension.cs b/Myshipping.Core/Extension/JsonExtension.cs index 1628f0a9..5c6accc1 100644 --- a/Myshipping.Core/Extension/JsonExtension.cs +++ b/Myshipping.Core/Extension/JsonExtension.cs @@ -26,6 +26,23 @@ namespace Myshipping.Core return jt as JObject; } + /// + /// 获取JArray + /// + /// + /// + /// + public static JArray GetJArrayValue(this JObject jobj, string prop) + { + var jt = jobj[prop]; + if (jt == null) + { + return null; + } + + return jt as JArray; + } + /// /// 获取字符串值 /// diff --git a/Myshipping.Core/Myshipping.Core.xml b/Myshipping.Core/Myshipping.Core.xml index 49a38200..42bcd889 100644 --- a/Myshipping.Core/Myshipping.Core.xml +++ b/Myshipping.Core/Myshipping.Core.xml @@ -1527,6 +1527,11 @@ 备注 + + + 船司代码 + + 主键 @@ -5345,6 +5350,14 @@ + + + 获取JArray + + + + + 获取字符串值 @@ -8894,6 +8907,11 @@ 排序 + + + 船司代码 + + 航线与港口的的关系表 diff --git a/Myshipping.Core/Service/CommonDB/CommonDBService.cs b/Myshipping.Core/Service/CommonDB/CommonDBService.cs index bd6e3a62..9f6d1039 100644 --- a/Myshipping.Core/Service/CommonDB/CommonDBService.cs +++ b/Myshipping.Core/Service/CommonDB/CommonDBService.cs @@ -104,7 +104,7 @@ public class CommonDBService : ICommonDBService, IDynamicApiController, ITransie _codeLaneRep = codeLaneRep; _relaPortCarrierLaneRep = relaPortCarrierLaneRep; _codeCountryRep = codeCountryRep; - _mappingIssueTypeRep= mappingIssueTypeRep; + _mappingIssueTypeRep = mappingIssueTypeRep; _mappingForwarder = mappingForwarder; } @@ -526,7 +526,7 @@ public class CommonDBService : ICommonDBService, IDynamicApiController, ITransie { var list = await _sysCacheService.GetAllMappingYard(); - var count = list.Where(x => x.Code == dto.Code && x.Module == dto.Module && x.GID != dto.GID).Count(); + var count = list.Where(x => x.Code == dto.Code && x.Module == dto.Module && x.CarrierCode == dto.CarrierCode && x.GID != dto.GID).Count(); if (count > 0) { throw Oops.Bah(ErrorCode.D1006); @@ -1328,7 +1328,7 @@ public class CommonDBService : ICommonDBService, IDynamicApiController, ITransie public async Task AddOrUpdateMappingIssueType([FromBody] MappingIssueTypeDto dto) { var list = await _sysCacheService.GetAllMappingIssueType(); - var count = list.Where(x => x.Code == dto.Code && x.Module == dto.Module && x.GID != dto.GID).Count(); + var count = list.Where(x => x.Code == dto.Code && x.Module == dto.Module && x.GID != dto.GID).Count(); if (count > 0) { throw Oops.Bah(ErrorCode.D1006); @@ -1578,13 +1578,13 @@ public class CommonDBService : ICommonDBService, IDynamicApiController, ITransie /// /// 查询条件 /// - [HttpGet("/commondb/CodeCountryList")] + [HttpGet("/commondb/CodeCountryList")] public async Task CodeCountryList([FromQuery] NameQueryDto input) { List list = await _sysCacheService.GetAllCodeCountry(); var queryList = list - .WhereIF(!string.IsNullOrEmpty(input.Name),x=>x.Code.ToUpper()==input.Name.ToUpper()) + .WhereIF(!string.IsNullOrEmpty(input.Name), x => x.Code.ToUpper() == input.Name.ToUpper()) .WhereIF(!string.IsNullOrEmpty(input.KeyWord), x => (!string.IsNullOrWhiteSpace(x.Code) && x.Code.Contains(input.KeyWord, System.StringComparison.CurrentCultureIgnoreCase)) || (!string.IsNullOrWhiteSpace(x.EnName) && x.EnName.Contains(input.KeyWord, System.StringComparison.CurrentCultureIgnoreCase)) diff --git a/Myshipping.Core/Service/CommonDB/Dto/MappingYardDto.cs b/Myshipping.Core/Service/CommonDB/Dto/MappingYardDto.cs index e089cc98..eeee79ca 100644 --- a/Myshipping.Core/Service/CommonDB/Dto/MappingYardDto.cs +++ b/Myshipping.Core/Service/CommonDB/Dto/MappingYardDto.cs @@ -41,5 +41,10 @@ namespace Myshipping.Core.Service.CommonDB.Dto /// public int Sort { get; set; } + /// + /// 船司代码 + /// + public string CarrierCode { get; set; } + } } diff --git a/Myshipping.Web.Core/applicationconfig.json b/Myshipping.Web.Core/applicationconfig.json index 28298932..22be0293 100644 --- a/Myshipping.Web.Core/applicationconfig.json +++ b/Myshipping.Web.Core/applicationconfig.json @@ -119,5 +119,7 @@ "Path": "TempFiles", "RemainHours": 2 }, - "ShippingOrderCompareUrl": "http://60.209.125.238:35210/api/TaskShippingOrderCompare/ExcuteShippingOrderCompare" + "ShippingOrderCompareUrl": "http://60.209.125.238:35210/api/TaskShippingOrderCompare/ExcuteShippingOrderCompare", + "BCOrDraftUserKey": "BookingOrderPlat", + "BCOrDraftUserSecret": "228b2db5952d13291f228d441018c1b6" } \ No newline at end of file diff --git a/Myshipping.Web.Entry/Myshipping.Web.Entry.csproj b/Myshipping.Web.Entry/Myshipping.Web.Entry.csproj index 2caa36a4..b52a76b2 100644 --- a/Myshipping.Web.Entry/Myshipping.Web.Entry.csproj +++ b/Myshipping.Web.Entry/Myshipping.Web.Entry.csproj @@ -26,6 +26,11 @@ + + <_WebToolingArtifacts Remove="Properties\PublishProfiles\linux.pubxml" /> + <_WebToolingArtifacts Remove="Properties\PublishProfiles\windows.pubxml" /> + + PreserveNewest