refactor:使用缓存优化轨迹订单查询
This commit is contained in:
parent
db200c2212
commit
5a43e54139
@ -1,3 +1,4 @@
|
|||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using SJZY.Expand.ABP.Core.Logger;
|
using SJZY.Expand.ABP.Core.Logger;
|
||||||
using SJZY.Track.Domain;
|
using SJZY.Track.Domain;
|
||||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||||
@ -10,16 +11,178 @@ namespace SJZY.Track.Repository.Repositories;
|
|||||||
|
|
||||||
public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, ITransientDependency
|
public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, ITransientDependency
|
||||||
{
|
{
|
||||||
|
//MemoryCache本身线程安全简单使用,短暂数据不一致可以容忍,每过固定时间强制清除缓存
|
||||||
|
private static readonly MemoryCache _memoryCache = new(new MemoryCacheOptions());
|
||||||
|
private static readonly Dictionary<int, string> _empty = new();
|
||||||
|
private static readonly Dictionary<string, Dictionary<int, string>> _empty2 = new();
|
||||||
|
private const int ThirdPartyOrderNumberCacheTimeSpan = 3 * 60;
|
||||||
|
private const int MainDataEnumCacheTimeSpan = 5 * 60;
|
||||||
|
|
||||||
|
private async Task<Dictionary<int, string>> GetThirdPartyOrderNumberForCacheAsync(int[] orderIds)
|
||||||
|
{
|
||||||
|
const string key = "ThirdPartyOrderNumber";
|
||||||
|
if (orderIds.Length == 0) return _empty;
|
||||||
|
|
||||||
|
var dict = _memoryCache.Get<Dictionary<int, string>>(key);
|
||||||
|
|
||||||
|
orderIds = orderIds.Distinct().ToArray();
|
||||||
|
if (dict != null && dict.Count != 0 && !orderIds.Except(dict.Keys).Any()) return dict;
|
||||||
|
|
||||||
|
var orders = await Context.Queryable<OrderEntity>()
|
||||||
|
.Includes(a => a.OrderPlatformNumbers)
|
||||||
|
.LeftJoin<OrderPlatformNumberEntity>((a, b) => a.Id == b.OrderId && b.IsDeleted == false)
|
||||||
|
.Where((a, b) => orderIds.Contains(a.Id))
|
||||||
|
.Select(a => new OrderEntity()
|
||||||
|
{
|
||||||
|
Id = a.Id,
|
||||||
|
OrderPlatformNumbers = a.OrderPlatformNumbers
|
||||||
|
})
|
||||||
|
.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<Dictionary<string, Dictionary<int, string>>> GetMainDataEnumForCacheAsync(List<int> orderTypes, List<int> questTypes)
|
||||||
|
{
|
||||||
|
const string key = "EnumForMainData";
|
||||||
|
if (orderTypes.Count == 0 && questTypes.Count == 0) return _empty2;
|
||||||
|
|
||||||
|
var dict = _memoryCache.Get<Dictionary<string, Dictionary<int, string>>>(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//从主数据中心查询类型描述
|
||||||
|
dict = (await Context.Queryable<VEnumValueInfoEntity>()
|
||||||
|
.Where(x =>
|
||||||
|
(x.Property == GlobalConst.MainDataKey_OrderType && orderTypes.Contains(x.Enumkey))
|
||||||
|
|| (x.Property == GlobalConst.MainDataKey_TrackQuestionType && questTypes.Contains(x.Enumkey))
|
||||||
|
)
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
x.Property,
|
||||||
|
x.Enumkey,
|
||||||
|
x.Disp
|
||||||
|
})
|
||||||
|
.ToListAsync()
|
||||||
|
)
|
||||||
|
.GroupBy(x => x.Property)
|
||||||
|
.ToDictionary(
|
||||||
|
g => g.Key,
|
||||||
|
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<UnifyPageResultDto<TrackOrderVO>> GetTrackOrderPagedList(GetPageTrackOrderInputVO input)
|
public async Task<UnifyPageResultDto<TrackOrderVO>> GetTrackOrderPagedList(GetPageTrackOrderInputVO input)
|
||||||
{
|
{
|
||||||
//查询完去重
|
//查询完去重
|
||||||
var pageList = await Context.Queryable<OrderEntity>()
|
UnifyPageResultDto<TrackOrderVO> pageList;
|
||||||
.Includes(a => a.OrderPlatformNumbers)
|
//没传递单号时
|
||||||
|
if (input.OrderNos.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
pageList = await Context.Queryable<OrderEntity>()
|
||||||
|
.LeftJoin<VExternalSubjectEntity>((a, b) => a.CustomId == b.Id && b.IsDeleted == false)
|
||||||
|
.LeftJoin<VSystemEntity>((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<OrderEntity>()
|
||||||
|
.Where(x => orderNos.Contains(x.OrderNo))
|
||||||
|
.Select(x => x.Id)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
//匹配外部单
|
||||||
|
var orderIdsForThirdParty = await Context.Queryable<OrderPlatformNumberEntity>()
|
||||||
|
.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<TrackOrderVO>
|
||||||
|
{
|
||||||
|
List = new List<TrackOrderVO>(),
|
||||||
|
Pagination = new PageInfoOutput()
|
||||||
|
{
|
||||||
|
PageIndex = input.PageIndex,
|
||||||
|
PageSize = input.PageSize,
|
||||||
|
Total = 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pageList = await Context.Queryable<OrderEntity>()
|
||||||
|
.Where(x => orderIds.Contains(x.Id))
|
||||||
.LeftJoin<VExternalSubjectEntity>((a, b) => a.CustomId == b.Id && b.IsDeleted == false)
|
.LeftJoin<VExternalSubjectEntity>((a, b) => a.CustomId == b.Id && b.IsDeleted == false)
|
||||||
.LeftJoin<VSystemEntity>((a, b, c) => a.SubSystemId == c.Id && c.IsDeleted == false)
|
.LeftJoin<VSystemEntity>((a, b, c) => a.SubSystemId == c.Id && c.IsDeleted == false)
|
||||||
.LeftJoin<OrderPlatformNumberEntity>((a, b, c, d) => a.Id == d.OrderId && d.IsDeleted == false)
|
|
||||||
.WhereIF(input.SubSystemId > 0, (a, b, c) => a.SubSystemId == input.SubSystemId)
|
.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,
|
.WhereIF(input.CreateTimeStart.HasValue && input.CreateTimeEnd.HasValue,
|
||||||
(a, b, c) => a.CreateTime >= input.CreateTimeStart && a.CreateTime <= input.CreateTimeEnd)
|
(a, b, c) => a.CreateTime >= input.CreateTimeStart && a.CreateTime <= input.CreateTimeEnd)
|
||||||
.WhereIF(input.CreateTimeStart.HasValue && (!input.CreateTimeEnd.HasValue),
|
.WhereIF(input.CreateTimeStart.HasValue && (!input.CreateTimeEnd.HasValue),
|
||||||
@ -31,7 +194,6 @@ public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, I
|
|||||||
.WhereIF(input.TabType > 0, (a, b, c) => a.QuestionType == input.TabType)
|
.WhereIF(input.TabType > 0, (a, b, c) => a.QuestionType == input.TabType)
|
||||||
.WhereIF(input.TabType == (int) TrackProblemType.Warn, (a, b, c) => !a.IsCompleted)
|
.WhereIF(input.TabType == (int) TrackProblemType.Warn, (a, b, c) => !a.IsCompleted)
|
||||||
.OrderByDescending((a, b, c) => a.CreateTime)
|
.OrderByDescending((a, b, c) => a.CreateTime)
|
||||||
.Distinct()
|
|
||||||
.Select((a, b, c) => new TrackOrderVO
|
.Select((a, b, c) => new TrackOrderVO
|
||||||
{
|
{
|
||||||
Id = a.Id,
|
Id = a.Id,
|
||||||
@ -51,47 +213,35 @@ public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, I
|
|||||||
SubSystemId = c.Id,
|
SubSystemId = c.Id,
|
||||||
DestinationTimeZone = a.DestinationTimeZone,
|
DestinationTimeZone = a.DestinationTimeZone,
|
||||||
EstimatedDeliveryDate = a.EstimatedDeliveryDate,
|
EstimatedDeliveryDate = a.EstimatedDeliveryDate,
|
||||||
ThirdPartyOrderNumber = BuildThirdPartyOrderNumber(a.OrderPlatformNumbers)
|
|
||||||
})
|
})
|
||||||
.ToPagedListAsync(input.PageIndex, input.PageSize);
|
.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 orderTypes = pageList.List.Select(x => x.OrderType).Distinct().ToList();
|
||||||
var questTypes = pageList.List.Select(x => x.QuestionType).Distinct().ToList();
|
var questTypes = pageList.List.Select(x => x.QuestionType).Distinct().ToList();
|
||||||
//从主数据中心查询类型描述
|
var typeDisplayDict = await GetMainDataEnumForCacheAsync(orderTypes, questTypes);
|
||||||
var typeDispDict = (await Context.Queryable<VEnumValueInfoEntity>()
|
|
||||||
.Where(x =>
|
|
||||||
(x.Property == GlobalConst.MainDataKey_OrderType && orderTypes.Contains(x.Enumkey))
|
|
||||||
|| (x.Property == GlobalConst.MainDataKey_TrackQuestionType && questTypes.Contains(x.Enumkey))
|
|
||||||
)
|
|
||||||
.Select(x => new
|
|
||||||
{
|
|
||||||
x.Property,
|
|
||||||
x.Enumkey,
|
|
||||||
x.Disp
|
|
||||||
})
|
|
||||||
.ToListAsync()
|
|
||||||
)
|
|
||||||
.GroupBy(x => x.Property)
|
|
||||||
.ToDictionary(
|
|
||||||
g => g.Key,
|
|
||||||
y => y.ToDictionary(x => x.Enumkey, x => x.Disp)
|
|
||||||
);
|
|
||||||
|
|
||||||
//填充数描述信息
|
//填充数描述信息
|
||||||
pageList.List.ForEach(x =>
|
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)
|
? orderTypeDisplayDict.TryGetValue(x.OrderType, out var orderTypeDisplay)
|
||||||
? 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)
|
? questDisplayDict.TryGetValue(x.QuestionType, out var questDisplay)
|
||||||
? questDisplay
|
? questDisplay
|
||||||
: $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_OrderType}] Enumkey:[{x.OrderType}]"
|
: $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_OrderType}]"
|
||||||
: $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_TrackQuestionType}]";
|
: $"未在主数据中心找到Property:[{GlobalConst.MainDataKey_TrackQuestionType}] EnumKey:[{x.OrderType}]";
|
||||||
});
|
});
|
||||||
|
|
||||||
return pageList;
|
return pageList;
|
||||||
@ -275,10 +425,12 @@ public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, I
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static string BuildThirdPartyOrderNumber(List<OrderPlatformNumberEntity> orderPlatformNumberEntities)
|
private static string BuildThirdPartyOrderNumber(List<OrderPlatformNumberEntity> orderPlatformNumberEntities)
|
||||||
{
|
{
|
||||||
|
if (orderPlatformNumberEntities.Count == 0) return GlobalConst.EmptyString;
|
||||||
const string separator = "、";
|
const string separator = "、";
|
||||||
var thirdPartyOrderNumbers = orderPlatformNumberEntities
|
var thirdPartyOrderNumbers = orderPlatformNumberEntities
|
||||||
.Where(x => !string.IsNullOrWhiteSpace(x.OrderNumber))
|
.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);
|
return string.Join(separator, thirdPartyOrderNumbers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user