优化
This commit is contained in:
parent
4a2b87ba36
commit
e0e376404e
@ -7,9 +7,22 @@ public class WarningDto
|
||||
/// </summary>
|
||||
public int TrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int CustomerId { get; set; }
|
||||
|
||||
public List<WarningOrderDto> Orders { get; set; } = new();
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"子系统:{SubSystemId},客户:{CustomerId},订单:{Orders.Select(x => x.Id)
|
||||
.JoinAsString(",")},发生轨迹状态{TrackStatusId}";
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,16 +2,6 @@ namespace SJZY.Track.Application.Contract.Events;
|
||||
|
||||
public class TrackChangeAfterUpdateOrderEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int CustomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单Id
|
||||
/// </summary>
|
||||
@ -32,11 +22,6 @@ public class TrackChangeAfterUpdateOrderEvent
|
||||
/// </summary>
|
||||
public string TrackEnContent { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹状态Id
|
||||
/// </summary>
|
||||
public int TrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹发生地
|
||||
/// </summary>
|
||||
@ -52,11 +37,6 @@ public class TrackChangeAfterUpdateOrderEvent
|
||||
/// </summary>
|
||||
public float TrackTimeZone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹内容代码
|
||||
/// </summary>
|
||||
public string? TrackCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时区缺失和发生地缺失标记,1表示时区,2表示发生地,3表示两种
|
||||
/// </summary>
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
namespace SJZY.Track.Application.Contract.Events;
|
||||
|
||||
public class TrackWarningCalcEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 子系统id
|
||||
/// </summary>
|
||||
public int SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户id
|
||||
/// </summary>
|
||||
public int CustomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹状态Id
|
||||
/// </summary>
|
||||
public int TrackStatusId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单id
|
||||
/// </summary>
|
||||
public int[] OrderIds { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹发生时间
|
||||
/// </summary>
|
||||
public DateTime TrackTime { get; set; }
|
||||
}
|
||||
@ -1,8 +1,6 @@
|
||||
using DotNetCore.CAP;
|
||||
using SJZY.Expand.ABP.Core.Logger;
|
||||
using SJZY.Track.Application.Contract.Dtos.Forewarning;
|
||||
using SJZY.Track.Application.Contract.Events;
|
||||
using SJZY.Track.Application.Contract.Services;
|
||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
@ -10,14 +8,11 @@ namespace SJZY.Track.Application.CAP.EventHandlers;
|
||||
|
||||
public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICapSubscribe
|
||||
{
|
||||
private readonly IForewarningNotifyService _forewarningNotifyService;
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
|
||||
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository,
|
||||
IForewarningNotifyService forewarningNotifyService)
|
||||
public TrackChangeAfterUpdateOrderEventHandler(IOrderRepository orderRepository)
|
||||
{
|
||||
_orderRepository = orderRepository;
|
||||
_forewarningNotifyService = forewarningNotifyService;
|
||||
}
|
||||
|
||||
[CapSubscribe(GlobalConst.TrackChangeAfterUpdateOrderSubscribe)]
|
||||
@ -27,7 +22,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
||||
|
||||
if (orders.Count == 0)
|
||||
{
|
||||
LogHelper.Warn("没有找到订单信息,无法更新轨迹信息");
|
||||
LogHelper.Warn($"没有找到订单信息:{@event.OrderIds.JoinAsString(",")},无法更新轨迹信息");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -74,9 +69,6 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
||||
x.LatestTrackTimeZone,
|
||||
x.DeficiencyTag
|
||||
});
|
||||
|
||||
// 预警计算
|
||||
await _forewarningNotifyService.WarningCalculateAsync(BuiltWarningDto(orders, @event));
|
||||
}
|
||||
|
||||
private async Task<List<OrderEntity>> GetOrdersAsync(int[] orderIds)
|
||||
@ -92,41 +84,6 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
||||
LatestTrackPlace = order.LatestTrackPlace,
|
||||
LatestTrackTime = order.LatestTrackTime,
|
||||
LatestTrackTimeZone = order.LatestTrackTimeZone,
|
||||
|
||||
// 因素
|
||||
CargoType = order.CargoType,
|
||||
CreateTime = order.CreateTime,
|
||||
ArrivalCountry = order.ArrivalCountry,
|
||||
ArrivalProvince = order.ArrivalProvince,
|
||||
ArrivalCity = order.ArrivalCity,
|
||||
ArrivalPostCode = order.ArrivalPostCode,
|
||||
IsTransit = order.IsTransit,
|
||||
LeavePort = order.LeavePort,
|
||||
ProductCode = order.ProductCode,
|
||||
});
|
||||
}
|
||||
|
||||
private WarningDto BuiltWarningDto(List<OrderEntity> orders, TrackChangeAfterUpdateOrderEvent @event)
|
||||
{
|
||||
return new WarningDto
|
||||
{
|
||||
TrackStatusId = @event.TrackStatusId,
|
||||
SubSystemId = @event.SubSystemId,
|
||||
CustomerId = @event.CustomId,
|
||||
Orders = orders.Select(order => new WarningOrderDto
|
||||
{
|
||||
Id = order.Id,
|
||||
TrackTime = @event.TrackTime,
|
||||
CargoType = order.CargoType,
|
||||
Month = order.CreateTime.Month,
|
||||
IsTransit = order.IsTransit,
|
||||
LeavePort = order.LeavePort,
|
||||
ProductCode = order.ProductCode,
|
||||
ArrivalCountry = order.ArrivalCountry,
|
||||
ArrivalProvince = order.ArrivalProvince,
|
||||
ArrivalCity = order.ArrivalCity,
|
||||
ArrivalPostCode = order.ArrivalPostCode,
|
||||
}).ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ using SJZY.Expand.ABP.Core.PublicMethords;
|
||||
using SJZY.Track.Application.Contract.Events;
|
||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Dtos.TrackContents;
|
||||
using SJZY.Track.Domain.Queries;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using OrderIdentifier = SJZY.Track.Application.Contract.Events.OrderIdentifier;
|
||||
@ -135,12 +136,74 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
||||
return;
|
||||
}
|
||||
|
||||
var insertTracks = await UpsertTrackAsync(@event, canNextOrderIds, trackContent);
|
||||
|
||||
if (canNextOrderIds.Count == 0) return;
|
||||
|
||||
if (insertTracks.Any())
|
||||
{
|
||||
// 批量add to es
|
||||
await _trackDetailsEsRepository.AddManyAsync(insertTracks);
|
||||
|
||||
// 添加轨迹触发订单拉取状态更新
|
||||
await _orderRepository.UpdatePullStatusToSilenceAsync(insertTracks.Select(x => x.OrderId).ToList(),
|
||||
@event.TrackCode);
|
||||
|
||||
// 添加轨迹触发预警计算(异步)
|
||||
await _capPublisher.PublishAsync(GlobalConst.TrackWarningCalcSubscribe, new TrackWarningCalcEvent
|
||||
{
|
||||
SubSystemId = @event.SubSystemId,
|
||||
CustomId = @event.CustomId,
|
||||
OrderIds = canNextOrderIds.ToArray(),
|
||||
TrackStatusId = trackContent.TrackStatusId,
|
||||
TrackTime = @event.TrackTime,
|
||||
});
|
||||
}
|
||||
|
||||
// 触发订单主表更新事件(异步)
|
||||
await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe,
|
||||
new TrackChangeAfterUpdateOrderEvent
|
||||
{
|
||||
OrderIds = canNextOrderIds.ToArray(),
|
||||
IsCompleted = trackContent.IsCompleted,
|
||||
TrackContent = trackContent.TrackContent,
|
||||
TrackEnContent = trackContent.TrackEnContent,
|
||||
TrackPlace = @event.TrackPlace,
|
||||
TrackTime = @event.TrackTime,
|
||||
TrackTimeZone = @event.TrackTimeZone,
|
||||
DeficiencyTagValue = @event.DeficiencyTagValue
|
||||
});
|
||||
|
||||
// 触发轨迹推送事件(异步)
|
||||
var trackPushEvent = new TrackPushEvent
|
||||
{
|
||||
OptionType = @event.IsAdd ? OptionType.新增 : OptionType.修改,
|
||||
SubSystemId = @event.SubSystemId,
|
||||
CustomId = @event.CustomId,
|
||||
OrderIds = canNextOrderIds.ToArray(),
|
||||
TrackCode = @event.TrackCode,
|
||||
SystemPushInfo = new SystemPushStruct
|
||||
{
|
||||
TrackStatus = trackContent.TrackStatus,
|
||||
TrackContent = trackContent.TrackContent,
|
||||
TrackPlace = @event.TrackPlace,
|
||||
TrackTime = @event.TrackTime,
|
||||
TrackTimeZone = @event.TrackTimeZone
|
||||
}
|
||||
};
|
||||
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent);
|
||||
}
|
||||
|
||||
private async Task<List<TrackDetailsIndex>> UpsertTrackAsync(TrackUpsertEvent @event, List<int> canNextOrderIds,
|
||||
TrackContentVO trackContent)
|
||||
{
|
||||
var orderIds = @event.OrderIdentifiers.Select(x => x.OrderId).ToArray();
|
||||
|
||||
// important:轨迹code相同,时间、发生地不同的,可能存在多条!!
|
||||
var tracks = await _trackDetailsEsRepository.GetListAsync(orderIds, @event.TrackCode, true);
|
||||
|
||||
var insertTracks = new List<TrackDetailsIndex>();
|
||||
var updateTracks = new List<TrackDetailsIndex>();
|
||||
|
||||
foreach (var order in @event.OrderIdentifiers)
|
||||
{
|
||||
@ -204,59 +267,17 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
|
||||
track.UpdateUser = @event.OperationMan ?? GlobalConst.SystemUser;
|
||||
track.UpdateTime = DateTime.Now;
|
||||
|
||||
await _trackDetailsEsRepository.UpdateAsync(track);
|
||||
updateTracks.Add(track);
|
||||
}
|
||||
|
||||
canNextOrderIds.Add(order.OrderId);
|
||||
}
|
||||
|
||||
if (canNextOrderIds.Count == 0) return;
|
||||
|
||||
if (insertTracks.Any())
|
||||
if (updateTracks.Any())
|
||||
{
|
||||
// 批量add to es
|
||||
await _trackDetailsEsRepository.AddManyAsync(insertTracks);
|
||||
|
||||
// add track触发订单拉取状态更新
|
||||
await _orderRepository.UpdatePullStatusToSilenceAsync(insertTracks.Select(x => x.OrderId).ToList(),
|
||||
@event.TrackCode);
|
||||
await _trackDetailsEsRepository.UpdateManyAsync(updateTracks);
|
||||
}
|
||||
|
||||
// 触发订单主表更新事件(异步)
|
||||
await _capPublisher.PublishAsync(GlobalConst.TrackChangeAfterUpdateOrderSubscribe,
|
||||
new TrackChangeAfterUpdateOrderEvent
|
||||
{
|
||||
SubSystemId = @event.SubSystemId,
|
||||
CustomId = @event.CustomId,
|
||||
OrderIds = canNextOrderIds.ToArray(),
|
||||
IsCompleted = trackContent.IsCompleted,
|
||||
TrackContent = trackContent.TrackContent,
|
||||
TrackEnContent = trackContent.TrackEnContent,
|
||||
TrackStatusId = trackContent.TrackStatusId,
|
||||
TrackPlace = @event.TrackPlace,
|
||||
TrackTime = @event.TrackTime,
|
||||
TrackTimeZone = @event.TrackTimeZone,
|
||||
TrackCode = @event.TrackCode,
|
||||
DeficiencyTagValue = @event.DeficiencyTagValue
|
||||
});
|
||||
|
||||
// 触发轨迹推送事件(异步)
|
||||
var trackPushEvent = new TrackPushEvent
|
||||
{
|
||||
OptionType = @event.IsAdd ? OptionType.新增 : OptionType.修改,
|
||||
SubSystemId = @event.SubSystemId,
|
||||
CustomId = @event.CustomId,
|
||||
OrderIds = canNextOrderIds.ToArray(),
|
||||
TrackCode = @event.TrackCode,
|
||||
SystemPushInfo = new SystemPushStruct
|
||||
{
|
||||
TrackStatus = trackContent.TrackStatus,
|
||||
TrackContent = trackContent.TrackContent,
|
||||
TrackPlace = @event.TrackPlace,
|
||||
TrackTime = @event.TrackTime,
|
||||
TrackTimeZone = @event.TrackTimeZone
|
||||
}
|
||||
};
|
||||
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent);
|
||||
return insertTracks;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
using DotNetCore.CAP;
|
||||
using SJZY.Expand.ABP.Core.Logger;
|
||||
using SJZY.Track.Application.Contract.Dtos.Forewarning;
|
||||
using SJZY.Track.Application.Contract.Events;
|
||||
using SJZY.Track.Application.Contract.Services;
|
||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace SJZY.Track.Application.CAP.EventHandlers;
|
||||
|
||||
public class TrackWarningCalcEventHandler : ITransientDependency, ICapSubscribe
|
||||
{
|
||||
private readonly IForewarningNotifyService _forewarningNotifyService;
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
|
||||
public TrackWarningCalcEventHandler(IOrderRepository orderRepository,
|
||||
IForewarningNotifyService forewarningNotifyService)
|
||||
{
|
||||
_orderRepository = orderRepository;
|
||||
_forewarningNotifyService = forewarningNotifyService;
|
||||
}
|
||||
|
||||
[CapSubscribe(GlobalConst.TrackWarningCalcSubscribe)]
|
||||
public async Task ConsumerAsync(TrackWarningCalcEvent @event)
|
||||
{
|
||||
var orders = await _orderRepository.GetListAsync(order => @event.OrderIds.Contains(order.Id), order =>
|
||||
new OrderEntity
|
||||
{
|
||||
Id = order.Id,
|
||||
// 因素
|
||||
CargoType = order.CargoType,
|
||||
CreateTime = order.CreateTime,
|
||||
ArrivalCountry = order.ArrivalCountry,
|
||||
ArrivalProvince = order.ArrivalProvince,
|
||||
ArrivalCity = order.ArrivalCity,
|
||||
ArrivalPostCode = order.ArrivalPostCode,
|
||||
IsTransit = order.IsTransit,
|
||||
LeavePort = order.LeavePort,
|
||||
ProductCode = order.ProductCode,
|
||||
});
|
||||
|
||||
if (orders.Count == 0)
|
||||
{
|
||||
LogHelper.Warn($"没有找到订单信息:{@event.OrderIds.JoinAsString(",")},无法做轨迹预警计算");
|
||||
return;
|
||||
}
|
||||
|
||||
// 预警计算
|
||||
await _forewarningNotifyService.WarningCalculateAsync(BuiltWarningDto(orders, @event));
|
||||
}
|
||||
|
||||
private WarningDto BuiltWarningDto(List<OrderEntity> orders, TrackWarningCalcEvent @event)
|
||||
{
|
||||
return new WarningDto
|
||||
{
|
||||
TrackStatusId = @event.TrackStatusId,
|
||||
SubSystemId = @event.SubSystemId,
|
||||
CustomerId = @event.CustomId,
|
||||
Orders = orders.Select(order => new WarningOrderDto
|
||||
{
|
||||
Id = order.Id,
|
||||
TrackTime = @event.TrackTime,
|
||||
CargoType = order.CargoType,
|
||||
Month = order.CreateTime.Month,
|
||||
IsTransit = order.IsTransit,
|
||||
LeavePort = order.LeavePort,
|
||||
ProductCode = order.ProductCode,
|
||||
ArrivalCountry = order.ArrivalCountry,
|
||||
ArrivalProvince = order.ArrivalProvince,
|
||||
ArrivalCity = order.ArrivalCity,
|
||||
ArrivalPostCode = order.ArrivalPostCode,
|
||||
}).ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -89,25 +89,28 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
}
|
||||
|
||||
var redisKey = GetForewarningNotifySetKeyRedisKey(dto.SubSystemId);
|
||||
long addCounter, delCounter = 0;
|
||||
|
||||
var tran = RedisHelper.Client.Multi();
|
||||
|
||||
// 左区间加入预警队列
|
||||
await tran.ZAddAsync(redisKey, adds.Select(x =>
|
||||
// 左区间加入预警队列,【只有第一次发生的才会被加入】
|
||||
addCounter = await tran.ZAddNxAsync(redisKey, adds.Select(x =>
|
||||
{
|
||||
var entry = new WarningNotifyCacheEntry(x.ruleId, x.orderId, x.counter);
|
||||
return new ZMember(entry.ToString(), x.ts);
|
||||
}).ToArray());
|
||||
|
||||
// 右区间移出预警队列
|
||||
// 右区间移出预警队列,【只要发生了就移除】
|
||||
var right = dels.Select(x => new WarningNotifyCacheEntry(x.ruleId, x.orderId, x.counter)).ToList();
|
||||
if (!right.IsNullOrEmpty())
|
||||
{
|
||||
await tran.ZRemAsync(redisKey, right.Select(x => x.ToString()).ToArray());
|
||||
delCounter = await tran.ZRemAsync(redisKey, right.Select(x => x.ToString()).ToArray());
|
||||
}
|
||||
|
||||
tran.Exec();
|
||||
|
||||
LogHelper.Info($"本次共计产生{addCounter}条预警,移除{delCounter}条预警,触发缘由是");
|
||||
|
||||
await _warningRecordEsRepository.BulkUpdateAsync(dels); // 标记处理完成
|
||||
}
|
||||
|
||||
@ -127,21 +130,21 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
var ruleIds = entries.Select(x => x.RuleId).Distinct().ToList();
|
||||
var notifyRules = await _warningQueries.GetWarningNotifyRulesAsync(ruleIds);
|
||||
|
||||
var userRules = new Dictionary<int, List<GetWarningNotifiesVo>>();
|
||||
foreach (var rule in notifyRules)
|
||||
{
|
||||
foreach (var userId in rule.NotifyUserIds)
|
||||
{
|
||||
if (!userRules.ContainsKey(userId))
|
||||
{
|
||||
userRules[userId] = new List<GetWarningNotifiesVo>();
|
||||
}
|
||||
|
||||
userRules[userId].Add(rule);
|
||||
}
|
||||
}
|
||||
|
||||
// 写入es预警记录
|
||||
var warningRecords = await WriteWarningRecordAsync(entries, notifyRules);
|
||||
|
||||
// 发通知
|
||||
await SendCoreAsync(entries, notifyRules);
|
||||
|
||||
// 移除已处理的预警
|
||||
await RedisHelper.Client.ZRemRangeByScoreAsync(redisKey, 0, timestamp);
|
||||
|
||||
return warningRecords.Count;
|
||||
}
|
||||
|
||||
private async Task<List<WarningRecordIndex>> WriteWarningRecordAsync(List<WarningNotifyCacheEntry> entries,
|
||||
List<GetWarningNotifiesVo> notifyRules)
|
||||
{
|
||||
var warningRecords = new List<WarningRecordIndex>();
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
@ -163,9 +166,25 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
}
|
||||
|
||||
await _warningRecordEsRepository.BulkInsertAsync(warningRecords);
|
||||
return warningRecords;
|
||||
}
|
||||
|
||||
private Task SendCoreAsync(List<WarningNotifyCacheEntry> entries, List<GetWarningNotifiesVo> notifyRules)
|
||||
{
|
||||
var userRules = new Dictionary<int, List<GetWarningNotifiesVo>>();
|
||||
foreach (var rule in notifyRules)
|
||||
{
|
||||
foreach (var userId in rule.NotifyUserIds)
|
||||
{
|
||||
if (!userRules.ContainsKey(userId))
|
||||
{
|
||||
userRules[userId] = new List<GetWarningNotifiesVo>();
|
||||
}
|
||||
|
||||
userRules[userId].Add(rule);
|
||||
}
|
||||
}
|
||||
|
||||
// 发通知
|
||||
foreach (var userRule in userRules)
|
||||
{
|
||||
var siteInternalContent = BuildNotifyContent(userRule.Value, entries, NotifyMode.SiteInternal);
|
||||
@ -173,48 +192,62 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
|
||||
if (!string.IsNullOrEmpty(siteInternalContent))
|
||||
{
|
||||
// todo:发送站内通知
|
||||
_ = _requestSendMessageService.Service.SendMessageByEmptyTemplateAsync(
|
||||
new SendMessageByEmptyTemplateInput
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
// todo:发送站内通知
|
||||
var res = await _requestSendMessageService.Service.SendMessageByEmptyTemplateAsync(
|
||||
new SendMessageByEmptyTemplateInput
|
||||
{
|
||||
IsNeedToHandle = null,
|
||||
BizId = null,
|
||||
MsgSource = null,
|
||||
SystemId = 0,
|
||||
TemplateCode = null,
|
||||
Channels = null,
|
||||
MsgTitle = null,
|
||||
MsgContent = null,
|
||||
PcURl = null,
|
||||
MobileURl = null,
|
||||
FileUrl = null,
|
||||
fileName = null,
|
||||
receivers = null,
|
||||
SiteLetterComponentStyle = (ComponentStyle) 0
|
||||
});
|
||||
|
||||
if (res.Code != GlobalConst.SuccessCode)
|
||||
{
|
||||
IsNeedToHandle = null,
|
||||
BizId = null,
|
||||
MsgSource = null,
|
||||
SystemId = 0,
|
||||
TemplateCode = null,
|
||||
Channels = null,
|
||||
MsgTitle = null,
|
||||
MsgContent = null,
|
||||
PcURl = null,
|
||||
MobileURl = null,
|
||||
FileUrl = null,
|
||||
fileName = null,
|
||||
receivers = null,
|
||||
SiteLetterComponentStyle = (ComponentStyle) 0
|
||||
});
|
||||
LogHelper.Error($"发送站内通知失败,用户:{userRule.Key},内容:{siteInternalContent}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(feiShuContent))
|
||||
{
|
||||
// 发送飞书通知
|
||||
_ = _messageClient.SendMessageAsync(new SendMessageInput
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
AppId = null,
|
||||
AppSecret = null,
|
||||
ReceiveIdType = IdTypeEnums.user_id,
|
||||
MsgType = MsgTypeEnums.文本,
|
||||
ReceiveIds = new List<string>
|
||||
// 发送飞书通知
|
||||
var res = await _messageClient.SendMessageAsync(new SendMessageInput
|
||||
{
|
||||
userRule.Key.ToString()
|
||||
},
|
||||
Content = feiShuContent
|
||||
AppId = null,
|
||||
AppSecret = null,
|
||||
ReceiveIdType = IdTypeEnums.user_id,
|
||||
MsgType = MsgTypeEnums.文本,
|
||||
ReceiveIds = new List<string>
|
||||
{
|
||||
userRule.Key.ToString()
|
||||
},
|
||||
Content = feiShuContent
|
||||
});
|
||||
|
||||
if (res.Code != GlobalConst.SuccessCode)
|
||||
{
|
||||
LogHelper.Error($"发送飞书通知失败,用户:{userRule.Key},内容:{feiShuContent}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await RedisHelper.Client.ZRemRangeByScoreAsync(redisKey, 0, timestamp);
|
||||
|
||||
return warningRecords.Count;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private string GetForewarningNotifySetKeyRedisKey(int subSystemId) =>
|
||||
@ -259,6 +292,7 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
var res = new List<ForewarningRuleCacheEntry>();
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
// 规则至少有一个因素,如果订单任一因素不符合则不命中
|
||||
if (rule.IsTransit != null)
|
||||
{
|
||||
if (order.IsTransit != rule.IsTransit) continue;
|
||||
@ -287,7 +321,8 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
if (!rule.Areas.IsNullOrEmpty())
|
||||
{
|
||||
var inArea = false;
|
||||
foreach (var area in rule.Areas!.Where(area => order.ArrivalCountry == area.Country))
|
||||
var areas = rule.Areas!.Where(area => order.ArrivalCountry == area.Country).ToList();
|
||||
foreach (var area in areas)
|
||||
{
|
||||
if (!area.LeftPostcode.IsNullOrEmpty() && !area.RightPostcode.IsNullOrEmpty())
|
||||
{
|
||||
@ -296,12 +331,31 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
|
||||
string.CompareOrdinal(order.ArrivalPostCode, area.RightPostcode) > 0) continue;
|
||||
}
|
||||
|
||||
if (!area.City.IsNullOrEmpty() && order.ArrivalCity != area.City) continue;
|
||||
if (!area.Province.IsNullOrEmpty() && order.ArrivalProvince != area.Province) continue;
|
||||
inArea = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!inArea)
|
||||
{
|
||||
foreach (var area in areas)
|
||||
{
|
||||
if (!area.City.IsNullOrEmpty() && order.ArrivalCity != area.City) continue;
|
||||
inArea = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inArea)
|
||||
{
|
||||
foreach (var area in areas)
|
||||
{
|
||||
if (!area.Province.IsNullOrEmpty() && order.ArrivalProvince != area.Province) continue;
|
||||
inArea = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!inArea) continue;
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,8 @@ public interface ITrackDetailsEsRepository : IElasticsearchClientService<TrackDe
|
||||
|
||||
Task UpdateAsync(TrackDetailsIndex index);
|
||||
|
||||
Task UpdateManyAsync(List<TrackDetailsIndex> indexes, int maxRetries = 3);
|
||||
|
||||
Task AddManyAsync(List<TrackDetailsIndex> index);
|
||||
|
||||
Task AddAsync(TrackDetailsIndex track);
|
||||
|
||||
@ -50,5 +50,5 @@ public partial class GlobalConst
|
||||
/// <summary>
|
||||
/// 预警计算任务
|
||||
/// </summary>
|
||||
public const string TrackWarningCalc = "SJZY.Track.TrackWarningCalc";
|
||||
public const string TrackWarningCalcSubscribe = "SJZY.Track.TrackWarningCalc";
|
||||
}
|
||||
|
||||
@ -154,6 +154,57 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract<TrackDetail
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateManyAsync(List<TrackDetailsIndex> indexes, int maxRetries = 3)
|
||||
{
|
||||
var retryCount = 0;
|
||||
var updateSuccessful = false;
|
||||
var track = indexes.First();
|
||||
|
||||
while (retryCount < maxRetries && !updateSuccessful)
|
||||
{
|
||||
var response = await Context.UpdateByQueryAsync<TrackDetailsIndex>(u => u
|
||||
.Index(GlobalConst.TrackDetailsIndex)
|
||||
.Query(q => q
|
||||
.Ids(t => t.Values(indexes.Select(x => x.Id)))
|
||||
)
|
||||
.Script(s => s
|
||||
.Source(@"
|
||||
ctx._source.TrackPlace = params.trackPlace;
|
||||
ctx._source.TrackTime = params.trackTime;
|
||||
ctx._source.TrackTimeZone = params.trackTimeZone;
|
||||
ctx._source.UpdateUser = params.updateUser;
|
||||
ctx._source.UpdateTime = params.updateTime;
|
||||
")
|
||||
.Params(p => p
|
||||
.Add("trackPlace", track.TrackPlace)
|
||||
.Add("trackTime", track.TrackTime)
|
||||
.Add("trackTimeZone", track.TrackTimeZone)
|
||||
.Add("updateUser", track.UpdateUser)
|
||||
.Add("updateTime", DateTime.Now)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (response.IsValid)
|
||||
{
|
||||
updateSuccessful = true;
|
||||
}
|
||||
else if (response.ServerError?.Status == 409) // 409 表示版本冲突
|
||||
{
|
||||
retryCount++;
|
||||
if (retryCount >= maxRetries)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"轨迹更新冲突达到最大次数,track:{indexes.Count}条,原因:{response.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"轨迹更新失败,track:{indexes.Count}条,原因:{response.DebugInformation}。");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AddManyAsync(List<TrackDetailsIndex> tracks)
|
||||
{
|
||||
// 按天写入es
|
||||
|
||||
@ -49,7 +49,7 @@ public class WarningRecordEsRepository : ElasticSearchContextAbstract<WarningRec
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
var r = await Context.UpdateByQueryAsync<WarningRecordIndex>(u => u
|
||||
.Index($"{GlobalConst.TrackWarningRecordIndex}-*")
|
||||
.Index(GlobalConst.TrackWarningRecordIndex)
|
||||
.Query(q =>
|
||||
q.Term(f => f.RuleId, rule.ruleId)
|
||||
&& q.Term(f => f.OrderId, rule.orderId)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user