using Furion; using Furion.DatabaseAccessor; using Furion.DependencyInjection; using Furion.DistributedIDGenerator; using Furion.FriendlyException; using Furion.JsonSerialization; using Furion.RemoteRequest.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using ServiceProjectSyncWin; using ServiceProjectSyncWin.Entities; using SqlSugar; using System.Collections.Specialized; using System.ComponentModel.DataAnnotations; using System.Net.Http.Headers; using System.Text; using System.Text.RegularExpressions; using System.Web; using static System.Net.Mime.MediaTypeNames; Serve.RunGeneric(additional: services => { services.AddRemoteRequest(); services.AddSqlsugarSetup(App.Configuration); }, true, true); Console.WriteLine("开始准备同步历史服务状态数据"); var service1 = App.GetService(); //service1.SyncServiceProjectRecord(); service1.SyncServiceProjectRecord4(); Console.ReadKey(); public interface ISyncHisRecord { void SyncServiceProjectRecord4(); //void SyncServiceProjectRecord2(); //void SyncServiceProjectRecord3(); } public class SyncHisRecord: ISyncHisRecord,ITransient { SqlSugar.ISqlSugarClient _db; private readonly ILogger _logger; public SyncHisRecord(ISqlSugarClient db, ILogger logger) { _db = db; _logger = logger; } public void SyncServiceProjectRecord() { int totalSyncNum = 0; int succSyncNum = 0; long maxId = 0; //349708986646597/中集世联达领鲜物流科技(山东)有限公司 long tenantId = 349708986646597; string batchNo = Guid.NewGuid().ToString(); _logger.LogInformation("批次={no} 触发同步货物状态 tenantId={tenantId}", batchNo, tenantId); try { var tenantInfo = _db.Queryable().First(a => a.Id == tenantId); /* 1、按批次读取服务状态数据。(去掉没有完成时间的、并且订舱数据是已删除的记录) 2、写入历史记录表。 3、单票生成触发报文,并推送状态。 4、更新历史记录,标记同步状态 */ maxId = _db.Queryable().Max(a => a.ORG_STATUS_ID); _logger.LogInformation("批次={no} 获取最后同步服务状态的ID={maxId}", batchNo, maxId); int takeNum = 1000; while (true) { var takeList = _db.Queryable() .InnerJoin((gs, cfg) => gs.ConfigId == cfg.Id) .InnerJoin((gs, cfg, bk) => gs.bookingId == bk.Id) .Where((gs, cfg, bk) => gs.FinishTime.HasValue && gs.TenantId == tenantId && !bk.IsDeleted && gs.FinishUserId != 142307070910551 && (maxId == 0 || gs.Id > maxId)) .OrderBy((gs, cfg, bk) => gs.Id) .Select((gs, cfg, bk) => new { GS = gs, CFG = cfg, BK = bk }) .Take(takeNum).ToList(); totalSyncNum += takeList.Count; Console.WriteLine($"批次={batchNo} 同步待处理任务 totalSyncNum={totalSyncNum}"); _logger.LogInformation("批次={no} 同步待处理任务 totalSyncNum={totalSyncNum}", batchNo, totalSyncNum); //没有记录跳出循环 if (takeList.Count == 0) { Console.WriteLine($"没有记录跳出循环 total={succSyncNum}"); break; } maxId = takeList.Max(a => a.GS.Id); _logger.LogInformation("批次={no} 获取最后同步服务状态的 maxId={maxId}", batchNo, maxId); //写入记录表 takeList.ForEach(async record => { var entity = new ServiceStatusBookingSyncHisInfo { PK_ID = Guid.NewGuid().ToString(), ORG_STATUS_ID = record.GS.Id, BOOKING_ID = record.BK.Id, FINISH_TIME = record.GS.FinishTime.Value, FINISH_USER_ID = record.GS.FinishUserId.Value, FINISH_USER_NAME = record.GS.FinishUser, MBL_NO = record.BK.MBLNO, SORT_NO = record.CFG.Sort, STATUS_SKU_CODE = record.CFG.SystemCode, STATUS_SKU_NAME = record.CFG.StatusName, STATUS_REMARK = record.GS.Remark, STATUS_VAL = record.GS.ExtData, TENANT_ID = record.GS.TenantId.Value, TENANT_NAME = tenantInfo.Name, VESSEL = record.BK.VESSEL, VOYNO = record.BK.VOYNO, }; _db.Insertable(entity).ExecuteCommand(); //await _serviceStatusBookingSyncHisInfoRepository.InsertAsync(entity); succSyncNum++; Console.WriteLine($"ORG_STATUS_ID={record.GS.Id} 写入成功 total={succSyncNum}"); Thread.Sleep(300); }); Console.WriteLine($"等待500毫秒"); Thread.Sleep(500); } //停用的状态(接受委托、放箱指令、已发账单、账单确认、账单已回传) string[] deletedStatusCodeArg = new string[] { "JSWTUO", "FXZLING", "YFZD", "ZDQR", "ZDYHC" }; /* 单票触发推送状态 1、取状态是null的,并且每次取前100个订舱记录。 2、按订舱记录取所有的状态记录。 3、生成触发脚本推送PUSH状态。(部分状态自动不执行) 4、执行成功后,更新对应的状态。 */ Console.WriteLine($"开始推送记录 succ={succSyncNum}"); while (true) { var bookingList = _db.Queryable() .Where(a => a.TENANT_ID == tenantId && a.STATUS == null) .Take(100).Select(a => a.BOOKING_ID).Distinct().ToList(); //无数据跳出 if (bookingList.Count == 0) { Console.WriteLine($"没有待推送记录跳出循环 succ={succSyncNum}"); break; } var taskList = _db.Queryable() .Where(a => a.TENANT_ID == tenantId && bookingList.Contains(a.BOOKING_ID)).ToList(); taskList.GroupBy(a => a.BOOKING_ID).ToList().ForEach(a => { DateTime currDate = DateTime.Now; var currStatusList = a.ToList(); var groupCheckList = currStatusList .Where(b => !deletedStatusCodeArg.Contains(b.STATUS_SKU_CODE)) .GroupBy(b => b.STATUS_SKU_CODE).Select(b => { var currList = b.ToList(); if (currList.Count == 1) return currList.FirstOrDefault(); return currList.OrderByDescending(c => c.ORG_STATUS_ID).FirstOrDefault(); }).ToList(); if (groupCheckList.Count > 0) { var firstInfo = groupCheckList.FirstOrDefault(); TrackingMessageInfo msgInfo = new TrackingMessageInfo { Head = new TrackingMessageHeadInfo { GID = IDGen.NextID().ToString(), MessageType = "PROJECT", ReceiverId = "ServiceProjectStatus", ReceiverName = "服务项目和状态", SenderId = "BookingOrder", SenderName = "海运订舱", RequestDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), Version = "2.0", RequestAction = "AddOrModify", }, Main = new TrackingMessageMainInfo { BusiId = firstInfo.BOOKING_ID.ToString(), BusiSystemCode = "BOOKING_ORDER", MBlNo = firstInfo.MBL_NO, VesselVoyno = $"{firstInfo.VESSEL}/{firstInfo.VOYNO}", OrderNo = "", PushType = TrackingPushTypeEnum.Status, OperTenantId = firstInfo.TENANT_ID, OperTenantName = firstInfo.TENANT_NAME, OpertType = TrackingOperTypeEnum.AUTO, OperUserId = firstInfo.FINISH_USER_ID.ToString(), OperUserName = firstInfo.FINISH_USER_NAME, SourceType = TrackingSourceTypeEnum.AUTO, StatusList = groupCheckList.Select(a => new TrackingMessageMainStatusInfo { StatusCode = a.STATUS_SKU_CODE, StatusDate = a.FINISH_TIME, StatusVal = a.STATUS_VAL, Remark = a.STATUS_REMARK }).ToList() } }; Console.WriteLine($"准备PUSH状态 msg={JSON.Serialize(msgInfo.Main)}"); //推送状态 var pushRlt = PushStatus(msgInfo).GetAwaiter().GetResult(); Console.WriteLine($"PUSH返回结果 rlt={JSON.Serialize(pushRlt)}"); groupCheckList.ForEach(async t => { t.STATUS = pushRlt.succ ? "SUCC" : "FAILURE"; t.SYNC_TIME = currDate; t.SYNC_RESULT = pushRlt.msg; if (deletedStatusCodeArg.Contains(t.STATUS_SKU_CODE)) { t.STATUS = "FAILURE"; t.SYNC_RESULT = "状态已取消不再同步"; } await _db.Updateable(t) .UpdateColumns(it => new { it.STATUS, it.SYNC_TIME, it.SYNC_RESULT }).ExecuteCommandAsync(); }); var undoList = currStatusList.GroupJoin(groupCheckList, l => l.ORG_STATUS_ID, r => r.ORG_STATUS_ID, (l, r) => { var currList = r.ToList(); if (currList.Count == 0) return new { IsUpdate = true, Obj = l }; return new { IsUpdate = false, Obj = l }; }).Where(c => c.IsUpdate) .Select(c => c.Obj).ToList(); if (undoList.Count > 0) { undoList.ForEach(async t => { t.STATUS = "FAILURE"; t.SYNC_RESULT = "状态已取最后触发记录"; t.SYNC_TIME = currDate; if (deletedStatusCodeArg.Contains(t.STATUS_SKU_CODE)) { t.SYNC_RESULT = "状态已取消不再同步"; } await _db.Updateable(t) .UpdateColumns(it => new { it.STATUS, it.SYNC_TIME, it.SYNC_RESULT }).ExecuteCommandAsync(); }); } Console.WriteLine($"更新表结束"); } else { Console.WriteLine($"没有可用记录"); } Thread.Sleep(300); }); Thread.Sleep(500); } } catch(Exception ex) { _logger.LogInformation("批次={no} 同步异常ex={ex}", batchNo, maxId); } } public async Task PushStatus(TrackingMessageInfo info) { TaskManageOrderResultDto model = null; /* 1、读取配置文件中的规则引擎URL 2、填充请求的类,并生成JSON报文 3、POST请求接口,并记录回执。 4、返回信息。 */ var url = App.Configuration["ServiceStatusPushUrl"]; try { var res = await url.SetHttpMethod(HttpMethod.Post) .SetBody(JSON.Serialize(info), "application/json") .SetContentEncoding(Encoding.UTF8) .PostAsync(); _logger.LogInformation("批次={no} 对应请求报文完成 res={res}", info.Head.GID, JSON.Serialize(res)); if (res.StatusCode == System.Net.HttpStatusCode.OK) { var userResult = await res.Content.ReadAsStringAsync(); var cmRlt = JSON.Deserialize(userResult); if(cmRlt.success) model = JSON.Deserialize(JSON.Serialize(cmRlt.data)); } } catch (Exception ex) { //写日志 if (ex is HttpRequestException) throw Oops.Oh(10000002); } return model; } public void SyncServiceProjectRecord2() { /* string fmt = "(16)PortofDischarge(17)PlaceofDelivery"; var fmtList = fmt.Select(a => a).ToList(); string name = "(1P6)E PNorAt oNf GDi,scMhaArgLeA YSIA P(1E7)N PAlaNceG o,f DMeAlivLerAy YSIA"; List array = new List(); List array2 = new List(); for (var i=0;i< name.Length;i++) { bool isExists = false; if(fmtList.Count > 0) { if (name[i] == fmtList.First()) { array.Add(name[i]); fmtList.Remove(fmtList[0]); isExists = true; } } if (!isExists) array2.Add(name[i]); } string s1 = string.Join("", array); string s2 = string.Join("", array2); */ string Consignee = "LOT 13/3,KAWASAN PERINDUSTRIAN, K AMPUNG KOLAM PADANG BESAR,02100 P ADANG BESAR,PERLIS. T EL;04-949 0507 FAX 94-949 2888"; string NotifyParty = "SHUN EE TRADING SDN BHD (1183208 U) LOT 13/3,KAWASAN PERINDUSTRIAN, K AMPUNG KOLAM PADANG BESAR,02100 P ADANG BESAR,PERLIS. T EL;04-949 0507 FAX 94-949 2888"; if (Regex.IsMatch(Consignee, "\\b[a-zA-Z]{1}\\b\\s+\\b[a-zA-Z]+\\b")) { Consignee = Regex.Replace(Consignee, "\\b[a-zA-Z]{1}\\b\\s+\\b[a-zA-Z]+\\b", m => Regex.Replace(m.Value, "\\s+", "")); } if (Regex.IsMatch(NotifyParty, "\\b[a-zA-Z]{1}\\b\\s+\\b[a-zA-Z]+\\b")) { NotifyParty = Regex.Replace(NotifyParty, "\\b[a-zA-Z]{1}\\b\\s+\\b[a-zA-Z]+\\b", m => Regex.Replace(m.Value, "\\s+", "")); } decimal similarity = 100; for (int i = 0; i < NotifyParty.Length; i++) { } } public void SyncServiceProjectRecord4() { /* 批量更新SI 截止时间 1、更新任务台 2、更新舱位的截止时间记录 */ var taskList = _db.Queryable().Where(a => (a.BUSI_TYPE == "BookingConfirmation" || a.BUSI_TYPE == "BookingAmendment")) .OrderBy(t=>t.CreatedTime) .ToList(); string batchNo = Guid.NewGuid().ToString(); _logger.LogInformation($"批次={batchNo} 提取待处理任务 num={taskList.Count}"); string bcReadUrl = "http://47.104.73.97:7115/api/TaskBCParser/ExcuteBCFileRead"; string amendReadUrl = "http://47.104.73.97:7115/api/TaskBookingAmendmentParser/ExcuteBookingAmendmentRead"; //foreach (var task in taskList) for(int i=0;i().Where(a => a.TASK_PKID == task.TASK_ID && a.FILE_CATEGORY == "BC").First(); if (fileInfo != null) { _logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 取到文件"); string bcFileFullPath = $"D:\\djy\\backend\\wwwroot\\{fileInfo.FILE_PATH}"; var bcFileName = Path.GetFileName(bcFileFullPath); if(!File.Exists(bcFileFullPath)) { _logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 取到文件不存在 path={bcFileFullPath}"); continue; } TaskBCInfoReadDto BCReadInfo = GetBCReaderInfo(bcFileFullPath, bcFileName, task.TenantId.Value, task.TASK_ID, bcReadUrl).GetAwaiter().GetResult(); _logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 识别完文件 BCReadInfo={JSON.Serialize(BCReadInfo)}"); StringBuilder msgBuilder = new StringBuilder(); if (BCReadInfo != null) { //SI_CUT_DATE if (BCReadInfo.SICutDate.HasValue) { if (!task.SI_CUT_DATE.HasValue || task.SI_CUT_DATE.Value != BCReadInfo.SICutDate.Value) { msgBuilder.Append($"SI_CUT_DATE org={task.SI_CUT_DATE} tar={BCReadInfo.SICutDate.Value}##"); task.SI_CUT_DATE = BCReadInfo.SICutDate.Value; } } else { msgBuilder.Append($"SI_CUT_DATE org={task.SI_CUT_DATE} tar=null"); task.SI_CUT_DATE = null; } //VGM_CUTOFF_TIME if (BCReadInfo.VGMCutoffTime.HasValue) { if (!task.VGM_CUTOFF_TIME.HasValue || task.VGM_CUTOFF_TIME.Value != BCReadInfo.VGMCutoffTime.Value) { msgBuilder.Append($"VGM_CUTOFF_TIME org={task.VGM_CUTOFF_TIME} tar={BCReadInfo.VGMCutoffTime.Value}##"); task.VGM_CUTOFF_TIME = BCReadInfo.VGMCutoffTime.Value; } } else { msgBuilder.Append($"VGM_CUTOFF_TIME org={task.VGM_CUTOFF_TIME} tar=null##"); task.VGM_CUTOFF_TIME = null; } //MANIFEST_CUT_DATE if (BCReadInfo.ManifestCutDate.HasValue) { if (!task.MANIFEST_CUT_DATE.HasValue || task.MANIFEST_CUT_DATE.Value != BCReadInfo.ManifestCutDate.Value) { msgBuilder.Append($"MANIFEST_CUT_DATE org={task.MANIFEST_CUT_DATE} tar={BCReadInfo.ManifestCutDate.Value}##"); task.MANIFEST_CUT_DATE = BCReadInfo.ManifestCutDate.Value; } } else { msgBuilder.Append($"MANIFEST_CUT_DATE org={task.MANIFEST_CUT_DATE} tar=null##"); task.MANIFEST_CUT_DATE = null; } //CY_CUTOFF_TIME if (BCReadInfo.CYCutoffTime.HasValue) { if (!task.MANIFEST_CUT_DATE.HasValue || task.MANIFEST_CUT_DATE.Value != BCReadInfo.CYCutoffTime.Value) { msgBuilder.Append($"CY_CUTOFF_TIME org={task.CY_CUTOFF_TIME} tar={BCReadInfo.CYCutoffTime.Value}##"); task.CY_CUTOFF_TIME = BCReadInfo.CYCutoffTime.Value; } } else { msgBuilder.Append($"CY_CUTOFF_TIME org={task.CY_CUTOFF_TIME} tar=null##"); task.CY_CUTOFF_TIME = null; } //MDGF_CUT_DATE if (BCReadInfo.MDGFCutDate.HasValue) { if (!task.MDGF_CUT_DATE.HasValue || task.MDGF_CUT_DATE.Value != BCReadInfo.MDGFCutDate.Value) { msgBuilder.Append($"MDGF_CUT_DATE org={task.MDGF_CUT_DATE} tar={BCReadInfo.MDGFCutDate.Value}##"); task.MDGF_CUT_DATE = BCReadInfo.MDGFCutDate.Value; } } else { msgBuilder.Append($"MDGF_CUT_DATE org={task.MDGF_CUT_DATE} tar=null##"); task.MDGF_CUT_DATE = null; } //CLOSING_DATE if (BCReadInfo.ClosingDate.HasValue) { if (!task.CLOSING_DATE.HasValue || task.CLOSING_DATE.Value != BCReadInfo.ClosingDate.Value) { msgBuilder.Append($"CLOSING_DATE org={task.CLOSING_DATE} tar={BCReadInfo.ClosingDate.Value}##"); task.CLOSING_DATE = BCReadInfo.ClosingDate.Value; } } else { msgBuilder.Append($"CLOSING_DATE org={task.CLOSING_DATE} tar=null##"); task.CLOSING_DATE = null; } //CLOSING_DATE if (BCReadInfo.CustomSICutDate.HasValue) { if (!task.CUSTOM_SI_CUT_DATE.HasValue || task.CUSTOM_SI_CUT_DATE.Value != BCReadInfo.CustomSICutDate.Value) { msgBuilder.Append($"CUSTOM_SI_CUT_DATE org={task.CUSTOM_SI_CUT_DATE} tar={BCReadInfo.CustomSICutDate.Value}##"); task.CUSTOM_SI_CUT_DATE = BCReadInfo.CustomSICutDate.Value; } } else { msgBuilder.Append($"CUSTOM_SI_CUT_DATE org={task.CUSTOM_SI_CUT_DATE} tar=null##"); task.CUSTOM_SI_CUT_DATE = null; } _db.Updateable(task).UpdateColumns(it => new { it.SI_CUT_DATE, it.CUSTOM_SI_CUT_DATE, it.VGM_CUTOFF_TIME, it.MANIFEST_CUT_DATE, it.CY_CUTOFF_TIME, it.MDGF_CUT_DATE, it.CLOSING_DATE }).ExecuteCommand(); } _logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 识别完文件 有变更 结果={msgBuilder.ToString()}"); } } else if (task.BUSI_TYPE == "BookingAmendment") { var fileInfo = _db.Queryable().Where(a => a.TASK_PKID == task.TASK_ID && a.FILE_CATEGORY == "BC_MODIFY").First(); if (fileInfo != null) { string bcFileFullPath = $"D:\\djy\\backend\\wwwroot\\{fileInfo.FILE_PATH}"; var bcFileName = Path.GetFileName(bcFileFullPath); if (!File.Exists(bcFileFullPath)) { _logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 取到文件不存在 path={bcFileFullPath}"); continue; } TaskBCInfoReadDto BCReadInfo = GetBCReaderInfo(bcFileFullPath, bcFileName, task.TenantId.Value, task.TASK_ID, amendReadUrl).GetAwaiter().GetResult(); StringBuilder msgBuilder = new StringBuilder(); if (BCReadInfo != null) { //SI_CUT_DATE if (BCReadInfo.SICutDate.HasValue) { if (!task.SI_CUT_DATE.HasValue || task.SI_CUT_DATE.Value != BCReadInfo.SICutDate.Value) { msgBuilder.Append($"SI_CUT_DATE org={task.SI_CUT_DATE} tar={BCReadInfo.SICutDate.Value}##"); task.SI_CUT_DATE = BCReadInfo.SICutDate.Value; } } else { msgBuilder.Append($"SI_CUT_DATE org={task.SI_CUT_DATE} tar=null"); task.SI_CUT_DATE = null; } //VGM_CUTOFF_TIME if (BCReadInfo.VGMCutoffTime.HasValue) { if (!task.VGM_CUTOFF_TIME.HasValue || task.VGM_CUTOFF_TIME.Value != BCReadInfo.VGMCutoffTime.Value) { msgBuilder.Append($"VGM_CUTOFF_TIME org={task.VGM_CUTOFF_TIME} tar={BCReadInfo.VGMCutoffTime.Value}##"); task.VGM_CUTOFF_TIME = BCReadInfo.VGMCutoffTime.Value; } } else { msgBuilder.Append($"VGM_CUTOFF_TIME org={task.VGM_CUTOFF_TIME} tar=null##"); task.VGM_CUTOFF_TIME = null; } //MANIFEST_CUT_DATE if (BCReadInfo.ManifestCutDate.HasValue) { if (!task.MANIFEST_CUT_DATE.HasValue || task.MANIFEST_CUT_DATE.Value != BCReadInfo.ManifestCutDate.Value) { msgBuilder.Append($"MANIFEST_CUT_DATE org={task.MANIFEST_CUT_DATE} tar={BCReadInfo.ManifestCutDate.Value}##"); task.MANIFEST_CUT_DATE = BCReadInfo.ManifestCutDate.Value; } } else { msgBuilder.Append($"MANIFEST_CUT_DATE org={task.MANIFEST_CUT_DATE} tar=null##"); task.MANIFEST_CUT_DATE = null; } //CY_CUTOFF_TIME if (BCReadInfo.CYCutoffTime.HasValue) { if (!task.MANIFEST_CUT_DATE.HasValue || task.MANIFEST_CUT_DATE.Value != BCReadInfo.CYCutoffTime.Value) { msgBuilder.Append($"CY_CUTOFF_TIME org={task.CY_CUTOFF_TIME} tar={BCReadInfo.CYCutoffTime.Value}##"); task.CY_CUTOFF_TIME = BCReadInfo.CYCutoffTime.Value; } } else { msgBuilder.Append($"CY_CUTOFF_TIME org={task.CY_CUTOFF_TIME} tar=null##"); task.CY_CUTOFF_TIME = null; } //MDGF_CUT_DATE if (BCReadInfo.MDGFCutDate.HasValue) { if (!task.MDGF_CUT_DATE.HasValue || task.MDGF_CUT_DATE.Value != BCReadInfo.MDGFCutDate.Value) { msgBuilder.Append($"MDGF_CUT_DATE org={task.MDGF_CUT_DATE} tar={BCReadInfo.MDGFCutDate.Value}##"); task.MDGF_CUT_DATE = BCReadInfo.MDGFCutDate.Value; } } else { msgBuilder.Append($"MDGF_CUT_DATE org={task.MDGF_CUT_DATE} tar=null##"); task.MDGF_CUT_DATE = null; } //CLOSING_DATE if (BCReadInfo.ClosingDate.HasValue) { if (!task.CLOSING_DATE.HasValue || task.CLOSING_DATE.Value != BCReadInfo.ClosingDate.Value) { msgBuilder.Append($"CLOSING_DATE org={task.CLOSING_DATE} tar={BCReadInfo.ClosingDate.Value}##"); task.CLOSING_DATE = BCReadInfo.ClosingDate.Value; } } else { msgBuilder.Append($"CLOSING_DATE org={task.CLOSING_DATE} tar=null##"); task.CLOSING_DATE = null; } //CLOSING_DATE if (BCReadInfo.CustomSICutDate.HasValue) { if (!task.CUSTOM_SI_CUT_DATE.HasValue || task.CUSTOM_SI_CUT_DATE.Value != BCReadInfo.CustomSICutDate.Value) { msgBuilder.Append($"CUSTOM_SI_CUT_DATE org={task.CUSTOM_SI_CUT_DATE} tar={BCReadInfo.CustomSICutDate.Value}##"); task.CUSTOM_SI_CUT_DATE = BCReadInfo.CustomSICutDate.Value; } } else { msgBuilder.Append($"CUSTOM_SI_CUT_DATE org={task.CUSTOM_SI_CUT_DATE} tar=null##"); task.CUSTOM_SI_CUT_DATE = null; } _db.Updateable(task).UpdateColumns(it => new { it.SI_CUT_DATE, it.CUSTOM_SI_CUT_DATE, it.VGM_CUTOFF_TIME, it.MANIFEST_CUT_DATE, it.CY_CUTOFF_TIME, it.MDGF_CUT_DATE, it.CLOSING_DATE }).ExecuteCommand(); } _logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 识别完文件 有变更 结果={msgBuilder.ToString()}"); } } Thread.Sleep(500); } } #region 读BC详情详情 /// /// 读BC详情详情 /// /// 文件完整路径 /// 文件名称 /// 所属租户 /// 任务ID /// 请求URL /// private async Task GetBCReaderInfo(string attachFullName, string fileName, long tenantId, string taskPKId, string url) { TaskBCInfoReadDto taskBCInfoReadDto = null; try { DateTime nowDate = DateTime.Now; EmailBCReadMessageInfo messageInfo = new EmailBCReadMessageInfo { Head = new TaskMessageHead { GID = IDGen.NextID().ToString(), MessageType = "BOOKING_AMENDMENT", SenderId = "DJY", SenderName = "新大简云", ReceiverId = "RulesEngine", ReceiverName = "大简云规则引擎", Version = "1.0", RequestDate = nowDate.ToString("yyyy-MM-dd HH:mm:ss"), RequestAction = "ReadFile", }, Main = new EmailBCReadMessageMainInfo { TenantId = tenantId > 0 ? tenantId.ToString() : "" } }; NameValueCollection par = new NameValueCollection(); par.Add("jsonData", JSON.Serialize(messageInfo)); //解析BookingAmendment var compareRlt = await ExcuteReadFile(par, url, new { file = "file", fileName = fileName, fileBytes = File.ReadAllBytes(attachFullName) }); _logger.LogInformation($"读取BC附件详情 taskPKId={taskPKId},compareRlt={JSON.Serialize(compareRlt)}"); if (compareRlt.succ) { taskBCInfoReadDto = JSON.Deserialize(JSON.Serialize(compareRlt.extra)); } } catch (Exception ex) { _logger.LogError($"读取BC附件详情异常,原因:{ex.Message}"); } return taskBCInfoReadDto; } #endregion #region 请求BookingAmendment解析 /// /// 请求BookingAmendment解析 /// /// 请求参数 /// 请求url /// 文件 /// 请求类型 /// 返回回执 [NonAction] private async Task ExcuteReadFile(NameValueCollection nameValueCollection, string url, dynamic fileInfo, string contentType = "application/json") { ParserReaderExcuteResultDto model = null; var result = string.Empty; using (var httpClient = new HttpClient()) { try { using (var reduceAttach = new MultipartFormDataContent()) { string[] allKeys = nameValueCollection.AllKeys; foreach (string key in allKeys) { var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(nameValueCollection[key])); dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue($"form-data") { Name = key }; reduceAttach.Add(dataContent); } #region 文件参数 if (fileInfo != null) { var Content = new ByteArrayContent(fileInfo.fileBytes); //Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") //{ // Name = fileInfo.file.ToString(), // FileName = fileInfo.fileName.ToString(), //}; Content.Headers.Add("Content-Type", contentType); reduceAttach.Add(Content, fileInfo.file.ToString(), HttpUtility.UrlEncode(fileInfo.fileName.ToString())); } #endregion //httpClient.DefaultRequestHeaders.Add("USER_KEY", App.Configuration["ApiUserKey"]); //httpClient.DefaultRequestHeaders.Add("USER_SECRET", App.Configuration["ApiUserSecret"]); //请求 var response = httpClient.PostAsync(url, reduceAttach).Result; result = response.Content.ReadAsStringAsync().Result; model = JSON.Deserialize(result); } } catch (Exception ex) { _logger.LogInformation("请求读取BC附件详情读取详情异常,原因:{error}", ex.Message); throw Oops.Oh($"请求读取BC附件详情读取详情异常,原因:{ex.Message}"); } } return model; } #endregion public class EmailBCReadMessageInfo { /// /// 表头 /// public TaskMessageHead Head { get; set; } /// /// 表体 /// public EmailBCReadMessageMainInfo Main { get; set; } } public class EmailBCReadMessageMainInfo { /// /// 所属租户ID /// public string TenantId { get; set; } } public class TaskMessageHead : WebAPIHeadBase { } public class WebAPIHeadBase { /// /// 报文惟一主键 /// /// 08dab66c-96a1-4f90-8606-2626e06202ad [Required(ErrorMessage = "必填")] public string GID { get; set; } /// /// 报文类型 BUSI_RULE-业务规则校验 /// /// BUSI_RULE [Required(ErrorMessage = "必填")] public string MessageType { get; set; } /// /// 发送方代码 /// /// CUSTOMER1 [Required(ErrorMessage = "必填")] public string SenderId { get; set; } /// /// 发送方名称 /// /// 企业A [Required(ErrorMessage = "必填")] public string SenderName { get; set; } /// /// 接收方代码 /// /// RulesEngine [Required(ErrorMessage = "必填")] public string ReceiverId { get; set; } /// /// 接收方名称 /// /// 大简云规则引擎 [Required(ErrorMessage = "必填")] public string ReceiverName { get; set; } /// /// 请求方登录TOKEN(可以是真实的登录人TOKEN或者是服务模拟登录人TOKEN) /// /// eyJhbGciOiJSUzI1NiIsImtpZCI6IkQ1RTkxMDI5OUU0RURFNUZEM0EwNTJBMEFDRDUzMUQzIiwidHlwIjoiYXQrand0In0 public string Token { get; set; } /// /// 版本号 默认1.0 /// /// 1.0 [Required(ErrorMessage = "必填")] public string Version { get; set; } = "1.0"; /// /// 请求时间 /// /// 2022-10-10 10:00:00 public string RequestDate { get; set; } /// /// 请求操作类型 /// /// Add [Required(ErrorMessage = "必填")] public string RequestAction { get; set; } = "Add"; } } public class ParserReaderExcuteResultDto { /// /// 是否成功 true=成功 false=失败 /// public bool succ { get; set; } = false; /// /// 状态 0-成功 /// public int status { get; set; } = 0; /// /// 返回消息 /// public string msg { get; set; } /// /// 总记录数 /// public int total { get; set; } /// /// 当前页列表数据 /// public object rows { get; set; } /// /// 合计信息 /// public object summary { get; set; } /// /// 扩展信息 /// public object extra { get; set; } /// /// 扩展信息2 /// public object extra2 { get; set; } /// /// 扩展信息场站统计 /// public object yardStatInfo { get; set; } /// /// 是否异常 /// public bool exceptionflag { get; set; } /// /// 生成HTML /// public string ResultHtml { get; set; } } /// /// /// public class TaskBCInfoReadDto { /// /// 订舱单位 /// public string BookingParty { get; set; } /// /// 发货人 /// public string Shipper { get; set; } /// /// 收货人 /// public string Consignee { get; set; } /// /// 通知人 /// public string NotifyParty { get; set; } /// /// BC更新次数 /// public Nullable BCModifyTimes { get; set; } /// /// BC更新时间 /// public Nullable BCModifyDate { get; set; } /// /// 主单号 /// public string MBLNo { get; set; } /// /// 船名 /// public string Vessel { get; set; } /// /// 航次 /// public string VoyNo { get; set; } /// /// 船公司 /// public string Carrier { get; set; } /// /// 收货地 /// public string PlaceReceipt { get; set; } /// /// 装货港 /// public string Portload { 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 PODETA { get; set; } /// /// 截单时间 /// public Nullable CutSingleTime { get; set; } /// /// 卸货港 /// public string PortDischarge { get; set; } /// /// 交货地 /// public string PlaceDelivery { get; set; } /// /// 装运方式 /// public string ShippingMethod { get; set; } /// /// 运输条款 /// public string Service { get; set; } /// /// 港前运输形态 /// public string PreTransMode { get; set; } /// /// 品名 /// public string Description { get; set; } /// /// 签单地点 /// public string IssuePlace { get; set; } /// /// 集港码头 /// public string CollectionTerminal { get; set; } /// /// 约号 /// public string ContractNo { get; set; } /// /// 预付地点 /// public string PrepardAT { get; set; } /// /// 船代 /// public string ShipAgent { get; set; } /// /// 场站 /// public string Yard { get; set; } /// /// 场站联系人 /// public string YardContactUserName { get; set; } /// /// 场站联系电话 /// public string YardContactTel { get; set; } /// /// 一代客服姓名 /// public string FstCustomerSerUserName { get; set; } /// /// 一代客服电话 /// public string FstCustomerSerUserTel { get; set; } /// /// 一代客服邮箱 /// public string FstCustomerSerUserEmail { get; set; } /// /// 备注1 /// public string Remark1 { get; set; } /// /// 截港时间 /// public Nullable CYCutoffTime { get; set; } /// /// 状态 TEMP-暂存 SUCC-已对应 ERROR-异常 /// public string Status { get; set; } /// /// 文件MD5 /// public string FileMD5 { get; set; } /// /// 最后对应时间,最后关联到订舱日期 /// public Nullable LastToBookingDate { get; set; } /// /// 来源邮箱 /// public string FromEmail { get; set; } /// /// 接收邮箱 /// public string RecvEmail { get; set; } /// /// 订舱ID,对应成功后,订舱ID写入 /// public Nullable BookingOrderId { get; set; } /// /// 集装箱列表 /// public List CtnList { get; set; } /// /// 顺序号 /// public int Indx { get; set; } /// /// 对应订舱序号 /// public int BKOrderIndx { get; set; } /// /// 舱位主键 /// public Nullable BookingSlotId { get; set; } /// /// 船公司代号 /// public string CarrierId { get; set; } /// /// 航线代码(船公司) /// public string LaneCode { get; set; } /// /// 航线名称(船公司) /// public string LaneName { get; set; } /// /// 承运方式 DIRECT_SHIP-直达;TRANSFER_SHIP-中转 /// public string CarriageType { get; set; } /// /// 承运方式名称 DIRECT_SHIP-直达;TRANSFER_SHIP-中转 /// public string CarriageTypeName { get; set; } /// /// 订舱方式 CONTRACT_ORDER-合约订舱;SPOT_ORDER-SPOT订舱 /// public string BookingSlotType { get; set; } /// /// 订舱方式名称 CONTRACT_ORDER-合约订舱;SPOT_ORDER-SPOT订舱 /// public string BookingSlotTypeName { get; set; } /// /// 箱型箱量 /// public string CtnStat { get; set; } /// /// 所在周数 /// public string WeekAt { get; set; } /// /// 箱使天数 /// public int DetensionFreeDays { get; set; } /// /// 样单截止日期 /// public Nullable SICutDate { get; set; } /// /// 舱单截止时间 /// public Nullable ManifestCutDate { get; set; } /// /// MDGF提交截止时间 /// public Nullable MDGFCutDate { get; set; } /// /// 中转港1 /// public string TransferPort1 { get; set; } /// /// 中转港2 /// public string TransferPort2 { get; set; } /// /// 二程船名 /// public string SecondVessel { get; set; } /// /// 二程航次 /// public string SecondVoyno { get; set; } /// /// 二程ETD /// public Nullable SecondETD { get; set; } /// /// 二程ETA /// public Nullable SecondETA { get; set; } /// /// 订舱确认时间 /// public Nullable BookingConfirmDate { get; set; } /// /// 客户样单截止日期 /// public Nullable CustomSICutDate { get; set; } } /// /// 任务BC集装箱 /// public class TaskBCInfoReadCtnDto { /// /// 箱型代码 /// public string CtnCode { get; set; } /// /// 箱型 /// public string CtnALL { get; set; } /// /// 箱量 /// public Nullable CTNNUM { get; set; } /// /// 件数 /// public Nullable PKGS { get; set; } /// /// 尺码 /// public Nullable CBM { get; set; } /// /// 毛重 /// public Nullable KGS { get; set; } /// /// 皮重 /// public Nullable TareWeight { get; set; } /// /// 危品票标示 /// public string IODGT { get; set; } /// /// 特殊装载需求 /// public string SpecialLoadingRequire { get; set; } /// /// 提箱场站 /// public string TakeCTNYard { get; set; } /// /// 提箱时间 /// public Nullable TakeCTNTime { get; set; } /// /// 还箱场站 /// public string ReturnCTNYard { get; set; } }