diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs
index fa5d3880..1c90e3a9 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs
@@ -4,6 +4,11 @@ namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class BatchUpsertTrackInput : OrderNosInfo
{
+ ///
+ /// true新增,false更新
+ ///
+ public bool IsAdd { get; set; }
+
///
/// 轨迹内容代码
///
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs
index 8248c8e0..ce97f715 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs
@@ -4,6 +4,11 @@ namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class UpsertTrackInput : OrderNoInfo
{
+ ///
+ /// true新增,false更新
+ ///
+ public bool IsAdd { get; set; }
+
///
/// 轨迹内容代码
///
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushConfigDto.cs
similarity index 96%
rename from src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs
rename to src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushConfigDto.cs
index a019087f..1f129458 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/TrackPush/TrackPushConfigDto.cs
@@ -1,4 +1,4 @@
-namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
+namespace SJZY.Track.Application.Contract.Dtos.TrackPush;
public class TrackPushConfigDto
{
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs
index eb836245..d6fcb03a 100644
--- a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs
+++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs
@@ -38,4 +38,14 @@ public class TrackUpsertEvent : UpsertTrackInput
/// 已经处理过的订单
///
public List Visited { get; set; } = new();
+
+ ///
+ /// 原轨迹内容
+ ///
+ public string? OriginTrackContent { get; set; }
+
+ ///
+ /// 原轨迹报文
+ ///
+ public string? OriginTrackData { get; set; }
}
\ No newline at end of file
diff --git a/src/SJZY.Track.Application.Contract/Services/ITrackPushCacheService.cs b/src/SJZY.Track.Application.Contract/Services/ITrackPushCacheService.cs
index a4a57bc0..91b80c3e 100644
--- a/src/SJZY.Track.Application.Contract/Services/ITrackPushCacheService.cs
+++ b/src/SJZY.Track.Application.Contract/Services/ITrackPushCacheService.cs
@@ -1,4 +1,4 @@
-using SJZY.Track.Application.Contract.Dtos.ProvideServices;
+using SJZY.Track.Application.Contract.Dtos.TrackPush;
namespace SJZY.Track.Application.Contract.Services;
@@ -19,7 +19,7 @@ public interface ITrackPushCacheService
/// 服务商id
///
///
- Task GetPushContentConfigAsync(int subSystemId, int customId, int trackContentId);
+ Task GetPushContentConfigAsync(int subSystemId, int customId, int trackContentId);
///
/// 根据轨迹代码推断下一个(升序)要推送的内容,如果找不到或者已经是最后一个了,返回null
diff --git a/src/SJZY.Track.Application/AutoMapper/TrackPushAutoMapperProfile.cs b/src/SJZY.Track.Application/AutoMapper/TrackPushAutoMapperProfile.cs
index 6be69d46..213d7872 100644
--- a/src/SJZY.Track.Application/AutoMapper/TrackPushAutoMapperProfile.cs
+++ b/src/SJZY.Track.Application/AutoMapper/TrackPushAutoMapperProfile.cs
@@ -1,8 +1,8 @@
using AutoMapper;
-using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Dtos.TrackPush;
using SJZY.Track.Domain.Aggregates.TrackPullAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
+using SJZY.Track.Domain.Dtos.TrackPush;
using Volo.Abp.AutoMapper;
namespace SJZY.Track.Application.AutoMapper;
@@ -15,7 +15,6 @@ public class TrackPushAutoMapperProfile : Profile
CreateMap(MemberList.None).Ignore(dest => dest.Id)
.ForMember(dest => dest.IsPush, opt => opt.MapFrom(source => true));
CreateMap(MemberList.None);
- CreateMap(MemberList.None)
- .ForMember(dest => dest.OrderType, opt => opt.MapFrom(source => source.OrderNoType));
+ CreateMap(MemberList.None);
}
}
\ No newline at end of file
diff --git a/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs
new file mode 100644
index 00000000..fbee07b0
--- /dev/null
+++ b/src/SJZY.Track.Application/EventHandlers/CAPFilter.cs
@@ -0,0 +1,109 @@
+using System.Globalization;
+using DotNetCore.CAP.Filter;
+using SJZY.Expand.ABP.Core;
+using SJZY.Expand.ABP.Core.Logger;
+using SJZY.Expand.ABP.Core.PublicMethords;
+
+namespace SJZY.Track.Application.EventHandlers;
+
+public class CAPFilter : SubscribeFilter
+{
+ const string _ERROR_CODE = "Error599";
+
+ ///
+ /// 执行前
+ ///
+ ///
+ ///
+ public override Task OnSubscribeExecutingAsync(ExecutingContext context)
+ {
+ var argumentJsonStr = context.Arguments.ToJson();
+
+ context.DeliverMessage.Headers["sjzy-receive-time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
+ context.DeliverMessage.Headers["sjzy-arguments"] = argumentJsonStr;
+
+ if (!string.IsNullOrEmpty(argumentJsonStr))
+ {
+ var hash = argumentJsonStr.GetHash();
+ using (RedisHelper.Client.Lock("Filter:" + hash, 10))
+ {
+ var isSkip = !string.IsNullOrEmpty(RedisHelper.Client.Get($"CapExcuteFilter:{hash}"));
+ if (isSkip)
+ throw new BusinessException(_ERROR_CODE, $"检测到重复消费,消费参数:{argumentJsonStr}");
+
+ RedisHelper.Client.Set($"CapExcuteFilter:{hash}", 60 * 10,
+ TimeSpan.FromDays(1).Seconds); // 1天内不允许一模一样的参数重复消费
+ }
+ }
+
+ return Task.CompletedTask;
+ }
+
+ ///
+ /// 执行后
+ ///
+ ///
+ ///
+ public override Task OnSubscribeExecutedAsync(ExecutedContext context)
+ {
+ context.DeliverMessage.Headers.TryGetValue("sjzy-receive-time", out var receiveTime);
+ context.DeliverMessage.Headers.TryGetValue("cap-msg-name", out var receiveName);
+ context.DeliverMessage.Headers.TryGetValue("sjzy-arguments", out var arguments);
+ context.DeliverMessage.Headers.TryGetValue("cap-msg-id", out var messageId);
+
+ BuildLog(receiveTime, receiveName, arguments, false, messageId);
+
+ return Task.CompletedTask;
+ }
+
+
+ ///
+ /// 消费异常事件
+ ///
+ ///
+ ///
+ public override Task OnSubscribeExceptionAsync(ExceptionContext context)
+ {
+ context.ExceptionHandled = true;
+
+ if (context.Exception is BusinessException ex && ex.Code == _ERROR_CODE)
+ LogHelper.Warn(ex.ToString());
+ else
+ LogHelper.Error(context.Exception.ToString());
+
+
+ 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);
+
+ BuildLog(receiveTime, receiveName, arguments, true, messageId);
+
+ return Task.CompletedTask;
+ }
+
+
+ private void BuildLog(string receiveTime, string receiveName, string arguments, bool isFromExecptionFliter,
+ string messageId)
+ {
+ var parsedDate = DateTime.ParseExact(receiveTime, "yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
+ var useTime = DateTime.Now - parsedDate;
+
+ var log = $@"
+|-消息编号:{messageId}
+|-消费者名:{receiveName}
+|-跳过执行:{(isFromExecptionFliter ? "是" : "否")}
+|-执行时间:{receiveTime}
+|-消费耗时:{useTime.Milliseconds}毫秒
+|-请求参数:{arguments}";
+
+ if (useTime.Minutes > 20)
+ {
+ LogHelper.Error(log);
+ }
+ else
+ {
+ //LogHelper.Info(log);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs
index 4f402731..28b38520 100644
--- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs
+++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs
@@ -1,5 +1,6 @@
using DotNetCore.CAP;
using SJZY.Expand.ABP.Core.Logger;
+using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
@@ -34,8 +35,6 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
return;
}
- @event.Visited.Add(@event.OrderId);
-
// 不同子系统需要做内容映射
if (@event.UpSubSystemId != 0 && @event.UpSubSystemId != @event.SubSystemId)
{
@@ -75,13 +74,11 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderId);
foreach (var linkedOrder in linkedOrders)
{
- var nextEvent = new TrackDeleteEvent
- {
- OrderId = linkedOrder.OrderId,
- TrackCodes = @event.TrackCodes,
- SubSystemId = linkedOrder.SubSystemId,
- UpSubSystemId = @event.SubSystemId
- };
+ var nextEvent = @event.DeepCopy();
+ nextEvent.Visited.Add(@event.OrderId);
+ nextEvent.TrackCodes = @event.TrackCodes;
+ nextEvent.SubSystemId = linkedOrder.SubSystemId;
+ nextEvent.UpSubSystemId = @event.SubSystemId;
await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, nextEvent);
}
diff --git a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs
index a4336631..58ddb13a 100644
--- a/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs
+++ b/src/SJZY.Track.Application/EventHandlers/TrackPushEventHandler.cs
@@ -51,6 +51,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
RequestId = res.RequestId,
Message = res.Msg,
OptionType = @event.OptionType.ToString(),
+ OrderId = @event.OrderId,
TrackStatus = @event.TrackStatus,
TrackCode = @event.TrackCode,
TrackContent = @event.TrackContent,
diff --git a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs
index 9d0e410d..be24fbf0 100644
--- a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs
+++ b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs
@@ -95,6 +95,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
TrackUpsertEvent @event)
{
var trackUpsertEvent = @event.DeepCopy();
+ trackUpsertEvent.OriginTrackData = JsonConvert.SerializeObject(trackToken);
var paramConfig = paramWithContentConfig.ParamConfig;
var contentConfigs = paramWithContentConfig.ContentConfigs;
TrackPullContentConfigDto? matchedContentConfig = null;
@@ -123,6 +124,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
var trackContent = trackToken[paramConfig.TrackContentName]?.Value();
if (!trackContent.IsNullOrWhiteSpace())
{
+ trackUpsertEvent.OriginTrackContent = trackContent;
Debug.Assert(trackContent != null, nameof(trackContent) + " != null");
matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackContentValue == trackContent);
diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs
index 6de64141..e51481e5 100644
--- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs
+++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs
@@ -1,8 +1,7 @@
-using System.Diagnostics;
-using DotNetCore.CAP;
+using DotNetCore.CAP;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
-using SJZY.Track.Application.Contract.Dtos.ProvideServices;
+using SJZY.Track.Application.Contract.Dtos.TrackPush;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
@@ -42,8 +41,6 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
return;
}
- @event.Visited.Add(@event.OrderId);
-
// 不同子系统需要做内容映射
if (@event.UpSubSystemId != 0 && @event.UpSubSystemId != @event.SubSystemId)
{
@@ -61,10 +58,12 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
}
var track = await _trackDetailsRepository.GetFirstOrDefaultAsync(@event.OrderId, @event.TrackCode);
+ if (track == null && !@event.IsAdd) return;
+ if (track != null && @event.IsAdd) return;
// step1、upsert es轨迹
- await UpsertTrackAsync(track, @event);
- Debug.Assert(track != null, nameof(track) + " != null");
+ track = await UpsertTrackAsync(track, @event);
+ if (track == null) return; // 模板没配该轨迹代码,无法入库
// step2、触发轨迹推送事件(异步)
await HandleTrackPushAsync(@event, track);
@@ -88,6 +87,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
foreach (var linkedOrder in linkedOrders)
{
var nextEvent = @event.DeepCopy();
+ nextEvent.Visited.Add(@event.OrderId);
nextEvent.OrderId = linkedOrder.OrderId;
nextEvent.OrderType = linkedOrder.OrderType;
nextEvent.OrderNo = linkedOrder.OrderNo;
@@ -104,7 +104,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
///
///
///
- private async Task UpsertTrackAsync(TrackDetailsIndex? track, TrackUpsertEvent @event)
+ private async Task UpsertTrackAsync(TrackDetailsIndex? track, TrackUpsertEvent @event)
{
if (track == default)
{
@@ -114,7 +114,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
if (trackContent == default)
{
// 订单所绑定的模板,没有一条内容可以匹配发生的轨迹
- return;
+ return null;
}
track = new TrackDetailsIndex
@@ -133,9 +133,13 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
TrackTime = @event.TrackTime!.Value,
TrackTimeZone = @event.TrackTimeZone!.Value,
IsCanDelete = trackContent.IsCanDelete,
+ OriginTrackContent = @event.OriginTrackContent,
+ OriginTrackData = @event.OriginTrackData,
CreateUser = CurrentUserRequest.CurrentUser.Name,
CreateTime = DateTime.Now
};
+
+ track.ZeroTrackTime = track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
}
else
{
@@ -147,6 +151,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
}
await _trackDetailsRepository.UpsertAsync(track);
+
+ return track;
}
///
@@ -163,7 +169,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
{
config = await _trackPushCacheService.GetPushContentConfigAsync(
@event.SubSystemId, @event.CustomId, track.TrackContentId);
- if (!config.IsCanUpdate) return;
+ if (config == null || !config.IsCanUpdate) return;
}
else
{
@@ -186,6 +192,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
OptionType = optionType,
ServiceProviderCode = config.ServiceProviderCode,
OrderNo = track.OrderNo,
+ OrderId = track.OrderId,
TrackContentId = config.TrackContentId,
TrackStatus = track.TrackStatus,
TrackCode = track.TrackCode,
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs
index de894ef4..9fd4cd56 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs
@@ -102,7 +102,7 @@ public class TrackPullService : ApplicationService
GlobalConst.TrackRefreshSubscribe, JsonConvert.SerializeObject(group.Key));
}
- await RedisHelper.Client.SetExAsync(redisKey, config.PullInterval * 60, 1);
+ await RedisHelper.Client.SetExAsync(redisKey, config.PullInterval * 60, orders.Count);
}
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs
index 2fee5408..85e48c02 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs
@@ -1,4 +1,5 @@
using DotNetCore.CAP;
+using Microsoft.AspNetCore.Authorization;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Application.Contract.Services;
@@ -74,10 +75,13 @@ public class TrackPushService : ApplicationService
await _pushCacheService.GetPushContentConfigAsync(order.SubSystemId, order.CustomId,
track.TrackContentId);
+ if (config == null) continue;
+
var trackPushEvent = new TrackPushEvent
{
ServiceProviderCode = config.ServiceProviderCode,
OrderNo = order.OrderNo,
+ OrderId = order.Id,
TrackContentId = config.TrackContentId,
TrackStatus = track.TrackStatus,
TrackCode = track.TrackCode,
@@ -107,17 +111,23 @@ public class TrackPushService : ApplicationService
/// 定时任务推送预警(》12小时没有推送的)
///
///
+ [AllowAnonymous]
[HttpPost("Track/PushWarnForTask")]
public async Task PushWarnForTaskAsync()
{
- var time = DateTime.Now.Subtract(TimeSpan.FromHours(12));
- var orders = await _orderRepository.GetListAsync(x =>
- !x.IsCompleted && x.QuestionType == 0 && x.LatestPushTime < time);
+ var orders = await _orderRepository.GetPushWarnOrdersAsync();
- orders.ForEach(x => { x.QuestionType = (int)TrackProblemType.Warn; });
+ var time = DateTime.Now.Subtract(TimeSpan.FromHours(12));
+
+ orders.ForEach(x =>
+ {
+ x.QuestionType = x.LatestPushTime == null || x.LatestPushTime < time
+ ? (int)TrackProblemType.Warn
+ : (int)TrackProblemType.None;
+ });
await _orderRepository.UpdateRangeAsync(orders, x => new { x.QuestionType });
- return $"成功将{orders.Select(x => x.OrderNo).JoinAsString(",")}置为预警单";
+ return $"成功将:{orders.Count(x => x.QuestionType == (int)TrackProblemType.Warn)}个订单置为预警";
}
}
\ 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 b45d9313..3e03dc21 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
@@ -86,6 +86,7 @@ public partial class TrackService : ApplicationService, ITrackService
// 新增/更新轨迹
var @event = new TrackUpsertEvent
{
+ IsAdd = input.IsAdd,
TrackCode = input.TrackCode,
TrackPlace = input.TrackPlace,
TrackTime = input.TrackTime,
diff --git a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs
index 46155e2e..fe72985a 100644
--- a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs
+++ b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs
@@ -1,9 +1,10 @@
using System.Linq.Expressions;
using SJZY.Expand.ABP.Core;
-using SJZY.Track.Application.Contract.Dtos.ProvideServices;
+using SJZY.Track.Application.Contract.Dtos.TrackPush;
using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Consts;
+using SJZY.Track.Domain.Dtos.TrackPush;
namespace SJZY.Track.Application.Services.TrackPush;
@@ -28,12 +29,12 @@ public class TrackPushCacheService : ApplicationService, ITrackPushCacheService
}
[NonAction]
- public async Task GetPushContentConfigAsync(int subSystemId, int customId,
+ public async Task GetPushContentConfigAsync(int subSystemId, int customId,
int trackContentId)
{
var data = await GetPushContentConfigsAsync(subSystemId, customId);
- return data.Single(x => x.TrackContentId == trackContentId);
+ return data?.FirstOrDefault(x => x.TrackContentId == trackContentId);
}
[NonAction]
@@ -74,16 +75,13 @@ public class TrackPushCacheService : ApplicationService, ITrackPushCacheService
var trackPushConfigEntity = await _trackPushConfigRepository.GetFirstAsync(exp);
if (trackPushConfigEntity == null) return data;
- var trackPushContentList =
- await _trackPushConfigRepository.GetContentListAsync(x => x.TrackPushConfigId == trackPushConfigEntity.Id);
+ var trackPushContentList = await _trackPushConfigRepository.GetContentListAsync(trackPushConfigEntity.Id);
if (trackPushContentList.Count == 0) return data;
- trackPushContentList = trackPushContentList.OrderBy(x => x.Sort).ToList();
-
data.IsAutoPush = trackPushConfigEntity.IsAutoPush;
data.ContentConfigs =
- ObjectMapper.Map, List>(trackPushContentList);
-
+ ObjectMapper.Map, List>(trackPushContentList);
+ ;
await RedisHelper.Client.SetAsync(
TrackPushContentKey(trackPushConfigEntity.SubSystemId, trackPushConfigEntity.CustomId), data);
diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
index b2b2cd06..88062bb8 100644
--- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
+++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
@@ -6,6 +6,7 @@ using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.InterfaceRelay.Application.Contracts;
using SJZY.Track.Application.Contract;
+using SJZY.Track.Application.EventHandlers;
using SJZY.Track.Application.Localization;
using SJZY.UserCenter.Contracts;
using SJZY.UserCenter.SharedModel;
@@ -90,7 +91,7 @@ namespace SJZY.Track.Application
{
dashboardOptions.PathBase = System.Diagnostics.Debugger.IsAttached
? ""
- : configuration["Swagger:JsonUrlPrefix"];
+ : configuration["Swagger:JsonUrlPrefix"]!;
});
options.FailedThresholdCallback = faileCalback =>
{
@@ -99,15 +100,15 @@ namespace SJZY.Track.Application
LogHelper.Error($@"
|-CAP失败回调事件:
|-处理类型:{(faileCalback.MessageType == DotNetCore.CAP.Messages.MessageType.Subscribe ? "消费消息达到最大重试次数,需要开发人员介入" : "生产消息推送失败")}
- |-头部信息:{faileCalback?.Message?.Headers?.ToJson()}
- |-消息内容:{((JsonElement)faileCalback?.Message?.Value).GetRawText()}");
+ |-头部信息:{faileCalback.Message.Headers.ToJson()}
+ |-消息内容:{((JsonElement?)faileCalback.Message.Value)?.GetRawText()}");
}
catch (Exception ex)
{
LogHelper.Error("【严重】CAP失败回调事件发生未处理异常" + ex);
}
};
- });
+ }).AddSubscribeFilter();
}
public override void PreConfigureServices(ServiceConfigurationContext context)
diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs
index acc0d4de..10832b40 100644
--- a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs
@@ -25,6 +25,11 @@ public interface IOrderRepository : IBasicRepository
///
Task DeleteOrderAsync(int orderId);
+ ///
+ /// 获取推送预警单
+ ///
+ ///
+ Task> GetPushWarnOrdersAsync();
#region 订单关联
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs
index 5581c19d..b3319d35 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs
@@ -52,11 +52,6 @@ public class TrackDetailsIndex : IdBaseIndex
///
public bool IsCompleted { get; set; }
- ///
- /// 原轨迹状态
- ///
- public string? OriginTrackStatus { get; set; }
-
///
/// 原轨迹内容
///
@@ -87,6 +82,11 @@ public class TrackDetailsIndex : IdBaseIndex
///
public float TrackTimeZone { get; set; }
+ ///
+ /// 转化后的轨迹发生时间
+ ///
+ public DateTime ZeroTrackTime { get; set; }
+
/// 是否可删
public bool IsCanDelete { get; set; }
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushConfigRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushConfigRepository.cs
index 80013967..641fb386 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushConfigRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackPushAggregate/ITrackPushConfigRepository.cs
@@ -23,11 +23,16 @@ public interface ITrackPushConfigRepository : IBasicRepository UpdateContentAsync(TrackPushContentConfigEntity updateObj);
- Task> GetContentListAsync(Expression> whereExpression);
+ Task> GetContentListAsync(
+ Expression> whereExpression);
+
+ Task> GetContentListAsync(int configId);
Task UpdateContentRangeAsync(List updateObjs);
- Task ContentMaxAsync(Expression> columns, Expression> whereExpression);
+ Task ContentMaxAsync(Expression> columns,
+ Expression> whereExpression);
- Task UpdateContentAsync(Expression> columns, Expression> whereExpression);
+ Task UpdateContentAsync(Expression> columns,
+ Expression> whereExpression);
}
\ No newline at end of file
diff --git a/src/SJZY.Track.Domain/Dtos/TrackPush/TrackPushContentConfigVO.cs b/src/SJZY.Track.Domain/Dtos/TrackPush/TrackPushContentConfigVO.cs
new file mode 100644
index 00000000..1f67fb8d
--- /dev/null
+++ b/src/SJZY.Track.Domain/Dtos/TrackPush/TrackPushContentConfigVO.cs
@@ -0,0 +1,59 @@
+namespace SJZY.Track.Domain.Dtos.TrackPush;
+
+public class TrackPushContentConfigVO
+{
+ ///
+ /// 是否自动推送
+ ///
+ public bool IsAutoPush { get; set; }
+
+ ///
+ /// 是否支持更新
+ ///
+ public bool IsCanUpdate { get; set; }
+
+ ///
+ /// 服务商code
+ ///
+ public string ServiceProviderCode { get; set; } = null!;
+
+ ///
+ /// 扩展字段参数值
+ ///
+ public string? ExpandFieldsValue { get; set; }
+
+ ///
+ /// 推送单号类型(主数据枚举TrackOrderType)
+ ///
+ public int OrderType { get; set; }
+
+ ///
+ /// 轨迹代码参数值
+ ///
+ public string? TrackContentCodeValue { get; set; }
+
+ ///
+ /// 轨迹内容id
+ ///
+ public int TrackContentId { get; set; }
+
+ ///
+ /// 轨迹内容参数值
+ ///
+ public string? TrackContentValue { get; set; }
+
+ ///
+ /// 轨迹内容英文参数值
+ ///
+ public string? TrackEnContentValue { get; set; }
+
+ ///
+ /// 轨迹状态参数值
+ ///
+ public string? TrackStatusValue { get; set; }
+
+ ///
+ /// 轨迹时区GMT
+ ///
+ public double? TrackTimeZone { get; set; }
+}
\ No newline at end of file
diff --git a/src/SJZY.Track.Repository/Queries/TrackOrderQueries.cs b/src/SJZY.Track.Repository/Queries/TrackOrderQueries.cs
index 8d9d2504..841a3555 100644
--- a/src/SJZY.Track.Repository/Queries/TrackOrderQueries.cs
+++ b/src/SJZY.Track.Repository/Queries/TrackOrderQueries.cs
@@ -1,6 +1,7 @@
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate;
using SJZY.Track.Domain.Dtos.Order;
+using SJZY.Track.Domain.Enums;
using SJZY.Track.Domain.Queries;
using SJZY.Track.Domain.VEntities;
using SJZY.Track.Repository.VData.Entitys;
@@ -38,6 +39,7 @@ public class TrackOrderQueries : ISugarRepository, ITrackOrderQueries,
.WhereIF(input.CustomerId > 0, (a, b, c) => a.CustomId == input.CustomerId)
.WhereIF(input.TrackOrderType > 0, (a, b, c) => a.OrderType == input.TrackOrderType)
.WhereIF(input.TabType > 0, (a, b, c) => a.QuestionType == input.TabType)
+ .WhereIF(input.TabType == (int)TrackProblemType.Warn, (a, b, c) => !a.IsCompleted)
.OrderByDescending((a, b, c) => a.CreateTime)
.Select((a, b, c) => new TrackOrderVO
{
diff --git a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs
index 26a8ed2b..3d18de17 100644
--- a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs
@@ -1,6 +1,8 @@
using SJZY.Track.Domain;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
+using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Dtos.Order;
+using SJZY.Track.Domain.Enums;
namespace SJZY.Track.Repository.Repositories;
@@ -53,6 +55,22 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
tran.Complete();
}
+ public async Task> GetPushWarnOrdersAsync()
+ {
+ var errorType = (int)TrackProblemType.Error;
+
+ return await Context.Queryable()
+ .LeftJoin((a, b) => a.SubSystemId == b.SubSystemId && a.CustomId == b.CustomId)
+ .Where((a, b) => !b.IsCompleted && b.QuestionType != errorType)
+ .Select((a, b) => new OrderEntity
+ {
+ Id = b.Id,
+ QuestionType = b.QuestionType,
+ LatestPushTime = b.LatestPushTime
+ })
+ .ToListAsync();
+ }
+
#region 订单关联
public async Task> GetLinkedOrdersAsync(int orderId)
diff --git a/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs
index e58b1020..74bfc0d3 100644
--- a/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/TrackPushConfigRepository.cs
@@ -1,14 +1,13 @@
-using SJZY.Expand.ABP.Core.PublicMethords;
+using System.Linq.Expressions;
+using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackPullAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
-using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate;
using SJZY.Track.Domain.Dtos.Common;
using SJZY.Track.Domain.Dtos.TrackPush;
using SJZY.Track.Domain.Enums;
using SJZY.Track.Domain.VEntities;
using SJZY.Track.Repository.VData.Entitys;
-using System.Linq.Expressions;
namespace SJZY.Track.Repository.Repositories;
@@ -19,11 +18,14 @@ public class TrackPushConfigRepository : BasicRepository,
{
return await AsQueryable()
.LeftJoin((trackPush, system) => trackPush.SubSystemId == system.Id && !system.IsDeleted)
- .LeftJoin((trackPush, system, externalSubject) => trackPush.CustomId == externalSubject.Id && !externalSubject.IsDeleted)
+ .LeftJoin((trackPush, system, externalSubject) =>
+ trackPush.CustomId == externalSubject.Id && !externalSubject.IsDeleted)
.Filter(null, true)
.Where(trackPush => !trackPush.IsDeleted)
.WhereIF(input.SubSystemId.HasValue, trackPush => trackPush.SubSystemId == input.SubSystemId)
- .WhereIF(!input.Keywords.IsNullOrWhiteSpace(), (trackPush, system, externalSubject) => externalSubject.Abbreviation.Contains(input.Keywords!) || externalSubject.Name.Contains(input.Keywords!))
+ .WhereIF(!input.Keywords.IsNullOrWhiteSpace(),
+ (trackPush, system, externalSubject) => externalSubject.Abbreviation.Contains(input.Keywords!) ||
+ externalSubject.Name.Contains(input.Keywords!))
.OrderByDescending(trackPush => trackPush.CreateTime)
.Select((trackPush, system, externalSubject) => new GetTrackPushConfigPageOutputVO
{
@@ -36,11 +38,14 @@ public class TrackPushConfigRepository : BasicRepository,
.ToPagedListAsync(input.PageIndex, input.PageSize);
}
- public async Task> GetContentPageAsync(GetTrackPushContentPageInputVO input)
+ public async Task> GetContentPageAsync(
+ GetTrackPushContentPageInputVO input)
{
return await Context.Queryable()
.InnerJoin((pushContent, trackContent) => pushContent.TrackContentId == trackContent.Id)
- .LeftJoin((pushContent, trackContent, enumValue) => enumValue.Property == EnumPropertyEnums.单号类型.GetDescription() && pushContent.OrderNoType == enumValue.Enumkey && !enumValue.IsDeleted)
+ .LeftJoin((pushContent, trackContent, enumValue) =>
+ enumValue.Property == EnumPropertyEnums.单号类型.GetDescription() &&
+ pushContent.OrderNoType == enumValue.Enumkey && !enumValue.IsDeleted)
.Where(pushContent => pushContent.TrackPushConfigId == input.TrackPushConfigId)
.OrderBy(pushContent => pushContent.Sort)
.Select((pushContent, trackContent, enumValue) => new GetTrackPushContentPageOutputVO
@@ -56,9 +61,12 @@ public class TrackPushConfigRepository : BasicRepository,
{
return await AsQueryable()
.LeftJoin((trackPush, system) => trackPush.SubSystemId == system.Id && !system.IsDeleted)
- .LeftJoin((trackPush, system, externalSubject) => trackPush.CustomId == externalSubject.Id && !externalSubject.IsDeleted)
- .LeftJoin((trackPush, system, externalSubject, service) => trackPush.ServiceProviderId == service.Id && !service.IsDeleted)
- .InnerJoin((trackPush, system, externalSubject, service, paramsConfig) => trackPush.Id == paramsConfig.PullOrPushConfigId && paramsConfig.IsPush && !paramsConfig.IsDeleted)
+ .LeftJoin((trackPush, system, externalSubject) =>
+ trackPush.CustomId == externalSubject.Id && !externalSubject.IsDeleted)
+ .LeftJoin((trackPush, system, externalSubject, service) =>
+ trackPush.ServiceProviderId == service.Id && !service.IsDeleted)
+ .InnerJoin((trackPush, system, externalSubject, service, paramsConfig) =>
+ trackPush.Id == paramsConfig.PullOrPushConfigId && paramsConfig.IsPush && !paramsConfig.IsDeleted)
.Filter(null, true)
.Where(trackPush => trackPush.Id == id && !trackPush.IsDeleted)
.Select((trackPush, system, externalSubject, service, paramsConfig) => new GetTrackPushConfigDetailOutputVO
@@ -112,7 +120,32 @@ public class TrackPushConfigRepository : BasicRepository,
return await Context.Updateable(updateObj).ExecuteCommandHasChangeAsync();
}
- public async Task> GetContentListAsync(Expression> whereExpression)
+ public async Task> GetContentListAsync(int configId)
+ {
+ return await Context.Queryable()
+ .LeftJoin((a, b) => a.Id == b.TrackPushConfigId)
+ .LeftJoin((a, b, c) => a.ServiceProviderId == c.Id)
+ .Where(a => a.Id == configId)
+ .OrderBy((a, b) => b.Sort)
+ .Select((a, b, c) => new TrackPushContentConfigVO
+ {
+ IsAutoPush = a.IsAutoPush,
+ IsCanUpdate = a.IsCanUpdate,
+ ServiceProviderCode = c.Code,
+ ExpandFieldsValue = b.ExpandFieldsValue,
+ OrderType = b.OrderNoType,
+ TrackContentCodeValue = b.TrackContentCodeValue,
+ TrackContentId = b.TrackContentId,
+ TrackContentValue = b.TrackContentValue,
+ TrackEnContentValue = b.TrackEnContentValue,
+ TrackStatusValue = b.TrackStatusValue,
+ TrackTimeZone = b.TrackTimeZone
+ })
+ .ToListAsync();
+ }
+
+ public async Task> GetContentListAsync(
+ Expression> whereExpression)
{
return await Context.Queryable().Where(whereExpression).ToListAsync();
}
@@ -122,13 +155,16 @@ public class TrackPushConfigRepository : BasicRepository,
return await Context.Updateable(updateObjs).ExecuteCommandHasChangeAsync();
}
- public async Task ContentMaxAsync(Expression> columns, Expression> whereExpression)
+ public async Task ContentMaxAsync(Expression> columns,
+ Expression> whereExpression)
{
return await Context.Queryable().Where(whereExpression).MaxAsync(columns);
}
- public async Task UpdateContentAsync(Expression> columns, Expression> whereExpression)
+ public async Task UpdateContentAsync(Expression> columns,
+ Expression> whereExpression)
{
- return await Context.Updateable().SetColumns(columns).Where(whereExpression).ExecuteCommandHasChangeAsync();
+ return await Context.Updateable().SetColumns(columns).Where(whereExpression)
+ .ExecuteCommandHasChangeAsync();
}
}
\ No newline at end of file
diff --git a/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs
index c1bb968f..b537adb1 100644
--- a/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/TrackPushRecordsRepository.cs
@@ -3,6 +3,7 @@ using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ElasticSearch.Services;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
+using SJZY.Track.Domain.Consts;
namespace SJZY.Track.Repository.Repositories;
@@ -30,6 +31,7 @@ public class TrackPushRecordsRepository : ElasticSearchContextAbstract> GetTrackPushRecordsAsync(int orderId)
{
var data = await Context.SearchAsync(x => x
+ .Index(GlobalConst.TrackPushRecordsIndex)
.Query(q =>
q.Term(t => t.OrderId, orderId)
)