using Microsoft.AspNetCore.Authorization; using SJZY.Expand.ABP.Core; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.InterfaceRelay.Application.Contracts; using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Dtos.TrackPull; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Application.Helpers; using SJZY.Track.Application.Rabbit; using SJZY.Track.Domain.Queries; using Volo.Abp.Http.Client.DynamicProxying; namespace SJZY.Track.Application.Services.ProvideServices; /// /// 轨迹刷新服务 /// [ApiExplorerSettings(GroupName = "提供接口")] [Route("/ProviderService")] public class TrackPullService : ApplicationService { private readonly IHttpClientProxy _httpClientProxy; private readonly IProvideQueries _provideQueries; private readonly ITrackPullCacheService _trackPullCacheService; public TrackPullService(IProvideQueries provideQueries, IHttpClientProxy httpClientProxy, ITrackPullCacheService trackPullCacheService) { _provideQueries = provideQueries; _httpClientProxy = httpClientProxy; _trackPullCacheService = trackPullCacheService; } /// /// 手动刷新轨迹 /// /// /// [HttpPost("Track/Refresh")] public async Task RefreshTrackAsync(RefreshTrackInput input) { // todo:罚时? input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空 // tips:这里没有区分订单类型,就算的不同类型的单一起刷新了也无所谓 var orders = await _provideQueries.FindOrderWithServiceProviderAsync(input.OrderNos); if (orders.Count == 0) { // tips:可能是没有配置、或者所有单都刷完了、或者单不存在 throw new BusinessException(message: "一个能更新的都没有"); } foreach (var group in orders.GroupBy(x => new { x.ServiceProviderName, x.SubSystemId, x.OrderType })) { var data = new List(group.Select(x => new TrackPullPayload { OrderNo = x.OrderNo })); 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) { LogHelper.Error($"刷新轨迹失败:{res.ToJson()}"); } } return true; } /// /// 定时任务刷新轨迹 /// /// [AllowAnonymous] [HttpPost("Track/RefreshForTask")] public async Task RefreshForTaskAsync() { var configs = await _trackPullCacheService.GetAllPullConfigsAsync(); var tasks = configs.Select(RefreshForConfigAsync).ToArray(); await Task.WhenAll(tasks); return true; } /// /// 轨迹刷新测试 /// /// /// /// [HttpPost("Track/TrackRefreshEventTest")] #if DEBUG [AllowAnonymous] #endif public async Task TrackRefreshEventTest([FromServices] TrackRefreshEventHandler trackRefreshEventHandler, InterfaceRelayForwardReplayEvent input) { await trackRefreshEventHandler.ConsumerAsync(input); return true; } private async Task RefreshForConfigAsync(TrackPullConfigDto config) { var redisKey = _trackPullCacheService.TrackPullKey(config.SubSystemId, config.ServiceProviderId); if (await RedisHelper.Client.ExistsAsync(redisKey)) { return; } var page = 1; var orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, page); while (orders.Any()) { var serviceProviderCode = orders.FirstOrDefault()?.ServiceProviderCode; var serviceProviderName = orders.FirstOrDefault()?.ServiceProviderName; foreach (var group in orders.GroupBy(x => new { 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); if (res.Code != InterfaceRelayConst.SuccessCode) { LogHelper.Error($"刷新轨迹失败:{res.ToJson()}"); } } orders = await _provideQueries.FindOrderWithServiceProviderAsync(config.ServiceProviderId, ++page); } await RedisHelper.Client.SetExAsync(redisKey, config.PullInterval * 60, orders.Count); } }