opt:优化轨迹upsert流程

This commit is contained in:
李鹏军 2024-03-26 17:31:50 +08:00
parent f85bc95e19
commit b232d96634
9 changed files with 136 additions and 47 deletions

View File

@ -1,14 +1,22 @@
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
namespace SJZY.Track.Application.Contract.Events;
namespace SJZY.Track.Application.Contract.Events;
public class TrackUpsertEvent : UpsertTrackInput
public class TrackUpsertEvent
{
/// <summary>
/// 订单id
/// </summary>
public int OrderId { get; set; }
/// <summary>
/// 订单类型
/// </summary>
public int OrderType { get; set; }
/// <summary>
/// 订单号
/// </summary>
public string OrderNo { get; set; } = null!;
/// <summary>
/// 订单是否完成
/// </summary>
@ -34,11 +42,6 @@ public class TrackUpsertEvent : UpsertTrackInput
/// </summary>
public int UpSubSystemId { get; set; }
/// <summary>
/// 已经处理过的订单
/// </summary>
public List<int> Visited { get; set; } = new();
/// <summary>
/// 原轨迹内容
/// </summary>
@ -53,4 +56,34 @@ public class TrackUpsertEvent : UpsertTrackInput
/// 操作人
/// </summary>
public string? OperationMan { get; set; }
/// <summary>
/// true新增,false更新,null表示刷新引发的新增/更新
/// </summary>
public bool? IsAdd { get; set; }
/// <summary>
/// 轨迹内容代码
/// </summary>
public string TrackCode { get; set; } = null!;
/// <summary>
/// 轨迹发生地
/// </summary>
public string TrackPlace { get; set; } = null!;
/// <summary>
/// 轨迹发生时间
/// </summary>
public DateTime TrackTime { get; set; }
/// <summary>
/// 轨迹发生时区
/// </summary>
public float TrackTimeZone { get; set; }
/// <summary>
/// 已经处理过的订单
/// </summary>
public List<int> Visited { get; set; } = new();
}

View File

@ -5,7 +5,7 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<Version>1.0.0</Version>
<Version>1.0.1</Version>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>

View File

@ -65,15 +65,15 @@ public class CAPFilter : SubscribeFilter
public override Task OnSubscribeExceptionAsync(ExceptionContext context)
{
context.ExceptionHandled = true;
context.DeliverMessage.Headers.TryGetValue("cap-msg-id", out var messageId);
if (context.Exception is BusinessException ex && ex.Code == _ERROR_CODE)
LogHelper.Warn(ex.ToString());
else
LogHelper.Error(context.Exception.ToString());
LogHelper.Error($"cap-msg-id:{messageId}\n{context.Exception}");
context.DeliverMessage.Headers.TryGetValue("sjzy-receive-time", out var receiveTime);
context.DeliverMessage.Headers.TryGetValue("cap-msg-id", out var messageId);
context.DeliverMessage.Headers.TryGetValue("cap-msg-name", out var receiveName);
context.DeliverMessage.Headers.TryGetValue("sjzy-arguments", out var arguments);
@ -89,16 +89,15 @@ public class CAPFilter : SubscribeFilter
var parsedDate = DateTime.ParseExact(receiveTime, "yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
var useTime = DateTime.Now - parsedDate;
var log = $@"
if (useTime.Minutes > 20)
{
var log = $@"
|-消息编号:{messageId}
|-消费者名:{receiveName}
|-跳过执行:{(isFromExecptionFliter ? "是" : "否")}
|-执行时间:{receiveTime}
|-消费耗时:{useTime.Milliseconds}毫秒
|-请求参数:{arguments}";
if (useTime.Minutes > 20)
{
LogHelper.Error(log);
}
else

View File

@ -158,7 +158,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
}
}
if (matchedContentConfig is null) return;
// if (matchedContentConfig is null) return;
// 轨迹发生地
var trackPlace = paramConfig.TrackPlaceName == null
@ -167,7 +167,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
if (trackPlace.IsNullOrWhiteSpace())
{
Expression<Func<OrderEntity, string?>> resultExpression =
(TrackLocationValue?)matchedContentConfig.TrackPlaceValue switch
(TrackLocationValue?)matchedContentConfig?.TrackPlaceValue switch
{
TrackLocationValue.ArrivalPort => x => x.ArrivalPort,
TrackLocationValue.ArriveCity => x => x.ArrivalCity,
@ -191,10 +191,10 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
: trackToken[paramConfig.TrackTimeZoneName]?.Value<float>();
// 新增/更新轨迹
trackUpsertEvent.TrackCode = matchedContentConfig.TrackContentCode;
trackUpsertEvent.TrackPlace = trackPlace ?? "CN";
trackUpsertEvent.TrackCode = matchedContentConfig?.TrackContentCode ?? GlobalConst.EmptyString;
trackUpsertEvent.TrackPlace = trackPlace ?? GlobalConst.EmptyString;
trackUpsertEvent.TrackTime = trackTime ?? DateTime.Now;
trackUpsertEvent.TrackTimeZone = trackTimeZone ?? matchedContentConfig.TrackTimeZoneValue ?? 8;
trackUpsertEvent.TrackTimeZone = trackTimeZone ?? matchedContentConfig?.TrackTimeZoneValue ?? 8;
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, trackUpsertEvent);
}
}

View File

@ -40,6 +40,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
return;
}
var isUnProcessed = false;
// 不同子系统需要做内容映射
if (@event.UpSubSystemId != 0 && @event.UpSubSystemId != @event.SubSystemId)
{
@ -56,13 +57,22 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
@event.TrackCode = mapCode;
}
var track = await _trackDetailsRepository.GetFirstOrDefaultAsync(@event.OrderId, @event.TrackCode);
if (track == null && !@event.IsAdd) return;
if (track != null && @event.IsAdd) return;
var track = @event.TrackCode == GlobalConst.EmptyString
? await _trackDetailsRepository.GetFirstOrDefaultAsync(@event.OrderId, @event.TrackTime)
: await _trackDetailsRepository.GetFirstOrDefaultAsync(@event.OrderId, @event.TrackCode);
if (@event.TrackCode == GlobalConst.EmptyString && track != null) return; // 无法映射的轨迹只做新增
if (@event.IsAdd != null) // 手动操作需要做区分
{
if (track == null && !@event.IsAdd!.Value) return; // 不存在不让改
if (track != null && @event.IsAdd!.Value) return; // 存在不让创建
}
// step1、upsert es轨迹
track = await UpsertTrackAsync(track, @event);
if (track == null) return; // 模板没配该轨迹代码,无法入库
if (track == null || @event.TrackCode == GlobalConst.EmptyString) return; // 模板没配该轨迹代码,不再继续
// step2、触发轨迹推送事件(异步)
await HandleTrackPushAsync(@event, track);
@ -107,44 +117,64 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
{
if (track == default)
{
//todo:可以优化
// 根据轨迹code在订单模板内容中寻找匹配的
var trackContent = await _provideQueries.MatchTrackContentAsync(@event.OrderId, @event.TrackCode);
if (trackContent == default)
{
// 订单所绑定的模板,没有一条内容可以匹配发生的轨迹
return null;
}
track = new TrackDetailsIndex
{
IndexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}",
OrderId = @event.OrderId,
OrderNo = @event.OrderNo,
OrderType = @event.OrderType,
TrackStatus = trackContent.Status,
TrackCode = @event.TrackCode,
TrackContent = trackContent.Content,
TrackContentId = trackContent.Id,
IsCompleted = trackContent.IsCompleted,
TrackEnContent = trackContent.EnContent,
TrackPlace = @event.TrackPlace,
TrackTime = @event.TrackTime!.Value,
TrackTimeZone = @event.TrackTimeZone!.Value,
IsCanDelete = trackContent.IsCanDelete,
TrackTime = @event.TrackTime,
TrackTimeZone = @event.TrackTimeZone,
IsCanDelete = false,
OriginTrackContent = @event.OriginTrackContent,
OriginTrackData = @event.OriginTrackData,
CreateUser = @event.OperationMan,
CreateTime = DateTime.Now
};
track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
// tips:刷新到无法匹配内容的轨迹引起的插入
if (@event.TrackCode == GlobalConst.EmptyString)
{
track.TrackStatus = GlobalConst.EmptyString;
track.TrackContent = GlobalConst.EmptyString;
track.TrackContentId = 0;
track.IsCompleted = false;
track.TrackEnContent = GlobalConst.EmptyString;
}
else
{
//todo:可以优化
// 根据轨迹code在订单模板内容中寻找匹配的
var trackContent = await _provideQueries.MatchTrackContentAsync(@event.OrderId, @event.TrackCode);
if (trackContent == default)
{
// 订单所绑定的模板,没有一条内容可以匹配发生的轨迹
return null;
}
track = new TrackDetailsIndex
{
TrackStatus = trackContent.Status,
TrackContent = trackContent.Content,
TrackContentId = trackContent.Id,
IsCompleted = trackContent.IsCompleted,
TrackEnContent = trackContent.EnContent,
IsCanDelete = trackContent.IsCanDelete
};
track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
}
}
else
{
// tips:刷新到无法匹配内容的轨迹 相同的发生时间不做更新处理
if (@event.TrackCode == GlobalConst.EmptyString) return track;
track.TrackPlace = @event.TrackPlace;
track.TrackTime = @event.TrackTime!.Value;
track.TrackTimeZone = @event.TrackTimeZone!.Value;
track.TrackTime = @event.TrackTime;
track.TrackTimeZone = @event.TrackTimeZone;
track.UpdateUser = @event.OperationMan ?? "系统";
track.UpdateTime = DateTime.Now;
}

View File

@ -91,8 +91,8 @@ public partial class TrackService : ApplicationService, ITrackService
IsAdd = input.IsAdd,
TrackCode = input.TrackCode,
TrackPlace = input.TrackPlace,
TrackTime = input.TrackTime,
TrackTimeZone = input.TrackTimeZone,
TrackTime = input.TrackTime!.Value,
TrackTimeZone = input.TrackTimeZone!.Value,
OrderType = input.OrderType,
OrderNo = order.OrderNo,
OrderId = order.Id,

View File

@ -6,6 +6,8 @@ public interface ITrackDetailsRepository
{
Task<TrackDetailsIndex?> GetFirstOrDefaultAsync(int orderId, string trackCode);
Task<TrackDetailsIndex?> GetFirstOrDefaultAsync(int orderId, DateTime trackTime);
Task UpsertAsync(TrackDetailsIndex index);
Task<List<TrackDetailsIndex>> GetListAsync(int orderType, List<string> orderNos);

View File

@ -0,0 +1,6 @@
namespace SJZY.Track.Domain.Consts;
public partial class GlobalConst
{
public const string EmptyString = "--";
}

View File

@ -32,6 +32,25 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
return res;
}
public async Task<TrackDetailsIndex?> GetFirstOrDefaultAsync(int orderId, DateTime trackTime)
{
var r = await Context.SearchAsync<TrackDetailsIndex>(s => s
.Source()
.Query(q =>
q.Term(f => f.OrderId, orderId)
&& q.Term(f => f.TrackTime, trackTime)
)
);
var res = r.Documents.FirstOrDefault();
if (res != default && r.Hits.FirstOrDefault() != default)
{
res.Id = r.Hits.FirstOrDefault()!.Id;
}
return res;
}
public async Task UpsertAsync(TrackDetailsIndex index)
{
if (index.Id.IsNullOrWhiteSpace())