using System.Dynamic; using Nest; using Newtonsoft.Json.Linq; using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.Track.Application.Contract.Dtos.Forewarning; using SJZY.Track.Domain.Aggregates.ForewarningAggregate; using SJZY.Track.Domain.Dtos.Forewarning; using SJZY.Track.Domain.Enums; using SqlSugar; namespace SJZY.Track.Application.Helpers; public class ForewarningHelper { /// /// 递推分裂预警规则列表 /// /// /// /// public static List CalcRuleList(List statusSpans, List factors) { if (statusSpans.Count == 0 || factors.Count == 0) { throw new BusinessException(message: "轨迹状态区间或因素列表为空"); } var len = statusSpans.Count * factors.Select(f => f.FactorValue.Count).Aggregate((pre, cur) => pre * cur); if (len == 0) { throw new BusinessException(message: "轨迹状态区间或因素列表为空"); } var rules = Enumerable.Range(0, len).Select(_ => new WarningRuleEntity()).ToList(); var repeat = len / statusSpans.Count; FillStatus(statusSpans, rules, repeat); foreach (var factor in factors) { var factorValueCount = factor.FactorValue.Count; // repeat梯度下降,与times成反比关系 repeat /= factorValueCount; var times = len / repeat / factorValueCount; FillFactor(factor, rules, repeat, times); } return rules; } private static void FillStatus(List statusSpans, List rules, int repeat) { var row = 0; foreach (var span in statusSpans) { for (var i = 0; i < repeat; i++, row++) { rules[row].StartTrackStatusId = span.StartTrackStatusId; rules[row].EndTrackStatusId = span.EndTrackStatusId; } } } private static void FillFactor(WarningFactorDto factor, List rules, int repeat, int times) { var row = 0; for (var i = 0; i < times; i++) { foreach (var value in factor.FactorValue) { var strValue = value.ToString(); if (strValue.IsNullOrEmpty()) { throw new BusinessException(message: "因素值不能为空"); } for (var j = 0; j < repeat; j++, row++) { switch (factor.FactorType) { case RuleFactorType.CargoType: if (value.Type is not JTokenType.String) { throw new BusinessException(message: "货物类型只接收字符串"); } rules[row].CargoType = strValue; break; case RuleFactorType.Months: foreach (var item in strValue.Split("/")) { if (!int.TryParse(item, out var month) || month < 1 || month > 12) { throw new BusinessException(message: "请输入合法的月份,多个月份请以'/'连接"); } } rules[row].Months = strValue; break; case RuleFactorType.Areas: if (value.Type is not JTokenType.Integer) { throw new BusinessException(message: "分区请传id"); } rules[row].AreaId = int.Parse(strValue); break; case RuleFactorType.IsTransit: if (value.Type is not JTokenType.Boolean) { throw new BusinessException(message: "是否中转只接收bool类型"); } rules[row].IsTransit = bool.Parse(strValue); break; case RuleFactorType.LeavePort: if (value.Type is not JTokenType.String) { throw new BusinessException(message: "货物类型只接收字符串"); } rules[row].LeavePort = strValue; break; case RuleFactorType.ProductCode: if (value.Type is not JTokenType.String) { throw new BusinessException(message: "货物类型只接收字符串"); } rules[row].ProductCode = strValue; break; default: throw new BusinessException(message: $"不支持的因素:{factor.FactorType}"); } } } } } public static List MapFactorEntities(List warningFactors) { return warningFactors.Select(x => new WarningFactorEntity { Type = x.FactorType, Value = x.FactorValue.ToJson() }).ToList(); } public static List MapNotifyEntities(CreateWarningInput input) { return input.TrackStatusSpans.Select(x => new WarningNotifyEntity { StartTrackStatusId = x.StartTrackStatusId, EndTrackStatusId = x.EndTrackStatusId, NotifyMode = input.NotifyMode, NotifyTemplate = input.NotifyTemplate, NotifyUserId = x.NotifyUserId }).ToList(); } public static EditWarningOutput MapWarningSummary(WarningEntity warning) { return new EditWarningOutput { Name = warning.Name, SubSystemId = warning.SubSystemId, CustomerId = warning.CustomerId, NotifyMode = warning.WarningNotifies.First().NotifyMode, NotifyTemplate = warning.WarningNotifies.First().NotifyTemplate, TrackStatusSpans = warning.WarningNotifies.Select(x => new WarningNotifyWithIdDto { Id = x.Id, StartTrackStatusId = x.StartTrackStatusId, EndTrackStatusId = x.EndTrackStatusId, NotifyUserId = x.NotifyUserId, }).ToList(), WarningFactors = warning.WarningFactors.Select(x => new WarningFactorWithIdDto { Id = x.Id, FactorType = x.Type, FactorValue = JArray.Parse(x.Value), }).ToList() }; } public static List DynamicCalcRuleList(List rules, List factors) { var dynamicList = new List(); foreach (var rule in rules) { dynamic dynamicRule = new ExpandoObject(); var dynamicRuleDict = (IDictionary)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; } }