connect:预警规则列表动态计算好给到前端

This commit is contained in:
xiaolipro 2024-07-26 17:12:46 +08:00
parent d5135249f7
commit f00805437d
7 changed files with 150 additions and 60 deletions

View File

@ -13,7 +13,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
private readonly IOrderRepository _orderRepository;
private readonly IForewarningNotifyService _forewarningNotifyService;
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository,
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository,
IForewarningNotifyService forewarningNotifyService)
{
_orderRepository = orderRepository;
@ -23,19 +23,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
[CapSubscribe(GlobalConst.TrackChangeAfterUpdateOrderSubscribe)]
public async Task ConsumerAsync(TrackChangeAfterUpdateOrderEvent @event)
{
var orders = await _orderRepository.GetListAsync(x => @event.OrderIds.Contains(x.Id),
x => new OrderEntity
{
Id = x.Id,
IsCompleted = x.IsCompleted,
LatestTrackContent = x.LatestTrackContent,
LatestTrackEnContent = x.LatestTrackEnContent,
LatestTrackPlace = x.LatestTrackPlace,
LatestTrackTime = x.LatestTrackTime,
LatestTrackTimeZone = x.LatestTrackTimeZone,
ArrivalCountry = x.ArrivalCountry,
ArrivalCity = x.ArrivalCity,
});
var orders = await _orderRepository.GetListAsync(x => @event.OrderIds.Contains(x.Id), x => MapOrderSummary(x));
if (orders.Count == 0) return;
@ -70,41 +58,78 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
x.IsCompleted, x.LatestTrackContent, x.LatestTrackEnContent, x.LatestTrackPlace, x.LatestTrackTime,
x.LatestTrackTimeZone
});
// 预警计算
WarningCalculationAsync(orders);
}
private ForewarningOrderModel OrderToForewarningOrderModel(OrderEntity order)
{
return new ForewarningOrderModel
private Task WarningCalculationAsync(List<OrderEntity> orders)
{
Id = order.Id,
Track = DetermineTrackBasedOnOrderDetails(order),
SystemId = order.SubSystemId,
CustomerId = order.CustomId,
CargoType = order.CargoType,
Month = order.CreateTime.Month,
Area = DetermineAreaBasedOnOrderDetails(order),
IsTransit = order.IsTransfer,
DeparturePort = order.LeavePort,
ProductCode = order.ProductCode
};
}
var forewarningOrderModels = orders.Select(OrderToForewarningOrderModel).ToList();
return Task.CompletedTask;
}
private OrderEntity MapOrderSummary(OrderEntity x)
{
return new OrderEntity
{
Id = x.Id,
// 轨迹
IsCompleted = x.IsCompleted,
LatestTrackContent = x.LatestTrackContent,
LatestTrackEnContent = x.LatestTrackEnContent,
LatestTrackPlace = x.LatestTrackPlace,
LatestTrackTime = x.LatestTrackTime,
LatestTrackTimeZone = x.LatestTrackTimeZone,
// 因素
CargoType = x.CargoType,
CreateTime = x.CreateTime,
ArrivalCountry = x.ArrivalCountry,
ArrivalProvince = x.ArrivalProvince,
ArrivalCity = x.ArrivalCity,
ArrivalPostCode = x.ArrivalPostCode,
IsTransit = x.IsTransit,
LeavePort = x.LeavePort,
ProductCode = x.ProductCode
};
}
private ForewarningOrderModel OrderToForewarningOrderModel(OrderEntity order)
{
return new ForewarningOrderModel
{
Id = order.Id,
Track = DetermineTrackBasedOnOrderDetails(order),
SystemId = order.SubSystemId,
CustomerId = order.CustomId,
CargoType = order.CargoType,
Month = order.CreateTime.Month,
Area = DetermineAreaBasedOnOrderDetails(order),
IsTransit = order.IsTransit,
LeavePort = order.LeavePort,
ProductCode = order.ProductCode
};
}
// Placeholder methods for deriving or converting values. You'll need to implement these based on your specific logic.
private int DetermineTrackBasedOnOrderDetails(OrderEntity order)
{
// Implement logic to determine Track
return default;
}
private int DetermineTrackBasedOnOrderDetails(OrderEntity order)
{
// Implement logic to determine Track
return default;
}
private int? DetermineMonthBasedOnOrderDetails(OrderEntity order)
{
// Implement logic to determine Month
return default;
}
private int? DetermineMonthBasedOnOrderDetails(OrderEntity order)
{
// Implement logic to determine Month
return default;
}
private int? DetermineAreaBasedOnOrderDetails(OrderEntity order)
{
// Implement logic to determine Area
return default;
}
private int? DetermineAreaBasedOnOrderDetails(OrderEntity order)
{
// Implement logic to determine Area
return default;
}
}

View File

@ -1,3 +1,5 @@
using System.Dynamic;
using Nest;
using Newtonsoft.Json.Linq;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Dtos.Forewarning;
@ -30,7 +32,7 @@ public class ForewarningHelper
throw new BusinessException(message: "轨迹状态区间或因素列表为空");
}
var rules = Enumerable.Repeat(new WarningRuleEntity(), len).ToList();
var rules = Enumerable.Range(0, len).Select(_ => new WarningRuleEntity()).ToList();
var repeat = len / statusSpans.Count;
@ -41,7 +43,7 @@ public class ForewarningHelper
var factorValueCount = factor.FactorValue.Count;
// repeat梯度下降,与times成反比关系
repeat /= factor.FactorValue.Count;
repeat /= factorValueCount;
var times = len / repeat / factorValueCount;
FillFactor(factor, rules, repeat, times);
}
@ -184,4 +186,53 @@ public class ForewarningHelper
}).ToList()
};
}
public static List<dynamic> DynamicCalcRuleList(List<WarningRuleVo> rules, List<RuleFactorType> factors)
{
var dynamicList = new List<dynamic>();
foreach (var rule in rules)
{
dynamic dynamicRule = new ExpandoObject();
var dynamicRuleDict = (IDictionary<string, object?>)dynamicRule;
dynamicRuleDict[nameof(Id)] = rule.Id;
dynamicRuleDict[nameof(rule.StartTrackStatus)] = rule.StartTrackStatus;
dynamicRuleDict[nameof(rule.EndTrackStatus)] = rule.EndTrackStatus;
foreach (var factor in factors)
{
switch (factor)
{
case RuleFactorType.CargoType:
dynamicRuleDict[nameof(rule.CargoType)] = rule.CargoType;
break;
case RuleFactorType.Months:
dynamicRuleDict[nameof(rule.Months)] = rule.Months;
break;
case RuleFactorType.Areas:
dynamicRuleDict[nameof(rule.Area)] = rule.Area;
break;
case RuleFactorType.IsTransit:
dynamicRuleDict[nameof(rule.IsTransit)] = rule.IsTransit;
break;
case RuleFactorType.LeavePort:
dynamicRuleDict[nameof(rule.LeavePort)] = rule.LeavePort;
break;
case RuleFactorType.ProductCode:
dynamicRuleDict[nameof(rule.ProductCode)] = rule.ProductCode;
break;
default:
throw new BusinessException(message: $"不支持的因素:{factor}");
}
}
dynamicRuleDict[nameof(rule.TotalTimeSpan)] = rule.TotalTimeSpan;
dynamicRuleDict[nameof(rule.WarnTimeSpan)] = rule.WarnTimeSpan;
dynamicRuleDict[nameof(rule.WarnCount)] = rule.WarnCount;
dynamicList.Add(dynamicRule);
}
return dynamicList;
}
}

View File

@ -221,7 +221,7 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
case RuleFactorType.CargoType:
return rule.CargoType;
case RuleFactorType.LeavePort:
return rule.DeparturePort;
return rule.LeavePort;
case RuleFactorType.Months:
return rule.Month.HasValue ? rule.Month.Value.ToString() : throw new Exception("月份不能为空");
case RuleFactorType.ProductCode:

View File

@ -3,6 +3,7 @@ using SJZY.Track.Application.Contract.Dtos.Forewarning;
using SJZY.Track.Application.Helpers;
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
using SJZY.Track.Domain.Dtos.Forewarning;
using SJZY.Track.Domain.Queries;
namespace SJZY.Track.Application.Services.ForewarningServices;
@ -38,6 +39,13 @@ public class ForewarningService : ApplicationService
public async Task<bool> CreateWarning(CreateWarningInput input)
{
var warning = ObjectMapper.Map<CreateWarningInput, WarningEntity>(input);
if (await _warningRepository.IsAnyAsync(x =>
x.SubSystemId == warning.SubSystemId && x.CustomerId == warning.CustomerId && x.Name == warning.Name))
{
throw new BusinessException(message: "该子系统下的客户已经存在一个同名预警: " + warning.Name);
}
warning.WarningRules = ForewarningHelper.CalcRuleList(input.TrackStatusSpans, input.WarningFactors);
warning.WarningFactors = ForewarningHelper.MapFactorEntities(input.WarningFactors);
warning.WarningNotifies = ForewarningHelper.MapNotifyEntities(input);
@ -126,18 +134,21 @@ public class ForewarningService : ApplicationService
return await _warningRepository.TurnWarningAsync(warning);
}
/// <summary>
/// 查询预警规则列表
/// </summary>
/// <param name="warningId">预警规则id</param>
/// <param name="factorQuery"></param>
/// <returns></returns>
[HttpGet("GetWarningRuleList")]
public async Task<List<WarningRuleVo>> GetWarningRuleListAsync([Required] int warningId)
public async Task<List<dynamic>> GetWarningRuleListAsync([Required] int warningId, [FromServices] IBasicQuery<WarningFactorEntity> factorQuery)
{
var factors = await factorQuery.GetListAsync(x => x.WarningId == warningId, x => x.Type);
var rules = await _warningRepository.GetWarningRuleListAsync(warningId);
return rules;
var dynamicList = ForewarningHelper.DynamicCalcRuleList(rules, factors);
return dynamicList;
}
/// <summary>

View File

@ -16,7 +16,7 @@ public class ForewarningOrderModel:IForewarningFactorValue
public int CustomerId { get; set; }
public string CargoType { get; set; }
public string? CargoType { get; set; }
public int? Month { get; set; }
@ -24,7 +24,10 @@ public class ForewarningOrderModel:IForewarningFactorValue
public bool? IsTransit { get; set; }
public string DeparturePort { get; set; }
/// <summary>
/// 起运港
/// </summary>
public string? LeavePort { get; set; }
public string ProductCode { get; set; }
public string? ProductCode { get; set; }
}

View File

@ -13,12 +13,12 @@ public record struct ForewarningRuleItem:IForewarningFactorValue
public int Count { get; set; }
public int TrackStart { get; set; }
public int TrackEnd { get; set; }
public string CargoType { get; set; }
public string? CargoType { get; set; }
public int? Month { get; set; }
public int? Area { get; set; }
public bool? IsTransit { get; set; }
public string DeparturePort { get; set; }
public string ProductCode { get; set; }
public string? LeavePort { get; set; }
public string? ProductCode { get; set; }
public string Conect { get; set; }

View File

@ -2,7 +2,7 @@ namespace SJZY.Track.Domain.Dtos.Forewarning;
public interface IForewarningFactorValue
{
public string CargoType { get; set; }
public string? CargoType { get; set; }
public int? Month { get; set; }
@ -10,7 +10,7 @@ public interface IForewarningFactorValue
public bool? IsTransit { get; set; }
public string DeparturePort { get; set; }
public string? LeavePort { get; set; }
public string ProductCode { get; set; }
public string? ProductCode { get; set; }
}