diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshAttach.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshAttach.cs index 651e5000..38d01ed5 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshAttach.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackRefreshAttach.cs @@ -2,18 +2,20 @@ namespace SJZY.Track.Application.Contract.Dtos.TrackPull; public class TrackRefreshAttach { - public TrackRefreshAttach(int serviceProviderId, string serviceProviderName, int subSystemId, int orderType) + public TrackRefreshAttach(string serviceProviderCode, string serviceProviderName, string subSystemCode, + int subSystemId, int orderType) { - ServiceProviderId = serviceProviderId; + ServiceProviderCode = serviceProviderCode; ServiceProviderName = serviceProviderName; + SubSystemCode = subSystemCode; SubSystemId = subSystemId; OrderType = orderType; } /// - /// 服务商id + /// 服务商code /// - public int ServiceProviderId { get; set; } + public string ServiceProviderCode { get; set; } /// /// 服务商name @@ -25,6 +27,11 @@ public class TrackRefreshAttach /// public int OrderType { get; set; } + /// + /// 子系统code + /// + public string SubSystemCode { get; set; } + /// /// 子系统id /// diff --git a/src/SJZY.Track.Application.Contract/Services/ITrackPullCacheService.cs b/src/SJZY.Track.Application.Contract/Services/ITrackPullCacheService.cs index d74dea96..da3fb64b 100644 --- a/src/SJZY.Track.Application.Contract/Services/ITrackPullCacheService.cs +++ b/src/SJZY.Track.Application.Contract/Services/ITrackPullCacheService.cs @@ -4,31 +4,22 @@ namespace SJZY.Track.Application.Contract.Services; public interface ITrackPullCacheService { - string TrackPullKey(int subSystemId, int serviceProviderId); - string TrackPullContentKey(int subSystemId, int serviceProviderId); - - /// - /// 获取所有拉取配置 - /// - /// - Task> GetAllPullConfigsAsync(); + string TrackPullKey(string subSystemCode, string serviceProviderCode); + string TrackPullContentKey(string subSystemCode, string serviceProviderCode); /// /// 获取服务商拉取配置 /// - /// 子系统id - /// 服务商id + /// 子系统code + /// 服务商code /// Task - GetPullParamsWithContentAsync(int subSystemId, int serviceProviderId); + GetPullParamsWithContentAsync(string subSystemCode, string serviceProviderCode); /// /// 设置拉取配置缓存 /// /// - /// 子系统id - /// 服务商id /// - Task SetPullConfigAsync(int? id = null, int? subSystemId = null, - int? serviceProviderId = null); + Task SetPullConfigAsync(int id); } diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushCompletedEventHandler.cs b/src/SJZY.Track.Application/Rabbit/TrackPushCompletedEventHandler.cs similarity index 75% rename from src/SJZY.Track.Application/CAP/EventHandlers/TrackPushCompletedEventHandler.cs rename to src/SJZY.Track.Application/Rabbit/TrackPushCompletedEventHandler.cs index e10d40fd..348d7a4b 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackPushCompletedEventHandler.cs +++ b/src/SJZY.Track.Application/Rabbit/TrackPushCompletedEventHandler.cs @@ -1,5 +1,9 @@ -using DotNetCore.CAP; +using System.Text; +using BSI.Stack.Rabbit; +using BSI.Stack.Rabbit.Handler; using Newtonsoft.Json; +using RabbitMQ.Client.Events; +using SJZY.Expand.ABP.Core.Logger; using SJZY.InterfaceRelay.Application.Contracts; using SJZY.Track.Application.Contract.Dtos.TrackPush; using SJZY.Track.Application.Helpers; @@ -8,23 +12,36 @@ using SJZY.Track.Domain.Aggregates.TrackPushAggregate; using SJZY.Track.Domain.Enums; using Volo.Abp.DependencyInjection; -namespace SJZY.Track.Application.CAP.EventHandlers; +namespace SJZY.Track.Application.Rabbit; -public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscribe +public class TrackPushCompletedEventHandler : ITransientDependency, IRabbitHandler { private readonly IOrderRepository _orderRepository; private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository; - public TrackPushCompletedEventHandler(ITrackPushRecordEsRepository trackPushRecordEsRepository, - IOrderRepository orderRepository) + public TrackPushCompletedEventHandler(IOrderRepository orderRepository, + ITrackPushRecordEsRepository trackPushRecordEsRepository) { - _trackPushRecordEsRepository = trackPushRecordEsRepository; _orderRepository = orderRepository; + _trackPushRecordEsRepository = trackPushRecordEsRepository; } - [CapSubscribe(GlobalConst.TrackPushCompletedSubscribe, Group = GlobalConst.TrackPushSubscribe)] - public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event) + public bool Enable(ConsumeOptions options) { + return options.Queue == GlobalConst.TrackPushCompletedSubscribe; + } + + public async Task Handle(IServiceProvider sp, BasicDeliverEventArgs args, ConsumeOptions options) + { + var msg = Encoding.UTF8.GetString(args.Body.ToArray()); + var @event = System.Text.Json.JsonSerializer.Deserialize(msg); + if (@event == null) + { + LogHelper.Warn( + $"rabbit on queue({options.Queue}) received msg can't convert to {nameof(InterfaceRelayForwardReplayEvent)}"); + return; + } + string? logStr = null; var optionType = Base64Helper.DeSerialize(@event.Attach); if (optionType == OptionType.新增.ToString()) @@ -47,17 +64,6 @@ public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscrib // 往es 写推送日志 await _trackPushRecordEsRepository.AddAsync(log); - // if (!log.IsSuccess) - // { - // // 重试过程中不会去更新订单主表 - // if (@event.RetryNum < 3) - // { - // @event.RetryNum++; - // await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, @event); - // return; - // } - // } - // 同步去更新订单主表 await TrackPushAfterUpdateOrderAsync(log); } diff --git a/src/SJZY.Track.Application/Rabbit/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/Rabbit/TrackRefreshEventHandler.cs index fd31a601..e456bf44 100644 --- a/src/SJZY.Track.Application/Rabbit/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/Rabbit/TrackRefreshEventHandler.cs @@ -79,8 +79,8 @@ public class TrackRefreshEventHandler : ITransientDependency, IRabbitHandler return; } - var config = await _trackPullCacheService.GetPullParamsWithContentAsync(attach.SubSystemId, - attach.ServiceProviderId); + var config = await _trackPullCacheService.GetPullParamsWithContentAsync(attach.SubSystemCode, + attach.ServiceProviderCode); if (config == null) { _logger.LogWarning("请求id: {@RequestId},轨迹消费失败,找不到拉取配置:{@Attach}", attach.ToJson(), @event.RequestId); diff --git a/src/SJZY.Track.Application/SJZY.Track.Application.csproj b/src/SJZY.Track.Application/SJZY.Track.Application.csproj index cf712237..407f97d8 100644 --- a/src/SJZY.Track.Application/SJZY.Track.Application.csproj +++ b/src/SJZY.Track.Application/SJZY.Track.Application.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs index 377edd93..59d127e5 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPullService.cs @@ -8,6 +8,8 @@ using SJZY.Track.Application.Contract.Dtos.TrackPull; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Application.Helpers; using SJZY.Track.Application.Rabbit; +using SJZY.Track.Application.Track2InterfaceRelay; +using SJZY.Track.Domain.Dtos.TrackPull; using SJZY.Track.Domain.Queries; using Volo.Abp.Http.Client.DynamicProxying; @@ -58,6 +60,7 @@ public class TrackPullService : ApplicationService { x.ServiceProviderName, x.SubSystemId, + x.SubSystemCode, x.OrderType })) { @@ -68,14 +71,20 @@ public class TrackPullService : ApplicationService var serviceProviderCode = group.FirstOrDefault()!.ServiceProviderCode; var attach = Base64Helper.SerializeObject(group.Key); - // 批量获取轨迹 - var res = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( - InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, GlobalConst.TrackRefreshSubscribe, - attach); - if (res.Code != InterfaceRelayConst.SuccessCode) + using (Track2InterfaceRelaySubSystemContext.Use( + new Track2InterfaceRelaySubSystemContext(group.Key.SubSystemCode))) { - LogHelper.Error($"刷新轨迹失败:{res.ToJson()}"); + // 批量获取轨迹 + var res = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( + InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, + GlobalConst.TrackRefreshSubscribe, + attach); + + if (res.Code != InterfaceRelayConst.SuccessCode) + { + LogHelper.Error($"刷新轨迹失败:{res.ToJson()}"); + } } } @@ -90,7 +99,7 @@ public class TrackPullService : ApplicationService [HttpPost("Track/RefreshForTask")] public async Task RefreshForTaskAsync() { - var configs = await _trackPullCacheService.GetAllPullConfigsAsync(); + var configs = await _provideQueries.GetAllPullConfigsAsync(); foreach (var config in configs) { @@ -118,9 +127,9 @@ public class TrackPullService : ApplicationService return true; } - private async Task RefreshForConfigAsync(TrackPullConfigDto config) + private async Task RefreshForConfigAsync(TrackPullConfigVo config) { - var redisKey = _trackPullCacheService.TrackPullKey(config.SubSystemId, config.ServiceProviderId); + var redisKey = _trackPullCacheService.TrackPullKey(config.SubSystemCode, config.ServiceProviderCode); if (await RedisHelper.Client.ExistsAsync(redisKey)) { return; @@ -130,36 +139,38 @@ public class TrackPullService : ApplicationService { try { - var page = 1; - var orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, page); - while (orders.Any()) + using (Track2InterfaceRelaySubSystemContext.Use( + new Track2InterfaceRelaySubSystemContext(config.SubSystemCode))) { - var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode; - var serviceProviderName = orders.FirstOrDefault()?.ServiceProviderName; - - foreach (var group in orders.GroupBy(x => new + var page = 1; + var orders = + await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, page); + while (orders.Any()) { - x.SubSystemId, - x.OrderType - })) - { - var data = new List(group.Select(x => new TrackPullPayload - { - OrderNo = x.OrderNo - })); - var attach = Base64Helper.SerializeObject(new TrackRefreshAttach(config.ServiceProviderId, - serviceProviderName!, group.Key.SubSystemId, group.Key.OrderType)); - var res = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( - InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, - GlobalConst.TrackRefreshSubscribe, attach); + var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode; + var serviceProviderName = orders.FirstOrDefault()?.ServiceProviderName; - if (res.Code != InterfaceRelayConst.SuccessCode) + foreach (var group in orders.GroupBy(x => x.OrderType)) { - LogHelper.Error($"刷新轨迹失败:{res.ToJson()}"); + var data = new List(group.Select(x => new TrackPullPayload + { + OrderNo = x.OrderNo + })); + var attach = Base64Helper.SerializeObject(new TrackRefreshAttach(config.ServiceProviderCode, + serviceProviderName!, config.SubSystemCode, config.SubSystemId, group.Key)); + var res = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( + InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, + GlobalConst.TrackRefreshSubscribe, attach); + + if (res.Code != InterfaceRelayConst.SuccessCode) + { + LogHelper.Error($"刷新轨迹失败:{res.ToJson()}"); + } } - } - orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, ++page); + orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, + ++page); + } } } catch (Exception e) diff --git a/src/SJZY.Track.Application/Services/TrackOrders/OrderWarningService.cs b/src/SJZY.Track.Application/Services/TrackOrders/OrderWarningService.cs index f6c00dad..f27cc1c9 100644 --- a/src/SJZY.Track.Application/Services/TrackOrders/OrderWarningService.cs +++ b/src/SJZY.Track.Application/Services/TrackOrders/OrderWarningService.cs @@ -1,8 +1,9 @@ using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; using SJZY.Expand.ABP.Core; using SJZY.Expand.ABP.Core.Logger; using SJZY.Track.Application.Contract.Services; +using SJZY.Track.Application.Track2InterfaceRelay; using SJZY.Track.Domain.Aggregates.ForewarningAggregate; using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Dtos.Forewarning; @@ -77,9 +78,9 @@ public class OrderWarningService /// [AllowAnonymous] [HttpPost("Track/SendWarningForTask")] - public async Task SendWarningForTaskAsync([FromBody] IConfiguration configuration) + public async Task SendWarningForTaskAsync([FromBody] IOptionsSnapshot options) { - var configs = configuration.GetSection("SubSystemWarning").Get>(); + var configs = options.Value; if (configs == null || configs.Keys.Count == 0) { throw new BusinessException("未配置预警系统"); @@ -88,21 +89,22 @@ public class OrderWarningService var subSystemIds = await _orderRepository.GetSubSystemListByCodesAsync(configs.Keys.ToList()); foreach (var item in subSystemIds) { + var subSystemId = item.id; // 如果已经发送过通知,不再发送 - var redisKey = $"{GlobalConst.ForewarningNotifyCheckKey}:{subSystemIds}"; + var redisKey = $"{GlobalConst.ForewarningNotifyCheckKey}:{subSystemId}"; if (await RedisHelper.Client.ExistsAsync(redisKey)) { continue; } - await RedisHelper.Client.SetExAsync(redisKey, 30 * 60, 1); + await RedisHelper.Client.SetExAsync(redisKey, configs[item.code].WarningNotifyInterval * 60, 1); // todo:改mq分流? _ = Task.Run(async () => { try { - var cnt = await _forewarningNotifyService.SendNotificationAsync(item.id); + var cnt = await _forewarningNotifyService.SendNotificationAsync(subSystemId); LogHelper.Info($"预警通知发送成功,新增预警记录{cnt}条"); } catch (Exception e) diff --git a/src/SJZY.Track.Application/Services/TrackPull/TrackPullCacheService.cs b/src/SJZY.Track.Application/Services/TrackPull/TrackPullCacheService.cs index d923cb07..cd1373b0 100644 --- a/src/SJZY.Track.Application/Services/TrackPull/TrackPullCacheService.cs +++ b/src/SJZY.Track.Application/Services/TrackPull/TrackPullCacheService.cs @@ -1,78 +1,60 @@ -using System.Linq.Expressions; 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.Dtos.TrackPull; +using Volo.Abp.DependencyInjection; +using Volo.Abp.ObjectMapping; namespace SJZY.Track.Application.Services.TrackPull; -public class TrackPullCacheService : ApplicationService, ITrackPullCacheService +public class TrackPullCacheService : ITransientDependency, ITrackPullCacheService { + private readonly IObjectMapper _objectMapper; private readonly ITrackPullConfigRepository _trackPullConfigRepository; - public TrackPullCacheService(ITrackPullConfigRepository trackPullConfigRepository) + public TrackPullCacheService(ITrackPullConfigRepository trackPullConfigRepository, IObjectMapper objectMapper) { _trackPullConfigRepository = trackPullConfigRepository; + _objectMapper = objectMapper; } - public string TrackPullKey(int subSystemId, int serviceProviderId) => - $"{GlobalConst.TrackPullKeyPrefix}:{subSystemId}:{serviceProviderId}"; + public string TrackPullKey(string subSystemCode, string serviceProviderCode) => + $"{GlobalConst.TrackPullKeyPrefix}:{subSystemCode}:{serviceProviderCode}"; - public string TrackPullContentKey(int subSystemId, int serviceProviderId) => - $"{GlobalConst.TrackPullContentKeyPrefix}:{subSystemId}:{serviceProviderId}"; + public string TrackPullContentKey(string subSystemCode, string serviceProviderCode) => + $"{GlobalConst.TrackPullContentKeyPrefix}:{subSystemCode}:{serviceProviderCode}"; - [NonAction] - public async Task> GetAllPullConfigsAsync() - { - return await _trackPullConfigRepository.GetListAsync(x => true, - x => new TrackPullConfigDto - { - SubSystemId = x.SubSystemId, - ServiceProviderId = x.ServiceProviderId, - PullInterval = x.PullInterval - }); - } - - [NonAction] - public async Task GetPullParamsWithContentAsync(int subSystemId, - int serviceProviderId) + public async Task GetPullParamsWithContentAsync(string subSystemCode, + string serviceProviderCode) { var data = await RedisHelper.Client.GetAsync(TrackPullContentKey( - subSystemId, - serviceProviderId)); + subSystemCode, serviceProviderCode)); - data ??= await SetPullConfigAsync(subSystemId: subSystemId, serviceProviderId: serviceProviderId); + var pullId = await _trackPullConfigRepository.FindIdAsync(subSystemCode, serviceProviderCode); + data ??= await SetPullConfigAsync(pullId); return data; } - [NonAction] - public async Task SetPullConfigAsync(int? id = null, int? subSystemId = null, - int? serviceProviderId = null) + public async Task SetPullConfigAsync(int id) { - Expression> exp = x => true; - if (id.HasValue) exp = x => x.Id == id; - else if (subSystemId.HasValue && serviceProviderId.HasValue) - exp = x => x.SubSystemId == subSystemId && x.ServiceProviderId == serviceProviderId; + var trackPullConfigDetail = await _trackPullConfigRepository.GetDetailAsync(id); + if (trackPullConfigDetail == null) return null; - var trackPullConfigEntity = await _trackPullConfigRepository.GetFirstAsync(exp); - if (trackPullConfigEntity == null) return null; - - var trackPullConfigDetail = await _trackPullConfigRepository.GetDetailAsync(trackPullConfigEntity.Id); - var trackPullContentList = await _trackPullConfigRepository.GetContentListCacheAsync(trackPullConfigEntity.Id); + var trackPullContentList = await _trackPullConfigRepository.GetContentListCacheAsync(id); if (trackPullContentList.Count == 0) return null; var data = new TrackPullParamsWithContentDto { ParamConfig = - ObjectMapper.Map(trackPullConfigDetail), - ContentConfigs = ObjectMapper.Map, List>( + _objectMapper.Map(trackPullConfigDetail), + ContentConfigs = _objectMapper.Map, List>( trackPullContentList) }; await RedisHelper.Client.SetAsync( - TrackPullContentKey(trackPullConfigEntity.SubSystemId, trackPullConfigEntity.ServiceProviderId), data); + TrackPullContentKey(trackPullConfigDetail.SubSystemCode, trackPullConfigDetail.ServiceProviderCode), data); return data; } diff --git a/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs b/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs index 037fed24..eaad7aca 100644 --- a/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs @@ -63,7 +63,7 @@ public class TrackPullService : ApplicationService /// /// [HttpGet("GetDetail")] - public async Task GetDetailAsync(int id) + public async Task GetDetailAsync(int id) { return await _trackPullConfigRepository.GetDetailAsync(id); } @@ -143,7 +143,7 @@ public class TrackPullService : ApplicationService await _trackPullConfigRepository.UpdateAsync(oldTrackPullEntity); - await _trackPullCacheService.SetPullConfigAsync(input.Id); + await _trackPullCacheService.SetPullConfigAsync(input.Id!.Value); } break; @@ -154,7 +154,7 @@ public class TrackPullService : ApplicationService await _trackPullConfigRepository.SoftDeleteContentAsync(x => x.TrackPullConfigId == input.Id); - await _trackPullCacheService.SetPullConfigAsync(input.Id); + await _trackPullCacheService.SetPullConfigAsync(input.Id!.Value); ts.Complete(); } @@ -222,7 +222,7 @@ public class TrackPullService : ApplicationService var entity = ObjectMapper.Map(input); await _trackPullConfigRepository.InsertContentAsync(entity); - await _trackPullCacheService.SetPullConfigAsync(input.TrackPullConfigId); + await _trackPullCacheService.SetPullConfigAsync(input.TrackPullConfigId!.Value); break; } diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs index 08af0976..e39da04e 100644 --- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs +++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs @@ -11,6 +11,7 @@ using SJZY.InterfaceRelay.Application.Contracts; using SJZY.Track.Application.CAP; using SJZY.Track.Application.Contract; using SJZY.Track.Application.Localization; +using SJZY.Track.Application.Track2InterfaceRelay; using SJZY.UserCenter.Contracts; using SJZY.UserCenter.SharedModel; using SJZY.UserCenter.SharedModel.Pub; @@ -68,7 +69,11 @@ public class SjzyTrackApplicationModule : AbpModule //用户中心 context.Services.AddHttpClientProxies(typeof(SjzyUserCenterHttpApiModule).Assembly, "UserCenter", false); - context.Services.AddHttpClient("InterfaceForward").AddHttpMessageHandler(); + + // 接口通 + context.Services.Configure(configuration.GetSection("Track2InterfaceRelay")); + context.Services.AddHttpClient("InterfaceForward") + .AddHttpMessageHandler(); context.Services.AddHttpClientProxies(typeof(SJZYInterfaceRelayApplicationContractsModule).Assembly, "InterfaceForward", false ); diff --git a/src/SJZY.Track.Application/Track2InterfaceRelay/Track2InterfaceRelayHttpMessageHandler.cs b/src/SJZY.Track.Application/Track2InterfaceRelay/Track2InterfaceRelayHttpMessageHandler.cs new file mode 100644 index 00000000..7f598d4e --- /dev/null +++ b/src/SJZY.Track.Application/Track2InterfaceRelay/Track2InterfaceRelayHttpMessageHandler.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Options; +using SJZY.InterfaceRelay.Application.Contracts; +using Volo.Abp.DependencyInjection; + +namespace SJZY.Track.Application.Track2InterfaceRelay; + +public class Track2InterfaceRelayHttpMessageHandler : DelegatingHandler, ITransientDependency +{ + private readonly Track2InterfaceRelayOptions _options; + + public Track2InterfaceRelayHttpMessageHandler(IOptionsSnapshot options) + { + _options = options.Value; + } + + protected override async Task SendAsync(HttpRequestMessage request, + CancellationToken cancellationToken) + { + if (Track2InterfaceRelaySubSystemContext.Current == null) + { + throw new BusinessException(message: $"请在{nameof(Track2InterfaceRelaySubSystemContext)}中调用接口通"); + } + + var subSystemCode = Track2InterfaceRelaySubSystemContext.Current.Code; + var config = _options.GetOrDefault(subSystemCode); + if (config == null) + { + throw new BusinessException(message: $"子系统{subSystemCode}未在轨迹中台配置,请联系管理员"); + } + + request.Headers.TryAddWithoutValidation(nameof(InterfaceForwardOptions.AppKey), config.AppKey); + request.Headers.TryAddWithoutValidation(nameof(InterfaceForwardOptions.AppSecret), config.AppSecret); + + return await base.SendAsync(request, cancellationToken); + } +} diff --git a/src/SJZY.Track.Application/Track2InterfaceRelay/Track2InterfaceRelayOptions.cs b/src/SJZY.Track.Application/Track2InterfaceRelay/Track2InterfaceRelayOptions.cs new file mode 100644 index 00000000..093501ad --- /dev/null +++ b/src/SJZY.Track.Application/Track2InterfaceRelay/Track2InterfaceRelayOptions.cs @@ -0,0 +1,23 @@ +namespace SJZY.Track.Application.Track2InterfaceRelay; + +public class Track2InterfaceRelayOptions : Dictionary +{ +} + +public class SubSystemConfig +{ + /// + /// 接口通appKey + /// + public string AppKey { get; set; } + + /// + /// 接口通app秘钥 + /// + public string AppSecret { get; set; } + + /// + /// 预警通知间隔(分钟) + /// + public int WarningNotifyInterval { get; set; } = 30; +} diff --git a/src/SJZY.Track.Application/Track2InterfaceRelay/Track2InterfaceRelaySubSystemContext.cs b/src/SJZY.Track.Application/Track2InterfaceRelay/Track2InterfaceRelaySubSystemContext.cs new file mode 100644 index 00000000..1382b909 --- /dev/null +++ b/src/SJZY.Track.Application/Track2InterfaceRelay/Track2InterfaceRelaySubSystemContext.cs @@ -0,0 +1,21 @@ +namespace SJZY.Track.Application.Track2InterfaceRelay; + +public class Track2InterfaceRelaySubSystemContext +{ + private static readonly AsyncLocal LocalContext = new(); + + public Track2InterfaceRelaySubSystemContext(string code) + { + Code = code; + } + + public string Code { get; set; } + public static Track2InterfaceRelaySubSystemContext? Current => LocalContext.Value; + + public static IDisposable Use(Track2InterfaceRelaySubSystemContext context) + { + var previousValue = Current; + LocalContext.Value = context; + return new DisposeAction(() => LocalContext.Value = previousValue); + } +} diff --git a/src/SJZY.Track.Domain/Aggregates/TrackPullAggregate/ITrackPullConfigRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackPullAggregate/ITrackPullConfigRepository.cs index 9c722b8a..d1cc0e36 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackPullAggregate/ITrackPullConfigRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackPullAggregate/ITrackPullConfigRepository.cs @@ -31,7 +31,7 @@ public interface ITrackPullConfigRepository : IBasicRepository /// /// - Task GetDetailAsync(int id); + Task GetDetailAsync(int id); /// /// 轨迹拉取配置内容详情 @@ -49,4 +49,5 @@ public interface ITrackPullConfigRepository : IBasicRepository UpdateContentAsync(TrackPullContentConfigEntity updateObj); Task IsContentAnyAsync(Expression> whereExpression); + Task FindIdAsync(string subSystemCode, string serviceProviderCode); } diff --git a/src/SJZY.Track.Domain/Dtos/Order/OrderWithServiceProviderVO.cs b/src/SJZY.Track.Domain/Dtos/Order/OrderWithServiceProviderVO.cs index 14a9d15b..448805af 100644 --- a/src/SJZY.Track.Domain/Dtos/Order/OrderWithServiceProviderVO.cs +++ b/src/SJZY.Track.Domain/Dtos/Order/OrderWithServiceProviderVO.cs @@ -21,6 +21,11 @@ public class OrderWithServiceProviderVO /// public string ServiceProviderName { get; set; } = null!; + /// + /// 子系统code + /// + public string SubSystemCode { get; set; } + /// /// 子系统id /// diff --git a/src/SJZY.Track.Domain/Dtos/TrackPull/GetTrackPullConfigDetailOutputVO.cs b/src/SJZY.Track.Domain/Dtos/TrackPull/GetTrackPullConfigDetailOutputVO.cs index b578a3de..dbaa37b3 100644 --- a/src/SJZY.Track.Domain/Dtos/TrackPull/GetTrackPullConfigDetailOutputVO.cs +++ b/src/SJZY.Track.Domain/Dtos/TrackPull/GetTrackPullConfigDetailOutputVO.cs @@ -25,9 +25,9 @@ public class GetTrackPullConfigDetailOutputVO public string ServiceProvider { get; set; } /// - /// 服务商id + /// 服务商code /// - public int ServiceProviderId { get; set; } + public string ServiceProviderCode { get; set; } /// /// 子系统 @@ -35,9 +35,9 @@ public class GetTrackPullConfigDetailOutputVO public string SubSystem { get; set; } /// - /// 子系统id + /// 子系统code /// - public int SubSystemId { get; set; } + public string SubSystemCode { get; set; } /// /// 拉取轨迹时区 diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackPullConfigDto.cs b/src/SJZY.Track.Domain/Dtos/TrackPull/TrackPullConfigVo.cs similarity index 52% rename from src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackPullConfigDto.cs rename to src/SJZY.Track.Domain/Dtos/TrackPull/TrackPullConfigVo.cs index d13b6f19..1a28568d 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/TrackPull/TrackPullConfigDto.cs +++ b/src/SJZY.Track.Domain/Dtos/TrackPull/TrackPullConfigVo.cs @@ -1,6 +1,6 @@ -namespace SJZY.Track.Application.Contract.Dtos.TrackPull; +namespace SJZY.Track.Domain.Dtos.TrackPull; -public class TrackPullConfigDto +public class TrackPullConfigVo { /// /// 服务商拉取频率(分钟) @@ -12,6 +12,16 @@ public class TrackPullConfigDto /// public int ServiceProviderId { get; set; } + /// + /// 服务商code + /// + public string ServiceProviderCode { get; set; } + + /// + /// 子系统code + /// + public string SubSystemCode { get; set; } + /// /// 子系统id /// diff --git a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs index f8c10e15..e45e1321 100644 --- a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs +++ b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs @@ -1,5 +1,6 @@ using SJZY.Track.Domain.Dtos.Order; using SJZY.Track.Domain.Dtos.TrackContents; +using SJZY.Track.Domain.Dtos.TrackPull; namespace SJZY.Track.Domain.Queries; @@ -34,5 +35,17 @@ public interface IProvideQueries Task> FindOrderWithServiceProviderAsync(int serviceProviderId, int pageIndex, int pageSize = 1000); + /// + /// 获取轨迹内容 + /// + /// + /// + /// Task GetTrackContentAsync(int subSystemId, string trackCode); + + /// + /// 获取所有拉取配置 + /// + /// + Task> GetAllPullConfigsAsync(); } diff --git a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs index c23394d9..a87f9f6a 100644 --- a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs +++ b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs @@ -1,8 +1,10 @@ using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackContentAggregate; +using SJZY.Track.Domain.Aggregates.TrackPullAggregate; using SJZY.Track.Domain.Aggregates.TrackStatusAggregate; using SJZY.Track.Domain.Dtos.Order; using SJZY.Track.Domain.Dtos.TrackContents; +using SJZY.Track.Domain.Dtos.TrackPull; using SJZY.Track.Domain.Queries; using SJZY.Track.Domain.VEntities; @@ -11,8 +13,7 @@ namespace SJZY.Track.Repository.Queries; /// /// 提供服务相关查询 /// -public class ProvideQueries : ISugarRepository, IProvideQueries, - ITransientDependency +public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDependency { /// /// ctor @@ -22,7 +23,6 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, Context = SqlsugarScopeBasic.GetContextSafely("default"); } - /// public async Task> MapTrackCodesAsync(int upSubSystemId, int subSystemId, params string[] trackCodes) { // 根据上游code得到下游code @@ -37,16 +37,18 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, public async Task> FindOrderWithServiceProviderAsync(List orderNos) { return await Context.Queryable() - .LeftJoin((a, b) => a.Id == b.OrderId) + .InnerJoin((a, b) => a.Id == b.OrderId) .LeftJoin((a, b, c) => b.ServiceProviderCode == c.Code) + .LeftJoin((a, b, c, d) => a.SubSystemId == d.Id) .Where(a => !a.IsCompleted && orderNos.Contains(a.OrderNo)) - .Select((a, b, c) => new OrderWithServiceProviderVO + .Select((a, b, c, d) => new OrderWithServiceProviderVO { OrderNo = a.OrderNo, OrderType = a.OrderType, ServiceProviderCode = c.Code, ServiceProviderName = c.Name, - SubSystemId = a.SubSystemId + SubSystemId = a.SubSystemId, + SubSystemCode = d.Key }) .ToListAsync(); } @@ -58,16 +60,17 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, return await Context.Queryable() .RightJoin((a, b) => a.Id == b.OrderId) .LeftJoin((a, b, c) => b.ServiceProviderCode == c.Code) + .LeftJoin((a, b, c, d) => a.SubSystemId == d.Id) .Where((a, b, c) => c.Id == serviceProviderId && !a.IsCompleted && b.StartTime <= DateTime.Now && b.EndTime >= DateTime.Now) - .Select((a, b, c) => new OrderWithServiceProviderVO + .Select((a, b, c, d) => new OrderWithServiceProviderVO { OrderNo = a.OrderNo, OrderType = a.OrderType, ServiceProviderCode = c.Code, ServiceProviderName = c.Name, SubSystemId = a.SubSystemId, - TrackPullStatus = b.PullStatus + SubSystemCode = d.Key }) .Skip((pageIndex - 1) * pageSize) .Take(pageSize) @@ -91,6 +94,22 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, .FirstAsync(); } + public async Task> GetAllPullConfigsAsync() + { + return await Context.Queryable() + .LeftJoin((a, b) => a.ServiceProviderId == b.Id) + .LeftJoin((a, b, c) => a.SubSystemId == c.Id) + .Select((a, b, c) => new TrackPullConfigVo + { + PullInterval = a.PullInterval, + ServiceProviderId = a.ServiceProviderId, + ServiceProviderCode = b.Code, + SubSystemCode = c.Key, + SubSystemId = c.Id + }) + .ToListAsync(); + } + /// /// db context /// diff --git a/src/SJZY.Track.Repository/Repositories/TrackPullConfigRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackPullConfigRepository.cs index 867fa9de..22dc7200 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackPullConfigRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackPullConfigRepository.cs @@ -73,22 +73,22 @@ public class TrackPullConfigRepository : BasicRepository, .ToListAsync(); } - public async Task GetDetailAsync(int id) + public async Task GetDetailAsync(int id) { return await AsQueryable() - .LeftJoin((trackPull, system) => trackPull.SubSystemId == system.Id && !system.IsDeleted) - .LeftJoin((trackPull, system, service) => - trackPull.ServiceProviderId == service.Id && !service.IsDeleted) - .Filter(null, true) - .Where(trackPull => trackPull.Id == id && !trackPull.IsDeleted) + .LeftJoin((trackPull, system) => trackPull.SubSystemId == system.Id) + .LeftJoin((trackPull, system, service) => trackPull.ServiceProviderId == service.Id) + .Where(trackPull => trackPull.Id == id) .Select( (trackPull, system, service) => new GetTrackPullConfigDetailOutputVO { Id = trackPull.Id, SubSystem = system.CnName, + SubSystemCode = system.Key, ServiceProvider = service.Name, + ServiceProviderCode = service.Code, }, true) - .SingleAsync(); + .FirstAsync(); } public async Task GetContentDetailAsync(int id) @@ -140,4 +140,14 @@ public class TrackPullConfigRepository : BasicRepository, { return await Context.Queryable().Where(whereExpression).AnyAsync(); } + + public async Task FindIdAsync(string subSystemCode, string serviceProviderCode) + { + return await AsQueryable() + .LeftJoin((trackPull, system) => trackPull.SubSystemId == system.Id) + .LeftJoin((trackPull, system, service) => trackPull.ServiceProviderId == service.Id) + .Where((trackPull, system, service) => system.Key == subSystemCode && service.Code == serviceProviderCode) + .Select(trackPull => trackPull.Id) + .FirstAsync(); + } }