track/src/SJZY.Track.Application/Helpers/ForewarningHelper.cs
2024-08-05 15:43:04 +08:00

243 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.Common;
using SJZY.Track.Domain.Dtos.Forewarning;
using SJZY.Track.Share.Enums;
namespace SJZY.Track.Application.Helpers;
public class ForewarningHelper
{
/// <summary>
/// 递推分裂预警规则列表
/// </summary>
/// <param name="statusSpans"></param>
/// <param name="factors"></param>
/// <returns></returns>
public static List<WarningRuleEntity> CalcRuleList(List<WarningNitifyDto> statusSpans,
List<WarningFactorDto> 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<WarningNitifyDto> statusSpans, List<WarningRuleEntity> 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].StartTrackStatus = span.StartTrackStatus;
rules[row].EndTrackStatusId = span.EndTrackStatusId;
rules[row].EndTrackStatus = span.EndTrackStatus;
}
}
}
private static void FillFactor(WarningFactorDto factor, List<WarningRuleEntity> 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.Area:
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<WarningFactorEntity> MapFactorEntities(List<WarningFactorDto> warningFactors)
{
return warningFactors.Select(x => new WarningFactorEntity
{
Type = x.FactorType,
Value = x.FactorValue.ToJson()
}).ToList();
}
public static List<WarningNotifyEntity> 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, List<IdWithNameDto> statusList)
{
var statusDic = statusList.ToDictionary(x => x.Id, x => x.Name);
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,
StartTrackStatus = statusDic.TryGetValue(x.StartTrackStatusId, out var start) ? start : "",
EndTrackStatusId = x.EndTrackStatusId,
EndTrackStatus = statusDic.TryGetValue(x.EndTrackStatusId, out var end) ? end : "",
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<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.Area:
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;
}
}