feat: 预警功能相关代码
This commit is contained in:
parent
0d28d10ef8
commit
895e12762d
@ -51,4 +51,19 @@ public class UpdateOrderInput : OrderNoInfo
|
|||||||
/// 订单航班信息
|
/// 订单航班信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<OrderFlightInfo> FlightInfos { get; set; } = new();
|
public List<OrderFlightInfo> FlightInfos { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 货物类型
|
||||||
|
/// </summary>
|
||||||
|
public string? CargoType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否转运
|
||||||
|
/// </summary>
|
||||||
|
public bool? IsTransfer { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 产品编码
|
||||||
|
/// </summary>
|
||||||
|
public string? ProductCode { get; set; }
|
||||||
}
|
}
|
||||||
@ -12,5 +12,8 @@
|
|||||||
<PackageReference Include="SJZY.Expand.ABP.Common" Version="7.0.11" />
|
<PackageReference Include="SJZY.Expand.ABP.Common" Version="7.0.11" />
|
||||||
<PackageReference Include="Volo.Abp.Core" Version="7.0.2" />
|
<PackageReference Include="Volo.Abp.Core" Version="7.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\SJZY.Track.Domain\SJZY.Track.Domain.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Contract.Services;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 预警通知服务接口定义。
|
||||||
|
/// 提供创建、删除预警通知和发送通知的功能。
|
||||||
|
/// </summary>
|
||||||
|
public interface IForewarningNotifyService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 创建预警通知。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="order">预警订单模型。</param>
|
||||||
|
/// <returns>创建操作的结果,以整数形式返回。</returns>
|
||||||
|
Task<int> CreateForewarningNotify(ForewarningOrderModel order);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除预警通知。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="order">预警订单模型。</param>
|
||||||
|
/// <returns>删除操作的结果,以整数形式返回。</returns>
|
||||||
|
Task<int> DeleteForewarningNotify(ForewarningOrderModel order);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送通知。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="intervalMinute">通知间隔时间,以分钟为单位。</param>
|
||||||
|
void SendNotification(int intervalMinute);
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace SJZY.Track.Application.Contract.Services;
|
||||||
|
|
||||||
|
public interface IKpiAreaCacheService
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace SJZY.Track.Application.Contract.Services;
|
||||||
|
|
||||||
|
public interface INotifyService
|
||||||
|
{
|
||||||
|
void SendNotification(string body);
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Contract.Services;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 定义了与规则因子缓存相关的服务接口。
|
||||||
|
/// </summary>
|
||||||
|
public interface IRuleFactorCacheService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有因子收集的规则。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>规则数组。</returns>
|
||||||
|
Task<ForewarningRule[]> GetAllFactorCollect();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有规则因子。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>规则因子实体列表。</returns>
|
||||||
|
Task<List<RuleFactor>> GetAllRuleFactor();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除因子缓存。
|
||||||
|
/// </summary>
|
||||||
|
void ClearFactorCache();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除规则缓存。
|
||||||
|
/// </summary>
|
||||||
|
void ClearRuleCache();
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.AutoMapper;
|
||||||
|
|
||||||
|
public class ForewarningMapperProfile :Profile
|
||||||
|
{
|
||||||
|
public ForewarningMapperProfile()
|
||||||
|
{
|
||||||
|
CreateMap<CreateRuleFactorRequest, RuleEntity>(MemberList.None);
|
||||||
|
CreateMap<RuleTrackStateDto, RuleTrackStateModel>();
|
||||||
|
CreateMap<FactorItemDto, FactorItemModel>();
|
||||||
|
CreateMap<RuleAreaEntity, AreaDto>();
|
||||||
|
CreateMap<UpdateRuleAreaRequest, RuleAreaEntity>(MemberList.None);
|
||||||
|
CreateMap<AddRuleAreaInfoRequest, RuleAreaInfoEntity>(MemberList.None)
|
||||||
|
.ForMember(dest => dest.Country, opt => opt.MapFrom(src => src.Country))
|
||||||
|
.ForMember(dest => dest.Province, opt => opt.MapFrom(src => src.Province))
|
||||||
|
.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))
|
||||||
|
.ForMember(dest => dest.AreaId, opt => opt.MapFrom(src => src.AreaId));
|
||||||
|
|
||||||
|
CreateMap<CreateRuleAreaRequest, RuleAreaEntity>(MemberList.None)
|
||||||
|
.ForMember(dest => dest.SubSystemId, opt => opt.MapFrom(src => src.SystemId))
|
||||||
|
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name));
|
||||||
|
|
||||||
|
CreateMap<UpdateRuleAreaInfoRequest, RuleAreaInfoEntity>(MemberList.None)
|
||||||
|
.ForMember(dest => dest.Country, opt => opt.MapFrom(src => src.Country))
|
||||||
|
.ForMember(dest => dest.Province, opt => opt.MapFrom(src => src.Province))
|
||||||
|
.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));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,10 @@
|
|||||||
using DotNetCore.CAP;
|
using DotNetCore.CAP;
|
||||||
using SJZY.Track.Application.Contract.Events;
|
using SJZY.Track.Application.Contract.Events;
|
||||||
|
using SJZY.Track.Application.Contract.Services;
|
||||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||||
using SJZY.Track.Domain.Consts;
|
using SJZY.Track.Domain.Consts;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
using Volo.Abp.DependencyInjection;
|
using Volo.Abp.DependencyInjection;
|
||||||
|
|
||||||
namespace SJZY.Track.Application.CAP.EventHandlers;
|
namespace SJZY.Track.Application.CAP.EventHandlers;
|
||||||
@ -11,12 +13,15 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
|||||||
{
|
{
|
||||||
private readonly IOrderRepository _orderRepository;
|
private readonly IOrderRepository _orderRepository;
|
||||||
private readonly ITrackDetailsRepository _trackDetailsRepository;
|
private readonly ITrackDetailsRepository _trackDetailsRepository;
|
||||||
|
private readonly IForewarningNotifyService _forewarningNotifyService;
|
||||||
|
|
||||||
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository,
|
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository,
|
||||||
ITrackDetailsRepository trackDetailsRepository)
|
ITrackDetailsRepository trackDetailsRepository,
|
||||||
|
IForewarningNotifyService forewarningNotifyService)
|
||||||
{
|
{
|
||||||
_orderRepository = orderRepository;
|
_orderRepository = orderRepository;
|
||||||
_trackDetailsRepository = trackDetailsRepository;
|
_trackDetailsRepository = trackDetailsRepository;
|
||||||
|
_forewarningNotifyService = forewarningNotifyService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CapSubscribe(GlobalConst.TrackChangeAfterUpdateOrderSubscribe)]
|
[CapSubscribe(GlobalConst.TrackChangeAfterUpdateOrderSubscribe)]
|
||||||
@ -68,4 +73,40 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
|||||||
x.LatestTrackTimeZone
|
x.LatestTrackTimeZone
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.IsTransfer,
|
||||||
|
DeparturePort = 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? DetermineMonthBasedOnOrderDetails(OrderEntity order)
|
||||||
|
{
|
||||||
|
// Implement logic to determine Month
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int? DetermineAreaBasedOnOrderDetails(OrderEntity order)
|
||||||
|
{
|
||||||
|
// Implement logic to determine Area
|
||||||
|
return default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
using JetBrains.Annotations;
|
||||||
|
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Helpers;
|
||||||
|
|
||||||
|
public class ForewarningFactorHelper
|
||||||
|
{
|
||||||
|
public static RuleCollectEntity[] GetFactorItem([NotNull]RuleFactorEntity ruleFactors)
|
||||||
|
{
|
||||||
|
var total = Factorial(ruleFactors);
|
||||||
|
var ruleCollect = AllocateFactor(total,ruleFactors.RuleId);
|
||||||
|
Assignment(ruleCollect,total,ruleFactors.CargoTypes,(item,value)=>item.CargoType=value);
|
||||||
|
Assignment(ruleCollect,total,ruleFactors.Months,(item,value)=>item.Month=value);
|
||||||
|
Assignment(ruleCollect,total,ruleFactors.Areas,(item,value)=>item.Area=value);
|
||||||
|
Assignment(ruleCollect,total,ruleFactors.IsTransit,(item,value)=>item.IsTransit=value);
|
||||||
|
Assignment(ruleCollect,total,ruleFactors.DeparturePorts,(item,value)=>item.DeparturePort=value);
|
||||||
|
Assignment(ruleCollect,total,ruleFactors.ProductCodes,(item,value)=>item.ProductCode=value);
|
||||||
|
return ruleCollect.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Assignment<T>(Span<RuleCollectEntity> ruleCollect,int total,IReadOnlyList<T> values,Action<RuleCollectEntity,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<RuleCollectEntity> AllocateFactor(int total,int ruleId)
|
||||||
|
{
|
||||||
|
|
||||||
|
Span<RuleCollectEntity> factors = new RuleCollectEntity[total];
|
||||||
|
for (int index = 0; index < total; index++)
|
||||||
|
{
|
||||||
|
factors[index] = new RuleCollectEntity()
|
||||||
|
{
|
||||||
|
RuleId = ruleId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return factors;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int Factorial(RuleFactorEntity ruleFactors)
|
||||||
|
{
|
||||||
|
return ruleFactors.CargoTypes.Count*ruleFactors.Months.Count*ruleFactors.Areas.Count*ruleFactors.IsTransit.Count*ruleFactors.DeparturePorts.Count*ruleFactors.ProductCodes.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,4 +29,8 @@
|
|||||||
<ProjectReference Include="..\SJZY.Track.Domain\SJZY.Track.Domain.csproj" />
|
<ProjectReference Include="..\SJZY.Track.Domain\SJZY.Track.Domain.csproj" />
|
||||||
<ProjectReference Include="..\SJZY.Track.Application.Contract\SJZY.Track.Application.Contract.csproj" />
|
<ProjectReference Include="..\SJZY.Track.Application.Contract\SJZY.Track.Application.Contract.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Validations\Forewarning\FactorItemDtoValidator.cs" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -0,0 +1,236 @@
|
|||||||
|
using FreeRedis;
|
||||||
|
using NetTaste;
|
||||||
|
using SJZY.Expand.ABP.Core;
|
||||||
|
using SJZY.Track.Application.Contract.Services;
|
||||||
|
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
using SJZY.Track.Domain.Consts;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
using SJZY.Track.Domain.Enums;
|
||||||
|
using SqlSugar;
|
||||||
|
using Volo.Abp.DependencyInjection;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Services.ForewarningServices;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 单例服务,用于处理预警通知
|
||||||
|
/// </summary>
|
||||||
|
public class ForewarningNotifyService:IForewarningNotifyService,ITransientDependency
|
||||||
|
{
|
||||||
|
private IRuleFactorCacheService _ruleFactorCache;
|
||||||
|
IReadOnlyDictionary<string,List<ForewarningRule>> _ruleGroupDict;
|
||||||
|
IReadOnlyDictionary<string,List<RuleFactor>> _factorDict;
|
||||||
|
private IReadOnlyDictionary<int, ForewarningRule> _rules;
|
||||||
|
readonly INotifyService _notifyService;
|
||||||
|
|
||||||
|
public ForewarningNotifyService(IRuleFactorCacheService ruleFactorCache, INotifyService notifyService)
|
||||||
|
{
|
||||||
|
_ruleFactorCache = ruleFactorCache;
|
||||||
|
_notifyService = notifyService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建预警通知
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="order">创建预警通知需要的订单信息</param>
|
||||||
|
/// <returns>创建的通知总量,0表示没有规则</returns>
|
||||||
|
public async Task<int> CreateForewarningNotify(ForewarningOrderModel order)
|
||||||
|
{
|
||||||
|
var rules = GetRule(order);
|
||||||
|
if (rules == null || rules.Count == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return await ExecuteRule(rules,order.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除预警通知
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="order">订单信息</param>
|
||||||
|
/// <returns>清理的行数</returns>
|
||||||
|
public async Task<int> DeleteForewarningNotify(ForewarningOrderModel order)
|
||||||
|
{
|
||||||
|
var rules = GetRule(order);
|
||||||
|
if (rules == null || rules.Count == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var willDeleteMembers = new List<string>();
|
||||||
|
foreach (var rule in rules)
|
||||||
|
{
|
||||||
|
var allRuleNotities= DeleteNotifyValue(rule, order.Id);
|
||||||
|
willDeleteMembers.AddRange(allRuleNotities);
|
||||||
|
}
|
||||||
|
|
||||||
|
await RedisHelper.Client.ZRemAsync(GlobalConst.ForewarningNotifyKeyPrefix, willDeleteMembers.ToArray());
|
||||||
|
return willDeleteMembers.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendNotification(int intervalMinute)
|
||||||
|
{
|
||||||
|
var currentTimestamp = GetTimestamp(DateTime.Now);
|
||||||
|
var notifyMembers = RedisHelper.Client.ZRangeByScore(GlobalConst.ForewarningNotifyKeyPrefix, 0, currentTimestamp);
|
||||||
|
if (notifyMembers == null || notifyMembers.Length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var notifyValues = notifyMembers.Select(val => new RuleNotifyValue(val));
|
||||||
|
foreach (var notifyValue in notifyValues)
|
||||||
|
{
|
||||||
|
if(!_rules.TryGetValue(notifyValue.RuleId, out var rule))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//todo 发送通知
|
||||||
|
_notifyService.SendNotification("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearCache()
|
||||||
|
{
|
||||||
|
_ruleGroupDict = null;
|
||||||
|
_factorDict = null;
|
||||||
|
_rules = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<string> DeleteNotifyValue(ForewarningRule rule,int orderId)
|
||||||
|
{
|
||||||
|
var members = new List<string>();
|
||||||
|
for(var index=0;index<rule.Count;index++)
|
||||||
|
{
|
||||||
|
var notifyValue = NotifyValue(rule, orderId, index);
|
||||||
|
members.Add(notifyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取规则
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rule"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private List<ForewarningRule> GetRule(ForewarningOrderModel order)
|
||||||
|
{
|
||||||
|
if (!_factorDict.TryGetValue(GetFactorKey(order.CustomerId, order.SystemId), out var factors))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var keys = GetForewarningKeys(factors, order);
|
||||||
|
var result = new List< ForewarningRule>();
|
||||||
|
|
||||||
|
foreach (var item in keys)
|
||||||
|
{
|
||||||
|
if (!_ruleGroupDict.TryGetValue(item, out var rules))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var allRules = rules.Where(val=>val.TrackStart <= order.Track && val.TrackEnd >= order.Track);
|
||||||
|
result.AddRange(allRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async ValueTask<int> ExecuteRule(List<ForewarningRule> rules,int orderId)
|
||||||
|
{
|
||||||
|
var members = new List<ZMember>();
|
||||||
|
foreach (var rule in rules)
|
||||||
|
{
|
||||||
|
var notifys = ExecuteRule(rule,orderId);
|
||||||
|
members.AddRange(notifys);
|
||||||
|
}
|
||||||
|
|
||||||
|
await RedisHelper.Client.ZAddAsync(GlobalConst.ForewarningNotifyKeyPrefix, members.ToArray());
|
||||||
|
return members.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ZMember> ExecuteRule(ForewarningRule rule,int orderId)
|
||||||
|
{
|
||||||
|
var members = new List<ZMember>();
|
||||||
|
var intervalMinute = 60 * ((rule.Timeliness - rule.Remind) / rule.Count);// 间隔多少分钟
|
||||||
|
|
||||||
|
for(var index=0;index<rule.Count;index++)
|
||||||
|
{
|
||||||
|
var notifyTime = (rule.Remind*60) + intervalMinute * index;
|
||||||
|
var notifyTimestamp = GetTimestamp(DateTime.Now.AddMinutes(notifyTime));
|
||||||
|
var notifyValue = new ZMember(NotifyValue(rule, orderId, index),notifyTimestamp);
|
||||||
|
members.Add(notifyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long GetTimestamp(DateTime dateTime)
|
||||||
|
{
|
||||||
|
return new DateTimeOffset(dateTime).ToUnixTimeSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string NotifyValue(ForewarningRule rule, int orderId,int sort)
|
||||||
|
{
|
||||||
|
var result =new RuleNotifyValue(rule.Id, orderId, sort, rule.TrackEnd);
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<string> GetForewarningKeys(List<RuleFactor> factors, IForewarningFactorValue rule)
|
||||||
|
{
|
||||||
|
var keys = new List<string>();
|
||||||
|
foreach (var factor in factors)
|
||||||
|
{
|
||||||
|
var key = GetRuleKey(rule, factor);
|
||||||
|
keys.Add(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Init()
|
||||||
|
{
|
||||||
|
var allFactorCollect = await _ruleFactorCache.GetAllFactorCollect();
|
||||||
|
var factors = await _ruleFactorCache.GetAllRuleFactor();
|
||||||
|
var factorsMap = factors.GroupBy(val=>val.RuleId)
|
||||||
|
.ToDictionary(val=>val.Key,val=>val.First());
|
||||||
|
|
||||||
|
_rules = allFactorCollect.ToDictionary(val => val.Id);
|
||||||
|
|
||||||
|
_factorDict = factors.GroupBy(val => GetFactorKey(val.CustomerId,val.SystemId))
|
||||||
|
.ToDictionary(val=>val.Key,val=>val.ToList());
|
||||||
|
|
||||||
|
_ruleGroupDict = allFactorCollect.GroupBy(x => GetRuleKey(x, factorsMap[x.RuleId]))
|
||||||
|
.ToDictionary(val => val.Key, val => val.ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetFactorKey(int customerId,int systemId)
|
||||||
|
{
|
||||||
|
return $"{customerId}:{systemId}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetRuleKey(IForewarningFactorValue rule,RuleFactor factors)
|
||||||
|
{
|
||||||
|
var key = "";
|
||||||
|
foreach (var factorItem in factors.FactorItems)
|
||||||
|
{
|
||||||
|
key+=GetFactorValue(factorItem,rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetFactorValue(FactorItemModel factorItem, IForewarningFactorValue rule)
|
||||||
|
{
|
||||||
|
switch (factorItem.FactorType)
|
||||||
|
{
|
||||||
|
case RuleFactorType.Areas:
|
||||||
|
return rule.Area.HasValue ? rule.Area.Value.ToString() : throw new Exception("区域不能为空");
|
||||||
|
case RuleFactorType.CargoType:
|
||||||
|
return rule.CargoType;
|
||||||
|
case RuleFactorType.DeparturePort:
|
||||||
|
return rule.DeparturePort;
|
||||||
|
case RuleFactorType.Month:
|
||||||
|
return rule.Month.HasValue ? rule.Month.Value.ToString() : throw new Exception("月份不能为空");
|
||||||
|
case RuleFactorType.ProductCode:
|
||||||
|
return rule.ProductCode;
|
||||||
|
case RuleFactorType.IsTransit:
|
||||||
|
return rule.IsTransit.HasValue ? "1" : "0";
|
||||||
|
// Add additional cases for other RuleFactorTypes as needed
|
||||||
|
default:
|
||||||
|
throw new Exception("未知的规则类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,128 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using AutoMapper;
|
||||||
|
using SJZY.Track.Application.Helpers;
|
||||||
|
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
using SqlSugar;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Services.ForewarningServices;
|
||||||
|
|
||||||
|
[ApiExplorerSettings(GroupName = "预警服务")]
|
||||||
|
[Route("/ForewarningService")]
|
||||||
|
public class ForewarningService: ApplicationService
|
||||||
|
{
|
||||||
|
readonly IRuleRepository _ruleRepository;
|
||||||
|
IRuleFactorRepository _ruleFactorRepository;
|
||||||
|
private IRuleCollectRepository _ruleCollectRepository;
|
||||||
|
|
||||||
|
public ForewarningService(IRuleRepository ruleRepository
|
||||||
|
,IRuleFactorRepository ruleFactorRepository
|
||||||
|
, IRuleCollectRepository ruleCollectRepository)
|
||||||
|
{
|
||||||
|
_ruleRepository = ruleRepository;
|
||||||
|
_ruleFactorRepository = ruleFactorRepository;
|
||||||
|
_ruleCollectRepository = ruleCollectRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建预警模板,存在则更新
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("ModifyForewarning")]
|
||||||
|
public async ValueTask<UnifyResultDto> ModifyForewarning(CreateRuleFactorRequest input)
|
||||||
|
{
|
||||||
|
var factors = ObjectMapper.Map<CreateRuleFactorRequest,RuleFactorEntity>(input);
|
||||||
|
var ruleCollects = 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, ruleCollects);
|
||||||
|
return new UnifyResultDto(true,"保存成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
var newRuleTemplate = ObjectMapper.Map<CreateRuleFactorRequest, RuleEntity>(input);
|
||||||
|
var ruleTemplateId = await _ruleRepository.CreateForewarning(newRuleTemplate, ruleCollects);
|
||||||
|
factors.Id = ruleTemplateId.ToString();
|
||||||
|
return new UnifyResultDto(true,"保存成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改时效
|
||||||
|
/// </summary>
|
||||||
|
[HttpPost("ModifyTimeliness")]
|
||||||
|
public async ValueTask<UnifyResultDto> ModifyTimeliness(ModifyTimelinessRequest input)
|
||||||
|
{
|
||||||
|
var ruleIds = input.Items.Select(val=>val.Id).ToList();
|
||||||
|
var ruleCollect = await _ruleCollectRepository.GetListAsync(val => ruleIds.Contains(val.Id) && val.RuleId == input.RuleId);
|
||||||
|
if (ruleCollect == null|| ruleCollect.Count == 0)
|
||||||
|
throw new BusinessException(message:"规则不存在");
|
||||||
|
|
||||||
|
var ruleMaps = ruleCollect.ToDictionary(val => val.Id);
|
||||||
|
var notModifyList = new List<int>();
|
||||||
|
foreach (var item in input.Items)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _ruleCollectRepository.UpdateRangeAsync(ruleCollect,val=>val.RuleId==input.RuleId);
|
||||||
|
|
||||||
|
if (notModifyList.Count > 0)
|
||||||
|
return new UnifyResultDto(true, $"更新成功,规则{string.Join(",", notModifyList)}不存在");
|
||||||
|
|
||||||
|
return new UnifyResultDto(true, "更新成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询预警模板列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("QueryForewarning")]
|
||||||
|
public async Task<UnifyResultDto> QueryForewarning(QueryForewarningRequest input)
|
||||||
|
{
|
||||||
|
var result = await _ruleRepository.QueryForewarning(input);
|
||||||
|
return new UnifyResultDto(true, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询预警规则列表
|
||||||
|
/// </summary>
|
||||||
|
[HttpPost("QueryForewarningRules")]
|
||||||
|
public async Task<UnifyResultDto> QueryForewarningRules(QueryForewarningRuleRequest input)
|
||||||
|
{
|
||||||
|
var result = await _ruleCollectRepository.QueryForewarningRule(input);
|
||||||
|
return new UnifyResultDto(true, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送预警通知
|
||||||
|
/// </summary>
|
||||||
|
[HttpPost("SendForewarningNotification")]
|
||||||
|
public void SendForewarningNotification()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
using SJZY.Expand.ABP.Core;
|
||||||
|
using SJZY.Track.Application.Contract.Services;
|
||||||
|
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||||
|
using SJZY.Track.Domain.Consts;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
using Volo.Abp.DependencyInjection;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Services.ForewarningServices;
|
||||||
|
|
||||||
|
public class KpiAreaCacheService:IKpiAreaCacheService,ITransientDependency
|
||||||
|
{
|
||||||
|
IKpiAreaRepository _kpiAreaRepository;
|
||||||
|
const string GlobalKpiAreaLockKey = "KpiAreaCacheService_GlobalLock";
|
||||||
|
|
||||||
|
public KpiAreaCacheService(IKpiAreaRepository kpiAreaRepository)
|
||||||
|
{
|
||||||
|
_kpiAreaRepository = kpiAreaRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetKey(int systemId, string country)
|
||||||
|
{
|
||||||
|
return $"{GlobalConst.KpiAreaKeyPrefix}:{systemId}:{country}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task GetKpiArea(int systemId, string country)
|
||||||
|
{
|
||||||
|
var key = GetKey(systemId, country);
|
||||||
|
var result = RedisHelper.Client.Get<KpiAreaInfo>(key);
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
using (var globalLock = RedisHelper.Client.Lock(GlobalKpiAreaLockKey, 10))
|
||||||
|
{
|
||||||
|
result = RedisHelper.Client.Get<KpiAreaInfo>(key);
|
||||||
|
if (result != null) return;
|
||||||
|
|
||||||
|
//todo 转换成KpiAreaInfo
|
||||||
|
var kpiArea =await _kpiAreaRepository.GetAllAreaInfos();
|
||||||
|
if (kpiArea == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RedisHelper.Client.Set(key, kpiArea, TimeSpan.FromSeconds(20));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
using SqlSugar;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Services.ForewarningServices;
|
||||||
|
|
||||||
|
[ApiExplorerSettings(GroupName = "预警服务")]
|
||||||
|
[Route("/ForewarningService")]
|
||||||
|
public class KpiAreaService : ApplicationService
|
||||||
|
{
|
||||||
|
readonly IKpiAreaRepository _ruleAreaRepository;
|
||||||
|
|
||||||
|
public KpiAreaService(IKpiAreaRepository ruleAreaRepository )
|
||||||
|
{
|
||||||
|
_ruleAreaRepository = ruleAreaRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建分区
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns>分区id</returns>
|
||||||
|
[HttpPost("KpiArea/CreateKpiArea")]
|
||||||
|
public async ValueTask<UnifyResultDto> CreateKpiArea(CreateRuleAreaRequest input)
|
||||||
|
{
|
||||||
|
var ruleAreaEntity = ObjectMapper.Map<CreateRuleAreaRequest, RuleAreaEntity>(input);
|
||||||
|
var areaId = await _ruleAreaRepository.CreateAreaAsync(ruleAreaEntity);
|
||||||
|
return new UnifyResultDto(true,areaId, "创建成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加区域信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns>区域id</returns>
|
||||||
|
[HttpPost("KpiArea/AddAreaInfo")]
|
||||||
|
public async ValueTask<UnifyResultDto> AddAreaInfoAsync(AddRuleAreaInfoRequest input)
|
||||||
|
{
|
||||||
|
var ruleAreaEntity = ObjectMapper.Map<AddRuleAreaInfoRequest, RuleAreaInfoEntity>(input);
|
||||||
|
var ruleInfoId = await _ruleAreaRepository.AddAreaInfoAsync(ruleAreaEntity);
|
||||||
|
return new UnifyResultDto(true,ruleInfoId, "添加成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除分区
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">分区id</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete("KpiArea/DeleteKpiArea")]
|
||||||
|
public async ValueTask<UnifyResultDto> DeleteKpiArea(int id)
|
||||||
|
{
|
||||||
|
await _ruleAreaRepository.DeleteArea(id);
|
||||||
|
return new UnifyResultDto(true, "删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除分区信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">分区信息id</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete("KpiArea/DeleteKpiAreaInfo")]
|
||||||
|
public async ValueTask<UnifyResultDto> DeleteKpiAreaInfo(int id)
|
||||||
|
{
|
||||||
|
await _ruleAreaRepository.DeleteAreaInfo(id);
|
||||||
|
return new UnifyResultDto(true, "删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新区域信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("KpiArea/ModifyKpiArea")]
|
||||||
|
public async Task<UnifyResultDto> ModifyKpiArea(UpdateRuleAreaRequest input)
|
||||||
|
{
|
||||||
|
if(input.Id<=0)
|
||||||
|
return new UnifyResultDto(false,"id不能为空");
|
||||||
|
|
||||||
|
var ruleArea =await _ruleAreaRepository.GetFirstAsync(val=>val.Id==input.Id);
|
||||||
|
if(ruleArea==null)
|
||||||
|
return new UnifyResultDto(false,"未找到该区域");
|
||||||
|
|
||||||
|
ruleArea.Name = input.Name;
|
||||||
|
await _ruleAreaRepository.UpdateAsync(ruleArea);
|
||||||
|
return new UnifyResultDto(true,"更新成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新区域信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("KpiArea/ModifyKpiAreaInfo")]
|
||||||
|
public async Task<UnifyResultDto> ModifyKpiAreaInfo(UpdateRuleAreaInfoRequest input)
|
||||||
|
{
|
||||||
|
if(input.Id<=0)
|
||||||
|
return new UnifyResultDto(false,"id不能为空");
|
||||||
|
|
||||||
|
//todo 测试不存在id的情况
|
||||||
|
RuleAreaInfoEntity areaInfo = await _ruleAreaRepository.GetAreaInfoById(input.Id);
|
||||||
|
if(areaInfo==null)
|
||||||
|
return new UnifyResultDto(false,"未找到该区域信息");
|
||||||
|
|
||||||
|
var ruleAreaEntity = ObjectMapper.Map(input,areaInfo);
|
||||||
|
await _ruleAreaRepository.UpdateAreaInfoAsync(ruleAreaEntity);
|
||||||
|
return new UnifyResultDto(true,"更新成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询分区列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("KpiArea/GetKpiAreas")]
|
||||||
|
public async Task<UnifyPageResultDto<AreaDto>> GetKpiAreas(QueryAreaRequest input)
|
||||||
|
{
|
||||||
|
return await _ruleAreaRepository.GetAreas(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询分区列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("KpiArea/GetKpiAreaInfos")]
|
||||||
|
public async Task<UnifyPageResultDto<RuleAreaInfoDto>> GetKpiAreaInfos(QueryAreaInfoRequest query)
|
||||||
|
{
|
||||||
|
return await _ruleAreaRepository.GetAreaInfos(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,195 @@
|
|||||||
|
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 IRuleCollectRepository _ruleCollectRepository;
|
||||||
|
readonly IRuleRepository _ruleRepository;
|
||||||
|
|
||||||
|
public RuleFactorCacheService(IRuleFactorRepository ruleFactorRepository,
|
||||||
|
IRuleCollectRepository ruleCollectRepository, IRuleRepository ruleRepository)
|
||||||
|
{
|
||||||
|
_ruleFactorRepository = ruleFactorRepository;
|
||||||
|
_ruleCollectRepository = ruleCollectRepository;
|
||||||
|
_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 _ruleCollectRepository.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(RuleCollectEntity 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(RuleCollectEntity entity)
|
||||||
|
{
|
||||||
|
return new ForewarningRule
|
||||||
|
{
|
||||||
|
Id = entity.Id,
|
||||||
|
RuleId = entity.RuleId,
|
||||||
|
Remind = entity.Remind,
|
||||||
|
Timeliness = entity.Timeliness,
|
||||||
|
Count = entity.Count,
|
||||||
|
TrackStart = entity.TrackStart,
|
||||||
|
TrackEnd = entity.TrackEnd,
|
||||||
|
CargoType = entity.CargoType,
|
||||||
|
Month = null,
|
||||||
|
Area = entity.Area,
|
||||||
|
IsTransit = entity.IsTransit,
|
||||||
|
DeparturePort = entity.DeparturePort,
|
||||||
|
ProductCode = entity.ProductCode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using SJZY.Track.Application.Contract.Services;
|
||||||
|
using Volo.Abp.DependencyInjection;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Services.Notifies;
|
||||||
|
|
||||||
|
public class NotifyService:INotifyService, ITransientDependency
|
||||||
|
{
|
||||||
|
public void SendNotification(string body)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Validations.Forewarning;
|
||||||
|
|
||||||
|
public class CreateRuleFactorValidation : AbstractValidator<CreateRuleFactorRequest>
|
||||||
|
{
|
||||||
|
public CreateRuleFactorValidation()
|
||||||
|
{
|
||||||
|
RuleForEach(x => x.Tracks).SetValidator(new RuleTrackStateDtoValidator());
|
||||||
|
RuleFor(x => x.FactorItems).NotNull().WithMessage("FactorItems cannot be null.");
|
||||||
|
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace SJZY.Track.Application.Validations.Forewarning;
|
||||||
|
|
||||||
|
public class FactorItemDtoValidator
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Application.Validations.Forewarning;
|
||||||
|
|
||||||
|
public class RuleTrackStateDtoValidator : AbstractValidator<RuleTrackStateDto>
|
||||||
|
{
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
using SJZY.Track.Domain.Enums;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
|
||||||
|
public class FactorItemModel
|
||||||
|
{
|
||||||
|
/// <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; }
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
|
||||||
|
public interface IForewarningList
|
||||||
|
{
|
||||||
|
void AddForewarning(int score,int id);
|
||||||
|
|
||||||
|
void DeleteForewarning(int score,int id);
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
|
||||||
|
public interface IRuleCollectRepository:IBasicRepository<RuleCollectEntity>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 查询分页
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<UnifyPageResultDto<RuleCollectDto>> QueryForewarningRule(QueryForewarningRuleRequest input);
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
|
||||||
|
public interface IRuleRepository:IBasicRepository<RuleEntity>
|
||||||
|
{
|
||||||
|
Task<int> CreateForewarning(RuleEntity rule, RuleCollectEntity[] factorList);
|
||||||
|
|
||||||
|
Task UpdateForewarning(RuleEntity rule, RuleCollectEntity[] factorList);
|
||||||
|
|
||||||
|
Task<UnifyPageResultDto<RuleEntity>> QueryForewarning(QueryForewarningRequest input);
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
|
||||||
|
public class RuleAreaEntity
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,110 @@
|
|||||||
|
namespace SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
|
||||||
|
[SugarTable("t_rule_collect")]
|
||||||
|
public class RuleCollectEntity : 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
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; }
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
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; }
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
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; }
|
||||||
|
}
|
||||||
6
src/SJZY.Track.Domain/Aggregates/KPIAreaAggregate.cs
Normal file
6
src/SJZY.Track.Domain/Aggregates/KPIAreaAggregate.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace SJZY.Track.Domain.Aggregates;
|
||||||
|
|
||||||
|
public class KPIAreaAggregate
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||||
|
|
||||||
|
public interface IKpiAreaRepository:IBasicRepository<RuleAreaEntity>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 创建分区
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
ValueTask<int> CreateAreaAsync(RuleAreaEntity entity);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加分区信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
ValueTask<int> AddAreaInfoAsync(RuleAreaInfoEntity entity);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除分区信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="areaInfoId">分区信息id</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<int> DeleteAreaInfo(int areaInfoId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除分区
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="areaId">分区id</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
ValueTask DeleteArea(int areaId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新区域信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<int> UpdateAreaInfoAsync(RuleAreaInfoEntity entity);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获得分区
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<UnifyPageResultDto<AreaDto>> GetAreas(QueryAreaRequest query);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取分区信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<UnifyPageResultDto<RuleAreaInfoDto>> GetAreaInfos(QueryAreaInfoRequest query);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取分区信息通过id
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<RuleAreaInfoEntity> GetAreaInfoById(int id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有区域信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<List<RuleAreaInfoEntity>> GetAllAreaInfos();
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
namespace SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||||
|
|
||||||
|
[SugarTable("t_rule_area", TableDescription = "KPI分区主表")]
|
||||||
|
public class RuleAreaEntity : IAggregateRoot
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 自增主键
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "自增主键")]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 子系统id
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "SubSystemId", ColumnDescription = "子系统id")]
|
||||||
|
public int SubSystemId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分区名称KPI名称
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "Name", Length = 64, ColumnDescription = "分区名称KPI名称")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建人
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "CreateUserId", ColumnDescription = "创建人")]
|
||||||
|
public int CreateUserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "CreateTime", ColumnDescription = "创建时间")]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新人
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "UpdateUserId", ColumnDescription = "更新人")]
|
||||||
|
public int UpdateUserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "UpdateTime", ColumnDescription = "更新时间")]
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
|
||||||
|
[SugarColumn(IsIgnore = true)]
|
||||||
|
public List<RuleAreaInfoEntity> AreaInfos { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
namespace SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||||
|
|
||||||
|
[SugarTable("t_rule_area_info", TableDescription = "kpi 区域子表")]
|
||||||
|
public class RuleAreaInfoEntity : IEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 自增主键
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "自增主键")]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// t_rule_area 表id
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "AreaId", ColumnDescription = "t_rule_area 表id")]
|
||||||
|
public int AreaId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 国家或地区
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "Country", Length = 128, ColumnDescription = "国家或地区")]
|
||||||
|
public string Country { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 州或者省份
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "Province", Length = 128, IsNullable = true, ColumnDescription = "州或者省份")]
|
||||||
|
public string Province { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 城市
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "City", Length = 128, IsNullable = true, ColumnDescription = "城市")]
|
||||||
|
public string City { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 起始邮编
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "LeftPostcode", Length = 10, IsNullable = true, ColumnDescription = "起始邮编")]
|
||||||
|
public string LeftPostcode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 截止邮编
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "RightPostcode", Length = 10, IsNullable = true, ColumnDescription = "截止邮编")]
|
||||||
|
public string RightPostcode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建人
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "CreateUserId", ColumnDescription = "创建人")]
|
||||||
|
public int CreateUserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "CreateTime", ColumnDescription = "创建时间")]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新人
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "UpdateUserId", IsNullable = false, ColumnDescription = "更新人")]
|
||||||
|
public int UpdateUserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "UpdateTime", IsNullable = false, ColumnDescription = "更新时间")]
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
}
|
||||||
@ -131,6 +131,24 @@ public class OrderEntity : IFullAuditedBasicEntitys, IAggregateRoot
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(ColumnName = "LeavePort")]
|
[SugarColumn(ColumnName = "LeavePort")]
|
||||||
public string? LeavePort { get; set; }
|
public string? LeavePort { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 起运港口
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "CargoType")]
|
||||||
|
public string? CargoType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 起运港口
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "IsTransfer")]
|
||||||
|
public bool? IsTransfer { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 起运港口
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "ProductCode")]
|
||||||
|
public string? ProductCode { get; set; }
|
||||||
|
|
||||||
[SugarColumn(IsIgnore = true)] public List<OrderFlightEntity> OrderFlights { get; set; }
|
[SugarColumn(IsIgnore = true)] public List<OrderFlightEntity> OrderFlights { get; set; }
|
||||||
[SugarColumn(IsIgnore = true)] public List<OrderTemplateEntity> OrderTemplates { get; set; }
|
[SugarColumn(IsIgnore = true)] public List<OrderTemplateEntity> OrderTemplates { get; set; }
|
||||||
|
|||||||
@ -11,4 +11,9 @@ public partial class GlobalConst
|
|||||||
/// 轨迹推送记录 es索引名称(模板)
|
/// 轨迹推送记录 es索引名称(模板)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string TrackPushRecordsIndex = "sjzy_track_push_records";
|
public const string TrackPushRecordsIndex = "sjzy_track_push_records";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 预警规则 es索引名称(模板)
|
||||||
|
/// </summary>
|
||||||
|
public const string RuleFactorIndex = "sjzy_rule_factor";
|
||||||
}
|
}
|
||||||
@ -21,4 +21,19 @@ public partial class GlobalConst
|
|||||||
/// 轨迹拉取配置信息redis key前缀
|
/// 轨迹拉取配置信息redis key前缀
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string TrackPullContentKeyPrefix = "TrackPullContent";
|
public const string TrackPullContentKeyPrefix = "TrackPullContent";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 规则因素缓存redis key前缀
|
||||||
|
/// </summary>
|
||||||
|
public const string RuleFactorKeyPrefix = "RuleFactor";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 预警通知redis key前缀
|
||||||
|
/// </summary>
|
||||||
|
public const string ForewarningNotifyKeyPrefix = "ForewarningNotity";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// kpi区域redis key前缀
|
||||||
|
/// </summary>
|
||||||
|
public const string KpiAreaKeyPrefix = "KpiArea";
|
||||||
}
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class AddRuleAreaInfoRequest
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public string Country { get; set; }
|
||||||
|
|
||||||
|
public string? Province { get; set; }
|
||||||
|
|
||||||
|
public string? City { get; set; }
|
||||||
|
|
||||||
|
public string? LeftPostCode { get; set; }
|
||||||
|
|
||||||
|
public string? RightPostCode { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public int AreaId { get; set; }
|
||||||
|
}
|
||||||
9
src/SJZY.Track.Domain/Dtos/Forewarning/AreaDto.cs
Normal file
9
src/SJZY.Track.Domain/Dtos/Forewarning/AreaDto.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class AreaDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int SubSystemId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
}
|
||||||
35
src/SJZY.Track.Domain/Dtos/Forewarning/AreaInfoDto.cs
Normal file
35
src/SJZY.Track.Domain/Dtos/Forewarning/AreaInfoDto.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class RuleAreaInfoDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 分区信息id
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分区id
|
||||||
|
/// </summary>
|
||||||
|
public int AreaId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 国家或地区
|
||||||
|
/// </summary>
|
||||||
|
public string Country { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 省份
|
||||||
|
/// </summary>
|
||||||
|
public string Province { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 城市
|
||||||
|
/// </summary>
|
||||||
|
public string City { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始邮编
|
||||||
|
/// </summary>
|
||||||
|
public string LeftPostcode { get; set; }
|
||||||
|
public string RightPostcode { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class CreateRuleAreaRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 系统id
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public int SystemId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 名称
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
65
src/SJZY.Track.Domain/Dtos/Forewarning/CreateRuleRequest.cs
Normal file
65
src/SJZY.Track.Domain/Dtos/Forewarning/CreateRuleRequest.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning
|
||||||
|
{
|
||||||
|
public class CreateRuleFactorRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// RuleId 表的id,小于0 表示创建新的规则
|
||||||
|
/// </summary>
|
||||||
|
public int RuleId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模板名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 子系统id
|
||||||
|
/// </summary>
|
||||||
|
public int SubSystemId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 客户id
|
||||||
|
/// </summary>
|
||||||
|
public int CustomId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置规则跟踪状态实体的列表。
|
||||||
|
/// </summary>
|
||||||
|
public List<RuleTrackStateDto> Tracks { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置因素项模型的列表。
|
||||||
|
/// </summary>
|
||||||
|
public List<FactorItemDto> FactorItems { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置货物类型的列表。
|
||||||
|
/// </summary>
|
||||||
|
public List<string> CargoTypes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置月份的列表。
|
||||||
|
/// </summary>
|
||||||
|
public List<string> Months { get; set; }
|
||||||
|
|
||||||
|
/// <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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/SJZY.Track.Domain/Dtos/Forewarning/FactorItemDto.cs
Normal file
16
src/SJZY.Track.Domain/Dtos/Forewarning/FactorItemDto.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
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; }
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class ForewarningOrderModel:IForewarningFactorValue
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 订单id
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前轨迹状态
|
||||||
|
/// </summary>
|
||||||
|
public int Track { get; set; }
|
||||||
|
|
||||||
|
public int SystemId { get; set; }
|
||||||
|
|
||||||
|
public int CustomerId { 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; }
|
||||||
|
}
|
||||||
26
src/SJZY.Track.Domain/Dtos/Forewarning/ForewarningRule.cs
Normal file
26
src/SJZY.Track.Domain/Dtos/Forewarning/ForewarningRule.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public record struct ForewarningRule:IForewarningFactorValue
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int CustomerId { get; set; }
|
||||||
|
|
||||||
|
public int SystemId { 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 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 Conect { get; set; }
|
||||||
|
|
||||||
|
public string Template { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public interface IForewarningFactorValue
|
||||||
|
{
|
||||||
|
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; }
|
||||||
|
}
|
||||||
6
src/SJZY.Track.Domain/Dtos/Forewarning/KpiAreaInfo.cs
Normal file
6
src/SJZY.Track.Domain/Dtos/Forewarning/KpiAreaInfo.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class KpiAreaInfo
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class ModifyTimelinessRequest
|
||||||
|
{
|
||||||
|
public List<TimelinessDto> Items { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 规则模板id
|
||||||
|
/// </summary>
|
||||||
|
public int RuleId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
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; }
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class QueryAreaInfoRequest: PageInfoInput
|
||||||
|
{
|
||||||
|
public int AreaId { get; set; }
|
||||||
|
}
|
||||||
14
src/SJZY.Track.Domain/Dtos/Forewarning/QueryAreaRequest.cs
Normal file
14
src/SJZY.Track.Domain/Dtos/Forewarning/QueryAreaRequest.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class QueryAreaRequest:PageInfoInput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 分区名称
|
||||||
|
/// </summary>
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 子系统id
|
||||||
|
/// </summary>
|
||||||
|
public int? SystemId { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class QueryForewarningRuleRequest: PageInfoInput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// kpi 预警规则模板id
|
||||||
|
/// </summary>
|
||||||
|
public int RuleId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 排序方式,不填不排序
|
||||||
|
/// </summary>
|
||||||
|
public string? SortField { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 排序方式
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAsc { get; set; } = false;
|
||||||
|
}
|
||||||
22
src/SJZY.Track.Domain/Dtos/Forewarning/RuleCollectDto.cs
Normal file
22
src/SJZY.Track.Domain/Dtos/Forewarning/RuleCollectDto.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
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; }
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class RuleCollectRequest
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
37
src/SJZY.Track.Domain/Dtos/Forewarning/RuleFactor.cs
Normal file
37
src/SJZY.Track.Domain/Dtos/Forewarning/RuleFactor.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class RuleFactor
|
||||||
|
{
|
||||||
|
public int RuleId { get; set; }
|
||||||
|
|
||||||
|
public int SystemId { get; set; }
|
||||||
|
|
||||||
|
public int CustomerId { get; set; }
|
||||||
|
|
||||||
|
/// <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; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置因素项模型的列表。
|
||||||
|
/// </summary>
|
||||||
|
public List<FactorItemModel> FactorItems { get; set; }
|
||||||
|
}
|
||||||
42
src/SJZY.Track.Domain/Dtos/Forewarning/RuleInfoModel.cs
Normal file
42
src/SJZY.Track.Domain/Dtos/Forewarning/RuleInfoModel.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
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; }
|
||||||
|
}
|
||||||
40
src/SJZY.Track.Domain/Dtos/Forewarning/RuleNotifyValue.cs
Normal file
40
src/SJZY.Track.Domain/Dtos/Forewarning/RuleNotifyValue.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class RuleNotifyValue
|
||||||
|
{
|
||||||
|
public int RuleId { get; set; }
|
||||||
|
|
||||||
|
public int OrderId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 第几次通知
|
||||||
|
/// </summary>
|
||||||
|
public int Count { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结束轨迹状态
|
||||||
|
/// </summary>
|
||||||
|
public int TrackEnd { get; set; }
|
||||||
|
|
||||||
|
public RuleNotifyValue(int ruleId, int orderId, int count, int trackEnd)
|
||||||
|
{
|
||||||
|
RuleId = ruleId;
|
||||||
|
OrderId = orderId;
|
||||||
|
Count = count;
|
||||||
|
TrackEnd = trackEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RuleNotifyValue(string notifyValue)
|
||||||
|
{
|
||||||
|
var values = notifyValue.Split(':');
|
||||||
|
RuleId = int.Parse(values[0]);
|
||||||
|
OrderId = int.Parse(values[1]);
|
||||||
|
Count = int.Parse(values[2]);
|
||||||
|
TrackEnd = int.Parse(values[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{RuleId}:{OrderId}:{Count}:{TrackEnd}";
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/SJZY.Track.Domain/Dtos/Forewarning/RuleTrackStateDto.cs
Normal file
24
src/SJZY.Track.Domain/Dtos/Forewarning/RuleTrackStateDto.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
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; }
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class UpdateRuleAreaInfoRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 分区信息id
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string Country { get; set; }
|
||||||
|
|
||||||
|
public string? Province { get; set; }
|
||||||
|
|
||||||
|
public string? City { get; set; }
|
||||||
|
|
||||||
|
public string? LeftPostCode { get; set; }
|
||||||
|
|
||||||
|
public string? RightPostCode { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
public class UpdateRuleAreaRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 名称
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分区id
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
38
src/SJZY.Track.Domain/Enums/RuleFactorType.cs
Normal file
38
src/SJZY.Track.Domain/Enums/RuleFactorType.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
namespace SJZY.Track.Domain.Enums;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 枚举表示不同类型的规则因素。
|
||||||
|
/// </summary>
|
||||||
|
public enum RuleFactorType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表示货物类型。
|
||||||
|
/// </summary>
|
||||||
|
CargoType,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示月份。
|
||||||
|
/// </summary>
|
||||||
|
Month,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示分区或区域。
|
||||||
|
/// </summary>
|
||||||
|
Areas,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 指示货物是否中转。
|
||||||
|
/// </summary>
|
||||||
|
IsTransit,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示起运港口。
|
||||||
|
/// </summary>
|
||||||
|
DeparturePort,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示产品编号。
|
||||||
|
/// </summary>
|
||||||
|
ProductCode
|
||||||
|
}
|
||||||
@ -11,5 +11,10 @@
|
|||||||
<PackageReference Include="SJZY.Expand.ABP.Core" Version="7.8.6"/>
|
<PackageReference Include="SJZY.Expand.ABP.Core" Version="7.8.6"/>
|
||||||
<PackageReference Include="SJZY.Expand.ElasticSearch" Version="7.0.17" />
|
<PackageReference Include="SJZY.Expand.ElasticSearch" Version="7.0.17" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Aggregates\KPIAreaAggregate.cs" />
|
||||||
|
<Compile Remove="Aggregates\ForewarningAggregate\RuleAreaEntity.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace SJZY.Track.Repository.Repositories;
|
||||||
|
|
||||||
|
public class KpiAreaInfoRepository
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
103
src/SJZY.Track.Repository/Repositories/KpiAreaRepository.cs
Normal file
103
src/SJZY.Track.Repository/Repositories/KpiAreaRepository.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
using SJZY.Track.Domain;
|
||||||
|
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Repository.Repositories;
|
||||||
|
|
||||||
|
public class KpiAreaRepository:BasicRepository<RuleAreaEntity> ,IKpiAreaRepository,ITransientDependency
|
||||||
|
{
|
||||||
|
public async ValueTask<int> CreateAreaAsync(RuleAreaEntity entity)
|
||||||
|
{
|
||||||
|
return await InsertReturnIdentityAsync(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<int> AddAreaInfoAsync(RuleAreaInfoEntity entity)
|
||||||
|
{
|
||||||
|
return await Context.Insertable(entity).ExecuteReturnIdentityAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask DeleteArea(int areaId)
|
||||||
|
{
|
||||||
|
using var transaction = TransactionHelper.GetReadCommitted();
|
||||||
|
await DeleteByIdAsync(areaId);
|
||||||
|
await Context.Deleteable<RuleAreaInfoEntity>().Where(x => x.AreaId == areaId).ExecuteCommandAsync();
|
||||||
|
transaction.Complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> DeleteAreaInfo(int areaInfoId)
|
||||||
|
{
|
||||||
|
return Context.Deleteable<RuleAreaInfoEntity>().Where(val=>val.Id==areaInfoId).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> UpdateAreaInfoAsync(RuleAreaInfoEntity entity)
|
||||||
|
{
|
||||||
|
return Context.Updateable<RuleAreaInfoEntity>(entity).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取分区
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<UnifyPageResultDto<AreaDto>> GetAreas(QueryAreaRequest query)
|
||||||
|
{
|
||||||
|
var queryable = Context.Queryable<RuleAreaEntity>();
|
||||||
|
if (!string.IsNullOrEmpty(query.Name))
|
||||||
|
{
|
||||||
|
queryable = queryable.Where(x => x.Name.Contains(query.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.SystemId.HasValue)
|
||||||
|
{
|
||||||
|
queryable = queryable.Where(x => x.SubSystemId == query.SystemId.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await queryable.OrderBy(x => x.Id, OrderByType.Desc)
|
||||||
|
.Select<AreaDto>(val=>new AreaDto()
|
||||||
|
{
|
||||||
|
Id = val.Id,
|
||||||
|
Name = val.Name,
|
||||||
|
SubSystemId = val.SubSystemId,
|
||||||
|
UpdateTime = val.CreateTime
|
||||||
|
})
|
||||||
|
.ToPagedListAsync(query.PageIndex, query.PageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获得分区信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<UnifyPageResultDto<RuleAreaInfoDto>> GetAreaInfos(QueryAreaInfoRequest query)
|
||||||
|
{
|
||||||
|
var queryable = Context.Queryable<RuleAreaInfoEntity>();
|
||||||
|
queryable = queryable.Where(x => x.AreaId == query.AreaId);
|
||||||
|
return await queryable.OrderBy(x => x.Id, OrderByType.Desc)
|
||||||
|
.Select<RuleAreaInfoDto>(val=>new RuleAreaInfoDto()
|
||||||
|
{
|
||||||
|
Id = val.Id,
|
||||||
|
AreaId = val.AreaId,
|
||||||
|
City = val.City,
|
||||||
|
Country = val.Country,
|
||||||
|
LeftPostcode = val.LeftPostcode,
|
||||||
|
RightPostcode = val.RightPostcode,
|
||||||
|
Province = val.Province
|
||||||
|
})
|
||||||
|
.ToPagedListAsync(query.PageIndex, query.PageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<RuleAreaInfoEntity> GetAreaInfoById(int id)
|
||||||
|
{
|
||||||
|
return Context.Queryable<RuleAreaInfoEntity>().FirstAsync(val => val.Id == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有区域信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<List<RuleAreaInfoEntity>> GetAllAreaInfos()
|
||||||
|
{
|
||||||
|
return Context.Queryable<RuleAreaInfoEntity>().ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
|
||||||
|
using SJZY.Track.Domain.Dtos.Forewarning;
|
||||||
|
|
||||||
|
namespace SJZY.Track.Repository.Repositories;
|
||||||
|
|
||||||
|
public class RuleCollectRepository: BasicRepository<RuleCollectEntity>, IRuleCollectRepository,ITransientDependency
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 查询预警规则分页信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<UnifyPageResultDto<RuleCollectDto>> QueryForewarningRule(QueryForewarningRuleRequest input)
|
||||||
|
{
|
||||||
|
var query = Context.Queryable<RuleCollectEntity>()
|
||||||
|
.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(RuleCollectEntity 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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/SJZY.Track.Repository/Repositories/RuleRepository.cs
Normal file
53
src/SJZY.Track.Repository/Repositories/RuleRepository.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
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, RuleCollectEntity[] factorList)
|
||||||
|
{
|
||||||
|
using var tran = TransactionHelper.GetReadCommitted();
|
||||||
|
|
||||||
|
var ruleId = await InsertReturnIdentityAsync(rule);
|
||||||
|
foreach (var item in factorList)
|
||||||
|
{
|
||||||
|
item.RuleId = ruleId;
|
||||||
|
}
|
||||||
|
await Context.Insertable(factorList).ExecuteCommandAsync();
|
||||||
|
tran.Complete();
|
||||||
|
return ruleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateForewarning(RuleEntity rule,RuleCollectEntity[] factorList)
|
||||||
|
{
|
||||||
|
using var tran = TransactionHelper.GetReadCommitted();
|
||||||
|
await UpdateAsync(rule);
|
||||||
|
await Context.Deleteable<RuleCollectEntity>().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>> QueryForewarning(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user