feat:预警迭代初步
This commit is contained in:
parent
25298dc494
commit
c44c4e3af2
@ -3,104 +3,104 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.Complete;
|
||||
/// <summary>
|
||||
/// 完整预警
|
||||
/// </summary>
|
||||
public class CompleteWarningDetailsDto // todo:需要根据状态排序
|
||||
public class CompleteWarningDetailsDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警明细唯一id
|
||||
/// </summary>
|
||||
public string EsId { get; set; }
|
||||
/// <summary>
|
||||
/// 预警明细唯一id
|
||||
/// </summary>
|
||||
public string EsId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int SubSystemId { get; set; }
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统名称
|
||||
/// </summary>
|
||||
public string SubSystemName { get; set; } // todo:id换名称
|
||||
/// <summary>
|
||||
/// 子系统名称
|
||||
/// </summary>
|
||||
public string SubSystemName { get; set; } // todo:id换名称
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public int OrderType { get; set; }
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public int OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型名称
|
||||
/// </summary>
|
||||
public string OrderTypeName { get; set; } // todo:type换名称
|
||||
/// <summary>
|
||||
/// 订单类型名称
|
||||
/// </summary>
|
||||
public string OrderTypeName { get; set; } // todo:type换名称
|
||||
|
||||
/// <summary>
|
||||
/// 订单id
|
||||
/// </summary>
|
||||
public int OrderId { get; set; }
|
||||
/// <summary>
|
||||
/// 订单id
|
||||
/// </summary>
|
||||
public int OrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string OrderNo { get; set; }
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string OrderNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态 (待处理样式标红)
|
||||
/// 1:待处理,2:已处理,3:已关闭
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
/// <summary>
|
||||
/// 状态 (待处理样式标红)
|
||||
/// 1:待处理,2:已处理,3:已关闭
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int CustomId { get; set; }
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int CustomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户简称
|
||||
/// </summary>
|
||||
public int CustomName { get; set; } // todo:id换名称
|
||||
/// <summary>
|
||||
/// 客户简称
|
||||
/// </summary>
|
||||
public string CustomName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 缺失轨迹状态
|
||||
/// </summary>
|
||||
public string MissingTrackStatus { get; set; } // todo:id换名称
|
||||
/// <summary>
|
||||
/// 缺失轨迹状态
|
||||
/// </summary>
|
||||
public string MissingTrackStatus { get; set; } // todo:id换名称
|
||||
|
||||
|
||||
//视图属性 todo:可以从订单主表拿到
|
||||
//视图属性 tips:从es即时拿取
|
||||
|
||||
/// <summary>
|
||||
/// 最新轨迹状态
|
||||
/// </summary>
|
||||
public string LatestTrackStatus { get; set; }
|
||||
/// <summary>
|
||||
/// 最新轨迹状态
|
||||
/// </summary>
|
||||
public string? LatestTrackStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新轨迹内容
|
||||
/// </summary>
|
||||
public string LatestTrackContent { get; set; }
|
||||
/// <summary>
|
||||
/// 最新轨迹内容
|
||||
/// </summary>
|
||||
public string? LatestTrackContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新轨迹发生地
|
||||
/// </summary>
|
||||
public string LatestTrackPlace { get; set; }
|
||||
/// <summary>
|
||||
/// 最新轨迹发生地
|
||||
/// </summary>
|
||||
public string? LatestTrackPlace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新轨迹发生时间
|
||||
/// </summary>
|
||||
public DateTime LatestTrackTime { get; set; }
|
||||
/// <summary>
|
||||
/// 最新轨迹发生时间
|
||||
/// </summary>
|
||||
public DateTime? LatestTrackTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新轨迹发生时区
|
||||
/// </summary>
|
||||
public float LatestTrackTimeZone { get; set; }
|
||||
/// <summary>
|
||||
/// 最新轨迹发生时区
|
||||
/// </summary>
|
||||
public float? LatestTrackTimeZone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象
|
||||
/// </summary>
|
||||
public string NotifyUserNames { get; set; }
|
||||
/// <summary>
|
||||
/// 通知对象
|
||||
/// </summary>
|
||||
public string NotifyUserNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
/// <summary>
|
||||
/// 预警创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警处理时间
|
||||
/// </summary>
|
||||
public DateTime? ProcessedTime { get; set; }
|
||||
/// <summary>
|
||||
/// 预警处理时间
|
||||
/// </summary>
|
||||
public DateTime? ProcessedTime { get; set; }
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Return;
|
||||
|
||||
namespace SJZY.Track.Application.Contract.Dtos.Warning.Complete;
|
||||
@ -21,7 +20,7 @@ public class CompleteWarningRuleItemDto
|
||||
/// <summary>
|
||||
/// 订单类型 e.g FBA订单、海运单
|
||||
/// </summary>
|
||||
public List<OrderTypeDto> OrderType { get; set; }
|
||||
public List<OrderTypeDto> OrderTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 检查点轨迹状态id
|
||||
|
||||
@ -8,16 +8,16 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.Complete;
|
||||
/// </summary>
|
||||
public class EditCompleteWarningRuleItemInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警规主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
/// <summary>
|
||||
/// 预警规主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则配置项目(列表内容传递)
|
||||
/// </summary>
|
||||
public List<EditCompleteWarningRuleItemDto> Items { get; set; } = new();
|
||||
/// <summary>
|
||||
/// 预警规则配置项目(列表内容传递)
|
||||
/// </summary>
|
||||
public List<EditCompleteWarningRuleItemDto> Items { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -25,35 +25,35 @@ public class EditCompleteWarningRuleItemInput
|
||||
/// </summary>
|
||||
public class EditCompleteWarningRuleItemDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 规则项目唯一id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
/// <summary>
|
||||
/// 规则项目唯一id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型集合(,分割) e.g. 1,2,3
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string OrderTypes { get; set; }
|
||||
/// <summary>
|
||||
/// 订单类型集合(,分割) e.g. 1,2,3
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string OrderTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 检查点轨迹状态id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int CheckPointTrackStatusId { get; set; }
|
||||
/// <summary>
|
||||
/// 检查点轨迹状态id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int CheckPointTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 要求的轨迹状态id集合 e.g. [[1,3],[5,7]]
|
||||
/// required: 集合元素(子集合)不要有交集!
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MinLength(1, ErrorMessage = "要求的轨迹状态id集合不能为空")]
|
||||
public List<List<int>> RequireTrackStatus { get; set; }
|
||||
/// <summary>
|
||||
/// 要求的轨迹状态id集合 e.g. [[1,3],[5,7]]
|
||||
/// required: 集合元素(子集合)不要有交集!
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MinLength(1, ErrorMessage = "要求的轨迹状态id集合不能为空")]
|
||||
public List<List<int>> RequireTrackStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象用户集合
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MinLength(1, ErrorMessage = "通知对象用户集合不能为空")]
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; } = new();
|
||||
/// <summary>
|
||||
/// 通知对象用户集合
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MinLength(1, ErrorMessage = "通知对象用户集合不能为空")]
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; } = new();
|
||||
}
|
||||
|
||||
@ -8,9 +8,9 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.DataAnnotations;
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
|
||||
public sealed class IdRequiredAttribute : RangeAttribute
|
||||
{
|
||||
public IdRequiredAttribute()
|
||||
: base(1, int.MaxValue)
|
||||
{
|
||||
ErrorMessage = "{0} is required and must be greater than 0";
|
||||
}
|
||||
public IdRequiredAttribute()
|
||||
: base(1, int.MaxValue)
|
||||
{
|
||||
ErrorMessage = "{0} is required and must be greater than 0";
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,15 +5,15 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
|
||||
public sealed class NotifyUserDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int UserId { get; set; }
|
||||
/// <summary>
|
||||
/// 用户id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string UserName { get; set; }
|
||||
/// <summary>
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string UserName { get; set; }
|
||||
}
|
||||
|
||||
@ -8,16 +8,16 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.Return;
|
||||
/// </summary>
|
||||
public class EditReturnWarningRuleItemInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警规主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
/// <summary>
|
||||
/// 预警规主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则配置项目(列表内容传递)
|
||||
/// </summary>
|
||||
public List<EditReturnWarningRuleItemDto> Items { get; set; } = new();
|
||||
/// <summary>
|
||||
/// 预警规则配置项目(列表内容传递)
|
||||
/// </summary>
|
||||
public List<EditReturnWarningRuleItemDto> Items { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -25,26 +25,26 @@ public class EditReturnWarningRuleItemInput
|
||||
/// </summary>
|
||||
public class EditReturnWarningRuleItemDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
/// <summary>
|
||||
/// 唯一id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹状态Id集合(,分割)
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string TrackStatusIds { get; set; }
|
||||
/// <summary>
|
||||
/// 轨迹状态Id集合(,分割)
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string TrackStatusIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时效(单位h)
|
||||
/// </summary>
|
||||
[Range(0.1, float.MaxValue, ErrorMessage = "时效必须大于0.1")]
|
||||
public float ReturnTimeSpan { get; set; }
|
||||
/// <summary>
|
||||
/// 时效(单位h)
|
||||
/// </summary>
|
||||
[Range(0.1, float.MaxValue, ErrorMessage = "时效必须大于0.1")]
|
||||
public float ReturnTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象用户集合
|
||||
/// </summary>
|
||||
[MinLength(1, ErrorMessage = "通知对象用户集合不能为空")]
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; } = new();
|
||||
/// <summary>
|
||||
/// 通知对象用户集合
|
||||
/// </summary>
|
||||
[MinLength(1, ErrorMessage = "通知对象用户集合不能为空")]
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; } = new();
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.Return;
|
||||
|
||||
/// <summary>
|
||||
/// 回传预警明细
|
||||
/// todo:需要根据状态排序
|
||||
/// </summary>
|
||||
public sealed class ReturnWarningDetailsDto
|
||||
{
|
||||
@ -17,7 +16,7 @@ public sealed class ReturnWarningDetailsDto
|
||||
public int SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统名称
|
||||
/// 子系统名称
|
||||
/// </summary>
|
||||
public string SubSystemName { get; set; } // todo:id换名称
|
||||
|
||||
@ -27,7 +26,7 @@ public sealed class ReturnWarningDetailsDto
|
||||
public int OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型名称
|
||||
/// 订单类型名称
|
||||
/// </summary>
|
||||
public string OrderTypeName { get; set; } // todo:type换名称
|
||||
|
||||
@ -52,17 +51,17 @@ public sealed class ReturnWarningDetailsDto
|
||||
public int CustomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户简称
|
||||
/// 客户简称
|
||||
/// </summary>
|
||||
public string CustomName { get; set; } // todo:id换名称
|
||||
public string CustomName { get; set; } // todo:id换名称
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹状态
|
||||
/// 轨迹状态
|
||||
/// </summary>
|
||||
public string TrackStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹代码
|
||||
/// 轨迹代码
|
||||
/// </summary>
|
||||
public string TrackCode { get; set; }
|
||||
|
||||
@ -87,7 +86,7 @@ public sealed class ReturnWarningDetailsDto
|
||||
public string PushTrackContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹发生地
|
||||
/// 轨迹发生地
|
||||
/// </summary>
|
||||
public string TrackPlace { get; set; }
|
||||
|
||||
@ -112,7 +111,7 @@ public sealed class ReturnWarningDetailsDto
|
||||
public DateTime? TrackReturnTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 回传时效
|
||||
/// 回传时效 (单位h)
|
||||
/// </summary>
|
||||
public float? ReturnTimeSpan { get; set; }
|
||||
|
||||
|
||||
@ -5,22 +5,22 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
|
||||
public class EditTransportWarningSceneRuleItemInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警规主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
/// <summary>
|
||||
/// 预警规主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 运输预警场景id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int SceneId { get; set; }
|
||||
/// <summary>
|
||||
/// 运输预警场景id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int SceneId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则配置项目(列表内容传递)
|
||||
/// </summary>
|
||||
public List<EditTransportWarningSceneRuleItemDto> Items { get; set; } = new();
|
||||
/// <summary>
|
||||
/// 预警规则配置项目(列表内容传递)
|
||||
/// </summary>
|
||||
public List<EditTransportWarningSceneRuleItemDto> Items { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -28,38 +28,38 @@ public class EditTransportWarningSceneRuleItemInput
|
||||
/// </summary>
|
||||
public class EditTransportWarningSceneRuleItemDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 规则项目id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
/// <summary>
|
||||
/// 规则项目id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹状态Id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int StartTrackStatusId { get; set; }
|
||||
/// <summary>
|
||||
/// 起始轨迹状态Id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int StartTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 截止轨迹状态Id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int EndTrackStatusId { get; set; }
|
||||
/// <summary>
|
||||
/// 截止轨迹状态Id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int EndTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时效 (单位h)
|
||||
/// </summary>
|
||||
[Range(0.1, float.MaxValue, ErrorMessage = "时效必须大于0.1")]
|
||||
public float TransportTimeSpan { get; set; }
|
||||
/// <summary>
|
||||
/// 时效 (单位h)
|
||||
/// </summary>
|
||||
[Range(0.1, float.MaxValue, ErrorMessage = "时效必须大于0.1")]
|
||||
public float TransportTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹生成预警时间 (单位h)
|
||||
/// </summary>
|
||||
[Range(0.1, float.MaxValue, ErrorMessage = "起始轨迹生成预警时间必须大于0.1")]
|
||||
public float StartTrackWarningTimeSpan { get; set; }
|
||||
/// <summary>
|
||||
/// 起始轨迹生成预警时间 (单位h)
|
||||
/// </summary>
|
||||
[Range(0.1, float.MaxValue, ErrorMessage = "起始轨迹生成预警时间必须大于0.1")]
|
||||
public float StartTrackWarningTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象用户集合
|
||||
/// </summary>
|
||||
[MinLength(1, ErrorMessage = "通知对象用户集合不能为空")]
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; } = new();
|
||||
/// <summary>
|
||||
/// 通知对象用户集合
|
||||
/// </summary>
|
||||
[MinLength(1, ErrorMessage = "通知对象用户集合不能为空")]
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; } = new();
|
||||
}
|
||||
|
||||
@ -7,9 +7,9 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
/// </summary>
|
||||
public class GetTransportWarningSceneInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
/// <summary>
|
||||
/// 预警主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
}
|
||||
|
||||
@ -7,15 +7,15 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
/// </summary>
|
||||
public class GetTransportWarningSceneRuleItemInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
/// <summary>
|
||||
/// 预警主体id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 运输预警场景id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int SceneId { get; set; }
|
||||
/// <summary>
|
||||
/// 运输预警场景id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int SceneId { get; set; }
|
||||
}
|
||||
|
||||
@ -5,145 +5,145 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
/// </summary>
|
||||
public sealed class TransportWarningDetailsDto // todo:需要根据状态排序
|
||||
{
|
||||
/// <summary>
|
||||
/// 预警明细唯一id
|
||||
/// </summary>
|
||||
public string EsId { get; set; }
|
||||
/// <summary>
|
||||
/// 预警明细唯一id
|
||||
/// </summary>
|
||||
public string EsId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int SubSystemId { get; set; }
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统名称
|
||||
/// </summary>
|
||||
public string SubSystemName { get; set; } // todo:id换名称
|
||||
/// <summary>
|
||||
/// 子系统名称
|
||||
/// </summary>
|
||||
public string SubSystemName { get; set; } // todo:id换名称
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int CustomId { get; set; }
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int CustomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户简称
|
||||
/// </summary>
|
||||
public string CustomName { get; set; } // todo:id换名称
|
||||
/// <summary>
|
||||
/// 客户简称
|
||||
/// </summary>
|
||||
public string CustomName { get; set; } // todo:id换名称
|
||||
|
||||
/// <summary>
|
||||
/// 订单id
|
||||
/// </summary>
|
||||
public int OrderId { get; set; }
|
||||
/// <summary>
|
||||
/// 订单id
|
||||
/// </summary>
|
||||
public int OrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string OrderNo { get; set; }
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string OrderNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public int OrderType { get; set; }
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public int OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型名称
|
||||
/// </summary>
|
||||
public string OrderTypeName { get; set; } // todo:type换名称
|
||||
/// <summary>
|
||||
/// 订单类型名称
|
||||
/// </summary>
|
||||
public string OrderTypeName { get; set; } // todo:type换名称
|
||||
|
||||
|
||||
// 实时属性 todo:从订单查询
|
||||
// 实时属性 todo:从es查询
|
||||
|
||||
/// <summary>
|
||||
/// 最新轨迹内容
|
||||
/// </summary>
|
||||
public string LatestTrackContent { get; set; }
|
||||
/// <summary>
|
||||
/// 最新轨迹内容
|
||||
/// </summary>
|
||||
public string? LatestTrackContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新轨迹时间
|
||||
/// </summary>
|
||||
public DateTime LatestTrackTime { get; set; }
|
||||
/// <summary>
|
||||
/// 最新轨迹时间
|
||||
/// </summary>
|
||||
public DateTime? LatestTrackTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新轨迹发生时区
|
||||
/// </summary>
|
||||
public float LatestTrackTimeZone { get; set; }
|
||||
/// <summary>
|
||||
/// 最新轨迹发生时区
|
||||
/// </summary>
|
||||
public float? LatestTrackTimeZone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新轨迹发生地
|
||||
/// </summary>
|
||||
public string LatestTrackPlace { get; set; }
|
||||
/// <summary>
|
||||
/// 最新轨迹发生地
|
||||
/// </summary>
|
||||
public string? LatestTrackPlace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象
|
||||
/// </summary>
|
||||
public string NotifyUserNames { get; set; }
|
||||
/// <summary>
|
||||
/// 通知对象
|
||||
/// </summary>
|
||||
public string NotifyUserNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹状态
|
||||
/// </summary>
|
||||
public string StartTrackStatus { get; set; }
|
||||
/// <summary>
|
||||
/// 起始轨迹状态
|
||||
/// </summary>
|
||||
public string StartTrackStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹内容
|
||||
/// </summary>
|
||||
public string StartTrackContent { get; set; }
|
||||
/// <summary>
|
||||
/// 起始轨迹内容
|
||||
/// </summary>
|
||||
public string StartTrackContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹发生时间
|
||||
/// </summary>
|
||||
public DateTime StartTrackTime { get; set; }
|
||||
/// <summary>
|
||||
/// 起始轨迹发生时间
|
||||
/// </summary>
|
||||
public DateTime StartTrackTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹时区
|
||||
/// </summary>
|
||||
public float StartTrackTimeZone { get; set; }
|
||||
/// <summary>
|
||||
/// 起始轨迹时区
|
||||
/// </summary>
|
||||
public float StartTrackTimeZone { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 截止轨迹状态
|
||||
/// </summary>
|
||||
public string EndTrackStatus { get; set; }
|
||||
/// <summary>
|
||||
/// 截止轨迹状态
|
||||
/// </summary>
|
||||
public string EndTrackStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 截止轨迹内容
|
||||
/// </summary>
|
||||
public string? EndTrackContent { get; set; }
|
||||
/// <summary>
|
||||
/// 截止轨迹内容
|
||||
/// </summary>
|
||||
public string? EndTrackContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 截止轨迹发生时间
|
||||
/// </summary>
|
||||
public DateTime? EndTrackTime { get; set; }
|
||||
/// <summary>
|
||||
/// 截止轨迹发生时间
|
||||
/// </summary>
|
||||
public DateTime? EndTrackTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 截止轨迹时区
|
||||
/// </summary>
|
||||
public float? EndTrackTimeZone { get; set; }
|
||||
/// <summary>
|
||||
/// 截止轨迹时区
|
||||
/// </summary>
|
||||
public float? EndTrackTimeZone { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 预警名称 (预警主体名称 如字节全程时效)
|
||||
/// </summary>
|
||||
public string WarningName { get; set; }
|
||||
/// <summary>
|
||||
/// 预警名称 (预警主体名称 如字节全程时效)
|
||||
/// </summary>
|
||||
public string WarningName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则描述(用于tooltip展示)
|
||||
/// </summary>
|
||||
public string WarningRuleDescription { get; set; }
|
||||
/// <summary>
|
||||
/// 预警规则描述(用于tooltip展示)
|
||||
/// </summary>
|
||||
public string WarningRuleDescription { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 累计运输时间
|
||||
/// </summary>
|
||||
public string CumulativeTimeSpan { get; set; } // todo:需要转换为某个格式
|
||||
/// <summary>
|
||||
/// 累计运输时间
|
||||
/// </summary>
|
||||
public string CumulativeTimeSpan { get; set; } // todo:需要转换为某个格式
|
||||
|
||||
/// <summary>
|
||||
/// 预警状态 (根据key展示对应名称,即将超时需要标红)
|
||||
/// 1:即将超时 2:已超时 3:已完成 4:超时完成 5:已关闭,初始为【即将超时】
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
/// <summary>
|
||||
/// 预警状态 (根据key展示对应名称,即将超时需要标红)
|
||||
/// 1:即将超时 2:已超时 3:已完成 4:超时完成 5:已关闭,初始为【即将超时】
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
/// <summary>
|
||||
/// 预警创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ public class TransportWarningSceneDto
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 场景摘要(用于展示场景tabs)
|
||||
/// 场景摘要(用于展示场景tabs)
|
||||
/// </summary>
|
||||
public string Summary { get; set; } // todo:将规则场景一些列因素转换为一段描述
|
||||
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
|
||||
namespace SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
|
||||
/// <summary>
|
||||
@ -46,4 +44,4 @@ public class TransportWarningSceneRuleItemDto
|
||||
/// 通知对象用户集合
|
||||
/// </summary>
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.DataAnnotations;
|
||||
|
||||
namespace SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
|
||||
public class UpsertTransportWarningSceneInput
|
||||
public sealed class UpsertTransportWarningSceneInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 场景唯一id (传0视为新增)
|
||||
|
||||
@ -8,38 +8,38 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
/// </summary>
|
||||
public class UpsertWarningRuleInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
/// <summary>
|
||||
/// 唯一id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int SubSystemId { get; set; } //子系统id
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int SubSystemId { get; set; } //子系统id
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int CustomId { get; set; } //客户id
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
[IdRequired]
|
||||
public int CustomId { get; set; } //客户id
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则名称
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 预警规则名称
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool IsEnabled { get; set; }
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警类型,1:运输时效,2:回传时效,3:完整预警
|
||||
/// </summary>
|
||||
[Range(1, 3, ErrorMessage = "预警类型只能选取以下值,1:运输时效,2:回传时效,3:完整预警")]
|
||||
public int WarningType { get; set; }
|
||||
/// <summary>
|
||||
/// 预警类型,1:运输时效,2:回传时效,3:完整预警
|
||||
/// </summary>
|
||||
[Range(1, 3, ErrorMessage = "预警类型只能选取以下值,1:运输时效,2:回传时效,3:完整预警")]
|
||||
public int WarningType { get; set; }
|
||||
}
|
||||
|
||||
@ -13,22 +13,22 @@ public sealed class WarningRuleDto
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int SubSystemId { get; set; } //子系统id
|
||||
public int SubSystemId { get; set; } //子系统id
|
||||
|
||||
/// <summary>
|
||||
/// 子系统名称
|
||||
/// 子系统名称
|
||||
/// </summary>
|
||||
public int SubSystemName { get; set; } // todo:id换name
|
||||
public string SubSystemName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int CustomId { get; set; } //客户id
|
||||
public int CustomId { get; set; } //客户id
|
||||
|
||||
/// <summary>
|
||||
/// 客户简称
|
||||
/// 客户简称
|
||||
/// </summary>
|
||||
public int CustomName { get; set; } // todo:id换name
|
||||
public string CustomName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则名称
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
using AutoMapper;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Complete;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Return;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
using SJZY.Track.Domain.Dtos.Warning;
|
||||
|
||||
namespace SJZY.Track.Application.AutoMapper;
|
||||
|
||||
public class WarningMapperProfile : Profile
|
||||
{
|
||||
public WarningMapperProfile()
|
||||
{
|
||||
CreateMap<GetPageCompleteWarningDetailsInput, GetPageCompleteWarningDetailsInputVO>(MemberList.None);
|
||||
CreateMap<GetPageReturnWarningDetailsInput, GetPageReturnWarningDetailsInputVO>(MemberList.None);
|
||||
CreateMap<GetPageTransportWarningDetailsInput, GetPageTransportWarningDetailsInputVO>(MemberList.None);
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ using SJZY.Track.Application.Helpers;
|
||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
using SJZY.Track.Domain.Queries;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Http.Client.DynamicProxying;
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Dtos.TrackContents;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
using SJZY.Track.Domain.Queries;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using OrderIdentifier = SJZY.Track.Application.Contract.Events.OrderIdentifier;
|
||||
|
||||
@ -10,6 +10,7 @@ using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
|
||||
using SJZY.Track.Domain.Dtos.TrackPush;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
using SJZY.Track.Domain.Queries;
|
||||
using SJZY.UserCenter.HttpApi.Services.User;
|
||||
using Volo.Abp.Http.Client.DynamicProxying;
|
||||
|
||||
@ -9,6 +9,7 @@ using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
using SJZY.Track.Domain.Queries;
|
||||
using SJZY.UserCenter.HttpApi.Services;
|
||||
using SJZY.UserCenter.HttpApi.Services.User;
|
||||
|
||||
@ -67,7 +67,7 @@ public class TrackOrderService : ApplicationService
|
||||
[HttpGet("GetOrderTypeDict")]
|
||||
public async Task<Dictionary<string, string>> GetOrderTypeDict()
|
||||
{
|
||||
return await _orderRepository.GetTrackOrderTypeDict();
|
||||
return await _orderRepository.GetTrackOrderTypeDictAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -57,7 +57,7 @@ public class TrackPushService : ApplicationService, ISingletonDependency
|
||||
{
|
||||
var orderTypes = await _trackPushConfigRepository.GetConfigTags(inputVo);
|
||||
if (orderTypes.Count == 0) return new List<TrackPushConfigTagDto>();
|
||||
var trackOrderTypes = await _orderRepository.GetTrackOrderTypeDict();
|
||||
var trackOrderTypes = await _orderRepository.GetTrackOrderTypeDictAsync();
|
||||
|
||||
return orderTypes.Select(x => new TrackPushConfigTagDto
|
||||
{
|
||||
|
||||
@ -1,4 +1,18 @@
|
||||
using SJZY.Expand.ABP.Core.PublicMethords;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Complete;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Return;
|
||||
using SJZY.Track.Application.Helpers;
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Warning;
|
||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Complete;
|
||||
using SJZY.Track.Domain.Dtos.Warning;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning;
|
||||
|
||||
@ -9,15 +23,21 @@ namespace SJZY.Track.Application.Services.Warning;
|
||||
[Route("Warning/Complete")]
|
||||
public class CompleteWarningService : ApplicationService
|
||||
{
|
||||
/// <summary>
|
||||
/// 编辑完整预警规则列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("EditCompleteWarningRuleItem")]
|
||||
public Task<UnifyResultDto> EditCompleteWarningRuleItem(EditCompleteWarningRuleItemInput input)
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
private readonly IWarningRuleRepository _warningRuleRepository;
|
||||
private readonly IWarningDetailsEsRepository _warningDetailsEsRepository;
|
||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
||||
private readonly ICompleteWarningHandler _completeWarningHandler;
|
||||
private readonly ITrackStatusRepository _trackStatusRepository;
|
||||
|
||||
public CompleteWarningService(IWarningRuleRepository warningRuleRepository, IWarningDetailsEsRepository warningDetailsEsRepository, ITrackDetailsEsRepository trackDetailsEsRepository, ICompleteWarningHandler completeWarningHandler, ITrackStatusRepository trackStatusRepository, IOrderRepository orderRepository)
|
||||
{
|
||||
return Task.FromResult(new UnifyResultDto());
|
||||
_warningRuleRepository = warningRuleRepository;
|
||||
_warningDetailsEsRepository = warningDetailsEsRepository;
|
||||
_trackDetailsEsRepository = trackDetailsEsRepository;
|
||||
_completeWarningHandler = completeWarningHandler;
|
||||
_trackStatusRepository = trackStatusRepository;
|
||||
_orderRepository = orderRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -26,10 +46,70 @@ public class CompleteWarningService : ApplicationService
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetCompleteWarningRuleItem")]
|
||||
public Task<UnifyResultDto<List<CompleteWarningRuleItemDto>>>
|
||||
GetCompleteWarningRuleItem(GetCompleteWarningRuleItemInput input)
|
||||
public async Task<UnifyResultDto<List<CompleteWarningRuleItemDto>>> GetCompleteWarningRuleItem(GetCompleteWarningRuleItemInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyResultDto<List<CompleteWarningRuleItemDto>>());
|
||||
var result = await _warningRuleRepository.GetCompleteRuleItemsAsync(input.WarningId);
|
||||
if (result.Count == 0)
|
||||
return new UnifyResultDto<List<CompleteWarningRuleItemDto>>(true, new List<CompleteWarningRuleItemDto>());
|
||||
|
||||
// todo:缓存优化
|
||||
var trackStatusIds = result
|
||||
.SelectMany(x =>
|
||||
{
|
||||
// todo:逻辑优化
|
||||
var checkStatusId = x.CheckPointTrackStatusId;
|
||||
var requireStatusIds = x.GetRequireTrackStatusIdGroups();
|
||||
requireStatusIds.Add(new HashSet<int>(1)
|
||||
{
|
||||
checkStatusId
|
||||
});
|
||||
return requireStatusIds.SelectMany(y => y);
|
||||
}).ToHashSet();
|
||||
|
||||
var trackStatusDict = (await _trackStatusRepository.GetListAsync(x => trackStatusIds.Contains(x.Id), x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Status
|
||||
})).ToDictionary(x => x.Id, y => y.Status);
|
||||
|
||||
// 查订单类型映射
|
||||
var orderTypeDict = await _orderRepository.GetTrackOrderTypeDictAsync();
|
||||
|
||||
var map = result.Select(x => new CompleteWarningRuleItemDto
|
||||
{
|
||||
Id = x.Id,
|
||||
WarningId = x.WarningId,
|
||||
OrderTypes = BuildOrderTypes(x),
|
||||
CheckPointTrackStatusId = x.CheckPointTrackStatusId,
|
||||
CheckPointTrackStatus = trackStatusDict.GetValueOrDefault(x.CheckPointTrackStatusId),
|
||||
RequireTrackStatus = BuildRequireTrackStatus(x),
|
||||
NotifyUsers = TextJsonHelper.Deserialize<List<NotifyUserDto>>(x.NotifyUsers)!
|
||||
});
|
||||
|
||||
return new UnifyResultDto<List<CompleteWarningRuleItemDto>>(true, map.ToList());
|
||||
|
||||
List<RequireTrackStatusItem> BuildRequireTrackStatus(CompleteWarningRuleItemEntity entity)
|
||||
{
|
||||
return entity.GetRequireTrackStatusIdGroups()
|
||||
.Select(g => new RequireTrackStatusItem
|
||||
{
|
||||
Statuses = g.Select(id => new TrackStatusDto
|
||||
{
|
||||
TrackStatusId = id,
|
||||
TrackStatus = trackStatusDict.GetValueOrDefault(id)
|
||||
}).ToList()
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
List<OrderTypeDto> BuildOrderTypes(CompleteWarningRuleItemEntity entity)
|
||||
{
|
||||
return entity.GetRuleOrderTypes()
|
||||
.Select(x => new OrderTypeDto
|
||||
{
|
||||
OrderType = x,
|
||||
OrderTypeName = orderTypeDict.GetValueOrDefault(x.ToString())
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -38,9 +118,114 @@ public class CompleteWarningService : ApplicationService
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetPageCompleteWarningDetails")]
|
||||
public Task<UnifyPageResultDto<CompleteWarningDetailsDto>>
|
||||
GetPageCompleteWarningDetails(GetPageCompleteWarningDetailsInput input)
|
||||
public async Task<UnifyPageResultDto<CompleteWarningDetailsDto>> GetPageCompleteWarningDetails(GetPageCompleteWarningDetailsInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyPageResultDto<CompleteWarningDetailsDto>());
|
||||
var vo = ObjectMapper.Map<GetPageCompleteWarningDetailsInput, GetPageCompleteWarningDetailsInputVO>(input);
|
||||
var result = await _warningDetailsEsRepository.GetPageCompleteWarningDetailsAsync(vo);
|
||||
|
||||
if (result.List.Count == 0)
|
||||
return new UnifyPageResultDto<CompleteWarningDetailsDto>(new List<CompleteWarningDetailsDto>(), input.PageIndex, input.PageSize, 0);
|
||||
|
||||
// todo:缓存优化
|
||||
var trackStatusIds = result.List
|
||||
.SelectMany(x => x.MissingTrackStatusIds.Split(',').Select(int.Parse))
|
||||
.ToHashSet();
|
||||
var trackStatusDict = (await _trackStatusRepository.GetListAsync(x => trackStatusIds.Contains(x.Id), x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Status
|
||||
})).ToDictionary(x => x.Id, y => y.Status);
|
||||
|
||||
// 查最新轨迹
|
||||
var orderIds = result.List.Select(x => x.OrderId).ToHashSet();
|
||||
var orderTracks = await _trackDetailsEsRepository.GetLatestListAsync(orderIds);
|
||||
var orderIdTrackDict = orderTracks.ToDictionary(x => x.OrderId);
|
||||
|
||||
// :填充子系统名称(冗余?)
|
||||
// :填充客户简称(冗余?)
|
||||
// :填充订单类型名称(冗余?)
|
||||
var map = result.List.Select(x =>
|
||||
{
|
||||
var orderIdTrack = orderIdTrackDict.GetValueOrDefault(x.OrderId);
|
||||
return new CompleteWarningDetailsDto
|
||||
{
|
||||
EsId = x.Id,
|
||||
SubSystemId = x.SubSystemId,
|
||||
SubSystemName = x.SubSystemName,
|
||||
OrderType = x.OrderType,
|
||||
OrderTypeName = x.OrderTypeName,
|
||||
OrderId = x.OrderId,
|
||||
OrderNo = x.OrderNo,
|
||||
Status = x.Status,
|
||||
CustomId = x.CustomId,
|
||||
CustomName = x.CustomName,
|
||||
MissingTrackStatus = BuildMissingTrackStatus(x.MissingTrackStatusIds),
|
||||
LatestTrackStatus = orderIdTrack?.TrackStatus,
|
||||
LatestTrackContent = orderIdTrack?.TrackContent,
|
||||
LatestTrackPlace = orderIdTrack?.TrackPlace,
|
||||
LatestTrackTime = orderIdTrack?.TrackTime,
|
||||
LatestTrackTimeZone = orderIdTrack?.TrackTimeZone,
|
||||
|
||||
NotifyUserNames = ToUserNames(x.NotifyUsers),
|
||||
CreateTime = x.CreateTime,
|
||||
ProcessedTime = x.ProcessedTime
|
||||
};
|
||||
});
|
||||
|
||||
var sorted = map.OrderBy(x =>
|
||||
{
|
||||
// 待处理置顶
|
||||
if (x.Status == 1) return x.Status;
|
||||
// 其他按创建时间从早到晚
|
||||
return DateTimeHelper.ConvertToUnixTimestamp(x.CreateTime);
|
||||
});
|
||||
|
||||
return new UnifyPageResultDto<CompleteWarningDetailsDto>(
|
||||
sorted.ToList(),
|
||||
result.Pagination.PageIndex,
|
||||
result.Pagination.PageSize,
|
||||
result.Pagination.Total);
|
||||
|
||||
// 通知用户提取用户名称
|
||||
string ToUserNames(string notifyUsers)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(notifyUsers))
|
||||
return string.Empty;
|
||||
return string.Join(',', notifyUsers.ToObject<List<NotifyUserDto>>().Select(x => x.UserName));
|
||||
}
|
||||
|
||||
string BuildMissingTrackStatus(string statusIds)
|
||||
{
|
||||
var trackStatus = statusIds.Split(',').Select(x =>
|
||||
{
|
||||
if (int.TryParse(x, out var id))
|
||||
return trackStatusDict.GetValueOrDefault(id)
|
||||
?? $"丢失{id}轨迹状态";
|
||||
|
||||
return null;
|
||||
}).Where(x => x != null);
|
||||
|
||||
return string.Join(',', trackStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 编辑完整预警规则列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("EditCompleteWarningRuleItem")]
|
||||
public async Task<UnifyResultDto> EditCompleteWarningRuleItem(EditCompleteWarningRuleItemInput input)
|
||||
{
|
||||
var rule = await _warningRuleRepository.GetWarningRuleByIdAsync(input.WarningId, WarningRuleType.完整预警);
|
||||
if (rule == null)
|
||||
{
|
||||
throw new BusinessException(message: $"预警规则主体不存在,WarningId=[{input.WarningId}]");
|
||||
}
|
||||
|
||||
var bos = CompleteWarningRuleItemBO.From(input);
|
||||
await _completeWarningHandler.HandleEditAsync(rule, bos);
|
||||
return new UnifyResultDto(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,170 @@
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Warning;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers;
|
||||
|
||||
public sealed class CompleteWarningHandler : ICompleteWarningHandler
|
||||
{
|
||||
private readonly IWarningRuleRepository _warningRuleRepository;
|
||||
|
||||
public CompleteWarningHandler(IWarningRuleRepository warningRuleRepository)
|
||||
{
|
||||
_warningRuleRepository = warningRuleRepository;
|
||||
}
|
||||
|
||||
public Task TrackDeletedHandleAsync(List<TrackDeletedSignal> deletedSignals)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task TrackAddedHandleAsync(List<TrackAddedSignal> addedSignals)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task WarningRuleToDisabledHandleAsync(WarningRuleEntity warningRule)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#region todo: 规则项目变更
|
||||
|
||||
public async Task HandleEditAsync(WarningRuleEntity rule, List<CompleteWarningRuleItemBO> postRuleItems)
|
||||
{
|
||||
var addRuleItems = postRuleItems.Where(x => x.Id == 0).ToList();
|
||||
// 1.找到之前的配置项目
|
||||
var entities = await _warningRuleRepository.GetCompleteRuleItemsAsync(rule.Id);
|
||||
var oldRuleItems = CompleteWarningRuleItemBO.From(entities);
|
||||
// 1.1之前的配置数量为0,做只新增处理
|
||||
if (oldRuleItems.Count == 0)
|
||||
{
|
||||
if (addRuleItems.Count != 0)
|
||||
await OnlyAddHandleAsync(rule, addRuleItems);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 1.2之前的配置数量不为0,提交的数量为0,做只删除处理
|
||||
if (oldRuleItems.Count != 0 && postRuleItems.Count == 0)
|
||||
{
|
||||
await OnlyDeleteHandleAsync(rule, oldRuleItems);
|
||||
return;
|
||||
}
|
||||
|
||||
// 关心规则修改/删除
|
||||
var updateRuleItems = new List<CompleteWarningRuleItemBO>();
|
||||
var deleteRuleItems = new List<CompleteWarningRuleItemBO>();
|
||||
|
||||
// 构建id配置项字典
|
||||
var oldDict = oldRuleItems.ToDictionary(x => x.Id);
|
||||
var updateAndAddRuleItems = postRuleItems.Where(x => x.Id == 0).ToList();
|
||||
var postDict = postRuleItems
|
||||
.Except(updateAndAddRuleItems) //tips:差异化比较时忽略新增的规则条目
|
||||
.ToDictionary(x => x.Id);
|
||||
|
||||
// 2.差异化比较
|
||||
var ruleItemIds = oldDict.Keys.Concat(postDict.Keys).ToHashSet();
|
||||
foreach (var ruleItemId in ruleItemIds)
|
||||
{
|
||||
var oldRule = oldDict.GetValueOrDefault(ruleItemId);
|
||||
var postRule = postDict.GetValueOrDefault(ruleItemId);
|
||||
if (oldRule != null && postRule != null)
|
||||
{
|
||||
//规则属性变更,(状态减少,时效变更)
|
||||
if (CanNeedFollow(oldRule, postRule))
|
||||
updateRuleItems.Add(postRule); //更新 关注新配置
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
//规则条目被删除
|
||||
if (oldRule != null && postRule == null)
|
||||
deleteRuleItems.Add(oldRule); //删除 关注旧配置
|
||||
}
|
||||
|
||||
// 3.处理变更
|
||||
await HandleRuleItemsChangeAsync(rule, addRuleItems, updateRuleItems, deleteRuleItems);
|
||||
}
|
||||
|
||||
private async Task OnlyDeleteHandleAsync(WarningRuleEntity rule, List<CompleteWarningRuleItemBO> bos)
|
||||
{
|
||||
var ruleItemIds = bos.Select(x => x.Id).ToHashSet();
|
||||
await _warningRuleRepository.DeleteCompleteRuleItemsAsync(ruleItemIds);
|
||||
|
||||
// 更新规则主体版本号
|
||||
await _warningRuleRepository.UpdateVersionAsync(rule);
|
||||
|
||||
// todo:暂时不处理后续逻辑
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
private async Task OnlyAddHandleAsync(WarningRuleEntity rule, List<CompleteWarningRuleItemBO> bos)
|
||||
{
|
||||
var entities = CompleteWarningRuleItemBO.ToEntities(bos);
|
||||
await _warningRuleRepository.BulkInsertCompleteRuleItemsAsync(entities);
|
||||
// 更新规则主体版本号
|
||||
await _warningRuleRepository.UpdateVersionAsync(rule);
|
||||
}
|
||||
|
||||
private async Task HandleRuleItemsChangeAsync(
|
||||
WarningRuleEntity rule,
|
||||
List<CompleteWarningRuleItemBO> addRuleItems,
|
||||
List<CompleteWarningRuleItemBO> updateRuleItems,
|
||||
List<CompleteWarningRuleItemBO> deleteRuleItems
|
||||
)
|
||||
{
|
||||
// 新增/修改/删除 实体,稍后做处理
|
||||
var addEntities = CompleteWarningRuleItemBO.ToEntities(addRuleItems);
|
||||
var updateEntities = CompleteWarningRuleItemBO.ToEntities(updateRuleItems);
|
||||
var deleteRuleItemIds = deleteRuleItems.Select(x => x.Id).ToHashSet();
|
||||
await _warningRuleRepository.BulkInsertCompleteRuleItemsAsync(addEntities);
|
||||
await _warningRuleRepository.BulkUpdateCompleteRuleItemsAsync(updateEntities);
|
||||
await _warningRuleRepository.DeleteCompleteRuleItemsAsync(deleteRuleItemIds);
|
||||
|
||||
// todo:暂时不启用后续规则
|
||||
return;
|
||||
}
|
||||
|
||||
private bool CanNeedFollow(CompleteWarningRuleItemBO oldRule, CompleteWarningRuleItemBO postRule)
|
||||
{
|
||||
// 关注的订单类型减少
|
||||
var oldTypes = oldRule.OrderTypes;
|
||||
var postTypes = postRule.OrderTypes;
|
||||
foreach (var type in oldTypes)
|
||||
{
|
||||
if (!postTypes.Contains(type))
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查点发生变化
|
||||
if (oldRule.CheckPointTrackStatusId != postRule.CheckPointTrackStatusId)
|
||||
return true;
|
||||
|
||||
// 要求的轨迹状态,
|
||||
// 条目内或关系状态变更,比如 案例1:S1/S2,S4 => S1/S3,案例2: S1/S2,S4 => S1,S4
|
||||
// 条目减少,S1/S2,S4 => S1/S2
|
||||
var oldStatusIds = oldRule.RequireTrackStatus.SelectMany(x => x).ToHashSet();
|
||||
var postStatusIds = postRule.RequireTrackStatus.SelectMany(x => x).ToHashSet();
|
||||
|
||||
if (oldStatusIds.Count > postStatusIds.Count) //数量减少,一定需要关注
|
||||
return true;
|
||||
|
||||
foreach (var statusId in oldStatusIds)
|
||||
{
|
||||
if (!postStatusIds.Contains(statusId)) //状态减少,需要关注
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public List<WarningNotifyTaskEntity> FilterAndHandleNeedNotifyTask(List<WarningNotifyTaskEntity> notifyTasks)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Complete;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Complete;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
|
||||
public sealed class CompleteWarningRuleItemBO
|
||||
{
|
||||
/// <summary>
|
||||
/// 规则项目唯一id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规主体id
|
||||
/// </summary>
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型集合(,分割) e.g. 1,2,3
|
||||
/// </summary>
|
||||
public HashSet<int> OrderTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 检查点轨迹状态id
|
||||
/// </summary>
|
||||
public int CheckPointTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 要求的轨迹状态id集合 e.g. [[1,3],[5,7]]
|
||||
/// required: 集合元素(子集合)不要有交集!
|
||||
/// </summary>
|
||||
public List<HashSet<int>> RequireTrackStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象用户集合
|
||||
/// </summary>
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; } = new();
|
||||
|
||||
public static List<CompleteWarningRuleItemBO> From(EditCompleteWarningRuleItemInput input)
|
||||
{
|
||||
return input.Items.Select(x => new CompleteWarningRuleItemBO
|
||||
{
|
||||
Id = x.Id,
|
||||
WarningId = input.WarningId,
|
||||
OrderTypes = x.OrderTypes.Split(",").Select(int.Parse).ToHashSet(),
|
||||
CheckPointTrackStatusId = x.CheckPointTrackStatusId,
|
||||
RequireTrackStatus = x.RequireTrackStatus.Select(y => y.ToHashSet()).ToList(),
|
||||
NotifyUsers = x.NotifyUsers
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public CompleteWarningRuleItemEntity ToEntity()
|
||||
{
|
||||
var requireTrackStatusIdExpression = string.Join(',', RequireTrackStatus.Select(sub => string.Join('/', sub)));
|
||||
|
||||
return new CompleteWarningRuleItemEntity(
|
||||
Id,
|
||||
WarningId,
|
||||
string.Join(",", OrderTypes),
|
||||
CheckPointTrackStatusId,
|
||||
requireTrackStatusIdExpression,
|
||||
TextJsonHelper.Serialize(NotifyUsers)!
|
||||
);
|
||||
}
|
||||
|
||||
public static List<CompleteWarningRuleItemEntity> ToEntities(List<CompleteWarningRuleItemBO> bos)
|
||||
{
|
||||
return bos.Select(x => x.ToEntity()).ToList();
|
||||
}
|
||||
|
||||
public static CompleteWarningRuleItemBO From(CompleteWarningRuleItemEntity entity)
|
||||
{
|
||||
return new CompleteWarningRuleItemBO
|
||||
{
|
||||
Id = entity.Id,
|
||||
WarningId = entity.WarningId,
|
||||
OrderTypes = entity.GetRuleOrderTypes(),
|
||||
CheckPointTrackStatusId = entity.CheckPointTrackStatusId,
|
||||
RequireTrackStatus = entity.GetRequireTrackStatusIdGroups(),
|
||||
NotifyUsers = TextJsonHelper.Deserialize<List<NotifyUserDto>>(entity.NotifyUsers)!
|
||||
};
|
||||
}
|
||||
|
||||
public static List<CompleteWarningRuleItemBO> From(List<CompleteWarningRuleItemEntity> entities)
|
||||
{
|
||||
return entities.Select(From).ToList();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Return;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
|
||||
public sealed class ReturnWarningRuleItemBO
|
||||
{
|
||||
/// <summary>
|
||||
/// 规则项目唯一id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则主体id
|
||||
/// </summary>
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹状态
|
||||
/// </summary>
|
||||
public HashSet<int> TrackStatusIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 回传预警时间
|
||||
/// </summary>
|
||||
public float ReturnTimeSpan { get; set; } //时效(单位小时),只是用于判断状态
|
||||
|
||||
/// <summary>
|
||||
/// 通知用户对象集合
|
||||
/// </summary>
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; }
|
||||
|
||||
|
||||
public static List<ReturnWarningRuleItemBO> From(EditReturnWarningRuleItemInput input)
|
||||
{
|
||||
var warningId = input.WarningId;
|
||||
return input.Items.Select(x => new ReturnWarningRuleItemBO
|
||||
{
|
||||
Id = x.Id,
|
||||
WarningId = warningId,
|
||||
TrackStatusIds = x.TrackStatusIds.Split(',').Select(int.Parse).ToHashSet(),
|
||||
ReturnTimeSpan = x.ReturnTimeSpan,
|
||||
NotifyUsers = x.NotifyUsers
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public static List<ReturnWarningRuleItemBO> From(List<ReturnWarningRuleItemEntity> entities)
|
||||
{
|
||||
return entities.Select(From).ToList();
|
||||
}
|
||||
|
||||
public static ReturnWarningRuleItemBO From(ReturnWarningRuleItemEntity entity)
|
||||
{
|
||||
return new ReturnWarningRuleItemBO
|
||||
{
|
||||
Id = entity.Id,
|
||||
WarningId = entity.WarningId,
|
||||
TrackStatusIds = entity.TrackStatusIds.Split(',').Select(int.Parse).ToHashSet(),
|
||||
ReturnTimeSpan = entity.ReturnTimeSpan,
|
||||
NotifyUsers = TextJsonHelper.Deserialize<List<NotifyUserDto>>(entity.NotifyUsers)!
|
||||
};
|
||||
}
|
||||
|
||||
public ReturnWarningRuleItemEntity ToEntity()
|
||||
{
|
||||
return new ReturnWarningRuleItemEntity(
|
||||
Id,
|
||||
WarningId,
|
||||
string.Join(',', TrackStatusIds),
|
||||
ReturnTimeSpan,
|
||||
TextJsonHelper.Serialize(NotifyUsers)!
|
||||
);
|
||||
}
|
||||
|
||||
public static List<ReturnWarningRuleItemEntity> ToEntities(List<ReturnWarningRuleItemBO> bos)
|
||||
{
|
||||
return bos.Select(x => x.ToEntity()).ToList();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,161 @@
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
|
||||
public sealed class TransportWarningSceneBO
|
||||
{
|
||||
/// <summary>
|
||||
/// 场景唯一id (传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则主体id
|
||||
/// </summary>
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否中转(单一)
|
||||
/// </summary>
|
||||
public bool? IsTransit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 货物类型(多个,分割)
|
||||
/// </summary>
|
||||
public string? CargoType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起运港口(多个,分割)
|
||||
/// </summary>
|
||||
public string? LeavePort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品编码(多个,分割)
|
||||
/// </summary>
|
||||
public string? ProductCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 月份(多个/分割)
|
||||
/// </summary>
|
||||
public string? Months { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区域Id(单一)
|
||||
/// </summary>
|
||||
public int? AreaId { get; set; }
|
||||
|
||||
|
||||
public bool CanHitScene(OrderEntity order, List<RuleAreaInfoEntity>? ruleAreas)
|
||||
{
|
||||
// 是否中转
|
||||
if (IsTransit != null && IsTransit != order.IsTransit) return false;
|
||||
|
||||
// 货物类型
|
||||
if (!string.IsNullOrWhiteSpace(CargoType) && order.CargoType != CargoType) return false;
|
||||
|
||||
// 启运港口
|
||||
if (!string.IsNullOrWhiteSpace(LeavePort) && order.LeavePort != LeavePort) return false;
|
||||
|
||||
// 产品编码
|
||||
if (!string.IsNullOrWhiteSpace(ProductCode) && order.ProductCode != ProductCode) return false;
|
||||
|
||||
// 月份
|
||||
if (!string.IsNullOrWhiteSpace(Months))
|
||||
{
|
||||
var months = string.IsNullOrEmpty(Months)
|
||||
? new HashSet<int>()
|
||||
: Months.Split('/').Select(int.Parse).ToHashSet();
|
||||
// 订单创建时间月份
|
||||
var orderCreateTimeMonth = order.CreateTime.Month;
|
||||
if (!months.Contains(orderCreateTimeMonth)) return false;
|
||||
}
|
||||
|
||||
// 区域
|
||||
if (ruleAreas != null && ruleAreas.Count > 0)
|
||||
{
|
||||
// 使用订单到达国家的二字码匹配区域
|
||||
var areas = ruleAreas.Where(area => order.ArrivalCountry == area.CountryCode).ToList();
|
||||
foreach (var area in areas)
|
||||
{
|
||||
// 邮编是否在关注的范围内?
|
||||
if (!string.IsNullOrWhiteSpace(area.LeftPostcode) && !string.IsNullOrWhiteSpace(area.RightPostcode))
|
||||
{
|
||||
// tips: 参考小包的邮编匹配,字典序
|
||||
if (string.CompareOrdinal(order.ArrivalPostCode, area.LeftPostcode) < 0 ||
|
||||
string.CompareOrdinal(order.ArrivalPostCode, area.RightPostcode) > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
// 城市是否匹配?
|
||||
if (!string.IsNullOrWhiteSpace(area.City) && order.ArrivalCity != area.City) return false;
|
||||
|
||||
// 省份是否匹配?
|
||||
if (!string.IsNullOrWhiteSpace(area.Province) && order.ArrivalProvince != area.Province) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static TransportWarningSceneEntity ToEntity(TransportWarningSceneBO bo)
|
||||
{
|
||||
return new TransportWarningSceneEntity(
|
||||
bo.Id,
|
||||
bo.WarningId,
|
||||
bo.CargoType,
|
||||
bo.Months,
|
||||
bo.AreaId,
|
||||
bo.IsTransit,
|
||||
bo.LeavePort,
|
||||
bo.ProductCode
|
||||
);
|
||||
}
|
||||
|
||||
public TransportWarningSceneEntity ToEntity()
|
||||
{
|
||||
return new TransportWarningSceneEntity(
|
||||
Id,
|
||||
WarningId,
|
||||
CargoType,
|
||||
Months,
|
||||
AreaId,
|
||||
IsTransit,
|
||||
LeavePort,
|
||||
ProductCode
|
||||
);
|
||||
}
|
||||
|
||||
public static TransportWarningSceneBO From(TransportWarningSceneEntity entity)
|
||||
{
|
||||
return new TransportWarningSceneBO
|
||||
{
|
||||
Id = entity.Id,
|
||||
WarningId = entity.WarningId,
|
||||
CargoType = entity.CargoType,
|
||||
Months = entity.Months,
|
||||
AreaId = entity.AreaId,
|
||||
IsTransit = entity.IsTransit,
|
||||
LeavePort = entity.LeavePort,
|
||||
ProductCode = entity.ProductCode
|
||||
};
|
||||
}
|
||||
|
||||
public static TransportWarningSceneBO From(UpsertTransportWarningSceneInput input)
|
||||
{
|
||||
return new TransportWarningSceneBO
|
||||
{
|
||||
Id = input.Id,
|
||||
WarningId = input.WarningId,
|
||||
CargoType = input.CargoType,
|
||||
Months = input.Months,
|
||||
AreaId = input.AreaId,
|
||||
IsTransit = input.IsTransit,
|
||||
LeavePort = input.LeavePort,
|
||||
ProductCode = input.ProductCode
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
|
||||
/// <summary>
|
||||
/// 处理运输时效规则项目的业务模型
|
||||
/// 可以通过入参/持久化模型转化
|
||||
/// </summary>
|
||||
public sealed class TransportWarningSceneRuleItemBO
|
||||
{
|
||||
/// <summary>
|
||||
/// 规则项目id(传0视为新增)
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警规主体id
|
||||
/// </summary>
|
||||
public int WarningId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 运输预警场景id
|
||||
/// </summary>
|
||||
public int SceneId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹状态Id
|
||||
/// </summary>
|
||||
public int StartTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 截止轨迹状态Id
|
||||
/// </summary>
|
||||
public int EndTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时效 (单位h)
|
||||
/// </summary>
|
||||
public float TransportTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始轨迹生成预警时间 (单位h)
|
||||
/// </summary>
|
||||
public float StartTrackWarningTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象用户集合
|
||||
/// </summary>
|
||||
public List<NotifyUserDto> NotifyUsers { get; set; }
|
||||
|
||||
public static List<TransportWarningSceneRuleItemBO> From(EditTransportWarningSceneRuleItemInput input)
|
||||
{
|
||||
var warningId = input.WarningId;
|
||||
var sceneId = input.SceneId;
|
||||
return input.Items.Select(x => new TransportWarningSceneRuleItemBO
|
||||
{
|
||||
Id = x.Id,
|
||||
WarningId = warningId,
|
||||
SceneId = sceneId,
|
||||
StartTrackStatusId = x.StartTrackStatusId,
|
||||
EndTrackStatusId = x.EndTrackStatusId,
|
||||
TransportTimeSpan = x.TransportTimeSpan,
|
||||
StartTrackWarningTimeSpan = x.StartTrackWarningTimeSpan,
|
||||
NotifyUsers = x.NotifyUsers
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static TransportWarningSceneRuleItemBO From(TransportWarningSceneRuleItemEntity entity)
|
||||
{
|
||||
return new TransportWarningSceneRuleItemBO
|
||||
{
|
||||
Id = entity.Id,
|
||||
WarningId = entity.WarningId,
|
||||
SceneId = entity.TransportWarningSceneId,
|
||||
StartTrackStatusId = entity.StartTrackStatusId,
|
||||
EndTrackStatusId = entity.EndTrackStatusId,
|
||||
TransportTimeSpan = entity.TransportTimeSpan,
|
||||
StartTrackWarningTimeSpan = entity.StartTrackWarningTimeSpan,
|
||||
NotifyUsers = TextJsonHelper.Deserialize<List<NotifyUserDto>>(entity.NotifyUsers)!
|
||||
};
|
||||
}
|
||||
|
||||
public static List<TransportWarningSceneRuleItemBO> From(List<TransportWarningSceneRuleItemEntity> entities)
|
||||
{
|
||||
return entities.Select(From).ToList();
|
||||
}
|
||||
|
||||
public TransportWarningSceneRuleItemEntity ToEntity()
|
||||
{
|
||||
return new TransportWarningSceneRuleItemEntity(
|
||||
Id,
|
||||
WarningId,
|
||||
SceneId,
|
||||
StartTrackStatusId,
|
||||
EndTrackStatusId,
|
||||
TransportTimeSpan,
|
||||
StartTrackWarningTimeSpan,
|
||||
TextJsonHelper.Serialize(NotifyUsers)!
|
||||
);
|
||||
}
|
||||
|
||||
public static List<TransportWarningSceneRuleItemEntity> ToEntities(List<TransportWarningSceneRuleItemBO> bos)
|
||||
{
|
||||
return bos.Select(x=>x.ToEntity()).ToList();
|
||||
}
|
||||
|
||||
public bool CanHitRule(int trackStatusId, HashSet<int> trackStatusIds)
|
||||
{
|
||||
return trackStatusId == StartTrackStatusId //命中起始轨迹状态
|
||||
&& !trackStatusIds.Contains(EndTrackStatusId); //缺失截止轨迹状态
|
||||
}
|
||||
|
||||
// 重新命中,用于规则扫描
|
||||
public bool CanReHit(HashSet<int> trackStatusIds)
|
||||
{
|
||||
return trackStatusIds.Contains(StartTrackStatusId) //存在起始
|
||||
&& !trackStatusIds.Contains(EndTrackStatusId); //不存在截止
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,162 @@
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Warning;
|
||||
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers;
|
||||
|
||||
public sealed class ReturnWarningHandler : IReturnWarningHandler
|
||||
{
|
||||
private readonly IWarningRuleRepository _warningRuleRepository;
|
||||
|
||||
public ReturnWarningHandler(IWarningRuleRepository warningRuleRepository)
|
||||
{
|
||||
_warningRuleRepository = warningRuleRepository;
|
||||
}
|
||||
|
||||
public Task TrackUpdatedOrDeletedHandleAsync(List<IWarningSignal> updateOrDeleteSignals)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<bool> ReceiveTrackPushRecordHandleAsync(TrackPushRecordIndex record)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
public Task WarningRuleToDisabledHandleAsync(WarningRuleEntity warningRule)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task PushConfigChangedHandleAsync(TrackPushConfigEntity pushConfig, TrackPushContentConfigEntity pushContentConfig)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
#region todo: 规则项目变更
|
||||
|
||||
public async Task HandleEditAsync(WarningRuleEntity rule, List<ReturnWarningRuleItemBO> postRuleItems)
|
||||
{
|
||||
var addRuleItems = postRuleItems.Where(x => x.Id == 0).ToList();
|
||||
// 1.找到之前的配置项目
|
||||
var entities = await _warningRuleRepository.GetReturnRuleItemsAsync(rule.Id);
|
||||
var oldRuleItems = ReturnWarningRuleItemBO.From(entities);
|
||||
// 1.1之前的配置数量为0,做只新增处理
|
||||
if (oldRuleItems.Count == 0)
|
||||
{
|
||||
if (addRuleItems.Count != 0)
|
||||
await OnlyAddHandleAsync(rule, addRuleItems);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 1.2之前的配置数量不为0,提交的数量为0,做只删除处理
|
||||
if (oldRuleItems.Count != 0 && postRuleItems.Count == 0)
|
||||
{
|
||||
await OnlyDeleteHandleAsync(rule, oldRuleItems);
|
||||
return;
|
||||
}
|
||||
|
||||
// 关心规则修改/删除
|
||||
var updateRuleItems = new List<ReturnWarningRuleItemBO>();
|
||||
var deleteRuleItems = new List<ReturnWarningRuleItemBO>();
|
||||
|
||||
// 2.差异化比较
|
||||
// 构建配置id字段
|
||||
var oldDict = oldRuleItems.ToDictionary(x => x.Id);
|
||||
var postDict = postRuleItems
|
||||
.Where(x => x.Id != 0) //tips:忽略新增的规则条目
|
||||
.ToDictionary(x => x.Id);
|
||||
var ruleItemIds = oldDict.Keys.Concat(postDict.Keys).ToHashSet();
|
||||
foreach (var ruleItemId in ruleItemIds)
|
||||
{
|
||||
var oldRule = oldDict.GetValueOrDefault(ruleItemId);
|
||||
var postRule = postDict.GetValueOrDefault(ruleItemId);
|
||||
if (oldRule != null && postRule != null)
|
||||
{
|
||||
//规则属性变更,(状态减少,时效变更)
|
||||
if (CanNeedFollow(oldRule, postRule))
|
||||
updateRuleItems.Add(postRule);
|
||||
continue;
|
||||
}
|
||||
|
||||
//规则条目被删除
|
||||
if (oldRule != null && postRule == null)
|
||||
deleteRuleItems.Add(oldRule);
|
||||
}
|
||||
|
||||
// 3.处理变更
|
||||
await HandleRuleItemsChangeAsync(rule, addRuleItems, updateRuleItems, deleteRuleItems);
|
||||
}
|
||||
|
||||
private async Task OnlyAddHandleAsync(WarningRuleEntity rule, List<ReturnWarningRuleItemBO> bos)
|
||||
{
|
||||
var entities = ReturnWarningRuleItemBO.ToEntities(bos);
|
||||
await _warningRuleRepository.BulkInsertReturnRuleItemsAsync(entities);
|
||||
// 更新规则主体版本号
|
||||
await _warningRuleRepository.UpdateVersionAsync(rule);
|
||||
}
|
||||
|
||||
private async Task OnlyDeleteHandleAsync(WarningRuleEntity rule, List<ReturnWarningRuleItemBO> bos)
|
||||
{
|
||||
var ruleItemIds = bos.Select(x => x.Id).ToHashSet();
|
||||
await _warningRuleRepository.DeleteReturnRuleItemsAsync(ruleItemIds);
|
||||
|
||||
// 更新规则主体版本号
|
||||
await _warningRuleRepository.UpdateVersionAsync(rule);
|
||||
|
||||
// todo:暂时不处理后续逻辑
|
||||
return;
|
||||
}
|
||||
|
||||
private async Task HandleRuleItemsChangeAsync(WarningRuleEntity rule,
|
||||
List<ReturnWarningRuleItemBO> addRuleItems,
|
||||
List<ReturnWarningRuleItemBO> updateRuleItems,
|
||||
List<ReturnWarningRuleItemBO> deleteRuleItems)
|
||||
{
|
||||
// 新增/修改/删除 实体,稍后做处理
|
||||
var addEntities = ReturnWarningRuleItemBO.ToEntities(addRuleItems);
|
||||
var updateEntities = ReturnWarningRuleItemBO.ToEntities(updateRuleItems);
|
||||
var deleteRuleItemIds = deleteRuleItems.Select(x => x.Id).ToHashSet();
|
||||
await _warningRuleRepository.BulkInsertReturnRuleItemsAsync(addEntities);
|
||||
await _warningRuleRepository.BulkUpdateReturnRuleItemsAsync(updateEntities);
|
||||
await _warningRuleRepository.DeleteReturnRuleItemsAsync(deleteRuleItemIds);
|
||||
|
||||
// todo:暂时不启用后续规则
|
||||
return;
|
||||
}
|
||||
|
||||
private static bool CanNeedFollow(ReturnWarningRuleItemBO oldRule, ReturnWarningRuleItemBO postRule)
|
||||
{
|
||||
// 时效发生更改
|
||||
if (Math.Abs(oldRule.ReturnTimeSpan - postRule.ReturnTimeSpan) > 1.0)
|
||||
return true;
|
||||
|
||||
// 关注的轨迹状态减少
|
||||
var oldStatusIds = oldRule.TrackStatusIds;
|
||||
var postStatusIds = postRule.TrackStatusIds;
|
||||
foreach (var statusId in oldStatusIds)
|
||||
if (!postStatusIds.Contains(statusId))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public List<ReturnWarningRuleItemEntity> DiffFilterReturnWarningRuleItems(WarningRuleEntity rule, List<ReturnWarningRuleItemEntity> postRuleItems)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<WarningNotifyTaskEntity> FilterAndHandleNeedNotifyTask(List<WarningNotifyTaskEntity> notifyTasks)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,418 @@
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Warning;
|
||||
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers;
|
||||
|
||||
public class TransportWarningHandler : ITransportWarningHandler
|
||||
{
|
||||
private readonly IKpiAreaRepository _kpiAreaRepository;
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
||||
private readonly IWarningRuleRepository _warningRuleRepository;
|
||||
private readonly IWarningTaskRepository _warningTaskRepository;
|
||||
private readonly IWarningDetailsEsRepository _warningDetailsEsRepository;
|
||||
|
||||
public TransportWarningHandler(IWarningTaskRepository warningTaskRepository, IWarningDetailsEsRepository warningDetailsEsRepository, IWarningRuleRepository warningRuleRepository, IOrderRepository orderRepository, ITrackDetailsEsRepository trackDetailsEsRepository, IKpiAreaRepository kpiAreaRepository)
|
||||
{
|
||||
_warningTaskRepository = warningTaskRepository;
|
||||
_warningDetailsEsRepository = warningDetailsEsRepository;
|
||||
_warningRuleRepository = warningRuleRepository;
|
||||
_orderRepository = orderRepository;
|
||||
_trackDetailsEsRepository = trackDetailsEsRepository;
|
||||
_kpiAreaRepository = kpiAreaRepository;
|
||||
}
|
||||
|
||||
#region 预警信号处理
|
||||
|
||||
public Task TrackDeletedHandleAsync(List<TrackDeletedSignal> deletedSignals)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task TrackAddedOrUpdatedHandleAsync(List<IWarningSignal> addOrDeleteSignals)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public Task WarningRuleToDisabledHandleAsync(WarningRuleEntity warningRule)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
#region todo: 规则场景变更
|
||||
|
||||
public async Task HandleSceneChangedAsync(WarningRuleEntity rule, TransportWarningSceneBO oldScene, TransportWarningSceneBO postScene)
|
||||
{
|
||||
if (!CanSceneChange(oldScene, postScene)) return;
|
||||
|
||||
// todo:暂时不做后续处理
|
||||
return;
|
||||
}
|
||||
|
||||
private bool CanSceneChange(TransportWarningSceneBO oldScene, TransportWarningSceneBO postScene)
|
||||
{
|
||||
return oldScene.CargoType != postScene.CargoType || //多个 普货,危险品
|
||||
oldScene.Months != postScene.Months || //多个 约束提交的月份组从小到大 1/3/4,不能出现 4/1/3这种 (如果出现则SequenceEqual)
|
||||
oldScene.AreaId != postScene.AreaId || // 单一,area1
|
||||
oldScene.IsTransit != postScene.IsTransit || //单一,true
|
||||
oldScene.LeavePort != postScene.LeavePort || //多个
|
||||
oldScene.ProductCode != postScene.ProductCode; //多个
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region todo: 规则项目变更
|
||||
|
||||
public async Task HandleEditAsync(WarningRuleEntity rule, TransportWarningSceneEntity scene, List<TransportWarningSceneRuleItemBO> postRuleItems)
|
||||
{
|
||||
var addRuleItems = postRuleItems.Where(x => x.Id == 0).ToList();
|
||||
|
||||
// 1.找到之前的配置项目
|
||||
var entities = await _warningRuleRepository.GetTransportSceneRuleItemsAsync(rule.Id, scene.Id);
|
||||
var oldRuleItems = TransportWarningSceneRuleItemBO.From(entities);
|
||||
// 1.1之前的配置数量为0,做只新增处理
|
||||
if (oldRuleItems.Count == 0)
|
||||
{
|
||||
if (addRuleItems.Count != 0)
|
||||
await OnlyAddHandleAsync(rule, scene, addRuleItems);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 1.2之前的配置数量不为0,提交的数量为0,做只删除处理
|
||||
if (oldRuleItems.Count != 0 && postRuleItems.Count == 0)
|
||||
{
|
||||
await OnlyDeleteHandleAsync(rule, scene, oldRuleItems);
|
||||
return;
|
||||
}
|
||||
|
||||
// 可能同时存在 新增/修改/删除
|
||||
var updateRuleItems = new List<TransportWarningSceneRuleItemBO>();
|
||||
var deleteRuleItems = new List<TransportWarningSceneRuleItemBO>();
|
||||
|
||||
// 2.差异化比较
|
||||
// 2.1构建配置id字段
|
||||
var oldRuleIdDict = oldRuleItems.ToDictionary(x => x.Id);
|
||||
var postRuleIdDict = postRuleItems
|
||||
.Except(addRuleItems) //tips:忽略新增的规则条目
|
||||
.ToDictionary(x => x.Id);
|
||||
var ruleItemIds = oldRuleIdDict.Keys.Concat(postRuleIdDict.Keys).ToHashSet();
|
||||
// 2.2比较
|
||||
foreach (var ruleItemId in ruleItemIds)
|
||||
{
|
||||
var oldRule = oldRuleIdDict.GetValueOrDefault(ruleItemId);
|
||||
var postRule = postRuleIdDict.GetValueOrDefault(ruleItemId);
|
||||
if (oldRule != null && postRule != null)
|
||||
{
|
||||
//规则属性变更,(起/止状态,时效变更)
|
||||
if (CanNeedFollow(oldRule, postRule))
|
||||
updateRuleItems.Add(postRule); //更新 关注新的配置
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
//规则条目被删除
|
||||
if (oldRule != null && postRule == null)
|
||||
deleteRuleItems.Add(oldRule); //删除 关注旧配置
|
||||
}
|
||||
|
||||
// 3.处理变更
|
||||
await HandleRuleItemsChangeAsync(rule, scene, addRuleItems, updateRuleItems, deleteRuleItems);
|
||||
}
|
||||
|
||||
private async Task OnlyAddHandleAsync(WarningRuleEntity rule, TransportWarningSceneEntity scene, List<TransportWarningSceneRuleItemBO> bos)
|
||||
{
|
||||
var entities = TransportWarningSceneRuleItemBO.ToEntities(bos);
|
||||
await _warningRuleRepository.BulkInsertTransportSceneRuleItemsAsync(entities);
|
||||
// 更新规则主体版本号
|
||||
await _warningRuleRepository.UpdateVersionAsync(rule);
|
||||
}
|
||||
|
||||
private async Task OnlyDeleteHandleAsync(WarningRuleEntity rule, TransportWarningSceneEntity scene, List<TransportWarningSceneRuleItemBO> bos)
|
||||
{
|
||||
var ruleItemIds = bos.Select(x => x.Id).ToHashSet();
|
||||
await _warningRuleRepository.DeleteTransportSceneRuleItemsAsync(ruleItemIds);
|
||||
|
||||
// 更新规则主体版本号
|
||||
await _warningRuleRepository.UpdateVersionAsync(rule);
|
||||
|
||||
// todo:暂时不处理后续逻辑
|
||||
return;
|
||||
// 处理轨迹删除
|
||||
await HandleDeleteAsync(ruleItemIds);
|
||||
}
|
||||
|
||||
private async Task HandleRuleItemsChangeAsync(
|
||||
WarningRuleEntity rule,
|
||||
TransportWarningSceneEntity scene,
|
||||
List<TransportWarningSceneRuleItemBO> addRuleItems,
|
||||
List<TransportWarningSceneRuleItemBO> updateRuleItems,
|
||||
List<TransportWarningSceneRuleItemBO> deleteRuleItems
|
||||
)
|
||||
{
|
||||
// 新增/修改/删除 实体,稍后做处理
|
||||
var addEntities = TransportWarningSceneRuleItemBO.ToEntities(addRuleItems);
|
||||
var updateEntities = TransportWarningSceneRuleItemBO.ToEntities(updateRuleItems);
|
||||
var deleteRuleItemIds = deleteRuleItems.Select(x => x.Id).ToHashSet();
|
||||
await _warningRuleRepository.BulkInsertTransportSceneRuleItemsAsync(addEntities);
|
||||
await _warningRuleRepository.BulkUpdateTransportSceneRuleItemsAsync(updateEntities);
|
||||
await _warningRuleRepository.DeleteTransportSceneRuleItemsAsync(deleteRuleItemIds);
|
||||
|
||||
// todo:暂时不启用后续规则
|
||||
return;
|
||||
// 1.查询变更配置相关的预警生成任务(未关闭的)
|
||||
var updateRuleItemIds = updateRuleItems.Select(x => x.Id).ToHashSet();
|
||||
var generateTasks = await _warningTaskRepository.GetTransportWarningDetailsGenerateTaskAsync(x =>
|
||||
!x.IsClosed
|
||||
&& x.WarningId == scene.WarningId
|
||||
&& updateRuleItemIds.Contains(x.WarningSceneRuleItemId)
|
||||
);
|
||||
|
||||
// 2.查询变更配置相关的预警通知任务(未关闭的)
|
||||
var warningNotifyTasks = await _warningTaskRepository.GetWarningNotifyTaskAsync(x =>
|
||||
!x.IsClosed
|
||||
&& x.WarningId == rule.Id
|
||||
&& x.WarningType == WarningRuleType.运输时效预警.GetHashCode()
|
||||
&& updateRuleItemIds.Contains(x.WarningRuleId)
|
||||
);
|
||||
|
||||
// 3.查询变更配置相关的预警明细(即将超时/已超时)
|
||||
var warningDetails = await _warningDetailsEsRepository.GetTransportWarningDetailsAsync(
|
||||
updateRuleItemIds,
|
||||
new HashSet<int>(2)
|
||||
{
|
||||
TransportWarningStatus.即将超时.GetHashCode(),
|
||||
TransportWarningStatus.已超时.GetHashCode()
|
||||
}
|
||||
);
|
||||
|
||||
// 构建处理快
|
||||
var handleBlocks = new List<HandleBlock>(generateTasks.Count + warningNotifyTasks.Count + warningDetails.Count);
|
||||
// 使用【预警明细】【预警生成任务】【预警通知任务】填充处理块
|
||||
handleBlocks.AddRange(generateTasks.Select(x => new HandleBlock(x.OrderId, x.WarningSceneRuleItemId, x)));
|
||||
handleBlocks.AddRange(warningNotifyTasks.Select(x => new HandleBlock(x.OrderId, x.WarningRuleId, x)));
|
||||
handleBlocks.AddRange(warningDetails.Select(x => new HandleBlock(x.OrderId, x.WarningSceneRuleItemId, x)));
|
||||
|
||||
// tips:无需在通过预警通知任务反找订单,因为产生预警通知任务时预警明细已经存在!
|
||||
// 查询订单
|
||||
var orderIds = handleBlocks.Select(x => x.OrderId).ToHashSet();
|
||||
var orders = await _orderRepository.GetListAsync(x => orderIds.Contains(x.Id));
|
||||
orderIds = orders.Select(x => x.Id).ToHashSet();
|
||||
// 查询这些订单相关的轨迹
|
||||
var allOrderTracks = await _trackDetailsEsRepository.GetListAsync(orderIds.ToArray());
|
||||
var orderTrackStatusIdsDict = allOrderTracks.GroupBy(x => x.OrderId)
|
||||
.ToDictionary(x => x.Key, y => y.ToList());
|
||||
|
||||
// 3.检查是否重新命中规则
|
||||
var ruleArea = scene.AreaId.HasValue ? await _kpiAreaRepository.GetFirstAsync(x => x.Id == scene.AreaId.Value) : null;
|
||||
var updateRuleItemIdDict = updateRuleItems.ToDictionary(x => x.Id);
|
||||
foreach (var group in handleBlocks.GroupBy(x => (x.OrderId, x.RuleItemId)))
|
||||
{
|
||||
var key = group.Key;
|
||||
var ruleItem = updateRuleItemIdDict[key.RuleItemId];
|
||||
var orderTracks = orderTrackStatusIdsDict[key.OrderId];
|
||||
var earliestTrack = orderTracks
|
||||
.Where(x => x.TrackStatusId == ruleItem.StartTrackStatusId)
|
||||
.OrderBy(x => x.TrackTime)
|
||||
.First();
|
||||
var orderStatusIds = orderTracks
|
||||
.Select(x => x.TrackStatusId)
|
||||
.ToHashSet();
|
||||
|
||||
var reHit = ruleItem.CanReHit(orderStatusIds); //存在起始,不存在截止,视为命中
|
||||
foreach (var block in group)
|
||||
{
|
||||
block.ReHitRule = reHit;
|
||||
if (reHit && block.Type == HandleType.Detail) //重新命中的轨迹,需要更新预警信息中的规则描述,以及轨迹信息(起始)
|
||||
{
|
||||
// 配置相关信息
|
||||
block.Detail.WarningName = rule.Name;
|
||||
block.Detail.WarningRuleDescription = block.Detail.GetWarningRuleDescription(scene, ruleItem.ToEntity(), ruleArea);
|
||||
block.Detail.TransportTimeSpan = ruleItem.TransportTimeSpan;
|
||||
block.Detail.StartTrackWarningTimeSpan = ruleItem.StartTrackWarningTimeSpan;
|
||||
// 起始轨迹相关信息
|
||||
block.Detail.StartTrackStatusId = earliestTrack.TrackStatusId;
|
||||
block.Detail.StartTrackStatus = earliestTrack.TrackStatus;
|
||||
block.Detail.StartTrackContentId = earliestTrack.TrackContentId;
|
||||
block.Detail.StartTrackContent = earliestTrack.TrackContent;
|
||||
block.Detail.StartTrackTime = earliestTrack.TrackTime; //用于更新累计运输时间
|
||||
block.Detail.StartTrackTimeZone = earliestTrack.TrackTimeZone;
|
||||
continue;
|
||||
}
|
||||
|
||||
// tips:更改后直接引发任务进行,等待下一轮任务扫描就会注意到
|
||||
if (reHit && block.Type == HandleType.GenerateTask) //重新命中的轨迹,需要更新预警生成任务
|
||||
{
|
||||
// 更新生成任务当中的相关信息
|
||||
block.GenerateTask.StartTrackStatusId = earliestTrack.TrackStatusId;
|
||||
block.GenerateTask.EndTrackStatusId = ruleItem.EndTrackStatusId;
|
||||
block.GenerateTask.StartTrackTime = earliestTrack.TrackTime;
|
||||
block.GenerateTask.StartTrackTimeZone = earliestTrack.TrackTimeZone;
|
||||
block.GenerateTask.StartTrackWarningTimeSpan = ruleItem.StartTrackWarningTimeSpan;
|
||||
block.GenerateTask.PlanExecutionTime = earliestTrack.TrackTime.AddHours(ruleItem.StartTrackWarningTimeSpan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重新命中规则的处理块
|
||||
var reHitRuleBlocks = handleBlocks.Where(x => x.ReHitRule).ToList();
|
||||
|
||||
// 3.1 更新预警明细(重新命中规则)
|
||||
var updateWarningDetails = reHitRuleBlocks
|
||||
.Where(x => x.Type == HandleType.Detail)
|
||||
.Select(x => x.Detail)
|
||||
.ToList();
|
||||
await _warningDetailsEsRepository.BulkUpdateTransportWarningDetailsAsync(updateWarningDetails);
|
||||
|
||||
// 3.2 更新预警生成任务(重新命中规则)
|
||||
var updateGenerateTasks = reHitRuleBlocks
|
||||
.Where(x => x.Type == HandleType.GenerateTask)
|
||||
.Select(x => x.GenerateTask)
|
||||
.ToList();
|
||||
await _warningTaskRepository.BulkUpdateTransportWarningDetailsGenerateTaskAsync(updateGenerateTasks);
|
||||
|
||||
// 3.3 处理需要关闭的【预警明细】【预警生成任务】【预警通知任务】(未命中规则)
|
||||
var typeIdsDict = handleBlocks
|
||||
.Except(reHitRuleBlocks)
|
||||
.GroupBy(x => x.Type)
|
||||
.ToDictionary(x => x.Key, y =>
|
||||
{
|
||||
return y.Key switch
|
||||
{
|
||||
HandleType.Detail => y.Select(x => x.Detail.Id).ToHashSet(),
|
||||
HandleType.GenerateTask => y.Select(x => x.GenerateTask.Id.ToString()).ToHashSet(),
|
||||
HandleType.NotifyTask => y.Select(x => x.NotifyTask.Id.ToString()).ToHashSet(),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
});
|
||||
|
||||
// 4.处理删除规则的相关联的【预警明细】【预警生成任务】【预警通知任务】
|
||||
// 预警信息状态修改为已关闭(即将超时/已超时)
|
||||
var closeDetailIds = typeIdsDict.GetValueOrDefault(HandleType.Detail, new HashSet<string>());
|
||||
await _warningDetailsEsRepository.BulkCloseTransportWarningDetailsAsync(closeDetailIds);
|
||||
|
||||
// 关闭相关的预警生成任务(未关闭的)
|
||||
var closeGenerateTaskIds = typeIdsDict.GetValueOrDefault(HandleType.GenerateTask, new HashSet<string>());
|
||||
await _warningTaskRepository.CloseTransportWarningDetailsGenerateTaskAsync(x =>
|
||||
!x.IsClosed
|
||||
&& (
|
||||
closeGenerateTaskIds.Contains(x.Id.ToString())
|
||||
|| (x.WarningId == rule.Id && deleteRuleItemIds.Contains(x.WarningSceneRuleItemId))
|
||||
)
|
||||
);
|
||||
|
||||
// 关闭关联的预警通知任务(未关闭的)
|
||||
var closeNotifyTaskIds = typeIdsDict.GetValueOrDefault(HandleType.NotifyTask, new HashSet<string>());
|
||||
await _warningTaskRepository.CloseWarningNotifyTaskAsync(x =>
|
||||
!x.IsClosed
|
||||
&& (
|
||||
closeNotifyTaskIds.Contains(x.Id.ToString())
|
||||
|| (x.WarningId == rule.Id
|
||||
&& x.WarningType == WarningRuleType.运输时效预警.GetHashCode()
|
||||
&& deleteRuleItemIds.Contains(x.WarningRuleId))
|
||||
));
|
||||
}
|
||||
|
||||
private async Task HandleDeleteAsync(HashSet<int> deleteRuleItemIds)
|
||||
{
|
||||
// 处理删除规则的相关联的【预警明细】【预警生成任务】【预警通知任务】
|
||||
// 预警信息状态修改为已关闭(即将超时/已超时)
|
||||
await _warningDetailsEsRepository.BulkCloseTransportWarningDetailsAsync(deleteRuleItemIds);
|
||||
|
||||
// 关闭相关的预警生成任务(未关闭的)
|
||||
await _warningTaskRepository.CloseTransportWarningDetailsGenerateTaskAsync(x =>
|
||||
!x.IsClosed
|
||||
&& deleteRuleItemIds.Contains(x.WarningSceneRuleItemId)
|
||||
);
|
||||
|
||||
// 关闭关联的预警通知任务(未关闭的)
|
||||
await _warningTaskRepository.CloseWarningNotifyTaskAsync(x =>
|
||||
!x.IsClosed
|
||||
&& x.WarningType == WarningRuleType.运输时效预警.GetHashCode()
|
||||
&& deleteRuleItemIds.Contains(x.WarningRuleId)
|
||||
);
|
||||
}
|
||||
|
||||
private static bool CanNeedFollow(TransportWarningSceneRuleItemBO oldRule, TransportWarningSceneRuleItemBO postRule)
|
||||
{
|
||||
if (oldRule.StartTrackStatusId != postRule.StartTrackStatusId)
|
||||
return true;
|
||||
|
||||
if (oldRule.EndTrackStatusId != postRule.EndTrackStatusId)
|
||||
return true;
|
||||
|
||||
if (Math.Abs(oldRule.TransportTimeSpan - postRule.TransportTimeSpan) > 1.0f)
|
||||
return true;
|
||||
|
||||
if (Math.Abs(oldRule.StartTrackWarningTimeSpan - postRule.StartTrackWarningTimeSpan) > 1.0f)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private enum HandleType
|
||||
{
|
||||
Detail = 0,
|
||||
GenerateTask = 1,
|
||||
NotifyTask = 2
|
||||
}
|
||||
|
||||
private sealed class HandleBlock
|
||||
{
|
||||
public int OrderId { get; }
|
||||
public int RuleItemId { get; }
|
||||
public HandleType Type { get; }
|
||||
|
||||
#nullable disable
|
||||
public TransportWarningDetailsIndex Detail { get; }
|
||||
public TransportWarningDetailsGenerateTaskEntity GenerateTask { get; }
|
||||
public WarningNotifyTaskEntity NotifyTask { get; }
|
||||
public bool ReHitRule { get; set; } //是否重新命中规则条目
|
||||
|
||||
private HandleBlock(int orderId, int ruleItemId)
|
||||
{
|
||||
OrderId = orderId;
|
||||
RuleItemId = ruleItemId;
|
||||
}
|
||||
|
||||
public HandleBlock(int orderId, int ruleItemId, TransportWarningDetailsIndex detail)
|
||||
: this(orderId, ruleItemId)
|
||||
{
|
||||
Type = HandleType.Detail;
|
||||
Detail = detail;
|
||||
}
|
||||
|
||||
public HandleBlock(int orderId, int ruleItemId, TransportWarningDetailsGenerateTaskEntity task)
|
||||
: this(orderId, ruleItemId)
|
||||
{
|
||||
Type = HandleType.GenerateTask;
|
||||
GenerateTask = task;
|
||||
}
|
||||
|
||||
public HandleBlock(int orderId, int ruleItemId, WarningNotifyTaskEntity task)
|
||||
: this(orderId, ruleItemId)
|
||||
{
|
||||
Type = HandleType.NotifyTask;
|
||||
NotifyTask = task;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public List<WarningNotifyTaskEntity> FilterAndHandleNeedNotifyTask(List<WarningNotifyTaskEntity> notifyTasks)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers.Warning;
|
||||
|
||||
public interface ICompleteWarningHandler : ITransientDependency
|
||||
{
|
||||
// 处理轨迹 删除 todo:未实现,用于处理信号,需要支持批量处理
|
||||
Task TrackDeletedHandleAsync(List<TrackDeletedSignal> deletedSignals);
|
||||
|
||||
// 处理轨迹 新增 todo:未实现,用于处理信号,需要支持批量处理
|
||||
Task TrackAddedHandleAsync(List<TrackAddedSignal> addedSignals);
|
||||
|
||||
// 完整预警主体禁用 todo:未实现
|
||||
Task WarningRuleToDisabledHandleAsync(WarningRuleEntity warningRule);
|
||||
|
||||
// 处理完整预警规则项变更
|
||||
Task HandleEditAsync(WarningRuleEntity rule, List<CompleteWarningRuleItemBO> postRuleItems);
|
||||
|
||||
// 预警通知任务可行性过滤 todo:未实现
|
||||
List<WarningNotifyTaskEntity> FilterAndHandleNeedNotifyTask(List<WarningNotifyTaskEntity> notifyTasks);
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers.Warning;
|
||||
|
||||
public interface IReturnWarningHandler : ITransientDependency
|
||||
{
|
||||
// 处理轨迹 修改/删除 todo:未实现,用于处理信号,需要支持批量处理
|
||||
Task TrackUpdatedOrDeletedHandleAsync(List<IWarningSignal> updateOrDeleteSignals);
|
||||
|
||||
// 收到轨迹推送记录(接口通回调)(人工介入/重试 阶段的回传) todo:未实现
|
||||
Task<bool> ReceiveTrackPushRecordHandleAsync(TrackPushRecordIndex record);
|
||||
|
||||
// 回传预警主体禁用 todo:未实现
|
||||
Task WarningRuleToDisabledHandleAsync(WarningRuleEntity warningRule);
|
||||
|
||||
// 处理推送映射配置变更 todo:未实现
|
||||
Task PushConfigChangedHandleAsync(TrackPushConfigEntity pushConfig, TrackPushContentConfigEntity pushContentConfig);
|
||||
|
||||
// 处理编辑回传预警规则项
|
||||
Task HandleEditAsync(WarningRuleEntity rule, List<ReturnWarningRuleItemBO> postRuleItems);
|
||||
|
||||
// 预警通知任务可行性过滤 todo:未实现
|
||||
List<WarningNotifyTaskEntity> FilterAndHandleNeedNotifyTask(List<WarningNotifyTaskEntity> notifyTasks);
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning.Handlers.Warning;
|
||||
|
||||
/// <summary>
|
||||
/// todo:提供业务模型的转化方法
|
||||
/// </summary>
|
||||
public interface ITransportWarningHandler : ITransientDependency
|
||||
{
|
||||
// 处理轨迹 删除 todo:用于处理信号,需要支持批量处理
|
||||
Task TrackDeletedHandleAsync(List<TrackDeletedSignal> deletedSignals);
|
||||
|
||||
// 处理轨迹 新增/修改 todo:用于处理信号,需要支持批量处理
|
||||
Task TrackAddedOrUpdatedHandleAsync(List<IWarningSignal> addOrDeleteSignals);
|
||||
|
||||
// 运输预警主体禁用 todo:未实现
|
||||
Task WarningRuleToDisabledHandleAsync(WarningRuleEntity warningRule);
|
||||
|
||||
// 运输预警场景变更
|
||||
Task HandleSceneChangedAsync(WarningRuleEntity rule, TransportWarningSceneBO oldScene, TransportWarningSceneBO postScene);
|
||||
|
||||
// 处理配置项列表保存
|
||||
Task HandleEditAsync(WarningRuleEntity rule, TransportWarningSceneEntity scene, List<TransportWarningSceneRuleItemBO> bos);
|
||||
|
||||
// 预警通知可行性筛选 todo:未实现
|
||||
List<WarningNotifyTaskEntity> FilterAndHandleNeedNotifyTask(List<WarningNotifyTaskEntity> notifyTasks);
|
||||
}
|
||||
@ -1,4 +1,13 @@
|
||||
using SJZY.Expand.ABP.Core.PublicMethords;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Return;
|
||||
using SJZY.Track.Application.Helpers;
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Warning;
|
||||
using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Dtos.Warning;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning;
|
||||
|
||||
@ -9,35 +18,17 @@ namespace SJZY.Track.Application.Services.Warning;
|
||||
[Route("Warning/Return")]
|
||||
public class ReturnWarningService : ApplicationService
|
||||
{
|
||||
/// <summary>
|
||||
/// 编辑回传预警规则列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("EditReturnWarningRuleItem")]
|
||||
public Task<UnifyResultDto> EditReturnWarningRuleItem(EditReturnWarningRuleItemInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyResultDto());
|
||||
}
|
||||
private readonly IReturnWarningHandler _returnWarningHandler;
|
||||
private readonly IWarningRuleRepository _warningRuleRepository;
|
||||
private readonly IWarningDetailsEsRepository _warningDetailsEsRepository;
|
||||
private readonly ITrackStatusRepository _trackStatusRepository;
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取回传预警明细
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetPageReturnWarningDetails")]
|
||||
public Task<UnifyPageResultDto<ReturnWarningDetailsDto>> GetPageReturnWarningDetails(GetPageReturnWarningDetailsInput input)
|
||||
public ReturnWarningService(IWarningRuleRepository warningRuleRepository, IWarningDetailsEsRepository warningDetailsEsRepository, IReturnWarningHandler returnWarningHandler, ITrackStatusRepository trackStatusRepository)
|
||||
{
|
||||
return Task.FromResult(new UnifyPageResultDto<ReturnWarningDetailsDto>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取回传报文日志
|
||||
/// </summary>
|
||||
[HttpPost("GetReturnMessageRecord")]
|
||||
public Task<UnifyResultDto<List<ReturnMessageRecordDto>>> GetReturnMessageRecord(GetReturnMessageRecordInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyResultDto<List<ReturnMessageRecordDto>>());
|
||||
_warningRuleRepository = warningRuleRepository;
|
||||
_warningDetailsEsRepository = warningDetailsEsRepository;
|
||||
_returnWarningHandler = returnWarningHandler;
|
||||
_trackStatusRepository = trackStatusRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -46,9 +37,163 @@ public class ReturnWarningService : ApplicationService
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetReturnWarningRuleItem")]
|
||||
public Task<UnifyResultDto<List<ReturnWarningRuleItemDto>>>
|
||||
GetReturnWarningRuleItem(GetReturnWarningRuleItemInput input)
|
||||
public async Task<UnifyResultDto<List<ReturnWarningRuleItemDto>>> GetReturnWarningRuleItem(GetReturnWarningRuleItemInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyResultDto<List<ReturnWarningRuleItemDto>>());
|
||||
var result = await _warningRuleRepository.GetReturnRuleItemsAsync(input.WarningId);
|
||||
|
||||
if (result.Count == 0)
|
||||
return new UnifyResultDto<List<ReturnWarningRuleItemDto>>(true, new List<ReturnWarningRuleItemDto>());
|
||||
|
||||
// todo:缓存优化
|
||||
var trackStatusIds = result
|
||||
.SelectMany(x => x.TrackStatusIds.Split(',').Select(int.Parse))
|
||||
.ToHashSet();
|
||||
var trackStatusDict = (await _trackStatusRepository.GetListAsync(x => trackStatusIds.Contains(x.Id), x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Status
|
||||
})).ToDictionary(x => x.Id, y => y.Status);
|
||||
|
||||
|
||||
var map = result.Select(x => new ReturnWarningRuleItemDto
|
||||
{
|
||||
Id = x.Id,
|
||||
TrackStatus = BuildTrackStatus(x.TrackStatusIds),
|
||||
ReturnTimeSpan = x.ReturnTimeSpan,
|
||||
NotifyUsers = x.NotifyUsers.ToObject<List<NotifyUserDto>>()
|
||||
});
|
||||
|
||||
return new UnifyResultDto<List<ReturnWarningRuleItemDto>>(true, map.ToList());
|
||||
|
||||
// todo:拆解优化
|
||||
List<TrackStatusDto> BuildTrackStatus(string statusIds)
|
||||
{
|
||||
return statusIds.Split(',')
|
||||
.Select(x =>
|
||||
{
|
||||
var id = int.Parse(x);
|
||||
return new TrackStatusDto
|
||||
{
|
||||
TrackStatus = trackStatusDict.GetValueOrDefault(id),
|
||||
TrackStatusId = id
|
||||
};
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取回传预警明细
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetPageReturnWarningDetails")]
|
||||
public async Task<UnifyPageResultDto<ReturnWarningDetailsDto>> GetPageReturnWarningDetails(GetPageReturnWarningDetailsInput input)
|
||||
{
|
||||
var vo = ObjectMapper.Map<GetPageReturnWarningDetailsInput, GetPageReturnWarningDetailsInputVO>(input);
|
||||
var result = await _warningDetailsEsRepository.GetPageReturnWarningDetailsAsync(vo);
|
||||
|
||||
// :填充子系统名称(冗余?)
|
||||
// :填充客户简称(冗余?)
|
||||
// :填充订单类型名称(冗余?)
|
||||
var map = result.List.Select(x => new ReturnWarningDetailsDto
|
||||
{
|
||||
EsId = x.Id,
|
||||
SubSystemId = x.SubSystemId,
|
||||
SubSystemName = x.SubSystemName,
|
||||
OrderType = x.OrderType,
|
||||
OrderTypeName = x.OrderTypeName,
|
||||
OrderId = x.OrderId,
|
||||
OrderNo = x.OrderNo,
|
||||
Status = x.Status,
|
||||
CustomId = x.CustomId,
|
||||
CustomName = x.CustomName,
|
||||
// 轨迹信息
|
||||
TrackStatus = x.TrackStatus,
|
||||
TrackCode = x.TrackCode,
|
||||
TrackContent = x.TrackContent,
|
||||
TrackPlace = x.TrackPlace,
|
||||
TrackTime = x.TrackTime,
|
||||
TrackTimeZone = x.TrackTimeZone,
|
||||
TrackCreateTime = x.TrackCreateTime,
|
||||
// 轨迹信息(映射后)
|
||||
PushTrackCode = x.PushTrackCode,
|
||||
PushTrackStatus = x.PushTrackStatus,
|
||||
PushTrackContent = x.PushTrackContent,
|
||||
// todo:计算属性
|
||||
ActualReturnTimeSpan = x.ActualReturnTimeSpan,
|
||||
SystemReturnTimeSpan = x.SystemReturnTimeSpan,
|
||||
TrackCreateTimeSpan = x.TrackCreateTimeSpan,
|
||||
|
||||
// 具体描述
|
||||
TrackReturnTime = x.TrackReturnTime,
|
||||
ReturnTimeSpan = x.ReturnTimeSpan,
|
||||
IsExistsKpi = x.IsExistsKpi,
|
||||
RetryCount = x.RetryCount,
|
||||
NotifyUserNames = ToUserNames(x.NotifyUsers),
|
||||
CreateTime = x.CreateTime,
|
||||
});
|
||||
|
||||
var sorted = map.OrderBy(x =>
|
||||
{
|
||||
// 人工介入置顶
|
||||
if (x.Status == 1) return x.Status;
|
||||
// 其他按创建时间从早到晚
|
||||
return DateTimeHelper.ConvertToUnixTimestamp(x.CreateTime);
|
||||
});
|
||||
|
||||
return new UnifyPageResultDto<ReturnWarningDetailsDto>(
|
||||
sorted.ToList(),
|
||||
result.Pagination.PageIndex,
|
||||
result.Pagination.PageSize,
|
||||
result.Pagination.Total);
|
||||
|
||||
// 通知用户提取用户名称
|
||||
string ToUserNames(string notifyUsers)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(notifyUsers))
|
||||
return string.Empty;
|
||||
return string.Join(',', notifyUsers.ToObject<List<NotifyUserDto>>().Select(x => x.UserName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取回传报文日志
|
||||
/// </summary>
|
||||
[HttpPost("GetReturnMessageRecord")]
|
||||
public async Task<UnifyResultDto<List<ReturnMessageRecordDto>>> GetReturnMessageRecord(GetReturnMessageRecordInput input)
|
||||
{
|
||||
var result = await _warningDetailsEsRepository.GetReturnMessageRecordListByIdAsync(input.WarningDetailsId);
|
||||
|
||||
var map = result.Select(x => new ReturnMessageRecordDto
|
||||
{
|
||||
EsId = x.Id,
|
||||
ReturnWarningDetailsId = x.WarningDetailsId,
|
||||
IsSuccess = x.IsSuccess,
|
||||
Message = x.Message,
|
||||
CreateTime = x.CreateTime
|
||||
});
|
||||
|
||||
return new UnifyResultDto<List<ReturnMessageRecordDto>>(true, map.ToList());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 编辑回传预警规则列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("EditReturnWarningRuleItem")]
|
||||
public async Task<UnifyResultDto> EditReturnWarningRuleItem(EditReturnWarningRuleItemInput input)
|
||||
{
|
||||
var rule = await _warningRuleRepository.GetWarningRuleByIdAsync(input.WarningId, WarningRuleType.回传时效预警);
|
||||
if (rule == null)
|
||||
{
|
||||
throw new BusinessException(message: $"预警规则主体不存在,WarningId=[{input.WarningId}]");
|
||||
}
|
||||
|
||||
var bos = ReturnWarningRuleItemBO.From(input);
|
||||
await _returnWarningHandler.HandleEditAsync(rule, bos);
|
||||
|
||||
return new UnifyResultDto(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,18 @@
|
||||
using System.Text;
|
||||
using SJZY.Expand.ABP.Core.PublicMethords;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
using SJZY.Track.Application.Helpers;
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Model;
|
||||
using SJZY.Track.Application.Services.Warning.Handlers.Warning;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
using SJZY.Track.Domain.Dtos.Warning;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning;
|
||||
|
||||
/// <summary>
|
||||
/// 运输时效预警服务
|
||||
@ -7,65 +21,259 @@ using SJZY.Track.Application.Contract.Dtos.Warning.Transport;
|
||||
[Route("Warning/Transport")]
|
||||
public class TransportWarningService : ApplicationService
|
||||
{
|
||||
private readonly IWarningRuleRepository _warningRuleRepository;
|
||||
private readonly IWarningDetailsEsRepository _warningDetailsEsRepository;
|
||||
private readonly ITransportWarningHandler _transportWarningHandler;
|
||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
||||
private readonly ITrackStatusRepository _trackStatusRepository;
|
||||
|
||||
/// <summary>
|
||||
/// 编辑预警规则项目(全量)
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("EditTransportWarningSceneRuleItem")]
|
||||
public Task<UnifyResultDto>
|
||||
EditTransportWarningSceneRuleItem(EditTransportWarningSceneRuleItemInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyResultDto());
|
||||
}
|
||||
public TransportWarningService(IWarningRuleRepository warningRuleRepository, IWarningDetailsEsRepository warningDetailsEsRepository, ITransportWarningHandler transportWarningHandler, ITrackDetailsEsRepository trackDetailsEsRepository, ITrackStatusRepository trackStatusRepository)
|
||||
{
|
||||
_warningRuleRepository = warningRuleRepository;
|
||||
_warningDetailsEsRepository = warningDetailsEsRepository;
|
||||
_transportWarningHandler = transportWarningHandler;
|
||||
_trackDetailsEsRepository = trackDetailsEsRepository;
|
||||
_trackStatusRepository = trackStatusRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取预警规则场景
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetTransportWarningScene")]
|
||||
public async Task<UnifyResultDto<List<TransportWarningSceneDto>>> GetTransportWarningScene(GetTransportWarningSceneInput input)
|
||||
{
|
||||
var entities = await _warningRuleRepository.GetTransportSceneAsync(input.WarningId);
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取运输时效预警明细
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetPageTransportWarningDetails")]
|
||||
public Task<UnifyPageResultDto<TransportWarningDetailsDto>>
|
||||
GetPageTransportWarningDetails(GetPageTransportWarningDetailsInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyPageResultDto<TransportWarningDetailsDto>());
|
||||
}
|
||||
var map = entities.Select(x => new TransportWarningSceneDto
|
||||
{
|
||||
Id = x.Id,
|
||||
WarningId = x.WarningId,
|
||||
Summary = BuildSummary(x),
|
||||
IsTransit = x.IsTransit,
|
||||
CargoType = x.CargoType,
|
||||
LeavePort = x.LeavePort,
|
||||
ProductCode = x.ProductCode,
|
||||
Months = x.Months,
|
||||
AreaId = x.AreaId
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// 获取预警规则场景
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetTransportWarningScene")]
|
||||
public Task<UnifyResultDto<List<TransportWarningSceneDto>>>
|
||||
GetTransportWarningScene(GetTransportWarningSceneInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyResultDto<List<TransportWarningSceneDto>>());
|
||||
}
|
||||
return new UnifyResultDto<List<TransportWarningSceneDto>>(true, map.ToList());
|
||||
|
||||
/// <summary>
|
||||
/// 获取运输时效场景规则项目
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetTransportWarningSceneRuleItem")]
|
||||
public Task<UnifyResultDto<List<TransportWarningSceneRuleItemDto>>>
|
||||
GetTransportWarningSceneRuleItem(GetTransportWarningSceneRuleItemInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyResultDto<List<TransportWarningSceneRuleItemDto>>());
|
||||
}
|
||||
// 构建场景摘要
|
||||
string BuildSummary(TransportWarningSceneEntity entity)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
// 货物类型
|
||||
if (!string.IsNullOrWhiteSpace(entity.CargoType))
|
||||
sb.Append($"{entity.CargoType}");
|
||||
// 月份
|
||||
if (!string.IsNullOrWhiteSpace(entity.Months))
|
||||
sb.Append($"/{entity.Months.Replace("/", string.Empty)}月份");
|
||||
// 中转
|
||||
if (entity.IsTransit != null)
|
||||
sb.Append($"/中转为{(entity.IsTransit.Value ? "是" : "否")}");
|
||||
// 起运港口
|
||||
if (!string.IsNullOrWhiteSpace(entity.LeavePort))
|
||||
sb.Append($"/{entity.LeavePort}");
|
||||
// 产品编码
|
||||
if (!string.IsNullOrWhiteSpace(entity.ProductCode))
|
||||
sb.Append($"/{entity.ProductCode}");
|
||||
|
||||
/// <summary>
|
||||
/// 新增/更新 运输时效场景
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("UpsertTransportWarningScene")]
|
||||
public Task<UnifyResultDto<IdBaseDto>>
|
||||
UpsertTransportWarningScene(UpsertTransportWarningSceneInput input)
|
||||
{
|
||||
return Task.FromResult(new UnifyResultDto<IdBaseDto>());
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取运输时效场景规则项目
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetTransportWarningSceneRuleItem")]
|
||||
public async Task<UnifyResultDto<List<TransportWarningSceneRuleItemDto>>> GetTransportWarningSceneRuleItem(GetTransportWarningSceneRuleItemInput input)
|
||||
{
|
||||
var entities = await _warningRuleRepository.GetTransportSceneRuleItemsAsync(input.WarningId, input.SceneId);
|
||||
|
||||
// todo:缓存优化
|
||||
var trackStatusIds = entities.SelectMany(x => new List<int>(2)
|
||||
{
|
||||
x.StartTrackStatusId,
|
||||
x.EndTrackStatusId
|
||||
}).ToHashSet();
|
||||
var trackStatusDict = (await _trackStatusRepository.GetListAsync(x => trackStatusIds.Contains(x.Id), x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Status
|
||||
})).ToDictionary(x => x.Id, y => y.Status);
|
||||
|
||||
var map = entities.Select(x => new TransportWarningSceneRuleItemDto
|
||||
{
|
||||
Id = x.Id,
|
||||
StartTrackStatusId = x.StartTrackStatusId,
|
||||
StartTrackStatus = trackStatusDict.GetValueOrDefault(x.StartTrackStatusId),
|
||||
EndTrackStatusId = x.EndTrackStatusId,
|
||||
EndTrackStatus = trackStatusDict.GetValueOrDefault(x.EndTrackStatusId),
|
||||
TransportTimeSpan = x.TransportTimeSpan,
|
||||
StartTrackWarningTimeSpan = x.StartTrackWarningTimeSpan,
|
||||
NotifyUsers = x.NotifyUsers.ToObject<List<NotifyUserDto>>()
|
||||
});
|
||||
|
||||
return new UnifyResultDto<List<TransportWarningSceneRuleItemDto>>(true, map.ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取运输时效预警明细
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetPageTransportWarningDetails")]
|
||||
public async Task<UnifyPageResultDto<TransportWarningDetailsDto>> GetPageTransportWarningDetails(GetPageTransportWarningDetailsInput input)
|
||||
{
|
||||
var vo = ObjectMapper.Map<GetPageTransportWarningDetailsInput, GetPageTransportWarningDetailsInputVO>(input);
|
||||
var result = await _warningDetailsEsRepository.GetPageTransportWarningDetailsAsync(vo);
|
||||
if (result.List.Count == 0)
|
||||
{
|
||||
return new UnifyPageResultDto<TransportWarningDetailsDto>(new List<TransportWarningDetailsDto>(), input.PageIndex, input.PageSize, 0);
|
||||
}
|
||||
|
||||
var orderIds = result.List.Select(x => x.OrderId).ToHashSet();
|
||||
var orderTracks = await _trackDetailsEsRepository.GetLatestListAsync(orderIds);
|
||||
var orderIdTrackDict = orderTracks.ToDictionary(x => x.OrderId);
|
||||
|
||||
// :填充子系统名称(冗余?)
|
||||
// :填充客户简称(冗余?)
|
||||
// :填充订单类型名称(冗余?)
|
||||
var map = result.List.Select(x =>
|
||||
{
|
||||
var orderIdTrack = orderIdTrackDict.GetValueOrDefault(x.OrderId);
|
||||
return new TransportWarningDetailsDto
|
||||
{
|
||||
EsId = x.Id,
|
||||
SubSystemId = x.SubSystemId,
|
||||
SubSystemName = x.SubSystemName,
|
||||
CustomId = x.CustomId,
|
||||
CustomName = x.CustomName,
|
||||
OrderId = x.OrderId,
|
||||
OrderNo = x.OrderNo,
|
||||
OrderType = x.OrderType,
|
||||
OrderTypeName = x.OrderTypeName,
|
||||
NotifyUserNames = ToUserNames(x.NotifyUsers),
|
||||
|
||||
// 最新轨迹 (不冗余)
|
||||
LatestTrackContent = orderIdTrack?.TrackContent,
|
||||
LatestTrackTime = orderIdTrack?.TrackTime,
|
||||
LatestTrackTimeZone = orderIdTrack?.TrackTimeZone,
|
||||
LatestTrackPlace = orderIdTrack?.TrackContent,
|
||||
|
||||
// 起始轨迹
|
||||
StartTrackStatus = x.StartTrackStatus,
|
||||
StartTrackContent = x.StartTrackContent,
|
||||
StartTrackTime = x.StartTrackTime,
|
||||
StartTrackTimeZone = x.StartTrackTimeZone,
|
||||
|
||||
// 截止轨迹
|
||||
EndTrackStatus = x.EndTrackStatus,
|
||||
EndTrackContent = x.EndTrackContent,
|
||||
EndTrackTime = x.EndTrackTime,
|
||||
EndTrackTimeZone = x.EndTrackTimeZone,
|
||||
|
||||
WarningName = x.WarningName,
|
||||
WarningRuleDescription = x.WarningRuleDescription,
|
||||
|
||||
// 累计运输时间
|
||||
CumulativeTimeSpan = FormatCumulativeTimeSpan(x.CumulativeTimeSpan),
|
||||
|
||||
Status = x.Status,
|
||||
CreateTime = x.CreateTime
|
||||
};
|
||||
});
|
||||
|
||||
var sorted = map.OrderBy(x =>
|
||||
{
|
||||
// 即将超时,已超时置顶
|
||||
if (x.Status is 1 or 2) return x.Status;
|
||||
// 其他按创建时间从早到晚
|
||||
return DateTimeHelper.ConvertToUnixTimestamp(x.CreateTime);
|
||||
});
|
||||
|
||||
return new UnifyPageResultDto<TransportWarningDetailsDto>(
|
||||
sorted.ToList(),
|
||||
result.Pagination.PageIndex,
|
||||
result.Pagination.PageSize,
|
||||
result.Pagination.Total);
|
||||
|
||||
// 通知用户提取用户名称
|
||||
string ToUserNames(string notifyUsers)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(notifyUsers))
|
||||
return string.Empty;
|
||||
return string.Join(',', notifyUsers.ToObject<List<NotifyUserDto>>().Select(x => x.UserName));
|
||||
}
|
||||
|
||||
// 格式化累计运输时间为文本形式
|
||||
string FormatCumulativeTimeSpan(long cumulativeTimeSpan)
|
||||
{
|
||||
var timeSpan = TimeSpan.FromMilliseconds(cumulativeTimeSpan);
|
||||
|
||||
return $"{timeSpan.Days:00}天{timeSpan.Hours:00}小时{timeSpan.Minutes:00}分钟";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增/更新 运输时效场景
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("UpsertTransportWarningScene")]
|
||||
public async Task<UnifyResultDto<IdBaseDto>> UpsertTransportWarningScene(UpsertTransportWarningSceneInput input)
|
||||
{
|
||||
var rule = await _warningRuleRepository.GetWarningRuleByIdAsync(input.WarningId, WarningRuleType.运输时效预警);
|
||||
if (rule == null)
|
||||
{
|
||||
throw new BusinessException(message: $"预警规则主体不存在,WarningId=[{input.WarningId}]");
|
||||
}
|
||||
|
||||
var postBo = TransportWarningSceneBO.From(input);
|
||||
// 查出旧场景
|
||||
var oldScene = await _warningRuleRepository.GetTransportSceneAsync(input.WarningId, input.Id);
|
||||
var oldBo = oldScene != null ? TransportWarningSceneBO.From(oldScene) : null;
|
||||
|
||||
// 更新或者新增
|
||||
var id = await _warningRuleRepository.UpsertTransportSceneReturnIdAsync(postBo.ToEntity());
|
||||
|
||||
if (oldBo != null)
|
||||
await _transportWarningHandler.HandleSceneChangedAsync(rule, oldBo, postBo);
|
||||
|
||||
return new UnifyResultDto<IdBaseDto>(true, new IdBaseDto
|
||||
{
|
||||
Id = id
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑预警规则项目(全量)
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("EditTransportWarningSceneRuleItem")]
|
||||
public async Task<UnifyResultDto> EditTransportWarningSceneRuleItem(EditTransportWarningSceneRuleItemInput input)
|
||||
{
|
||||
var rule = await _warningRuleRepository.GetWarningRuleByIdAsync(input.WarningId, WarningRuleType.运输时效预警);
|
||||
if (rule == null)
|
||||
{
|
||||
throw new BusinessException(message: $"预警规则主体不存在,WarningId=[{input.WarningId}]");
|
||||
}
|
||||
|
||||
var ruleScene = await _warningRuleRepository.GetTransportSceneAsync(input.WarningId, input.SceneId);
|
||||
if (ruleScene == null)
|
||||
{
|
||||
throw new BusinessException(message: $"运输时效规则场景不存在,WarningIdId=[{input.WarningId}] SceneId=[{input.SceneId}]");
|
||||
}
|
||||
|
||||
var postRuleItems = TransportWarningSceneRuleItemBO.From(input);
|
||||
await _transportWarningHandler.HandleEditAsync(rule, ruleScene, postRuleItems);
|
||||
|
||||
return new UnifyResultDto(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using SJZY.Track.Application.Contract.Dtos.Warning;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Queries;
|
||||
|
||||
namespace SJZY.Track.Application.Services.Warning;
|
||||
|
||||
@ -9,6 +11,17 @@ namespace SJZY.Track.Application.Services.Warning;
|
||||
[Route("Warning")]
|
||||
public class WarningService : ApplicationService
|
||||
{
|
||||
private readonly IWarningRuleRepository _warningRuleRepository;
|
||||
private readonly IVSystemQueries _vSystemQueries;
|
||||
private readonly IVExternalSubjectQueries _vExternalSubjectQueries;
|
||||
|
||||
public WarningService(IWarningRuleRepository warningRuleRepository, IVSystemQueries vSystemQueries, IVExternalSubjectQueries vExternalSubjectQueries)
|
||||
{
|
||||
_warningRuleRepository = warningRuleRepository;
|
||||
_vSystemQueries = vSystemQueries;
|
||||
_vExternalSubjectQueries = vExternalSubjectQueries;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增/修改预警规则主体
|
||||
/// </summary>
|
||||
@ -17,18 +30,24 @@ public class WarningService : ApplicationService
|
||||
[HttpPost("UpsertWarningRule")]
|
||||
public async Task<UnifyResultDto<IdBaseDto>> UpsertWarningRule(UpsertWarningRuleInput input)
|
||||
{
|
||||
// var id = await _warningRuleRepository.UpsertReturnIdAsync(new WarningRuleEntity(
|
||||
// input.Id,
|
||||
// input.Name,
|
||||
// input.SubSystemId,
|
||||
// input.CustomId,
|
||||
// input.IsEnabled,
|
||||
// input.WarningType)
|
||||
// );
|
||||
// 要求 SubSystemId+CustomId+Name 联合不能重复
|
||||
if (await _warningRuleRepository.CheckNameDuplicateAsync(input.Id, input.SubSystemId, input.CustomId, input.Name))
|
||||
{
|
||||
throw new BusinessException(message: $"SubSystemId:[{input.SubSystemId}],CustomId:[{input.CustomId}],已存在名称为[{input.Name}]规则,不允许重复添加/修改");
|
||||
}
|
||||
|
||||
var id = await _warningRuleRepository.UpsertReturnIdAsync(new WarningRuleEntity(
|
||||
input.Id,
|
||||
input.Name,
|
||||
input.SubSystemId,
|
||||
input.CustomId,
|
||||
input.IsEnabled,
|
||||
input.WarningType)
|
||||
);
|
||||
|
||||
return new UnifyResultDto<IdBaseDto>(true, new IdBaseDto
|
||||
{
|
||||
Id = input.Id
|
||||
Id = id
|
||||
});
|
||||
}
|
||||
|
||||
@ -38,9 +57,40 @@ public class WarningService : ApplicationService
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetWarningRule")]
|
||||
public Task<UnifyResultDto<List<WarningRuleDto>>> GetWarningRule(GetWarningRuleInput input)
|
||||
public async Task<UnifyResultDto<List<WarningRuleDto>>> GetWarningRule(GetWarningRuleInput input)
|
||||
{
|
||||
//var result = await _warningRuleRepository.GetWarningRuleListAsync(input.SubSystemId, input.KeyWord, input.IsEnabled, input.WarningType);
|
||||
throw new NotImplementedException();
|
||||
var result = await _warningRuleRepository.GetWarningRuleListAsync(input.SubSystemId, input.KeyWord, input.IsEnabled, input.WarningType);
|
||||
if (result.Count == 0)
|
||||
return new UnifyResultDto<List<WarningRuleDto>>(true, new List<WarningRuleDto>());
|
||||
|
||||
// todo:缓存优化
|
||||
var customIds = result.Select(x => x.CustomId).ToHashSet();
|
||||
var customDict = (await _vExternalSubjectQueries
|
||||
.GetListAsync(x => customIds.Contains(x.Id), x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Abbreviation
|
||||
})).ToDictionary(x => x.Id, x => x.Abbreviation);
|
||||
|
||||
var subSystemIds = result.Select(x => x.SubSystemId).ToHashSet();
|
||||
var subSystemDict = (await _vSystemQueries
|
||||
.GetListAsync(x => subSystemIds.Contains(x.Id), x => new
|
||||
{
|
||||
x.Id,
|
||||
x.CnName
|
||||
})).ToDictionary(x => x.Id, x => x.CnName);
|
||||
|
||||
return new UnifyResultDto<List<WarningRuleDto>>(true, result.Select(x => new WarningRuleDto
|
||||
{
|
||||
Id = x.Id,
|
||||
SubSystemId = x.SubSystemId,
|
||||
SubSystemName = customDict.GetValueOrDefault(x.SubSystemId),
|
||||
CustomId = x.CustomId,
|
||||
CustomName = subSystemDict.GetValueOrDefault(x.CustomId),
|
||||
Name = x.Name,
|
||||
IsEnabled = x.IsEnabled,
|
||||
WarningType = x.WarningType,
|
||||
Version = x.Version
|
||||
}).ToList());
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ public interface IOrderRepository : IBasicRepository<OrderEntity>
|
||||
/// key:OrderType value:TypeName
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<Dictionary<string, string>> GetTrackOrderTypeDict();
|
||||
Task<Dictionary<string, string>> GetTrackOrderTypeDictAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 获取分页的轨迹订单
|
||||
|
||||
@ -8,8 +8,7 @@ public interface ITrackDetailsEsRepository : IElasticsearchClientService<TrackDe
|
||||
{
|
||||
Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds, string trackCode, bool forUpsert = false);
|
||||
|
||||
// todo:s07 获取这些订单的最新一条轨迹
|
||||
// Task<List<TrackDetailsIndex>> GetLatestListAsync(HashSet<int> eventOrderIds);
|
||||
Task<List<TrackDetailsIndex>> GetLatestListAsync(HashSet<int> eventOrderIds);
|
||||
|
||||
Task<List<TrackDetailsIndex>> GetLatestListAsync(int[] eventOrderIds, List<string> trackCodes);
|
||||
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
using Nest;
|
||||
using SJZY.Expand.ElasticSearch;
|
||||
using SJZY.Track.Domain.Consts;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Complete;
|
||||
|
||||
[ElasticsearchType(RelationName = GlobalConst.CompleteWarningDetailsIndex)]
|
||||
public sealed class CompleteWarningDetailsIndex : IdBaseIndex
|
||||
{
|
||||
public string IndexName { get; set; }
|
||||
public int WarningId { get; set; }
|
||||
public int CompleteWarningRuleId { get; set; }
|
||||
public string Version { get; set; }
|
||||
|
||||
//public string NotifyModes { get; set; } //通知方式,多个方式(,)分割 eg: 1,2
|
||||
public string NotifyUsers { get; set; } //通知人Json eg: [{"UserId":1,"UserName":"张三"},{"UserId":2,"UserName":"李四"}]
|
||||
public int CheckPointTrackStatusId { get; set; } // (冗余)检查点轨迹状态Id
|
||||
public string MissingTrackStatusIds { get; set; } //(冗余)缺失的轨迹状态
|
||||
|
||||
//订单信息
|
||||
public int SubSystemId { get; set; } //(冗余)子系统Id
|
||||
public string SubSystemName { get; set; } //(冗余)子系统名称
|
||||
public int CustomId { get; set; } //(冗余)客户Id
|
||||
public string CustomName { get; set; } //(冗余)客户名称
|
||||
public int OrderId { get; set; }
|
||||
public string OrderNo { get; set; } //订单号
|
||||
public int OrderType { get; set; } //(冗余)订单类型
|
||||
public string OrderTypeName { get; set; } //(冗余)订单类型名称
|
||||
|
||||
//可变属性
|
||||
public int Status { get; set; } // 1:待处理,2:已处理,3:已关闭
|
||||
|
||||
//视图属性(todo:查es 最新)
|
||||
// public int LatestTrackStatusId { get; set; } //最新轨迹状态Id
|
||||
// public string LatestTrackStatus { get; set; } //(冗余)最新轨迹状态
|
||||
// public int LatestTrackContentId { get; set; } //最新轨迹内容Id
|
||||
// public string LatestTrackContent { get; set; } //(冗余)最新轨迹内容名称
|
||||
// public DateTime LatestTrackTime { get; set; } //最新轨迹发生时间
|
||||
// public float LatestTrackTimeZone { get; set; } //最新轨迹发生时区
|
||||
// public string LatestTrackPlace { get; set; } //最新轨迹发生地
|
||||
|
||||
//审计属性
|
||||
public DateTime CreateTime { get; set; } // 预警创建时间
|
||||
public DateTime? ProcessedTime { get; set; } // 预警处理时间
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Complete;
|
||||
|
||||
[SugarTable("t_warning_complete_rule_item", TableDescription = "完整预警规则项")]
|
||||
public sealed class CompleteWarningRuleItemEntity : IFullAuditedBasicEntitys, IEntity
|
||||
{
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "WarningId", ColumnDescription = "预警规则主体id")]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "OrderTypes", ColumnDescription = "订单类型集合(,分割)")]
|
||||
public string OrderTypes { get; set; } //订单类型, 逗号分隔(1,3)
|
||||
|
||||
[SugarColumn(ColumnName = "CheckPointTrackStatusId", ColumnDescription = "检查点轨迹状态id")]
|
||||
public int CheckPointTrackStatusId { get; set; } //检查点轨迹状态id
|
||||
|
||||
[SugarColumn(ColumnName = "RequireTrackStatusIdExpression", ColumnDescription = "要求该订单持有的轨迹状态的表达式 S1/S2,S3 代表: 存在状态S1或者S2并且存在S3才算")]
|
||||
public string RequireTrackStatusIdExpression { get; set; } //要求该订单持有的轨迹状态的表达式 S1/S2,S3 代表: 存在状态S1或者S2并且存在S3
|
||||
|
||||
// [SugarColumn(ColumnName = "NotifyModes", ColumnDescription = "通知方式,多个方式(,)分割 eg: 1,2")]
|
||||
// public string NotifyModes { get; set; } //通知方式,多个方式(,)分割 eg: 1,2
|
||||
|
||||
[SugarColumn(ColumnName = "NotifyUsers", ColumnDescription = "通知人Json eg: [{\"UserId\":1,\"UserName\":\"张三\"},{\"UserId\":2,\"UserName\":\"李四\"}]")]
|
||||
public string NotifyUsers { get; set; } //通知人Json eg: [{"UserId":1,"UserName":"张三"},{"UserId":2,"UserName":"李四"}]
|
||||
|
||||
public CompleteWarningRuleItemEntity()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public CompleteWarningRuleItemEntity(int id, int warningId, string orderTypes, int checkPointTrackStatusId, string requireTrackStatusIdExpression, string notifyUsers)
|
||||
{
|
||||
Id = id;
|
||||
WarningId = warningId;
|
||||
OrderTypes = orderTypes;
|
||||
CheckPointTrackStatusId = checkPointTrackStatusId;
|
||||
RequireTrackStatusIdExpression = requireTrackStatusIdExpression;
|
||||
NotifyUsers = notifyUsers;
|
||||
}
|
||||
|
||||
public HashSet<int> GetRuleOrderTypes()
|
||||
{
|
||||
return OrderTypes.Split(',').Select(int.Parse).ToHashSet();
|
||||
}
|
||||
|
||||
public List<HashSet<int>> GetRequireTrackStatusIdGroups()
|
||||
{
|
||||
return RequireTrackStatusIdExpression
|
||||
.Split(",")
|
||||
.Select(g => g.Split('/').Select(int.Parse).ToHashSet())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
// 查看是否能命中这个规则
|
||||
public bool CanHitRule(int orderType, int trackStatusId)
|
||||
{
|
||||
var orderTypes = GetRuleOrderTypes();
|
||||
//没有命中订单类型
|
||||
if (!orderTypes.Contains(orderType)) return false;
|
||||
//没有命中状态检查点
|
||||
if (trackStatusId != CheckPointTrackStatusId) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 根据轨迹状态id集合判断是否缺失轨迹状态
|
||||
public bool ExistsMissingTrackStatus(HashSet<int> trackStatusIds)
|
||||
{
|
||||
if (trackStatusIds.Count == 0) return true;
|
||||
|
||||
//组之间是并且关系,组内为或的关系
|
||||
var groups = GetRequireTrackStatusIdGroups();
|
||||
|
||||
// 当没有某个组没有交集产生,则认定为轨迹缺失
|
||||
foreach (var g in groups)
|
||||
{
|
||||
if (!g.Intersect(trackStatusIds).Any())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Complete;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
using SJZY.Track.Domain.Dtos.Warning;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
|
||||
public interface IWarningDetailsEsRepository
|
||||
{
|
||||
#region 运输预警明细
|
||||
|
||||
// 分页获取运输预警明细
|
||||
Task<UnifyPageResultDto<TransportWarningDetailsIndex>> GetPageTransportWarningDetailsAsync(GetPageTransportWarningDetailsInputVO input);
|
||||
|
||||
// 获取运输预警明细(预警规则id+状态)
|
||||
Task<List<TransportWarningDetailsIndex>> GetTransportWarningDetailsAsync(HashSet<int> ruleItemIds, HashSet<int> status);
|
||||
|
||||
// 更新运输预警明细
|
||||
Task UpdateTransportWarningDetailsAsync(TransportWarningDetailsIndex detail);
|
||||
|
||||
// 批量更新运输预警明细
|
||||
Task BulkUpdateTransportWarningDetailsAsync(List<TransportWarningDetailsIndex> details, int maxRetries = 3);
|
||||
|
||||
// 批量关闭运输预警明细
|
||||
Task BulkCloseTransportWarningDetailsAsync(HashSet<string> detailIds, int maxRetries = 3);
|
||||
// 批量关闭运输预警明细
|
||||
Task BulkCloseTransportWarningDetailsAsync(HashSet<int> ruleItemIds, int maxRetries = 3);
|
||||
|
||||
// 新增运输预警明细
|
||||
Task InsertTransportWarningDetailsAsync(TransportWarningDetailsIndex detail);
|
||||
|
||||
// 批量新增运输预警明细
|
||||
Task BulkInsertTransportWarningDetailsAsync(List<TransportWarningDetailsIndex> details, int maxRetries = 3);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 回传预警明细
|
||||
|
||||
// 分页获取回传预警明细
|
||||
Task<UnifyPageResultDto<ReturnWarningDetailsIndex>> GetPageReturnWarningDetailsAsync(GetPageReturnWarningDetailsInputVO input);
|
||||
|
||||
// 获取回传日志列表
|
||||
Task<List<ReturnMessageRecordIndex>> GetReturnMessageRecordListByIdAsync(string esId);
|
||||
|
||||
// 更新回传预警明细
|
||||
Task UpdateReturnWarningDetailsAsync(ReturnWarningDetailsIndex detail);
|
||||
|
||||
// 批量更新回传预警明细
|
||||
Task BulkUpdateReturnWarningDetailsAsync(List<ReturnWarningDetailsIndex> details, int maxRetries = 3);
|
||||
|
||||
// 新增回传预警明细
|
||||
Task InsertReturnWarningDetailsAsync(ReturnWarningDetailsIndex detail);
|
||||
|
||||
// 批量新增回传预警明细
|
||||
Task BulkInsertReturnWarningDetailsAsync(List<ReturnWarningDetailsIndex> details, int maxRetries = 3);
|
||||
|
||||
// 新增回传日志
|
||||
Task InsertReturnMessageRecordAsync(ReturnMessageRecordIndex detail);
|
||||
|
||||
// 批量新增回传日志
|
||||
Task BulkInsertReturnMessageRecordAsync(List<ReturnMessageRecordIndex> details, int maxRetries = 3);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 完整预警明细
|
||||
|
||||
// 分页获取完整预警明细
|
||||
Task<UnifyPageResultDto<CompleteWarningDetailsIndex>> GetPageCompleteWarningDetailsAsync(GetPageCompleteWarningDetailsInputVO input);
|
||||
|
||||
// 更新完整预警明细
|
||||
Task UpdateCompleteWarningDetailsAsync(CompleteWarningDetailsIndex detail);
|
||||
|
||||
// 批量完整回传预警明细
|
||||
Task BulkUpdateCompleteWarningDetailsAsync(List<CompleteWarningDetailsIndex> details, int maxRetries = 3);
|
||||
|
||||
// 新增完整预警明细
|
||||
Task InsertCompleteWarningDetailsAsync(CompleteWarningDetailsIndex detail);
|
||||
|
||||
// 批量新增完整预警明细
|
||||
Task BulkInsertCompleteWarningDetailsAsync(List<CompleteWarningDetailsIndex> details, int maxRetries = 3);
|
||||
|
||||
#endregion
|
||||
|
||||
Task CreateAliasAsync();
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Complete;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
|
||||
/// <summary>
|
||||
/// 预警规则仓储
|
||||
/// todo:需要使用vo
|
||||
/// </summary>
|
||||
public interface IWarningRuleRepository : IBasicRepository<WarningRuleEntity>
|
||||
{
|
||||
#region 规则主体
|
||||
|
||||
// 检查名称是否重复
|
||||
Task<bool> CheckNameDuplicateAsync(int id,int subsystemId, int customId, string name);
|
||||
|
||||
// 新增/更新预警规则主体,并返回id
|
||||
Task<int> UpsertReturnIdAsync(WarningRuleEntity entity);
|
||||
|
||||
// 更新版本号
|
||||
Task<string> UpdateVersionAsync(WarningRuleEntity entity);
|
||||
|
||||
// 模糊查询预警规则主体
|
||||
Task<List<WarningRuleEntity>> GetWarningRuleListAsync(int? subsystemId, string? keyword, bool? isEnabled, int? warningType);
|
||||
|
||||
// 获取启用的预警规则主体
|
||||
Task<WarningRuleEntity?> GetWarningRuleForEnabledAsync(int subSystemId, int customId, WarningRuleType warningType);
|
||||
|
||||
// 获取预警规则主体根据id
|
||||
Task<WarningRuleEntity?> GetWarningRuleByIdAsync(int id, WarningRuleType? warningType = null);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 运输时效预警规则
|
||||
|
||||
// 获取运输预警场景列表
|
||||
Task<List<TransportWarningSceneEntity>> GetTransportSceneAsync(int warningId);
|
||||
|
||||
// 获取运输预警场景列表
|
||||
Task<TransportWarningSceneEntity?> GetTransportSceneAsync(int warningId, int sceneId);
|
||||
|
||||
// 全量获取的运输时效场景规则项目
|
||||
Task<List<TransportWarningSceneRuleItemEntity>> GetTransportSceneRuleItemsAsync(int warningId, int sceneId);
|
||||
|
||||
// 新增/更新 运输预警场景
|
||||
Task<int> UpsertTransportSceneReturnIdAsync(TransportWarningSceneEntity entity);
|
||||
|
||||
// 批量更新运输时效场景规则项目
|
||||
Task<int> BulkUpdateTransportSceneRuleItemsAsync(List<TransportWarningSceneRuleItemEntity> entities);
|
||||
|
||||
// 批量新增运输时效场景规则项目
|
||||
Task<int> BulkInsertTransportSceneRuleItemsAsync(List<TransportWarningSceneRuleItemEntity> entities);
|
||||
|
||||
// 删除运输预警场景规则项目
|
||||
Task<int> DeleteTransportSceneRuleItemsAsync(HashSet<int> ruleItemIds);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 回传时效预警规则
|
||||
|
||||
// 获取全量回传预警规则规则项目
|
||||
Task<List<ReturnWarningRuleItemEntity>> GetReturnRuleItemsAsync(int warningId);
|
||||
|
||||
// 批量新增回传时效场景规则项目
|
||||
Task<int> BulkInsertReturnRuleItemsAsync(List<ReturnWarningRuleItemEntity> entities);
|
||||
|
||||
// 批量更新回传预警规则规则项目
|
||||
Task<int> BulkUpdateReturnRuleItemsAsync(List<ReturnWarningRuleItemEntity> entities);
|
||||
|
||||
// 删除回传预警规则项目
|
||||
Task<int> DeleteReturnRuleItemsAsync(HashSet<int> ruleItemIds);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 完整预警规则
|
||||
|
||||
// 获取全量预警规则规则项目
|
||||
Task<List<CompleteWarningRuleItemEntity>> GetCompleteRuleItemsAsync(int warningId);
|
||||
|
||||
// 批量更新预警规则规则项目
|
||||
Task<int> BulkUpdateCompleteRuleItemsAsync(List<CompleteWarningRuleItemEntity> entities);
|
||||
|
||||
// 批量新增完整时效规则项目
|
||||
Task<int> BulkInsertCompleteRuleItemsAsync(List<CompleteWarningRuleItemEntity> entities);
|
||||
|
||||
// 删除完整预警场景规则项目
|
||||
Task<int> DeleteCompleteRuleItemsAsync(HashSet<int> ruleItemIds);
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
|
||||
public interface IWarningTaskRepository
|
||||
{
|
||||
#region 预警通知任务
|
||||
|
||||
// 初步扫描出可能要进行的预警通知任务
|
||||
Task<List<WarningNotifyTaskEntity>> ScanMayNeedExecutedTaskAsync();
|
||||
|
||||
// 获取预警通知任务
|
||||
Task<List<WarningNotifyTaskEntity>> GetWarningNotifyTaskAsync(Expression<Func<WarningNotifyTaskEntity, bool>> expression);
|
||||
|
||||
// 添加一个预警通知任务
|
||||
Task<bool> AddWarningNotifyTaskAsync(WarningNotifyTaskEntity entity);
|
||||
|
||||
// 批量添加预警通知任务
|
||||
Task<int> BulkInsertWarningNotifyTaskAsync(List<WarningNotifyTaskEntity> entities);
|
||||
|
||||
// 关闭预警通知任务
|
||||
Task<int> CloseWarningNotifyTaskAsync(Expression<Func<WarningNotifyTaskEntity, bool>> expression);
|
||||
|
||||
// 关闭预警通知任务
|
||||
Task<bool> CloseWarningNotifyTaskAsync(WarningNotifyTaskEntity entity);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 回传预警_重试推送任务
|
||||
|
||||
// 扫描重试推送任务
|
||||
Task<List<ReturnWarningRetryPushTaskEntity>> ScanReturnWarningRetryPushTaskAsync();
|
||||
|
||||
// 条件获取重试推送任务
|
||||
Task<List<ReturnWarningRetryPushTaskEntity>> GetReturnWarningRetryPushTaskAsync(Expression<Func<ReturnWarningRetryPushTaskEntity, bool>> expression);
|
||||
|
||||
// 添加回传预警_重试推送任务
|
||||
Task<bool> AddReturnWarningRetryPushTaskAsync(ReturnWarningRetryPushTaskEntity entity);
|
||||
|
||||
// 批量添加回传预警_重试推送任务
|
||||
Task<int> BulkInsertReturnWarningRetryPushTaskAsync(List<ReturnWarningRetryPushTaskEntity> entities);
|
||||
|
||||
// 条件关闭回传预警_重试推送任务
|
||||
Task<int> CloseReturnWarningRetryPushTaskAsync(Expression<Func<ReturnWarningRetryPushTaskEntity, bool>> expression);
|
||||
|
||||
// 关闭回传预警_重试推送任务
|
||||
Task<bool> CloseReturnWarningRetryPushTaskAsync(ReturnWarningRetryPushTaskEntity entity);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 运输预警_预警明细生成任务
|
||||
|
||||
// 扫描预警明细生成任务
|
||||
Task<List<TransportWarningDetailsGenerateTaskEntity>> ScanTransportWarningDetailsGenerateTaskAsync();
|
||||
|
||||
// 条件获取运输预警明细生成任务
|
||||
Task<List<TransportWarningDetailsGenerateTaskEntity>> GetTransportWarningDetailsGenerateTaskAsync(Expression<Func<TransportWarningDetailsGenerateTaskEntity, bool>> expression);
|
||||
|
||||
// 添加运输预警明细生成任务
|
||||
Task<bool> AddTransportWarningDetailsGenerateTaskAsync(TransportWarningDetailsGenerateTaskEntity entity);
|
||||
|
||||
// 批量添加运输预警明细生成任务
|
||||
Task<int> BulkInsertTransportWarningDetailsGenerateTaskAsync(List<TransportWarningDetailsGenerateTaskEntity> entities);
|
||||
|
||||
// 批量更新运输预警明细生成任务
|
||||
Task<int> BulkUpdateTransportWarningDetailsGenerateTaskAsync(List<TransportWarningDetailsGenerateTaskEntity> entities);
|
||||
|
||||
// 条件关闭运输预警明细生成任务
|
||||
Task<int> CloseTransportWarningDetailsGenerateTaskAsync(Expression<Func<TransportWarningDetailsGenerateTaskEntity, bool>> expression);
|
||||
|
||||
// 关闭运输预警明细生成任务
|
||||
Task<bool> CloseTransportWarningDetailsGenerateTaskAsync(TransportWarningDetailsGenerateTaskEntity entity);
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
using Nest;
|
||||
using SJZY.Expand.ElasticSearch;
|
||||
using SJZY.Track.Domain.Consts;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
|
||||
[ElasticsearchType(RelationName = GlobalConst.ReturnMessageRecordIndex)]
|
||||
public class ReturnMessageRecordIndex : IdBaseIndex
|
||||
{
|
||||
public string IndexName { get; set; }
|
||||
public string WarningDetailsId { get; set; } //回传预警明细Id
|
||||
public bool IsSuccess { get; set; } //是否成功
|
||||
public string Message { get; set; } //报文内容 Json字符串
|
||||
|
||||
//审计属性
|
||||
public DateTime CreateTime { get; set; } //报文创建时间
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
using Nest;
|
||||
using SJZY.Expand.ElasticSearch;
|
||||
using SJZY.Track.Domain.Consts;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
|
||||
// 回传时效预警明细
|
||||
[ElasticsearchType(RelationName = GlobalConst.ReturnWarningDetailsIndex)]
|
||||
public class ReturnWarningDetailsIndex : IdBaseIndex
|
||||
{
|
||||
public string IndexName { get; set; }
|
||||
//是否存在KPI考核,根据是否命中规则
|
||||
public bool IsExistsKpi => ReturnWarningRuleId != null && ReturnWarningRuleId > 0;
|
||||
public int? WarningId { get; set; }
|
||||
public int? ReturnWarningRuleId { get; set; }
|
||||
public string? Version { get; set; } //预警规则版本
|
||||
public float? ReturnTimeSpan { get; set; } //(冗余)回传时效(单位小时)
|
||||
//public string NotifyModes { get; set; } //通知方式,多个方式(,)分割 eg: 1,2
|
||||
public string NotifyUsers { get; set; } //通知人Json eg: [{"UserId":1,"UserName":"张三"},{"UserId":2,"UserName":"李四"}]
|
||||
|
||||
//订单信息
|
||||
public int SubSystemId { get; set; } //(冗余)子系统Id
|
||||
public string SubSystemName { get; set; } //(冗余)子系统名称
|
||||
public int CustomId { get; set; } //(冗余)客户Id
|
||||
public string CustomName { get; set; } //(冗余)客户名称
|
||||
public int OrderId { get; set; }
|
||||
public string OrderNo { get; set; } //订单号
|
||||
public int OrderType { get; set; } //(冗余)订单类型
|
||||
public string OrderTypeName { get; set; } //(冗余)订单类型名称
|
||||
|
||||
//轨迹信息-原始
|
||||
public int TrackStatusId { get; set; }
|
||||
public string TrackStatus { get; set; } //(冗余)轨迹状态名称
|
||||
public string? CompareFields { get; set; } //(冗余)比较字段
|
||||
public string? Extra { get; set; } //扩展字段
|
||||
public int TrackContentId { get; set; }
|
||||
public string TrackContent { get; set; }
|
||||
public string TrackCode { get; set; }
|
||||
public string TrackPlace { get; set; } //轨迹发生地
|
||||
public DateTime TrackTime { get; set; } //轨迹发生时间
|
||||
public float TrackTimeZone { get; set; } //轨迹发生时区
|
||||
public DateTime TrackCreateTime { get; set; } //轨迹创建时间
|
||||
|
||||
//轨迹信息-映射后
|
||||
public string PushTrackStatus { get; set; } //(冗余)推送轨迹状态
|
||||
public string PushTrackCode { get; set; }
|
||||
public string PushTrackContent { get; set; }
|
||||
public string PushTrackEnContent { get; set; }
|
||||
|
||||
//可变属性
|
||||
public DateTime? TrackReturnTime { get; set; } //轨迹回传时间, tips:只有回传成功了才写入
|
||||
public int RetryCount { get; set; } // 回传重试次数
|
||||
public int Status { get; set; } // 1:人工介入 2:重试中 3:推送完成 4:已关闭
|
||||
|
||||
//计算属性
|
||||
public long? ActualReturnTimeSpan { get; set; } //实际回传用时(单位毫秒)
|
||||
public long? SystemReturnTimeSpan { get; set; } //系统回传用时 (单位毫秒)
|
||||
public long TrackCreateTimeSpan { get; set; } //轨迹创建用时(单位毫秒)
|
||||
|
||||
//审计属性
|
||||
public DateTime CreateTime { get; set; } // 预警创建时间
|
||||
public DateTime? UpdateTime { get; set; } // 明细更新时间
|
||||
|
||||
public bool MatchExtra(string? compareFields, string? extra)
|
||||
{
|
||||
// 匹配字段为空,明细明细字段为空
|
||||
if (string.IsNullOrWhiteSpace(compareFields))
|
||||
return string.IsNullOrWhiteSpace(CompareFields);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(CompareFields))
|
||||
return false;
|
||||
|
||||
if (!string.Equals(CompareFields, compareFields)) //todo:当比较字段存放到轨迹明细中,后面修改了比较字段后会发生什么?
|
||||
return false;
|
||||
|
||||
if (string.IsNullOrEmpty(extra) || string.IsNullOrEmpty(Extra))
|
||||
return false;
|
||||
|
||||
return TextJsonHelper.EqJsonStringField(extra, Extra, compareFields);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
|
||||
// 预警重试推送任务
|
||||
[SugarTable("t_warning_return_retry_task", TableDescription = "回传预警重试推送任务")]
|
||||
public sealed class ReturnWarningRetryPushTaskEntity : IFullAuditedBasicEntitys, IEntity
|
||||
{
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "OrderId", ColumnDescription = "订单Id")]
|
||||
public int OrderId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "WarningDetailId", ColumnDescription = "预警明细id")]
|
||||
public string WarningDetailId { get; set; } //预警明细id
|
||||
|
||||
// 轨迹明细
|
||||
[SugarColumn(ColumnName = "TrackCode", ColumnDescription = "轨迹code")]
|
||||
public string TrackCode { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "TrackContent", ColumnDescription = "轨迹内容")]
|
||||
public string TrackContent { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "CompareFields", ColumnDescription = "比较字段")]
|
||||
public string? CompareFields { get; set; } //轨迹明细中的比较字段
|
||||
|
||||
[SugarColumn(ColumnName = "Extra", ColumnDescription = "扩展字段")]
|
||||
public string? Extra { get; set; } //轨迹明细中的扩展字段
|
||||
|
||||
|
||||
[SugarColumn(ColumnName = "OptionType", ColumnDescription = "操作类型")]
|
||||
public string OptionType { get; set; } //操作类型,
|
||||
|
||||
[SugarColumn(ColumnName = "ServiceProviderCode", ColumnDescription = "服务商code")]
|
||||
public string ServiceProviderCode { get; set; } //服务商code
|
||||
|
||||
[SugarColumn(ColumnName = "PushContent", ColumnDescription = "推送内容")]
|
||||
public string PushContent { get; set; } //推送数据的序列化值,为TrackPushInput/TrackUpdateInput集合
|
||||
|
||||
[SugarColumn(ColumnName = "IsClosed", ColumnDescription = "是否关闭")]
|
||||
public bool IsClosed { get; set; } // 已关闭的任务不会在执行
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
|
||||
// 回传预警规则项
|
||||
[SugarTable("t_warning_return_rule_item", TableDescription = "回传预警规则项")]
|
||||
public sealed class ReturnWarningRuleItemEntity : IFullAuditedBasicEntitys, IEntity
|
||||
{
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "WarningId", ColumnDescription = "预警规则主体id")]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "TrackStatusIds", ColumnDescription = "关注的轨迹状态Id集合")]
|
||||
public string TrackStatusIds { get; set; } //关注的轨迹状态Id,可以是多个使用,分割
|
||||
|
||||
[SugarColumn(ColumnName = "ReturnTimeSpan", ColumnDescription = "时效(单位小时)")]
|
||||
public float ReturnTimeSpan { get; set; } //时效(单位小时),只是用于判断状态
|
||||
|
||||
// [SugarColumn(ColumnName = "NotifyModes", ColumnDescription = "通知方式,多个方式(,)分割 eg: 1,2")]
|
||||
// public string NotifyModes { get; set; } //通知方式,多个方式(,)分割 eg: 1,2
|
||||
|
||||
[SugarColumn(ColumnName = "NotifyUsers", ColumnDescription = "通知人Json eg: [{\"UserId\":1,\"UserName\":\"张三\"},{\"UserId\":2,\"UserName\":\"李四\"}]")]
|
||||
public string NotifyUsers { get; set; } //通知人Json eg: [{"UserId":1,"UserName":"张三"},{"UserId":2,"UserName":"李四"}]
|
||||
|
||||
public ReturnWarningRuleItemEntity()
|
||||
{
|
||||
}
|
||||
|
||||
public ReturnWarningRuleItemEntity(int id, int warningId,string trackStatusIds, float returnTimeSpan, string notifyUsers)
|
||||
{
|
||||
Id = id;
|
||||
WarningId = warningId;
|
||||
TrackStatusIds = trackStatusIds;
|
||||
ReturnTimeSpan = returnTimeSpan;
|
||||
NotifyUsers = notifyUsers;
|
||||
}
|
||||
|
||||
public HashSet<int> GetRuleStatusIds()
|
||||
{
|
||||
return TrackStatusIds.Split(',').Select(int.Parse).ToHashSet();
|
||||
}
|
||||
|
||||
public bool CanHitRule(int trackStatusId)
|
||||
{
|
||||
return GetRuleStatusIds().Contains(trackStatusId);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
|
||||
public interface IWarningSignal
|
||||
{
|
||||
public int OrderId { get; set; }
|
||||
public WarningSignalType Type { get; set; }
|
||||
}
|
||||
|
||||
public enum WarningSignalType
|
||||
{
|
||||
轨迹新增 = 0,
|
||||
|
||||
轨迹删除 = 1,
|
||||
|
||||
轨迹更新 = 2,
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹新增信号
|
||||
/// </summary>
|
||||
public sealed class TrackAddedSignal : IWarningSignal
|
||||
{
|
||||
public WarningSignalType Type { get; set; } = WarningSignalType.轨迹新增;
|
||||
|
||||
public int OrderId { get; set; }
|
||||
|
||||
public string EsId { get; set; } //新增轨迹的esId
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹删除信号
|
||||
/// </summary>
|
||||
public class TrackDeletedSignal : IWarningSignal
|
||||
{
|
||||
public WarningSignalType Type { get; set; } = WarningSignalType.轨迹删除;
|
||||
|
||||
public int OrderId { get; set; }
|
||||
|
||||
public TrackDetailsIndex DeletedTrack { get; set; } //已删除的轨迹
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Signals;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹更新信号
|
||||
/// </summary>
|
||||
public class TrackUpdatedSignal:IWarningSignal
|
||||
{
|
||||
public WarningSignalType Type { get; set; } = WarningSignalType.轨迹更新;
|
||||
|
||||
public int OrderId { get; set; }
|
||||
|
||||
public TrackDetailsIndex BeforeChangeTrack { get; set; } //更改前的轨迹明细
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
|
||||
[SugarTable("t_warning_transport_generate_task", TableDescription = "运输时效预警明细生成任务")]
|
||||
[SugarIndex("IDX_IsClosed_PlanExecutionTime", nameof(IsClosed), OrderByType.Desc, nameof(PlanExecutionTime), OrderByType.Asc)]
|
||||
public sealed class TransportWarningDetailsGenerateTaskEntity : IFullAuditedBasicEntitys, IEntity
|
||||
{
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "OrderId", ColumnDescription = "订单Id")]
|
||||
public int OrderId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "WarningId", ColumnDescription = "预警主体Id")]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "WarningSceneId", ColumnDescription = "运输时效场景Id")]
|
||||
public int WarningSceneId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "WarningSceneRuleItemId", ColumnDescription = "运输时效预警规则项Id")]
|
||||
public int WarningSceneRuleItemId { get; set; } //运输时效预警规则项目Id
|
||||
|
||||
|
||||
[SugarColumn(ColumnName = "StartTrackStatusId", ColumnDescription = "起始轨迹状态Id")]
|
||||
public int StartTrackStatusId { get; set; } //起始轨迹状态Id
|
||||
|
||||
[SugarColumn(ColumnName = "EndTrackStatusId", ColumnDescription = "截止轨迹状态Id")]
|
||||
public int EndTrackStatusId { get; set; } //截止轨迹状态Id
|
||||
|
||||
[SugarColumn(ColumnName = "StartTrackTime", ColumnDescription = "起始轨迹发生时间")]
|
||||
public DateTime StartTrackTime { get; set; } //起始轨迹发生时间
|
||||
|
||||
[SugarColumn(ColumnName = "StartTrackTimeZone", ColumnDescription = "起始轨迹发生时区")]
|
||||
public float StartTrackTimeZone { get; set; } //起始轨迹发生时区
|
||||
|
||||
[SugarColumn(ColumnName = "StartTrackWarningTimeSpan", ColumnDescription = "起始轨迹生成预警时间")]
|
||||
public float StartTrackWarningTimeSpan { get; set; } //起始轨迹生成预警时间 (单位小时)
|
||||
|
||||
[SugarColumn(ColumnName = "PlanExecutionTime", ColumnDescription = "计划执行时间")]
|
||||
public DateTime PlanExecutionTime { get; set; } //计划执行时间 tips:缓存【起始轨迹发生时间】+【起始轨迹生成预警时间】 结果,用于查询时过滤
|
||||
|
||||
|
||||
[SugarColumn(ColumnName = "IsClosed", ColumnDescription = "是否关闭")]
|
||||
public bool IsClosed { get; set; } //是否关闭,执行完成被关闭/手动关闭
|
||||
}
|
||||
@ -0,0 +1,144 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Text;
|
||||
using Nest;
|
||||
using SJZY.Expand.ElasticSearch;
|
||||
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
|
||||
using SJZY.Track.Domain.Consts;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
|
||||
// 运输时效预警明细
|
||||
[ElasticsearchType(RelationName = GlobalConst.TransportWarningDetailsIndex)]
|
||||
public sealed class TransportWarningDetailsIndex : IdBaseIndex
|
||||
{
|
||||
public string IndexName { get; set; }
|
||||
public int WarningId { get; set; }
|
||||
public int WarningSceneId { get; set; }
|
||||
public int WarningSceneRuleItemId { get; set; }
|
||||
public string Version { get; set; } //预警版本号
|
||||
|
||||
public string WarningName { get; set; } //(冗余)预警规则名称,规则主体名称
|
||||
public string WarningRuleDescription { get; set; } // 预警规则描述 (场景+场景规则项目构建)
|
||||
|
||||
public float TransportTimeSpan { get; set; } //时效 (单位小时),用于计算状态
|
||||
public float StartTrackWarningTimeSpan { get; set; } //起始轨迹生成预警时间 (单位小时),用于计算状态
|
||||
//public string NotifyModes { get; set; } //通知方式,多个方式(,)分割 eg: 1,2
|
||||
public string NotifyUsers { get; set; } //通知人Json eg: [{"UserId":1,"UserName":"张三"},{"UserId":2,"UserName":"李四"}]
|
||||
|
||||
//订单信息
|
||||
public int SubSystemId { get; set; } //(冗余)子系统Id
|
||||
public string SubSystemName { get; set; } //(冗余)子系统名称
|
||||
public int CustomId { get; set; } //(冗余)客户Id
|
||||
public string CustomName { get; set; } //冗余 客户简称(用于查询条件)
|
||||
public int OrderId { get; set; }
|
||||
public string OrderNo { get; set; } //订单号
|
||||
public int OrderType { get; set; } //(冗余)订单类型
|
||||
public string OrderTypeName { get; set; } //(冗余)订单类型名称
|
||||
|
||||
//轨迹信息-起始(更新用例:新增轨迹时,场景/规则项变更并且重新命中)
|
||||
public int StartTrackStatusId { get; set; } //起始轨迹状态Id
|
||||
public string StartTrackStatus { get; set; } //(冗余)起始轨迹状态名称
|
||||
public int StartTrackContentId { get; set; } //起始轨迹内容Id
|
||||
public string StartTrackContent { get; set; } //(冗余)起始轨迹内容名称
|
||||
public DateTime StartTrackTime { get; set; } //起始轨迹发生时间
|
||||
public float StartTrackTimeZone { get; set; } //起始轨迹发生时区
|
||||
|
||||
//轨迹信息-截止(更新用例:新增轨迹时)
|
||||
public int EndTrackStatusId { get; set; } //截止轨迹状态Id
|
||||
public string EndTrackStatus { get; set; } //(冗余)截止轨迹状态名称
|
||||
public int? EndTrackContentId { get; set; } //截止轨迹内容Id
|
||||
public string? EndTrackContent { get; set; } //(冗余)截止轨迹内容名称
|
||||
public DateTime? EndTrackTime { get; set; } //截止轨迹发生时间
|
||||
public float? EndTrackTimeZone { get; set; } //截止轨迹发生时区
|
||||
|
||||
// // 实时属性 todo:后面拆出vo
|
||||
// public int LatestTrackContentId { get; set; } //最新轨迹内容Id
|
||||
// public string LatestTrackContent { get; set; } //(冗余)最新轨迹内容名称
|
||||
// public DateTime LatestTrackTime { get; set; } //最新轨迹发生时间
|
||||
// public float LatestTrackTimeZone { get; set; } //最新轨迹发生时区
|
||||
// public string LatestTrackPlace { get; set; } //最新轨迹发生地
|
||||
|
||||
|
||||
//计算属性
|
||||
public long CumulativeTimeSpan { get; set; } //累计运输时间:当前时间-起始轨迹状态中的最早轨迹发生时间(利用 轨迹信息-起始 完成计算)单位(毫秒)
|
||||
public int Status { get; set; } //1:即将超时 2:已超时 3:已完成 4:超时完成 5:已关闭,初始为【即将超时】
|
||||
|
||||
//审计属性
|
||||
public DateTime CreateTime { get; set; } //预警创建时间
|
||||
|
||||
private static readonly ImmutableHashSet<int> CompletedStatus = ImmutableHashSet.Create(3, 4, 5);
|
||||
|
||||
// todo:计算并设置状态,后续维护到vo当中
|
||||
public int CalcStatus()
|
||||
{
|
||||
// 结束态无需计算,直接返回
|
||||
if (CompletedStatus.Contains(Status)) return Status;
|
||||
|
||||
//时效
|
||||
var transportTimeSpan = TimeSpan.FromHours(TransportTimeSpan); //小时
|
||||
//累计运输时间
|
||||
var cumulativeTimeSpan = TimeSpan.FromMilliseconds(CumulativeTimeSpan); //毫秒
|
||||
//预警时效(预警发出的时间对比于最早轨迹状态时间的跨度)
|
||||
var startTrackWarningTimeSpan = TimeSpan.FromHours(StartTrackWarningTimeSpan); //小时
|
||||
|
||||
//时效>累计运输时间>=预警时效 状态调整为【即将超时】
|
||||
if (transportTimeSpan > cumulativeTimeSpan && cumulativeTimeSpan >= startTrackWarningTimeSpan)
|
||||
return Status = 1;
|
||||
|
||||
//时效<累计运输时间 状态调整为【已超时】
|
||||
if (transportTimeSpan < cumulativeTimeSpan)
|
||||
return Status = 2;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
// 预警规则描述,创建预警明细,更新场景(需要重新匹配),更新规则项目(需要重新匹配),更新规则区域名称
|
||||
// todo:缺失更新规则区域名称目前不被感知,出现预警明细和对于的规则区域名称不一致
|
||||
// todo:转化为bo的使用
|
||||
public string GetWarningRuleDescription(TransportWarningSceneEntity scene, TransportWarningSceneRuleItemEntity ruleItem, RuleAreaEntity? ruleArea)
|
||||
{
|
||||
var res = new StringBuilder("{");
|
||||
// 起始轨迹状态-截止轨迹状态
|
||||
res.Append($"{StartTrackStatus}-{EndTrackStatus}");
|
||||
|
||||
// 货物类型 (普货/危险品/...)
|
||||
if (!string.IsNullOrWhiteSpace(scene.CargoType))
|
||||
res.Append($",{scene.CargoType}");
|
||||
// 月份 (1/3/5/...)
|
||||
if (!string.IsNullOrWhiteSpace(scene.Months))
|
||||
res.Append($",{scene.Months}");
|
||||
// 区域名称 (美国xxx区域)
|
||||
if (ruleArea != null)
|
||||
res.Append($",{ruleArea.Name}");
|
||||
// 是否中转(中转/直飞)
|
||||
if (scene.IsTransit != null)
|
||||
res.Append($",{(scene.IsTransit ?? false ? "中转" : "直飞")}");
|
||||
// 出发港(xxx港)
|
||||
if (!string.IsNullOrWhiteSpace(scene.LeavePort))
|
||||
res.Append($",{scene.LeavePort}");
|
||||
// 产品代码(xxx)
|
||||
if (!string.IsNullOrWhiteSpace(scene.ProductCode))
|
||||
res.Append($",{scene.ProductCode}");
|
||||
|
||||
// 规则配置信息
|
||||
res.Append($",生成预警时间{ruleItem.StartTrackWarningTimeSpan}小时" +
|
||||
$",提醒时效{ruleItem.TransportTimeSpan}}}");
|
||||
|
||||
return res.ToString();
|
||||
}
|
||||
|
||||
public DateTime GetUtc0StartTrackTime()
|
||||
{
|
||||
return Math.Abs(StartTrackTimeZone - GlobalConst.NoneTrackTimeZone) < 0.1f
|
||||
? StartTrackTime
|
||||
: StartTrackTime.Subtract(TimeSpan.FromHours(StartTrackTimeZone));
|
||||
}
|
||||
|
||||
public DateTime? GetUtc0EndTrackTime()
|
||||
{
|
||||
if (EndTrackTime == null || EndTrackTimeZone == null) return null;
|
||||
return Math.Abs(EndTrackTimeZone.Value - GlobalConst.NoneTrackTimeZone) < 0.1f
|
||||
? EndTrackTime
|
||||
: EndTrackTime.Value.Subtract(TimeSpan.FromHours(EndTrackTimeZone.Value));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
|
||||
// 运输时效场景
|
||||
[SugarTable("t_warning_transport_scene", TableDescription = "运输时效规则场景")]
|
||||
public sealed class TransportWarningSceneEntity : IFullAuditedBasicEntitys, IEntity
|
||||
{
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "WarningId", ColumnDescription = "预警规则id")]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "IsTransit", ColumnDescription = "是否中转")]
|
||||
public bool? IsTransit { get; set; } //是否中转
|
||||
|
||||
[SugarColumn(ColumnName = "CargoType", ColumnDescription = "货物类型")]
|
||||
public string? CargoType { get; set; } //货物类型,
|
||||
|
||||
[SugarColumn(ColumnName = "LeavePort", ColumnDescription = "起运港口")]
|
||||
public string? LeavePort { get; set; } //起运港口
|
||||
|
||||
[SugarColumn(ColumnName = "ProductCode", ColumnDescription = "产品编码")]
|
||||
public string? ProductCode { get; set; } //产品编码
|
||||
|
||||
[SugarColumn(ColumnName = "Months", ColumnDescription = "月份")]
|
||||
public string? Months { get; set; } //月份, 1/2/3
|
||||
|
||||
[SugarColumn(ColumnName = "AreaId", ColumnDescription = "区域id")]
|
||||
public int? AreaId { get; set; } //区域Id,单分区
|
||||
|
||||
public TransportWarningSceneEntity()
|
||||
{
|
||||
}
|
||||
|
||||
public TransportWarningSceneEntity(int id, int warningId, string? cargoType, string? months, int? areaId, bool? isTransit, string? leavePort, string? productCode)
|
||||
{
|
||||
Id = id;
|
||||
WarningId = warningId;
|
||||
CargoType = cargoType;
|
||||
Months = months;
|
||||
AreaId = areaId;
|
||||
IsTransit = isTransit;
|
||||
LeavePort = leavePort;
|
||||
ProductCode = productCode;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
|
||||
// 运输时效场景规则项
|
||||
[SugarTable("t_warning_transport_scene_rule_item", TableDescription = "运输时效规则场景规则项")]
|
||||
public sealed class TransportWarningSceneRuleItemEntity : IFullAuditedBasicEntitys, IEntity
|
||||
{
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "WarningId", ColumnDescription = "预警规则id")]
|
||||
public int WarningId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "TransportWarningSceneId", ColumnDescription = "运输场景id")]
|
||||
public int TransportWarningSceneId { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "StartTrackStatusId", ColumnDescription = "起始轨迹状态Id")]
|
||||
public int StartTrackStatusId { get; set; } //起始轨迹状态Id,tips:用于匹配轨迹
|
||||
|
||||
[SugarColumn(ColumnName = "EndTrackStatusId", ColumnDescription = "截止轨迹状态Id")]
|
||||
public int EndTrackStatusId { get; set; } //截止轨迹状态Id, tips:用于验证预警明细是否可以产生,预警通知是否可以进行
|
||||
|
||||
[SugarColumn(ColumnName = "TransportTimeSpan", ColumnDescription = "时效 (单位小时)")]
|
||||
public float TransportTimeSpan { get; set; } //时效 (单位小时)
|
||||
|
||||
[SugarColumn(ColumnName = "StartTrackWarningTimeSpan", ColumnDescription = "起始轨迹生成预警时间 (单位小时)")]
|
||||
public float StartTrackWarningTimeSpan { get; set; } //起始轨迹生成预警时间 (单位小时)
|
||||
|
||||
// [SugarColumn(ColumnName = "NotifyModes", ColumnDescription = "通知方式,多个方式(,)分割 eg: 1,2")]
|
||||
// public string NotifyModes { get; set; } //通知方式,多个方式(,)分割 eg: 1,2
|
||||
|
||||
[SugarColumn(ColumnName = "NotifyUsers", ColumnDescription = "通知人Json eg: [{\"UserId\":1,\"UserName\":\"张三\"},{\"UserId\":2,\"UserName\":\"李四\"}]")]
|
||||
public string NotifyUsers { get; set; } //通知人Json eg: [{"UserId":1,"UserName":"张三"},{"UserId":2,"UserName":"李四"}]
|
||||
|
||||
public TransportWarningSceneRuleItemEntity()
|
||||
{
|
||||
}
|
||||
|
||||
public TransportWarningSceneRuleItemEntity(int id, int warningId, int transportWarningSceneId, int startTrackStatusId, int endTrackStatusId, float transportTimeSpan, float startTrackWarningTimeSpan, string notifyUsers)
|
||||
{
|
||||
Id = id;
|
||||
WarningId = warningId;
|
||||
TransportWarningSceneId = transportWarningSceneId;
|
||||
StartTrackStatusId = startTrackStatusId;
|
||||
EndTrackStatusId = endTrackStatusId;
|
||||
TransportTimeSpan = transportTimeSpan;
|
||||
StartTrackWarningTimeSpan = startTrackWarningTimeSpan;
|
||||
NotifyUsers = notifyUsers;
|
||||
}
|
||||
|
||||
public bool CanHitRule(int trackStatusId, HashSet<int> trackStatusIds)
|
||||
{
|
||||
return trackStatusId == StartTrackStatusId //命中起始轨迹状态
|
||||
&& !trackStatusIds.Contains(EndTrackStatusId); //缺失截止轨迹状态
|
||||
}
|
||||
|
||||
// 重新命中,用于规则扫描
|
||||
public bool CanReHit(HashSet<int> trackStatusIds)
|
||||
{
|
||||
return trackStatusIds.Contains(StartTrackStatusId) //存在起始
|
||||
&& !trackStatusIds.Contains(EndTrackStatusId); //不存在截止
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
|
||||
[SugarTable("t_warning_notify_task", TableDescription = "预警通知任务")]
|
||||
public sealed class WarningNotifyTaskEntity : IFullAuditedBasicEntitys, IAggregateRoot
|
||||
{
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "OrderId", ColumnDescription = "订单Id")]
|
||||
public int OrderId { get; set; } //(冗余)订单id
|
||||
|
||||
[SugarColumn(ColumnName = "WarningId", ColumnDescription = "预警主体Id")]
|
||||
public int WarningId { get; set; } // 预警Id
|
||||
|
||||
[SugarColumn(ColumnName = "WarningRuleId", ColumnDescription = "预警规则Id")]
|
||||
public int WarningRuleId { get; set; } // 预警规则项目Id
|
||||
|
||||
[SugarColumn(ColumnName = "WarningDetailsId", ColumnDescription = "预警明细Id")]
|
||||
public string WarningDetailsId { get; set; } //预警明细id
|
||||
|
||||
[SugarColumn(ColumnName = "AuxiliaryId", ColumnDescription = "辅助id,用于过滤匹配")]
|
||||
public string? AuxiliaryId { get; set; } //辅助标识,用于增强匹配(例如运输时效预警有会有不同场景,可以通过这个字段完成匹配)
|
||||
|
||||
[SugarColumn(ColumnName = "WarningType", ColumnDescription = "预警类型,1:运输时效,2:回传时效,3:完整预警")]
|
||||
public int WarningType { get; set; } // 预警类型,1:运输时效,2:回传时效,3:完整预警
|
||||
|
||||
// [SugarColumn(ColumnName = "NotifyModes", ColumnDescription = "通知方式,多个方式(,)分割 eg: 1,2")]
|
||||
// public string NotifyModes { get; set; } //通知方式,多个方式(,)分割 eg: 1,2
|
||||
|
||||
[SugarColumn(ColumnName = "NotifyUsers", ColumnDescription = "通知人Json eg: [{\"UserId\":1,\"UserName\":\"张三\"},{\"UserId\":2,\"UserName\":\"李四\"}]")]
|
||||
public string NotifyUsers { get; set; } //通知人Json eg: [{"UserId":1,"UserName":"张三"},{"UserId":2,"UserName":"李四"}]
|
||||
|
||||
|
||||
[SugarColumn(ColumnName = "Tags", ColumnDescription = "标签集合(,分割)")]
|
||||
public string? Tags { get; set; } // 标签(加急?)
|
||||
|
||||
[SugarColumn(ColumnName = "IsClosed", ColumnDescription = "是否关闭")]
|
||||
public bool IsClosed { get; set; } //是否已经关闭,使用时过滤已关闭的通知任务
|
||||
|
||||
public WarningNotifyTaskEntity()
|
||||
{
|
||||
}
|
||||
|
||||
public WarningNotifyTaskEntity(int orderId, int warningId, int warningRuleId, string warningDetailsId, int warningType, string notifyUsers, string? tags = null)
|
||||
{
|
||||
OrderId = orderId;
|
||||
WarningId = warningId;
|
||||
WarningRuleId = warningRuleId;
|
||||
WarningDetailsId = warningDetailsId;
|
||||
WarningType = warningType;
|
||||
NotifyUsers = notifyUsers;
|
||||
Tags = tags;
|
||||
CreateTime = DateTime.Now;
|
||||
IsClosed = false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
|
||||
// 预警规则主体
|
||||
[SugarTable("t_warning_0", TableDescription = "预警规则主体(用于将来替换t_warning)")]
|
||||
public sealed class WarningRuleEntity : IFullAuditedBasicEntitys, IAggregateRoot
|
||||
{
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "SubSystemId", ColumnDescription = "子系统id")]
|
||||
public int SubSystemId { get; set; } //子系统id
|
||||
|
||||
[SugarColumn(ColumnName = "CustomId", ColumnDescription = "客户id")]
|
||||
public int CustomId { get; set; } //客户id
|
||||
|
||||
// [SugarColumn(ColumnName = "CustomName", ColumnDescription = "客户名称")]
|
||||
// public string CustomName { get; set; } //冗余客户简称,用于查询
|
||||
|
||||
[SugarColumn(ColumnName = "Name", ColumnDescription = "预警规则名称")]
|
||||
public string Name { get; set; } //预警规则名称
|
||||
|
||||
[SugarColumn(ColumnName = "IsEnabled", ColumnDescription = "是否启用")]
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
[SugarColumn(ColumnName = "WarningType", ColumnDescription = "预警类型,1:运输时效,2:回传时效,3:完整预警")]
|
||||
public int WarningType { get; set; } //预警类型,1:运输时效,2:回传时效,3:完整预警
|
||||
|
||||
[SugarColumn(ColumnName = "Version", ColumnDescription = "规则版本,用于标识规则产物(如预警信息)")]
|
||||
public string Version { get; set; } //规则版本,用于标识规则产物(如预警信息)
|
||||
|
||||
|
||||
public WarningRuleEntity()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public WarningRuleEntity(int id, string name, int subSystemId, int customId, bool isEnabled, int warningType, string version)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
SubSystemId = subSystemId;
|
||||
CustomId = customId;
|
||||
IsEnabled = isEnabled;
|
||||
WarningType = warningType;
|
||||
Version = version;
|
||||
}
|
||||
|
||||
public WarningRuleEntity(int id, string name, int subSystemId, int customId, bool isEnabled, int warningType)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
SubSystemId = subSystemId;
|
||||
CustomId = customId;
|
||||
IsEnabled = isEnabled;
|
||||
WarningType = warningType;
|
||||
Version = VersionGenerate.GenVersion();
|
||||
}
|
||||
|
||||
// 子系统+客户id确定命中规则主体
|
||||
public bool CanHitRule(int subSystemId, int customId)
|
||||
{
|
||||
return SubSystemId == subSystemId && CustomId == customId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Warning;
|
||||
|
||||
public class GetPageCompleteWarningDetailsInputVO : PageInfoInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int? SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号,多个订单号(,分割)
|
||||
/// </summary>
|
||||
public string? OrderNos { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public int? OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// 1:待处理,2:已处理,3:已关闭
|
||||
/// </summary>
|
||||
public int? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int? CustomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 缺失轨迹状态id
|
||||
/// </summary>
|
||||
public int? MissingTrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象id
|
||||
/// </summary>
|
||||
public int? NotifyUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警创建时间开始
|
||||
/// </summary>
|
||||
public DateTime? WarningCreateTimeStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警创建时间截止
|
||||
/// </summary>
|
||||
public DateTime? WarningCreateTimeEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警处理时间开始
|
||||
/// </summary>
|
||||
public DateTime? WarningHandleTimeStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警处理时间截止
|
||||
/// </summary>
|
||||
public DateTime? WarningHandleTimeEnd { get; set; }
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Warning;
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取回传预警明细输入
|
||||
/// </summary>
|
||||
public class GetPageReturnWarningDetailsInputVO : PageInfoInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int? SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号,多个订单号(,分割)
|
||||
/// </summary>
|
||||
public string? OrderNos { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public int? OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// 1:人工介入 2:重试中 3:推送完成 4:已关闭
|
||||
/// </summary>
|
||||
public int? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int? CustomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹状态id
|
||||
/// </summary>
|
||||
public int? TrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹内容id
|
||||
/// </summary>
|
||||
public int? TrackContentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否有Kpi考核 (传null为查全部)
|
||||
/// </summary>
|
||||
public bool? IsKpi { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象用户id
|
||||
/// </summary>
|
||||
public int? NotifyUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹发生时间开始
|
||||
/// </summary>
|
||||
public DateTime? TrackTimeStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹发生时间截止
|
||||
/// </summary>
|
||||
public DateTime? TrackTimeEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹创建时间开始
|
||||
/// </summary>
|
||||
public DateTime? TrackCreateTimeStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹创建时间截止
|
||||
/// </summary>
|
||||
public DateTime? TrackCreateTimeEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹回传时间开始
|
||||
/// </summary>
|
||||
public DateTime? TrackReturnTimeStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹回传时间截止
|
||||
/// </summary>
|
||||
public DateTime? TrackReturnTimeEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警创建时间开始
|
||||
/// </summary>
|
||||
public DateTime? WarningCreateTimeStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警创建时间截止
|
||||
/// </summary>
|
||||
public DateTime? WarningCreateTimeEnd { get; set; }
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
namespace SJZY.Track.Domain.Dtos.Warning;
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取运输预警明细
|
||||
/// </summary>
|
||||
public class GetPageTransportWarningDetailsInputVO : PageInfoInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int? SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号,多个订单号(,分割)
|
||||
/// </summary>
|
||||
public string? OrderNos { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public int? OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public int? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户Id
|
||||
/// </summary>
|
||||
public int? CustomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 预警名称
|
||||
/// </summary>
|
||||
public string? WarningName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知对象用户Id
|
||||
/// </summary>
|
||||
public int? NotifyUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间开始
|
||||
/// </summary>
|
||||
public DateTime? CreateTimeStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间截止
|
||||
/// </summary>
|
||||
public DateTime? CreateTimeEnd { get; set; }
|
||||
}
|
||||
8
src/SJZY.Track.Domain/Enums/CompleteWarningStatus.cs
Normal file
8
src/SJZY.Track.Domain/Enums/CompleteWarningStatus.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace SJZY.Track.Domain.Enums;
|
||||
|
||||
public enum CompleteWarningStatus
|
||||
{
|
||||
待处理 = 1,
|
||||
已处理 = 2,
|
||||
已关闭 = 3
|
||||
}
|
||||
9
src/SJZY.Track.Domain/Enums/ReturnWarningStatus.cs
Normal file
9
src/SJZY.Track.Domain/Enums/ReturnWarningStatus.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace SJZY.Track.Domain.Enums;
|
||||
|
||||
public enum ReturnWarningStatus
|
||||
{
|
||||
人工介入 = 1,
|
||||
重试中 = 2,
|
||||
推送完成 = 3,
|
||||
已关闭 = 4
|
||||
}
|
||||
10
src/SJZY.Track.Domain/Enums/TransportWarningStatus.cs
Normal file
10
src/SJZY.Track.Domain/Enums/TransportWarningStatus.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace SJZY.Track.Domain.Enums;
|
||||
|
||||
public enum TransportWarningStatus
|
||||
{
|
||||
即将超时 = 1,
|
||||
已超时 = 2,
|
||||
已完成 = 3,
|
||||
超时完成 = 4,
|
||||
已关闭 = 5,
|
||||
}
|
||||
120
src/SJZY.Track.Domain/Extensions/CollectionExtensions.cs
Normal file
120
src/SJZY.Track.Domain/Extensions/CollectionExtensions.cs
Normal file
@ -0,0 +1,120 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Nest;
|
||||
using SJZY.Expand.ElasticSearch;
|
||||
|
||||
namespace SJZY.Track.Domain.Extensions;
|
||||
|
||||
public class ListWrapperFactory
|
||||
{
|
||||
public static ListWrapper<TInput, Func<QueryContainerDescriptor<TIndex>, QueryContainer>> CreateListWrapper<TIndex, TInput>(TInput input)
|
||||
where TIndex : IdBaseIndex
|
||||
{
|
||||
return new ListWrapper<TInput, Func<QueryContainerDescriptor<TIndex>, QueryContainer>>(new (), input);
|
||||
}
|
||||
}
|
||||
public class ListWrapper<TInput, TItem> : List<TItem>
|
||||
{
|
||||
public List<TItem> List { get; set; }
|
||||
public TInput Input { get; set; }
|
||||
|
||||
public ListWrapper(List<TItem> list, TInput input)
|
||||
{
|
||||
List = list;
|
||||
Input = input;
|
||||
}
|
||||
|
||||
public void AddIf(Predicate<TInput> predicate,TItem item)
|
||||
{
|
||||
if(predicate(Input))
|
||||
List.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CollectionExtensions
|
||||
{
|
||||
private static readonly ConcurrentDictionary<Type, object?> DefaultValueCache = new();
|
||||
|
||||
public static void AddNotEmpty<TInput, TItem>(this ICollection<TItem> list, TInput input, TItem item)
|
||||
{
|
||||
if (input is null) return;
|
||||
|
||||
var t = typeof(TInput);
|
||||
if (t == typeof(string))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(input as string))
|
||||
list.Add(item);
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是Nullable类型,则获取其UnderlyingType
|
||||
if (t.Name.StartsWith("Nullable"))
|
||||
{
|
||||
t = Nullable.GetUnderlyingType(t)!;
|
||||
// 判断是否为数值类型
|
||||
if (t.IsNumericType())
|
||||
{
|
||||
// 动态转换为数值比较
|
||||
dynamic val = Convert.ChangeType(input, t);
|
||||
dynamic defaultVal = Activator.CreateInstance(t);
|
||||
|
||||
// 当值为0时视为默认值
|
||||
if (val != defaultVal)
|
||||
{
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取类型对应的默认值(带缓存)
|
||||
var defaultValue = (TInput)DefaultValueCache.GetOrAdd(t, _ => default(TInput))!;
|
||||
|
||||
// 使用 EqualityComparer 避免装箱拆箱
|
||||
if (!EqualityComparer<TInput>.Default.Equals(input, defaultValue))
|
||||
{
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddNotEmpty<TInput, TItem>(this ICollection<TItem> list, TInput input, Func<TInput, TItem> factory)
|
||||
{
|
||||
AddNotEmpty(list, input, factory(input));
|
||||
}
|
||||
|
||||
|
||||
public static void AddIf<TInput, TItem>(this ICollection<TItem> list, TInput input, Func<TInput, bool> predicate, TItem item)
|
||||
{
|
||||
if (predicate(input))
|
||||
list.Add(item);
|
||||
}
|
||||
|
||||
public static void AddIf<TInput, TItem>(this ICollection<TItem> list, TInput input, Func<TInput, bool> predicate, Func<TInput, TItem> factory)
|
||||
{
|
||||
if (predicate(input))
|
||||
list.Add(factory(input));
|
||||
}
|
||||
|
||||
|
||||
private static bool IsNumericType(this Type? type)
|
||||
{
|
||||
if (type == null) return false;
|
||||
|
||||
return Type.GetTypeCode(type) switch
|
||||
{
|
||||
TypeCode.Byte or
|
||||
TypeCode.SByte or
|
||||
TypeCode.UInt16 or
|
||||
TypeCode.UInt32 or
|
||||
TypeCode.UInt64 or
|
||||
TypeCode.Int16 or
|
||||
TypeCode.Int32 or
|
||||
TypeCode.Int64 or
|
||||
TypeCode.Decimal or
|
||||
TypeCode.Double or
|
||||
TypeCode.Single => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
34
src/SJZY.Track.Domain/Extensions/PollyHelper.cs
Normal file
34
src/SJZY.Track.Domain/Extensions/PollyHelper.cs
Normal file
@ -0,0 +1,34 @@
|
||||
namespace SJZY.Track.Domain.Extensions;
|
||||
|
||||
public static class PollyHelper
|
||||
{
|
||||
public static async Task<TResult> RetryPollyExecAsync<TResult>(Func<Task<TResult>> func, Func<TResult, bool> successValidator, int maxRetries = 3, bool throwOtherException = true)
|
||||
{
|
||||
TResult result = default!;
|
||||
var retryCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
while (retryCount < maxRetries)
|
||||
{
|
||||
result = await func();
|
||||
|
||||
// 如果认为成功则直返回值
|
||||
if (successValidator(result))
|
||||
return result;
|
||||
|
||||
// 超过最大重试次数,抛出异常
|
||||
retryCount++;
|
||||
if (retryCount >= maxRetries)
|
||||
throw new InvalidOperationException($"操作失败超过最大重试次数{maxRetries}次,原因:{result}。");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (throwOtherException)
|
||||
throw;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace SJZY.Track.Application.Helpers;
|
||||
namespace SJZY.Track.Domain.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 针对 Text.Json 的一些辅助方法
|
||||
@ -178,4 +177,11 @@ public static class TextJsonHelper
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool EqJsonStringField(string json1, string json2, string fieldName)
|
||||
{
|
||||
var aJsonElement = JsonDocument.Parse(json1);
|
||||
var bJsonElement = JsonDocument.Parse(json2);
|
||||
return EqByJsonElementField(aJsonElement, bJsonElement, fieldName);
|
||||
}
|
||||
}
|
||||
15
src/SJZY.Track.Domain/Extensions/VersionGenerate.cs
Normal file
15
src/SJZY.Track.Domain/Extensions/VersionGenerate.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace SJZY.Track.Domain.Extensions;
|
||||
|
||||
public static class VersionGenerate
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成版本号 guid+日期
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GenVersion()
|
||||
{
|
||||
var guid = Guid.NewGuid().ToString("N");
|
||||
var date = DateTime.Now.ToString("s");
|
||||
return $"{guid}-{date}";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
using SJZY.Track.Domain.VEntities;
|
||||
|
||||
namespace SJZY.Track.Domain.Queries;
|
||||
|
||||
public interface IVExternalSubjectQueries : IBasicQuery<VExternalSubjectEntity>
|
||||
{
|
||||
}
|
||||
@ -4,7 +4,7 @@
|
||||
/// 外部主体
|
||||
/// </summary>
|
||||
[SugarTable("v_external_subject")]
|
||||
public class VExternalSubjectEntity : IFullAuditedBasicEntitys
|
||||
public class VExternalSubjectEntity : IFullAuditedBasicEntitys,IEntity
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
using SJZY.Track.Domain.Queries;
|
||||
using SJZY.Track.Domain.VEntities;
|
||||
|
||||
namespace SJZY.Track.Repository.Queries;
|
||||
|
||||
public class VExternalSubjectQueries : BasicQuery<VExternalSubjectEntity>, IVExternalSubjectQueries, ITransientDependency
|
||||
{
|
||||
}
|
||||
@ -62,7 +62,7 @@ public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, I
|
||||
return dict;
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, string>> GetTrackOrderTypeDict()
|
||||
public async Task<Dictionary<string, string>> GetTrackOrderTypeDictAsync()
|
||||
{
|
||||
const string key = "TrackOrderType";
|
||||
var orderTypes = await _memoryCache.GetOrCreateAsync(key, async (entry) =>
|
||||
|
||||
@ -61,6 +61,44 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract<TrackDetail
|
||||
return r.ToIdList();
|
||||
}
|
||||
|
||||
public async Task<List<TrackDetailsIndex>> GetLatestListAsync(HashSet<int> eventOrderIds)
|
||||
{
|
||||
var r = await Context.SearchAsync<TrackDetailsIndex>(x => x
|
||||
.Index(GlobalConst.TrackDetailsIndex)
|
||||
.Source()
|
||||
.Query(q => q
|
||||
.Bool(b => b
|
||||
.Must(
|
||||
mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(eventOrderIds))
|
||||
)
|
||||
)
|
||||
)
|
||||
.Size(SafelyLimit)
|
||||
.Aggregations(a => a
|
||||
.Terms("orders", t => t
|
||||
.Field(f => f.OrderId)
|
||||
.Aggregations(aa => aa
|
||||
.TopHits("latest_track", th => th
|
||||
.Size(1)
|
||||
.Sort(so => so
|
||||
.Field(f => f.ZeroTrackTime, SortOrder.Descending)
|
||||
)
|
||||
.Source()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"最新轨迹查询失败,orderIds:[{eventOrderIds.JoinAsString(", ")}],原因:{r.DebugInformation}。");
|
||||
}
|
||||
|
||||
return r.Documents.ToList();
|
||||
}
|
||||
|
||||
public async Task<List<TrackDetailsIndex>> GetLatestListAsync(int[] orderIds, List<string> trackCodes)
|
||||
{
|
||||
var excludeTrackCodes = trackCodes.ToList();
|
||||
|
||||
@ -0,0 +1,707 @@
|
||||
using Nest;
|
||||
using SJZY.Expand.ElasticSearch.Services;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Complete;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
using SJZY.Track.Domain.Consts;
|
||||
using SJZY.Track.Domain.Dtos.Warning;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
|
||||
namespace SJZY.Track.Repository.Repositories;
|
||||
|
||||
public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransientDependency
|
||||
{
|
||||
private readonly IElasticClient _client;
|
||||
|
||||
public WarningDetailsEsRepository(ConnectionFactory connection)
|
||||
{
|
||||
_client = connection.GetContext(typeof(TransportWarningDetailsIndex));
|
||||
}
|
||||
|
||||
#region 运输时效
|
||||
|
||||
public async Task<UnifyPageResultDto<TransportWarningDetailsIndex>> GetPageTransportWarningDetailsAsync(GetPageTransportWarningDetailsInputVO input)
|
||||
{
|
||||
var musts = ListWrapperFactory.CreateListWrapper<TransportWarningDetailsIndex, GetPageTransportWarningDetailsInputVO>(input);
|
||||
|
||||
var orderNos = input.OrderNos?.Split(',');
|
||||
|
||||
// 精确匹配
|
||||
musts.AddIf(x => x.CustomId > 0, c => c.Term(f => f.CustomId, input.CustomId));
|
||||
musts.AddIf(_ => orderNos?.Length > 0, c => c.Terms(f => f.Field(d => d.OrderNo.Suffix("keyword")).Terms(orderNos)));
|
||||
musts.AddIf(x => x.OrderType > 0, c => c.Term(f => f.OrderType, input.OrderType));
|
||||
musts.AddIf(x => x.Status > 0, c => c.Term(f => f.Status, input.Status));
|
||||
musts.AddIf(x => x.CustomId > 0, c => c.Term(f => f.CustomId, input.CustomId));
|
||||
musts.AddIf(x => !string.IsNullOrWhiteSpace(x.WarningName), c => c.Term(f => f.WarningName, input.WarningName));
|
||||
musts.AddIf(x => x.CreateTimeStart.HasValue, c => c.DateRange(r => r.Field(f => f.CreateTime).GreaterThanOrEquals(input.CreateTimeStart)));
|
||||
musts.AddIf(x => x.CreateTimeEnd.HasValue, c => c.DateRange(r => r.Field(f => f.CreateTime).LessThanOrEquals(input.CreateTimeEnd)));
|
||||
|
||||
// 模糊匹配userId
|
||||
musts.AddIf(x => x.NotifyUserId.HasValue, c => c.Match(f => f.Field(d => d.NotifyUsers).Query(input.NotifyUserId.ToString())));
|
||||
|
||||
var resp = await _client.SearchAsync<TransportWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.TransportWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.From((input.PageIndex - 1) * input.PageSize)
|
||||
.Size(input.PageSize));
|
||||
|
||||
return new UnifyPageResultDto<TransportWarningDetailsIndex>(resp.ToIdList(), input.PageIndex, input.PageSize, (int) resp.Total);
|
||||
}
|
||||
|
||||
public async Task<List<TransportWarningDetailsIndex>> GetTransportWarningDetailsAsync(HashSet<int> ruleItemIds, HashSet<int> status)
|
||||
{
|
||||
var r = await _client.SearchAsync<TransportWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.TransportWarningDetailsIndex)
|
||||
.Query(q => q
|
||||
.Bool(b => b
|
||||
.Must(
|
||||
mu => mu.Terms(t => t.Field(f => f.WarningSceneRuleItemId).Terms(ruleItemIds)),
|
||||
mu => mu.Terms(t => t.Field(f => f.Status).Terms(status)))
|
||||
)));
|
||||
|
||||
return r.Documents.ToList();
|
||||
}
|
||||
|
||||
public async Task UpdateTransportWarningDetailsAsync(TransportWarningDetailsIndex detail)
|
||||
{
|
||||
var r = await _client.UpdateAsync<TransportWarningDetailsIndex, object>(detail.Id,
|
||||
u => u.Index(detail.IndexName)
|
||||
.Doc(new
|
||||
{
|
||||
detail.WarningId,
|
||||
detail.WarningSceneId,
|
||||
detail.WarningSceneRuleItemId,
|
||||
detail.Version,
|
||||
detail.WarningName,
|
||||
detail.WarningRuleDescription,
|
||||
detail.TransportTimeSpan,
|
||||
detail.StartTrackWarningTimeSpan,
|
||||
//detail.NotifyModes,
|
||||
detail.NotifyUsers,
|
||||
detail.SubSystemId,
|
||||
detail.CustomId,
|
||||
detail.CustomName,
|
||||
detail.OrderId,
|
||||
detail.OrderNo,
|
||||
detail.OrderType,
|
||||
detail.StartTrackStatusId,
|
||||
detail.StartTrackContentId,
|
||||
detail.StartTrackTime,
|
||||
detail.StartTrackTimeZone,
|
||||
detail.EndTrackStatusId,
|
||||
detail.EndTrackContentId,
|
||||
detail.EndTrackTime,
|
||||
detail.EndTrackTimeZone,
|
||||
// detail.LatestTrackContentId,
|
||||
// detail.LatestTrackContent,
|
||||
// detail.LatestTrackTime,
|
||||
// detail.LatestTrackTimeZone,
|
||||
// detail.LatestTrackPlace,
|
||||
detail.CumulativeTimeSpan,
|
||||
detail.Status,
|
||||
detail.CreateTime,
|
||||
}));
|
||||
}
|
||||
|
||||
public async Task BulkUpdateTransportWarningDetailsAsync(List<TransportWarningDetailsIndex> details, int maxRetries = 3)
|
||||
{
|
||||
if (details.Count == 0) return;
|
||||
|
||||
//构建批量更新操作描述符
|
||||
var desc = new BulkDescriptor().UpdateMany(details,
|
||||
(u, detail) => u.Id(detail.Id)
|
||||
.Index(detail.IndexName)
|
||||
.Script(s => s.Source(@"
|
||||
ctx._source.WarningId = param.WarningId;
|
||||
ctx._source.WarningSceneId = param.WarningSceneId;
|
||||
ctx._source.WarningSceneRuleItemId = param.WarningSceneRuleItemId;
|
||||
ctx._source.Version = param.Version;
|
||||
ctx._source.WarningName = param.WarningName;
|
||||
ctx._source.WarningRuleDescription = param.WarningRuleDescription;
|
||||
ctx._source.TransportTimeSpan = param.TransportTimeSpan;
|
||||
ctx._source.StartTrackWarningTimeSpa = param.StartTrackWarningTimeSpa;n
|
||||
//ctx._source.NotifyModes = param.NotifyModes;
|
||||
ctx._source.NotifyUsers = param.NotifyUsers;
|
||||
ctx._source.SubSystemId = param.SubSystemId;
|
||||
ctx._source.CustomId = param.CustomId;
|
||||
ctx._source.CustomName = param.CustomName;
|
||||
ctx._source.OrderId = param.OrderId;
|
||||
ctx._source.OrderNo = param.OrderNo;
|
||||
ctx._source.OrderType = param.OrderType;
|
||||
ctx._source.StartTrackStatusId = param.StartTrackStatusId;
|
||||
ctx._source.StartTrackContentId = param.StartTrackContentId;
|
||||
ctx._source.StartTrackTime = param.StartTrackTime;
|
||||
ctx._source.StartTrackTimeZone = param.StartTrackTimeZone;
|
||||
ctx._source.EndTrackStatusId = param.EndTrackStatusId;
|
||||
ctx._source.EndTrackContentId = param.EndTrackContentId;
|
||||
ctx._source.EndTrackTime = param.EndTrackTime;
|
||||
ctx._source.EndTrackTimeZone = param.EndTrackTimeZone;
|
||||
//ctx._source.LatestTrackContentId = param.LatestTrackContentId;
|
||||
//ctx._source.LatestTrackContent = param.LatestTrackContent;
|
||||
//ctx._source.LatestTrackTime = param.LatestTrackTime;
|
||||
//ctx._source.LatestTrackTimeZone = param.LatestTrackTimeZone;
|
||||
//ctx._source.LatestTrackPlace = param.LatestTrackPlace;
|
||||
ctx._source.CumulativeTimeSpan = param.CumulativeTimeSpan;
|
||||
ctx._source.Status = param.Status;
|
||||
ctx._source.CreateTime = param.CreateTime;
|
||||
").Params(p => p
|
||||
.Add("WarningId", detail.WarningId)
|
||||
.Add("WarningSceneId", detail.WarningSceneId)
|
||||
.Add("WarningSceneRuleItemId", detail.WarningSceneRuleItemId)
|
||||
.Add("Version", detail.Version)
|
||||
.Add("WarningName", detail.WarningName)
|
||||
.Add("WarningRuleDescription", detail.WarningRuleDescription)
|
||||
.Add("TransportTimeSpan", detail.TransportTimeSpan)
|
||||
.Add("StartTrackWarningTimeSpan", detail.StartTrackWarningTimeSpan)
|
||||
//.Add("NotifyModes", detail.NotifyModes)
|
||||
.Add("NotifyUsers", detail.NotifyUsers)
|
||||
.Add("SubSystemId", detail.SubSystemId)
|
||||
.Add("CustomId", detail.CustomId)
|
||||
.Add("CustomName", detail.CustomName)
|
||||
.Add("OrderId", detail.OrderId)
|
||||
.Add("OrderNo", detail.OrderNo)
|
||||
.Add("OrderType", detail.OrderType)
|
||||
.Add("StartTrackStatusId", detail.StartTrackStatusId)
|
||||
.Add("StartTrackContentId", detail.StartTrackContentId)
|
||||
.Add("StartTrackTime", detail.StartTrackTime)
|
||||
.Add("StartTrackTimeZone", detail.StartTrackTimeZone)
|
||||
.Add("EndTrackStatusId", detail.EndTrackStatusId)
|
||||
.Add("EndTrackContentId", detail.EndTrackContentId)
|
||||
.Add("EndTrackTime", detail.EndTrackTime)
|
||||
.Add("EndTrackTimeZone", detail.EndTrackTimeZone)
|
||||
// .Add("LatestTrackContentId", detail.LatestTrackContentId)
|
||||
// .Add("LatestTrackContent", detail.LatestTrackContent)
|
||||
// .Add("LatestTrackTime", detail.LatestTrackTime)
|
||||
// .Add("LatestTrackTimeZone", detail.LatestTrackTimeZone)
|
||||
// .Add("LatestTrackPlace", detail.LatestTrackPlace)
|
||||
// .Add("CumulativeTimeSpan", detail.CumulativeTimeSpan)
|
||||
.Add("Status", detail.Status)
|
||||
.Add("CreateTime", detail.CreateTime)
|
||||
)));
|
||||
|
||||
await PollyHelper.RetryPollyExecAsync(() => _client.BulkAsync(desc), response =>
|
||||
{
|
||||
if (response.IsValid) // 认为成功
|
||||
return true;
|
||||
|
||||
if (response.ServerError.Status == 409) //版本冲突认为失败,则重试
|
||||
return false;
|
||||
|
||||
throw new InvalidOperationException($"ES更新失败:{details.Count}条,原因:{response.DebugInformation}。");
|
||||
});
|
||||
}
|
||||
|
||||
public async Task BulkCloseTransportWarningDetailsAsync(HashSet<string> detailIds, int maxRetries = 3)
|
||||
{
|
||||
var status = new HashSet<int>(2)
|
||||
{
|
||||
TransportWarningStatus.即将超时.GetHashCode(),
|
||||
TransportWarningStatus.已超时.GetHashCode()
|
||||
};
|
||||
|
||||
var r = await _client.UpdateByQueryAsync<TransportWarningDetailsIndex>(u =>
|
||||
u.Index(GlobalConst.TransportWarningDetailsIndex)
|
||||
.Query(q => q
|
||||
.Bool(b => b.Must(
|
||||
mu => mu.Terms(t => t.Field(f => f.Status).Terms(status)),
|
||||
mu => mu.Terms(t => t.Field(f => f.Id).Terms(detailIds))
|
||||
)
|
||||
)
|
||||
)
|
||||
.Script(s => s
|
||||
.Source("ctx._source.status = params.status")
|
||||
.Params(p => p.Add("status", (int) TransportWarningStatus.已关闭))
|
||||
)
|
||||
);
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"运输时效预警明细更新失败,detailsIds:{detailIds},原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task BulkCloseTransportWarningDetailsAsync(HashSet<int> ruleItemIds, int maxRetries = 3)
|
||||
{
|
||||
var status = new HashSet<int>(2)
|
||||
{
|
||||
TransportWarningStatus.即将超时.GetHashCode(),
|
||||
TransportWarningStatus.已超时.GetHashCode()
|
||||
};
|
||||
|
||||
var r = await _client.UpdateByQueryAsync<TransportWarningDetailsIndex>(u =>
|
||||
u.Index(GlobalConst.TransportWarningDetailsIndex)
|
||||
.Query(q => q
|
||||
.Bool(b => b.Must(
|
||||
mu => mu.Terms(t => t.Field(f => f.Status).Terms(status)),
|
||||
mu => mu.Terms(t => t.Field(f => f.WarningSceneRuleItemId).Terms(ruleItemIds))
|
||||
)
|
||||
)
|
||||
)
|
||||
.Script(s => s
|
||||
.Source("ctx._source.status = params.status")
|
||||
.Params(p => p.Add("status", (int) TransportWarningStatus.已关闭))
|
||||
)
|
||||
);
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"运输时效预警明细更新失败,ruleItemIds:{ruleItemIds},原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InsertTransportWarningDetailsAsync(TransportWarningDetailsIndex detail)
|
||||
{
|
||||
var indexName = $"{GlobalConst.TransportWarningDetailsIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
detail.IndexName = indexName;
|
||||
var r = await _client.IndexAsync(detail, s => s.Index(indexName));
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException($"运输预警明细新增失败,{detail},原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task BulkInsertTransportWarningDetailsAsync(List<TransportWarningDetailsIndex> details, int maxRetries = 3)
|
||||
{
|
||||
// 按天写入es
|
||||
var indexName = $"{GlobalConst.TransportWarningDetailsIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
details.ForEach(x => x.IndexName = indexName);
|
||||
|
||||
var r = await _client.IndexManyAsync(details, indexName);
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException($"运输预警明细新增失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 回传时效
|
||||
|
||||
public async Task<UnifyPageResultDto<ReturnWarningDetailsIndex>> GetPageReturnWarningDetailsAsync(GetPageReturnWarningDetailsInputVO input)
|
||||
{
|
||||
var musts = ListWrapperFactory.CreateListWrapper<ReturnWarningDetailsIndex, GetPageReturnWarningDetailsInputVO>(input);
|
||||
|
||||
var orderNos = input.OrderNos?.Split(',');
|
||||
|
||||
// 精确匹配
|
||||
musts.AddIf(x => x.SubSystemId > 0, c => c.Term(f => f.SubSystemId, input.SubSystemId));
|
||||
musts.AddIf(_ => orderNos?.Length > 0, c => c.Terms(f => f.Field(d => d.OrderNo.Suffix("keyword")).Terms(orderNos)));
|
||||
musts.AddIf(x => x.OrderType > 0, c => c.Term(f => f.OrderType, input.OrderType));
|
||||
musts.AddIf(x => x.Status > 0, c => c.Term(f => f.Status, input.Status));
|
||||
musts.AddIf(x => x.CustomId > 0, c => c.Term(f => f.CustomId, input.CustomId));
|
||||
musts.AddIf(x => x.TrackStatusId > 0, c => c.Term(f => f.TrackStatusId, input.TrackStatusId));
|
||||
musts.AddIf(x => x.TrackContentId > 0, c => c.Term(f => f.TrackContentId, input.TrackContentId));
|
||||
musts.AddIf(x => x.IsKpi.HasValue, c => c.Term(f => f.IsExistsKpi, input.IsKpi!.Value));
|
||||
musts.AddIf(x => x.TrackTimeStart.HasValue, c => c.DateRange(r => r.Field(f => f.TrackTime).GreaterThanOrEquals(input.TrackTimeStart)));
|
||||
musts.AddIf(x => x.TrackTimeEnd.HasValue, c => c.DateRange(r => r.Field(f => f.TrackTime).LessThanOrEquals(input.TrackTimeEnd)));
|
||||
musts.AddIf(x => x.TrackCreateTimeStart.HasValue, c => c.DateRange(r => r.Field(f => f.TrackCreateTime).LessThanOrEquals(input.TrackCreateTimeStart)));
|
||||
musts.AddIf(x => x.TrackCreateTimeEnd.HasValue, c => c.DateRange(r => r.Field(f => f.TrackCreateTime).LessThanOrEquals(input.TrackCreateTimeEnd)));
|
||||
musts.AddIf(x => x.TrackReturnTimeStart.HasValue, c => c.DateRange(r => r.Field(f => f.TrackReturnTime).LessThanOrEquals(input.TrackReturnTimeStart)));
|
||||
musts.AddIf(x => x.TrackReturnTimeEnd.HasValue, c => c.DateRange(r => r.Field(f => f.TrackReturnTime).LessThanOrEquals(input.TrackReturnTimeEnd)));
|
||||
musts.AddIf(x => x.WarningCreateTimeStart.HasValue, c => c.DateRange(r => r.Field(f => f.CreateTime).LessThanOrEquals(input.WarningCreateTimeStart)));
|
||||
musts.AddIf(x => x.WarningCreateTimeEnd.HasValue, c => c.DateRange(r => r.Field(f => f.CreateTime).LessThanOrEquals(input.WarningCreateTimeEnd)));
|
||||
|
||||
// 模糊匹配userId(json字符串包含userId)
|
||||
musts.AddIf(x => x.NotifyUserId.HasValue, c => c.Match(f => f.Field(d => d.NotifyUsers).Query(input.NotifyUserId.ToString())));
|
||||
|
||||
var resp = await _client.SearchAsync<ReturnWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.ReturnWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.From((input.PageIndex - 1) * input.PageSize)
|
||||
.Size(input.PageSize));
|
||||
|
||||
return new UnifyPageResultDto<ReturnWarningDetailsIndex>(resp.ToIdList(), input.PageIndex, input.PageSize, (int) resp.Total);
|
||||
}
|
||||
|
||||
public async Task<List<ReturnMessageRecordIndex>> GetReturnMessageRecordListByIdAsync(string esId)
|
||||
{
|
||||
var resp = await _client.SearchAsync<ReturnMessageRecordIndex>(x => x
|
||||
.Index(GlobalConst.ReturnMessageRecordIndex)
|
||||
.Query(q => q.Term(t => t.WarningDetailsId.Suffix("keyword"), esId))
|
||||
.Size(1000)
|
||||
);
|
||||
|
||||
return resp.ToIdList();
|
||||
}
|
||||
|
||||
public async Task UpdateReturnWarningDetailsAsync(ReturnWarningDetailsIndex detail)
|
||||
{
|
||||
var r = await _client.UpdateAsync<ReturnWarningDetailsIndex, object>(detail.Id,
|
||||
u => u.Index(detail.IndexName)
|
||||
.Doc(new
|
||||
{
|
||||
detail.ReturnWarningRuleId,
|
||||
detail.WarningId,
|
||||
detail.Version,
|
||||
detail.ReturnTimeSpan,
|
||||
//detail.NotifyModes,
|
||||
detail.NotifyUsers,
|
||||
detail.SubSystemId,
|
||||
detail.CustomId,
|
||||
detail.OrderId,
|
||||
detail.OrderNo,
|
||||
detail.OrderType,
|
||||
detail.TrackStatusId,
|
||||
detail.TrackStatus,
|
||||
detail.CompareFields,
|
||||
detail.Extra,
|
||||
detail.TrackContentId,
|
||||
detail.TrackContent,
|
||||
detail.TrackCode,
|
||||
detail.TrackPlace,
|
||||
detail.TrackTime,
|
||||
detail.TrackTimeZone,
|
||||
detail.TrackCreateTime,
|
||||
detail.PushTrackStatus,
|
||||
detail.PushTrackCode,
|
||||
detail.PushTrackContent,
|
||||
detail.PushTrackEnContent,
|
||||
detail.TrackReturnTime,
|
||||
detail.RetryCount,
|
||||
detail.Status,
|
||||
detail.ActualReturnTimeSpan,
|
||||
detail.SystemReturnTimeSpan,
|
||||
detail.TrackCreateTimeSpan,
|
||||
detail.CreateTime,
|
||||
detail.UpdateTime,
|
||||
}));
|
||||
}
|
||||
|
||||
public async Task BulkUpdateReturnWarningDetailsAsync(List<ReturnWarningDetailsIndex> details, int maxRetries = 3)
|
||||
{
|
||||
if (details.Count == 0) return;
|
||||
|
||||
//构建批量更新操作描述符
|
||||
var desc = new BulkDescriptor().UpdateMany(details,
|
||||
(u, detail) => u.Id(detail.Id)
|
||||
.Index(detail.IndexName)
|
||||
.Script(s => s.Source(@"
|
||||
ctx._source.ReturnWarningRuleId = param.ReturnWarningRuleId;
|
||||
ctx._source.WarningId = param.WarningId;
|
||||
ctx._source.Version = param.Version;
|
||||
ctx._source.ReturnTimeSpan = param.ReturnTimeSpan;
|
||||
//ctx._source.NotifyModes = param.NotifyModes;
|
||||
ctx._source.NotifyUsers = param.NotifyUsers;
|
||||
ctx._source.SubSystemId = param.SubSystemId;
|
||||
ctx._source.CustomId = param.CustomId;
|
||||
ctx._source.OrderId = param.OrderId;
|
||||
ctx._source.OrderNo = param.OrderNo;
|
||||
ctx._source.OrderType = param.OrderType;
|
||||
ctx._source.TrackStatusId = param.TrackStatusId;
|
||||
ctx._source.TrackStatus = param.TrackStatus;
|
||||
ctx._source.CompareFields = param.CompareFields;
|
||||
ctx._source.Extra = param.Extra;
|
||||
ctx._source.TrackContentId = param.TrackContentId;
|
||||
ctx._source.TrackContent = param.TrackContent;
|
||||
ctx._source.TrackCode = param.TrackCode;
|
||||
ctx._source.TrackPlace = param.TrackPlace;
|
||||
ctx._source.TrackTime = param.TrackTime;
|
||||
ctx._source.TrackTimeZone = param.TrackTimeZone;
|
||||
ctx._source.TrackCreateTime = param.TrackCreateTime;
|
||||
ctx._source.PushTrackStatus = param.PushTrackStatus;
|
||||
ctx._source.PushTrackCode = param.PushTrackCode;
|
||||
ctx._source.PushTrackContent = param.PushTrackContent;
|
||||
ctx._source.PushTrackEnContent = param.PushTrackEnContent;
|
||||
ctx._source.TrackReturnTime = param.TrackReturnTime;
|
||||
ctx._source.RetryCount = param.RetryCount;
|
||||
ctx._source.Status = param.Status;
|
||||
ctx._source.ActualReturnTimeSpan = param.ActualReturnTimeSpan;
|
||||
ctx._source.SystemReturnTimeSpan = param.SystemReturnTimeSpan;
|
||||
ctx._source.TrackCreateTimeSpan = param.TrackCreateTimeSpan;
|
||||
ctx._source.CreateTime = param.CreateTime;
|
||||
ctx._source.UpdateTime = param.UpdateTime;
|
||||
").Params(p => p
|
||||
.Add("ReturnWarningRuleId", detail.ReturnWarningRuleId)
|
||||
.Add("WarningId", detail.WarningId)
|
||||
.Add("Version", detail.Version)
|
||||
.Add("ReturnTimeSpan", detail.ReturnTimeSpan)
|
||||
//.Add("NotifyModes", detail.NotifyModes)
|
||||
.Add("NotifyUsers", detail.NotifyUsers)
|
||||
.Add("SubSystemId", detail.SubSystemId)
|
||||
.Add("CustomId", detail.CustomId)
|
||||
.Add("OrderId", detail.OrderId)
|
||||
.Add("OrderNo", detail.OrderNo)
|
||||
.Add("OrderType", detail.OrderType)
|
||||
.Add("TrackStatusId", detail.TrackStatusId)
|
||||
.Add("TrackStatus", detail.TrackStatus)
|
||||
.Add("CompareFields", detail.CompareFields)
|
||||
.Add("Extra", detail.Extra)
|
||||
.Add("TrackContentId", detail.TrackContentId)
|
||||
.Add("TrackContent", detail.TrackContent)
|
||||
.Add("TrackCode", detail.TrackCode)
|
||||
.Add("TrackPlace", detail.TrackPlace)
|
||||
.Add("TrackTime", detail.TrackTime)
|
||||
.Add("TrackTimeZone", detail.TrackTimeZone)
|
||||
.Add("TrackCreateTime", detail.TrackCreateTime)
|
||||
.Add("PushTrackStatus", detail.PushTrackStatus)
|
||||
.Add("PushTrackCode", detail.PushTrackCode)
|
||||
.Add("PushTrackContent", detail.PushTrackContent)
|
||||
.Add("PushTrackEnContent", detail.PushTrackEnContent)
|
||||
.Add("TrackReturnTime", detail.TrackReturnTime)
|
||||
.Add("RetryCount", detail.RetryCount)
|
||||
.Add("Status", detail.Status)
|
||||
.Add("ActualReturnTimeSpan", detail.ActualReturnTimeSpan)
|
||||
.Add("SystemReturnTimeSpan", detail.SystemReturnTimeSpan)
|
||||
.Add("TrackCreateTimeSpan", detail.TrackCreateTimeSpan)
|
||||
.Add("CreateTime", detail.CreateTime)
|
||||
.Add("UpdateTime", detail.UpdateTime)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
await PollyHelper.RetryPollyExecAsync(() => _client.BulkAsync(desc), response =>
|
||||
{
|
||||
if (response.IsValid) // 认为成功
|
||||
return true;
|
||||
|
||||
if (response.ServerError.Status == 409) //版本冲突认为失败,则重试
|
||||
return false;
|
||||
|
||||
throw new InvalidOperationException($"ES更新失败:{details.Count}条,原因:{response.DebugInformation}。");
|
||||
});
|
||||
}
|
||||
|
||||
public async Task InsertReturnWarningDetailsAsync(ReturnWarningDetailsIndex detail)
|
||||
{
|
||||
var indexName = $"{GlobalConst.ReturnWarningDetailsIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
detail.IndexName = indexName;
|
||||
var r = await _client.IndexAsync(detail, s => s.Index(indexName));
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException($"回传预警明细新增失败,{detail},原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task BulkInsertReturnWarningDetailsAsync(List<ReturnWarningDetailsIndex> details, int maxRetries = 3)
|
||||
{
|
||||
// 按天写入es
|
||||
var indexName = $"{GlobalConst.ReturnWarningDetailsIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
details.ForEach(x => x.IndexName = indexName);
|
||||
|
||||
var r = await _client.IndexManyAsync(details, indexName);
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException($"回传预警明细新增失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InsertReturnMessageRecordAsync(ReturnMessageRecordIndex detail)
|
||||
{
|
||||
var indexName = $"{GlobalConst.ReturnMessageRecordIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
detail.IndexName = indexName;
|
||||
var r = await _client.IndexAsync(detail, s => s.Index(indexName));
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException($"回传日志新增失败,{detail},原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task BulkInsertReturnMessageRecordAsync(List<ReturnMessageRecordIndex> details, int maxRetries = 3)
|
||||
{
|
||||
// 按天写入es
|
||||
var indexName = $"{GlobalConst.ReturnMessageRecordIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
details.ForEach(x => x.IndexName = indexName);
|
||||
|
||||
var r = await _client.IndexManyAsync(details, indexName);
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException($"回传日志新增失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 完整
|
||||
|
||||
public async Task<UnifyPageResultDto<CompleteWarningDetailsIndex>> GetPageCompleteWarningDetailsAsync(GetPageCompleteWarningDetailsInputVO input)
|
||||
{
|
||||
var musts = ListWrapperFactory.CreateListWrapper<CompleteWarningDetailsIndex, GetPageCompleteWarningDetailsInputVO>(input);
|
||||
|
||||
var orderNos = input.OrderNos?.Split(',');
|
||||
|
||||
musts.AddIf(x => x.SubSystemId > 0, c => c.Term(f => f.SubSystemId, input.SubSystemId));
|
||||
musts.AddIf(_ => orderNos?.Length > 0, c => c.Terms(f => f.Field(d => d.OrderNo.Suffix("keyword")).Terms(orderNos)));
|
||||
musts.AddIf(x => x.OrderType > 0, c => c.Term(f => f.OrderType, input.OrderType));
|
||||
musts.AddIf(x => x.Status > 0, c => c.Term(f => f.Status, input.Status));
|
||||
musts.AddIf(x => x.CustomId > 0, c => c.Term(f => f.CustomId, input.CustomId));
|
||||
musts.AddIf(x => x.MissingTrackStatusId > 0, c => c.Match(f => f.Field(d => d.MissingTrackStatusIds).Query(input.MissingTrackStatusId.ToString())));
|
||||
musts.AddIf(x => x.WarningCreateTimeStart.HasValue, c => c.DateRange(r => r.Field(f => f.CreateTime).LessThanOrEquals(input.WarningCreateTimeStart)));
|
||||
musts.AddIf(x => x.WarningCreateTimeEnd.HasValue, c => c.DateRange(r => r.Field(f => f.CreateTime).LessThanOrEquals(input.WarningCreateTimeEnd)));
|
||||
musts.AddIf(x => x.WarningHandleTimeStart.HasValue, c => c.DateRange(r => r.Field(f => f.ProcessedTime).LessThanOrEquals(input.WarningHandleTimeStart)));
|
||||
musts.AddIf(x => x.WarningHandleTimeEnd.HasValue, c => c.DateRange(r => r.Field(f => f.ProcessedTime).LessThanOrEquals(input.WarningHandleTimeEnd)));
|
||||
|
||||
// 模糊匹配userId
|
||||
musts.AddIf(x => x.NotifyUserId.HasValue, c => c.Match(f => f.Field(d => d.NotifyUsers).Query(input.NotifyUserId.ToString())));
|
||||
|
||||
var resp = await _client.SearchAsync<CompleteWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.CompleteWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.From((input.PageIndex - 1) * input.PageSize)
|
||||
.Size(input.PageSize));
|
||||
|
||||
return new UnifyPageResultDto<CompleteWarningDetailsIndex>(resp.ToIdList(), input.PageIndex, input.PageSize, (int) resp.Total);
|
||||
}
|
||||
|
||||
public async Task UpdateCompleteWarningDetailsAsync(CompleteWarningDetailsIndex detail)
|
||||
{
|
||||
var r = await _client.UpdateAsync<CompleteWarningDetailsIndex, object>(detail.Id,
|
||||
u => u.Index(detail.IndexName)
|
||||
.Doc(new
|
||||
{
|
||||
detail.WarningId,
|
||||
detail.CompleteWarningRuleId,
|
||||
detail.Version,
|
||||
//detail.NotifyModes,
|
||||
detail.NotifyUsers,
|
||||
detail.CheckPointTrackStatusId,
|
||||
detail.MissingTrackStatusIds,
|
||||
detail.SubSystemId,
|
||||
detail.CustomId,
|
||||
detail.OrderId,
|
||||
detail.OrderNo,
|
||||
detail.OrderType,
|
||||
detail.Status,
|
||||
detail.CreateTime,
|
||||
detail.ProcessedTime,
|
||||
}));
|
||||
}
|
||||
|
||||
public async Task BulkUpdateCompleteWarningDetailsAsync(List<CompleteWarningDetailsIndex> details, int maxRetries = 3)
|
||||
{
|
||||
if (details.Count == 0) return;
|
||||
|
||||
//构建批量更新操作描述符
|
||||
var desc = new BulkDescriptor().UpdateMany(details,
|
||||
(u, detail) => u.Id(detail.Id)
|
||||
.Index(detail.IndexName)
|
||||
.Script(s => s.Source(@"
|
||||
ctx._source.WarningId = param.WarningId;
|
||||
ctx._source.CompleteWarningRuleId = param.CompleteWarningRuleId;
|
||||
ctx._source.Version = param.Version;
|
||||
//ctx._source.NotifyModes = param.NotifyModes;
|
||||
ctx._source.NotifyUsers = param.NotifyUsers;
|
||||
ctx._source.CheckPointTrackStatusId = param.CheckPointTrackStatusId;
|
||||
ctx._source.MissingTrackStatusIds = param.MissingTrackStatusIds;
|
||||
ctx._source.SubSystemId = param.SubSystemId;
|
||||
ctx._source.CustomId = param.CustomId;
|
||||
ctx._source.OrderId = param.OrderId;
|
||||
ctx._source.OrderNo = param.OrderNo;
|
||||
ctx._source.OrderType = param.OrderType;
|
||||
ctx._source.Status = param.Status;
|
||||
ctx._source.CreateTime = param.CreateTime;
|
||||
ctx._source.ProcessedTime = param.ProcessedTime;
|
||||
")
|
||||
.Params(p => p
|
||||
.Add("WarningId", detail.WarningId)
|
||||
.Add("CompleteWarningRuleId", detail.CompleteWarningRuleId)
|
||||
.Add("Version", detail.Version)
|
||||
//.Add("NotifyModes", detail.NotifyModes)
|
||||
.Add("NotifyUsers", detail.NotifyUsers)
|
||||
.Add("CheckPointTrackStatusId", detail.CheckPointTrackStatusId)
|
||||
.Add("MissingTrackStatusIds", detail.MissingTrackStatusIds)
|
||||
.Add("SubSystemId", detail.SubSystemId)
|
||||
.Add("CustomId", detail.CustomId)
|
||||
.Add("OrderId", detail.OrderId)
|
||||
.Add("OrderNo", detail.OrderNo)
|
||||
.Add("OrderType", detail.OrderType)
|
||||
.Add("Status", detail.Status)
|
||||
.Add("CreateTime", detail.CreateTime)
|
||||
.Add("ProcessedTime", detail.ProcessedTime)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
await PollyHelper.RetryPollyExecAsync(() => _client.BulkAsync(desc), response =>
|
||||
{
|
||||
if (response.IsValid) // 认为成功
|
||||
return true;
|
||||
|
||||
if (response.ServerError.Status == 409) //版本冲突认为失败,则重试
|
||||
return false;
|
||||
|
||||
throw new InvalidOperationException($"ES更新失败:{details.Count}条,原因:{response.DebugInformation}。");
|
||||
});
|
||||
}
|
||||
|
||||
public async Task InsertCompleteWarningDetailsAsync(CompleteWarningDetailsIndex detail)
|
||||
{
|
||||
var indexName = $"{GlobalConst.CompleteWarningDetailsIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
detail.IndexName = indexName;
|
||||
var r = await _client.IndexAsync(detail, s => s.Index(indexName));
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException($"完整预警明细新增失败,{detail},原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task BulkInsertCompleteWarningDetailsAsync(List<CompleteWarningDetailsIndex> details, int maxRetries = 3)
|
||||
{
|
||||
// 按天写入es
|
||||
var indexName = $"{GlobalConst.CompleteWarningDetailsIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
details.ForEach(x => x.IndexName = indexName);
|
||||
|
||||
var r = await _client.IndexManyAsync(details, indexName);
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException($"完整预警明细新增失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public async Task CreateAliasAsync()
|
||||
{
|
||||
var indexName1 = $"{GlobalConst.TransportWarningDetailsIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
var indexName2 = $"{GlobalConst.ReturnWarningDetailsIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
var indexName3 = $"{GlobalConst.CompleteWarningDetailsIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
var indexName4 = $"{GlobalConst.ReturnMessageRecordIndex}-{DateTime.Now:yyyy.MM.dd}";
|
||||
|
||||
var exists1 = await _client.Indices.ExistsAsync(indexName1);
|
||||
if (!exists1.Exists)
|
||||
{
|
||||
await _client.Indices.CreateAsync(indexName1);
|
||||
await _client.MapAsync<TransportWarningDetailsIndex>(m => m.Index(indexName1).AutoMap());
|
||||
}
|
||||
|
||||
var exists2 = await _client.Indices.ExistsAsync(indexName2);
|
||||
if (!exists2.Exists)
|
||||
{
|
||||
await _client.Indices.CreateAsync(indexName2);
|
||||
await _client.MapAsync<ReturnWarningDetailsIndex>(m => m.Index(indexName2).AutoMap());
|
||||
}
|
||||
|
||||
var exists3 = await _client.Indices.ExistsAsync(indexName3);
|
||||
if (!exists3.Exists)
|
||||
{
|
||||
await _client.Indices.CreateAsync(indexName3);
|
||||
await _client.MapAsync<CompleteWarningDetailsIndex>(m => m.Index(indexName3).AutoMap());
|
||||
}
|
||||
|
||||
var exists4 = await _client.Indices.ExistsAsync(indexName4);
|
||||
if (!exists4.Exists)
|
||||
{
|
||||
await _client.Indices.CreateAsync(indexName4);
|
||||
await _client.MapAsync<ReturnMessageRecordIndex>(m => m.Index(indexName4).AutoMap());
|
||||
}
|
||||
|
||||
var r = await _client.Indices.BulkAliasAsync(b =>
|
||||
b.Add(a => a.Alias(GlobalConst.TransportWarningDetailsIndex).Index(indexName1))
|
||||
.Add(a => a.Alias(GlobalConst.ReturnWarningDetailsIndex).Index(indexName2))
|
||||
.Add(a => a.Alias(GlobalConst.CompleteWarningDetailsIndex).Index(indexName3))
|
||||
.Add(a => a.Alias(GlobalConst.ReturnMessageRecordIndex).Index(indexName4))
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
217
src/SJZY.Track.Repository/Repositories/WarningRuleRepository.cs
Normal file
217
src/SJZY.Track.Repository/Repositories/WarningRuleRepository.cs
Normal file
@ -0,0 +1,217 @@
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Complete;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
using SJZY.Track.Domain.Extensions;
|
||||
|
||||
namespace SJZY.Track.Repository.Repositories;
|
||||
|
||||
public sealed class WarningRuleRepository : BasicRepository<WarningRuleEntity>, IWarningRuleRepository, ITransientDependency
|
||||
{
|
||||
#region 规则主体
|
||||
|
||||
public async Task<bool> CheckNameDuplicateAsync(int id, int subsystemId, int customId, string name)
|
||||
{
|
||||
var entity = await Context.Queryable<WarningRuleEntity>()
|
||||
.Where(x => x.SubSystemId == subsystemId &&
|
||||
x.CustomId == customId
|
||||
&& string.Equals(x.Name, name))
|
||||
.FirstAsync();
|
||||
|
||||
// 如果是新增,则要求不能重复添加 subsystemId+customId+name三者都相同的
|
||||
if (id == 0)
|
||||
return entity != null;
|
||||
|
||||
// 如果是修改,则要求查出来的和要修改的是同一个,否则视为重复
|
||||
return entity.Id != id;
|
||||
}
|
||||
|
||||
public async Task<int> UpsertReturnIdAsync(WarningRuleEntity entity)
|
||||
{
|
||||
if (entity.Id == 0)
|
||||
{
|
||||
return await Context.Insertable(entity)
|
||||
.ExecuteReturnIdentityAsync();
|
||||
}
|
||||
|
||||
var isUpdated = await Context.Updateable(entity)
|
||||
.ExecuteCommandHasChangeAsync();
|
||||
|
||||
// 指定了id更新失败
|
||||
if (!isUpdated)
|
||||
{
|
||||
throw new Exception($"{entity}更新失败");
|
||||
}
|
||||
|
||||
return entity.Id;
|
||||
}
|
||||
|
||||
public async Task<string> UpdateVersionAsync(WarningRuleEntity entity)
|
||||
{
|
||||
var version = VersionGenerate.GenVersion();
|
||||
await Context.Updateable<WarningRuleEntity>()
|
||||
.Where(x => x.Id == entity.Id)
|
||||
.SetColumns(x => x.Version, version)
|
||||
.ExecuteCommandHasChangeAsync();
|
||||
return version;
|
||||
}
|
||||
|
||||
public Task<List<WarningRuleEntity>> GetWarningRuleListAsync(int? subsystemId, string? keyword, bool? isEnabled, int? warningType)
|
||||
{
|
||||
return Context.Queryable<WarningRuleEntity>()
|
||||
.WhereIF(subsystemId.HasValue, x => x.SubSystemId == subsystemId!.Value)
|
||||
// todo: 客户/kpi名称 改成客户下拉
|
||||
// .WhereIF(!string.IsNullOrWhiteSpace(keyword), x => x.Name.Contains(keyword!) || x.CustomName.Contains(keyword!))
|
||||
.WhereIF(isEnabled.HasValue, x => x.IsEnabled == isEnabled!.Value)
|
||||
.WhereIF(warningType.HasValue, x => x.WarningType == warningType!.Value)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<WarningRuleEntity?> GetWarningRuleForEnabledAsync(int subSystemId, int customId, WarningRuleType warningType)
|
||||
{
|
||||
var warningRules = await Context.Queryable<WarningRuleEntity>()
|
||||
.Where(x => x.SubSystemId == subSystemId)
|
||||
.Where(x => x.CustomId == customId)
|
||||
.Where(x => x.WarningType == (int) warningType)
|
||||
.ToListAsync();
|
||||
|
||||
return warningRules.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task<WarningRuleEntity?> GetWarningRuleByIdAsync(int id, WarningRuleType? warningType = null)
|
||||
{
|
||||
var result = await Context.Queryable<WarningRuleEntity>()
|
||||
.Where(x => x.Id == id)
|
||||
.WhereIF(warningType.HasValue, x => x.WarningType == (int) warningType!.Value)
|
||||
.ToListAsync();
|
||||
return result.FirstOrDefault();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 运输时效预警规则
|
||||
|
||||
public Task<List<TransportWarningSceneEntity>> GetTransportSceneAsync(int warningId)
|
||||
{
|
||||
return Context.Queryable<TransportWarningSceneEntity>()
|
||||
.Where(x => x.WarningId == warningId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<TransportWarningSceneEntity?> GetTransportSceneAsync(int warningId, int sceneId)
|
||||
{
|
||||
var result = await Context.Queryable<TransportWarningSceneEntity>()
|
||||
.Where(x => x.WarningId == warningId && x.Id == sceneId)
|
||||
.ToListAsync();
|
||||
return result.FirstOrDefault();
|
||||
}
|
||||
|
||||
public Task<List<TransportWarningSceneRuleItemEntity>> GetTransportSceneRuleItemsAsync(int warningId, int sceneId)
|
||||
{
|
||||
return Context.Queryable<TransportWarningSceneRuleItemEntity>()
|
||||
.Where(x => x.WarningId == warningId && x.TransportWarningSceneId == sceneId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<int> UpsertTransportSceneReturnIdAsync(TransportWarningSceneEntity entity)
|
||||
{
|
||||
if (entity.Id == 0)
|
||||
{
|
||||
return await Context.Insertable(entity)
|
||||
.ExecuteReturnIdentityAsync();
|
||||
}
|
||||
|
||||
var isUpdated = await Context.Updateable(entity)
|
||||
.ExecuteCommandHasChangeAsync();
|
||||
|
||||
// 指定了id更新失败
|
||||
if (!isUpdated)
|
||||
{
|
||||
throw new Exception($"{entity}更新失败");
|
||||
}
|
||||
|
||||
return entity.Id;
|
||||
}
|
||||
|
||||
public async Task<int> BulkUpdateTransportSceneRuleItemsAsync(List<TransportWarningSceneRuleItemEntity> entities)
|
||||
{
|
||||
return await Context.Updateable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<int> BulkInsertTransportSceneRuleItemsAsync(List<TransportWarningSceneRuleItemEntity> entities)
|
||||
{
|
||||
return Context.Insertable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<int> DeleteTransportSceneRuleItemsAsync(HashSet<int> ruleItemIds)
|
||||
{
|
||||
return Context.Deleteable<TransportWarningSceneRuleItemEntity>()
|
||||
.Where(x => ruleItemIds.Contains(x.Id))
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 回传时效预警规则
|
||||
|
||||
public Task<List<ReturnWarningRuleItemEntity>> GetReturnRuleItemsAsync(int warningId)
|
||||
{
|
||||
return Context.Queryable<ReturnWarningRuleItemEntity>()
|
||||
.Where(x => x.WarningId == warningId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public Task<int> BulkInsertReturnRuleItemsAsync(List<ReturnWarningRuleItemEntity> entities)
|
||||
{
|
||||
return Context.Insertable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public async Task<int> BulkUpdateReturnRuleItemsAsync(List<ReturnWarningRuleItemEntity> entities)
|
||||
{
|
||||
return await Context.Updateable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<int> DeleteReturnRuleItemsAsync(HashSet<int> ruleItemIds)
|
||||
{
|
||||
return Context.Deleteable<ReturnWarningRuleItemEntity>()
|
||||
.Where(x => ruleItemIds.Contains(x.Id))
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 完整预警规则
|
||||
|
||||
public Task<List<CompleteWarningRuleItemEntity>> GetCompleteRuleItemsAsync(int warningId)
|
||||
{
|
||||
return Context.Queryable<CompleteWarningRuleItemEntity>()
|
||||
.Where(x => x.WarningId == warningId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<int> BulkUpdateCompleteRuleItemsAsync(List<CompleteWarningRuleItemEntity> entities)
|
||||
{
|
||||
return await Context.Updateable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<int> BulkInsertCompleteRuleItemsAsync(List<CompleteWarningRuleItemEntity> entities)
|
||||
{
|
||||
return Context.Insertable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<int> DeleteCompleteRuleItemsAsync(HashSet<int> ruleItemIds)
|
||||
{
|
||||
return Context.Deleteable<CompleteWarningRuleItemEntity>()
|
||||
.Where(x => ruleItemIds.Contains(x.Id))
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
159
src/SJZY.Track.Repository/Repositories/WarningTaskRepository.cs
Normal file
159
src/SJZY.Track.Repository/Repositories/WarningTaskRepository.cs
Normal file
@ -0,0 +1,159 @@
|
||||
using System.Linq.Expressions;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Return;
|
||||
using SJZY.Track.Domain.Aggregates.WarningAggregate.Transport;
|
||||
|
||||
namespace SJZY.Track.Repository.Repositories;
|
||||
|
||||
public sealed class WarningTaskRepository : BasicRepository<WarningNotifyTaskEntity>, IWarningTaskRepository, ITransientDependency
|
||||
{
|
||||
//public ISqlSugarClient Context { get; set; }
|
||||
|
||||
public WarningTaskRepository()
|
||||
{
|
||||
//Context = SqlsugarScopeBasic.GetContextSafely("default");
|
||||
}
|
||||
|
||||
#region 预警通知任务
|
||||
|
||||
public Task<List<WarningNotifyTaskEntity>> ScanMayNeedExecutedTaskAsync()
|
||||
{
|
||||
return Context.Queryable<WarningNotifyTaskEntity>()
|
||||
.Where(x => x.IsClosed == false)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public Task<List<WarningNotifyTaskEntity>> GetWarningNotifyTaskAsync(Expression<Func<WarningNotifyTaskEntity, bool>> expression)
|
||||
{
|
||||
return Context.Queryable<WarningNotifyTaskEntity>()
|
||||
.Where(expression)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> AddWarningNotifyTaskAsync(WarningNotifyTaskEntity entity)
|
||||
{
|
||||
return await Context.Insertable(entity).ExecuteCommandAsync() > 0;
|
||||
}
|
||||
|
||||
public Task<int> BulkInsertWarningNotifyTaskAsync(List<WarningNotifyTaskEntity> entities)
|
||||
{
|
||||
return Context.Insertable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<int> CloseWarningNotifyTaskAsync(Expression<Func<WarningNotifyTaskEntity, bool>> expression)
|
||||
{
|
||||
return Context.Updateable<WarningNotifyTaskEntity>()
|
||||
.Where(expression)
|
||||
.SetColumns(x => x.IsClosed, true)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<bool> CloseWarningNotifyTaskAsync(WarningNotifyTaskEntity entity)
|
||||
{
|
||||
if (entity.IsClosed) return Task.FromResult(false);
|
||||
return Context.Updateable(entity)
|
||||
.SetColumns(x => x.IsClosed, true)
|
||||
.ExecuteCommandHasChangeAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 回传预警_重试推送任务
|
||||
|
||||
public Task<List<ReturnWarningRetryPushTaskEntity>> ScanReturnWarningRetryPushTaskAsync()
|
||||
{
|
||||
return Context.Queryable<ReturnWarningRetryPushTaskEntity>()
|
||||
.Where(x => x.IsClosed == false)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public Task<List<ReturnWarningRetryPushTaskEntity>> GetReturnWarningRetryPushTaskAsync(Expression<Func<ReturnWarningRetryPushTaskEntity, bool>> expression)
|
||||
{
|
||||
return Context.Queryable<ReturnWarningRetryPushTaskEntity>()
|
||||
.Where(expression)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> AddReturnWarningRetryPushTaskAsync(ReturnWarningRetryPushTaskEntity entity)
|
||||
{
|
||||
return await Context.Insertable(entity)
|
||||
.ExecuteCommandAsync() > 0;
|
||||
}
|
||||
|
||||
public Task<int> BulkInsertReturnWarningRetryPushTaskAsync(List<ReturnWarningRetryPushTaskEntity> entities)
|
||||
{
|
||||
return Context.Insertable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<int> CloseReturnWarningRetryPushTaskAsync(Expression<Func<ReturnWarningRetryPushTaskEntity, bool>> expression)
|
||||
{
|
||||
return Context.Updateable<ReturnWarningRetryPushTaskEntity>()
|
||||
.Where(expression)
|
||||
.SetColumns(x => x.IsClosed, true)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<bool> CloseReturnWarningRetryPushTaskAsync(ReturnWarningRetryPushTaskEntity entity)
|
||||
{
|
||||
if (entity.IsClosed) return Task.FromResult(false);
|
||||
return Context.Updateable(entity)
|
||||
.SetColumns(x => x.IsClosed, true)
|
||||
.ExecuteCommandHasChangeAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 运输预警_预警明细生成任务
|
||||
|
||||
public Task<List<TransportWarningDetailsGenerateTaskEntity>> ScanTransportWarningDetailsGenerateTaskAsync()
|
||||
{
|
||||
return Context.Queryable<TransportWarningDetailsGenerateTaskEntity>()
|
||||
.Where(x => x.IsClosed == false)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public Task<List<TransportWarningDetailsGenerateTaskEntity>> GetTransportWarningDetailsGenerateTaskAsync(Expression<Func<TransportWarningDetailsGenerateTaskEntity, bool>> expression)
|
||||
{
|
||||
return Context.Queryable<TransportWarningDetailsGenerateTaskEntity>()
|
||||
.Where(expression)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> AddTransportWarningDetailsGenerateTaskAsync(TransportWarningDetailsGenerateTaskEntity entity)
|
||||
{
|
||||
return await Context.Insertable(entity)
|
||||
.ExecuteCommandAsync() > 0;
|
||||
}
|
||||
|
||||
public Task<int> BulkInsertTransportWarningDetailsGenerateTaskAsync(List<TransportWarningDetailsGenerateTaskEntity> entities)
|
||||
{
|
||||
return Context.Insertable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<int> BulkUpdateTransportWarningDetailsGenerateTaskAsync(List<TransportWarningDetailsGenerateTaskEntity> entities)
|
||||
{
|
||||
return Context.Updateable(entities)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<int> CloseTransportWarningDetailsGenerateTaskAsync(Expression<Func<TransportWarningDetailsGenerateTaskEntity, bool>> expression)
|
||||
{
|
||||
return Context.Updateable<TransportWarningDetailsGenerateTaskEntity>()
|
||||
.Where(expression)
|
||||
.SetColumns(x => x.IsClosed, true)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public Task<bool> CloseTransportWarningDetailsGenerateTaskAsync(TransportWarningDetailsGenerateTaskEntity entity)
|
||||
{
|
||||
if (entity.IsClosed) return Task.FromResult(false);
|
||||
return Context.Updateable(entity)
|
||||
.SetColumns(x => x.IsClosed, true)
|
||||
.ExecuteCommandHasChangeAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user