Merge branch 'S02-轨迹中台第二部分' into dev

This commit is contained in:
李鹏军 2024-03-26 15:20:40 +08:00
commit 82c380b7a9
15 changed files with 110 additions and 16 deletions

View File

@ -22,6 +22,11 @@ public class TrackPushEvent
/// </summary>
public string OrderNo { get; set; } = null!;
/// <summary>
/// 订单类型
/// </summary>
public int OrderType { get; set; }
/// <summary>
/// 轨迹内容id
/// </summary>

View File

@ -48,4 +48,9 @@ public class TrackUpsertEvent : UpsertTrackInput
/// 原轨迹报文
/// </summary>
public string? OriginTrackData { get; set; }
/// <summary>
/// 操作人
/// </summary>
public string? OperationMan { get; set; }
}

View File

@ -32,7 +32,7 @@ public class CAPFilter : SubscribeFilter
throw new BusinessException(_ERROR_CODE, $"检测到重复消费,消费参数:{argumentJsonStr}");
RedisHelper.Client.Set($"CapExcuteFilter:{hash}", 60 * 10,
TimeSpan.FromDays(1).Seconds); // 1天内不允许一模一样的参数重复消费
TimeSpan.FromHours(1).Seconds); // 1h内不允许一模一样的参数重复消费
}
}

View File

@ -44,7 +44,7 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
var isSuccess = res.Code == InterfaceRelayConst.SuccessCode;
// 写推送日志
// 往es 写推送日志
await _trackPushRecordsRepository.AddAsync(new TrackPushRecordIndex
{
IndexName = $"{GlobalConst.TrackPushRecordsIndex}-{DateTime.Now:yyyy.MM.dd}",
@ -52,6 +52,8 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
Message = res.Msg,
OptionType = @event.OptionType.ToString(),
OrderId = @event.OrderId,
OrderType = @event.OrderType,
OrderNo = @event.OrderNo,
TrackStatus = @event.TrackStatus,
TrackCode = @event.TrackCode,
TrackContent = @event.TrackContent,

View File

@ -8,7 +8,6 @@ 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;
namespace SJZY.Track.Application.EventHandlers;
@ -135,7 +134,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
IsCanDelete = trackContent.IsCanDelete,
OriginTrackContent = @event.OriginTrackContent,
OriginTrackData = @event.OriginTrackData,
CreateUser = CurrentUserRequest.CurrentUser.Name,
CreateUser = @event.OperationMan,
CreateTime = DateTime.Now
};
@ -146,7 +145,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
track.TrackPlace = @event.TrackPlace;
track.TrackTime = @event.TrackTime!.Value;
track.TrackTimeZone = @event.TrackTimeZone!.Value;
track.UpdateUser = CurrentUserRequest.CurrentUser.Name;
track.UpdateUser = @event.OperationMan ?? "系统";
track.UpdateTime = DateTime.Now;
}
@ -192,6 +191,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
OptionType = optionType,
ServiceProviderCode = config.ServiceProviderCode,
OrderNo = track.OrderNo,
OrderType = track.OrderType,
OrderId = track.OrderId,
TrackContentId = config.TrackContentId,
TrackStatus = track.TrackStatus,

View File

@ -86,10 +86,10 @@ public class TrackPullService : ApplicationService
}
var orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId);
var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode;
foreach (var group in orders.GroupBy(x =>
new TrackRefreshAttach(x.ServiceProviderId, x.ServiceProviderCode, x.SubSystemId,
x.OrderType)))
new { x.SubSystemId, x.OrderType }))
{
var data = group.Select(x => new
{
@ -98,10 +98,13 @@ public class TrackPullService : ApplicationService
// 批量获取轨迹
await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(
InterfaceRelayConst.GetTrackInterfaceCode, group.Key.ServiceProviderCode, data,
GlobalConst.TrackRefreshSubscribe, JsonConvert.SerializeObject(group.Key));
InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data,
GlobalConst.TrackRefreshSubscribe,
JsonConvert.SerializeObject(new TrackRefreshAttach(config.ServiceProviderId, serviceProviderCode!,
group.Key.SubSystemId, group.Key.OrderType)));
}
if (config.PullInterval < 60) config.PullInterval = 60;
await RedisHelper.Client.SetExAsync(redisKey, config.PullInterval * 60, orders.Count);
}

View File

@ -5,6 +5,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.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Consts;
using SJZY.Track.Domain.Enums;
using SJZY.UserCenter.HttpApi.Services;
@ -22,16 +23,19 @@ public class TrackPushService : ApplicationService
private readonly IOrderRepository _orderRepository;
private readonly ITrackPushCacheService _pushCacheService;
private readonly ICapPublisher _capPublisher;
private readonly ITrackPushRecordsRepository _trackPushRecordsRepository;
public TrackPushService(ITrackPushCacheService pushCacheService,
ITrackDetailsRepository trackDetailsRepository
, IOrderRepository orderRepository
, ICapPublisher capPublisher)
, ICapPublisher capPublisher
, ITrackPushRecordsRepository trackPushRecordsRepository)
{
_pushCacheService = pushCacheService;
_trackDetailsRepository = trackDetailsRepository;
_orderRepository = orderRepository;
_capPublisher = capPublisher;
_trackPushRecordsRepository = trackPushRecordsRepository;
}
/// <summary>
@ -47,7 +51,7 @@ public class TrackPushService : ApplicationService
var orders = await _orderRepository.GetListAsync(x =>
x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => new
{
x.Id, x.OrderNo, x.SubSystemId, x.CustomId
x.Id, x.OrderNo, x.OrderType, x.SubSystemId, x.CustomId
});
if (orders.Count == 0)
@ -75,10 +79,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,
OrderType = order.OrderType,
OrderId = order.Id,
TrackContentId = config.TrackContentId,
TrackStatus = track.TrackStatus,
@ -113,14 +120,30 @@ public class TrackPushService : ApplicationService
[HttpPost("Track/PushWarnForTask")]
public async Task<string> 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)}个订单置为预警";
}
/// <summary>
/// 获取轨迹推送记录
/// </summary>
/// <returns></returns>
/// <param name="input"></param>
[HttpGet("Track/GetTrackPushRecords")]
public async Task<List<TrackPushRecordIndex>> GetTrackPushRecordsAsync(OrderNoInfo input)
{
return await _trackPushRecordsRepository.GetTrackPushRecordsAsync(input.OrderNo, input.OrderType);
}
}

View File

@ -6,6 +6,7 @@ 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;
namespace SJZY.Track.Application.Services.ProvideServices;
@ -56,6 +57,7 @@ public partial class TrackService : ApplicationService, ITrackService
@event.LatestPushTrackContentId = order.LatestPushTrackContentId;
@event.CustomId = order.CustomId;
@event.IsCompleted = order.IsCompleted;
@event.OperationMan = CurrentUserRequest.CurrentUser.Name;
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event);
return true;
}

View File

@ -25,6 +25,11 @@ public interface IOrderRepository : IBasicRepository<OrderEntity>
/// <returns></returns>
Task DeleteOrderAsync(int orderId);
/// <summary>
/// 获取推送预警单
/// </summary>
/// <returns></returns>
Task<List<OrderEntity>> GetPushWarnOrdersAsync();
#region 订单关联

View File

@ -15,4 +15,6 @@ public interface ITrackPushRecordsRepository
/// <param name="orderId"></param>
/// <returns></returns>
Task<List<TrackPushRecordIndex>> GetTrackPushRecordsAsync(int orderId);
Task<List<TrackPushRecordIndex>> GetTrackPushRecordsAsync(string inputOrderNo, int inputOrderType);
}

View File

@ -17,6 +17,16 @@ public class TrackPushRecordIndex : IdBaseIndex
/// </summary>
public int OrderId { get; set; }
/// <summary>
/// 订单号
/// </summary>
public string OrderNo { get; set; } = null!;
/// <summary>
/// 订单类型(主数据枚举TrackOrderType)
/// </summary>
public int OrderType { get; set; }
/// <summary>
/// 接口通请求Id
/// </summary>

View File

@ -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
{

View File

@ -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,23 @@ public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, I
tran.Complete();
}
public async Task<List<OrderEntity>> GetPushWarnOrdersAsync()
{
var errorType = (int)TrackProblemType.Error;
return await Context.Queryable<TrackPushConfigEntity>()
.LeftJoin<OrderEntity>((a, b) => a.SubSystemId == b.SubSystemId && a.CustomId == b.CustomId)
.Where((a, b) => !b.IsCompleted && b.QuestionType != errorType)
.Where("a.CreateTime < DATE_SUB(now(),INTERVAL 12 hour)") // 过滤掉创建时间不足12小时的
.Select((a, b) => new OrderEntity
{
Id = b.Id,
QuestionType = b.QuestionType,
LatestPushTime = b.LatestPushTime
})
.ToListAsync();
}
#region 订单关联
public async Task<List<LinkedOrderVO>> GetLinkedOrdersAsync(int orderId)

View File

@ -93,10 +93,12 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
var data = await Context.SearchAsync<TrackDetailsIndex>(x => x
.Source(s => s.Includes(fd => fd
.Field(f => f.OrderId)
.Field(f => f.OrderNo)
.Field(f => f.TrackStatus)
.Field(f => f.TrackCode)
.Field(f => f.TrackContent)
.Field(f => f.TrackContentId)
.Field(f => f.TrackPlace)
.Field(f => f.TrackTime)
.Field(f => f.TrackTimeZone)

View File

@ -40,4 +40,18 @@ public class TrackPushRecordsRepository : ElasticSearchContextAbstract<TrackDeta
return data.Documents.ToList();
}
public async Task<List<TrackPushRecordIndex>> GetTrackPushRecordsAsync(string orderNo, int orderType)
{
var data = await Context.SearchAsync<TrackPushRecordIndex>(x => x
.Index(GlobalConst.TrackPushRecordsIndex)
.Query(q =>
q.Term(t => t.OrderNo.Suffix("keyword"), orderNo)
&& q.Term(f => f.OrderType, orderType)
)
.Size(1000)
.Sort(s => s.Field(f => f.CreateTime, SortOrder.Descending)));
return data.Documents.ToList();
}
}