opt
This commit is contained in:
parent
ad563dda97
commit
64ab6757a9
@ -7,11 +7,6 @@ public class TrackChangeAfterUpdateOrderEvent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int[] OrderIds { get; set; } = null!;
|
public int[] OrderIds { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否删除引起的更新
|
|
||||||
/// </summary>
|
|
||||||
public bool IsDelete { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 这条轨迹是否意味着完成(只有刷新会设为true)
|
/// 这条轨迹是否意味着完成(只有刷新会设为true)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -21,8 +21,7 @@ public class CapFilter : SubscribeFilter
|
|||||||
context.DeliverMessage.Headers["sjzy-receive-time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
|
context.DeliverMessage.Headers["sjzy-receive-time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
|
||||||
|
|
||||||
// 轨迹增改要做幂等
|
// 轨迹增改要做幂等
|
||||||
if (!context.DeliverMessage.Headers["cap-msg-name"]
|
if (!context.DeliverMessage.Headers["cap-msg-name"].IsIn(GlobalConst.TrackUpsertSubscribe))
|
||||||
.IsIn(GlobalConst.TrackUpsertSubscribe))
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
// 本地调试不做幂等
|
// 本地调试不做幂等
|
||||||
@ -76,11 +75,13 @@ public class CapFilter : SubscribeFilter
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override Task OnSubscribeExceptionAsync(ExceptionContext context)
|
public override Task OnSubscribeExceptionAsync(ExceptionContext context)
|
||||||
{
|
{
|
||||||
context.ExceptionHandled = true;
|
|
||||||
context.DeliverMessage.Headers.TryGetValue("cap-msg-id", out var messageId);
|
context.DeliverMessage.Headers.TryGetValue("cap-msg-id", out var messageId);
|
||||||
|
|
||||||
if (context.Exception is BusinessException ex && ex.Code == ErrorCode)
|
if (context.Exception is BusinessException ex && ex.Code == ErrorCode)
|
||||||
|
{
|
||||||
|
context.ExceptionHandled = true; // 幂等不做重试
|
||||||
LogHelper.Warn(ex.ToString());
|
LogHelper.Warn(ex.ToString());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
LogHelper.Error($"cap-msg-id:{messageId}\n{context.Exception}");
|
LogHelper.Error($"cap-msg-id:{messageId}\n{context.Exception}");
|
||||||
|
|
||||||
@ -101,14 +102,14 @@ public class CapFilter : SubscribeFilter
|
|||||||
var parsedDate = DateTime.ParseExact(receiveTime, "yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
|
var parsedDate = DateTime.ParseExact(receiveTime, "yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
|
||||||
var useTime = DateTime.Now - parsedDate;
|
var useTime = DateTime.Now - parsedDate;
|
||||||
|
|
||||||
if (useTime.Minutes > 20)
|
if (useTime.Minutes > 10)
|
||||||
{
|
{
|
||||||
var log = $@"
|
var log = $@"
|
||||||
|-消息编号:{messageId}
|
|-消息编号:{messageId}
|
||||||
|-消费者名:{receiveName}
|
|-消费者名:{receiveName}
|
||||||
|-跳过执行:{(isFromExecptionFliter ? "是" : "否")}
|
|-跳过执行:{(isFromExecptionFliter ? "是" : "否")}
|
||||||
|-执行时间:{receiveTime}
|
|-执行时间:{receiveTime}
|
||||||
|-消费耗时:{useTime.Milliseconds}毫秒
|
|-消费耗时:{useTime.Seconds}秒
|
||||||
|-请求参数:{arguments}";
|
|-请求参数:{arguments}";
|
||||||
LogHelper.Error(log);
|
LogHelper.Error(log);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,53 +36,25 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
|
|||||||
|
|
||||||
if (orders.Count == 0) return;
|
if (orders.Count == 0) return;
|
||||||
|
|
||||||
// todo:delete可能发生回退,直接去es查最新轨迹,但是可能es还没有刷盘,导致回退失效,可以考虑加个定时任务弥补
|
foreach (var order in orders)
|
||||||
if (@event.IsDelete)
|
|
||||||
{
|
{
|
||||||
foreach (var order in orders)
|
if (order.LatestTrackTime != null &&
|
||||||
|
@event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) <
|
||||||
|
order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0)))
|
||||||
{
|
{
|
||||||
var tracks = await _trackDetailsRepository.GetListAsync(@event.OrderIds);
|
continue;
|
||||||
|
|
||||||
var track = tracks.Where(x => x.OrderId == order.Id).MaxBy(x => x.TrackTime);
|
|
||||||
// 删除全部轨迹导致的重置行为
|
|
||||||
if (track == default)
|
|
||||||
{
|
|
||||||
if (order.LatestTrackTime == null) return;
|
|
||||||
|
|
||||||
// tips:订单是支持从已完成态到未完成态的
|
|
||||||
order.ResetTrackInfo();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 删除引发的回退更新
|
|
||||||
order.IsCompleted = @event.IsCompleted;
|
|
||||||
order.LatestTrackContent = track.TrackContent;
|
|
||||||
order.LatestTrackEnContent = track.TrackEnContent;
|
|
||||||
order.LatestTrackPlace = track.TrackPlace;
|
|
||||||
order.LatestTrackTime = track.TrackTime;
|
|
||||||
order.LatestTrackTimeZone = track.TrackTimeZone;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else // upsert可以直接计算
|
|
||||||
{
|
|
||||||
foreach (var order in orders)
|
|
||||||
{
|
|
||||||
if (order.LatestTrackTime != null &&
|
|
||||||
@event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) <
|
|
||||||
order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0)))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// upsert引发的更新
|
if (!order.IsCompleted)
|
||||||
|
{
|
||||||
order.IsCompleted = @event.IsCompleted;
|
order.IsCompleted = @event.IsCompleted;
|
||||||
order.LatestTrackContent = @event.TrackContent;
|
|
||||||
order.LatestTrackEnContent = @event.TrackEnContent;
|
|
||||||
order.LatestTrackPlace = @event.TrackPlace;
|
|
||||||
order.LatestTrackTime = @event.TrackTime;
|
|
||||||
order.LatestTrackTimeZone = @event.TrackTimeZone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
order.LatestTrackContent = @event.TrackContent;
|
||||||
|
order.LatestTrackEnContent = @event.TrackEnContent;
|
||||||
|
order.LatestTrackPlace = @event.TrackPlace;
|
||||||
|
order.LatestTrackTime = @event.TrackTime;
|
||||||
|
order.LatestTrackTimeZone = @event.TrackTimeZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _orderRepository.UpdateRangeAsync(orders, x => new
|
await _orderRepository.UpdateRangeAsync(orders, x => new
|
||||||
|
|||||||
@ -74,19 +74,50 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
|
|||||||
private async Task DeleteTrackAsync(TrackDeleteEvent @event)
|
private async Task DeleteTrackAsync(TrackDeleteEvent @event)
|
||||||
{
|
{
|
||||||
// 删除轨迹(删的是同子系统下的单,所以code是统一的)
|
// 删除轨迹(删的是同子系统下的单,所以code是统一的)
|
||||||
var isOk = await _trackDetailsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes);
|
var tracks = await _trackDetailsRepository.GetLatestListAsync(@event.OrderIds, @event.TrackCodes);
|
||||||
|
|
||||||
if (isOk)
|
await _trackDetailsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes);
|
||||||
|
|
||||||
|
var orders = await _orderRepository.GetListAsync(x => @event.OrderIds.Contains(x.Id),
|
||||||
|
x => new OrderEntity
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
LatestTrackContent = x.LatestTrackContent,
|
||||||
|
LatestTrackEnContent = x.LatestTrackEnContent,
|
||||||
|
LatestTrackPlace = x.LatestTrackPlace,
|
||||||
|
LatestTrackTime = x.LatestTrackTime,
|
||||||
|
LatestTrackTimeZone = x.LatestTrackTimeZone,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (orders.Count == 0) return;
|
||||||
|
|
||||||
|
foreach (var order in orders)
|
||||||
{
|
{
|
||||||
// 触发订单主表更新事件
|
var track = tracks.FirstOrDefault(x => x.OrderId == order.Id);
|
||||||
await _capPublisher.PublishDelayAsync(TimeSpan.FromSeconds(3),
|
|
||||||
GlobalConst.TrackChangeAfterUpdateOrderSubscribe,
|
// 删除全部轨迹导致的重置行为
|
||||||
new TrackChangeAfterUpdateOrderEvent
|
if (track == default)
|
||||||
{
|
{
|
||||||
OrderIds = @event.OrderIds,
|
if (order.LatestTrackTime == null) return;
|
||||||
TrackCode = @event.TrackCodes.JoinAsString(","),
|
|
||||||
IsDelete = true
|
// tips:订单是支持从已完成态到未完成态的
|
||||||
});
|
order.ResetTrackInfo();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 删除引发的回退更新
|
||||||
|
order.LatestTrackContent = track.TrackContent;
|
||||||
|
order.LatestTrackEnContent = track.TrackEnContent;
|
||||||
|
order.LatestTrackPlace = track.TrackPlace;
|
||||||
|
order.LatestTrackTime = track.TrackTime;
|
||||||
|
order.LatestTrackTimeZone = track.TrackTimeZone;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await _orderRepository.UpdateRangeAsync(orders, x => new
|
||||||
|
{
|
||||||
|
x.LatestTrackContent, x.LatestTrackEnContent, x.LatestTrackPlace, x.LatestTrackTime,
|
||||||
|
x.LatestTrackTimeZone
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,7 +6,8 @@ public interface ITrackDetailsRepository
|
|||||||
{
|
{
|
||||||
Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds, string trackCode);
|
Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds, string trackCode);
|
||||||
|
|
||||||
Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds);
|
Task<List<TrackDetailsIndex>> GetLatestListAsync(int[] eventOrderIds, List<string> trackCodes);
|
||||||
|
|
||||||
|
|
||||||
Task<bool> AnyAsync(int orderId, DateTime trackTime);
|
Task<bool> AnyAsync(int orderId, DateTime trackTime);
|
||||||
|
|
||||||
@ -22,11 +23,5 @@ public interface ITrackDetailsRepository
|
|||||||
Task<(List<TrackDetailsIndex> list, long total)> GetListAsync(TrackDetailsQueryInput input);
|
Task<(List<TrackDetailsIndex> list, long total)> GetListAsync(TrackDetailsQueryInput input);
|
||||||
Task<List<TrackDetailsIndex>> GetListAsync(int orderId);
|
Task<List<TrackDetailsIndex>> GetListAsync(int orderId);
|
||||||
|
|
||||||
/// <summary>
|
Task DeleteTrackAsync(int[] orderIds, List<string> trackCodes);
|
||||||
/// 删除轨迹
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="orderIds"></param>
|
|
||||||
/// <param name="trackCodes"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<bool> DeleteTrackAsync(int[] orderIds, List<string> trackCodes);
|
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
using Nest;
|
using Nest;
|
||||||
using SJZY.Expand.ABP.Core.Logger;
|
|
||||||
using SJZY.Expand.ElasticSearch.Services;
|
using SJZY.Expand.ElasticSearch.Services;
|
||||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||||
|
using SJZY.Track.Domain.Consts;
|
||||||
using SJZY.Track.Domain.Dtos.TrackDetails;
|
using SJZY.Track.Domain.Dtos.TrackDetails;
|
||||||
|
|
||||||
namespace SJZY.Track.Repository.Repositories;
|
namespace SJZY.Track.Repository.Repositories;
|
||||||
@ -30,8 +30,10 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
return r.ToIdList();
|
return r.ToIdList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds)
|
public async Task<List<TrackDetailsIndex>> GetLatestListAsync(int[] orderIds, List<string> trackCodes)
|
||||||
{
|
{
|
||||||
|
var excludeTrackCodes = trackCodes.ToList();
|
||||||
|
excludeTrackCodes.Add(GlobalConst.EmptyString);
|
||||||
var data = await Context.SearchAsync<TrackDetailsIndex>(x => x
|
var data = await Context.SearchAsync<TrackDetailsIndex>(x => x
|
||||||
.Source(s => s.Includes(fd => fd
|
.Source(s => s.Includes(fd => fd
|
||||||
.Field(f => f.TrackEnContent)
|
.Field(f => f.TrackEnContent)
|
||||||
@ -40,6 +42,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
.Field(f => f.TrackTime)
|
.Field(f => f.TrackTime)
|
||||||
.Field(f => f.TrackTimeZone)
|
.Field(f => f.TrackTimeZone)
|
||||||
.Field(f => f.OrderId)
|
.Field(f => f.OrderId)
|
||||||
|
.Field(f => f.TrackCode)
|
||||||
))
|
))
|
||||||
.Query(q => q
|
.Query(q => q
|
||||||
.Bool(b => b
|
.Bool(b => b
|
||||||
@ -47,15 +50,27 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds))
|
mu => mu.Terms(t => t.Field(f => f.OrderId).Terms(orderIds))
|
||||||
)
|
)
|
||||||
.MustNot(mn => mn
|
.MustNot(mn => mn
|
||||||
.Term(t => t
|
.Terms(t => t
|
||||||
.Field(f => f.TrackCode.Suffix("keyword"))
|
.Field(f => f.TrackCode.Suffix("keyword"))
|
||||||
.Value("--")
|
.Terms(excludeTrackCodes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Size(0)
|
||||||
|
.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)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending))
|
|
||||||
.Size(1)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return data.Documents.ToList();
|
return data.Documents.ToList();
|
||||||
@ -98,7 +113,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
|
|
||||||
if (!r.IsValid)
|
if (!r.IsValid)
|
||||||
{
|
{
|
||||||
LogHelper.Error($"轨迹更新失败,原因:{r.DebugInformation}。");
|
throw new Exception($"轨迹更新失败,原因:{r.DebugInformation}。");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +124,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
|
|
||||||
if (!r.IsValid)
|
if (!r.IsValid)
|
||||||
{
|
{
|
||||||
LogHelper.Error($"{tracks.Count}条轨迹新增失败,原因:{r.DebugInformation}。");
|
throw new Exception($"{tracks.Count}条轨迹新增失败,原因:{r.DebugInformation}。");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,12 +161,12 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
q.Term(t => t.OrderId, orderId)
|
q.Term(t => t.OrderId, orderId)
|
||||||
)
|
)
|
||||||
.Size(1000)
|
.Size(1000)
|
||||||
.Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending)));
|
.Sort(s => s.Field(f => f.ZeroTrackTime, SortOrder.Descending)));
|
||||||
|
|
||||||
return data.Documents.ToList();
|
return data.Documents.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> DeleteTrackAsync(int[] orderIds, List<string> trackCodes)
|
public async Task DeleteTrackAsync(int[] orderIds, List<string> trackCodes)
|
||||||
{
|
{
|
||||||
var r = await Context.DeleteByQueryAsync<TrackDetailsIndex>(x => x
|
var r = await Context.DeleteByQueryAsync<TrackDetailsIndex>(x => x
|
||||||
.Query(
|
.Query(
|
||||||
@ -164,8 +179,6 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
|
|
||||||
if (!r.IsValid)
|
if (!r.IsValid)
|
||||||
throw new Exception($"轨迹数据删除失败,原因:{r.DebugInformation}");
|
throw new Exception($"轨迹数据删除失败,原因:{r.DebugInformation}");
|
||||||
|
|
||||||
return r.Deleted > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(List<TrackDetailsIndex> list, long total)> GetListAsync(TrackDetailsQueryInput input)
|
public async Task<(List<TrackDetailsIndex> list, long total)> GetListAsync(TrackDetailsQueryInput input)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user