feat: 轨迹拉取定时任务
This commit is contained in:
parent
a431ec7ec7
commit
cb8edf4cbb
@ -139,6 +139,7 @@ public class TrackCenterApiModule : FakeModule
|
||||
public override void ConfigureApplication(ApplicationConfigureContext context)
|
||||
{
|
||||
var app = context.GetWebApplication();
|
||||
var configuration = context.GetConfiguration();
|
||||
app.Use(async (httpContext, next) =>
|
||||
{
|
||||
httpContext.Request.EnableBuffering();
|
||||
@ -158,13 +159,12 @@ public class TrackCenterApiModule : FakeModule
|
||||
|
||||
app.UseCors(DefaultCorsPolicyName);
|
||||
|
||||
// todo: 缺乏配置
|
||||
app.UseHangfireDashboard("/hangfire", new DashboardOptions
|
||||
{
|
||||
DisplayStorageConnectionString = false,
|
||||
IgnoreAntiforgeryToken = true,
|
||||
AppPath = "",
|
||||
PrefixPath = "",
|
||||
AppPath = configuration["ASPNETCORE_PATHBASE"],
|
||||
PrefixPath = configuration["ASPNETCORE_PATHBASE"],
|
||||
DashboardTitle = "轨迹预警任务",
|
||||
Authorization = [new AnonymousHangfireAuthorizationFilter()]
|
||||
});
|
||||
|
||||
@ -21,11 +21,6 @@ public class EditTrackPullPriorityInput
|
||||
/// </summary>
|
||||
public string Customer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public TrackOrderType OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号类型
|
||||
/// </summary>
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
using Hangfire;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TrackCenter.Application.Helpers;
|
||||
using TrackCenter.Application.Options;
|
||||
using TrackCenter.Application.Services.TimerTaskss;
|
||||
|
||||
namespace TrackCenter.Application.HostServices;
|
||||
|
||||
public class TrackTaskComponentHostedService : IHostedService
|
||||
{
|
||||
private readonly IOptionsMonitor<TrackAppOptions> _optionsMonitor;
|
||||
private TrackAppOptions? _oldOptions;
|
||||
private readonly ILogger<TrackTaskComponentHostedService> _logger;
|
||||
|
||||
public TrackTaskComponentHostedService(IOptionsMonitor<TrackAppOptions> optionsMonitor, ILogger<TrackTaskComponentHostedService> logger)
|
||||
{
|
||||
_optionsMonitor = optionsMonitor;
|
||||
_logger = logger;
|
||||
var onChanged = DebounceHelper.WrapMethod(TimeSpan.FromSeconds(1), () => { ReloadConfig(optionsMonitor); });
|
||||
optionsMonitor.OnChange(_ => onChanged.Debounce());
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
ReloadConfig(_optionsMonitor);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void ReloadConfig(IOptionsMonitor<TrackAppOptions> optionsMonitor)
|
||||
{
|
||||
var newVal = optionsMonitor.CurrentValue;
|
||||
_logger.LogInformation("轨迹任务配置,轨迹刷新执行周期{a}min",
|
||||
newVal.TrackPullTaskMinuteInterval
|
||||
);
|
||||
// 轨迹刷新任务
|
||||
if ((_oldOptions?.TrackPullTaskMinuteInterval ?? 0) != newVal.TrackPullTaskMinuteInterval)
|
||||
{
|
||||
var q = GlobalConst.TaskQueueLevelDict[_optionsMonitor.CurrentValue.TrackPullTaskLevel];
|
||||
RecurringJob.AddOrUpdate<TrackPullTask>("Execute_TrackPullTask",
|
||||
q,
|
||||
x => x.RefreshForTaskAsync(),
|
||||
$"*/{newVal.TrackPullTaskMinuteInterval} * * * *");
|
||||
}
|
||||
|
||||
_oldOptions = newVal;
|
||||
}
|
||||
}
|
||||
@ -26,4 +26,9 @@ public class TrackAppOptions
|
||||
/// 轨迹拉取任务间隔(分钟)
|
||||
/// </summary>
|
||||
public int TrackPullTaskMinuteInterval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 拉取优先级
|
||||
/// </summary>
|
||||
public int TrackPullTaskLevel { get; set; }
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ using SqlSugar;
|
||||
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||
using TrackCenter.Domain.Aggregates.TrackContentAggregate;
|
||||
using TrackCenter.Domain.Aggregates.TrackFlagAggregate;
|
||||
using TrackCenter.Domain.Aggregates.TrackPullAggregate;
|
||||
using TrackCenter.Domain.Aggregates.TrackStatusAggregate;
|
||||
using TrackCenter.Domain.Dtos.Order;
|
||||
using TrackCenter.Domain.Dtos.TrackContents;
|
||||
@ -19,7 +18,8 @@ namespace TrackCenter.Application.Queries;
|
||||
public class ProvideQueries : SqlSugarRootlessRepository<TrackCenterDbContext>, ITransientDependency
|
||||
{
|
||||
public ISqlSugarClient Context => GetDbContextAsync().Result;
|
||||
public async Task<List<string>> MapTrackCodesAsync(string upAppKey, string appKey, params string[] trackCodes)
|
||||
|
||||
public async Task<List<string>> MapTrackCodesAsync(string upAppKey, string appKey, params string[] trackCodes)
|
||||
{
|
||||
// 根据上游code得到下游code
|
||||
return await Context.Queryable<TrackContentMapEntity>()
|
||||
@ -29,7 +29,8 @@ public class ProvideQueries : SqlSugarRootlessRepository<TrackCenterDbContext>,
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<List<TrackCodeMapVO>> GetTrackCodeMapsAsync(string upAppKey, string appKey, params string[] trackCodes)
|
||||
public async Task<List<TrackCodeMapVO>> GetTrackCodeMapsAsync(string upAppKey, string appKey,
|
||||
params string[] trackCodes)
|
||||
{
|
||||
// 根据上游code得到下游code
|
||||
return await Context.Queryable<TrackContentMapEntity>()
|
||||
@ -66,22 +67,23 @@ public class ProvideQueries : SqlSugarRootlessRepository<TrackCenterDbContext>,
|
||||
}
|
||||
|
||||
public async Task<List<OrderWithServiceProviderVO>> FindOrderWithServiceProviderAsync(
|
||||
string serviceProviderCode,
|
||||
string appKey,
|
||||
TrackPullConfigVo config,
|
||||
int pageIndex, int pageSize = 1000)
|
||||
{
|
||||
return await Context.Queryable<OrderEntity>()
|
||||
.InnerJoin<OrderPullStatusEntity>((a, b) => a.Id == b.OrderId)
|
||||
.Where((a, b) => b.ServiceProviderCode == serviceProviderCode
|
||||
&& a.AppKey == appKey
|
||||
.Where((a, b) => b.ServiceProviderCode == config.ServiceProviderCode
|
||||
&& a.AppKey == config.AppKey
|
||||
&& !a.IsCompleted
|
||||
&& b.StartTime <= DateTime.Now
|
||||
&& b.EndTime >= DateTime.Now
|
||||
)
|
||||
.WhereIF(config.Customer != GlobalConst.All, a => a.Customer == config.Customer)
|
||||
.Select((a, b) => new OrderWithServiceProviderVO
|
||||
{
|
||||
//优先使用第三方的订单号,为空时才使用主单号
|
||||
OrderNo = string.IsNullOrWhiteSpace(b.OrderNo) ? a.OrderNo : b.OrderNo,
|
||||
OrderNo = config.OrderNoType == TrackOrderNoType.客户单号 ? a.OrderNo :
|
||||
config.OrderNoType == TrackOrderNoType.跟踪单号 ? a.TrackNo : a.ThirdPartyOrderNumber,
|
||||
OrderType = a.OrderType,
|
||||
AppKey = a.AppKey,
|
||||
ServiceProviderCode = b.ServiceProviderCode
|
||||
|
||||
@ -36,18 +36,20 @@ public class TrackPullTask : ApplicationServiceBase, ISingletonDependency
|
||||
using var serviceScope = _serviceScopeFactory.CreateScope();
|
||||
|
||||
var trackPullConfigRepository = serviceScope.ServiceProvider.GetRequiredService<ITrackPullConfigRepository>();
|
||||
// var configs = await trackPullConfigRepository.AsQueryable()
|
||||
// .LeftJoin<TrackPullPriorityEntity>((a, b) => a.Id == b.TrackPullConfigId)
|
||||
// .Where()
|
||||
|
||||
|
||||
var configs = await trackPullConfigRepository.GetListAsync(x => true, x => new TrackPullConfigVo
|
||||
{
|
||||
// todo:去读priority表,按照客户、订单类型、优先级拉
|
||||
PullInterval = 60,
|
||||
ServiceProviderCode = x.ServiceProviderCode,
|
||||
AppKey = x.AppKey
|
||||
});
|
||||
var configs = await trackPullConfigRepository.AsQueryable()
|
||||
.LeftJoin<TrackPullPriorityEntity>((a, b) => a.Id == b.TrackPullConfigId)
|
||||
.Select((a, b) => new TrackPullConfigVo
|
||||
{
|
||||
// tips:去读priority表,根据客户看用哪个订单号类型拉
|
||||
PullInterval = b.PullInterval,
|
||||
Customer = b.Customer,
|
||||
Priority = b.Priority,
|
||||
OrderNoType = b.OrderNoType,
|
||||
ServiceProviderCode = a.ServiceProviderCode,
|
||||
AppKey = a.AppKey
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var config in configs)
|
||||
{
|
||||
@ -58,11 +60,10 @@ public class TrackPullTask : ApplicationServiceBase, ISingletonDependency
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task RefreshForConfigAsync(IServiceScope serviceScope, TrackPullConfigVo config)
|
||||
{
|
||||
var trackPullCacheService = LazyServiceProvider.GetRequiredService<TrackPullCacheService>();
|
||||
var redisKey = trackPullCacheService.TrackPullKey(config.AppKey, config.ServiceProviderCode);
|
||||
var redisKey = trackPullCacheService.TrackPullKey(config);
|
||||
if (await RedisHelper.Client.ExistsAsync(redisKey))
|
||||
{
|
||||
return;
|
||||
@ -97,7 +98,7 @@ public class TrackPullTask : ApplicationServiceBase, ISingletonDependency
|
||||
{
|
||||
var page = 1;
|
||||
var orders =
|
||||
await provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderCode, config.AppKey, page);
|
||||
await provideQueries.FindOrderWithServiceProviderAsync(config, page);
|
||||
while (orders.Any())
|
||||
{
|
||||
var serviceProviderCode = orders.First().ServiceProviderCode;
|
||||
@ -120,8 +121,7 @@ public class TrackPullTask : ApplicationServiceBase, ISingletonDependency
|
||||
}
|
||||
}
|
||||
|
||||
orders = await provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderCode,
|
||||
config.AppKey, ++page);
|
||||
orders = await provideQueries.FindOrderWithServiceProviderAsync(config, ++page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,8 +16,8 @@ public class TrackPullCacheService : ITransientDependency
|
||||
_objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
public string TrackPullKey(string appKey, string serviceProviderCode) =>
|
||||
$"{GlobalConst.TrackPullKeyPrefix}:{appKey}:{serviceProviderCode}";
|
||||
public string TrackPullKey(TrackPullConfigVo config) =>
|
||||
$"{GlobalConst.TrackPullKeyPrefix}:{config.AppKey}:{config.ServiceProviderCode}:{config.Customer}";
|
||||
|
||||
public async Task<TrackPullParamsWithContentDto?> GetPullParamsWithContentAsync(string appKey,
|
||||
string serviceProviderCode)
|
||||
|
||||
@ -107,7 +107,6 @@ public class TrackPullService(
|
||||
{
|
||||
TrackPullConfigId = id,
|
||||
Customer = GlobalConst.All,
|
||||
OrderType = TrackOrderType.小包,
|
||||
OrderNoType = TrackOrderNoType.跟踪单号,
|
||||
Priority = 999,
|
||||
PullInterval = 12 * 60 // 12小时
|
||||
@ -282,7 +281,6 @@ public class TrackPullService(
|
||||
Expression<Func<TrackPullPriorityEntity, bool>> isPriorityAnyExp = x =>
|
||||
x.TrackPullConfigId == input.TrackPullConfigId &&
|
||||
x.Customer == input.Customer &&
|
||||
x.OrderType == input.OrderType &&
|
||||
x.OrderNoType == input.OrderNoType;
|
||||
|
||||
if (input.Options == OptionTypeNoNull.修改)
|
||||
|
||||
@ -68,10 +68,7 @@ public class TrackCenterApplicationModule : FakeModule
|
||||
options.FallbackWindowLookbackSeconds =
|
||||
configuration.GetValue<int>("CAP:FallbackWindowLookbackSeconds");
|
||||
|
||||
options.UseDashboard(dashboardOptions =>
|
||||
{
|
||||
dashboardOptions.PathBase = "";
|
||||
});
|
||||
options.UseDashboard(dashboardOptions => { dashboardOptions.PathBase = ""; });
|
||||
options.FailedThresholdCallback = faileCalback =>
|
||||
{
|
||||
try
|
||||
@ -102,10 +99,10 @@ public class TrackCenterApplicationModule : FakeModule
|
||||
|
||||
#endregion
|
||||
|
||||
var options = configuration.GetSection("Redis").Get<ConnectionStringBuilder>();
|
||||
if (options == null)
|
||||
var redisOptions = configuration.GetSection("Redis").Get<ConnectionStringBuilder>();
|
||||
if (redisOptions == null)
|
||||
throw new FakeException("未找到Redis相关配置,请检查配置文件中是否包含名为Redis的节点");
|
||||
RedisHelper.Init(options, showLogInfo: Debugger.IsAttached);
|
||||
RedisHelper.Init(redisOptions, showLogInfo: Debugger.IsAttached);
|
||||
|
||||
context.Services.AddHostedService<RabbitClient>();
|
||||
context.Services.Configure<RabbitOptions>(options =>
|
||||
@ -194,17 +191,20 @@ public class TrackCenterApplicationModule : FakeModule
|
||||
context.Services.AddHangfireServer(o =>
|
||||
{
|
||||
// 索引越小优先级越高
|
||||
o.Queues = new[] { GlobalConst.WarningJobQueueLevel0, GlobalConst.WarningJobQueueLevel1, GlobalConst.WarningJobQueueLevel2, "default" };
|
||||
o.Queues =
|
||||
[
|
||||
GlobalConst.WarningJobQueueLevel0,
|
||||
GlobalConst.WarningJobQueueLevel1,
|
||||
GlobalConst.WarningJobQueueLevel2,
|
||||
"default"
|
||||
];
|
||||
o.ServerName = Dns.GetHostName();
|
||||
o.ShutdownTimeout = TimeSpan.FromSeconds(10);
|
||||
o.WorkerCount = 1;
|
||||
});
|
||||
|
||||
// 轨迹拉取定时任务
|
||||
RecurringJob.AddOrUpdate<TrackPullTask>("Execute_TrackPullTask",
|
||||
x => x.RefreshForTaskAsync(),
|
||||
$"*/{configuration["TrackApp:TrackPullTaskMinuteInterval"]} * * * *");
|
||||
|
||||
// 注册轨迹业务定时任务服务
|
||||
context.Services.AddHostedService<TrackTaskComponentHostedService>();
|
||||
|
||||
context.Services.AddHttpClient("itfx", client =>
|
||||
{
|
||||
|
||||
@ -20,12 +20,6 @@ public class TrackPullPriorityEntity: FullAuditedEntity<int, int>
|
||||
[SugarColumn(ColumnName = "Customer")]
|
||||
public string Customer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "OrderType")]
|
||||
public TrackOrderType OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号类型
|
||||
/// </summary>
|
||||
|
||||
@ -16,16 +16,6 @@ public class GetTrackPullPriorityDetailOutputVO
|
||||
/// </summary>
|
||||
public string Customer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public TrackOrderType OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public string OrderTypeName => OrderType.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// 订单号类型
|
||||
/// </summary>
|
||||
|
||||
@ -11,16 +11,6 @@ public class GetTrackPullPriorityPageOutputVO
|
||||
/// </summary>
|
||||
public string Customer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public TrackOrderType OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型
|
||||
/// </summary>
|
||||
public string OrderTypeName => OrderType.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// 订单号类型
|
||||
/// </summary>
|
||||
|
||||
@ -21,4 +21,11 @@ public class TrackPullConfigVo
|
||||
/// 客户
|
||||
/// </summary>
|
||||
public string Customer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
|
||||
public TrackOrderNoType OrderNoType { get; set; }
|
||||
}
|
||||
|
||||
@ -133,7 +133,6 @@ public class TrackPullConfigRepository : BasicRepository<TrackPullConfigEntity>,
|
||||
{
|
||||
Id = x.Id,
|
||||
Customer = x.Customer,
|
||||
OrderType = x.OrderType,
|
||||
OrderNoType = x.OrderNoType,
|
||||
Priority = x.Priority,
|
||||
PullInterval = x.PullInterval,
|
||||
@ -154,7 +153,6 @@ public class TrackPullConfigRepository : BasicRepository<TrackPullConfigEntity>,
|
||||
Id = x.Id,
|
||||
TrackPullConfigId = x.TrackPullConfigId,
|
||||
Customer = x.Customer,
|
||||
OrderType = x.OrderType,
|
||||
OrderNoType = x.OrderNoType,
|
||||
Priority = x.Priority,
|
||||
PullInterval = x.PullInterval
|
||||
|
||||
Loading…
Reference in New Issue
Block a user