diff --git a/src/SJZY.Track.Application/Helpers/ForewarningFactorHelper.cs b/src/SJZY.Track.Application/Helpers/ForewarningFactorHelper.cs index c88ec276..5490aea1 100644 --- a/src/SJZY.Track.Application/Helpers/ForewarningFactorHelper.cs +++ b/src/SJZY.Track.Application/Helpers/ForewarningFactorHelper.cs @@ -5,54 +5,56 @@ namespace SJZY.Track.Application.Helpers; public class ForewarningFactorHelper { - public static RuleCollectEntity[] GetFactorItem([NotNull]RuleFactorEntity ruleFactors) + public static RuleItemEntity[] GetFactorItem([NotNull] RuleFactorEntity ruleFactors) { var total = Factorial(ruleFactors); - var ruleCollect = AllocateFactor(total,ruleFactors.RuleId); - Assignment(ruleCollect,total,ruleFactors.CargoTypes,(item,value)=>item.CargoType=value); - Assignment(ruleCollect,total,ruleFactors.Months,(item,value)=>item.Month=value); - Assignment(ruleCollect,total,ruleFactors.Areas,(item,value)=>item.Area=value); - Assignment(ruleCollect,total,ruleFactors.IsTransit,(item,value)=>item.IsTransit=value); - Assignment(ruleCollect,total,ruleFactors.DeparturePorts,(item,value)=>item.DeparturePort=value); - Assignment(ruleCollect,total,ruleFactors.ProductCodes,(item,value)=>item.ProductCode=value); + var ruleCollect = AllocateFactor(total, ruleFactors.RuleId); + Assignment(ruleCollect, total, ruleFactors.CargoTypes, (item, value) => item.CargoType = value); + Assignment(ruleCollect, total, ruleFactors.Months, (item, value) => item.Month = value); + Assignment(ruleCollect, total, ruleFactors.Areas, (item, value) => item.Area = value); + Assignment(ruleCollect, total, ruleFactors.IsTransit, (item, value) => item.IsTransit = value); + Assignment(ruleCollect, total, ruleFactors.DeparturePorts, (item, value) => item.DeparturePort = value); + Assignment(ruleCollect, total, ruleFactors.ProductCodes, (item, value) => item.ProductCode = value); return ruleCollect.ToArray(); } - - private static void Assignment(Span ruleCollect,int total,IReadOnlyList values,Action action) + + private static void Assignment(Span ruleCollect, int total, IReadOnlyList values, + Action action) { if (values.Count == 0) { return; } - + var segment = total / values.Count; - for(int index=0;index AllocateFactor(int total,int ruleId) + + private static Span AllocateFactor(int total, int ruleId) { - - Span factors = new RuleCollectEntity[total]; + Span factors = new RuleItemEntity[total]; for (int index = 0; index < total; index++) { - factors[index] = new RuleCollectEntity() + factors[index] = new RuleItemEntity() { RuleId = ruleId }; } + return factors; } - + internal static int Factorial(RuleFactorEntity ruleFactors) { - return ruleFactors.CargoTypes.Count*ruleFactors.Months.Count*ruleFactors.Areas.Count*ruleFactors.IsTransit.Count*ruleFactors.DeparturePorts.Count*ruleFactors.ProductCodes.Count; + return ruleFactors.CargoTypes.Count * ruleFactors.Months.Count * ruleFactors.Areas.Count * + ruleFactors.IsTransit.Count * ruleFactors.DeparturePorts.Count * ruleFactors.ProductCodes.Count; } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/Services/ForewarningServices/ForewarningNotifyService.cs b/src/SJZY.Track.Application/Services/ForewarningServices/ForewarningNotifyService.cs index d692dad5..490c7c20 100644 --- a/src/SJZY.Track.Application/Services/ForewarningServices/ForewarningNotifyService.cs +++ b/src/SJZY.Track.Application/Services/ForewarningServices/ForewarningNotifyService.cs @@ -1,24 +1,22 @@ using FreeRedis; -using NetTaste; using SJZY.Expand.ABP.Core; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.ForewarningAggregate; using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Dtos.Forewarning; using SJZY.Track.Domain.Enums; -using SqlSugar; using Volo.Abp.DependencyInjection; namespace SJZY.Track.Application.Services.ForewarningServices; /// -/// 单例服务,用于处理预警通知 +/// 用于处理预警通知 /// -public class ForewarningNotifyService:IForewarningNotifyService,ITransientDependency +public class ForewarningNotifyService : IForewarningNotifyService, ITransientDependency { private IRuleFactorCacheService _ruleFactorCache; - IReadOnlyDictionary> _ruleGroupDict; - IReadOnlyDictionary> _factorDict; + IReadOnlyDictionary> _ruleGroupDict; + IReadOnlyDictionary> _factorDict; private IReadOnlyDictionary _rules; readonly INotifyService _notifyService; @@ -27,7 +25,7 @@ public class ForewarningNotifyService:IForewarningNotifyService,ITransientDepend _ruleFactorCache = ruleFactorCache; _notifyService = notifyService; } - + /// /// 创建预警通知 /// @@ -38,10 +36,10 @@ public class ForewarningNotifyService:IForewarningNotifyService,ITransientDepend var rules = GetRule(order); if (rules == null || rules.Count == 0) return 0; - - return await ExecuteRule(rules,order.Id); + + return await ExecuteRule(rules, order.Id); } - + /// /// 清除预警通知 /// @@ -56,10 +54,10 @@ public class ForewarningNotifyService:IForewarningNotifyService,ITransientDepend var willDeleteMembers = new List(); foreach (var rule in rules) { - var allRuleNotities= DeleteNotifyValue(rule, order.Id); + var allRuleNotities = DeleteNotifyValue(rule, order.Id); willDeleteMembers.AddRange(allRuleNotities); } - + await RedisHelper.Client.ZRemAsync(GlobalConst.ForewarningNotifyKeyPrefix, willDeleteMembers.ToArray()); return willDeleteMembers.Count; } @@ -67,32 +65,33 @@ public class ForewarningNotifyService:IForewarningNotifyService,ITransientDepend public void SendNotification(int intervalMinute) { var currentTimestamp = GetTimestamp(DateTime.Now); - var notifyMembers = RedisHelper.Client.ZRangeByScore(GlobalConst.ForewarningNotifyKeyPrefix, 0, currentTimestamp); + var notifyMembers = + RedisHelper.Client.ZRangeByScore(GlobalConst.ForewarningNotifyKeyPrefix, 0, currentTimestamp); if (notifyMembers == null || notifyMembers.Length == 0) return; - + var notifyValues = notifyMembers.Select(val => new RuleNotifyValue(val)); foreach (var notifyValue in notifyValues) { - if(!_rules.TryGetValue(notifyValue.RuleId, out var rule)) + if (!_rules.TryGetValue(notifyValue.RuleId, out var rule)) continue; //todo 发送通知 _notifyService.SendNotification(""); } } - + public void ClearCache() { _ruleGroupDict = null; _factorDict = null; _rules = null; } - - private List DeleteNotifyValue(ForewarningRule rule,int orderId) + + private List DeleteNotifyValue(ForewarningRule rule, int orderId) { var members = new List(); - for(var index=0;index /// 获取规则 /// @@ -112,45 +111,45 @@ public class ForewarningNotifyService:IForewarningNotifyService,ITransientDepend { return null; } - + var keys = GetForewarningKeys(factors, order); - var result = new List< ForewarningRule>(); - + var result = new List(); + foreach (var item in keys) { if (!_ruleGroupDict.TryGetValue(item, out var rules)) continue; - - var allRules = rules.Where(val=>val.TrackStart <= order.Track && val.TrackEnd >= order.Track); + + var allRules = rules.Where(val => val.TrackStart <= order.Track && val.TrackEnd >= order.Track); result.AddRange(allRules); } return result; } - private async ValueTask ExecuteRule(List rules,int orderId) + private async ValueTask ExecuteRule(List rules, int orderId) { var members = new List(); foreach (var rule in rules) { - var notifys = ExecuteRule(rule,orderId); + var notifys = ExecuteRule(rule, orderId); members.AddRange(notifys); } await RedisHelper.Client.ZAddAsync(GlobalConst.ForewarningNotifyKeyPrefix, members.ToArray()); return members.Count; } - - private List ExecuteRule(ForewarningRule rule,int orderId) + + private List ExecuteRule(ForewarningRule rule, int orderId) { var members = new List(); - var intervalMinute = 60 * ((rule.Timeliness - rule.Remind) / rule.Count);// 间隔多少分钟 - - for(var index=0;index GetForewarningKeys(List factors, IForewarningFactorValue rule) { var keys = new List(); @@ -179,34 +178,35 @@ public class ForewarningNotifyService:IForewarningNotifyService,ITransientDepend return keys; } - + private async Task Init() { + // todo:缓存设计有问题 重构 120s 10w 30w 3000k/s var allFactorCollect = await _ruleFactorCache.GetAllFactorCollect(); var factors = await _ruleFactorCache.GetAllRuleFactor(); - var factorsMap = factors.GroupBy(val=>val.RuleId) - .ToDictionary(val=>val.Key,val=>val.First()); - + var factorsMap = factors.GroupBy(val => val.RuleId) + .ToDictionary(val => val.Key, val => val.First()); + _rules = allFactorCollect.ToDictionary(val => val.Id); - - _factorDict = factors.GroupBy(val => GetFactorKey(val.CustomerId,val.SystemId)) - .ToDictionary(val=>val.Key,val=>val.ToList()); + + _factorDict = factors.GroupBy(val => GetFactorKey(val.CustomerId, val.SystemId)) + .ToDictionary(val => val.Key, val => val.ToList()); _ruleGroupDict = allFactorCollect.GroupBy(x => GetRuleKey(x, factorsMap[x.RuleId])) .ToDictionary(val => val.Key, val => val.ToList()); } - - private string GetFactorKey(int customerId,int systemId) + + private string GetFactorKey(int customerId, int systemId) { return $"{customerId}:{systemId}"; } - - private string GetRuleKey(IForewarningFactorValue rule,RuleFactor factors) + + private string GetRuleKey(IForewarningFactorValue rule, RuleFactor factors) { var key = ""; foreach (var factorItem in factors.FactorItems) { - key+=GetFactorValue(factorItem,rule); + key += GetFactorValue(factorItem, rule); } return key; diff --git a/src/SJZY.Track.Application/Services/ForewarningServices/ForewarningService.cs b/src/SJZY.Track.Application/Services/ForewarningServices/ForewarningService.cs index 2f660c83..b9544324 100644 --- a/src/SJZY.Track.Application/Services/ForewarningServices/ForewarningService.cs +++ b/src/SJZY.Track.Application/Services/ForewarningServices/ForewarningService.cs @@ -1,29 +1,26 @@ -using System.Diagnostics.CodeAnalysis; -using AutoMapper; using SJZY.Track.Application.Helpers; using SJZY.Track.Domain.Aggregates.ForewarningAggregate; using SJZY.Track.Domain.Dtos.Forewarning; -using SqlSugar; namespace SJZY.Track.Application.Services.ForewarningServices; [ApiExplorerSettings(GroupName = "预警服务")] [Route("/ForewarningService")] -public class ForewarningService: ApplicationService +public class ForewarningService : ApplicationService { readonly IRuleRepository _ruleRepository; IRuleFactorRepository _ruleFactorRepository; - private IRuleCollectRepository _ruleCollectRepository; - + private IRuleItemRepository _ruleItemRepository; + public ForewarningService(IRuleRepository ruleRepository - ,IRuleFactorRepository ruleFactorRepository - , IRuleCollectRepository ruleCollectRepository) + , IRuleFactorRepository ruleFactorRepository + , IRuleItemRepository ruleItemRepository) { _ruleRepository = ruleRepository; _ruleFactorRepository = ruleFactorRepository; - _ruleCollectRepository = ruleCollectRepository; + _ruleItemRepository = ruleItemRepository; } - + /// /// 创建预警模板,存在则更新 /// @@ -32,46 +29,48 @@ public class ForewarningService: ApplicationService [HttpPost("ModifyForewarning")] public async ValueTask ModifyForewarning(CreateRuleFactorRequest input) { - var factors = ObjectMapper.Map(input); - var ruleCollects = ForewarningFactorHelper.GetFactorItem(factors); - + var factors = ObjectMapper.Map(input); + var ruleItems = ForewarningFactorHelper.GetFactorItem(factors); + //todo 原子性没有保证,后续可能需要调整 if (input.RuleId > 0) { await _ruleFactorRepository.DeleteByIdAsync(input.RuleId.ToString()); } - + if (input.RuleId > 0) { - var ruleTemplate = await _ruleRepository.GetFirstAsync(val=>val.Id == input.RuleId); + var ruleTemplate = await _ruleRepository.GetFirstAsync(val => val.Id == input.RuleId); if (ruleTemplate == null) - return new UnifyResultDto(false,"规则不存在"); - + return new UnifyResultDto(false, "规则不存在"); + ruleTemplate.Name = input.Name; ruleTemplate.CustomId = input.CustomId; await _ruleFactorRepository.IndexDocumentAsync(factors); - await _ruleRepository.UpdateForewarning(ruleTemplate, ruleCollects); - return new UnifyResultDto(true,"保存成功"); + await _ruleRepository.UpdateForewarning(ruleTemplate, ruleItems); + return new UnifyResultDto(true, "保存成功"); } - + var newRuleTemplate = ObjectMapper.Map(input); - var ruleTemplateId = await _ruleRepository.CreateForewarning(newRuleTemplate, ruleCollects); - factors.Id = ruleTemplateId.ToString(); - return new UnifyResultDto(true,"保存成功"); + var ruleId = await _ruleRepository.CreateForewarning(newRuleTemplate, ruleItems); + factors.Id = ruleId.ToString(); + await _ruleFactorRepository.IndexDocumentAsync(factors); + return new UnifyResultDto(true, "保存成功"); } - + /// /// 修改时效 /// [HttpPost("ModifyTimeliness")] public async ValueTask ModifyTimeliness(ModifyTimelinessRequest input) { - var ruleIds = input.Items.Select(val=>val.Id).ToList(); - var ruleCollect = await _ruleCollectRepository.GetListAsync(val => ruleIds.Contains(val.Id) && val.RuleId == input.RuleId); - if (ruleCollect == null|| ruleCollect.Count == 0) - throw new BusinessException(message:"规则不存在"); - + var ruleIds = input.Items.Select(val => val.Id).ToList(); + var ruleCollect = + await _ruleItemRepository.GetListAsync(val => ruleIds.Contains(val.Id) && val.RuleId == input.RuleId); + if (ruleCollect == null || ruleCollect.Count == 0) + throw new BusinessException(message: "规则不存在"); + var ruleMaps = ruleCollect.ToDictionary(val => val.Id); var notModifyList = new List(); foreach (var item in input.Items) @@ -81,48 +80,45 @@ public class ForewarningService: ApplicationService notModifyList.Add(item.Id); continue; } - - rule.Remind= item.Remind; + + rule.Remind = item.Remind; rule.Timeliness = item.Timeliness; rule.Count = item.Count; } - - await _ruleCollectRepository.UpdateRangeAsync(ruleCollect,val=>val.RuleId==input.RuleId); - + + await _ruleItemRepository.UpdateRangeAsync(ruleCollect, val => val.RuleId == input.RuleId); + if (notModifyList.Count > 0) return new UnifyResultDto(true, $"更新成功,规则{string.Join(",", notModifyList)}不存在"); - + return new UnifyResultDto(true, "更新成功"); } - - /// - /// 查询预警模板列表 - /// - /// - [HttpPost("QueryForewarning")] - public async Task QueryForewarning(QueryForewarningRequest input) - { - var result = await _ruleRepository.QueryForewarning(input); - return new UnifyResultDto(true, result); - } /// /// 查询预警规则列表 /// - [HttpPost("QueryForewarningRules")] - public async Task QueryForewarningRules(QueryForewarningRuleRequest input) + /// + [HttpPost("QueryForewarning")] + public async Task QueryForewarning(QueryForewarningRequest input) { - var result = await _ruleCollectRepository.QueryForewarningRule(input); + var result = await _ruleRepository.QueryForewarningRuleAsync(input); return new UnifyResultDto(true, result); } - + + /// + /// 查询预警规则明细列表 + /// + [HttpPost("QueryForewarningRules")] + public async Task> QueryForewarningRuleItems(QueryForewarningRuleRequest input) + { + return await _ruleItemRepository.QueryForewarningRuleItemsAsync(input); + } + /// /// 发送预警通知 /// [HttpPost("SendForewarningNotification")] public void SendForewarningNotification() { - } - } \ No newline at end of file diff --git a/src/SJZY.Track.Application/Services/ForewarningServices/KpiAreaService.cs b/src/SJZY.Track.Application/Services/ForewarningServices/KpiAreaService.cs index f87b3109..3fc7c3ac 100644 --- a/src/SJZY.Track.Application/Services/ForewarningServices/KpiAreaService.cs +++ b/src/SJZY.Track.Application/Services/ForewarningServices/KpiAreaService.cs @@ -1,7 +1,5 @@ -using AutoMapper; using SJZY.Track.Domain.Aggregates.KPIAreaAggregate; using SJZY.Track.Domain.Dtos.Forewarning; -using SqlSugar; namespace SJZY.Track.Application.Services.ForewarningServices; @@ -9,9 +7,9 @@ namespace SJZY.Track.Application.Services.ForewarningServices; [Route("/ForewarningService")] public class KpiAreaService : ApplicationService { - readonly IKpiAreaRepository _ruleAreaRepository; + private readonly IKpiAreaRepository _ruleAreaRepository; - public KpiAreaService(IKpiAreaRepository ruleAreaRepository ) + public KpiAreaService(IKpiAreaRepository ruleAreaRepository) { _ruleAreaRepository = ruleAreaRepository; } @@ -26,7 +24,7 @@ public class KpiAreaService : ApplicationService { var ruleAreaEntity = ObjectMapper.Map(input); var areaId = await _ruleAreaRepository.CreateAreaAsync(ruleAreaEntity); - return new UnifyResultDto(true,areaId, "创建成功"); + return new UnifyResultDto(true, areaId, "创建成功"); } /// @@ -39,7 +37,7 @@ public class KpiAreaService : ApplicationService { var ruleAreaEntity = ObjectMapper.Map(input); var ruleInfoId = await _ruleAreaRepository.AddAreaInfoAsync(ruleAreaEntity); - return new UnifyResultDto(true,ruleInfoId, "添加成功"); + return new UnifyResultDto(true, ruleInfoId, "添加成功"); } /// @@ -53,7 +51,7 @@ public class KpiAreaService : ApplicationService await _ruleAreaRepository.DeleteArea(id); return new UnifyResultDto(true, "删除成功"); } - + /// /// 删除分区信息 /// @@ -65,7 +63,7 @@ public class KpiAreaService : ApplicationService await _ruleAreaRepository.DeleteAreaInfo(id); return new UnifyResultDto(true, "删除成功"); } - + /// /// 更新区域信息 /// @@ -74,18 +72,18 @@ public class KpiAreaService : ApplicationService [HttpPost("KpiArea/ModifyKpiArea")] public async Task ModifyKpiArea(UpdateRuleAreaRequest input) { - if(input.Id<=0) - return new UnifyResultDto(false,"id不能为空"); - - var ruleArea =await _ruleAreaRepository.GetFirstAsync(val=>val.Id==input.Id); - if(ruleArea==null) - return new UnifyResultDto(false,"未找到该区域"); - + if (input.Id <= 0) + return new UnifyResultDto(false, "id不能为空"); + + var ruleArea = await _ruleAreaRepository.GetFirstAsync(val => val.Id == input.Id); + if (ruleArea == null) + return new UnifyResultDto(false, "未找到该区域"); + ruleArea.Name = input.Name; await _ruleAreaRepository.UpdateAsync(ruleArea); - return new UnifyResultDto(true,"更新成功"); + return new UnifyResultDto(true, "更新成功"); } - + /// /// 更新区域信息 /// @@ -94,19 +92,19 @@ public class KpiAreaService : ApplicationService [HttpPost("KpiArea/ModifyKpiAreaInfo")] public async Task ModifyKpiAreaInfo(UpdateRuleAreaInfoRequest input) { - if(input.Id<=0) - return new UnifyResultDto(false,"id不能为空"); - + if (input.Id <= 0) + return new UnifyResultDto(false, "id不能为空"); + //todo 测试不存在id的情况 - RuleAreaInfoEntity areaInfo = await _ruleAreaRepository.GetAreaInfoById(input.Id); - if(areaInfo==null) - return new UnifyResultDto(false,"未找到该区域信息"); - - var ruleAreaEntity = ObjectMapper.Map(input,areaInfo); + var areaInfo = await _ruleAreaRepository.GetAreaInfoById(input.Id); + if (areaInfo == null) + return new UnifyResultDto(false, "未找到该区域信息"); + + var ruleAreaEntity = ObjectMapper.Map(input, areaInfo); await _ruleAreaRepository.UpdateAreaInfoAsync(ruleAreaEntity); - return new UnifyResultDto(true,"更新成功"); + return new UnifyResultDto(true, "更新成功"); } - + /// /// 查询分区列表 /// @@ -117,7 +115,7 @@ public class KpiAreaService : ApplicationService { return await _ruleAreaRepository.GetAreas(input); } - + /// /// 查询分区列表 /// diff --git a/src/SJZY.Track.Application/Services/ForewarningServices/RuleFactorCacheService.cs b/src/SJZY.Track.Application/Services/ForewarningServices/RuleFactorCacheService.cs index 6b7ffcb4..74bc9345 100644 --- a/src/SJZY.Track.Application/Services/ForewarningServices/RuleFactorCacheService.cs +++ b/src/SJZY.Track.Application/Services/ForewarningServices/RuleFactorCacheService.cs @@ -7,189 +7,188 @@ using Volo.Abp.DependencyInjection; namespace SJZY.Track.Application.Services.ForewarningServices; -public class RuleFactorCacheService:IRuleFactorCacheService,ITransientDependency +public class RuleFactorCacheService : IRuleFactorCacheService, ITransientDependency { - private const string GlobalFactorLockKey = "RuleFactorCacheService_GlobalLock"; - private const string GlobalRuleLockKey = "RuleFactorCacheService_GlobalLock"; - readonly IRuleFactorRepository _ruleFactorRepository; - readonly IRuleCollectRepository _ruleCollectRepository; - readonly IRuleRepository _ruleRepository; + private const string GlobalFactorLockKey = "RuleFactorCacheService_GlobalLock"; + private const string GlobalRuleLockKey = "RuleFactorCacheService_GlobalLock"; + readonly IRuleFactorRepository _ruleFactorRepository; + readonly IRuleItemRepository _ruleItemRepository; + readonly IRuleRepository _ruleRepository; - public RuleFactorCacheService(IRuleFactorRepository ruleFactorRepository, - IRuleCollectRepository ruleCollectRepository, IRuleRepository ruleRepository) - { - _ruleFactorRepository = ruleFactorRepository; - _ruleCollectRepository = ruleCollectRepository; - _ruleRepository = ruleRepository; - } + public RuleFactorCacheService(IRuleFactorRepository ruleFactorRepository, + IRuleItemRepository ruleItemRepository, IRuleRepository ruleRepository) + { + _ruleFactorRepository = ruleFactorRepository; + _ruleItemRepository = ruleItemRepository; + _ruleRepository = ruleRepository; + } - private string GetKey() - { - return $"{GlobalConst.RuleFactorKeyPrefix}:allFactor"; - } - - private string GetRuleKey() - { - return $"{GlobalConst.RuleFactorKeyPrefix}:allRule"; - } + private string GetKey() + { + return $"{GlobalConst.RuleFactorKeyPrefix}:allFactor"; + } - /// - /// 获取所有规则数据 - /// - /// - [NonAction] - public async Task GetAllFactorCollect() - { - - var key = GetRuleKey(); - var result =await RedisHelper.Client.GetAsync(key); - if (result == null) - { - using (var globalLock = RedisHelper.Client.Lock(GlobalRuleLockKey, 10)) - { - result =await RedisHelper.Client.GetAsync(key); - if (result != null) return result; + private string GetRuleKey() + { + return $"{GlobalConst.RuleFactorKeyPrefix}:allRule"; + } - var ruleCollect = await _ruleCollectRepository.GetListAsync(val => true); - if (ruleCollect == null || ruleCollect.Count == 0) + /// + /// 获取所有规则数据 + /// + /// + [NonAction] + public async Task GetAllFactorCollect() + { + var key = GetRuleKey(); + var result = await RedisHelper.Client.GetAsync(key); + if (result == null) + { + using (var globalLock = RedisHelper.Client.Lock(GlobalRuleLockKey, 10)) { - ForewarningRule[] rules = new ForewarningRule[0]; - await RedisHelper.Client.SetAsync(key,rules , TimeSpan.FromSeconds(20)); - return result; + result = await RedisHelper.Client.GetAsync(key); + if (result != null) return result; + + var ruleCollect = await _ruleItemRepository.GetListAsync(val => true); + if (ruleCollect == null || ruleCollect.Count == 0) + { + ForewarningRule[] rules = new ForewarningRule[0]; + await RedisHelper.Client.SetAsync(key, rules, TimeSpan.FromSeconds(20)); + return result; + } + + var ruleList = ruleCollect.SelectMany(RuleEntityToRule); + await RedisHelper.Client.SetAsync(key, ruleList); + return result; } + } - var ruleList = ruleCollect.SelectMany(RuleEntityToRule); - await RedisHelper.Client.SetAsync(key, ruleList); - return result; - } - } + return result; + } - return result; - } - - /// - /// 获取所有因素数据 - /// - /// 获取所有因素,返回值可能为空 - [NonAction] - public async Task> GetAllRuleFactor() - { - var key = GetKey(); - var result =await RedisHelper.Client.GetAsync>(key); - if (result == null) - { - using (var globalLock = RedisHelper.Client.Lock(GlobalFactorLockKey, 10)) - { - result =await RedisHelper.Client.GetAsync>(key); - if (result != null) return result; - - result = await GenerateAllRuleFactor(); - if (result == null || result.Count == 0) + /// + /// 获取所有因素数据 + /// + /// 获取所有因素,返回值可能为空 + [NonAction] + public async Task> GetAllRuleFactor() + { + var key = GetKey(); + var result = await RedisHelper.Client.GetAsync>(key); + if (result == null) + { + using (var globalLock = RedisHelper.Client.Lock(GlobalFactorLockKey, 10)) { - await RedisHelper.Client.SetAsync(key,new List() , TimeSpan.FromSeconds(20)); - return result; + result = await RedisHelper.Client.GetAsync>(key); + if (result != null) return result; + + result = await GenerateAllRuleFactor(); + if (result == null || result.Count == 0) + { + await RedisHelper.Client.SetAsync(key, new List(), TimeSpan.FromSeconds(20)); + return result; + } + + await RedisHelper.Client.SetAsync(key, result); + return result; } - - await RedisHelper.Client.SetAsync(key, result); - return result; - } - } + } - return result; - } - - [NonAction] - public void ClearFactorCache() - { - RedisHelper.Client.DelAsync(GetKey()); - } + return result; + } - [NonAction] - public void ClearRuleCache() - { - RedisHelper.Client.DelAsync(GetRuleKey()); - } + [NonAction] + public void ClearFactorCache() + { + RedisHelper.Client.DelAsync(GetKey()); + } - private async Task> GenerateAllRuleFactor() - { - var factors =await _ruleFactorRepository.GetAllList(); - var ruleTemplate =await _ruleRepository.GetListAsync(val => true); - var ruleMap = ruleTemplate.ToDictionary(val => val.Id); - var result = new List(); - foreach (var item in factors) - { - if(!ruleMap.TryGetValue(item.RuleId,out var rule)) - continue; - var ruleFactors = EntityToRuleFactor(item, rule); - result.AddRange(ruleFactors); - } + [NonAction] + public void ClearRuleCache() + { + RedisHelper.Client.DelAsync(GetRuleKey()); + } - return result; - } - - private ForewarningRule[] RuleEntityToRule(RuleCollectEntity entity) - { - var result = RuleCollectToRule(entity); - if (string.IsNullOrEmpty(entity.Month)) - { - return new ForewarningRule[] { result }; - } + private async Task> GenerateAllRuleFactor() + { + var factors = await _ruleFactorRepository.GetAllList(); + var ruleTemplate = await _ruleRepository.GetListAsync(val => true); + var ruleMap = ruleTemplate.ToDictionary(val => val.Id); + var result = new List(); + foreach (var item in factors) + { + if (!ruleMap.TryGetValue(item.RuleId, out var rule)) + continue; + var ruleFactors = EntityToRuleFactor(item, rule); + result.AddRange(ruleFactors); + } - var months = entity.Month.Split('/'); - var rules = new List(months.Length); + return result; + } - foreach (var month in months) - { - if (int.TryParse(month, out int monthInt)) - { - var rule = result; - rule.Month = monthInt; - rules.Add(rule); - } - } + private ForewarningRule[] RuleEntityToRule(RuleItemEntity entity) + { + var result = RuleCollectToRule(entity); + if (string.IsNullOrEmpty(entity.Month)) + { + return new ForewarningRule[] { result }; + } - return rules.ToArray(); - } + var months = entity.Month.Split('/'); + var rules = new List(months.Length); - private ForewarningRule RuleCollectToRule(RuleCollectEntity entity) - { - return new ForewarningRule - { - Id = entity.Id, - RuleId = entity.RuleId, - Remind = entity.Remind, - Timeliness = entity.Timeliness, - Count = entity.Count, - TrackStart = entity.TrackStart, - TrackEnd = entity.TrackEnd, - CargoType = entity.CargoType, - Month = null, - Area = entity.Area, - IsTransit = entity.IsTransit, - DeparturePort = entity.DeparturePort, - ProductCode = entity.ProductCode - }; - } + foreach (var month in months) + { + if (int.TryParse(month, out int monthInt)) + { + var rule = result; + rule.Month = monthInt; + rules.Add(rule); + } + } - private List EntityToRuleFactor(RuleFactorEntity entity,RuleEntity ruleTemplate) - { - List result = new List(); - foreach (var track in entity.Tracks) - { - var item = new RuleFactor() - { - CustomerId = ruleTemplate.CustomId, - RuleId = ruleTemplate.Id, - NotifyUser = track.NotifyUser, - NotifyTemplate = track.NotifyTemplate, - FactorItems = entity.FactorItems, - End = track.End, - Start = track.Start, - SystemId = ruleTemplate.SubSystemId - }; - result.Add(item); - } + return rules.ToArray(); + } - return result; - } + private ForewarningRule RuleCollectToRule(RuleItemEntity entity) + { + return new ForewarningRule + { + Id = entity.Id, + RuleId = entity.RuleId, + Remind = entity.Remind, + Timeliness = entity.Timeliness, + Count = entity.Count, + TrackStart = entity.TrackStart, + TrackEnd = entity.TrackEnd, + CargoType = entity.CargoType, + Month = null, + Area = entity.Area, + IsTransit = entity.IsTransit, + DeparturePort = entity.DeparturePort, + ProductCode = entity.ProductCode + }; + } + + private List EntityToRuleFactor(RuleFactorEntity entity, RuleEntity ruleTemplate) + { + List result = new List(); + foreach (var track in entity.Tracks) + { + var item = new RuleFactor() + { + CustomerId = ruleTemplate.CustomId, + RuleId = ruleTemplate.Id, + NotifyUser = track.NotifyUser, + NotifyTemplate = track.NotifyTemplate, + FactorItems = entity.FactorItems, + End = track.End, + Start = track.Start, + SystemId = ruleTemplate.SubSystemId + }; + result.Add(item); + } + + return result; + } } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleCollectRepository.cs b/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleItemRepository.cs similarity index 71% rename from src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleCollectRepository.cs rename to src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleItemRepository.cs index b48a7186..c06aa847 100644 --- a/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleCollectRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleItemRepository.cs @@ -2,12 +2,12 @@ using SJZY.Track.Domain.Dtos.Forewarning; namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate; -public interface IRuleCollectRepository:IBasicRepository +public interface IRuleItemRepository : IBasicRepository { /// /// 查询分页 /// /// /// - Task> QueryForewarningRule(QueryForewarningRuleRequest input); + Task> QueryForewarningRuleItemsAsync(QueryForewarningRuleRequest input); } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleRepository.cs b/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleRepository.cs index 04a32139..04488ef5 100644 --- a/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/IRuleRepository.cs @@ -2,11 +2,11 @@ using SJZY.Track.Domain.Dtos.Forewarning; namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate; -public interface IRuleRepository:IBasicRepository +public interface IRuleRepository : IBasicRepository { - Task CreateForewarning(RuleEntity rule, RuleCollectEntity[] factorList); - - Task UpdateForewarning(RuleEntity rule, RuleCollectEntity[] factorList); + Task CreateForewarning(RuleEntity rule, RuleItemEntity[] ruleItems); - Task> QueryForewarning(QueryForewarningRequest input); + Task UpdateForewarning(RuleEntity rule, RuleItemEntity[] factorList); + + Task> QueryForewarningRuleAsync(QueryForewarningRequest input); } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleFactorEntity.cs b/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleFactorEntity.cs index b356b062..0b99b712 100644 --- a/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleFactorEntity.cs +++ b/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleFactorEntity.cs @@ -5,14 +5,14 @@ using SJZY.Track.Domain.Consts; namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate; [ElasticsearchType(RelationName = GlobalConst.RuleFactorIndex)] -public class RuleFactorEntity:IdBaseIndex +public class RuleFactorEntity : IdBaseIndex { /// /// RuleId 表的id /// [Keyword(Index = true)] public int RuleId { get; set; } - + /// /// 获取或设置规则跟踪状态实体的列表。 /// @@ -52,4 +52,4 @@ public class RuleFactorEntity:IdBaseIndex /// 获取或设置产品编号的列表。 /// public List ProductCodes { get; set; } -} +} \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleCollectEntity.cs b/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleItemEntity.cs similarity index 92% rename from src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleCollectEntity.cs rename to src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleItemEntity.cs index ba4648e2..b08b1edc 100644 --- a/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleCollectEntity.cs +++ b/src/SJZY.Track.Domain/Aggregates/ForewarningAggregate/RuleItemEntity.cs @@ -1,16 +1,15 @@ namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate; -[SugarTable("t_rule_collect")] -public class RuleCollectEntity : IAggregateRoot,ICloneable +[SugarTable("t_rule_item")] +public class RuleItemEntity : IAggregateRoot, ICloneable { /// /// 自增主键 /// [SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)] public int Id { get; set; } - - [SugarColumn(ColumnName = "RuleId")] - public int RuleId { get; set; } + + [SugarColumn(ColumnName = "RuleId")] public int RuleId { get; set; } /// /// 提醒的时间(小时) @@ -29,7 +28,7 @@ public class RuleCollectEntity : IAggregateRoot,ICloneable /// [SugarColumn(ColumnName = "Count")] public int Count { get; set; } - + /// /// 起始轨迹 /// @@ -59,19 +58,19 @@ public class RuleCollectEntity : IAggregateRoot,ICloneable /// [SugarColumn(ColumnName = "Area")] public int? Area { get; set; } - + /// /// 是否中转 /// [SugarColumn(ColumnName = "IsTransit")] public bool? IsTransit { get; set; } - + /// /// 起运港口 /// [SugarColumn(ColumnName = "DeparturePort")] public string DeparturePort { get; set; } - + /// /// 产品编码 /// diff --git a/src/SJZY.Track.Domain/Aggregates/KPIAreaAggregate/IKpiAreaRepository.cs b/src/SJZY.Track.Domain/Aggregates/KPIAreaAggregate/IKpiAreaRepository.cs index cc1d5168..c3c906d9 100644 --- a/src/SJZY.Track.Domain/Aggregates/KPIAreaAggregate/IKpiAreaRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/KPIAreaAggregate/IKpiAreaRepository.cs @@ -2,7 +2,7 @@ using SJZY.Track.Domain.Dtos.Forewarning; namespace SJZY.Track.Domain.Aggregates.KPIAreaAggregate; -public interface IKpiAreaRepository:IBasicRepository +public interface IKpiAreaRepository : IBasicRepository { /// /// 创建分区 @@ -45,7 +45,7 @@ public interface IKpiAreaRepository:IBasicRepository /// /// Task> GetAreas(QueryAreaRequest query); - + /// /// 获取分区信息 /// @@ -58,7 +58,7 @@ public interface IKpiAreaRepository:IBasicRepository /// /// /// - Task GetAreaInfoById(int id); + Task GetAreaInfoById(int id); /// /// 获取所有区域信息 diff --git a/src/SJZY.Track.Repository/Repositories/KpiAreaRepository.cs b/src/SJZY.Track.Repository/Repositories/KpiAreaRepository.cs index 601821e5..9717997a 100644 --- a/src/SJZY.Track.Repository/Repositories/KpiAreaRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/KpiAreaRepository.cs @@ -1,17 +1,16 @@ using SJZY.Track.Domain; -using SJZY.Track.Domain.Aggregates.ForewarningAggregate; using SJZY.Track.Domain.Aggregates.KPIAreaAggregate; using SJZY.Track.Domain.Dtos.Forewarning; namespace SJZY.Track.Repository.Repositories; -public class KpiAreaRepository:BasicRepository ,IKpiAreaRepository,ITransientDependency +public class KpiAreaRepository : BasicRepository, IKpiAreaRepository, ITransientDependency { public async ValueTask CreateAreaAsync(RuleAreaEntity entity) { - return await InsertReturnIdentityAsync(entity); + return await InsertReturnIdentityAsync(entity); } - + public async ValueTask AddAreaInfoAsync(RuleAreaInfoEntity entity) { return await Context.Insertable(entity).ExecuteReturnIdentityAsync(); @@ -24,12 +23,12 @@ public class KpiAreaRepository:BasicRepository ,IKpiAreaReposito await Context.Deleteable().Where(x => x.AreaId == areaId).ExecuteCommandAsync(); transaction.Complete(); } - + public Task DeleteAreaInfo(int areaInfoId) { - return Context.Deleteable().Where(val=>val.Id==areaInfoId).ExecuteCommandAsync(); + return Context.Deleteable().Where(val => val.Id == areaInfoId).ExecuteCommandAsync(); } - + public Task UpdateAreaInfoAsync(RuleAreaInfoEntity entity) { return Context.Updateable(entity).ExecuteCommandAsync(); @@ -47,14 +46,14 @@ public class KpiAreaRepository:BasicRepository ,IKpiAreaReposito { queryable = queryable.Where(x => x.Name.Contains(query.Name)); } - + if (query.SystemId.HasValue) { queryable = queryable.Where(x => x.SubSystemId == query.SystemId.Value); } - + return await queryable.OrderBy(x => x.Id, OrderByType.Desc) - .Select(val=>new AreaDto() + .Select(val => new AreaDto() { Id = val.Id, Name = val.Name, @@ -74,7 +73,7 @@ public class KpiAreaRepository:BasicRepository ,IKpiAreaReposito var queryable = Context.Queryable(); queryable = queryable.Where(x => x.AreaId == query.AreaId); return await queryable.OrderBy(x => x.Id, OrderByType.Desc) - .Select(val=>new RuleAreaInfoDto() + .Select(val => new RuleAreaInfoDto() { Id = val.Id, AreaId = val.AreaId, @@ -87,9 +86,9 @@ public class KpiAreaRepository:BasicRepository ,IKpiAreaReposito .ToPagedListAsync(query.PageIndex, query.PageSize); } - public Task GetAreaInfoById(int id) + public Task GetAreaInfoById(int id) { - return Context.Queryable().FirstAsync(val => val.Id == id); + return Context.Queryable().FirstAsync(val => val.Id == id)!; } /// diff --git a/src/SJZY.Track.Repository/Repositories/RuleCollectRepository.cs b/src/SJZY.Track.Repository/Repositories/RuleItemRepository.cs similarity index 80% rename from src/SJZY.Track.Repository/Repositories/RuleCollectRepository.cs rename to src/SJZY.Track.Repository/Repositories/RuleItemRepository.cs index 250eedf1..03139fb6 100644 --- a/src/SJZY.Track.Repository/Repositories/RuleCollectRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/RuleItemRepository.cs @@ -3,28 +3,28 @@ using SJZY.Track.Domain.Dtos.Forewarning; namespace SJZY.Track.Repository.Repositories; -public class RuleCollectRepository: BasicRepository, IRuleCollectRepository,ITransientDependency +public class RuleItemRepository : BasicRepository, IRuleItemRepository, ITransientDependency { /// /// 查询预警规则分页信息 /// /// /// - public Task> QueryForewarningRule(QueryForewarningRuleRequest input) + public Task> QueryForewarningRuleItemsAsync(QueryForewarningRuleRequest input) { - var query = Context.Queryable() + var query = Context.Queryable() .Where(val => val.RuleId == input.RuleId); - + if (!string.IsNullOrEmpty(input.SortField)) { query = query.OrderByPropertyName(input.SortField, input.IsAsc ? OrderByType.Asc : OrderByType.Desc); } - - return query.Select(val=>MapToDto(val)) + + return query.Select(val => MapToDto(val)) .ToPagedListAsync(input.PageIndex, input.PageSize); } - private RuleCollectDto MapToDto(RuleCollectEntity entity) + private RuleCollectDto MapToDto(RuleItemEntity entity) { return new RuleCollectDto() { diff --git a/src/SJZY.Track.Repository/Repositories/RuleRepository.cs b/src/SJZY.Track.Repository/Repositories/RuleRepository.cs index 4867ab3f..a285017a 100644 --- a/src/SJZY.Track.Repository/Repositories/RuleRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/RuleRepository.cs @@ -4,27 +4,28 @@ using SJZY.Track.Domain.Dtos.Forewarning; namespace SJZY.Track.Repository.Repositories; -public class RuleRepository:BasicRepository ,IRuleRepository,ITransientDependency +public class RuleRepository : BasicRepository, IRuleRepository, ITransientDependency { - public async Task CreateForewarning(RuleEntity rule, RuleCollectEntity[] factorList) + public async Task CreateForewarning(RuleEntity rule, RuleItemEntity[] ruleItems) { using var tran = TransactionHelper.GetReadCommitted(); var ruleId = await InsertReturnIdentityAsync(rule); - foreach (var item in factorList) + foreach (var item in ruleItems) { item.RuleId = ruleId; } - await Context.Insertable(factorList).ExecuteCommandAsync(); + + await Context.Insertable(ruleItems).ExecuteCommandAsync(); tran.Complete(); return ruleId; } - - public async Task UpdateForewarning(RuleEntity rule,RuleCollectEntity[] factorList) + + public async Task UpdateForewarning(RuleEntity rule, RuleItemEntity[] factorList) { using var tran = TransactionHelper.GetReadCommitted(); await UpdateAsync(rule); - await Context.Deleteable().Where(x=>x.RuleId==rule.Id).ExecuteCommandAsync(); + await Context.Deleteable().Where(x => x.RuleId == rule.Id).ExecuteCommandAsync(); await Context.Insertable(factorList).ExecuteCommandAsync(); tran.Complete(); } @@ -34,12 +35,13 @@ public class RuleRepository:BasicRepository ,IRuleRepository,ITransi /// /// /// - public Task> QueryForewarning(QueryForewarningRequest input) + public Task> QueryForewarningRuleAsync(QueryForewarningRequest input) { var query = Context.Queryable() - .WhereIF(input.SystemId.HasValue,val=>val.SubSystemId == input.SystemId) - .WhereIF(string.IsNullOrEmpty(input.KeyWord), val=> val.CustomName.Contains(input.KeyWord)||val.Name.Contains(input.KeyWord)); - + .WhereIF(input.SystemId.HasValue, val => val.SubSystemId == input.SystemId) + .WhereIF(!string.IsNullOrEmpty(input.KeyWord), + val => val.CustomName.Contains(input.KeyWord!) || val.Name.Contains(input.KeyWord!)); + if (!string.IsNullOrEmpty(input.SortField)) { query = query.OrderByPropertyName(input.SortField, input.IsAsc ? OrderByType.Asc : OrderByType.Desc); @@ -47,7 +49,4 @@ public class RuleRepository:BasicRepository ,IRuleRepository,ITransi return query.ToPagedListAsync(input.PageIndex, input.PageSize); } - - - } \ No newline at end of file