From 5a43e54139c231ff9988ca2a300aebb21493b572 Mon Sep 17 00:00:00 2001 From: hardstylewyl <827778732@qq.com> Date: Fri, 3 Jan 2025 16:38:56 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=E4=BD=BF=E7=94=A8=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BD=A8=E8=BF=B9=E8=AE=A2=E5=8D=95=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/OrderRepository.cs | 252 ++++++++++++++---- 1 file changed, 202 insertions(+), 50 deletions(-) diff --git a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs index 90e6c5bf..ac00889a 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; @@ -275,10 +425,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); }