@ -1,3 +1,4 @@
using System.Linq.Expressions ;
using SJZY.Track.Application.Services.Warning.Model ;
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate ;
using SJZY.Track.Domain.Aggregates.OrderAggregate ;
@ -11,6 +12,7 @@ using SJZY.Track.Domain.Dtos.TrackDetails;
using SJZY.Track.Domain.Dtos.Warning ;
using SJZY.Track.Domain.Enums ;
using SJZY.Track.Domain.Extensions ;
using SqlSugar ;
using Volo.Abp.DependencyInjection ;
namespace SJZY.Track.Application.Services.Warning.Handlers ;
@ -36,9 +38,10 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
_trackStatusRepository = trackStatusRepository ;
}
#region todo - test : 预 警 信 号 批 处 理 - 删 除 轨 迹
#region 预 警 信 号 批 处 理 - 删 除 轨 迹
// tips:删除轨迹信号在运输预警处理只关注被删除的轨迹的状态
// 可能影响【运输预警明细】【运输预警明细生成任务】
public async Task TrackDeletedHandleAsync ( List < TrackDeletedSignal > deletedSignals )
{
// 1.查询订单
@ -50,42 +53,35 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
) ) . ToHashSet ( ) ;
if ( orderIds . Count = = 0 ) return ;
// 1.1 构建订单和轨迹状态ids字典
// 利用信号 构建订单和轨迹状态ids字典
var orderIdTrackStatusIdsDict = deletedSignals
. Where ( s = > orderIds . Contains ( s . OrderId ) ) // tips: 信号 过滤
. Where ( s = > orderIds . Contains ( s . OrderId ) ) // tips: 过滤掉无需处理的信号
. GroupBy ( x = > x . OrderId )
. ToDictionary ( x = > x . Key , y = > y . Select ( z = > z . DeletedTrack . TrackStatusId ) . ToHashSet ( ) ) ;
if ( orderIdTrackStatusIdsDict . Count = = 0 ) return ;
// 2.查询订单每个状态最早轨迹的字点(tips: 由于已经是删除, 查询出的轨迹不会包含当前已经删除的轨迹)
var trackStatus EarliestDict = await _trackDetailsEsRepository . GetTrackStatusEarliestDictAsync ( orderIds ) ;
var orderIdTrackStatusId EarliestDict = await _trackDetailsEsRepository . GetTrackStatusEarliestDictAsync ( orderIds ) ;
// 3.查订单的运输时效预警明细,命中起始轨迹状态的(即将超时/已超时)
var warningDetails = await _warningDetailsEsRepository . GetTransportWarningDetailsAsync ( new GetTransportWarningDetailsVO
{
// tips:要求订单id+轨迹状态id同时满足的预警明细
OrderIdStartTracksStatusIdsDict = orderIdTrackStatusIdsDict
OrderIdStartTracksStatusIdsDict = orderIdTrackStatusIdsDict // tips:要求订单id+轨迹状态id同时满足的预警明细
} ) ;
// 订单和它的预警明细字典
var order DetailsDict = warningDetails
var order IdWarning DetailsDict = warningDetails
. GroupBy ( x = > x . OrderId )
. ToDictionary ( x = > x . Key , y = > y . ToList ( ) ) ;
// 4.查询预警明细生成任务 ,命中起始轨迹状态的(即将超时/已超时)
// 4.查询预警明细生成任务
var generateTasks = await _warningTaskRepository . GetTransportWarningDetailsGenerateTaskAsync ( x = >
! x . IsClosed
& & orderIds . Contains ( x . OrderId )
// && orderIdTrackStatusIdsDict[x.OrderId].Contains(x.StartTrackStatusId)
) ;
generateTasks = generateTasks . Where ( x = >
{
var statusIds = orderIdTrackStatusIdsDict [ x . OrderId ] ;
return statusIds . Contains ( x . StartTrackStatusId ) ;
} ) . ToList ( ) ;
// 订单和它的预警生成任务字典
var oderGenerateTaskDict = generateTasks
// 订单和它的预警生成任务字典, tips:只选择命中起始轨迹状态的任务
var orderIdGenerateTaskDict = generateTasks
. Where ( x = > orderIdTrackStatusIdsDict [ x . OrderId ] . Contains ( x . StartTrackStatusId ) ) // tips:字典一定存在该订单
. GroupBy ( x = > x . OrderId )
. ToDictionary ( x = > x . Key , y = > y . ToList ( ) ) ;
@ -95,24 +91,23 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
// 以订单的维度处理预警明细
foreach ( var orderId in orderIds )
{
var order Details = order DetailsDict. GetValueOrDefault ( orderId , Empty < TransportWarningDetailsIndex > . List ) ;
var orderTrackStatusEarliestDict = trackStatusEarliestDict. GetValueOrDefault ( orderId , new Dictionary < int , TrackDetailsIndex > ( 0 ) ) ;
var orderTasks = o derGenerateTaskDict. GetValueOrDefault ( orderId , Empty < TransportWarningDetailsGenerateTaskEntity > . List ) ;
var order Warning Details = order IdWarning DetailsDict. GetValueOrDefault ( orderId , Empty < TransportWarningDetailsIndex > . List ) ;
var orderTrackStatusEarliestDict = orderIdTrackStatusIdEarliestDict. GetValueOrDefault ( orderId , Empty < int , TrackDetailsIndex > . Dict ) ;
var orderTasks = o r derId GenerateTaskDict. GetValueOrDefault ( orderId , Empty < TransportWarningDetailsGenerateTaskEntity > . List ) ;
// 明细和生成任务都不存在跳过
if ( orderDetails . Count = = 0 & & orderTasks . Count = = 0 )
continue ;
// 预警明细和生成任务都不存在跳过
if ( orderWarningDetails . Count = = 0 & & orderTasks . Count = = 0 ) continue ;
// 轨迹全部被删除 直接关闭即可
// 轨迹全部被删除 关闭(预警生成任务,预警明细)
if ( orderTrackStatusEarliestDict . Count = = 0 )
{
order Details. ForEach ( x = >
order Warning Details. ForEach ( x = >
{
x . Status = TransportWarningStatus . 已 关 闭 . GetHashCode ( ) ;
x . CumulativeTimeSpan = x . CalcCumulativeTimeSpan ( ) ; //tips:完成态缓存累计运输时间
} ) ;
orderTasks . ForEach ( x = > x . IsClosed = true ) ;
needUpdateDetails . AddRange ( order Details) ;
needUpdateDetails . AddRange ( order Warning Details) ;
needUpdateGenerateTask . AddRange ( orderTasks ) ;
continue ;
}
@ -125,8 +120,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
// 尝试寻找该轨迹状态的最早轨迹
var earliestTrack = orderTrackStatusEarliestDict . GetValueOrDefault ( group . Key ) ;
// 不存在起始轨迹状态轨迹?
// 关闭预警生成任务
// 不存在起始轨迹状态轨迹?关闭预警生成任务
if ( earliestTrack = = null )
{
tasks . ForEach ( x = > x . IsClosed = true ) ;
@ -136,18 +130,18 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
// 存在起始状态最早轨迹?
// 如果任务上的起始轨迹发生时间有变动则修改为最新的
// todo:需要补充转化未utc0时区
foreach ( var task in tasks . Where ( x = > x . StartTrackTime ! = earliestTrack . TrackTime ) )
foreach ( var task in tasks . Where ( x = > x . GetUtc0StartTrackTime ( ) ! = earliestTrack . GetUtc0TrackTime ( ) ) )
{
task . StartTrackTime = earliestTrack . TrackTime ;
task . StartTrackTimeZone = earliestTrack . TrackTimeZone ;
task . PlanExecutionTime = earliestTrack . TrackTime . AddHours ( task . StartTrackWarningTimeSpan ) ;
// tips:任务执行的时区为+8, 所以需要将起始状态最早轨迹转化为+8时区来计算计划执行时间
task . PlanExecutionTime = earliestTrack . GetUtc0TrackTime ( ) . AddHours ( task . StartTrackWarningTimeSpan + 8f ) ;
needUpdateGenerateTask . Add ( task ) ;
}
}
// 以起始轨迹状态id分组处理预警明细
foreach ( var group in order Details. GroupBy ( x = > x . StartTrackStatusId ) )
foreach ( var group in order Warning Details. GroupBy ( x = > x . StartTrackStatusId ) )
{
var details = group . ToList ( ) ;
@ -173,18 +167,17 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
}
// 存在起始状态最早轨迹?
// 最早轨迹如果早于预警明细中的起始轨迹时间,则修改预警明细
// todo:时区信息如果未提供则比较时间无意义!!,出现一个有时区一个无时区(后续可能强约束时区必填)?
// 最早轨迹如果有变化,则同步修改预警明细
foreach ( var detail in details )
{
//保持预警明细中始终为起始状态的最早轨迹
if ( detail . GetUtc0StartTrackTime ( ) = = earliestTrack . GetUtc0TrackTime ( ) ) continue ;
detail . StartTrackContentId = earliestTrack . TrackContentId ;
detail . StartTrackContent = earliestTrack . TrackContent ;
detail . StartTrackTime = earliestTrack . TrackTime ;
detail . StartTrackTimeZone = earliestTrack . TrackTimeZone ;
needUpdateDetails . Add ( detail ) ;
}
needUpdateDetails . AddRange ( details ) ;
}
}
@ -203,81 +196,116 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
#endregion
#region todo - test : 预 警 信 号 批 处 理 - 新 增 修 改 轨 迹
#region 预 警 信 号 批 处 理 - 新 增 修 改 轨 迹
// tips:新增修改轨迹信号,在运输处理关注最新的轨迹
public async Task TrackAddedOrUpdatedHandleAsync ( List < IWarningSignal > addOrUpdateSignals )
{
// 1.查询订单
var orderIdSet = addOrUpdateSignals . Select ( x = > x . OrderId ) . ToHashSet ( ) ;
// 只处理未完结并且未删除的订单
// tips: 只处理未完结并且未删除的订单
var orders = await _orderRepository . GetListAsync ( x = > orderIdSet . Contains ( x . Id ) & & x . IsCompleted = = false ) ;
if ( orders . Count = = 0 ) return ; //无任何订单需要处理,直接提交信号丢弃
if ( orders . Count = = 0 ) return ;
var orderIds = orders . Select ( x = > x . Id ) . ToHashSet ( ) ;
// 1.1 构建订单和轨迹状态ids字典
var orderIdTrackStatusIdsDict = addOrUpdateSignals
. Where ( x = > orderIds . Contains ( x . OrderId ) ) // tips:信号过滤
. GroupBy ( x = > x . OrderId )
. ToDictionary ( x = > x . Key , y = >
y . Select ( x = > x . Type = = WarningSignalType . 轨 迹 新 增
? ( ( TrackAddedSignal ) x ) . TrackStatusId
: ( ( TrackUpdatedSignal ) x ) . BeforeChangeTrack . TrackStatusId
) . ToHashSet ( )
) ;
if ( orderIdTrackStatusIdsDict . Count = = 0 ) return ;
// 构建订单和轨迹状态ids字典 tips:可以利用此优化查询轨迹
// var orderIdTrackStatusIdsDict = addOrUpdateSignals
// .Where(x => orderIds.Contains(x.OrderId)) // tips:信号过滤
// .GroupBy(x => x.OrderId)
// .ToDictionary(x => x.Key, y =>
// y.Select(x => x.Type == WarningSignalType.轨迹新增
// ? ((TrackAddedSignal) x).TrackStatusId
// : ((TrackUpdatedSignal) x).BeforeChangeTrack.TrackStatusId
// ).ToHashSet()
// );
// 2.查询订单所有轨迹(tips: 查最新轨迹) k:订单id v:[k:轨迹状态id v:轨迹状态下最早轨迹]
var earliestTrackStatusTrackDict = await _trackDetailsEsRepository . GetTrackStatusEarliestDictAsync ( orderIds ) ;
// 3.以订单维度处理
// 过滤没有轨迹的订单
orders = orders . Where ( x = > earliestTrackStatusTrackDict . ContainsKey ( x . Id ) ) . ToList ( ) ;
if ( orders . Count = = 0 ) return ;
// 3.查轨迹主体
var conditions = orders . Select ( x = > ( x . SubSystemId , x . CustomId ) ) . ToHashSet ( ) ;
var ruleDict = await _warningRuleRepository . GetWarningRuleForEnabledAsync ( conditions , WarningRuleType . 运 输 时 效 预 警 ) ;
if ( ruleDict . Count = = 0 ) return ;
// 4.查规则场景
var ruleIds = ruleDict . Keys . ToHashSet ( ) ;
var scenes = await _warningRuleRepository . GetTransportSceneAsync ( x = > ruleIds . Contains ( x . WarningId ) ) ;
if ( scenes . Count = = 0 ) return ;
// 5.查区域信息
var areaIds = scenes . Where ( x = > x . AreaId > 0 ) . Select ( x = > x . AreaId ! . Value ) . ToHashSet ( ) ;
var ruleAreaInfosDict = await _kpiAreaRepository . GetAreaInfosDictByAreaId ( areaIds ) ;
// 选出订单命中的场景
var hitSceneIds = new HashSet < int > ( ) ;
var orderIdHitSceneIdsDict = new Dictionary < int , HashSet < int > > ( ) ;
var sceneBos = TransportWarningSceneBO . From ( scenes ) ;
foreach ( var order in orders )
{
var sceneSet = new HashSet < int > ( ) ;
foreach ( var scene in sceneBos )
{
if ( ! scene . CanHitScene ( order , ruleAreaInfosDict . GetValueOrDefault ( scene . AreaId ? ? 0 ) ) ) continue ;
sceneSet . Add ( scene . Id ) ;
hitSceneIds . Add ( scene . Id ) ;
}
if ( sceneSet . Count > 0 )
orderIdHitSceneIdsDict . TryAdd ( order . Id , sceneSet ) ;
}
if ( orderIdHitSceneIdsDict . Count = = 0 ) return ;
// 6.查预警规则项目,所有被命中的场景下
var allRuleItems = await _warningRuleRepository . GetTransportSceneRuleItemsAsync ( x = > hitSceneIds . Contains ( x . TransportWarningSceneId ) ) ;
if ( allRuleItems . Count = = 0 ) return ;
var allRuleItemBos = TransportWarningSceneRuleItemBO . From ( allRuleItems ) ;
var ruleItemBoDict = allRuleItemBos . ToDictionary ( x = > x . Id ) ;
// 建立订单和预警规则ids的关联字典
var orderIdRuleItemIdsDict = new Dictionary < int , HashSet < int > > ( ) ;
foreach ( var order in orders )
{
var sceneIds = orderIdHitSceneIdsDict . GetValueOrDefault ( order . Id ) ;
if ( sceneIds = = null ) continue ;
var ruleItems = allRuleItemBos . Where ( x = > sceneIds . Contains ( x . SceneId ) ) . ToList ( ) ;
if ( ruleItems . Count = = 0 ) continue ;
orderIdRuleItemIdsDict . TryAdd ( order . Id , ruleItems . Select ( x = > x . Id ) . ToHashSet ( ) ) ;
}
// 7.查预警明细 订单所有跟规则相关的明细,要求(即将超时/已超时)
var allWarningDetails = await _warningDetailsEsRepository . GetTransportWarningDetailsAsync ( new GetTransportWarningDetailsVO
{
OrderIdRuleItemIdsDict = orderIdRuleItemIdsDict ,
} ) ;
var orderIdWarningDetailDict = allWarningDetails
. GroupBy ( x = > x . OrderId )
. ToDictionary ( x = > x . Key , y = > y . ToList ( ) ) ;
// 8.查预警生成任务
Expression < Func < TransportWarningDetailsGenerateTaskEntity , bool > > baseExp = x = > x . IsClosed = = false ;
var exp = Expressionable . Create < TransportWarningDetailsGenerateTaskEntity > ( ) ;
foreach ( var ( orderId , ruleItemIds ) in orderIdRuleItemIdsDict )
exp . Or ( x = > x . OrderId = = orderId & & ruleItemIds . Contains ( x . WarningSceneRuleItemId ) ) ;
var allWarningTasks = await _warningTaskRepository . GetTransportWarningDetailsGenerateTaskAsync ( baseExp . And ( exp . ToExpression ( ) ) ) ;
var orderIdWarningTaskDict = allWarningTasks
. GroupBy ( x = > x . OrderId )
. ToDictionary ( x = > x . Key , y = > y . ToList ( ) ) ;
// 9.以订单维度处理
var updateDetails = new List < TransportWarningDetailsIndex > ( ) ;
var addDetailGenerateTasks = new List < TransportWarningDetailsGenerateTaskEntity > ( ) ;
var updateDetailGenerateTasks = new List < TransportWarningDetailsGenerateTaskEntity > ( ) ;
var closeNotifyDetailsIds = new HashSet < string > ( ) ;
// todo:优化流程
foreach ( var order in orders )
{
var trackStatusTrackDict = earliestTrackStatusTrackDict . GetValueOrDefault ( order . Id ) ;
if ( trackStatusTrackDict = = null ) continue ;
// 匹配规则主体,要求已经启用
var rule = await _warningRuleRepository . GetWarningRuleForEnabledAsync ( order . SubSystemId , order . CustomId , WarningRuleType . 运 输 时 效 预 警 ) ;
if ( rule = = null ) continue ;
// 查找主体下所有场景
var scenes = await _warningRuleRepository . GetTransportSceneAsync ( rule . Id ) ;
if ( scenes . Count = = 0 ) continue ;
// 查找场景关联的区域信息
var areaIds = scenes . Select ( x = > x . AreaId ? ? 0 ) . ToHashSet ( ) ;
var ruleAreaInfosDict = await _kpiAreaRepository . GetAreaInfosDictByAreaId ( areaIds ) ;
// 选出订单命中的场景ids
var sceneBos = TransportWarningSceneBO . From ( scenes ) ;
var hitSceneIds = sceneBos
. Where ( x = > x . CanHitScene ( order , ruleAreaInfosDict . GetValueOrDefault ( x . AreaId ? ? 0 ) ) )
. Select ( x = > x . Id )
. ToHashSet ( ) ;
// 查询命中场景下的所有规则项目
var ruleItems = await _warningRuleRepository . GetTransportSceneRuleItemsAsync ( x = > hitSceneIds . Contains ( x . TransportWarningSceneId ) , y = > y ) ;
if ( ruleItems . Count = = 0 ) continue ;
var ruleItemIds = ruleItems . Select ( x = > x . Id ) . ToHashSet ( ) ;
var ruleItemBoDict = TransportWarningSceneRuleItemBO
. From ( ruleItems )
. ToDictionary ( x = > x . Id ) ;
// 查订单所有跟规则相关的明细,要求(即将超时/已超时)
var warningDetails = await _warningDetailsEsRepository . GetTransportWarningDetailsAsync ( new GetTransportWarningDetailsVO
{
RuleItemIds = ruleItemIds ,
OrderIds = new HashSet < int > ( 1 )
{
order . Id
} ,
} ) ;
var trackStatusTrackDict = earliestTrackStatusTrackDict [ order . Id ] ; // 一定存在,已经存在前置过滤
var warningDetails = orderIdWarningDetailDict . GetValueOrDefault ( order . Id , Empty < TransportWarningDetailsIndex > . List ) ;
// 处理【通知阶段】的预警明细
if ( warningDetails . Count > 0 )
@ -287,12 +315,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
closeNotifyDetailsIds . UnionWith ( needCloseNotifyDetailsIds ) ;
}
// 查订单所有跟规则相关的明细生成任务(未来可能会执行),要求(未关闭)
var orderTasks = await _warningTaskRepository . GetTransportWarningDetailsGenerateTaskAsync ( x = >
! x . IsClosed
& & x . OrderId = = order . Id
& & ruleItemIds . Contains ( x . WarningSceneRuleItemId )
) ;
var orderTasks = orderIdWarningTaskDict . GetValueOrDefault ( order . Id , Empty < TransportWarningDetailsGenerateTaskEntity > . List ) ;
// 处理【预警明细生成就绪阶段】预警明细生成任务
var ( updateTasks , addTasks ) = HandleDetailGenerateTask ( order , orderTasks , warningDetails , ruleItemBoDict , trackStatusTrackDict ) ;
@ -300,7 +323,6 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
updateDetailGenerateTasks . AddRange ( updateTasks ) ;
}
// 4.批量操作
if ( closeNotifyDetailsIds . Count > 0 )
{
await _warningTaskRepository . CloseWarningNotifyTaskAsync ( x = >
@ -321,7 +343,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
// 处理【通知阶段】的预警明细
// 起始轨迹状态轨迹变更(存在起始,不存在截止)
// 收到了截止轨迹(存在起始,存在截止)
private ( List < TransportWarningDetailsIndex > UpdateDeatils , HashSet < string > CloseNotifyDetailIds ) HandleExistsDetails (
private static ( List < TransportWarningDetailsIndex > UpdateDeatils , HashSet < string > CloseNotifyDetailIds ) HandleExistsDetails (
List < TransportWarningDetailsIndex > warningDetails ,
Dictionary < int , TransportWarningSceneRuleItemBO > ruleItemBoDict ,
Dictionary < int , TrackDetailsIndex > trackStatusIdEarliestTrackDict
@ -400,7 +422,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
// 命中:存在任务,起始轨迹状态轨迹变更则更新任务信息,
// 命中:不存在任务,添加生成任务
// 未命中,已有的任务关闭,没有的忽略生成
private ( List < TransportWarningDetailsGenerateTaskEntity > UpdateTasks , List < TransportWarningDetailsGenerateTaskEntity > AddTasks ) HandleDetailGenerateTask ( OrderEntity order ,
private static ( List < TransportWarningDetailsGenerateTaskEntity > UpdateTasks , List < TransportWarningDetailsGenerateTaskEntity > AddTasks ) HandleDetailGenerateTask ( OrderEntity order ,
List < TransportWarningDetailsGenerateTaskEntity > tasks ,
List < TransportWarningDetailsIndex > warningDetails ,
Dictionary < int , TransportWarningSceneRuleItemBO > ruleItemBoDict ,
@ -460,7 +482,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
return ( updateTasks , insertTasks ) ;
}
private TransportWarningDetailsGenerateTaskEntity BuildDetailsGenerateTask (
private static TransportWarningDetailsGenerateTaskEntity BuildDetailsGenerateTask (
OrderEntity order ,
TransportWarningSceneRuleItemBO ruleItem ,
TrackDetailsIndex earliestTrack
@ -485,7 +507,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
#endregion 预 警 信 号 处 理
#region todo - test : 运 输 预 警 主 体 关 闭
#region 运 输 预 警 主 体 关 闭
public async Task WarningRuleToDisabledHandleAsync ( WarningRuleEntity rule )
{
@ -517,7 +539,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
#endregion
#region todo - test : 规 则 场 景 变 更
#region 规 则 场 景 变 更
// tips:由于只是改动了场景,只要订单仍然命中场景,那么订单相关的预警生成任务/预警通知任务无需处理,预警明细更新部分场景信息。未命中则相关联条目全部删除
// 更新:删除不符合【场景】条件的【预警生成任务】【预警明细】【预警通知任务】,符合场景则修改预警明细的【预警规则描述】
@ -526,17 +548,17 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
if ( ! CanSceneChange ( oldScene , postScene ) )
return ;
// 1. 1 找到该场景下所有的预警生成任务(未关闭的)
// 1. 找到该场景下所有的预警生成任务(未关闭的)
var generateTasks = await _warningTaskRepository . GetTransportWarningDetailsGenerateTaskAsync ( x = >
! x . IsClosed
& & x . WarningId = = postScene . Id
& & x . WarningId = = postScene . Warning Id
& & x . WarningSceneId = = postScene . Id
) ;
// 1.1 预警生成任务反找订单id
// 预警生成任务反找订单id
var orderIds = generateTasks . Select ( x = > x . OrderId ) . ToHashSet ( ) ;
// 2. 1 找到该场景下所有的预警明细(即将超时/已超时)
// 2. 找到该场景下所有的预警明细(即将超时/已超时)
var warningDetails = await _warningDetailsEsRepository . GetTransportWarningDetailsAsync ( new GetTransportWarningDetailsVO ( )
{
SceneIds = new HashSet < int > ( 1 )
@ -545,7 +567,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
} ,
} ) ;
// 2.2 预警明细反找订单id并合并
// 预警明细反找订单id并合并
orderIds . UnionWith ( warningDetails . Select ( x = > x . OrderId ) ) ;
// tips:无需在通过预警通知任务反找订单,因为产生预警通知任务时预警明细已经存在!
@ -574,9 +596,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
// 明细->规则
var updateDetails = warningDetails . Where ( x = > reHitSceneOrderIds . Contains ( x . OrderId ) ) . ToList ( ) ;
var updateRuleItemIds = updateDetails . Select ( x = > x . WarningSceneRuleItemId ) . ToHashSet ( ) ;
var updateRuleItems = await _warningRuleRepository . GetTransportSceneRuleItemsAsync (
x = > updateRuleItemIds . Contains ( x . Id ) ,
y = > y ) ;
var updateRuleItems = await _warningRuleRepository . GetTransportSceneRuleItemsAsync ( x = > updateRuleItemIds . Contains ( x . Id ) ) ;
var ruleItemDict = updateRuleItems . ToDictionary ( x = > x . Id ) ;
// 场景->区域
@ -596,8 +616,8 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
if ( needUpdateDetails . Count > 0 )
await _warningDetailsEsRepository . BulkUpdateTransportWarningDetailsAsync ( needUpdateDetails ) ;
if ( noHitSceneOrderIds . Count = = 0 )
return ;
// 没有任何未命中场景的订单
if ( noHitSceneOrderIds . Count = = 0 ) return ;
// 5.关闭不符合场景的【预警明细】【预警生成任务】【预警通知任务】
// 预警明细状态修改为已关闭(即将超时/已超时)
@ -654,7 +674,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
) ;
}
private bool CanSceneChange ( TransportWarningSceneBO oldScene , TransportWarningSceneBO postScene )
private static bool CanSceneChange ( TransportWarningSceneBO oldScene , TransportWarningSceneBO postScene )
{
return oldScene . CargoType ! = postScene . CargoType | | //多个 普货,危险品
oldScene . Months ! = postScene . Months | | //多个 约束提交的月份组从小到大 1/3/4, 不能出现 4/1/3这种 (如果出现则SequenceEqual)
@ -666,7 +686,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
#endregion todo : 规 则 场 景 变 更
#region todo - test : 规 则 项 目 变 更
#region 规 则 项 目 变 更
public async Task HandleEditAsync ( WarningRuleEntity rule , TransportWarningSceneBO scene , List < TransportWarningSceneRuleItemBO > postRuleItems )
{
@ -746,7 +766,6 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
await HandleDeleteAsync ( ruleItemIds ) ;
}
// todo:需要优化
private async Task HandleRuleItemsChangeAsync (
WarningRuleEntity rule ,
TransportWarningSceneBO scene ,
@ -771,31 +790,15 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
var deleteRuleItemIds = deleteRuleItems . Select ( x = > x . Id ) . ToHashSet ( ) ;
if ( deleteRuleItemIds . Count > 0 )
await _warningRuleRepository . DeleteTransportSceneRuleItemsAsync ( deleteRuleItemIds ) ;
// 不存在更新需要关注的,也不存在删除的
if ( updateFollowRuleItems . Count = = 0 & & deleteRuleItemIds . Count = = 0 ) return ;
// 只存在删除的规则项目,直接关闭处理返回即可
if ( updateFollowRuleItems . Count = = 0 )
{
// 关闭相关的预警生成任务(未关闭的)
await _warningTaskRepository . CloseTransportWarningDetailsGenerateTaskAsync ( x = >
! x . IsClosed
& & x . WarningId = = rule . Id
& & deleteRuleItemIds . Contains ( x . WarningSceneRuleItemId )
) ;
// 关闭关联的预警通知任务(未关闭的)
await _warningTaskRepository . CloseWarningNotifyTaskAsync ( x = >
! x . IsClosed
& & x . WarningId = = rule . Id
& & x . WarningType = = WarningRuleType . 运 输 时 效 预 警 . GetHashCode ( )
& & deleteRuleItemIds . Contains ( x . WarningRuleItemId )
) ;
return ;
await _warningRuleRepository . DeleteTransportSceneRuleItemsAsync ( deleteRuleItemIds ) ;
// 处理删除规则后的【预警明细】和【预警生成任务】和【预警通知任务】
await HandleDeleteAsync ( deleteRuleItemIds ) ;
}
// 不存在更新需要关注的
if ( updateFollowRuleItems . Count = = 0 ) return ;
// 1.查询变更配置相关的预警生成任务(未关闭的)
var updateFollowRuleItemIds = updateFollowRuleItems . Select ( x = > x . Id ) . ToHashSet ( ) ;
var generateTasks = await _warningTaskRepository . GetTransportWarningDetailsGenerateTaskAsync ( x = >
@ -915,25 +918,17 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
await _warningTaskRepository . BulkUpdateTransportWarningDetailsGenerateTaskAsync ( updateGenerateTasks ) ;
// 3.3 处理需要关闭的【预警明细】【预警生成任务】【预警通知任务】(未命中规则)
var typeId sDict = handleBlocks
. Except ( reHitRuleBlocks )
var notHitHandleBlock sDict = 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 ( )
} ;
} ) ;
. ToDictionary ( x = > x . Key , y = > y . ToList ( ) ) ;
// 4.处理删除规则的相关联的【预警明细】【预警生成任务】【预警通知任务】
// 预警信息状态修改为已关闭(即将超时/已超时)
var closeDetail Ids = typeIdsDict . GetValueOrDefault ( HandleType . Detail , new HashSet < string > ( ) ) ;
if ( closeDetail Id s. Count > 0 )
var closeDetailHandleBlocks = notHitHandleBlocksDict . GetValueOrDefault ( HandleType . Detail , Empty < HandleBlock > . List ) ;
if ( closeDetailHandleBlocks . Count > 0 )
{
var closeDetailIds = closeDetailHandleBlocks . Select ( x = > x . Detail . Id ) . ToHashSet ( ) ;
await _warningDetailsEsRepository . BulkCloseTransportWarningDetailsAsync ( new BulkCloseTransportWarningDetailsVO
{
DetailsIds = closeDetailIds ,
@ -941,25 +936,26 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
}
// 关闭相关的预警生成任务(未关闭的)
var closeGenerateTaskIds = typeIdsDict . GetValueOrDefault ( HandleType . GenerateTask , new HashSet < string > ( ) ) ;
var closeGenerateTaskHandleBlocks = notHitHandleBlocksDict . GetValueOrDefault ( HandleType . GenerateTask , Empty < HandleBlock > . List ) ;
if ( closeGenerateTaskHandleBlocks . Count > 0 )
{
var closeGenerateTaskIds = closeGenerateTaskHandleBlocks . Select ( x = > x . GenerateTask . Id ) . ToHashSet ( ) ;
await _warningTaskRepository . CloseTransportWarningDetailsGenerateTaskAsync ( x = >
! x . IsClosed
& & (
closeGenerateTaskIds . Contains ( x . Id . ToString ( ) )
| | x . WarningId = = rule . Id & & deleteRuleItemIds . Contains ( x . WarningSceneRuleItemId )
)
& & closeGenerateTaskIds . Contains ( x . Id )
) ;
}
// 关闭关联的预警通知任务(未关闭的)
var closeNotifyTaskIds = typeIdsDict . GetValueOrDefault ( HandleType . NotifyTask , new HashSet < string > ( ) ) ;
var closeNotifyTaskHandleBlocks = notHitHandleBlocksDict . GetValueOrDefault ( HandleType . NotifyTask , Empty < HandleBlock > . List ) ;
if ( closeNotifyTaskHandleBlocks . Count > 0 )
{
var closeNotifyTaskIds = closeNotifyTaskHandleBlocks . Select ( x = > x . NotifyTask . Id ) . ToHashSet ( ) ;
await _warningTaskRepository . CloseWarningNotifyTaskAsync ( x = >
! x . IsClosed
& & (
closeNotifyTaskIds . Contains ( x . Id . ToString ( ) )
| | x . WarningId = = rule . Id
& & x . WarningType = = WarningRuleType . 运 输 时 效 预 警 . GetHashCode ( )
& & deleteRuleItemIds . Contains ( x . WarningRuleItemId )
) ) ;
& & closeNotifyTaskIds . Contains ( x . Id )
) ;
}
}
private async Task HandleDeleteAsync ( HashSet < int > deleteRuleItemIds )
@ -1060,17 +1056,14 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
#endregion todo : 规 则 项 目 变 更
#region todo - test : 批 量 处 理 预 警 明 细 生 成 任 务
#region 批 量 处 理 预 警 明 细 生 成 任 务
public async Task HandleWarningDetailsGenerateTask ( List < TransportWarningDetailsGenerateTaskEntity > tasks )
{
// 1.查询订单,tips:只处理未完结并且未删除的订单
var orderIdSet = tasks . Select ( x = > x . OrderId ) . ToHashSet ( ) ;
var orders = await _orderRepository . GetListAsync ( x = >
orderIdSet . Contains ( x . Id )
& & x . IsCompleted = = false
) ;
if ( orders . Count = = 0 ) return ; //不存在符合条件的订单,直接全部关闭
var orders = await _orderRepository . GetListAsync ( x = > orderIdSet . Contains ( x . Id ) & & x . IsCompleted = = false ) ;
if ( orders . Count = = 0 ) return ;
// 构建订单id和订单字典
var orderDict = orders . ToDictionary ( x = > x . Id ) ;
@ -1095,13 +1088,13 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
{
OrderIdTracksStatusIdsDict = orderIdTrackStatusIdsDict
} ) ;
if ( orderTracksDict . Count = = 0 ) return ; //不存在轨迹,直接全部关闭
if ( orderTracksDict . Count = = 0 ) return ;
// 3.查出任务相关,运输时效规则配置
// 查出启用的规则主体
var warningIds = tasks . Select ( x = > x . WarningId ) . ToHashSet ( ) ;
var waningRules = await _warningRuleRepository . GetListAsync ( x = > x . IsEnabled & & warningIds . Contains ( x . Id ) ) ;
if ( waningRules . Count = = 0 ) return ; //不存在启用的规则主体,直接全部关闭
if ( waningRules . Count = = 0 ) return ;
// 构建规则主体id和版本号字典,稍后用于填充明细的版本号
var ruleDict = waningRules . ToDictionary ( x = > x . Id ) ;
@ -1114,8 +1107,8 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
if ( ruleItemIds . Count = = 0 ) return ;
// 查出规则配置
var ruleItems = await _warningRuleRepository . GetTransportSceneRuleItemsAsync ( x = > ruleItemIds . Contains ( x . Id ) , y = > y );
if ( ruleItems . Count = = 0 ) return ; //不存在规则配置,直接全部关闭
var ruleItems = await _warningRuleRepository . GetTransportSceneRuleItemsAsync ( x = > ruleItemIds . Contains ( x . Id ) );
if ( ruleItems . Count = = 0 ) return ;
// 构建规则id和规则条目字典
var ruleItemDict = ruleItems . ToDictionary ( x = > x . Id ) ;
@ -1123,7 +1116,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
// 4.选出可以执行的任务和需要关闭的任务
var needCloseTaskIds = new HashSet < int > ( ) ;
var addDetails = new List < TransportWarningDetailsIndex > ( ) ;
foreach ( ( int orderId , List < TransportWarningDetailsGenerateTaskEntity > orderTasks ) in orderIdTasksDict )
foreach ( var ( orderId , orderTasks ) in orderIdTasksDict )
{
var order = orderDict . GetValueOrDefault ( orderId ) ;
// 订单不存在/已完结 直接关闭任务即可
@ -1216,7 +1209,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
}
private TransportWarningDetailsIndex BuildTransportWarningDetail (
private static TransportWarningDetailsIndex BuildTransportWarningDetail (
OrderEntity order ,
TransportWarningSceneRuleItemEntity ruleItem ,
List < TrackDetailsIndex > tracks
@ -1269,7 +1262,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen
return detail ;
}
private List < WarningNotifyTaskEntity > BuildWarningNotifyTask ( List < TransportWarningDetailsIndex > details )
private static List < WarningNotifyTaskEntity > BuildWarningNotifyTask ( List < TransportWarningDetailsIndex > details )
{
return details . Select ( x = > new WarningNotifyTaskEntity
{