diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs
index 7e4376cf..1a56a04e 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs
@@ -14,7 +14,7 @@ public partial class TrackService
private readonly ITrackTemplateRepository _trackTemplateRepository;
///
- /// 查询轨迹
+ /// 查询轨迹(时区补正)
///
///
///
@@ -90,12 +90,17 @@ public partial class TrackService
}
// 排序
- var sortedList = await TracksOrdered(res, input);
+ var sortedList = await TracksOrdered(res, input, input.SortMethod, input.TrackTemplateCode);
return new UnifyResultDto>(true, sortedList, "操作成功");
}
+ ///
+ /// 查询轨迹(原样返回)
+ ///
+ ///
+ ///
[HttpPost("Track/QueryV2")]
public async Task>> QueryV2Async(GetTrackInputV2 input)
{
@@ -163,15 +168,15 @@ public partial class TrackService
}
// 排序
- var sortedList = await TracksOrdered(res, input);
+ var sortedList = await TracksOrdered(res, input, input.SortMethod);
return new UnifyResultDto>(true, sortedList, "操作成功");
}
- private async Task> TracksOrdered(List list, GetTrackInput input)
+ private async Task> TracksOrdered(List list, OrderNosInfo orderNosInfo, SortMethod? sortMethod, string? trackTemplateCode = null)
{
- switch (input.SortMethod)
+ switch (sortMethod)
{
case SortMethod.ByTrackTime:
case SortMethod.ByTemplateAndTrackTime:
@@ -184,11 +189,11 @@ public partial class TrackService
list.ForEach(item => item.TrackDetails.Sort((a, b) => b.Time.CompareTo(a.Time)));
break;
default:
- throw new ArgumentOutOfRangeException(nameof(input.SortMethod), input.SortMethod, "不支持的排序方式");
+ throw new ArgumentOutOfRangeException(nameof(sortMethod), sortMethod, "不支持的排序方式");
}
- if (input.SortMethod != SortMethod.ByTemplateAndTrackTime
- && input.SortMethod != SortMethod.ByTemplateAndTrackTimeDesc)
+ if (sortMethod != SortMethod.ByTemplateAndTrackTime
+ && sortMethod != SortMethod.ByTemplateAndTrackTimeDesc)
{
return list;
}
@@ -196,134 +201,178 @@ public partial class TrackService
//查出订单模板
var templates = await _trackTemplateRepository.GetTrackTemplateListAsync(new GetTrackTemplateListInputVo
{
- SubSystemId = input.SubSystemId,
- TemplateCode = input.TrackTemplateCode
+ SubSystemId = orderNosInfo.SubSystemId,
+ TemplateCode = trackTemplateCode
});
if (templates.Count == 0)
{
- throw new BusinessException("轨迹模板不存在");
+ return list;
}
+ //查出订单和模板的关系,构建订单号和模板code的关系
+ var orderNoTemplateDict = (await _orderRepository
+ .GetOrderTemplateAsync(orderNosInfo.SubSystemId, orderNosInfo.OrderType, orderNosInfo.OrderNos))
+ .ToDictionary(x => x.OrderNo, x => x.TemplateCodes?.Split(",").ToHashSet());
+
+ //查询出订单和模板的关联关系,保证该订单使用自己的模板排序
foreach (var getTrackOutput in list)
{
- getTrackOutput.TrackDetails = SortByTemplate(getTrackOutput.TrackDetails, templates, input.SortMethod.Value);
+ //查看该订单具有的模板
+ var curOrderNoTemplateCodes = orderNoTemplateDict[getTrackOutput.OrderNo];
+ if (curOrderNoTemplateCodes == null || curOrderNoTemplateCodes.Count == 0) continue;
+
+ //选出这个订单号所具有的模板
+ var tipTemplates = templates.Where(x => curOrderNoTemplateCodes.Contains(x.TemplateCode)).ToList();
+ if (tipTemplates.Count == 0) continue;
+
+ getTrackOutput.TrackDetails = SortByTemplatesAsync(getTrackOutput.TrackDetails, tipTemplates, sortMethod == SortMethod.ByTemplateAndTrackTime);
}
return list;
}
- private async Task> TracksOrdered(List list, GetTrackInputV2 input)
+ ///
+ /// 轨迹发生时间(统一utc)排序,相同时间按模板排序,考虑多个模板的情况
+ ///
+ ///
+ private static List SortByTemplatesAsync(List seq, List templates, bool isAsc = true)
{
- switch (input.SortMethod)
+ //转化为统一时间
+ var trackWraps = seq.Select(x => new TrackWrap(x));
+ var sortedTracks = (isAsc
+ ? trackWraps.OrderBy(x => x.Time)
+ : trackWraps.OrderByDescending(x => x.Time)).ToList();
+
+
+ //用于统计时间相同的轨迹
+ var timeEqTrackDict = new Dictionary>();
+ for (var i = 0; i < sortedTracks.Count; i++)
{
- case SortMethod.ByTrackTime:
- case SortMethod.ByTemplateAndTrackTime:
- // tips:quick-sort 直接修改原list
- list.ForEach(item => item.TrackDetails.Sort((a, b) => a.Time.CompareTo(b.Time)));
- break;
- case null:
- case SortMethod.ByTrackTimeDesc:
- case SortMethod.ByTemplateAndTrackTimeDesc:
- list.ForEach(item => item.TrackDetails.Sort((a, b) => b.Time.CompareTo(a.Time)));
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(input.SortMethod), input.SortMethod, "不支持的排序方式");
- }
-
- return list;
- }
-
- //按模板排序
- private static List SortByTemplate(List tracks, List templates, SortMethod sortMethod)
- {
- if (templates.Count == 0 ||
- tracks.Count == 0)
- {
- return new List();
- }
-
- var isAsc = sortMethod == SortMethod.ByTemplateAndTrackTime;
-
- var allTemplateCodes = new HashSet();
-
- foreach (var template in templates)
- {
- tracks = Sort(tracks, template, isAsc, allTemplateCodes);
- }
- // tracks = templates.Aggregate(tracks,
- // (current, template) => Sort(current, template, isAsc, allTemplateCodes));
-
- return tracks;
- }
-
- private static List Sort(List seq, TrackTemplateOutputVo template, bool isAsc = true, HashSet? allTemplateCodes = null)
- {
- if (template.TemplateContents.Count == 0)
- {
- return seq;
- }
-
- // 创建一个字典,用于存储排序序列中元素的索引
- var sortDict = new Dictionary();
- template.TemplateContents.Sort((x, y) => x.Sort.CompareTo(y.Sort));
- var sortSeq = template.TemplateContents
- .Select(x => seq.FirstOrDefault(y => y.Code == x.Code))
- .Where(x => x != null)
- .ToList();
- for (var i = 0; i < sortSeq.Count; i++)
- {
- sortDict[sortSeq[i]!] = isAsc ? i : sortSeq.Count - i;
- }
-
- // 将模板code添加到上下文集合中
- if (allTemplateCodes != null)
- {
- allTemplateCodes.UnionWith(template.TemplateContents.Select(x => x.Code));
- }
-
- // 根据排序序列和字典中的索引对序列进行排序
- // 使用稳定排序算法,如OrderBy,它保持相等元素的相对顺序
- var sorted = seq.OrderBy(item => sortDict.GetValueOrDefault(item, int.MaxValue)).ToList();
-
- // 存在
- if (allTemplateCodes != null)
- {
- //查询到没有命中到模板的轨迹
- var noTipTemplateTracks = sorted.Where(x => !allTemplateCodes.Contains(x.Code)).ToList();
-
- //查询未命中轨迹的索引字典
- var trackIdxDict = new Dictionary();
- var trackSortDict = new SortedDictionary();
- foreach (var track in noTipTemplateTracks)
- {
- trackIdxDict[track] = sorted.IndexOf(track);
- trackSortDict[trackIdxDict[track]] = track;
- }
-
- //没有命中的轨迹排序
- var noTipTemplateTrackSorted = (isAsc
- ? noTipTemplateTracks.OrderBy(x => x.Time)
- : noTipTemplateTracks.OrderByDescending(x => x.Time))
- .ToList();
-
- for (var i = 0; i < trackSortDict.Count; i++)
- {
- //在序列中的实际位置
- var (idx, st) = trackSortDict.ElementAt(0);
- //在这个位置它应该是哪个轨迹
- var track = noTipTemplateTrackSorted[0];
- //交换位置
- if (track != st)
+ var trackWrap = sortedTracks[i];
+ if (timeEqTrackDict.TryGetValue(trackWrap.Time, out var list))
+ list.Add(new TrackIdxWarp(trackWrap.Track, i));
+ else
+ timeEqTrackDict.Add(trackWrap.Time, new List
{
- var idx2 = trackIdxDict[track];
- sorted[idx2] = st;
- sorted[idx] = track;
+ new TrackIdxWarp(trackWrap.Track, i)
+ });
+ }
+
+
+ //选出需要按模板重排序的轨迹
+ var timeEqTracks = timeEqTrackDict
+ .Where(kv => kv.Value.Count > 1)
+ .ToDictionary(kv => kv.Key, kv => kv.Value);
+
+ //初始化为最后一个模板排序
+ var preSortDict = templates[templates.Count - 1]
+ .TemplateContents
+ .OrderBy(x => x.Sort)
+ .ToDictionary(x => x.Code, x => x.Sort);
+
+ for (var i = templates.Count - 2; i >= 0; i--)
+ {
+ var curCodeSortDict = templates[i]
+ .TemplateContents
+ .ToDictionary(x => x.Code, y => y.Sort);
+
+ //没在之前模板出现的code
+ var noTipPreCodeSortDict = curCodeSortDict
+ .Where(x => !preSortDict.ContainsKey(x.Key))
+ .ToDictionary(x => x.Key, y => y.Value);
+
+ //插入未命中的模板code
+ foreach (var (noTipCode, curNoTipCodeSort) in noTipPreCodeSortDict)
+ {
+ //初始化插入位置
+ var insertPos = -1;
+ foreach (var (preCode, _) in preSortDict)
+ {
+ if (curCodeSortDict.TryGetValue(preCode, out var preCodeSort))
+ {
+ //未命中的相对于之前模板的偏后,设置插入位置在
+ if (preCodeSort < curNoTipCodeSort)
+ {
+ insertPos = preSortDict[preCode] + 1;
+ }
+ }
+ }
+
+ //结束了还没选好位置,未命中的code相对于之前的模板code在当前模板最前面
+ if (insertPos == -1)
+ {
+ foreach (var (c, s) in preSortDict)
+ preSortDict[c] = s + 1;
+ preSortDict[noTipCode] = 0;
+ }
+ else
+ {
+ foreach (var (c, s) in preSortDict.Where(x => x.Value >= insertPos))
+ preSortDict[c] = s + 1;
+ preSortDict[noTipCode] = insertPos;
}
}
}
- return sorted;
+
+ foreach (var trackIdxWarps in timeEqTracks.Values)
+ {
+ var curIndex = trackIdxWarps.Min(x => x.Index);
+ //按模板从小到大排序
+ var sortByTemplate = (isAsc
+ ? trackIdxWarps
+ .OrderBy(x => preSortDict.GetValueOrDefault(x.Track.Code, int.MaxValue))
+ : trackIdxWarps
+ .OrderByDescending(x => preSortDict.GetValueOrDefault(x.Track.Code, int.MaxValue))
+ ).ToList();
+ for (var j = 0; j < sortByTemplate.Count; j++)
+ {
+ var track = sortByTemplate[j];
+ //当前索引不对应
+ if (track.Index != curIndex + j)
+ {
+ var temp1 = sortedTracks[track.Index].Track;
+ var temp2 = sortedTracks[curIndex + j].Track;
+ sortedTracks[track.Index].Track = temp2;
+ sortedTracks[curIndex + j].Track = temp1;
+ trackIdxWarps.First(x => x.Index == curIndex + j).Index = track.Index;
+ track.Index = curIndex + j;
+ }
+ }
+ }
+
+ return sortedTracks.Select(x => x.Track).ToList();
+ }
+
+
+ private class TrackIdxWarp
+ {
+ public TrackDetail Track { get; set; }
+ public int Index { get; set; }
+
+ public TrackIdxWarp(TrackDetail track, int index)
+ {
+ Track = track;
+ Index = index;
+ }
+ }
+
+
+ private class TrackWrap
+ {
+ public TrackDetail Track { get; set; }
+
+ public DateTime Time { get; set; }
+
+ public TrackWrap(TrackDetail track)
+ {
+ Track = track;
+ var timeZone = track.TimeZone ?? GlobalConst.NoneTrackTimeZone;
+ Time = Math.Abs(timeZone - GlobalConst.NoneTrackTimeZone) < 1
+ ? track.Time
+ : track.Time.Subtract(TimeSpan.FromHours(timeZone));
+ }
}
}
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
index f20c415e..eca70b47 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
@@ -30,6 +30,7 @@ public partial class TrackService : ApplicationService, ITrackService
IHttpClientProxy requestCurrentUserService, ITrackTemplateRepository trackTemplateRepository)
{
_orderRepository = orderRepository;
+ this._orderRepository = orderRepository;
_capPublisher = capPublisher;
_trackContentRepository = trackContentRepository;
_requestCurrentUserService = requestCurrentUserService;
diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs
index 96be07a4..467ab9c0 100644
--- a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs
@@ -12,7 +12,7 @@ public interface IOrderRepository : IBasicRepository
///
Task> GetTrackOrderPagedList(GetPageTrackOrderInputVO input);
- ///
+ ///
/// 通过三方平台和三方单号查询订单
///
/// 三方平台
@@ -62,6 +62,27 @@ public interface IOrderRepository : IBasicRepository
///
Task> GetSubSystemListByCodesAsync(List codes);
+ #region 订单模板
+
+ ///
+ /// 根据订单id,获取订单所属的模板
+ ///
+ ///
+ ///
+ Task> GetOrderTemplateAsync(int[] orderId);
+
+ ///
+ /// 根据子系统+订单号+类型,获取订单所属的模板
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task> GetOrderTemplateAsync(int subSystemId,int orderType,List orderNos);
+
+ #endregion
+
+
#region 订单关联
///
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackTemplateAggregate/ITrackTemplateRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackTemplateAggregate/ITrackTemplateRepository.cs
index efae67b2..e8a50f2d 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackTemplateAggregate/ITrackTemplateRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackTemplateAggregate/ITrackTemplateRepository.cs
@@ -45,6 +45,8 @@ public interface ITrackTemplateRepository : IBasicRepository> whereExpression);
Task> GetTrackTemplateListAsync(GetTrackTemplateListInputVo input);
+
Task> GetPageTrackTemplateListAsync(GetPageTrackTemplateListInputVo input);
+
Task> GetContentByTemplateCodes(string[] codes, int systemId);
}
diff --git a/src/SJZY.Track.Domain/Dtos/Order/OrderTemplateVO.cs b/src/SJZY.Track.Domain/Dtos/Order/OrderTemplateVO.cs
new file mode 100644
index 00000000..26c110a0
--- /dev/null
+++ b/src/SJZY.Track.Domain/Dtos/Order/OrderTemplateVO.cs
@@ -0,0 +1,13 @@
+namespace SJZY.Track.Domain.Dtos.Order;
+
+///
+/// 订单关联的模板模型
+///
+public class OrderTemplateVO
+{
+ public int OrderId { get; set; }
+
+ public string OrderNo { get; set; }
+
+ public string? TemplateCodes { get; set; }
+}
diff --git a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs
index 90e6c5bf..a071f693 100644
--- a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs
@@ -1,3 +1,4 @@
+using Microsoft.Extensions.Caching.Memory;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Track.Domain;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
@@ -10,56 +11,64 @@ namespace SJZY.Track.Repository.Repositories;
public class OrderRepository : BasicRepository, IOrderRepository, ITransientDependency
{
- public async Task> GetTrackOrderPagedList(GetPageTrackOrderInputVO input)
+ //MemoryCache本身线程安全简单使用,短暂数据不一致可以容忍,每过固定时间强制清除缓存
+ private static readonly MemoryCache _memoryCache = new(new MemoryCacheOptions());
+ private static readonly Dictionary _empty = new();
+ private static readonly Dictionary> _empty2 = new();
+ private const int ThirdPartyOrderNumberCacheTimeSpan = 3 * 60;
+ private const int MainDataEnumCacheTimeSpan = 5 * 60;
+
+ private async Task> GetThirdPartyOrderNumberForCacheAsync(int[] orderIds)
{
- //查询完去重
- var pageList = await Context.Queryable()
+ const string key = "ThirdPartyOrderNumber";
+ if (orderIds.Length == 0) return _empty;
+
+ var dict = _memoryCache.Get>(key);
+
+ orderIds = orderIds.Distinct().ToArray();
+ if (dict != null && dict.Count != 0 && !orderIds.Except(dict.Keys).Any()) return dict;
+
+ var orders = await Context.Queryable()
.Includes(a => a.OrderPlatformNumbers)
- .LeftJoin((a, b) => a.CustomId == b.Id && b.IsDeleted == false)
- .LeftJoin((a, b, c) => a.SubSystemId == c.Id && c.IsDeleted == false)
- .LeftJoin((a, b, c, d) => a.Id == d.OrderId && d.IsDeleted == false)
- .WhereIF(input.SubSystemId > 0, (a, b, c) => a.SubSystemId == input.SubSystemId)
- .WhereIF(!input.OrderNos.IsNullOrEmpty(), (a, b, c, d) => input.OrderNos!.Contains(a.OrderNo) || input.OrderNos!.Contains(d.OrderNumber))
- .WhereIF(input.CreateTimeStart.HasValue && input.CreateTimeEnd.HasValue,
- (a, b, c) => a.CreateTime >= input.CreateTimeStart && a.CreateTime <= input.CreateTimeEnd)
- .WhereIF(input.CreateTimeStart.HasValue && (!input.CreateTimeEnd.HasValue),
- (a, b, c) => a.CreateTime >= input.CreateTimeStart)
- .WhereIF((!input.CreateTimeStart.HasValue) && input.CreateTimeEnd.HasValue,
- (a, b, c) => a.CreateTime <= input.CreateTimeEnd)
- .WhereIF(input.CustomerId > 0, (a, b, c) => a.CustomId == input.CustomerId)
- .WhereIF(input.TrackOrderType > 0, (a, b, c) => a.OrderType == input.TrackOrderType)
- .WhereIF(input.TabType > 0, (a, b, c) => a.QuestionType == input.TabType)
- .WhereIF(input.TabType == (int) TrackProblemType.Warn, (a, b, c) => !a.IsCompleted)
- .OrderByDescending((a, b, c) => a.CreateTime)
- .Distinct()
- .Select((a, b, c) => new TrackOrderVO
+ .LeftJoin((a, b) => a.Id == b.OrderId && b.IsDeleted == false)
+ .Where((a, b) => orderIds.Contains(a.Id))
+ .Select(a => new OrderEntity()
{
Id = a.Id,
- OrderNumber = a.OrderNo,
- OrderType = a.OrderType,
- QuestionType = a.QuestionType,
- CustomerShortName = b.Abbreviation,
- CustomerCode = b.Code,
- CustomerId = a.CustomId,
- NewestTrackContent = a.LatestTrackContent,
- NewestTrackEnContent = a.LatestTrackEnContent,
- NewestTrackPlace = a.LatestTrackPlace,
- NewestTrackTime = a.LatestTrackTime,
- IsFinish = a.IsCompleted,
- CreateTime = a.CreateTime,
- SubSystem = c.CnName,
- SubSystemId = c.Id,
- DestinationTimeZone = a.DestinationTimeZone,
- EstimatedDeliveryDate = a.EstimatedDeliveryDate,
- ThirdPartyOrderNumber = BuildThirdPartyOrderNumber(a.OrderPlatformNumbers)
+ OrderPlatformNumbers = a.OrderPlatformNumbers
})
- .ToPagedListAsync(input.PageIndex, input.PageSize);
+ .ToListAsync();
+
+ if (orders.Count == 0)
+ return _empty;
+
+ orders = orders.DistinctBy(x => x.Id).ToList();
+
+ dict = orders.ToDictionary(x => x.Id, x => BuildThirdPartyOrderNumber(x.OrderPlatformNumbers));
+
+ _memoryCache.Set(key, dict, new MemoryCacheEntryOptions
+ {
+ AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(ThirdPartyOrderNumberCacheTimeSpan),
+ Size = dict.Count
+ });
+ return dict;
+ }
+
+ private async Task>> GetMainDataEnumForCacheAsync(List orderTypes, List questTypes)
+ {
+ const string key = "EnumForMainData";
+ if (orderTypes.Count == 0 && questTypes.Count == 0) return _empty2;
+
+ var dict = _memoryCache.Get>>(key);
+ if (dict != null && dict.Count != 0
+ && !orderTypes.Except(dict[GlobalConst.MainDataKey_OrderType].Keys).Any()
+ && !questTypes.Except(dict[GlobalConst.MainDataKey_TrackQuestionType].Keys).Any())
+ {
+ return dict;
+ }
- //查询订单类型描述
- var orderTypes = pageList.List.Select(x => x.OrderType).Distinct().ToList();
- var questTypes = pageList.List.Select(x => x.QuestionType).Distinct().ToList();
//从主数据中心查询类型描述
- var typeDispDict = (await Context.Queryable()
+ dict = (await Context.Queryable()
.Where(x =>
(x.Property == GlobalConst.MainDataKey_OrderType && orderTypes.Contains(x.Enumkey))
|| (x.Property == GlobalConst.MainDataKey_TrackQuestionType && questTypes.Contains(x.Enumkey))
@@ -78,20 +87,161 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
y => y.ToDictionary(x => x.Enumkey, x => x.Disp)
);
+ if (dict.Count == 0)
+ return _empty2;
+
+ _memoryCache.Set(key, dict, new MemoryCacheEntryOptions
+ {
+ AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(MainDataEnumCacheTimeSpan),
+ Size = dict.Count
+ });
+ return dict;
+ }
+
+ public async Task> GetTrackOrderPagedList(GetPageTrackOrderInputVO input)
+ {
+ //查询完去重
+ UnifyPageResultDto pageList;
+ //没传递单号时
+ if (input.OrderNos.IsNullOrEmpty())
+ {
+ pageList = await Context.Queryable()
+ .LeftJoin((a, b) => a.CustomId == b.Id && b.IsDeleted == false)
+ .LeftJoin((a, b, c) => a.SubSystemId == c.Id && c.IsDeleted == false)
+ .WhereIF(input.SubSystemId > 0, (a, b, c) => a.SubSystemId == input.SubSystemId)
+ .WhereIF(input.CreateTimeStart.HasValue && input.CreateTimeEnd.HasValue,
+ (a, b, c) => a.CreateTime >= input.CreateTimeStart && a.CreateTime <= input.CreateTimeEnd)
+ .WhereIF(input.CreateTimeStart.HasValue && (!input.CreateTimeEnd.HasValue),
+ (a, b, c) => a.CreateTime >= input.CreateTimeStart)
+ .WhereIF((!input.CreateTimeStart.HasValue) && input.CreateTimeEnd.HasValue,
+ (a, b, c) => a.CreateTime <= input.CreateTimeEnd)
+ .WhereIF(input.CustomerId > 0, (a, b, c) => a.CustomId == input.CustomerId)
+ .WhereIF(input.TrackOrderType > 0, (a, b, c) => a.OrderType == input.TrackOrderType)
+ .WhereIF(input.TabType > 0, (a, b, c) => a.QuestionType == input.TabType)
+ .WhereIF(input.TabType == (int) TrackProblemType.Warn, (a, b, c) => !a.IsCompleted)
+ .OrderByDescending((a, b, c) => a.CreateTime)
+ .Select((a, b, c) => new TrackOrderVO
+ {
+ Id = a.Id,
+ OrderNumber = a.OrderNo,
+ OrderType = a.OrderType,
+ QuestionType = a.QuestionType,
+ CustomerShortName = b.Abbreviation,
+ CustomerCode = b.Code,
+ CustomerId = a.CustomId,
+ NewestTrackContent = a.LatestTrackContent,
+ NewestTrackEnContent = a.LatestTrackEnContent,
+ NewestTrackPlace = a.LatestTrackPlace,
+ NewestTrackTime = a.LatestTrackTime,
+ IsFinish = a.IsCompleted,
+ CreateTime = a.CreateTime,
+ SubSystem = c.CnName,
+ SubSystemId = c.Id,
+ DestinationTimeZone = a.DestinationTimeZone,
+ EstimatedDeliveryDate = a.EstimatedDeliveryDate
+ })
+ .ToPagedListAsync(input.PageIndex, input.PageSize);
+ }
+ //传递单号时
+ else
+ {
+ var orderNos = input.OrderNos!.Distinct().ToList();
+
+ //匹配主单
+ var orderIds = await Context.Queryable()
+ .Where(x => orderNos.Contains(x.OrderNo))
+ .Select(x => x.Id)
+ .ToListAsync();
+
+ //匹配外部单
+ var orderIdsForThirdParty = await Context.Queryable()
+ .Where(x => !string.IsNullOrWhiteSpace(x.OrderNumber) && orderNos.Contains(x.OrderNumber))
+ .Select(x => x.OrderId)
+ .ToListAsync();
+
+ var orderHashset = orderIds.ToHashSet();
+ orderHashset.UnionWith(orderIdsForThirdParty);
+ orderIds = orderHashset.ToList();
+
+ //没有任何单
+ if (orderIds.Count == 0)
+ {
+ return new UnifyPageResultDto
+ {
+ List = new List(),
+ Pagination = new PageInfoOutput()
+ {
+ PageIndex = input.PageIndex,
+ PageSize = input.PageSize,
+ Total = 0
+ }
+ };
+ }
+
+ pageList = await Context.Queryable()
+ .Where(x => orderIds.Contains(x.Id))
+ .LeftJoin((a, b) => a.CustomId == b.Id && b.IsDeleted == false)
+ .LeftJoin((a, b, c) => a.SubSystemId == c.Id && c.IsDeleted == false)
+ .WhereIF(input.SubSystemId > 0, (a, b, c) => a.SubSystemId == input.SubSystemId)
+ .WhereIF(input.CreateTimeStart.HasValue && input.CreateTimeEnd.HasValue,
+ (a, b, c) => a.CreateTime >= input.CreateTimeStart && a.CreateTime <= input.CreateTimeEnd)
+ .WhereIF(input.CreateTimeStart.HasValue && (!input.CreateTimeEnd.HasValue),
+ (a, b, c) => a.CreateTime >= input.CreateTimeStart)
+ .WhereIF((!input.CreateTimeStart.HasValue) && input.CreateTimeEnd.HasValue,
+ (a, b, c) => a.CreateTime <= input.CreateTimeEnd)
+ .WhereIF(input.CustomerId > 0, (a, b, c) => a.CustomId == input.CustomerId)
+ .WhereIF(input.TrackOrderType > 0, (a, b, c) => a.OrderType == input.TrackOrderType)
+ .WhereIF(input.TabType > 0, (a, b, c) => a.QuestionType == input.TabType)
+ .WhereIF(input.TabType == (int) TrackProblemType.Warn, (a, b, c) => !a.IsCompleted)
+ .OrderByDescending((a, b, c) => a.CreateTime)
+ .Select((a, b, c) => new TrackOrderVO
+ {
+ Id = a.Id,
+ OrderNumber = a.OrderNo,
+ OrderType = a.OrderType,
+ QuestionType = a.QuestionType,
+ CustomerShortName = b.Abbreviation,
+ CustomerCode = b.Code,
+ CustomerId = a.CustomId,
+ NewestTrackContent = a.LatestTrackContent,
+ NewestTrackEnContent = a.LatestTrackEnContent,
+ NewestTrackPlace = a.LatestTrackPlace,
+ NewestTrackTime = a.LatestTrackTime,
+ IsFinish = a.IsCompleted,
+ CreateTime = a.CreateTime,
+ SubSystem = c.CnName,
+ SubSystemId = c.Id,
+ DestinationTimeZone = a.DestinationTimeZone,
+ EstimatedDeliveryDate = a.EstimatedDeliveryDate,
+ })
+ .ToPagedListAsync(input.PageIndex, input.PageSize);
+ }
+
+
+ //补三方单号,从缓存中加速查
+ var orderIdArr = pageList.List.Select(x => x.Id).ToArray();
+ var thirdPartyOrderNumbers = await GetThirdPartyOrderNumberForCacheAsync(orderIdArr);
+ pageList.List.ForEach(x => x.ThirdPartyOrderNumber = thirdPartyOrderNumbers[x.Id]);
+
+ //查询订单类型描述,从缓存中加速查
+ var orderTypes = pageList.List.Select(x => x.OrderType).Distinct().ToList();
+ var questTypes = pageList.List.Select(x => x.QuestionType).Distinct().ToList();
+ var typeDisplayDict = await GetMainDataEnumForCacheAsync(orderTypes, questTypes);
+
//填充数描述信息
pageList.List.ForEach(x =>
{
- x.OrderTypeName = typeDispDict.TryGetValue(GlobalConst.MainDataKey_OrderType, out var orderTypeDisplayDict)
+ x.OrderTypeName = typeDisplayDict.TryGetValue(GlobalConst.MainDataKey_OrderType, out var orderTypeDisplayDict)
? orderTypeDisplayDict.TryGetValue(x.OrderType, out var orderTypeDisplay)
? orderTypeDisplay
- : $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_OrderType}] Enumkey:[{x.OrderType}]"
- : $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_OrderType}]";
+ : $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_OrderType}] "
+ : $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_OrderType}] EnumKey:[{x.OrderType}]";
- x.QuestionTypeName = typeDispDict.TryGetValue(GlobalConst.MainDataKey_TrackQuestionType, out var questDisplayDict)
+ x.QuestionTypeName = typeDisplayDict.TryGetValue(GlobalConst.MainDataKey_TrackQuestionType, out var questDisplayDict)
? questDisplayDict.TryGetValue(x.QuestionType, out var questDisplay)
? questDisplay
- : $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_OrderType}] Enumkey:[{x.OrderType}]"
- : $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_TrackQuestionType}]";
+ : $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_OrderType}]"
+ : $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_TrackQuestionType}] EnumKey:[{x.OrderType}]";
});
return pageList;
@@ -246,6 +396,32 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
return res.Select(x => (x.Key, x.Id)).ToList();
}
+ public Task> GetOrderTemplateAsync(int[] orderId)
+ {
+ return Context.Queryable()
+ .Where(x => orderId.Contains(x.Id))
+ .Select(a => new OrderTemplateVO
+ {
+ OrderId = a.Id,
+ OrderNo = a.OrderNo,
+ TemplateCodes = a.TemplateCodes
+ })
+ .ToListAsync();
+ }
+
+ public Task> GetOrderTemplateAsync(int subSystemId, int orderType, List orderNos)
+ {
+ return Context.Queryable()
+ .Where(x => orderNos.Contains(x.OrderNo) && x.SubSystemId == subSystemId && x.OrderType == orderType)
+ .Select(a => new OrderTemplateVO
+ {
+ OrderId = a.Id,
+ OrderNo = a.OrderNo,
+ TemplateCodes = a.TemplateCodes
+ })
+ .ToListAsync();
+ }
+
public Task GetSystemInfoById(int id)
{
return Context.Queryable().FirstAsync(m => m.IsDeleted == false && m.Id == id);
@@ -275,10 +451,12 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
///
private static string BuildThirdPartyOrderNumber(List orderPlatformNumberEntities)
{
+ if (orderPlatformNumberEntities.Count == 0) return GlobalConst.EmptyString;
const string separator = "、";
var thirdPartyOrderNumbers = orderPlatformNumberEntities
.Where(x => !string.IsNullOrWhiteSpace(x.OrderNumber))
- .Select(x => $"{x.OrderNumber}({x.Platform})").ToList();
+ .Select(x => $"{x.OrderNumber}({x.Platform})")
+ .ToList();
return string.Join(separator, thirdPartyOrderNumbers);
}