using Microsoft.AspNetCore.Http; using TrackCenter.Application.Dtos.ProvideServices; using TrackCenter.Application.Helpers; using TrackCenter.Application.Helpers.OSS; using TrackCenter.Domain.Aggregates.TrackDetailsAggregate; using TrackCenter.Domain.Dtos.TrackTemplate; namespace TrackCenter.Application.Services.ProvideServices; /// /// 轨迹查询服务 /// public partial class TrackService { private readonly ITrackDetailsEsRepository _trackDetailsEsRepository; private readonly IHttpContextAccessor _contextAccessor; /// /// 查询轨迹(时区补正) /// /// /// /// [HttpPost("Track/Query")] public async Task> QueryAsync(GetTrackInput input) { var res = new List(); input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空 var details = await _trackDetailsEsRepository.GetListAsync(input.AppKey, input.OrderType, input.OrderNos); //内部应用不过滤外部轨迹 var isFilterExternal = false; var ossKeys = details .Where(x => x.Files != null && x.Files.Count > 0) .SelectMany(x => x.Files!.Select(y => y.OssKey)) .ToArray(); //根据osskey获取下载地址 var ossKeyUrlDict = OSSHelper.GetUrlByKeys(ossKeys); foreach (var group in details.GroupBy(x => x.OrderId)) { var item = new GetTrackOutput(); var trackDetails = group .WhereIf(isFilterExternal, x => x.IsExternal) .ToList(); if (trackDetails.Count == 0) continue; item.OrderNo = trackDetails.First().OrderNo; item.TrackDetails = trackDetails.Select(x => new TrackDetail { EsId = x.Id, Code = x.TrackCode, Status = x.TrackStatus, Content = x.TrackContent, EnContent = x.TrackEnContent, OriginContent = x.OriginTrackContent, Location = x.TrackPlace, Time = Math.Abs(x.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1 ? x.TrackTime : x.ZeroTrackTime.AddHours(input.TimeZone ?? 8), TimeZone = Math.Abs(x.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1 ? null : input.TimeZone ?? 8, IsExternal = x.IsExternal, Source = x.Source, Remarks = x.Remarks, Files = x.Files?.Select(y => new FileItemDto { FileName = y.FileName, OssKey = y.OssKey, DownloadUrl = ossKeyUrlDict.TryGetValue(y.OssKey, out var url) ? url : null }).ToList(), TrackPlaceCity = x.TrackPlaceCity, TrackPlaceCityId = x.TrackPlaceCityId, TrackPlaceProvince = x.TrackPlaceProvince, TrackPlaceProvinceId = x.TrackPlaceProvinceId, TrackPlaceNation = x.TrackPlaceNation, TrackPlaceNationId = x.TrackPlaceNationId, TrackPlacePostcode = x.TrackPlacePostcode, DestinationTimeZone = x.DestinationTimeZone, EstimatedDeliveryDate = x.EstimatedDeliveryDate, Extra = x.Extra, CreateTime = x.CreateTime }).ToList(); res.Add(item); } // 排序 var sortedList = await TracksOrdered(res, input, input.SortMethod); return sortedList; } /// /// 查询轨迹(原样返回) /// /// /// [HttpPost("Track/QueryV2")] public async Task> QueryV2Async(GetTrackInputV2 input) { var res = new List(); input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空 var details = await _trackDetailsEsRepository.GetListAsync(input.AppKey, input.OrderType, input.OrderNos); //内部应用不过滤外部轨迹 var isFilterExternal = false; var ossKeys = details .Where(x => x.Files != null && x.Files.Count > 0) .SelectMany(x => x.Files!.Select(y => y.OssKey)) .ToArray(); //根据osskey获取下载地址 var ossKeyUrlDict = OSSHelper.GetUrlByKeys(ossKeys); foreach (var group in details.GroupBy(x => x.OrderId)) { var item = new GetTrackOutput(); var trackDetails = group .WhereIf(isFilterExternal, x => x.IsExternal) .ToList(); if (trackDetails.Count == 0) continue; item.OrderNo = trackDetails.First().OrderNo; item.TrackDetails = trackDetails.Select(x => new TrackDetail { EsId = x.Id, Code = x.TrackCode, Status = x.TrackStatus, Content = x.TrackContent, EnContent = x.TrackEnContent, OriginContent = x.OriginTrackContent, Location = x.TrackPlace, Time = x.TrackTime, IsExternal = x.IsExternal, Source = x.Source, Remarks = x.Remarks, Files = x.Files?.Select(y => new FileItemDto { FileName = y.FileName, OssKey = y.OssKey, DownloadUrl = ossKeyUrlDict.TryGetValue(y.OssKey, out var url) ? url : null }).ToList(), TrackPlaceCity = x.TrackPlaceCity, TrackPlaceCityId = x.TrackPlaceCityId, TrackPlaceProvince = x.TrackPlaceProvince, TrackPlaceProvinceId = x.TrackPlaceProvinceId, TrackPlaceNation = x.TrackPlaceNation, TrackPlaceNationId = x.TrackPlaceNationId, TrackPlacePostcode = x.TrackPlacePostcode, DestinationTimeZone = x.DestinationTimeZone, EstimatedDeliveryDate = x.EstimatedDeliveryDate, Extra = x.Extra, CreateTime = x.CreateTime, }).ToList(); res.Add(item); } // 排序 var sortedList = await TracksOrdered(res, input, input.SortMethod); return sortedList; } private Task> TracksOrdered(List list, OrderNosInfo orderNosInfo, SortMethod? sortMethod) { switch (sortMethod) { case SortMethod.ByTrackTime: // tips:quick-sort 直接修改原list list.ForEach(item => item.TrackDetails.Sort((a, b) => DateTimeHelper.ConvertUtc0Compare(a.Time, a.TimeZone ?? 8, b.Time, b.TimeZone ?? 8))); break; case null: case SortMethod.ByTrackTimeDesc: list.ForEach(item => item.TrackDetails.Sort((a, b) => DateTimeHelper.ConvertUtc0Compare(b.Time, b.TimeZone ?? 8, a.Time, a.TimeZone ?? 8))); break; case SortMethod.ByCreateTime: list.ForEach(item => item.TrackDetails.Sort((a, b) => a.CreateTime.CompareTo(b.CreateTime))); break; case SortMethod.ByCreateTimeDesc: list.ForEach(item => item.TrackDetails.Sort((a, b) => b.CreateTime.CompareTo(a.CreateTime))); break; default: throw new ArgumentOutOfRangeException(nameof(sortMethod), sortMethod, "不支持的排序方式"); } return Task.FromResult(list); } }