From f39cd3421c8934cd413d95a5649f6e38ec066aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=86=9B?= <2357729423@qq.com> Date: Mon, 18 Mar 2024 09:44:42 +0800 Subject: [PATCH] init --- .../TrackPushContentConfigDto.cs | 10 ++ .../Dtos/TrackPull/TrackRefreshAttach.cs | 32 +++++ .../Dtos/TrackPull/TrackRefreshDto.cs | 16 --- .../Events/TrackPushAfterUpdateOrderEvent.cs | 24 ++++ .../Events/TrackPushEvent.cs | 74 ++++++++++ ...cs => TrackUpsertAfterUpdateOrderEvent.cs} | 2 +- .../Events/TrackUpsertEvent.cs | 5 + .../OrderLinkAfterFillTrackHandler.cs | 1 + .../EventHandlers/TrackDeleteEventHandler.cs | 7 +- .../TrackPushAfterUpdateOrderEventHandler.cs | 36 +++++ .../EventHandlers/TrackPushEventHandler.cs | 123 ++++++++++++++++ .../EventHandlers/TrackRefreshEventHandler.cs | 15 +- ...rackUpsertAfterUpdateOrderEventHandler.cs} | 23 +-- .../EventHandlers/TrackUpsertEventHandler.cs | 128 +++++++++++------ .../ProvideServices/OrderService.Link.cs | 1 + .../ProvideServices/TrackPullService.cs | 34 ++--- .../ProvideServices/TrackPushService.cs | 64 +++++---- .../Services/ProvideServices/TrackService.cs | 4 +- .../TrackPull/TrackPullCacheService.cs | 4 +- .../Services/TrackPull/TrackPullService.cs | 133 ++++++++++-------- .../TrackPush/TrackPushCacheService.cs | 4 +- .../TrackDetailsIndex.cs | 18 +-- .../ITrackPushRecordsRepository.cs | 11 ++ .../TrackPushRecordIndex.cs | 51 +++++++ .../Consts/GlobalConst.ES.cs | 14 ++ .../Consts/GlobalConst.MQ.cs | 39 +++++ .../Consts/GlobalConst.Redis.cs | 24 ++++ .../Consts/InterfaceRelayConst.cs | 27 ++++ .../Dtos/Order/LinkedOrderVO.cs | 5 + ...ProblemType.cs => TrackPushProblemType.cs} | 7 +- src/SJZY.Track.Domain/GlobalConst.cs | 54 ------- .../Queries/ProvideQueries.cs | 2 +- .../Repositories/OrderRepository.cs | 3 +- .../TrackPushRecordsRepository.cs | 28 ++++ 34 files changed, 766 insertions(+), 257 deletions(-) create mode 100644 src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshAttach.cs delete mode 100644 src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshDto.cs create mode 100644 src/SJZY.Track.Application.Contract/Events/TrackPushAfterUpdateOrderEvent.cs create mode 100644 src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs rename src/SJZY.Track.Application.Contract/Events/{UpdateOrderTrackEvent.cs => TrackUpsertAfterUpdateOrderEvent.cs} (95%) create mode 100644 src/SJZY.Track.Application/EventHandlers/TrackPushAfterUpdateOrderEventHandler.cs create mode 100644 src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs rename src/SJZY.Track.Application/EventHandlers/{UpdateOrderTrackEventHandler.cs => TrackUpsertAfterUpdateOrderEventHandler.cs} (76%) create mode 100644 src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushRecordsRepository.cs create mode 100644 src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/TrackPushRecordIndex.cs create mode 100644 src/SJZY.Track.Domain/Consts/GlobalConst.ES.cs create mode 100644 src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs create mode 100644 src/SJZY.Track.Domain/Consts/GlobalConst.Redis.cs create mode 100644 src/SJZY.Track.Domain/Consts/InterfaceRelayConst.cs rename src/SJZY.Track.Domain/Enums/{TrackProblemType.cs => TrackPushProblemType.cs} (64%) delete mode 100644 src/SJZY.Track.Domain/GlobalConst.cs create mode 100644 src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs index 64ae2569..a019087f 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs @@ -15,6 +15,16 @@ public class TrackPushConfigDto public class TrackPushContentConfigDto { + /// + /// 是否自动推送 + /// + public bool IsAutoPush { get; set; } + + /// + /// 是否支持更新 + /// + public bool IsCanUpdate { get; set; } + /// /// 服务商code /// diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshAttach.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshAttach.cs new file mode 100644 index 00000000..ae47f35a --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshAttach.cs @@ -0,0 +1,32 @@ +namespace SJZY.Track.Application.Contract.Dtos.TrackPull; + +public class TrackRefreshAttach +{ + public TrackRefreshAttach(int serviceProviderId, string serviceProviderCode, int subSystemId, int orderType) + { + ServiceProviderId = serviceProviderId; + ServiceProviderCode = serviceProviderCode; + SubSystemId = subSystemId; + OrderType = orderType; + } + + /// + /// 服务商id + /// + public int ServiceProviderId { get; set; } + + /// + /// 服务商code + /// + public string ServiceProviderCode { get; set; } + + /// + /// 订单类型(主数据枚举TrackOrderType) + /// + public int OrderType { get; set; } + + /// + /// 子系统id + /// + public int SubSystemId { get; set; } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshDto.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshDto.cs deleted file mode 100644 index d8d476d2..00000000 --- a/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshDto.cs +++ /dev/null @@ -1,16 +0,0 @@ -using SJZY.Track.Application.Contract.Dtos.ProvideServices; - -namespace SJZY.Track.Application.Contract.Dtos.TrackPull; - -public class TrackRefreshDto : OrderNoInfo -{ - /// - /// 服务商id - /// - public int ServiceProviderId { get; set; } - - /// - /// 子系统id - /// - public int SubSystemId { get; set; } -} \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/TrackPushAfterUpdateOrderEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackPushAfterUpdateOrderEvent.cs new file mode 100644 index 00000000..b81b52cc --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Events/TrackPushAfterUpdateOrderEvent.cs @@ -0,0 +1,24 @@ +namespace SJZY.Track.Application.Contract.Events; + +public class TrackPushAfterUpdateOrderEvent +{ + /// + /// 订单Id + /// + public int OrderId { get; set; } + + /// + /// 轨迹内容id + /// + public int TrackContentId { get; set; } + + /// + /// 是否成功 + /// + public bool IsSuccess { get; set; } + + /// + /// 最新描述 + /// + public string? Message { get; set; } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs new file mode 100644 index 00000000..c7277eb2 --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Events/TrackPushEvent.cs @@ -0,0 +1,74 @@ +namespace SJZY.Track.Application.Contract.Events; + +public class TrackPushEvent +{ + /// + /// 操作类型 + /// + public OptionType OptionType { get; set; } = OptionType.新增; + + /// + /// 服务商code + /// + public string ServiceProviderCode { get; set; } = null!; + + /// + /// 订单id + /// + public int OrderId { get; set; } + + /// + /// 订单号 + /// + public string OrderNo { get; set; } = null!; + + /// + /// 轨迹内容id + /// + public int TrackContentId { get; set; } + + /// + /// 轨迹发生地 + /// + public string TrackPlace { get; set; } = null!; + + /// + /// 轨迹发生时间 + /// + public DateTime TrackTime { get; set; } + + /// + /// 轨迹发生时区 + /// + public float TrackTimeZone { get; set; } + + /// + /// 轨迹代码参数值 + /// + public string? TrackContentCodeValue { get; set; } + + /// + /// 轨迹内容参数值 + /// + public string? TrackContentValue { get; set; } + + /// + /// 轨迹内容英文参数值 + /// + public string? TrackEnContentValue { get; set; } + + /// + /// 轨迹状态参数值 + /// + public string? TrackStatusValue { get; set; } + + /// + /// 扩展字段参数值 + /// + public string? ExpandFieldsValue { get; set; } + + /// + /// 推送人 + /// + public string? PushMan { get; set; } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/UpdateOrderTrackEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertAfterUpdateOrderEvent.cs similarity index 95% rename from src/SJZY.Track.Application.Contract/Events/UpdateOrderTrackEvent.cs rename to src/SJZY.Track.Application.Contract/Events/TrackUpsertAfterUpdateOrderEvent.cs index 7daa9a7d..bf3907b4 100644 --- a/src/SJZY.Track.Application.Contract/Events/UpdateOrderTrackEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertAfterUpdateOrderEvent.cs @@ -1,6 +1,6 @@ namespace SJZY.Track.Application.Contract.Events; -public class UpdateOrderTrackEvent +public class TrackUpsertAfterUpdateOrderEvent { /// /// 订单Id diff --git a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs index 5bbcbea6..eb836245 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs @@ -9,6 +9,11 @@ public class TrackUpsertEvent : UpsertTrackInput /// public int OrderId { get; set; } + /// + /// 订单是否完成 + /// + public bool IsCompleted { get; set; } + /// /// 客户id /// diff --git a/src/SJZY.Track.Application/EventHandlers/OrderLinkAfterFillTrackHandler.cs b/src/SJZY.Track.Application/EventHandlers/OrderLinkAfterFillTrackHandler.cs index 9335175a..1d628a3a 100644 --- a/src/SJZY.Track.Application/EventHandlers/OrderLinkAfterFillTrackHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/OrderLinkAfterFillTrackHandler.cs @@ -2,6 +2,7 @@ using SJZY.Track.Application.Contract.Events; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; +using SJZY.Track.Domain.Consts; using Volo.Abp.DependencyInjection; namespace SJZY.Track.Application.EventHandlers; diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index 1bbf3aac..1a1f0df0 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -3,6 +3,7 @@ using SJZY.Expand.ABP.Core.Logger; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Queries; using Volo.Abp.DependencyInjection; @@ -63,12 +64,12 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe { var track = await _trackDetailsRepository.GetLatestAsync(@event.OrderId); var updateOrderEvent = track == default - ? new UpdateOrderTrackEvent + ? new TrackUpsertAfterUpdateOrderEvent { OrderId = @event.OrderId, IsDelete = true } - : new UpdateOrderTrackEvent + : new TrackUpsertAfterUpdateOrderEvent { OrderId = @event.OrderId, IsCompleted = track.IsCompleted, @@ -79,7 +80,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe TrackTimeZone = track.TrackTimeZone, IsDelete = true }; - await _capPublisher.PublishAsync(GlobalConst.UpdateOrderTrackSubscribe, updateOrderEvent); + await _capPublisher.PublishAsync(GlobalConst.TrackUpsertAfterUpdateOrderSubscribe, updateOrderEvent); } // 根据订单关联关系异步向下刷 diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushAfterUpdateOrderEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushAfterUpdateOrderEventHandler.cs new file mode 100644 index 00000000..a1953f49 --- /dev/null +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushAfterUpdateOrderEventHandler.cs @@ -0,0 +1,36 @@ +using DotNetCore.CAP; +using SJZY.Track.Application.Contract.Events; +using SJZY.Track.Domain.Aggregates.OrderAggregate; +using SJZY.Track.Domain.Consts; +using Volo.Abp.DependencyInjection; + +namespace SJZY.Track.Application.EventHandlers; + +public class TrackPushAfterUpdateOrderEventHandler : ITransientDependency, ICapSubscribe +{ + private readonly IOrderRepository _orderRepository; + + public TrackPushAfterUpdateOrderEventHandler(IOrderRepository orderRepository) + { + _orderRepository = orderRepository; + } + + [CapSubscribe(GlobalConst.TrackPushAfterUpdateOrderSubscribe)] + public async Task ConsumerAsync(TrackPushAfterUpdateOrderEvent @event) + { + var order = await _orderRepository.GetFirstAsync(x => x.Id == @event.OrderId); + if (order == default) return; + + // 异常:最近一条推送是失败 + // 预警:添加一条推送距离现在超过12h + // if (!@event.IsSuccess) + // { + // order.QuestionType = TrackPushProblemType.Error; + // } + + await _orderRepository.UpdateColumnAsync(order, x => new + { + x.LatestPushTrackContentId, x.QuestionType + }); + } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs new file mode 100644 index 00000000..b2b977a8 --- /dev/null +++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs @@ -0,0 +1,123 @@ +using DotNetCore.CAP; +using SJZY.InterfaceRelay.Application.Contracts; +using SJZY.Track.Application.Contract.Events; +using SJZY.Track.Domain.Aggregates.TrackPushAggregate; +using SJZY.Track.Domain.Consts; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.DynamicProxying; + +namespace SJZY.Track.Application.EventHandlers; + +public class TrackPushEventHandler : ITransientDependency, ICapSubscribe +{ + private readonly IHttpClientProxy _httpClientProxy; + private readonly ITrackPushRecordsRepository _trackPushRecordsRepository; + private readonly ICapPublisher _capPublisher; + + public TrackPushEventHandler(IHttpClientProxy httpClientProxy, + ITrackPushRecordsRepository trackPushRecordsRepository, ICapPublisher capPublisher) + { + _httpClientProxy = httpClientProxy; + _trackPushRecordsRepository = trackPushRecordsRepository; + _capPublisher = capPublisher; + } + + [CapSubscribe(GlobalConst.TrackPushSubscribe)] + public async Task ConsumerAsync(TrackPushEvent @event) + { + switch (@event.OptionType) + { + case OptionType.无: + break; + case OptionType.新增: + await PushAddAsync(@event); + break; + case OptionType.删除: + break; + case OptionType.修改: + await PushUpdateAsync(@event); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private async Task PushAddAsync(TrackPushEvent @event) + { + var data = new + { + orderNo = @event.OrderNo, + data = new[] + { + new + { + // 推真实的发生地和发生时间(时间是计算后的) + location = @event.TrackPlace, + date = @event.TrackTime, + timeZone = @event.TrackTimeZone, + description = @event.TrackEnContentValue, + description_cn = @event.TrackContentValue, + code = @event.TrackContentCodeValue, + status = @event.TrackStatusValue, + extra = @event.ExpandFieldsValue + } + } + }; + + + var res = await _httpClientProxy.Service.ForwardWithSubscribeAsync(InterfaceRelayConst.PushTrackInterfaceCode, + @event.ServiceProviderCode, data); + + var isSuccess = res.Code == InterfaceRelayConst.SuccessCode; + // 写推送日志 + await _trackPushRecordsRepository.AddAsync(new TrackPushRecordIndex + { + IndexName = $"{GlobalConst.TrackPushRecordsIndex}-{DateTime.Now:yyyy.MM.dd}", + RequestId = res.RequestId, + OptionType = OptionType.新增, + TrackPlace = @event.TrackPlace, + TrackTime = @event.TrackTime, + TrackTimeZone = @event.TrackTimeZone, + IsSuccess = isSuccess, + CreateUser = @event.PushMan ?? "系统", + CreateTime = DateTime.Now + }); + + // 更新订单主表 + await _capPublisher.PublishAsync(GlobalConst.TrackPushAfterUpdateOrderSubscribe, + new TrackPushAfterUpdateOrderEvent + { + OrderId = @event.OrderId, + TrackContentId = @event.TrackContentId, + IsSuccess = isSuccess, + Message = res.Msg + }); + } + + private async Task PushUpdateAsync(TrackPushEvent @event) + { + var data = new + { + orderNo = @event.OrderNo, + data = new[] + { + new + { + // 推真实的发生地和发生时间 + location = @event.TrackPlace, + date = @event.TrackTime, + timeZone = @event.TrackTimeZone, + description = @event.TrackEnContentValue, + description_cn = @event.TrackContentValue, + code = @event.TrackContentCodeValue, + status = @event.TrackStatusValue, + extra = @event.ExpandFieldsValue + } + } + }; + + + await _httpClientProxy.Service.ForwardWithSubscribeAsync(InterfaceRelayConst.TrackUpdateInterfaceCode, + @event.ServiceProviderCode, data); + } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs index 52c005f2..d732258d 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs @@ -9,6 +9,7 @@ using SJZY.Track.Application.Contract.Dtos.TrackPull; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.OrderAggregate; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Enums; using Volo.Abp.DependencyInjection; @@ -31,12 +32,10 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe [CapSubscribe(GlobalConst.TrackRefreshSubscribe)] public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event) { - // tips:attach返回的是服务商id,必有 - var refreshDto = JsonConvert.DeserializeObject>(@event.RequestParams)?.FirstOrDefault(); - if (refreshDto is null) return; - var config = - await _trackPullCacheService.GetPullParamWithContentConfigAsync(refreshDto.SubSystemId, - refreshDto.ServiceProviderId); + var attach = JsonConvert.DeserializeObject(@event.Attach); + if (attach is null) return; + var config = await _trackPullCacheService.GetPullParamWithContentConfigAsync(attach.SubSystemId, + attach.ServiceProviderId); var data = JObject.Parse(@event.Data.ToString()!); var orderToken = data[config.ParamConfig.OrderPath]; @@ -44,12 +43,12 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe { foreach (var token in orderTokens) { - await HandleOrderAsync(token, config, refreshDto.OrderType); + await HandleOrderAsync(token, config, attach.OrderType); } } else if (orderToken is JObject) { - await HandleOrderAsync(orderToken, config, refreshDto.OrderType); + await HandleOrderAsync(orderToken, config, attach.OrderType); } } diff --git a/src/SJZY.Track.Application/EventHandlers/UpdateOrderTrackEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertAfterUpdateOrderEventHandler.cs similarity index 76% rename from src/SJZY.Track.Application/EventHandlers/UpdateOrderTrackEventHandler.cs rename to src/SJZY.Track.Application/EventHandlers/TrackUpsertAfterUpdateOrderEventHandler.cs index 7eb5811a..1ce9ae93 100644 --- a/src/SJZY.Track.Application/EventHandlers/UpdateOrderTrackEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertAfterUpdateOrderEventHandler.cs @@ -1,21 +1,22 @@ using DotNetCore.CAP; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Domain.Aggregates.OrderAggregate; +using SJZY.Track.Domain.Consts; using Volo.Abp.DependencyInjection; namespace SJZY.Track.Application.EventHandlers; -public class UpdateOrderTrackEventHandler : ITransientDependency, ICapSubscribe +public class TrackUpsertAfterUpdateOrderEventHandler : ITransientDependency, ICapSubscribe { private readonly IOrderRepository _orderRepository; - public UpdateOrderTrackEventHandler(IOrderRepository orderRepository) + public TrackUpsertAfterUpdateOrderEventHandler(IOrderRepository orderRepository) { _orderRepository = orderRepository; } - [CapSubscribe(GlobalConst.UpdateOrderTrackSubscribe)] - public async Task ConsumerAsync(UpdateOrderTrackEvent @event) + [CapSubscribe(GlobalConst.TrackUpsertAfterUpdateOrderSubscribe)] + public async Task ConsumerAsync(TrackUpsertAfterUpdateOrderEvent @event) { var order = await _orderRepository.GetFirstAsync(x => x.Id == @event.OrderId); if (order == default) return; @@ -37,14 +38,20 @@ public class UpdateOrderTrackEventHandler : ITransientDependency, ICapSubscribe // 删除引发的回退更新 if (order.LatestTrackTime != null && - order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0)) == - @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone))) return; + @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) == + order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0))) + { + return; + } } else // upsert引发的更新 { if (order.LatestTrackTime != null && - order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0)) > - @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone))) return; + @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone)) < + order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0))) + { + return; + } } order.IsCompleted = @event.IsCompleted; diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs index 7c6f3159..a0733812 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -1,10 +1,12 @@ -using DotNetCore.CAP; +using System.Diagnostics; +using DotNetCore.CAP; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Queries; using SJZY.UserCenter.HttpApi.Services; using Volo.Abp.DependencyInjection; @@ -57,15 +59,52 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe @event.TrackCode = mapCode; } - await UpsertTrackAsync(@event); - } - - private async Task UpsertTrackAsync(TrackUpsertEvent @event) - { - // 不存在则新增轨迹,存在则更新 var track = await _trackDetailsRepository.GetFirstOrDefaultAsync(@event.OrderId, @event.TrackCode); - var orderIsCompleted = false; + // step1、upsert es轨迹 + await UpsertTrackAsync(track, @event); + Debug.Assert(track != null, nameof(track) + " != null"); + + // step2、触发轨迹推送事件(异步) + await HandleTrackPushAsync(@event, track); + + // step3、触发订单主表更新事件(异步) + await _capPublisher.PublishAsync(GlobalConst.TrackUpsertAfterUpdateOrderSubscribe, + new TrackUpsertAfterUpdateOrderEvent + { + OrderId = track.OrderId, + IsCompleted = track.IsCompleted, + TrackCode = track.TrackCode, + TrackContent = track.TrackContent, + TrackEnContent = track.TrackEnContent, + TrackPlace = track.TrackPlace, + TrackTime = track.TrackTime, + TrackTimeZone = track.TrackTimeZone + }); + + // step4、根据订单关联关系异步向下刷(异步) + var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderId); + foreach (var linkedOrder in linkedOrders) + { + var nextEvent = @event.DeepCopy(); + nextEvent.OrderId = linkedOrder.OrderId; + nextEvent.OrderType = linkedOrder.OrderType; + nextEvent.OrderNo = linkedOrder.OrderNo; + nextEvent.SubSystemId = linkedOrder.SubSystemId; + nextEvent.LatestPushTrackContentId = linkedOrder.LatestPushTrackContentId; + nextEvent.CustomId = linkedOrder.CustomId; + nextEvent.UpSubSystemId = @event.SubSystemId; + await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, nextEvent); + } + } + + /// + /// 不存在则新增轨迹,存在则更新 + /// + /// + /// + private async Task UpsertTrackAsync(TrackDetailsIndex? track, TrackUpsertEvent @event) + { if (track == default) { //todo:可以优化 @@ -73,12 +112,10 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe var trackContent = await _provideQueries.MatchTrackContentAsync(@event.OrderId, @event.TrackCode); if (trackContent == default) { - //throw new BusinessException(message: $"订单:{@event.OrderNo} 所绑定的模板,没有一条内容可以匹配轨迹代码:{@event.TrackCode}"); + // 订单所绑定的模板,没有一条内容可以匹配发生的轨迹 return; } - orderIsCompleted = trackContent.IsCompleted; - track = new TrackDetailsIndex { IndexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}", @@ -89,7 +126,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe TrackCode = @event.TrackCode, TrackContent = trackContent.Content, TrackContentId = trackContent.Id, - IsCompleted = orderIsCompleted, + IsCompleted = trackContent.IsCompleted, TrackEnContent = trackContent.EnContent, TrackPlace = @event.TrackPlace, TrackTime = @event.TrackTime!.Value, @@ -108,44 +145,47 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe track.UpdateTime = DateTime.Now; } - // upsert es轨迹 await _trackDetailsRepository.UpsertAsync(track); + } - // 触发轨迹推送事件 - var content = await _trackPushCacheService.InferNextPushContentOrNullAsync( + /// + /// 处理轨迹自动推送 + /// + /// + /// + private async Task HandleTrackPushAsync(TrackUpsertEvent @event, TrackDetailsIndex track) + { + var config = await _trackPushCacheService.InferNextPushContentOrNullAsync( @event.SubSystemId, @event.CustomId, @event.LatestPushTrackContentId); - if (content != default && content.TrackContentId == track.TrackContentId && - content.OrderType == @event.OrderType) - { - //await PushTrack(content); - } - // 触发订单主表更新事件 - await _capPublisher.PublishAsync(GlobalConst.UpdateOrderTrackSubscribe, new UpdateOrderTrackEvent - { - OrderId = track.OrderId, - IsCompleted = orderIsCompleted, - TrackCode = track.TrackCode, - TrackContent = track.TrackContent, - TrackEnContent = track.TrackEnContent, - TrackPlace = track.TrackPlace, - TrackTime = track.TrackTime, - TrackTimeZone = track.TrackTimeZone - }); + if (config == null || !config.IsAutoPush) return; - // 根据订单关联关系异步向下刷 - var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderId); - foreach (var linkedOrder in linkedOrders) + // 当前发生的轨迹就是要推送的 + if (config.TrackContentId == track.TrackContentId && config.OrderType == @event.OrderType) { - var nextEvent = @event.DeepCopy(); - nextEvent.OrderId = linkedOrder.OrderId; - nextEvent.OrderType = linkedOrder.OrderType; - nextEvent.OrderNo = linkedOrder.OrderNo; - nextEvent.SubSystemId = linkedOrder.SubSystemId; - nextEvent.LatestPushTrackContentId = linkedOrder.LatestPushTrackContentId; - nextEvent.CustomId = linkedOrder.CustomId; - nextEvent.UpSubSystemId = @event.SubSystemId; - await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, nextEvent); + var trackPushEvent = new TrackPushEvent + { + ServiceProviderCode = config.ServiceProviderCode, + OrderNo = track.OrderNo, + TrackContentId = config.TrackContentId, + TrackPlace = track.TrackPlace, + TrackTime = track.TrackTime.AddHours(config.TrackTimeZone ?? track.TrackTimeZone - track.TrackTimeZone), + TrackTimeZone = (float)(config.TrackTimeZone ?? track.TrackTimeZone), + TrackContentCodeValue = config.TrackContentCodeValue, + TrackContentValue = config.TrackContentValue, + TrackEnContentValue = config.TrackEnContentValue, + TrackStatusValue = config.TrackStatusValue, + ExpandFieldsValue = config.ExpandFieldsValue + }; + + // 推送更新 + if (!track.Id.IsNullOrWhiteSpace()) + { + trackPushEvent.OptionType = OptionType.修改; + if (!config.IsCanUpdate) return; + } + + await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); } } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs index 51f50f3b..88eb9530 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs @@ -2,6 +2,7 @@ using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Events; using SJZY.Track.Domain.Aggregates.OrderAggregate; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Queries; namespace SJZY.Track.Application.Services.ProvideServices; diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs index 10f1d52a..f1f72e52 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs @@ -1,9 +1,11 @@ using Microsoft.AspNetCore.Authorization; +using Newtonsoft.Json; using SJZY.Expand.ABP.Core; using SJZY.InterfaceRelay.Application.Contracts; using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Dtos.TrackPull; using SJZY.Track.Application.Contract.Services; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Queries; using Volo.Abp.Http.Client.DynamicProxying; @@ -40,27 +42,27 @@ public class TrackPullService : ApplicationService // todo:罚时? input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空 - // 这里没有区分订单类型,就算的不同类型的单一起刷新了也无所谓 + // tips:这里没有区分订单类型,就算的不同类型的单一起刷新了也无所谓 var orders = await _provideQueries.FindOrderWithServiceProviderAsync(input.OrderNos); if (orders.Count == 0) { - throw new BusinessException(message: "一个拉取配置都不存在"); + // tips:可能是没有配置、或者所有单都刷完了、或者单不存在 + throw new BusinessException(message: "一个能更新的都没有"); } - foreach (var group in orders.GroupBy(x => x.ServiceProviderCode)) + foreach (var group in orders.GroupBy(x => + new TrackRefreshAttach(x.ServiceProviderId, x.ServiceProviderCode, x.SubSystemId, x.OrderType))) { - var data = group.Select(x => new TrackRefreshDto + var data = group.Select(x => new { - OrderType = x.OrderType, - OrderNo = x.OrderNo, - ServiceProviderId = x.ServiceProviderId, - SubSystemId = x.SubSystemId + x.OrderNo }).ToList(); // 批量获取轨迹 await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( - "A012", group.Key, data, GlobalConst.TrackRefreshSubscribe); + "A012", group.Key.ServiceProviderCode, data, + GlobalConst.TrackRefreshSubscribe, JsonConvert.SerializeObject(group.Key)); } return true; @@ -85,19 +87,19 @@ public class TrackPullService : ApplicationService var orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId); - foreach (var group in orders.GroupBy(x => x.ServiceProviderCode)) + foreach (var group in orders.GroupBy(x => + new TrackRefreshAttach(x.ServiceProviderId, x.ServiceProviderCode, x.SubSystemId, + x.OrderType))) { - var data = group.Select(x => new TrackRefreshDto + var data = group.Select(x => new { - OrderType = x.OrderType, - OrderNo = x.OrderNo, - ServiceProviderId = x.ServiceProviderId, - SubSystemId = x.SubSystemId + x.OrderNo }).ToList(); // 批量获取轨迹 await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( - "A012", group.Key, data, GlobalConst.TrackRefreshSubscribe); + InterfaceRelayConst.GetTrackInterfaceCode, group.Key.ServiceProviderCode, data, + GlobalConst.TrackRefreshSubscribe, JsonConvert.SerializeObject(group.Key)); } await RedisHelper.Client.SetExAsync(redisKey, config.PullInterval * 60, 1); diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs index 443bceb3..1ad3a61c 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs @@ -1,9 +1,11 @@ -using SJZY.InterfaceRelay.Application.Contracts; +using DotNetCore.CAP; using SJZY.Track.Application.Contract.Dtos.ProvideServices; +using SJZY.Track.Application.Contract.Events; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; -using Volo.Abp.Http.Client.DynamicProxying; +using SJZY.Track.Domain.Consts; +using SJZY.UserCenter.HttpApi.Services; namespace SJZY.Track.Application.Services.ProvideServices; @@ -17,16 +19,17 @@ public class TrackPushService : ApplicationService private readonly ITrackDetailsRepository _trackDetailsRepository; private readonly IOrderRepository _orderRepository; private readonly ITrackPushCacheService _pushCacheService; - private readonly IHttpClientProxy _httpClientProxy; + private readonly ICapPublisher _capPublisher; - public TrackPushService( - IHttpClientProxy httpClientProxy, ITrackPushCacheService pushCacheService, - ITrackDetailsRepository trackDetailsRepository, IOrderRepository orderRepository) + public TrackPushService(ITrackPushCacheService pushCacheService, + ITrackDetailsRepository trackDetailsRepository + , IOrderRepository orderRepository + , ICapPublisher capPublisher) { - _httpClientProxy = httpClientProxy; _pushCacheService = pushCacheService; _trackDetailsRepository = trackDetailsRepository; _orderRepository = orderRepository; + _capPublisher = capPublisher; } /// @@ -35,11 +38,10 @@ public class TrackPushService : ApplicationService /// /// [HttpPost("Track/Push")] - public async Task PushTrackAsync(PushTrackInput input) + public async Task PushTrackAsync(PushTrackInput input) { input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空 - var orders = await _orderRepository.GetListAsync(x => x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => new { @@ -53,6 +55,13 @@ public class TrackPushService : ApplicationService var tracks = await _trackDetailsRepository.GetListAsync(input.OrderType, input.OrderNos, input.TrackCode); + if (tracks.Count == 0) + { + throw new BusinessException(message: "一个能推的轨迹都不存在"); + } + + var res = 0; + foreach (var order in orders) { // 如果没有轨迹,就不需要推 @@ -64,30 +73,27 @@ public class TrackPushService : ApplicationService await _pushCacheService.GetPushContentConfigAsync(order.SubSystemId, order.CustomId, track.TrackContentId); - var data = new + var trackPushEvent = new TrackPushEvent { - order.OrderNo, - data = new[] - { - new - { - // 推真实的发生地和发生时间 - location = track.TrackPlace, - date = track.TrackTime.AddHours(config.TrackTimeZone ?? - track.TrackTimeZone - track.TrackTimeZone), - timeZone = config.TrackTimeZone ?? track.TrackTimeZone, - description = config.TrackEnContentValue, - description_cn = config.TrackContentValue, - code = config.TrackContentCodeValue, - status = config.TrackStatusValue, - extra = config.ExpandFieldsValue - } - } + ServiceProviderCode = config.ServiceProviderCode, + OrderNo = order.OrderNo, + TrackPlace = track.TrackPlace, + TrackTime = track.TrackTime.AddHours(config.TrackTimeZone ?? + track.TrackTimeZone - track.TrackTimeZone), + TrackTimeZone = (float)(config.TrackTimeZone ?? track.TrackTimeZone), + TrackContentCodeValue = config.TrackContentCodeValue, + TrackContentValue = config.TrackContentValue, + TrackEnContentValue = config.TrackEnContentValue, + TrackStatusValue = config.TrackStatusValue, + ExpandFieldsValue = config.ExpandFieldsValue, + PushMan = CurrentUserRequest.CurrentUser.Name, }; - await _httpClientProxy.Service.ForwardWithSubscribeAsync("A024", config.ServiceProviderCode, data); + await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); + + res++; } - return true; + return $"即将推送轨迹代码{input.TrackCode}给{res}个订单"; } } \ No newline at end of file diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs index b9af7e6e..b45d9313 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs @@ -4,6 +4,7 @@ using SJZY.Track.Application.Contract.Events; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Queries; namespace SJZY.Track.Application.Services.ProvideServices; @@ -41,7 +42,7 @@ public partial class TrackService : ApplicationService, ITrackService var order = await _orderRepository.GetFirstAsync(x => x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => new { - x.Id, x.SubSystemId, x.LatestPushTrackContentId, x.CustomId + x.Id, x.SubSystemId, x.LatestPushTrackContentId, x.CustomId, x.IsCompleted }); if (order == default) { @@ -54,6 +55,7 @@ public partial class TrackService : ApplicationService, ITrackService @event.SubSystemId = order.SubSystemId; @event.LatestPushTrackContentId = order.LatestPushTrackContentId; @event.CustomId = order.CustomId; + @event.IsCompleted = order.IsCompleted; await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event); return true; } diff --git a/src/SJZY.Track.Application/Services/TrackPull/TrackPullCacheService.cs b/src/SJZY.Track.Application/Services/TrackPull/TrackPullCacheService.cs index b5418f24..c5c7f8fd 100644 --- a/src/SJZY.Track.Application/Services/TrackPull/TrackPullCacheService.cs +++ b/src/SJZY.Track.Application/Services/TrackPull/TrackPullCacheService.cs @@ -3,12 +3,12 @@ using SJZY.Expand.ABP.Core; using SJZY.Track.Application.Contract.Dtos.TrackPull; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.TrackPullAggregate; +using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Dtos.TrackPull; -using Volo.Abp.DependencyInjection; namespace SJZY.Track.Application.Services.TrackPull; -public class TrackPullCacheService : ApplicationService, ITrackPullCacheService, ITransientDependency +public class TrackPullCacheService : ApplicationService, ITrackPullCacheService { private readonly ITrackPullConfigRepository _trackPullConfigRepository; diff --git a/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs b/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs index daba134c..af00b7c6 100644 --- a/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs @@ -9,7 +9,6 @@ using SJZY.Track.Domain.Aggregates.TrackPullAggregate; using SJZY.Track.Domain.Dtos.Common; using SJZY.Track.Domain.Dtos.TrackPull; using SqlSugar; -using Volo.Abp.DependencyInjection; namespace SJZY.Track.Application.Services.TrackPull; @@ -18,7 +17,7 @@ namespace SJZY.Track.Application.Services.TrackPull; /// [ApiExplorerSettings(GroupName = "轨迹拉取")] [Route("/Track/PullConfig")] -public class TrackPullService : ApplicationService, ITransientDependency +public class TrackPullService : ApplicationService { private readonly IStringLocalizer _stringLocalizer; private readonly ITrackPullConfigRepository _trackPullConfigRepository; @@ -100,52 +99,57 @@ public class TrackPullService : ApplicationService, ITransientDependency switch (input.Options) { case OptionTypeNoNull.新增: + { + var trackPullEntity = ObjectMapper.Map(input); + var trackPullParamsEntity = + ObjectMapper.Map(input); + + int id; + + using (var ts = TransactionScopeHelper.Create()) { - var trackPullEntity = ObjectMapper.Map(input); - var trackPullParamsEntity = ObjectMapper.Map(input); + id = await _trackPullConfigRepository.InsertReturnIdentityAsync(trackPullEntity); - int id = 0; + trackPullParamsEntity.PullOrPushConfigId = id; + await _trackPullConfigRepository.InsertParamsAsync(trackPullParamsEntity); - using (var ts = TransactionScopeHelper.Create()) - { - id = await _trackPullConfigRepository.InsertReturnIdentityAsync(trackPullEntity); - - trackPullParamsEntity.PullOrPushConfigId = id; - await _trackPullConfigRepository.InsertParamsAsync(trackPullParamsEntity); - - ts.Complete(); - } - - await _trackPullCacheService.SetPullConfigAsync(id); + ts.Complete(); } + + await _trackPullCacheService.SetPullConfigAsync(id); + } break; case OptionTypeNoNull.修改: + { + var oldTrackPullEntity = await _trackPullConfigRepository.GetFirstAsync(x => x.Id == input.Id) ?? + throw new BusinessException(message: _stringLocalizer["NotFindData"]); + + var oldTrackPullParamsEntity = + await _trackPullConfigRepository.GetParamsSingleAsync(x => + x.PullOrPushConfigId == input.Id && !x.IsPush); + + ObjectMapper.Map(input, oldTrackPullEntity); + ObjectMapper.Map(input, oldTrackPullParamsEntity); + + using (var ts = TransactionScopeHelper.Create()) { - var oldTrackPullEntity = await _trackPullConfigRepository.GetFirstAsync(x => x.Id == input.Id) ?? throw new BusinessException(message: _stringLocalizer["NotFindData"]); + await _trackPullConfigRepository.UpdateAsync(oldTrackPullEntity); + await _trackPullConfigRepository.UpdateParamsAsync(oldTrackPullParamsEntity); - var oldTrackPullParamsEntity = await _trackPullConfigRepository.GetParamsSingleAsync(x => x.PullOrPushConfigId == input.Id && !x.IsPush); - - ObjectMapper.Map(input, oldTrackPullEntity); - ObjectMapper.Map(input, oldTrackPullParamsEntity); - - using (var ts = TransactionScopeHelper.Create()) - { - await _trackPullConfigRepository.UpdateAsync(oldTrackPullEntity); - await _trackPullConfigRepository.UpdateParamsAsync(oldTrackPullParamsEntity); - - ts.Complete(); - } - - await _trackPullCacheService.SetPullConfigAsync(input.Id); + ts.Complete(); } + + await _trackPullCacheService.SetPullConfigAsync(input.Id); + } break; case OptionTypeNoNull.删除: using (var ts = TransactionScopeHelper.Create()) { await _trackPullConfigRepository.SoftDeleteAsync(x => x.Id == input.Id); - await _trackPullConfigRepository.SoftDeleteParamsAsync(x => x.PullOrPushConfigId == input.Id && !x.IsPush); + await _trackPullConfigRepository.SoftDeleteParamsAsync(x => + x.PullOrPushConfigId == input.Id && !x.IsPush); await _trackPullConfigRepository.SoftDeleteContentAsync(x => x.TrackPullConfigId == input.Id); ts.Complete(); @@ -171,21 +175,32 @@ public class TrackPullService : ApplicationService, ITransientDependency { if (input.Options != OptionTypeNoNull.删除) { - Expression> isContentAnyExp = x => x.TrackPullConfigId == input.TrackPullConfigId; + Expression> isContentAnyExp = x => + x.TrackPullConfigId == input.TrackPullConfigId; if (input.Options == OptionTypeNoNull.修改) isContentAnyExp = isContentAnyExp.And(x => x.Id != input.Id); - if (await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackContentId == input.TrackContentId))) + if (await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => + x.TrackContentId == input.TrackContentId))) throw new BusinessException(message: _stringLocalizer["IsTrackPullContentAny"]); - else if (!input.TrackContentCodeValue.IsNullOrWhiteSpace() && await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackContentCodeValue == input.TrackContentCodeValue))) + else if (!input.TrackContentCodeValue.IsNullOrWhiteSpace() && + await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => + x.TrackContentCodeValue == input.TrackContentCodeValue))) throw new BusinessException(message: _stringLocalizer["IsTrackPullContentCodeValueAny"]); - else if (!input.TrackStatusValue.IsNullOrWhiteSpace() && await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackStatusValue == input.TrackStatusValue))) + else if (!input.TrackStatusValue.IsNullOrWhiteSpace() && + await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => + x.TrackStatusValue == input.TrackStatusValue))) throw new BusinessException(message: _stringLocalizer["IsTrackPullContentStatusValueAny"]); - else if (!input.TrackContentValue.IsNullOrWhiteSpace() && await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackContentValue == input.TrackContentValue))) + else if (!input.TrackContentValue.IsNullOrWhiteSpace() && + await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => + x.TrackContentValue == input.TrackContentValue))) throw new BusinessException(message: _stringLocalizer["IsTrackPullContentValueAny"]); else if (!input.TrackKeywords.IsNullOrEmpty()) { Expression> trackKeywordExp = _ => false; - input.TrackKeywords!.ForEach(item => { trackKeywordExp = trackKeywordExp.Or(x => SqlFunc.SplitIn(x.TrackKeyword, item)); }); + input.TrackKeywords!.ForEach(item => + { + trackKeywordExp = trackKeywordExp.Or(x => SqlFunc.SplitIn(x.TrackKeyword, item)); + }); if (await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(trackKeywordExp))) throw new BusinessException(message: _stringLocalizer["IsTrackPullContentKeywordsAny"]); @@ -195,38 +210,38 @@ public class TrackPullService : ApplicationService, ITransientDependency switch (input.Options) { case OptionTypeNoNull.新增: - { - var entity = ObjectMapper.Map(input); + { + var entity = ObjectMapper.Map(input); - await _trackPullConfigRepository.InsertContentAsync(entity); - await _trackPullCacheService.SetPullConfigAsync(input.TrackPullConfigId); + await _trackPullConfigRepository.InsertContentAsync(entity); + await _trackPullCacheService.SetPullConfigAsync(input.TrackPullConfigId); - break; - } + break; + } case OptionTypeNoNull.修改: - { - var oldTrackPullContentEntity = await _trackPullConfigRepository.GetContentByIdAsync(input.Id!.Value) ?? - throw new BusinessException(message: _stringLocalizer["NotFindData"]); + { + var oldTrackPullContentEntity = await _trackPullConfigRepository.GetContentByIdAsync(input.Id!.Value) ?? + throw new BusinessException(message: _stringLocalizer["NotFindData"]); - ObjectMapper.Map(input, oldTrackPullContentEntity); + ObjectMapper.Map(input, oldTrackPullContentEntity); - await _trackPullConfigRepository.UpdateContentAsync(oldTrackPullContentEntity); - await _trackPullCacheService.SetPullConfigAsync(oldTrackPullContentEntity.TrackPullConfigId); + await _trackPullConfigRepository.UpdateContentAsync(oldTrackPullContentEntity); + await _trackPullCacheService.SetPullConfigAsync(oldTrackPullContentEntity.TrackPullConfigId); - break; - } + break; + } case OptionTypeNoNull.删除: - { - var oldTrackPullContentEntity = await _trackPullConfigRepository.GetContentByIdAsync(input.Id!.Value) ?? - throw new BusinessException(message: _stringLocalizer["NotFindData"]); + { + var oldTrackPullContentEntity = await _trackPullConfigRepository.GetContentByIdAsync(input.Id!.Value) ?? + throw new BusinessException(message: _stringLocalizer["NotFindData"]); - await _trackPullConfigRepository.SoftDeleteContentAsync(x => x.Id == input.Id); - await _trackPullCacheService.SetPullConfigAsync(oldTrackPullContentEntity.TrackPullConfigId); + await _trackPullConfigRepository.SoftDeleteContentAsync(x => x.Id == input.Id); + await _trackPullCacheService.SetPullConfigAsync(oldTrackPullContentEntity.TrackPullConfigId); - break; - } + break; + } default: throw new BusinessException(message: _stringLocalizer[SjzyBasicLocalization.Validation_IsInEnum, diff --git a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs index 36e386b8..46155e2e 100644 --- a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs +++ b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs @@ -3,11 +3,11 @@ using SJZY.Expand.ABP.Core; using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.TrackPushAggregate; -using Volo.Abp.DependencyInjection; +using SJZY.Track.Domain.Consts; namespace SJZY.Track.Application.Services.TrackPush; -public class TrackPushCacheService : ApplicationService, ITrackPushCacheService, ITransientDependency +public class TrackPushCacheService : ApplicationService, ITrackPushCacheService { private readonly ITrackPushConfigRepository _trackPushConfigRepository; diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs index 964b4ee4..43721588 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs @@ -1,5 +1,6 @@ using Nest; using SJZY.Expand.ElasticSearch; +using SJZY.Track.Domain.Consts; namespace SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; @@ -11,11 +12,6 @@ public class TrackDetailsIndex : IdBaseIndex /// public int OrderId { get; set; } - /// - /// 服务商code - /// - public string? ServiceProviderCode { get; set; } - /// /// 订单号 /// @@ -36,11 +32,6 @@ public class TrackDetailsIndex : IdBaseIndex /// public string TrackStatus { get; set; } = null!; - /// - /// 原轨迹状态 - /// - public string? OriginTrackStatus { get; set; } - /// /// 轨迹内容代码 /// @@ -57,10 +48,15 @@ public class TrackDetailsIndex : IdBaseIndex public int TrackContentId { get; set; } /// - /// 是否意味着完成 + /// 这条轨迹是否意味着完成(删除回退需要用到) /// public bool IsCompleted { get; set; } + /// + /// 原轨迹状态 + /// + public string? OriginTrackStatus { get; set; } + /// /// 原轨迹内容 /// diff --git a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushRecordsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushRecordsRepository.cs new file mode 100644 index 00000000..c7ae38be --- /dev/null +++ b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushRecordsRepository.cs @@ -0,0 +1,11 @@ +namespace SJZY.Track.Domain.Aggregates.TrackPushAggregate; + +public interface ITrackPushRecordsRepository +{ + /// + /// 添加推送记录 + /// + /// + /// + Task AddAsync(TrackPushRecordIndex index); +} \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/TrackPushRecordIndex.cs b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/TrackPushRecordIndex.cs new file mode 100644 index 00000000..66800c8a --- /dev/null +++ b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/TrackPushRecordIndex.cs @@ -0,0 +1,51 @@ +using Nest; +using SJZY.Expand.ABP.Common.Enums; +using SJZY.Expand.ElasticSearch; +using SJZY.Track.Domain.Consts; + +namespace SJZY.Track.Domain.Aggregates.TrackPushAggregate; + +[ElasticsearchType(RelationName = GlobalConst.TrackPushRecordsIndex)] +public class TrackPushRecordIndex : IdBaseIndex +{ + /// + /// 索引名称 + /// + public string IndexName { get; set; } = null!; + + /// + /// 接口通请求Id + /// + public Guid RequestId { get; set; } + + /// + /// 操作类型 + /// + public OptionType OptionType { get; set; } + + /// + /// 轨迹发生地 + /// + public string TrackPlace { get; set; } = null!; + + /// + /// 轨迹发生时间 + /// + public DateTime TrackTime { get; set; } + + /// + /// 轨迹发生时区 + /// + public float TrackTimeZone { get; set; } + + /// + /// 是否成功 + /// + public bool IsSuccess { get; set; } + + /// 创建人 + public string? CreateUser { get; set; } + + /// 创建时间 + public DateTime CreateTime { get; set; } +} \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.ES.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.ES.cs new file mode 100644 index 00000000..3dd246c4 --- /dev/null +++ b/src/SJZY.Track.Domain/Consts/GlobalConst.ES.cs @@ -0,0 +1,14 @@ +namespace SJZY.Track.Domain.Consts; + +public partial class GlobalConst +{ + /// + /// 轨迹明细 es索引名称(模板) + /// + public const string TrackIndex = "sjzy_track_details"; + + /// + /// 轨迹推送记录 es索引名称(模板) + /// + public const string TrackPushRecordsIndex = "sjzy_track_push_records"; +} \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs new file mode 100644 index 00000000..d9dfd74b --- /dev/null +++ b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs @@ -0,0 +1,39 @@ +namespace SJZY.Track.Domain.Consts; + +public partial class GlobalConst +{ + /// + /// 轨迹新增/更新 + /// + public const string TrackUpsertSubscribe = "SJZY.Track.TrackUpsert"; + + /// + /// 轨迹删除 + /// + public const string TrackDeleteSubscribe = "SJZY.Track.TrackDelete"; + + /// + /// 接口通批量轨迹刷新 + /// + public const string TrackRefreshSubscribe = "SJZY.Track.TrackRefresh"; + + /// + /// 轨迹推送 + /// + public const string TrackPushSubscribe = "SJZY.Track.TrackPush"; + + /// + /// 轨迹新增/更新后触发更新订单主表 + /// + public const string TrackUpsertAfterUpdateOrderSubscribe = "SJZY.Track.TrackUpsertAfterUpdateOrder"; + + /// + /// 轨迹推送后触发更新订单主表 + /// + public const string TrackPushAfterUpdateOrderSubscribe = "SJZY.Traack.TrackPushAfterUpdateOrder"; + + /// + /// 关联订单后补轨迹 + /// + public const string OrderLinkAfterFillTrack = "SJZY.Track.OrderLinkAfterFillTrack"; +} \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.Redis.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.Redis.cs new file mode 100644 index 00000000..e2ca18ae --- /dev/null +++ b/src/SJZY.Track.Domain/Consts/GlobalConst.Redis.cs @@ -0,0 +1,24 @@ +namespace SJZY.Track.Domain.Consts; + +public partial class GlobalConst +{ + /// + /// 轨迹要推送的客户redis key前缀 + /// + public const string TrackPushKeyPrefix = "TrackPush"; + + /// + /// 轨迹推送内容配置redis key前缀 + /// + public const string TrackPushContentKeyPrefix = "TrackPushContent"; + + /// + /// 轨迹拉取配置信息redis key前缀 + /// + public const string TrackPullKeyPrefix = "TrackPull"; + + /// + /// 轨迹拉取配置信息redis key前缀 + /// + public const string TrackPullContentKeyPrefix = "TrackPullContent"; +} \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Consts/InterfaceRelayConst.cs b/src/SJZY.Track.Domain/Consts/InterfaceRelayConst.cs new file mode 100644 index 00000000..24743a5b --- /dev/null +++ b/src/SJZY.Track.Domain/Consts/InterfaceRelayConst.cs @@ -0,0 +1,27 @@ +namespace SJZY.Track.Domain.Consts; + +/// +/// 接口通常量 +/// +public class InterfaceRelayConst +{ + /// + /// 接口通成功代码 + /// + public const string SuccessCode = "200"; + + /// + /// 获取轨迹接口代码 + /// + public const string GetTrackInterfaceCode = "A012"; + + /// + /// 推送轨迹接口代码 + /// + public const string PushTrackInterfaceCode = "A024"; + + /// + /// 更新轨迹接口代码 + /// + public const string TrackUpdateInterfaceCode = "A040"; +} \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs b/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs index 8cc9fbb2..2e0ffbed 100644 --- a/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs +++ b/src/SJZY.Track.Domain/Dtos/Order/LinkedOrderVO.cs @@ -31,4 +31,9 @@ public class LinkedOrderVO /// 客户id /// public int CustomId { get; set; } + + /// + /// 订单是否完成 + /// + public bool IsCompleted { get; set; } } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Enums/TrackProblemType.cs b/src/SJZY.Track.Domain/Enums/TrackPushProblemType.cs similarity index 64% rename from src/SJZY.Track.Domain/Enums/TrackProblemType.cs rename to src/SJZY.Track.Domain/Enums/TrackPushProblemType.cs index 4abcc47e..93bbdbcb 100644 --- a/src/SJZY.Track.Domain/Enums/TrackProblemType.cs +++ b/src/SJZY.Track.Domain/Enums/TrackPushProblemType.cs @@ -1,8 +1,13 @@ namespace SJZY.Track.Domain.Enums; [Flags] -public enum TrackProblemType +public enum TrackPushProblemType { + /// + /// 没问题 + /// + None = 0, + /// /// 异常 /// diff --git a/src/SJZY.Track.Domain/GlobalConst.cs b/src/SJZY.Track.Domain/GlobalConst.cs deleted file mode 100644 index 528115ea..00000000 --- a/src/SJZY.Track.Domain/GlobalConst.cs +++ /dev/null @@ -1,54 +0,0 @@ -namespace SJZY.Track.Domain; - -public class GlobalConst -{ - /// - /// 轨迹明细 es索引名称 - /// - public const string TrackIndex = "sjzy_track_details"; - - /// - /// 轨迹新增/更新 mq订阅名称 - /// - public const string TrackUpsertSubscribe = "SJZY.Track.TrackUpsert"; - - /// - /// 轨迹删除 mq订阅名称 - /// - public const string TrackDeleteSubscribe = "SJZY.Track.TrackDelete"; - - /// - /// 接口通批量轨迹刷新 mq订阅名称 - /// - public const string TrackRefreshSubscribe = "SJZY.Track.TrackRefresh"; - - /// - /// 轨迹新增/更新后触发更新订单轨迹 mq订阅名称 - /// - public const string UpdateOrderTrackSubscribe = "SJZY.Track.UpdateOrderTrack"; - - /// - /// 关联订单后补轨迹 mq订阅名称 - /// - public const string OrderLinkAfterFillTrack = "SJZY.Track.OrderLinkAfterFillTrack"; - - /// - /// 轨迹要推送的客户redis key前缀 - /// - public const string TrackPushKeyPrefix = "TrackPush"; - - /// - /// 轨迹推送内容配置redis key前缀 - /// - public const string TrackPushContentKeyPrefix = "TrackPushContent"; - - /// - /// 轨迹拉取配置信息redis key前缀 - /// - public const string TrackPullKeyPrefix = "TrackPull"; - - /// - /// 轨迹拉取配置信息redis key前缀 - /// - public const string TrackPullContentKeyPrefix = "TrackPullContent"; -} \ No newline at end of file diff --git a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs index 8058689e..5bf07b06 100644 --- a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs +++ b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs @@ -113,7 +113,7 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, return await Context.Queryable() .LeftJoin((a, b) => a.Id == b.OrderId) .LeftJoin((a, b, c) => b.ServiceProviderId == c.Id) - .Where(a => orderNos.Contains(a.OrderNo)) + .Where(a => !a.IsCompleted && orderNos.Contains(a.OrderNo)) .Select((a, b, c) => new OrderWithServiceProviderVO { OrderNo = a.OrderNo, diff --git a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs index 633db8c2..26a8ed2b 100644 --- a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs @@ -67,7 +67,8 @@ public class OrderRepository : BasicRepository, IOrderRepository, I OrderNo = b.OrderNo, SubSystemId = b.SubSystemId, LatestPushTrackContentId = b.LatestPushTrackContentId, - CustomId = b.CustomId + CustomId = b.CustomId, + IsCompleted = b.IsCompleted }) .ToListAsync(); } diff --git a/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs new file mode 100644 index 00000000..31adf93d --- /dev/null +++ b/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs @@ -0,0 +1,28 @@ +using SJZY.Expand.ABP.Core.Logger; +using SJZY.Expand.ElasticSearch.Services; +using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; +using SJZY.Track.Domain.Aggregates.TrackPushAggregate; + +namespace SJZY.Track.Repository.Repositories; + +public class TrackPushRecordsRepository : ElasticSearchContextAbstract, ITrackPushRecordsRepository, + ITransientDependency +{ + public TrackPushRecordsRepository(ConnectionFactory connectionFactory) : base(connectionFactory) + { + } + + public async Task AddAsync(TrackPushRecordIndex index) + { + // 按天写入es + var r = await Context.IndexAsync(index, request => request + .Index(index.IndexName) + //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 + ); + + if (!r.IsValid) + { + LogHelper.Error($"轨迹推送记录写入es失败,原因:{r.DebugInformation}。"); + } + } +} \ No newline at end of file