LadingTrackingService.cs 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. using System.Threading.Tasks;
  2. using XYY.Core.Standard.AliYun;
  3. using XYY.Core.Standard.ExcelHelper.MSExcelHelper;
  4. using XYY.TaskTrack.Standard.TaskModel;
  5. using System.Linq;
  6. using System.Collections.Generic;
  7. using XYY.Data.Standard.First;
  8. using XYY.TaskTrack.Standard;
  9. using System;
  10. using XYY.Core.Standard.Data.Infrastructure;
  11. using XYY.Model.Standard.Task;
  12. using XYY.Data.Standard.Tasks;
  13. using XYY.Data.Standard.Order;
  14. using Dapper;
  15. using XYY.Data.Model.Standard.Tracking;
  16. using XYY.Service.Standard.First.Model;
  17. using XYY.Model.Standard.First;
  18. using RestSharp;
  19. using Newtonsoft.Json;
  20. using Newtonsoft.Json.Linq;
  21. using XYY.Service.Standard.First.DB;
  22. using XYY.Common.Standard;
  23. using System.Diagnostics;
  24. using XYY.Service.Standard.First.Mapping;
  25. using System.Threading;
  26. using XYY.Service.Standard.First.Mail;
  27. namespace XYY.Service.Standard.First
  28. {
  29. public class LadingTrackingService : ILadingTrackingService
  30. {
  31. private IAliYunPostFileSerivce _aliYunPostFileSerivce;
  32. private IExcelHelper _excelHelper;
  33. private ILogistics_LadingBillRepository _logistics_LadingBillRepository;
  34. private ITaskTrackDataRepository _taskTrackData;
  35. private IOrderRepository _orderRepository;
  36. private IUnitOfWork _unitOfWork;
  37. private IMQManager _MQManager;
  38. private IFirstDB _firstDB;
  39. private IOrderMailService _orderMailService;
  40. public LadingTrackingService(IExcelHelper excelHelper,
  41. IAliYunPostFileSerivce aliYunPostFileSerivce,
  42. ILogistics_LadingBillRepository logistics_LadingBillRepository,
  43. ITaskTrackDataRepository taskTrackData,
  44. IMQManager MQManager,
  45. IOrderRepository orderRepository,
  46. IUnitOfWork unitOfWork,
  47. IFirstDB firstDB,
  48. IOrderMailService orderMailService)
  49. {
  50. _excelHelper = excelHelper;
  51. _aliYunPostFileSerivce = aliYunPostFileSerivce;
  52. _logistics_LadingBillRepository = logistics_LadingBillRepository;
  53. _taskTrackData = taskTrackData;
  54. _MQManager = MQManager;
  55. _orderRepository = orderRepository;
  56. _unitOfWork = unitOfWork;
  57. _firstDB = firstDB;
  58. _orderMailService = orderMailService;
  59. }
  60. /// <summary>
  61. /// 添加批量上传的任务
  62. /// </summary>
  63. /// <param name="fileUrl"></param>
  64. /// <returns></returns>
  65. public async Task<BatchJobResult> AddBatchJob(System.IO.Stream formFile)
  66. {
  67. BatchJobResult batchJobResult = new BatchJobResult();
  68. var list = _excelHelper.LoadDataAsStream<BatchMapping, Job_LadingBillLogisticsItem>(formFile);
  69. list = list.Where(x => !string.IsNullOrEmpty(x.LadingBillNumber)).ToList();
  70. var ladingBillNumbers = list.Select(x => x.LadingBillNumber).ToArray();
  71. list =
  72. list.GroupBy(x => x.LadingBillNumber).Select(x =>
  73. x.OrderByDescending(y => y.DepartTime).ThenByDescending(y => y.ClearanceTime).ThenByDescending(y => y.ArrivalTime)
  74. .First()).ToList();
  75. var waitLaddingBills = await _logistics_LadingBillRepository.QueryBill(ladingBillNumbers);
  76. var notFinds = ladingBillNumbers.Where(x => !waitLaddingBills.Any(y => y.LadingBillNumber.Trim() == x)).Select(x => new Job_LadingBillLogisticsItem { LadingBillNumber = x }).ToList();
  77. if (notFinds.Count > 0)
  78. {
  79. //未找到的提单号,生成一个Excel文件返回
  80. string url = _excelHelper.OutData<NotFindMapping, Job_LadingBillLogisticsItem>(notFinds);
  81. batchJobResult.ErrorFileUrl = url;
  82. }
  83. //提前循环,判断起飞和到达时间
  84. foreach (var i in list)
  85. {
  86. var tempWaitBills = waitLaddingBills.Where(x => x.LadingBillNumber == i.LadingBillNumber && x.IsDeleted == false).FirstOrDefault();
  87. if (tempWaitBills == null) { continue; }
  88. //始终更新创建时间
  89. i.CreateTime = tempWaitBills.CreateTime.Value;
  90. //赋值轨迹抓取的数据
  91. if (tempWaitBills.DepartTime.HasValue && !string.IsNullOrEmpty(tempWaitBills.DepartRemark) && tempWaitBills.DepartRemark.Contains("轨迹抓取更新"))
  92. {
  93. i.DepartTime = tempWaitBills.DepartTime;
  94. }
  95. if (tempWaitBills.ArrivalTime.HasValue && !string.IsNullOrEmpty(tempWaitBills.ArrivalRemark) && tempWaitBills.ArrivalRemark.Contains("轨迹抓取更新"))
  96. {
  97. i.ArrivalTime = tempWaitBills.ArrivalTime;
  98. }
  99. //如果清关时间和起飞时间一样的话,起飞轨迹会比清关轨迹排在前边,导致轨迹顺序混乱,
  100. //所以要加100毫秒。加100毫秒的目的保证正确排序,但两者时分秒显示能保持一致
  101. if (i.ClearanceTime.HasValue && i.DepartTime.HasValue && i.ClearanceTime.Value == i.DepartTime.Value)
  102. {
  103. i.ClearanceTime = i.ClearanceTime.Value.AddMilliseconds(100);
  104. }
  105. }
  106. list = list.Where(x => waitLaddingBills.Any(y => y.LadingBillNumber == x.LadingBillNumber && (
  107. x.CustomsClearanceTime != y.CustomsClearanceTime ||
  108. x.ArrivalTime != y.ArrivalTime
  109. || x.ClearanceTime != y.ClearanceTime
  110. || x.DepartTime != y.DepartTime
  111. || x.LeaveWarehouseTime != y.LeaveWarehouseTime
  112. || x.TrafficTime != y.TrafficTime))).ToList();
  113. List<Job_LadingBillLogisticsItem> list2 = new List<Job_LadingBillLogisticsItem>();
  114. //判断是否是补数据
  115. foreach (var f in list)
  116. {
  117. var item = waitLaddingBills.Where(x => x.LadingBillNumber == f.LadingBillNumber).FirstOrDefault();
  118. //系统存在提单
  119. //if (
  120. // (!item.ArrivalTime.HasValue && f.ArrivalTime.HasValue && f.ArrivalTime < DateTime.Now) ||
  121. // (!item.ClearanceTime.HasValue && f.ClearanceTime.HasValue && f.ClearanceTime < DateTime.Now) ||
  122. // (!item.DepartTime.HasValue && f.DepartTime.HasValue && f.DepartTime.Value < DateTime.Now) ||
  123. // (!item.TrafficTime.HasValue && f.TrafficTime.HasValue && f.TrafficTime.Value < DateTime.Now)
  124. // )
  125. //{
  126. bool isAdd = false;
  127. //增加更新节点判断
  128. if (!item.ArrivalTime.HasValue && f.ArrivalTime.HasValue && f.ArrivalTime < DateTime.Now) { f.updatedNode.Add("ArrivalTime"); isAdd = true; }
  129. if (!item.ClearanceTime.HasValue && f.ClearanceTime.HasValue && f.ClearanceTime < DateTime.Now) { f.updatedNode.Add("ClearanceTime"); isAdd = true; }
  130. if (!item.DepartTime.HasValue && f.DepartTime.HasValue && f.DepartTime.Value < DateTime.Now) { f.updatedNode.Add("DepartTime"); isAdd = true; }
  131. if (!item.TrafficTime.HasValue && f.TrafficTime.HasValue && f.TrafficTime.Value < DateTime.Now) { f.updatedNode.Add("TrafficTime"); isAdd = true; }
  132. //如果提单时间离港小于当前时间,我们不再推送
  133. if (isAdd) { list2.Add(f); }
  134. //}
  135. }
  136. //校验数据时间,只校验需要补的数据
  137. var verify = await LadingTimeVerify(waitLaddingBills, list);
  138. if (!verify.Item1) { return verify.Item2; }
  139. //邮件数据记录
  140. await _orderMailService.AddClearanceMail(list);
  141. //待上传列表
  142. TaskTrackModel taskTrackModel = new TaskTrackModel()
  143. {
  144. WaitQty = list.Count,
  145. Name = "batchTrace" + Guid.NewGuid().ToString(),
  146. Summary = list.Count
  147. };
  148. batchJobResult.JobId = taskTrackModel.Name;
  149. await _taskTrackData.InitTaskTrack(taskTrackModel);
  150. //内部数据更新
  151. await _MQManager.Publish(new Job_LadingBillLogistics { Jobs = list });
  152. //通知第三方Api数据更新
  153. await _MQManager.Publish(new Job_Customer_FristLog { Jobs = list2 });
  154. return batchJobResult;
  155. }
  156. public async Task<Tuple<bool, BatchJobResult>> LadingTimeVerify(List<Logistics_LadingBill> waitLaddingBills, List<Job_LadingBillLogisticsItem> jobs)
  157. {
  158. List<LadingTimeError> error = new List<LadingTimeError>();
  159. foreach (var item in jobs)
  160. {
  161. var tempWaitBills = waitLaddingBills.Where(x => x.LadingBillNumber == item.LadingBillNumber).FirstOrDefault();
  162. if (item.CustomsClearanceTime.HasValue && item.CustomsClearanceTime < tempWaitBills.CreateTime)
  163. {
  164. error.Add(new LadingTimeError() { LadingBillNumber = item.LadingBillNumber, ErrorMessage = "国内报关时间不应小于提单创建时间" });
  165. }
  166. else if (item.DeliveryTime.HasValue && item.CustomsClearanceTime.HasValue && item.DeliveryTime < item.CustomsClearanceTime)
  167. {
  168. error.Add(new LadingTimeError() { LadingBillNumber = item.LadingBillNumber, ErrorMessage = "交航时间不应小于国内报关时间" });
  169. }
  170. else if (item.DeliveryTime.HasValue && item.DepartTime.HasValue && item.DepartTime < item.DeliveryTime)
  171. {
  172. error.Add(new LadingTimeError() { LadingBillNumber = item.LadingBillNumber, ErrorMessage = "离港时间不应小于交航时间" });
  173. }
  174. else if (item.ArrivalTime.HasValue && item.DepartTime.HasValue && item.ArrivalTime < item.DepartTime)
  175. {
  176. error.Add(new LadingTimeError() { LadingBillNumber = item.LadingBillNumber, ErrorMessage = "到港时间不应小于离港时间" });
  177. }
  178. else if (item.ArrivalTime.HasValue && item.ClearanceTime.HasValue && item.ClearanceTime < item.ArrivalTime)
  179. {
  180. error.Add(new LadingTimeError() { LadingBillNumber = item.LadingBillNumber, ErrorMessage = "清关时间不应小于到港时间" });
  181. }
  182. }
  183. if (error != null && error.Count > 0)
  184. {
  185. BatchJobResult batchJobResult = new BatchJobResult();
  186. string url = _excelHelper.OutData<TimeErrorMapping, LadingTimeError>(error);
  187. batchJobResult.ErrorFileUrl = url;
  188. return Tuple.Create(false, batchJobResult);
  189. }
  190. else
  191. {
  192. return Tuple.Create(true, new BatchJobResult());
  193. }
  194. }
  195. public async Task TestPublic()
  196. {
  197. await _MQManager.Publish(new Job_Customer_FristLog
  198. {
  199. Jobs = new List<Job_LadingBillLogisticsItem>{new Job_LadingBillLogisticsItem{
  200. LadingBillNumber="test111",
  201. ClearanceTime =DateTime.Parse("2021-08-19 14:22:09"),
  202. ArrivalTime=DateTime.Now,
  203. DepartTime=DateTime.Now
  204. } }
  205. });
  206. }
  207. public async Task TestSendLog(Frist_Log fristLog)
  208. {
  209. await _MQManager.Publish(fristLog);
  210. }
  211. public async Task TrackSupplement(TrackSupplementRequest param)
  212. {
  213. await _MQManager.Publish(param);
  214. }
  215. public async Task SendInitHKXiKeOrders()
  216. {
  217. //上网轨迹
  218. string sql = @" select a.CustomerOrderNo from order_order(nolock)a join Logistics_Trace(nolock)b on a.TrackingNumber = b.TrackingNumber
  219. where a.CustomerId = 691 and b.OnlineTime is not null";
  220. var orders = await _orderRepository.QueryBySqlAsync(sql);
  221. var log = new Frist_Log
  222. {
  223. Groups = new List<Data.Model.Standard.Tracking.Logistics_TraceGroup>()
  224. };
  225. foreach (var order in orders)
  226. {
  227. var group = new Data.Model.Standard.Tracking.Logistics_TraceGroup
  228. {
  229. CustomerOrderNo = order.CustomerOrderNo,
  230. List = new List<Data.Model.Standard.Tracking.EsLogisticsTrackingLog>
  231. {
  232. }
  233. };
  234. log.Groups.Add(group);
  235. if (order.ReceiveTime.HasValue)
  236. {
  237. group.List.Add(new Data.Model.Standard.Tracking.EsLogisticsTrackingLog
  238. {
  239. TriggerTime = order.ReceiveTime.Value,
  240. Location = "guangzhou",
  241. Status = 8,
  242. StatusString = "Item inbound in sorting center."
  243. });
  244. }
  245. }
  246. //XiKeApi xiKeApi = new XiKeApi();
  247. //var erros = await xiKeApi.Send(log.Groups);
  248. //await AddErrors(erros, "称重");
  249. //装箱数据
  250. //foreach (var order in orders)
  251. //{
  252. // var group = new Data.Model.Standard.Tracking.Logistics_TraceGroup
  253. // {
  254. // CustomerOrderNo = order.CustomerOrderNo,
  255. // List = new List<Data.Model.Standard.Tracking.EsLogisticsTrackingLog>
  256. // {
  257. // }
  258. // };
  259. // log.Groups.Add(group);
  260. // if (order.ReceiveTime.HasValue)
  261. // {
  262. // group.List.Add(new Data.Model.Standard.Tracking.EsLogisticsTrackingLog
  263. // {
  264. // TriggerTime = order.ReceiveTime.Value,
  265. // Location = "guangzhou",
  266. // Status = 2,
  267. // StatusString = "Item inbound in sorting center."
  268. // });
  269. // }
  270. // if (order.SendOutTime.HasValue)
  271. // {
  272. // group.List.Add(new Data.Model.Standard.Tracking.EsLogisticsTrackingLog
  273. // {
  274. // TriggerTime = order.SendOutTime.Value,
  275. // Location = "guangzhou",
  276. // Status = 3,
  277. // StatusString = "Item outbound in sorting center."
  278. // });
  279. // }
  280. //}
  281. //头程推送、称重、装箱
  282. //string sql = @"select * from order_order(nolock) where customerid = 691 and orderStatus>1";
  283. //var orders = await _orderRepository.QueryBySqlAsync(sql);
  284. //var log = new Frist_Log
  285. //{
  286. // Groups = new List<Data.Model.Standard.Tracking.Logistics_TraceGroup>()
  287. //};
  288. ////装箱数据
  289. //foreach (var order in orders)
  290. //{
  291. // var group = new Data.Model.Standard.Tracking.Logistics_TraceGroup
  292. // {
  293. // CustomerOrderNo = order.CustomerOrderNo,
  294. // List = new List<Data.Model.Standard.Tracking.EsLogisticsTrackingLog>
  295. // {
  296. // }
  297. // };
  298. // log.Groups.Add(group);
  299. // if (order.ReceiveTime.HasValue)
  300. // {
  301. // group.List.Add(new Data.Model.Standard.Tracking.EsLogisticsTrackingLog
  302. // {
  303. // TriggerTime = order.ReceiveTime.Value,
  304. // Location = "guangzhou",
  305. // Status = 2,
  306. // StatusString = "Item inbound in sorting center."
  307. // });
  308. // }
  309. // if (order.SendOutTime.HasValue)
  310. // {
  311. // group.List.Add(new Data.Model.Standard.Tracking.EsLogisticsTrackingLog
  312. // {
  313. // TriggerTime = order.SendOutTime.Value,
  314. // Location = "guangzhou",
  315. // Status = 3,
  316. // StatusString = "Item outbound in sorting center."
  317. // });
  318. // }
  319. //}
  320. //XiKeApi xiKeApi = new XiKeApi();
  321. //var erros = await xiKeApi.Send(log.Groups);
  322. //await AddErrors(erros, "称重");
  323. ////头程轨迹
  324. //string fristSql = @"select c.LadingBillNumber,a.TrackingNumber,a.Id,a.ReceiverCountryCode,d.DepartTime,d.ArrivalTime,d.ClearanceTime,a.CustomerOrderNo from Order_Order(nolock) a
  325. // join Logistics_Boxdetail(nolock) b on a.id = b.orderid join logistics_box(nolock) c on b.boxid=c.id
  326. // join Logistics_LadingBill(nolock) d on d.LadingBillNumber = c.LadingBillNumber
  327. // where d.IsDeleted=0
  328. // and (a.CustomerId = 691)";
  329. //List<dynamic> firstTrackings = new List<dynamic>();
  330. //using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(_unitOfWork.ConnectionAddress))
  331. //{
  332. // connection.Open();
  333. // firstTrackings = (await connection.QueryAsync<dynamic>(fristSql, null, null, null, null)).ToList();
  334. //}
  335. //var groups = firstTrackings.GroupBy(x => new Job_LadingBillLogisticsItem
  336. //{
  337. // LadingBillNumber = x.LadingBillNumber,
  338. // ArrivalTime = x.ArrivalTime,
  339. // DepartTime = x.DepartTime,
  340. // ClearanceTime = x.ClearanceTime
  341. //});
  342. //foreach (var ladingBillNumber
  343. // in groups)
  344. //{
  345. // if (ladingBillNumber.ToList().Count > 0)
  346. // {
  347. // var logs =
  348. // JobSubscribe.JobSubscribe.GetLogs2(ladingBillNumber.ToList(), ladingBillNumber.Key);
  349. // xiKeApi = new XiKeApi();
  350. // erros = await xiKeApi.Send(logs);
  351. // await AddErrors(erros, "头程");
  352. // }
  353. //}
  354. }
  355. public async Task AddErrors(List<Logistics_TraceGroup> erros, string target)
  356. {
  357. if (erros.Count > 0)
  358. {
  359. Frist_Log log = new Frist_Log();
  360. log.Groups = erros;
  361. //持久化
  362. await _unitOfWork.InsertAsync<ErroJobLog>(new ErroJobLog
  363. {
  364. ActionUrl = "http://120.24.149.148:9520/api/BatchTracking/TestSendLog",
  365. IsExecute = true,
  366. Request = Newtonsoft.Json.JsonConvert.SerializeObject(log),
  367. Target = target,
  368. CreateTime = DateTime.Now
  369. });
  370. }
  371. }
  372. #region 对接51Track 航空订单
  373. public async Task<List<Lading51TrackResult>> Lading51TrackService(List<string> ladingNumber, bool IsTest = false)
  374. {
  375. List<Lading51TrackResult> trackResults = new List<Lading51TrackResult>();
  376. List<WaitQueryData> dbData = await GetWaitToQueryTrack(ladingNumber);
  377. if (dbData == null || dbData.Count == 0) { throw new Exception("51Track 航空订单,无提单数据可查询"); }
  378. var groupData = dbData.GroupBy(x => new { x.LadingBillNumber }).ToList();
  379. //取出数据逻辑的条件
  380. List<Lading51TrackRules> rules = await GetLading51TrackRules();
  381. Stopwatch stopWatch = new Stopwatch();
  382. double TotalMilliseconds = 3000;//默认不停,执行过快会重复赋值
  383. //mq数据
  384. List<Job_LadingBillLogisticsItem> list2 = new List<Job_LadingBillLogisticsItem>() { };
  385. foreach (var item in groupData)
  386. {
  387. try
  388. {
  389. if (1000 - TotalMilliseconds > 0)
  390. {
  391. System.Threading.Thread.Sleep(2000 - (int)TotalMilliseconds);
  392. TotalMilliseconds = 0;
  393. }
  394. stopWatch.Start();
  395. var trackResult = await QueryBy51Track(IsTest ? "618-62659726" : item.Key.LadingBillNumber);//用测试提单测,会默认一个提单的轨迹去更
  396. var esModel = await ConvertToEsModel(trackResult, item.ToList(), rules);
  397. if (esModel.Count == 0)
  398. {
  399. TimeSpan ts = stopWatch.Elapsed;
  400. TotalMilliseconds = ts.TotalMilliseconds;
  401. stopWatch.Reset();
  402. continue;
  403. }
  404. var waitUpdate = JsonConvert.DeserializeObject<List<Logistics_TraceGroup>>(JsonConvert.SerializeObject(esModel));
  405. await EsTrackUpdate(waitUpdate);
  406. await ExecuteUpdateLadingTrackTime(trackResult, item.ToList());
  407. //添加mq任务
  408. #region 添加mq任务
  409. var tempLadingInfo = item.FirstOrDefault();
  410. var tempEsInfo = waitUpdate.FirstOrDefault();
  411. //这里只会添加4和5两种轨迹
  412. Job_LadingBillLogisticsItem job = new Job_LadingBillLogisticsItem();
  413. bool isAdd = false;
  414. if (tempEsInfo.List.Any(y => y.Status == 4))
  415. {
  416. //起飞时间
  417. job.LadingBillNumber = tempLadingInfo.LadingBillNumber;
  418. job.DepartTime = tempEsInfo.List.Where(x => x.Status == 4).OrderByDescending(x => x.TriggerTime).FirstOrDefault().TriggerTime;
  419. job.updatedNode.Add("DepartTime"); isAdd = true;
  420. }
  421. if (tempEsInfo.List.Any(y => y.Status == 5))
  422. {
  423. //到达时间
  424. job.LadingBillNumber = tempLadingInfo.LadingBillNumber;
  425. job.ArrivalTime = tempEsInfo.List.Where(x => x.Status == 5).OrderByDescending(x => x.TriggerTime).FirstOrDefault().TriggerTime;
  426. job.updatedNode.Add("ArrivalTime"); isAdd = true;
  427. }
  428. if (isAdd) { list2.Add(job); }
  429. #endregion
  430. //ExecuteSendLogs(esModel, dbData.Where(x => x.CustomerId == 7 || x.CustomerId == 691).ToList());//写死判断,只有细刻需要发送此api
  431. //判断时间
  432. TimeSpan ts1 = stopWatch.Elapsed;
  433. TotalMilliseconds = ts1.TotalMilliseconds;
  434. stopWatch.Reset();
  435. }
  436. catch (Exception ex)
  437. {
  438. trackResults.Add(new Lading51TrackResult() { LadingBillNumber = item.Key.LadingBillNumber, errorMessage = ex.Message });
  439. TimeSpan ts = stopWatch.Elapsed;
  440. TotalMilliseconds = ts.TotalMilliseconds;
  441. stopWatch.Reset();
  442. }
  443. }
  444. if (list2.Count > 0) { await _MQManager.Publish(new Job_Customer_FristLog { Jobs = list2 }); }
  445. return trackResults;
  446. }
  447. public async Task testDez()
  448. {
  449. string json = @"{
  450. ""meta"": {
  451. ""code"": 200,
  452. ""type"": ""Success"",
  453. ""message"": ""Request Success""
  454. },
  455. ""data"": {
  456. ""618-62659726"": {
  457. ""track_number"": ""618-62659726"",
  458. ""return_data"": {
  459. ""status_number"": 4,
  460. ""origin"": ""CAN"",
  461. ""destination"": ""CDG"",
  462. ""piece"": ""36"",
  463. ""weight"": ""628.0"",
  464. ""track_info"": [
  465. {
  466. ""plan_date"": ""2023-06-28 15:36:00"",
  467. ""actual_date"": ""2023-06-28 15:36:00"",
  468. ""event"": ""Shipment Delivered"",
  469. ""station"": ""CDG"",
  470. ""flight_number"": ""-"",
  471. ""status"": ""DLV"",
  472. ""piece"": ""36"",
  473. ""weight"": ""628.0""
  474. },
  475. {
  476. ""plan_date"": ""2023-06-28 11:03:00"",
  477. ""actual_date"": ""2023-06-28 11:03:00"",
  478. ""event"": ""Shipment Ready for Pick-up"",
  479. ""station"": ""CDG"",
  480. ""flight_number"": ""-"",
  481. ""status"": ""NFD"",
  482. ""piece"": ""36"",
  483. ""weight"": ""628.0""
  484. },
  485. {
  486. ""plan_date"": ""2023-06-28 11:03:00"",
  487. ""actual_date"": ""2023-06-28 11:03:00"",
  488. ""event"": ""Shipment Checked Into Warehouse"",
  489. ""station"": ""CDG"",
  490. ""flight_number"": ""SQ0336"",
  491. ""status"": """",
  492. ""piece"": ""36"",
  493. ""weight"": ""628.0""
  494. },
  495. {
  496. ""plan_date"": ""2023-06-28 09:40:00"",
  497. ""actual_date"": ""2023-06-28 09:40:00"",
  498. ""event"": ""Document Delivered"",
  499. ""station"": ""CDG"",
  500. ""flight_number"": ""-"",
  501. ""status"": ""AWD"",
  502. ""piece"": ""36"",
  503. ""weight"": ""628.0""
  504. },
  505. {
  506. ""plan_date"": ""2023-06-28 07:40:00"",
  507. ""actual_date"": ""2023-06-28 07:40:00"",
  508. ""event"": ""Cleared By Customs"",
  509. ""station"": ""CDG"",
  510. ""flight_number"": ""-"",
  511. ""status"": """",
  512. ""piece"": ""36"",
  513. ""weight"": ""-""
  514. },
  515. {
  516. ""plan_date"": ""2023-06-28 07:28:00"",
  517. ""actual_date"": ""2023-06-28 07:28:00"",
  518. ""event"": ""Flight Arrived"",
  519. ""station"": ""CDG"",
  520. ""flight_number"": ""SQ0336"",
  521. ""status"": ""ARR"",
  522. ""piece"": ""36"",
  523. ""weight"": ""628.0""
  524. },
  525. {
  526. ""plan_date"": ""2023-06-28 00:17:00"",
  527. ""actual_date"": ""2023-06-28 00:17:00"",
  528. ""event"": ""Flight Departed"",
  529. ""station"": ""SIN"",
  530. ""flight_number"": ""SQ0336"",
  531. ""status"": ""DEP"",
  532. ""piece"": ""36"",
  533. ""weight"": ""628.0""
  534. },
  535. {
  536. ""plan_date"": ""2023-06-27 12:15:00"",
  537. ""actual_date"": ""2023-06-27 12:15:00"",
  538. ""event"": ""Shipment Checked Into Warehouse"",
  539. ""station"": ""SIN"",
  540. ""flight_number"": ""SQ7821"",
  541. ""status"": """",
  542. ""piece"": ""36"",
  543. ""weight"": ""628.0""
  544. },
  545. {
  546. ""plan_date"": ""2023-06-27 11:55:00"",
  547. ""actual_date"": ""2023-06-27 11:55:00"",
  548. ""event"": ""Flight Arrived"",
  549. ""station"": ""SIN"",
  550. ""flight_number"": ""SQ7821"",
  551. ""status"": ""ARR"",
  552. ""piece"": ""36"",
  553. ""weight"": ""628.0""
  554. },
  555. {
  556. ""plan_date"": ""2023-06-27 05:11:00"",
  557. ""actual_date"": ""2023-06-27 05:11:00"",
  558. ""event"": ""Flight Departed"",
  559. ""station"": ""CAN"",
  560. ""flight_number"": ""SQ7821"",
  561. ""status"": ""DEP"",
  562. ""piece"": ""36"",
  563. ""weight"": ""628.0""
  564. },
  565. {
  566. ""plan_date"": ""2023-06-26 10:40:00"",
  567. ""actual_date"": ""2023-06-26 10:40:00"",
  568. ""event"": ""Freight On Hand"",
  569. ""station"": ""CAN"",
  570. ""flight_number"": ""-"",
  571. ""status"": ""FOH"",
  572. ""piece"": ""36"",
  573. ""weight"": ""628.0""
  574. },
  575. {
  576. ""plan_date"": ""2023-06-26 10:40:00"",
  577. ""actual_date"": ""2023-06-26 10:40:00"",
  578. ""event"": ""Shipment Received"",
  579. ""station"": ""CAN"",
  580. ""flight_number"": ""-"",
  581. ""status"": ""RCF"",
  582. ""piece"": ""36"",
  583. ""weight"": ""628.0""
  584. }
  585. ],
  586. ""flight_info"": {
  587. ""SQ7821"": {
  588. ""depart_station"": ""CAN"",
  589. ""arrival_station"": ""SIN"",
  590. ""plan_depart_time"": ""2023-06-27 05:55:00"",
  591. ""depart_time"": null,
  592. ""plan_arrival_time"": ""2023-06-27 09:50:00"",
  593. ""arrival_time"": null
  594. },
  595. ""SQ0336"": {
  596. ""depart_station"": ""SIN"",
  597. ""arrival_station"": ""CDG"",
  598. ""plan_depart_time"": ""2023-06-28 00:15:00"",
  599. ""depart_time"": null,
  600. ""plan_arrival_time"": ""2023-06-28 07:35:00"",
  601. ""arrival_time"": null
  602. }
  603. },
  604. ""flight_info_new"": [
  605. {
  606. ""plan_arrival_time"": ""2023-06-27 09:50:00"",
  607. ""plan_depart_time"": ""2023-06-27 05:55:00"",
  608. ""depart_station"": ""CAN"",
  609. ""arrival_station"": ""SIN"",
  610. ""flight_number"": ""SQ7821"",
  611. ""status"": ""Confirmed""
  612. },
  613. {
  614. ""plan_arrival_time"": ""2023-06-28 07:35:00"",
  615. ""plan_depart_time"": ""2023-06-28 00:15:00"",
  616. ""depart_station"": ""SIN"",
  617. ""arrival_station"": ""CDG"",
  618. ""flight_number"": ""SQ0336"",
  619. ""status"": ""Confirmed""
  620. }
  621. ],
  622. ""flight_way_station"": [
  623. ""CAN"",
  624. ""SIN"",
  625. ""CDG""
  626. ],
  627. ""last_event"": ""2023-06-28 15:36:00, Shipment Delivered, CDG, -""
  628. },
  629. ""airline_info"": {
  630. ""name"": ""新加坡"",
  631. ""url"": ""http://www.siacargo.com/ccn/ShipmentTrack.aspx"",
  632. ""track_url"": ""http://www.siacargo.com/ccn/ShipmentTrack.aspx"",
  633. ""trackpage_url"": ""https://www.51tracking.com/aircargo/cn/618-62659726""
  634. }
  635. }
  636. }
  637. }";
  638. var data = TrackDeserializeObject("618-62659726", json);
  639. }
  640. #region db数据处理
  641. /// <summary>
  642. /// 获取待查数据
  643. /// 过滤非快线渠道
  644. /// </summary>
  645. /// <param name="ladingNumber"></param>
  646. /// <returns></returns>
  647. private async Task<List<WaitQueryData>> GetWaitToQueryTrack(List<string> ladingNumber)
  648. {
  649. string ladingNumberWhere = string.Empty;
  650. if (ladingNumber != null && ladingNumber.Count > 0) { ladingNumberWhere = " and t.LadingBillNumber in @param "; }
  651. List<string> ladingNumber3 = new List<string>() { "784", "180", "205", "160", "880", "235", "057", "618" };
  652. string sql = @" select t.LadingBillNumber,t.OriginPort,t.Destination,t.ServiceName,b.TrackingNumber,b.OrderId,c.CustomerOrderNo,c.ReceiverCountryCode,c.CustomerId
  653. ,t.DepartTime,t.TrafficTime
  654. from Logistics_LadingBill(nolock) t
  655. left join Logistics_Box(nolock) a on a.LadingBillNumber=t.LadingBillNumber
  656. left join Logistics_BoxDetail(nolock) b on b.BoxId=a.Id
  657. left join Order_Order(nolock) c on c.Id=b.OrderId
  658. where t.CreateTime>='2023-03-01' and t.IsDeleted=0 and ''=ISNULL(t.ArrivalTime,'') and ''!=ISNULL(b.TrackingNumber,'') and ''!=ISNULL(t.ServiceName,'')
  659. and ''!=ISNULL(t.OriginPort,'') and ''!=ISNULL(t.Destination,'') and left(t.LadingBillNumber,3) in @ladingNumber3 " + ladingNumberWhere;
  660. var result = (await _unitOfWork.QueryBySqlAsync<WaitQueryData>(sql, 300, new { ladingNumber3 = ladingNumber3, param = ladingNumber })).ToList();
  661. return result;
  662. }
  663. /// <summary>
  664. /// 更新提单轨迹时间
  665. /// 起飞、到达、
  666. /// </summary>
  667. /// <returns></returns>
  668. private async Task<bool> ExecuteUpdateLadingTrackTime(TrackResult trackResult, List<WaitQueryData> dbData)
  669. {
  670. if (dbData == null || dbData.Count == 0) { return false; }
  671. var prot1 = dbData.FirstOrDefault()?.Destination;
  672. var prot2 = dbData.FirstOrDefault()?.OriginPort;
  673. var track_infos = trackResult.data.ladingInfo.return_data.flight_Infos;
  674. if (track_infos == null || track_infos.Count == 0) { return false; }
  675. var OriginPortTrack = track_infos.Where(x => prot2 == x.depart_station)?.OrderBy(x => Convert.ToDateTime(x.depart_time))?.FirstOrDefault();
  676. var DestinationTrack = track_infos.Where(x => prot1 == x.arrival_station)?.OrderBy(x => Convert.ToDateTime(x.arrival_time))?.FirstOrDefault();
  677. string sql = string.Empty;
  678. if (OriginPortTrack != null && !string.IsNullOrEmpty(OriginPortTrack.depart_time))
  679. {
  680. string updateTrafficTime = string.Empty;
  681. if (!dbData.FirstOrDefault().TrafficTime.HasValue)
  682. {
  683. updateTrafficTime = $",TrafficTime='{Convert.ToDateTime(OriginPortTrack.depart_time).AddHours(-8)}' ";
  684. }
  685. sql = $"update Logistics_LadingBill set DepartTime='{OriginPortTrack.depart_time}',DepartRemark='51轨迹抓取更新,{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}'{updateTrafficTime} where LadingBillNumber='{dbData.FirstOrDefault().LadingBillNumber}' and ISNULL(DepartTime,'')='';";
  686. }
  687. if (DestinationTrack != null && !string.IsNullOrEmpty(DestinationTrack.arrival_time))
  688. {
  689. sql += $"update Logistics_LadingBill set ArrivalTime='{DestinationTrack.arrival_time}',ArrivalRemark='51轨迹抓取更新,{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}' where LadingBillNumber='{dbData.FirstOrDefault().LadingBillNumber}' and ISNULL(ArrivalTime,'')='';";
  690. }
  691. if (!string.IsNullOrEmpty(sql)) { await _unitOfWork.ExecuteAsync(sql); }
  692. return false;
  693. }
  694. private async Task<List<Lading51TrackRules>> GetLading51TrackRules()
  695. {
  696. string sql = " select * from Logistics_Lading51TrackRules ";
  697. var data = await _unitOfWork.QueryBySqlAsync<Lading51TrackRules>(sql);
  698. return data.ToList();
  699. }
  700. #endregion
  701. #region 51API对接
  702. public async Task<TrackResult> QueryBy51Track(string ladingNumber)
  703. {
  704. var client = new RestClient("http://api.51tracking.com");
  705. var request = new RestRequest("/v2/trackings/aircargo", Method.POST);
  706. request.AddHeader("Tracking-Api-Key", "e0febb2a-eef1-45a3-b534-3dda7465fb4e");
  707. request.AddHeader("Content-Type", "application/json");
  708. TrackRequestBody body = new TrackRequestBody() { track_number = ladingNumber };
  709. request.AddJsonBody(body);
  710. var response = await client.ExecuteAsync(request);
  711. if (response.StatusCode == System.Net.HttpStatusCode.OK)
  712. {
  713. var MetaStatus = JsonConvert.DeserializeObject<StatusResult>(response.Content);
  714. if (MetaStatus.meta.code == 200)
  715. {
  716. //进一步解析
  717. var result = JsonConvert.DeserializeObject<TrackResult>(response.Content);
  718. result.data.ladingInfo = TrackDeserializeObject(ladingNumber, response.Content);
  719. return result;
  720. }
  721. else
  722. {
  723. throw new Exception($"51Track查询航空订单错误:{MetaStatus.meta.message}");
  724. }
  725. }
  726. else
  727. {
  728. throw new Exception($"51TrackApi请求错误:{response.StatusCode},{response.Content}");
  729. }
  730. }
  731. private ladingInfo TrackDeserializeObject(string ladingNumber, string Content)
  732. {
  733. var jo = JsonConvert.DeserializeObject<JObject>(Content);
  734. var data = (jo["data"] as JObject).GetValue(ladingNumber);
  735. var ladingInfo = JsonConvert.DeserializeObject<ladingInfo>(data.ToString());
  736. List<string> flight_numbers = ladingInfo.return_data.flight_info_new?.Select(x => x.flight_number)?.Distinct()?.ToList();
  737. if (flight_numbers == null) { return ladingInfo; }
  738. List<flight_info> infos = new List<flight_info>();
  739. foreach (var item in flight_numbers)
  740. {
  741. var info = (data["return_data"]["flight_info"] as JObject).GetValue(item);
  742. if (info != null)
  743. {
  744. flight_info _info = JsonConvert.DeserializeObject<flight_info>(info.ToString());
  745. infos.Add(_info);
  746. }
  747. }
  748. ladingInfo.return_data.flight_Infos = infos;
  749. return ladingInfo;
  750. }
  751. #endregion
  752. #region 轨迹处理
  753. private async Task<List<Logistics_TraceGroup>> ConvertToEsModel(TrackResult trackResult, List<WaitQueryData> dbData, List<Lading51TrackRules> rules)
  754. {
  755. List<Track_infoItem> tracks = new List<Track_infoItem>();
  756. List<Logistics_TraceGroup> insertLogs = new List<Logistics_TraceGroup>();
  757. var track_infos = trackResult.data.ladingInfo.return_data.flight_Infos;
  758. var trackInfos = trackResult.data.ladingInfo.return_data.track_info;
  759. Time51Value OriginPortTrack = null;
  760. Time51Value DestinationTrack = null;
  761. if (trackInfos != null && trackInfos.Count > 0
  762. && rules.Any(x => dbData.FirstOrDefault().LadingBillNumber.StartsWith(x.LadingNumber3)))
  763. {
  764. //一个单号只能有一种逻辑
  765. var rule = rules.Where(x => dbData.FirstOrDefault().LadingBillNumber.StartsWith(x.LadingNumber3)).FirstOrDefault();
  766. var tempOriginPortTrack = trackInfos
  767. .Where(x => dbData.FirstOrDefault().OriginPort?.Trim() == x.station?.Trim())
  768. ?.OrderBy(x => Convert.ToDateTime(x.actual_date?.Trim()))?.FirstOrDefault();
  769. OriginPortTrack = new Time51Value() { dateTime = tempOriginPortTrack?.actual_date };
  770. var tempDestinationTrack = trackInfos
  771. .Where(x => dbData.FirstOrDefault().Destination?.Trim() == x.station?.Trim())
  772. ?.OrderBy(x => Convert.ToDateTime(x.actual_date?.Trim()))?.FirstOrDefault();
  773. DestinationTrack = new Time51Value() { dateTime = tempDestinationTrack?.actual_date };
  774. }
  775. else if (track_infos != null && track_infos.Count > 0)
  776. {
  777. var tempOriginPortTrack = track_infos.Where(x => dbData.FirstOrDefault().OriginPort?.Trim() == x.depart_station?.Trim() && !string.IsNullOrEmpty(x?.depart_time?.Trim()))?.OrderBy(x => Convert.ToDateTime(x?.depart_time?.Trim()))?.FirstOrDefault();
  778. OriginPortTrack = new Time51Value() { dateTime = tempOriginPortTrack?.depart_time };
  779. var tempDestinationTrack = track_infos.Where(x => dbData.FirstOrDefault().Destination?.Trim() == x.arrival_station?.Trim()&&!string.IsNullOrEmpty(x?.arrival_time?.Trim()))?.OrderBy(x => Convert.ToDateTime(x?.arrival_time?.Trim()))?.FirstOrDefault();
  780. DestinationTrack = new Time51Value() { dateTime = tempDestinationTrack?.arrival_time };
  781. }
  782. //判断是否有时间数据,无则跳过 两者皆空
  783. if ((OriginPortTrack == null && DestinationTrack == null) || (string.IsNullOrEmpty(OriginPortTrack?.dateTime) && string.IsNullOrEmpty(DestinationTrack?.dateTime)))
  784. {
  785. return insertLogs;
  786. }
  787. else
  788. {
  789. //有则判断时间,是否符合,不符合发送微信通知
  790. var temp = dbData.FirstOrDefault();
  791. if (temp.TrafficTime.HasValue && !string.IsNullOrEmpty(OriginPortTrack?.dateTime) && Convert.ToDateTime(OriginPortTrack.dateTime) < temp.TrafficTime)
  792. {
  793. sendMessageToWeChat("51提单轨迹同步", $"提单号:【{temp.LadingBillNumber}】,交航时间大于起飞时间,异常!", new List<string>() { "LiuZhengKai", "fanlihang" });
  794. }
  795. else if (temp.DepartTime.HasValue && !string.IsNullOrEmpty(DestinationTrack?.dateTime) && Convert.ToDateTime(DestinationTrack.dateTime) < temp.DepartTime)
  796. {
  797. sendMessageToWeChat("51提单轨迹同步", $"提单号:【{temp.LadingBillNumber}】,起飞时间大于到达时间,异常!", new List<string>() { "LiuZhengKai", "fanlihang" });
  798. }
  799. }
  800. foreach (var tn in dbData)
  801. {
  802. var g = new Logistics_TraceGroup
  803. {
  804. TrackingNumber = tn.TrackingNumber,
  805. CustomerOrderNo = tn.CustomerOrderNo,
  806. List = new List<EsLogisticsTrackingLog>()
  807. };
  808. if (OriginPortTrack != null && !string.IsNullOrEmpty(OriginPortTrack.dateTime) && !tn.DepartTime.HasValue)
  809. {
  810. //没有交航时间,额外补一条轨迹,补一条
  811. if (!tn.TrafficTime.HasValue)
  812. {
  813. g.List.Add(new EsLogisticsTrackingLog
  814. {
  815. CreateTime = DateTime.Now,
  816. TriggerTime = Convert.ToDateTime(OriginPortTrack.dateTime).AddHours(-8),
  817. Status = 4,
  818. Location = "广州",
  819. OrderId = tn.OrderId,
  820. ChannelId = 0,
  821. TrackingNumber = tn.TrackingNumber,
  822. StatusString = "Arrived Export Airport.",//写死轨迹信息
  823. Uid = Guid.NewGuid().ToString()
  824. });
  825. }
  826. g.List.Add(new EsLogisticsTrackingLog
  827. {
  828. CreateTime = DateTime.Now,
  829. TriggerTime = Convert.ToDateTime(OriginPortTrack.dateTime),
  830. Status = 4,
  831. Location = "广州",
  832. OrderId = tn.OrderId,
  833. ChannelId = 0,
  834. TrackingNumber = tn.TrackingNumber,
  835. StatusString = "Item is ready for departure.",//写死轨迹信息
  836. Uid = Guid.NewGuid().ToString()
  837. });
  838. }
  839. if (DestinationTrack != null && !string.IsNullOrEmpty(DestinationTrack.dateTime))
  840. {
  841. g.List.Add(new EsLogisticsTrackingLog
  842. {
  843. CreateTime = DateTime.Now,
  844. TriggerTime = Convert.ToDateTime(DestinationTrack.dateTime),
  845. Status = 5,
  846. Location = tn.ReceiverCountryCode,
  847. OrderId = tn.OrderId,
  848. ChannelId = 0,
  849. TrackingNumber = tn.TrackingNumber,
  850. StatusString = "Item is being presented to customs.",//写死轨迹信息
  851. Uid = Guid.NewGuid().ToString()
  852. });
  853. }
  854. if (g.List.Count > 0) { insertLogs.Add(g); }
  855. }
  856. return insertLogs;
  857. }
  858. private async Task EsTrackUpdate(List<Logistics_TraceGroup> logistics)
  859. {
  860. bool isSuccess = await _firstDB.InsertAndUpdate(logistics);
  861. }
  862. //发送轨迹日志
  863. private TrackingEventType ToEventCode(int code)
  864. {
  865. switch (code)
  866. {
  867. case 5:
  868. return TrackingEventType.Arrive;
  869. case 4:
  870. return TrackingEventType.Departure;
  871. case 6:
  872. return TrackingEventType.Clearance;
  873. default:
  874. throw new Exception("转换失败");
  875. }
  876. }
  877. private void ExecuteSendLogs(List<Logistics_TraceGroup> logistics, List<WaitQueryData> queryDatas)
  878. {
  879. if (queryDatas.Count > 0)
  880. {
  881. List<string> CustomerOrderNoS = queryDatas.Select(x => x.CustomerOrderNo).Distinct().ToList();
  882. var apiData = logistics.Where(x => CustomerOrderNoS.Contains(x.CustomerOrderNo)).ToList();
  883. var logs2 = apiData.SelectMany(x => x.List.Select(y => new
  884. {
  885. CustomerNo = x.CustomerOrderNo,
  886. TrackingEventType = ToEventCode(y.Status),
  887. Key = x.CustomerOrderNo + "_" + ToEventCode(y.Status),
  888. EventLoaction = y.Location,
  889. EventContent = y.StatusString,
  890. EventTime = y.TriggerTime,
  891. GetTime = DateTime.Now.ToString_yyyyMMddHHmmss()
  892. }));
  893. for (int i = 0; i < Math.Ceiling(logs2.Count() / 120.0); i++)
  894. {
  895. var logs3 = logs2.Skip(120 * i).Take(120).ToList();
  896. SendXiKeLogsApi(logs3);
  897. }
  898. }
  899. }
  900. private static void SendXiKeLogsApi(dynamic dynamic)
  901. {
  902. RestSharp.RestClient rc = new RestSharp.RestClient("http://120.24.149.148:9520/");
  903. RestSharp.RestRequest rq = new RestSharp.RestRequest("/api/TrackingLog/AddLog", RestSharp.Method.POST);
  904. rq.AddHeader("Authorization", "token 132A7468DE079C6CEB59F383A661E612");
  905. if (dynamic.Count > 0)
  906. {
  907. rq.AddJsonBody(dynamic);
  908. //最长30秒超时
  909. rq.Timeout = 30 * 1000;
  910. var res = rc.Execute(rq);
  911. if (res.StatusCode == System.Net.HttpStatusCode.OK)
  912. {
  913. }
  914. else
  915. {
  916. throw new Exception(res.ErrorMessage ?? res.Content);
  917. }
  918. }
  919. }
  920. #endregion
  921. #endregion
  922. #region 头程轨迹匹配规则
  923. public async Task<long> AddFirstTrackMatchRule(Logistics_FirstTrackMatch dto)
  924. {
  925. if ((await _unitOfWork.IsExistsAsync<Logistics_FirstTrackMatch>(x => x.LadingCode == dto.LadingCode && x.status == dto.status))) { throw new Exception("已存在相同提单号与状态的规则,不能重复添加"); }
  926. long Id = await _unitOfWork.InsertAsync(dto);
  927. return Id;
  928. }
  929. public async Task<bool> DeleteFirstTrackMatchRule(int Id)
  930. {
  931. bool result = await _unitOfWork.DeleteByIdAsync<Logistics_FirstTrackMatch>(Id);
  932. return result;
  933. }
  934. public async Task<bool> UpdateFirstTrackMatchRule(Logistics_FirstTrackMatch dto)
  935. {
  936. if ((await _unitOfWork.IsExistsAsync<Logistics_FirstTrackMatch>(x => x.LadingCode == dto.LadingCode && x.status == dto.status && x.Id != dto.Id))) { throw new Exception("已存在相同提单号与状态的规则,不能重复添加"); }
  937. bool result = await _unitOfWork.UpdateAsync(dto);
  938. return result;
  939. }
  940. public async Task<PageResult<Logistics_FirstTrackMatch>> GetFirstTrackMatchRules(QueryModel queryModel)
  941. {
  942. var pageResult = await _unitOfWork.GetPagingListAsync<Logistics_FirstTrackMatch>(queryModel);
  943. return pageResult;
  944. }
  945. public async Task<List<Logistics_FirstTrackMatch>> GetAllFirstTrackMatchRules(List<string> LadingCode)
  946. {
  947. string sqlWhere = string.Empty;
  948. if (LadingCode != null && LadingCode.Count > 0) { sqlWhere = $" and LadingCode in @LadingCode "; }
  949. string sql = "select *from Logistics_FirstTrackMatch where 1=1 " + sqlWhere;
  950. var data = await _unitOfWork.QueryBySqlAsync<Logistics_FirstTrackMatch>(sql, null, new { LadingCode = LadingCode });
  951. return data.ToList();
  952. }
  953. public async Task<NodeTimeData> GetNodeTime(NodeTimeData data)
  954. {
  955. var dbData = (await _unitOfWork.QueryAsync<Logistics_LadingBill>(x => x.LadingBillNumber == data.LadingBillNumber));
  956. var trackData = await QueryBy51Track(data.LadingBillNumber);
  957. var prot1 = dbData?.FirstOrDefault()?.Destination;
  958. var prot2 = dbData?.FirstOrDefault()?.OriginPort;
  959. var track_infos = trackData.data.ladingInfo.return_data.flight_Infos;
  960. if (string.IsNullOrEmpty(prot1) || string.IsNullOrEmpty(prot2)) { throw new Exception("提单号不正确,或提单口岸信息不全,无法匹配查询!"); }
  961. if (track_infos == null || track_infos.Count == 0) { throw new Exception("提单起飞落地时间尚未更新,请过段时间再查!"); }
  962. var OriginPortTrack = track_infos.Where(x => prot2.Trim() == x.depart_station.Trim())?.OrderBy(x => Convert.ToDateTime(x?.depart_time?.Trim()))?.FirstOrDefault();
  963. var DestinationTrack = track_infos.Where(x => prot1.Trim() == x.arrival_station.Trim())?.OrderBy(x => Convert.ToDateTime(x?.arrival_time?.Trim()))?.FirstOrDefault();
  964. if (OriginPortTrack != null && !string.IsNullOrEmpty(OriginPortTrack.depart_time))
  965. {
  966. data.Code1Time = OriginPortTrack.depart_time;
  967. }
  968. if (DestinationTrack != null && !string.IsNullOrEmpty(DestinationTrack.arrival_time))
  969. {
  970. data.Code2Time = DestinationTrack.arrival_time;
  971. }
  972. return data;
  973. }
  974. #endregion
  975. #region 企微发送消息
  976. public static void sendMessageToWeChat(string jobName, string message, List<string> WeChatId)
  977. {
  978. int count = 0; bool isSucess = false;
  979. do
  980. {
  981. try
  982. {
  983. var client = new RestClient("http://120.24.149.148:9505/WarningNotice/NoticeTextToUser");
  984. client.Timeout = -1;
  985. var request = new RestRequest(Method.POST);
  986. request.AddHeader("Content-Type", "application/json");
  987. var weChatModel = new
  988. {
  989. ServiceType = "微信",
  990. TargetName = jobName,
  991. Content = "【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "】 " + (!string.IsNullOrEmpty(message) ? "执行结果," + message : "定时任务完成"),
  992. UserId = WeChatId,
  993. };
  994. var body = JsonConvert.SerializeObject(weChatModel);
  995. request.AddParameter("application/json", body, ParameterType.RequestBody);
  996. IRestResponse response = client.Execute(request);
  997. if (response.StatusCode == System.Net.HttpStatusCode.OK)
  998. {
  999. isSucess = true;
  1000. }
  1001. else
  1002. {
  1003. count++;
  1004. }
  1005. }
  1006. catch (Exception ex)
  1007. {
  1008. count++;
  1009. }
  1010. Console.WriteLine($"【{jobName}】企微消息发送:{(isSucess ? "成功" : "失败")}");
  1011. //睡眠再继续
  1012. if (count <= 3 && !isSucess) { Thread.Sleep(TimeSpan.FromSeconds(30)); }
  1013. }
  1014. while (count <= 3 && !isSucess);
  1015. }
  1016. #endregion
  1017. }
  1018. }