importance:预警初步重构
This commit is contained in:
parent
740bc61558
commit
c3f904ccdc
@ -0,0 +1,17 @@
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
namespace SJZY.Track.Application.Contract.Dtos.Forewarning;
|
||||
|
||||
public class ModifyTimeSpanInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警id
|
||||
/// </summary>
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 规则详情中的时效相关信息
|
||||
/// </summary>
|
||||
public List<WarningTimeSpanDto> Items { get; set; } = new();
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
namespace SJZY.Track.Application.Contract.Dtos.Forewarning;
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则时效
|
||||
/// </summary>
|
||||
public class WarningTimeSpanDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警规则id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时效
|
||||
/// </summary>
|
||||
public float TotalTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒时效
|
||||
/// </summary>
|
||||
public float WarnTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒次数
|
||||
/// </summary>
|
||||
public int WarnCount { get; set; }
|
||||
}
|
||||
@ -12,7 +12,7 @@ public interface IRuleFactorCacheService
|
||||
/// 获取所有因子收集的规则。
|
||||
/// </summary>
|
||||
/// <returns>规则数组。</returns>
|
||||
Task<ForewarningRule[]> GetAllFactorCollect();
|
||||
Task<ForewarningRuleItem[]> GetAllFactorCollect();
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有规则因子。
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using AutoMapper;
|
||||
using SJZY.Track.Application.Contract.Dtos.Forewarning;
|
||||
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
@ -9,9 +10,8 @@ public class ForewarningMapperProfile :Profile
|
||||
{
|
||||
public ForewarningMapperProfile()
|
||||
{
|
||||
CreateMap<CreateRuleFactorRequest, RuleEntity>(MemberList.None);
|
||||
CreateMap<RuleTrackStateDto, RuleTrackStateModel>();
|
||||
CreateMap<FactorItemDto, FactorItemModel>();
|
||||
CreateMap<CreateWarningInput, WarningEntity>(MemberList.None);
|
||||
CreateMap<WarningTimeSpanDto, WarningRuleEntity>(MemberList.None);
|
||||
CreateMap<RuleAreaEntity, AreaDto>();
|
||||
CreateMap<UpdateRuleAreaRequest, RuleAreaEntity>(MemberList.None);
|
||||
CreateMap<AddRuleAreaInfoRequest, RuleAreaInfoEntity>(MemberList.None)
|
||||
@ -32,17 +32,5 @@ public class ForewarningMapperProfile :Profile
|
||||
.ForMember(dest => dest.City, opt => opt.MapFrom(src => src.City))
|
||||
.ForMember(dest => dest.LeftPostcode, opt => opt.MapFrom(src => src.LeftPostCode))
|
||||
.ForMember(dest => dest.RightPostcode, opt => opt.MapFrom(src => src.RightPostCode));
|
||||
|
||||
CreateMap<CreateRuleFactorRequest, RuleFactorEntity>(MemberList.None)
|
||||
.ForMember(dest => dest.RuleId, opt => opt.MapFrom(src => src.RuleId))
|
||||
.ForMember(dest => dest.Tracks, opt => opt.MapFrom(src => src.Tracks))
|
||||
.ForMember(dest => dest.FactorItems, opt => opt.MapFrom(src => src.FactorItems))
|
||||
.ForMember(dest => dest.CargoTypes, opt => opt.MapFrom(src => src.CargoTypes))
|
||||
.ForMember(dest => dest.Months, opt => opt.MapFrom(src => src.Months.Select(m => m.ToString())))
|
||||
.ForMember(dest => dest.IsTransit, opt => opt.MapFrom(src => src.IsTransit.Select(i => i == 1)))
|
||||
.ForMember(dest => dest.Areas, opt => opt.MapFrom(src => src.Areas))
|
||||
.ForMember(dest => dest.DeparturePorts, opt => opt.MapFrom(src => src.DeparturePorts))
|
||||
.ForMember(dest => dest.ProductCodes, opt => opt.MapFrom(src => src.ProductCodes));
|
||||
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,6 @@
|
||||
using SJZY.Track.Application.Contract.Events;
|
||||
using SJZY.Track.Application.Contract.Services;
|
||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Consts;
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
@ -12,15 +11,12 @@ namespace SJZY.Track.Application.CAP.EventHandlers;
|
||||
public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICapSubscribe
|
||||
{
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
private readonly ITrackDetailsRepository _trackDetailsRepository;
|
||||
private readonly IForewarningNotifyService _forewarningNotifyService;
|
||||
|
||||
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository,
|
||||
ITrackDetailsRepository trackDetailsRepository,
|
||||
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository,
|
||||
IForewarningNotifyService forewarningNotifyService)
|
||||
{
|
||||
_orderRepository = orderRepository;
|
||||
_trackDetailsRepository = trackDetailsRepository;
|
||||
_forewarningNotifyService = forewarningNotifyService;
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscrib
|
||||
[CapSubscribe(GlobalConst.TrackPushCompletedSubscribe, Group = GlobalConst.TrackPushSubscribe)]
|
||||
public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event)
|
||||
{
|
||||
string logStr = null;
|
||||
string? logStr = null;
|
||||
var optionType = Base64Helper.DeSerialize<string>(@event.Attach);
|
||||
if (optionType == OptionType.新增.ToString())
|
||||
{
|
||||
|
||||
@ -23,8 +23,8 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
|
||||
private readonly ITrackPushCacheService _trackPushCacheService;
|
||||
private readonly ITrackDetailsRepository _trackDetailsRepository;
|
||||
private readonly ITrackPushRecordsRepository _trackPushRecordsRepository;
|
||||
private List<TrackPushContentConfigDto> _pushConfigs;
|
||||
private List<OrderEntity> _orders;
|
||||
private List<TrackPushContentConfigDto> _pushConfigs = null!;
|
||||
private List<OrderEntity> _orders = null!;
|
||||
|
||||
public TrackPushEventHandler(IHttpClientProxy<IInterfaceForwardServiceV2> httpClientProxy,
|
||||
IOrderRepository orderRepository, ITrackPushCacheService trackPushCacheService,
|
||||
|
||||
@ -1,65 +0,0 @@
|
||||
using JetBrains.Annotations;
|
||||
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
namespace SJZY.Track.Application.Helpers;
|
||||
|
||||
public class ForewarningFactorHelper
|
||||
{
|
||||
public static RuleItemEntity[] GetFactorItem([NotNull] RuleFactorEntity ruleFactors)
|
||||
{
|
||||
var total = Factorial(ruleFactors);
|
||||
var ruleCollect = AllocateFactor(total, ruleFactors.RuleId);
|
||||
Assignment(ruleCollect, total, ruleFactors.Tracks, (item, value) =>
|
||||
{
|
||||
item.TrackEnd = value.End;
|
||||
item.TrackStart = value.Start;
|
||||
});
|
||||
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<T>(Span<RuleItemEntity> ruleCollect, int total, IReadOnlyList<T> values,
|
||||
Action<RuleItemEntity, T> action)
|
||||
{
|
||||
if (values.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var segment = total / values.Count;
|
||||
for (int index = 0; index < values.Count; index++)
|
||||
{
|
||||
var start = index * segment;
|
||||
var assignmentSlice = ruleCollect.Slice(start, segment);
|
||||
foreach (var item in assignmentSlice)
|
||||
{
|
||||
action(item, values[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Span<RuleItemEntity> AllocateFactor(int total, int ruleId)
|
||||
{
|
||||
Span<RuleItemEntity> factors = new RuleItemEntity[total];
|
||||
for (int index = 0; index < total; index++)
|
||||
{
|
||||
factors[index] = new RuleItemEntity()
|
||||
{
|
||||
RuleId = ruleId
|
||||
};
|
||||
}
|
||||
|
||||
return factors;
|
||||
}
|
||||
|
||||
internal static int Factorial(RuleFactorEntity ruleFactors)
|
||||
{
|
||||
return ruleFactors.Tracks.Count* ruleFactors.CargoTypes.Count * ruleFactors.Months.Count * ruleFactors.Areas.Count *
|
||||
ruleFactors.IsTransit.Count * ruleFactors.DeparturePorts.Count * ruleFactors.ProductCodes.Count;
|
||||
}
|
||||
}
|
||||
139
src/SJZY.Track.Application/Helpers/ForewarningHelper.cs
Normal file
139
src/SJZY.Track.Application/Helpers/ForewarningHelper.cs
Normal file
@ -0,0 +1,139 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SJZY.Expand.ABP.Core.PublicMethords;
|
||||
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
using SJZY.Track.Domain.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<TrackStatusSpanDto> statusSpans,
|
||||
List<WarningFactorDto> factors)
|
||||
{
|
||||
var len = statusSpans.Count * factors.Select(f => f.FactorValue.Count).Aggregate((pre, cur) => pre * cur);
|
||||
if (len == 0)
|
||||
{
|
||||
throw new BusinessException(message: "轨迹状态区间或因素列表为空");
|
||||
}
|
||||
|
||||
var rules = new List<WarningRuleEntity>(len);
|
||||
|
||||
var repeat = len / statusSpans.Count;
|
||||
|
||||
FillStatus(statusSpans, rules, repeat);
|
||||
|
||||
foreach (var factor in factors)
|
||||
{
|
||||
var factorValueCount = factor.FactorValue.Count;
|
||||
repeat /= factor.FactorValue.Count; // repeat梯度下降,与times成反比关系
|
||||
|
||||
for (int time = 0; time < len / repeat / factorValueCount; time++)
|
||||
{
|
||||
FillFactor(factor, rules, repeat, time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return rules;
|
||||
}
|
||||
|
||||
private static void FillStatus(List<TrackStatusSpanDto> statusSpans, List<WarningRuleEntity> rules, int repeat)
|
||||
{
|
||||
for (var i = 0; i < statusSpans.Count; i++)
|
||||
{
|
||||
var span = statusSpans[i];
|
||||
|
||||
for (var j = 0; j < repeat; j++)
|
||||
{
|
||||
var row = i * repeat + j;
|
||||
rules[row].StartTrackStatusId = span.StartTrackStatusId;
|
||||
rules[row].EndTrackStatusId = span.EndTrackStatusId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void FillFactor(WarningFactorDto factor, List<WarningRuleEntity> rules, int repeat, int time)
|
||||
{
|
||||
for (var i = 0; i < factor.FactorValue.Count * time; i++)
|
||||
{
|
||||
for (var j = 0; j < repeat; j++)
|
||||
{
|
||||
var row = i * repeat + j;
|
||||
var value = factor.FactorValue[row];
|
||||
var strValue = value.ToString();
|
||||
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<WarningFactorEntity> MapFactorEntities(List<WarningFactorDto> warningFactors)
|
||||
{
|
||||
return warningFactors.Select(x => new WarningFactorEntity
|
||||
{
|
||||
Type = x.FactorType,
|
||||
Value = x.FactorValue.ToJson()
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
@ -15,9 +15,9 @@ namespace SJZY.Track.Application.Services.ForewarningServices;
|
||||
public class ForewarningNotifyService : IForewarningNotifyService, ITransientDependency
|
||||
{
|
||||
private IRuleFactorCacheService _ruleFactorCache;
|
||||
IReadOnlyDictionary<string, List<ForewarningRule>> _ruleGroupDict;
|
||||
IReadOnlyDictionary<string, List<ForewarningRuleItem>> _ruleGroupDict;
|
||||
IReadOnlyDictionary<string, List<RuleFactor>> _factorDict;
|
||||
private IReadOnlyDictionary<int, ForewarningRule> _rules;
|
||||
private IReadOnlyDictionary<int, ForewarningRuleItem> _rules;
|
||||
readonly INotifyService _notifyService;
|
||||
|
||||
public ForewarningNotifyService(IRuleFactorCacheService ruleFactorCache, INotifyService notifyService)
|
||||
@ -88,12 +88,12 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
_rules = null;
|
||||
}
|
||||
|
||||
private List<string> DeleteNotifyValue(ForewarningRule rule, int orderId)
|
||||
private List<string> DeleteNotifyValue(ForewarningRuleItem ruleItem, int orderId)
|
||||
{
|
||||
var members = new List<string>();
|
||||
for (var index = 0; index < rule.Count; index++)
|
||||
for (var index = 0; index < ruleItem.Count; index++)
|
||||
{
|
||||
var notifyValue = NotifyValue(rule, orderId, index);
|
||||
var notifyValue = NotifyValue(ruleItem, orderId, index);
|
||||
members.Add(notifyValue);
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
/// </summary>
|
||||
/// <param name="rule"></param>
|
||||
/// <returns></returns>
|
||||
private List<ForewarningRule> GetRule(ForewarningOrderModel order)
|
||||
private List<ForewarningRuleItem> GetRule(ForewarningOrderModel order)
|
||||
{
|
||||
if (!_factorDict.TryGetValue(GetFactorKey(order.CustomerId, order.SystemId), out var factors))
|
||||
{
|
||||
@ -113,7 +113,7 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
}
|
||||
|
||||
var keys = GetForewarningKeys(factors, order);
|
||||
var result = new List<ForewarningRule>();
|
||||
var result = new List<ForewarningRuleItem>();
|
||||
|
||||
foreach (var item in keys)
|
||||
{
|
||||
@ -127,7 +127,7 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
return result;
|
||||
}
|
||||
|
||||
private async ValueTask<int> ExecuteRule(List<ForewarningRule> rules, int orderId)
|
||||
private async ValueTask<int> ExecuteRule(List<ForewarningRuleItem> rules, int orderId)
|
||||
{
|
||||
var members = new List<ZMember>();
|
||||
foreach (var rule in rules)
|
||||
@ -140,16 +140,16 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
return members.Count;
|
||||
}
|
||||
|
||||
private List<ZMember> ExecuteRule(ForewarningRule rule, int orderId)
|
||||
private List<ZMember> ExecuteRule(ForewarningRuleItem ruleItem, int orderId)
|
||||
{
|
||||
var members = new List<ZMember>();
|
||||
var intervalMinute = 60 * ((rule.Timeliness - rule.Remind) / rule.Count); // 间隔多少分钟
|
||||
var intervalMinute = 60 * ((ruleItem.Timeliness - ruleItem.Remind) / ruleItem.Count); // 间隔多少分钟
|
||||
|
||||
for (var index = 0; index < rule.Count; index++)
|
||||
for (var index = 0; index < ruleItem.Count; index++)
|
||||
{
|
||||
var notifyTime = (rule.Remind * 60) + intervalMinute * index;
|
||||
var notifyTime = (ruleItem.Remind * 60) + intervalMinute * index;
|
||||
var notifyTimestamp = GetTimestamp(DateTime.Now.AddMinutes(notifyTime));
|
||||
var notifyValue = new ZMember(NotifyValue(rule, orderId, index), notifyTimestamp);
|
||||
var notifyValue = new ZMember(NotifyValue(ruleItem, orderId, index), notifyTimestamp);
|
||||
members.Add(notifyValue);
|
||||
}
|
||||
|
||||
@ -161,9 +161,9 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
return new DateTimeOffset(dateTime).ToUnixTimeSeconds();
|
||||
}
|
||||
|
||||
private string NotifyValue(ForewarningRule rule, int orderId, int sort)
|
||||
private string NotifyValue(ForewarningRuleItem ruleItem, int orderId, int sort)
|
||||
{
|
||||
var result = new RuleNotifyValue(rule.Id, orderId, sort, rule.TrackEnd);
|
||||
var result = new RuleNotifyValue(ruleItem.Id, orderId, sort, ruleItem.TrackEnd);
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
@ -220,9 +220,9 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
return rule.Area.HasValue ? rule.Area.Value.ToString() : throw new Exception("区域不能为空");
|
||||
case RuleFactorType.CargoType:
|
||||
return rule.CargoType;
|
||||
case RuleFactorType.DeparturePort:
|
||||
case RuleFactorType.LeavePort:
|
||||
return rule.DeparturePort;
|
||||
case RuleFactorType.Month:
|
||||
case RuleFactorType.Months:
|
||||
return rule.Month.HasValue ? rule.Month.Value.ToString() : throw new Exception("月份不能为空");
|
||||
case RuleFactorType.ProductCode:
|
||||
return rule.ProductCode;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using SJZY.Track.Application.Contract.Dtos.Forewarning;
|
||||
using SJZY.Track.Application.Helpers;
|
||||
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
@ -8,110 +10,73 @@ namespace SJZY.Track.Application.Services.ForewarningServices;
|
||||
[Route("/ForewarningService")]
|
||||
public class ForewarningService : ApplicationService
|
||||
{
|
||||
readonly IRuleRepository _ruleRepository;
|
||||
readonly IRuleFactorRepository _ruleFactorRepository;
|
||||
private readonly IRuleItemRepository _ruleItemRepository;
|
||||
|
||||
public ForewarningService(IRuleRepository ruleRepository
|
||||
, IRuleFactorRepository ruleFactorRepository
|
||||
, IRuleItemRepository ruleItemRepository)
|
||||
private readonly IWarningRepository _warningRepository;
|
||||
|
||||
public ForewarningService(IWarningRepository warningRepository)
|
||||
{
|
||||
_ruleRepository = ruleRepository;
|
||||
_ruleFactorRepository = ruleFactorRepository;
|
||||
_ruleItemRepository = ruleItemRepository;
|
||||
_warningRepository = warningRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建预警模板,存在则更新
|
||||
/// 创建预警
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("ModifyForewarning")]
|
||||
public async ValueTask<UnifyResultDto> ModifyForewarning(CreateRuleFactorRequest input)
|
||||
[HttpPost("CreateWarning")]
|
||||
public async Task<bool> CreateWarning(CreateWarningInput input)
|
||||
{
|
||||
var factors = ObjectMapper.Map<CreateRuleFactorRequest, RuleFactorEntity>(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);
|
||||
if (ruleTemplate == null)
|
||||
return new UnifyResultDto(false, "规则不存在");
|
||||
|
||||
ruleTemplate.Name = input.Name;
|
||||
ruleTemplate.CustomId = input.CustomId;
|
||||
|
||||
await _ruleFactorRepository.IndexDocumentAsync(factors);
|
||||
await _ruleRepository.UpdateForewarning(ruleTemplate, ruleItems);
|
||||
return new UnifyResultDto(true, "保存成功");
|
||||
}
|
||||
|
||||
var newRuleTemplate = ObjectMapper.Map<CreateRuleFactorRequest, RuleEntity>(input);
|
||||
var ruleId = await _ruleRepository.CreateForewarning(newRuleTemplate, ruleItems);
|
||||
factors.Id = ruleId.ToString();
|
||||
await _ruleFactorRepository.IndexDocumentAsync(factors);
|
||||
return new UnifyResultDto(true, "保存成功");
|
||||
var warning = ObjectMapper.Map<CreateWarningInput, WarningEntity>(input);
|
||||
warning.WarningRules = ForewarningHelper.CalcRuleList(input.TrackStatusSpans, input.WarningFactors);
|
||||
warning.WarningFactors = ForewarningHelper.MapFactorEntities(input.WarningFactors);
|
||||
await _warningRepository.CreateForewarningAsync(warning);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改时效
|
||||
/// 修改预警规则时效
|
||||
/// </summary>
|
||||
[HttpPost("ModifyTimeliness")]
|
||||
public async ValueTask<UnifyResultDto> ModifyTimeliness(ModifyTimelinessRequest input)
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessException"></exception>
|
||||
[HttpPost("ModifyTimeSpans")]
|
||||
public async Task<bool> ModifyTimeSpans(ModifyTimeSpanInput input)
|
||||
{
|
||||
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<int>();
|
||||
foreach (var item in input.Items)
|
||||
if (!await _warningRepository.IsAnyAsync(x => x.Id == input.WarningId))
|
||||
{
|
||||
if (!ruleMaps.TryGetValue(item.Id, out var rule))
|
||||
{
|
||||
notModifyList.Add(item.Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
rule.Remind = item.Remind;
|
||||
rule.Timeliness = item.Timeliness;
|
||||
rule.Count = item.Count;
|
||||
throw new BusinessException(message: "预警不存在");
|
||||
}
|
||||
|
||||
await _ruleItemRepository.UpdateRangeAsync(ruleCollect, val => val.RuleId == input.RuleId);
|
||||
if (input.Items.IsNullOrEmpty()) return false;
|
||||
|
||||
if (notModifyList.Count > 0)
|
||||
return new UnifyResultDto(true, $"更新成功,规则{string.Join(",", notModifyList)}不存在");
|
||||
var warningRules = ObjectMapper.Map<List<WarningTimeSpanDto>, List<WarningRuleEntity>>(input.Items);
|
||||
|
||||
return new UnifyResultDto(true, "更新成功");
|
||||
await _warningRepository.ModifyTimeSpansAsync(warningRules);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取预警分页列表
|
||||
/// </summary>
|
||||
/// <param name="inputVo"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetWarningPageList")]
|
||||
public async Task<UnifyPageResultDto<WarningPageOutput>> GetWarningPageList(GetWarningPageInputVo inputVo)
|
||||
{
|
||||
if (!inputVo.KeyWord.IsNullOrEmpty()) inputVo.KeyWord = inputVo.KeyWord!.Trim();
|
||||
return await _warningRepository.GetWarningPageListAsync(inputVo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询预警规则列表
|
||||
/// </summary>
|
||||
/// <param name="warningId">预警规则id</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("QueryForewarning")]
|
||||
public async Task<UnifyResultDto> QueryForewarning(QueryForewarningRequest input)
|
||||
[HttpGet("GetWarningRuleList")]
|
||||
public async Task<List<WarningRuleOutput>> GetWarningRuleListAsync([Required] int warningId)
|
||||
{
|
||||
var result = await _ruleRepository.QueryForewarningRuleAsync(input);
|
||||
return new UnifyResultDto(true, result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询预警规则明细列表
|
||||
/// </summary>
|
||||
[HttpPost("QueryForewarningRules")]
|
||||
public async Task<UnifyPageResultDto<RuleCollectDto>> QueryForewarningRuleItems(QueryForewarningRuleRequest input)
|
||||
{
|
||||
return await _ruleItemRepository.QueryForewarningRuleItemsAsync(input);
|
||||
return await _warningRepository.GetWarningRuleListAsync(warningId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,194 +0,0 @@
|
||||
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 Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace SJZY.Track.Application.Services.ForewarningServices;
|
||||
|
||||
public class RuleFactorCacheService : IRuleFactorCacheService, ITransientDependency
|
||||
{
|
||||
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,
|
||||
IRuleItemRepository ruleItemRepository, IRuleRepository ruleRepository)
|
||||
{
|
||||
_ruleFactorRepository = ruleFactorRepository;
|
||||
_ruleItemRepository = ruleItemRepository;
|
||||
_ruleRepository = ruleRepository;
|
||||
}
|
||||
|
||||
private string GetKey()
|
||||
{
|
||||
return $"{GlobalConst.RuleFactorKeyPrefix}:allFactor";
|
||||
}
|
||||
|
||||
private string GetRuleKey()
|
||||
{
|
||||
return $"{GlobalConst.RuleFactorKeyPrefix}:allRule";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有规则数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[NonAction]
|
||||
public async Task<ForewarningRule[]> GetAllFactorCollect()
|
||||
{
|
||||
var key = GetRuleKey();
|
||||
var result = await RedisHelper.Client.GetAsync<ForewarningRule[]>(key);
|
||||
if (result == null)
|
||||
{
|
||||
using (var globalLock = RedisHelper.Client.Lock(GlobalRuleLockKey, 10))
|
||||
{
|
||||
result = await RedisHelper.Client.GetAsync<ForewarningRule[]>(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;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有因素数据
|
||||
/// </summary>
|
||||
/// <returns>获取所有因素,返回值可能为空</returns>
|
||||
[NonAction]
|
||||
public async Task<List<RuleFactor>> GetAllRuleFactor()
|
||||
{
|
||||
var key = GetKey();
|
||||
var result = await RedisHelper.Client.GetAsync<List<RuleFactor>>(key);
|
||||
if (result == null)
|
||||
{
|
||||
using (var globalLock = RedisHelper.Client.Lock(GlobalFactorLockKey, 10))
|
||||
{
|
||||
result = await RedisHelper.Client.GetAsync<List<RuleFactor>>(key);
|
||||
if (result != null) return result;
|
||||
|
||||
result = await GenerateAllRuleFactor();
|
||||
if (result == null || result.Count == 0)
|
||||
{
|
||||
await RedisHelper.Client.SetAsync(key, new List<RuleFactor>(), TimeSpan.FromSeconds(20));
|
||||
return result;
|
||||
}
|
||||
|
||||
await RedisHelper.Client.SetAsync(key, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public void ClearFactorCache()
|
||||
{
|
||||
RedisHelper.Client.DelAsync(GetKey());
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public void ClearRuleCache()
|
||||
{
|
||||
RedisHelper.Client.DelAsync(GetRuleKey());
|
||||
}
|
||||
|
||||
private async Task<List<RuleFactor>> GenerateAllRuleFactor()
|
||||
{
|
||||
var factors = await _ruleFactorRepository.GetAllList();
|
||||
var ruleTemplate = await _ruleRepository.GetListAsync(val => true);
|
||||
var ruleMap = ruleTemplate.ToDictionary(val => val.Id);
|
||||
var result = new List<RuleFactor>();
|
||||
foreach (var item in factors)
|
||||
{
|
||||
if (!ruleMap.TryGetValue(item.RuleId, out var rule))
|
||||
continue;
|
||||
var ruleFactors = EntityToRuleFactor(item, rule);
|
||||
result.AddRange(ruleFactors);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private ForewarningRule[] RuleEntityToRule(RuleItemEntity entity)
|
||||
{
|
||||
var result = RuleCollectToRule(entity);
|
||||
if (string.IsNullOrEmpty(entity.Month))
|
||||
{
|
||||
return new ForewarningRule[] { result };
|
||||
}
|
||||
|
||||
var months = entity.Month.Split('/');
|
||||
var rules = new List<ForewarningRule>(months.Length);
|
||||
|
||||
foreach (var month in months)
|
||||
{
|
||||
if (int.TryParse(month, out int monthInt))
|
||||
{
|
||||
var rule = result;
|
||||
rule.Month = monthInt;
|
||||
rules.Add(rule);
|
||||
}
|
||||
}
|
||||
|
||||
return rules.ToArray();
|
||||
}
|
||||
|
||||
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<RuleFactor> EntityToRuleFactor(RuleFactorEntity entity, RuleEntity ruleTemplate)
|
||||
{
|
||||
List<RuleFactor> result = new List<RuleFactor>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -3,31 +3,16 @@ using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
namespace SJZY.Track.Application.Validations.Forewarning;
|
||||
|
||||
public class CreateRuleFactorValidation : AbstractValidator<CreateRuleFactorRequest>
|
||||
public class CreateRuleFactorValidation : AbstractValidator<CreateWarningInput>
|
||||
{
|
||||
public CreateRuleFactorValidation()
|
||||
{
|
||||
RuleForEach(x => x.Tracks).SetValidator(new RuleTrackStateDtoValidator());
|
||||
RuleFor(x => x.FactorItems).NotNull().WithMessage("FactorItems cannot be null.");
|
||||
RuleFor(x => x.WarningFactors).NotNull().WithMessage("因素列表不能为空");
|
||||
RuleFor(x => x.TrackStatusSpans).NotNull().WithMessage("轨迹状态列表不能为空");
|
||||
|
||||
RuleFor(x => x.CargoTypes).NotEmpty().WithMessage("CargoTypes cannot be empty.");
|
||||
RuleForEach(x => x.CargoTypes).NotEmpty().WithMessage("CargoType cannot be empty.");
|
||||
|
||||
RuleFor(x => x.Months).NotEmpty().WithMessage("Months cannot be empty.");
|
||||
RuleForEach(x => x.Months)
|
||||
.ForEach(val=>val.Must(t=>t>0))
|
||||
.WithMessage("Each month array must have 12 elements.");
|
||||
|
||||
RuleFor(x => x.IsTransit).NotEmpty().WithMessage("IsTransit cannot be empty.");
|
||||
RuleForEach(x => x.IsTransit).InclusiveBetween(0, 1).WithMessage("IsTransit must be 0 or 1.");
|
||||
|
||||
RuleFor(x => x.Areas).NotEmpty().WithMessage("Areas cannot be empty.");
|
||||
RuleForEach(x => x.Areas).GreaterThan(0).WithMessage("Area must be greater than 0.");
|
||||
|
||||
RuleFor(x => x.DeparturePorts).NotEmpty().WithMessage("DeparturePorts cannot be empty.");
|
||||
RuleForEach(x => x.DeparturePorts).NotEmpty().WithMessage("DeparturePort cannot be empty.");
|
||||
|
||||
RuleFor(x => x.ProductCodes).NotEmpty().WithMessage("ProductCodes cannot be empty.");
|
||||
RuleForEach(x => x.ProductCodes).NotEmpty().WithMessage("ProductCode cannot be empty.");
|
||||
RuleFor(x => x.NotifyTemplate).NotEmpty().WithMessage("通知模板必填")
|
||||
.MaximumLength(256).WithMessage("通知模板长度不能超过256");
|
||||
|
||||
// todo: more validation
|
||||
}
|
||||
}
|
||||
@ -3,13 +3,12 @@ using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
namespace SJZY.Track.Application.Validations.Forewarning;
|
||||
|
||||
public class RuleTrackStateDtoValidator : AbstractValidator<RuleTrackStateDto>
|
||||
public class RuleTrackStateDtoValidator : AbstractValidator<TrackStatusSpanDto>
|
||||
{
|
||||
public RuleTrackStateDtoValidator()
|
||||
{
|
||||
RuleFor(x => x.Start).GreaterThanOrEqualTo(0).WithMessage("Start must be greater than or equal to 0.");
|
||||
RuleFor(x => x.End).GreaterThanOrEqualTo(0).WithMessage("End must be greater than or equal to 0.");
|
||||
RuleFor(x => x.NotifyUser).NotEmpty().WithMessage("NotifyUser cannot be empty.");
|
||||
RuleFor(x => x.NotifyTemplate).NotEmpty().WithMessage("NotifyTemplate cannot be empty.");
|
||||
RuleFor(x => x.StartTrackStatusId).GreaterThan(0).WithMessage("起始轨迹状态id必须大于0");
|
||||
RuleFor(x => x.EndTrackStatusId).GreaterThan(0).WithMessage("终止轨迹状态id必须大于0");
|
||||
RuleFor(x => x.NotifyUserId).NotEmpty().WithMessage("通知对象不能为空");
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
public interface IForewarningList
|
||||
{
|
||||
void AddForewarning(int score,int id);
|
||||
|
||||
void DeleteForewarning(int score,int id);
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
using SJZY.Expand.ElasticSearch.Services;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
public interface IRuleFactorRepository:IElasticsearchClientService<RuleFactorEntity>
|
||||
{
|
||||
Task<List<RuleFactorEntity>> GetFactorByIdsAsync(int[] ruleIds);
|
||||
|
||||
Task<List<RuleFactorEntity>> GetAllList();
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
public interface IRuleItemRepository : IBasicRepository<RuleItemEntity>
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询分页
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<UnifyPageResultDto<RuleCollectDto>> QueryForewarningRuleItemsAsync(QueryForewarningRuleRequest input);
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
public interface IRuleRepository : IBasicRepository<RuleEntity>
|
||||
{
|
||||
Task<int> CreateForewarning(RuleEntity rule, RuleItemEntity[] ruleItems);
|
||||
|
||||
Task UpdateForewarning(RuleEntity rule, RuleItemEntity[] factorList);
|
||||
|
||||
Task<UnifyPageResultDto<RuleEntity>> QueryForewarningRuleAsync(QueryForewarningRequest input);
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
public interface IWarningRepository : IBasicRepository<WarningEntity>
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建预警
|
||||
/// </summary>
|
||||
/// <param name="warning"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> CreateForewarningAsync(WarningEntity warning);
|
||||
|
||||
/// <summary>
|
||||
/// 修改预警
|
||||
/// </summary>
|
||||
/// <param name="warning"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateForewarningAsync(WarningEntity warning);
|
||||
|
||||
/// <summary>
|
||||
/// 复制预警
|
||||
/// </summary>
|
||||
/// <param name="warningId"></param>
|
||||
/// <returns></returns>
|
||||
Task CopyForewarning(int warningId);
|
||||
|
||||
/// <summary>
|
||||
/// 获取预警分页列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<UnifyPageResultDto<WarningPageOutput>> GetWarningPageListAsync(GetWarningPageInputVo input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取预警规则列表
|
||||
/// </summary>
|
||||
/// <param name="warningId">预警id</param>
|
||||
/// <returns></returns>
|
||||
Task<List<WarningRuleOutput>> GetWarningRuleListAsync(int warningId);
|
||||
|
||||
/// <summary>
|
||||
/// 修改预警时效
|
||||
/// </summary>
|
||||
/// <param name="inputItems"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> ModifyTimeSpansAsync(List<WarningRuleEntity> inputItems);
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
[SugarTable("t_rule")]
|
||||
public class RuleEntity:IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "SubSystemId")]
|
||||
public int SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CustomId")]
|
||||
public int CustomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 规则模板名称,KPI名称
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Name", Length = 64)]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 规则模板名称,KPI名称
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CustomName", Length = 64)]
|
||||
public string CustomName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建人
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CreateUserId")]
|
||||
public int CreateUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CreateTime")]
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新人
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "UpdateUserId", IsNullable = false)]
|
||||
public int UpdateUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "UpdateTime", IsNullable = false)]
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
using Nest;
|
||||
using SJZY.Expand.ElasticSearch;
|
||||
using SJZY.Track.Domain.Consts;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
[ElasticsearchType(RelationName = GlobalConst.RuleFactorIndex)]
|
||||
public class RuleFactorEntity : IdBaseIndex
|
||||
{
|
||||
/// <summary>
|
||||
/// RuleId 表的id
|
||||
/// </summary>
|
||||
[Keyword(Index = true)]
|
||||
public int RuleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置规则跟踪状态实体的列表。
|
||||
/// </summary>
|
||||
public List<RuleTrackStateModel> Tracks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置因素项模型的列表。
|
||||
/// </summary>
|
||||
public List<FactorItemModel> FactorItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置货物类型的列表。
|
||||
/// </summary>
|
||||
public List<string> CargoTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置月份的列表。
|
||||
/// </summary>
|
||||
public List<string> Months { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置是否中转的列表。
|
||||
/// </summary>
|
||||
public List<bool> IsTransit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置区域的列表。
|
||||
/// </summary>
|
||||
public List<int> Areas { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置起运港口的列表。
|
||||
/// </summary>
|
||||
public List<string> DeparturePorts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置产品编号的列表。
|
||||
/// </summary>
|
||||
public List<string> ProductCodes { get; set; }
|
||||
}
|
||||
@ -1,109 +0,0 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
[SugarTable("t_rule_item")]
|
||||
public class RuleItemEntity : IAggregateRoot, ICloneable
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "RuleId")] public int RuleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒的时间(小时)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Remind")]
|
||||
public float Remind { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时效(小时)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Timeliness")]
|
||||
public float Timeliness { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒次数
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Count")]
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "TrackStart", IsNullable = false)]
|
||||
public int TrackStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 终止轨迹
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "TrackEnd", IsNullable = false)]
|
||||
public int TrackEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 货物类型
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CargoType", Length = 64)]
|
||||
public string CargoType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 月份
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Month", Length = 25)]
|
||||
public string Month { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区域
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Area")]
|
||||
public int? Area { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否中转
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "IsTransit")]
|
||||
public bool? IsTransit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起运港口
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "DeparturePort")]
|
||||
public string DeparturePort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品编码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "ProductCode")]
|
||||
public string ProductCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建人
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CreateUserId")]
|
||||
public int CreateUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CreateTime")]
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新人
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "UpdateUserId")]
|
||||
public int UpdateUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "UpdateTime")]
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
var clone = this.MemberwiseClone();
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
public class RuleTrackStateModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the start track value.
|
||||
/// </summary>
|
||||
public int Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the end track value.
|
||||
/// </summary>
|
||||
public int End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user to notify.
|
||||
/// </summary>
|
||||
public string NotifyUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the notification template.
|
||||
/// </summary>
|
||||
public string NotifyTemplate { get; set; }
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
[SugarTable("t_warning")]
|
||||
public class WarningEntity: IFullAuditedBasicEntitys, IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "SubSystemId")]
|
||||
public int SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CustomerId")]
|
||||
public int CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CustomerName", Length = 255)]
|
||||
public string CustomerName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 规则模板名称,KPI名称
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Name", Length = 64)]
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用,默认否
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "IsEnable")]
|
||||
public bool IsEnable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<WarningRuleEntity> WarningRules { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 预警因素
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<WarningFactorEntity> WarningFactors { get; set; } = new();
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
public class WarningFactorEntity : IFullAuditedBasicEntitys
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警id
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "WarningId")]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 因素类型(1货物类型,2月份,3分区,4是否中转,5起运港口,6销售产品)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Type")]
|
||||
public RuleFactorType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警因素值(json数组字符串)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Value")]
|
||||
public string Value { get; set; } = null!;
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
[SugarTable("t_warning_rule")]
|
||||
public class WarningRuleEntity : IFullAuditedBasicEntitys
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警id
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "WarningId")]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时效(小时)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "TotalTimeSpan")]
|
||||
public float TotalTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒的时间(小时)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "WarnTimeSpan")]
|
||||
public float WarnTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒次数
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "WarnCount")]
|
||||
public int WarnCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹状态id
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "StartTrackStatusId", IsNullable = false)]
|
||||
public int StartTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 终止轨迹状态id
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "EndTrackStatusId", IsNullable = false)]
|
||||
public int EndTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 货物类型
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "CargoType", Length = 64)]
|
||||
public string? CargoType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 月份
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Months", Length = 25)]
|
||||
public string? Months { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区域
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "AreaId")]
|
||||
public int? AreaId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否中转
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "IsTransit")]
|
||||
public bool? IsTransit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起运港口
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "LeavePort")]
|
||||
public string? LeavePort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品编码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "ProductCode")]
|
||||
public string? ProductCode { get; set; }
|
||||
}
|
||||
@ -1,16 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning
|
||||
{
|
||||
public class CreateRuleFactorRequest
|
||||
public class CreateWarningInput
|
||||
{
|
||||
/// <summary>
|
||||
/// RuleId 表的id,小于0 表示创建新的规则
|
||||
/// </summary>
|
||||
public int RuleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模板名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
@ -20,46 +18,31 @@ namespace SJZY.Track.Domain.Dtos.Forewarning
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int CustomId { get; set; }
|
||||
public int CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置规则跟踪状态实体的列表。
|
||||
/// 客户名称
|
||||
/// </summary>
|
||||
public List<RuleTrackStateDto> Tracks { get; set; }
|
||||
public string CustomerName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置因素项模型的列表。
|
||||
/// 通知方式
|
||||
/// </summary>
|
||||
public List<FactorItemDto> FactorItems { get; set; }
|
||||
public NotifyMode NotifyMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置货物类型的列表。
|
||||
/// 通知模板
|
||||
/// </summary>
|
||||
public List<string> CargoTypes { get; set; }
|
||||
public string NotifyTemplate { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置月份的列表。
|
||||
/// 轨迹状态跨度列表
|
||||
/// </summary>
|
||||
public List<string> Months { get; set; }
|
||||
public List<TrackStatusSpanDto> TrackStatusSpans { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置是否中转的列表。
|
||||
/// 预警因素列表。
|
||||
/// </summary>
|
||||
public List<int> IsTransit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置区域的列表。
|
||||
/// </summary>
|
||||
public List<int> Areas { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置起运港口的列表。
|
||||
/// </summary>
|
||||
public List<string> DeparturePorts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置产品编号的列表。
|
||||
/// </summary>
|
||||
public List<string> ProductCodes { get; set; }
|
||||
public List<WarningFactorDto> WarningFactors { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class FactorItemDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the sort order.
|
||||
/// </summary>
|
||||
public int Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the rule factor.
|
||||
/// </summary>
|
||||
public RuleFactorType FactorType { get; set; }
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public record struct ForewarningRule:IForewarningFactorValue
|
||||
public record struct ForewarningRuleItem:IForewarningFactorValue
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class GetWarningPageInputVo: PageInfoInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int? SystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关键字(客户or名称)
|
||||
/// </summary>
|
||||
public string? KeyWord { get; set; }
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class QueryForewarningRuleRequest: PageInfoInput
|
||||
public class GetWarningRuleListInput: PageInfoInput
|
||||
{
|
||||
/// <summary>
|
||||
/// kpi 预警规则模板id
|
||||
@ -1,40 +0,0 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class ModifyTimelinessRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 规则详情中的时效相关信息
|
||||
/// </summary>
|
||||
public List<TimelinessDto> Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 规则模板id
|
||||
/// </summary>
|
||||
public int RuleId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 规则详情时效
|
||||
/// </summary>
|
||||
public class TimelinessDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 时效
|
||||
/// </summary>
|
||||
public float Timeliness { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒时效
|
||||
/// </summary>
|
||||
public float Remind { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒次数
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 规则详情id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class QueryForewarningRequest: PageInfoInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int? SystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户或者模板名称
|
||||
/// </summary>
|
||||
public string? KeyWord { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序方式,不填不排序
|
||||
/// </summary>
|
||||
public string? SortField { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序方式
|
||||
/// </summary>
|
||||
public bool IsAsc { get; set; } = false;
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class RuleCollectDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int RuleId { get; set; }
|
||||
public float Remind { get; set; }
|
||||
public float Timeliness { get; set; }
|
||||
public int Count { get; set; }
|
||||
public int TrackStart { get; set; }
|
||||
public int TrackEnd { get; set; }
|
||||
public string CargoType { get; set; }
|
||||
public string Month { get; set; }
|
||||
public int? Area { get; set; }
|
||||
public bool? IsTransit { get; set; }
|
||||
public string DeparturePort { get; set; }
|
||||
public string ProductCode { get; set; }
|
||||
public int CreateUserId { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
public int UpdateUserId { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class RuleInfoModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置因素项模型的列表。
|
||||
/// </summary>
|
||||
public FactorItemModel FactorItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置货物类型的列表。
|
||||
/// </summary>
|
||||
public string CargoTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置月份的列表。
|
||||
/// </summary>
|
||||
public short Months { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置是否中转的列表。
|
||||
/// </summary>
|
||||
public bool? IsTransit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置区域的列表。
|
||||
/// </summary>
|
||||
public int Areas { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置起运港口的列表。
|
||||
/// </summary>
|
||||
public string DeparturePorts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置产品编号的列表。
|
||||
/// </summary>
|
||||
public string ProductCodes { get; set; }
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class RuleTrackStateDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the start track value.
|
||||
/// </summary>
|
||||
public int Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the end track value.
|
||||
/// </summary>
|
||||
public int End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user to notify.
|
||||
/// </summary>
|
||||
public string NotifyUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the notification template.
|
||||
/// </summary>
|
||||
public string NotifyTemplate { get; set; }
|
||||
}
|
||||
19
src/SJZY.Track.Domain/Dtos/Forewarning/TrackStatusSpanDto.cs
Normal file
19
src/SJZY.Track.Domain/Dtos/Forewarning/TrackStatusSpanDto.cs
Normal file
@ -0,0 +1,19 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class TrackStatusSpanDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 起始轨迹状态id
|
||||
/// </summary>
|
||||
public int StartTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 终止轨迹状态id
|
||||
/// </summary>
|
||||
public int EndTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知人id
|
||||
/// </summary>
|
||||
public int NotifyUserId { get; set; }
|
||||
}
|
||||
17
src/SJZY.Track.Domain/Dtos/Forewarning/WarningFactorDto.cs
Normal file
17
src/SJZY.Track.Domain/Dtos/Forewarning/WarningFactorDto.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class WarningFactorDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 因素类型
|
||||
/// </summary>
|
||||
public RuleFactorType FactorType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 因素值
|
||||
/// </summary>
|
||||
public JArray FactorValue { get; set; } = new();
|
||||
}
|
||||
29
src/SJZY.Track.Domain/Dtos/Forewarning/WarningPageOutput.cs
Normal file
29
src/SJZY.Track.Domain/Dtos/Forewarning/WarningPageOutput.cs
Normal file
@ -0,0 +1,29 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class WarningPageOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统
|
||||
/// </summary>
|
||||
public string SubSystem { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 客户
|
||||
/// </summary>
|
||||
public string Custom { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 规则模板名称,KPI名称
|
||||
/// </summary>
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime? UpdateTime { get; set; }
|
||||
}
|
||||
64
src/SJZY.Track.Domain/Dtos/Forewarning/WarningRuleOutput.cs
Normal file
64
src/SJZY.Track.Domain/Dtos/Forewarning/WarningRuleOutput.cs
Normal file
@ -0,0 +1,64 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
public class WarningRuleOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时效(小时)
|
||||
/// </summary>
|
||||
public float TotalTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒的时间(小时)
|
||||
/// </summary>
|
||||
public float WarnTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒次数
|
||||
/// </summary>
|
||||
public int WarnCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹状态
|
||||
/// </summary>
|
||||
public string StartTrackStatus { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 终止轨迹状态
|
||||
/// </summary>
|
||||
public string EndTrackStatus { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 货物类型
|
||||
/// </summary>
|
||||
public string? CargoType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 月份
|
||||
/// </summary>
|
||||
public string? Months { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区域
|
||||
/// </summary>
|
||||
public int? AreaId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否中转
|
||||
/// </summary>
|
||||
public bool? IsTransit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起运港口
|
||||
/// </summary>
|
||||
public string? LeavePort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 销售产品
|
||||
/// </summary>
|
||||
public string? ProductCode { get; set; }
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SJZY.Track.Domain.Dtos.Order
|
||||
{
|
||||
public class GetOrderDetailsInputVO
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class TrackOrderDetailVO
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
14
src/SJZY.Track.Domain/Enums/NotifyMode.cs
Normal file
14
src/SJZY.Track.Domain/Enums/NotifyMode.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace SJZY.Track.Domain.Enums;
|
||||
|
||||
public enum NotifyMode
|
||||
{
|
||||
/// <summary>
|
||||
/// 站内信
|
||||
/// </summary>
|
||||
SiteInternal = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 飞书
|
||||
/// </summary>
|
||||
FeiShu = 2
|
||||
}
|
||||
@ -9,12 +9,12 @@ public enum RuleFactorType
|
||||
/// <summary>
|
||||
/// 表示货物类型。
|
||||
/// </summary>
|
||||
CargoType,
|
||||
CargoType = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 表示月份。
|
||||
/// </summary>
|
||||
Month,
|
||||
Months,
|
||||
|
||||
/// <summary>
|
||||
/// 表示分区或区域。
|
||||
@ -29,10 +29,10 @@ public enum RuleFactorType
|
||||
/// <summary>
|
||||
/// 表示起运港口。
|
||||
/// </summary>
|
||||
DeparturePort,
|
||||
LeavePort,
|
||||
|
||||
/// <summary>
|
||||
/// 表示产品编号。
|
||||
/// 表示销售产品。
|
||||
/// </summary>
|
||||
ProductCode
|
||||
}
|
||||
@ -91,7 +91,7 @@ AND `a`.`IsDeleted` = 0 AND `b`.`IsDeleted` = 0;");
|
||||
|
||||
public async Task UnLinkByIdsAsync(List<int> linkIds)
|
||||
{
|
||||
await Context.Deleteable(linkIds).ExecuteCommandAsync();
|
||||
await Context.Deleteable<OrderLinkEntity>(linkIds).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
using Nest;
|
||||
using SJZY.Expand.ElasticSearch.Services;
|
||||
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
|
||||
namespace SJZY.Track.Repository.Repositories;
|
||||
|
||||
public class RuleFactorRepository:ElasticSearchContextAbstract<RuleFactorEntity>, IRuleFactorRepository,
|
||||
ITransientDependency
|
||||
{
|
||||
public RuleFactorRepository(ConnectionFactory connectionFactory) : base(connectionFactory)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task CreateAsync(RuleFactorEntity entity)
|
||||
{
|
||||
await IndexDocumentAsync(entity);
|
||||
}
|
||||
|
||||
public async Task<List<RuleFactorEntity>> GetFactorByIdsAsync(int[] ruleIds)
|
||||
{
|
||||
var response = await Context.SearchAsync<RuleFactorEntity>(s => s.Query(q => q.Terms(t => t.Field(f => f.RuleId).Terms(ruleIds))));
|
||||
int num = response.ApiCall.HttpStatusCode ?? throw new Exception("数据查询失败,原因:" + response.DebugInformation);
|
||||
switch (num)
|
||||
{
|
||||
case 200:
|
||||
return response.Documents.ToList();
|
||||
case 404:
|
||||
return new List<RuleFactorEntity>();
|
||||
default:
|
||||
throw new Exception($"数据查询失败,http status: {num},原因:{response.DebugInformation}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public async Task<List<RuleFactorEntity>> GetAllList()
|
||||
{
|
||||
var response = await Context.SearchAsync<RuleFactorEntity>();
|
||||
int num = response.ApiCall.HttpStatusCode ?? throw new Exception("数据查询失败,原因:" + response.DebugInformation);
|
||||
switch (num)
|
||||
{
|
||||
case 200:
|
||||
return response.Documents.ToList();
|
||||
case 404:
|
||||
return new List<RuleFactorEntity>();
|
||||
default:
|
||||
throw new Exception($"数据查询失败,http status: {num},原因:{response.DebugInformation}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
namespace SJZY.Track.Repository.Repositories;
|
||||
|
||||
public class RuleItemRepository : BasicRepository<RuleItemEntity>, IRuleItemRepository, ITransientDependency
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询预警规则分页信息
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public Task<UnifyPageResultDto<RuleCollectDto>> QueryForewarningRuleItemsAsync(QueryForewarningRuleRequest input)
|
||||
{
|
||||
var query = Context.Queryable<RuleItemEntity>()
|
||||
.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))
|
||||
.ToPagedListAsync(input.PageIndex, input.PageSize);
|
||||
}
|
||||
|
||||
private RuleCollectDto MapToDto(RuleItemEntity entity)
|
||||
{
|
||||
return new RuleCollectDto()
|
||||
{
|
||||
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 = entity.Month,
|
||||
Area = entity.Area,
|
||||
IsTransit = entity.IsTransit,
|
||||
DeparturePort = entity.DeparturePort,
|
||||
ProductCode = entity.ProductCode,
|
||||
CreateUserId = entity.CreateUserId,
|
||||
CreateTime = entity.CreateTime,
|
||||
UpdateUserId = entity.UpdateUserId,
|
||||
UpdateTime = entity.UpdateTime
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
using SJZY.Track.Domain;
|
||||
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
|
||||
namespace SJZY.Track.Repository.Repositories;
|
||||
|
||||
public class RuleRepository : BasicRepository<RuleEntity>, IRuleRepository, ITransientDependency
|
||||
{
|
||||
public async Task<int> CreateForewarning(RuleEntity rule, RuleItemEntity[] ruleItems)
|
||||
{
|
||||
using var tran = TransactionHelper.GetReadCommitted();
|
||||
|
||||
var ruleId = await InsertReturnIdentityAsync(rule);
|
||||
foreach (var item in ruleItems)
|
||||
{
|
||||
item.RuleId = ruleId;
|
||||
}
|
||||
|
||||
await Context.Insertable(ruleItems).ExecuteCommandAsync();
|
||||
tran.Complete();
|
||||
return ruleId;
|
||||
}
|
||||
|
||||
public async Task UpdateForewarning(RuleEntity rule, RuleItemEntity[] factorList)
|
||||
{
|
||||
using var tran = TransactionHelper.GetReadCommitted();
|
||||
await UpdateAsync(rule);
|
||||
await Context.Deleteable<RuleItemEntity>().Where(x => x.RuleId == rule.Id).ExecuteCommandAsync();
|
||||
await Context.Insertable(factorList).ExecuteCommandAsync();
|
||||
tran.Complete();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询预警模板分页信息
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public Task<UnifyPageResultDto<RuleEntity>> QueryForewarningRuleAsync(QueryForewarningRequest input)
|
||||
{
|
||||
var query = Context.Queryable<RuleEntity>()
|
||||
.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);
|
||||
}
|
||||
|
||||
return query.ToPagedListAsync(input.PageIndex, input.PageSize);
|
||||
}
|
||||
}
|
||||
75
src/SJZY.Track.Repository/Repositories/WarningRepository.cs
Normal file
75
src/SJZY.Track.Repository/Repositories/WarningRepository.cs
Normal file
@ -0,0 +1,75 @@
|
||||
using SJZY.Track.Domain;
|
||||
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
|
||||
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||
using SJZY.Track.Domain.VEntities;
|
||||
|
||||
namespace SJZY.Track.Repository.Repositories;
|
||||
|
||||
public class WarningRepository : BasicRepository<WarningEntity>, IWarningRepository, ITransientDependency
|
||||
{
|
||||
public async Task<int> CreateForewarningAsync(WarningEntity warning)
|
||||
{
|
||||
using var tran = TransactionHelper.GetReadCommitted();
|
||||
|
||||
var ruleId = await InsertReturnIdentityAsync(warning);
|
||||
warning.WarningRules.ForEach(x => x.WarningId = ruleId);
|
||||
warning.WarningFactors.ForEach(x => x.WarningId = ruleId);
|
||||
|
||||
await Context.Insertable(warning.WarningRules).ExecuteCommandAsync();
|
||||
await Context.Insertable(warning.WarningFactors).ExecuteCommandAsync();
|
||||
tran.Complete();
|
||||
return ruleId;
|
||||
}
|
||||
|
||||
public Task<int> UpdateForewarningAsync(WarningEntity warning)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task CopyForewarning(int warningId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<UnifyPageResultDto<WarningPageOutput>> GetWarningPageListAsync(GetWarningPageInputVo input)
|
||||
{
|
||||
var query = Context.Queryable<WarningEntity>()
|
||||
.LeftJoin<VSystemEntity>((a, b) => a.SubSystemId == b.Id)
|
||||
.WhereIF(input.SystemId.HasValue, (a, b) => a.SubSystemId == input.SystemId)
|
||||
.WhereIF(!string.IsNullOrEmpty(input.KeyWord), a => a.CustomerName.Contains(input.KeyWord!) || a.Name.Contains(input.KeyWord!))
|
||||
.OrderBy(a => a.UpdateTime, OrderByType.Desc);
|
||||
|
||||
return query
|
||||
.Select((a, b) => new WarningPageOutput
|
||||
{
|
||||
Id = a.Id,
|
||||
SubSystem = b.CnName,
|
||||
Custom = a.CustomerName,
|
||||
Name = a.Name,
|
||||
UpdateTime = a.UpdateTime
|
||||
})
|
||||
.ToPagedListAsync(input.PageIndex, input.PageSize);
|
||||
}
|
||||
|
||||
public async Task<List<WarningRuleOutput>> GetWarningRuleListAsync(int warningId)
|
||||
{
|
||||
return await Context.Queryable<WarningRuleEntity>()
|
||||
.LeftJoin<TrackStatusEntity>((a, b) => a.StartTrackStatusId == b.Id)
|
||||
.LeftJoin<TrackStatusEntity>((a, b, c) => a.EndTrackStatusId == c.Id)
|
||||
.Where(a => a.WarningId == warningId)
|
||||
.Select((a, b, c) => new WarningRuleOutput
|
||||
{
|
||||
StartTrackStatus = b.Status,
|
||||
EndTrackStatus = c.Status,
|
||||
}, true)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<int> ModifyTimeSpansAsync(List<WarningRuleEntity> rules)
|
||||
{
|
||||
return await Context.Updateable(rules)
|
||||
.UpdateColumns(x => new { x.TotalTimeSpan, x.WarnTimeSpan, x.WarnCount })
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user