diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs index 578c298d..64ae2569 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/TrackPushContentConfigDto.cs @@ -10,11 +10,16 @@ public class TrackPushConfigDto /// /// 轨迹推送内容配置 /// - public List ContentConfigs { get; set; } + public List ContentConfigs { get; set; } = new(); } public class TrackPushContentConfigDto { + /// + /// 服务商code + /// + public string ServiceProviderCode { get; set; } = null!; + /// /// 扩展字段参数值 /// diff --git a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs index 56032acb..5bbcbea6 100644 --- a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs @@ -20,7 +20,7 @@ public class TrackUpsertEvent : UpsertTrackInput public int SubSystemId { get; set; } /// - /// 最新推送代码(异步维护) + /// 最新推送轨迹内容id(异步维护) /// public int? LatestPushTrackContentId { get; set; } diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs index 03e18f69..9febcaf7 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushService.cs @@ -2,7 +2,7 @@ using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.OrderAggregate; -using SJZY.Track.Domain.Aggregates.TrackContentAggregate; +using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using Volo.Abp.Http.Client.DynamicProxying; namespace SJZY.Track.Application.Services.ProvideServices; @@ -14,23 +14,23 @@ namespace SJZY.Track.Application.Services.ProvideServices; [Route("/ProviderService")] public class TrackPushService : ApplicationService { + private readonly ITrackDetailsRepository _trackDetailsRepository; private readonly IOrderRepository _orderRepository; - private readonly ITrackContentRepository _trackContentRepository; private readonly ITrackPushCacheService _pushCacheService; private readonly IHttpClientProxy _httpClientProxy; - public TrackPushService(IOrderRepository orderRepository, + public TrackPushService( IHttpClientProxy httpClientProxy, ITrackPushCacheService pushCacheService, - ITrackContentRepository trackContentRepository) + ITrackDetailsRepository trackDetailsRepository, IOrderRepository orderRepository) { - _orderRepository = orderRepository; _httpClientProxy = httpClientProxy; _pushCacheService = pushCacheService; - _trackContentRepository = trackContentRepository; + _trackDetailsRepository = trackDetailsRepository; + _orderRepository = orderRepository; } /// - /// 推送轨迹 + /// 手工推送轨迹 /// /// /// @@ -38,10 +38,7 @@ public class TrackPushService : ApplicationService public async Task PushTrackAsync(PushTrackInput input) { input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空 - if (input.OrderNos.Count == 0) - { - throw new BusinessException(message: "订单一个都不存在"); - } + var orders = await _orderRepository.GetListAsync(x => x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => new @@ -49,27 +46,46 @@ public class TrackPushService : ApplicationService x.Id, x.OrderNo, x.SubSystemId, x.CustomId }); - var trackContents = await _trackContentRepository.GetListAsync(x => x.Code == input.TrackCode, x => new + if (input.OrderNos.Count == 0) { - x.SubSystemId, x.Id - }); + throw new BusinessException(message: "一个推送配置都不存在"); + } - foreach (var group in orders.GroupBy(x => - new { x.SubSystemId, x.CustomId })) + var tracks = await _trackDetailsRepository.GetListAsync(input.OrderType, input.OrderNos, input.TrackCode); + + foreach (var order in orders) { - var trackContent = trackContents.FirstOrDefault(x => x.SubSystemId == group.Key.SubSystemId); - if (trackContent == null) continue; - var config = await _pushCacheService.GetPushContentConfigAsync(group.Key.SubSystemId, - group.Key.CustomId, trackContent.Id); - var data = group.Select(x => new + // 如果没有轨迹,就不需要推 + var track = tracks.FirstOrDefault(x => x.OrderId == order.Id); + if (track == null) continue; + + // 手工推送不推断,直接无脑推 + var config = + await _pushCacheService.GetPushContentConfigAsync(order.SubSystemId, order.CustomId, + track.TrackContentId); + + var data = new { - x.OrderNo - }).ToList(); + order.OrderNo, + data = new[] + { + new + { + // 推真实的发生地和发生时间 + location = track.TrackPlace, + date = track.TrackTime.AddHours(config.TrackTimeZone ?? + track.TrackTimeZone - track.TrackTimeZone), + timeZone = config.TrackTimeZone ?? track.TrackTimeZone, + description = config.TrackEnContentValue, + description_cn = config.TrackContentValue, + code = config.TrackContentCodeValue, + status = config.TrackStatusValue, + extra = config.ExpandFieldsValue + } + } + }; - // 批量获取轨迹 - // await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( - // "A024", group.Key.ServiceProviderCode, data, - // GlobalConst.TrackRefreshSubscribe, JsonConvert.SerializeObject(group.Key)); + await _httpClientProxy.Service.ForwardWithSubscribeAsync("A024", config.ServiceProviderCode, data); } return true; diff --git a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs index 61ddbcb5..36e386b8 100644 --- a/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs +++ b/src/SJZY.Track.Application/Services/TrackPush/TrackPushCacheService.cs @@ -1,8 +1,8 @@ -using SJZY.Expand.ABP.Core; +using System.Linq.Expressions; +using SJZY.Expand.ABP.Core; using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.TrackPushAggregate; -using System.Linq.Expressions; using Volo.Abp.DependencyInjection; namespace SJZY.Track.Application.Services.TrackPush; @@ -11,7 +11,8 @@ public class TrackPushCacheService : ApplicationService, ITrackPushCacheService, { private readonly ITrackPushConfigRepository _trackPushConfigRepository; - private string TrackPushContentKey(int subSystemId, int customId) => $"{GlobalConst.TrackPushKeyPrefix}:{subSystemId}:{customId}"; + private string TrackPushContentKey(int subSystemId, int customId) => + $"{GlobalConst.TrackPushKeyPrefix}:{subSystemId}:{customId}"; public TrackPushCacheService(ITrackPushConfigRepository trackPushConfigRepository) { @@ -27,7 +28,8 @@ public class TrackPushCacheService : ApplicationService, ITrackPushCacheService, } [NonAction] - public async Task GetPushContentConfigAsync(int subSystemId, int customId, int trackContentId) + public async Task GetPushContentConfigAsync(int subSystemId, int customId, + int trackContentId) { var data = await GetPushContentConfigsAsync(subSystemId, customId); @@ -35,7 +37,8 @@ public class TrackPushCacheService : ApplicationService, ITrackPushCacheService, } [NonAction] - public async Task InferNextPushContentOrNullAsync(int subSystemId, int customId, int? trackContentId) + public async Task InferNextPushContentOrNullAsync(int subSystemId, int customId, + int? trackContentId) { var data = await GetPushConfigAsync(subSystemId, customId); if (!data.IsAutoPush) return null; @@ -45,36 +48,44 @@ public class TrackPushCacheService : ApplicationService, ITrackPushCacheService, if (data.ContentConfigs.Count > 1 && data.ContentConfigs.Any(x => x.TrackContentId == trackContentId)) { int index = data.ContentConfigs.FindIndex(x => x.TrackContentId == trackContentId); + if (index == data.ContentConfigs.Count - 1) return null; int nextIndex = (index + 1) % data.ContentConfigs.Count; // 计算下一个索引,处理最后一个元素的情况 return data.ContentConfigs[nextIndex]; } - else return null; + + return null; } - else return data.ContentConfigs.FirstOrDefault(); + + return data.ContentConfigs.FirstOrDefault(); } [NonAction] - public async Task SetPushContentConfigsAsync(int? id = null, int? subSystemId = null, int? customId = null) + public async Task SetPushContentConfigsAsync(int? id = null, int? subSystemId = null, + int? customId = null) { var data = new TrackPushConfigDto { ContentConfigs = new() }; Expression> exp = x => true; if (id.HasValue) exp = x => x.Id == id; - else if (subSystemId.HasValue && customId.HasValue) exp = x => x.SubSystemId == subSystemId && x.CustomId == customId; + else if (subSystemId.HasValue && customId.HasValue) + exp = x => x.SubSystemId == subSystemId && x.CustomId == customId; 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(x => x.TrackPushConfigId == 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); + data.ContentConfigs = + ObjectMapper.Map, List>(trackPushContentList); - await RedisHelper.Client.SetAsync(TrackPushContentKey(trackPushConfigEntity.SubSystemId, trackPushConfigEntity.CustomId), data); + await RedisHelper.Client.SetAsync( + TrackPushContentKey(trackPushConfigEntity.SubSystemId, trackPushConfigEntity.CustomId), data); return data; } diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs index 34cdac01..b0a1cf21 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -10,6 +10,8 @@ public interface ITrackDetailsRepository Task> GetListAsync(int orderType, List orderNos); + Task> GetListAsync(int orderType, List orderNos, string trackCode); + Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input); Task> GetListAsync(int orderId); diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs index 812b2377..964b4ee4 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs @@ -11,6 +11,11 @@ public class TrackDetailsIndex : IdBaseIndex /// public int OrderId { get; set; } + /// + /// 服务商code + /// + public string? ServiceProviderCode { get; set; } + /// /// 订单号 /// diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index 8bc2739d..132341a1 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -87,6 +87,11 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract> GetListAsync(int orderType, List orderNos, string trackCode) + { + throw new NotImplementedException(); + } + public async Task> GetListAsync(int orderId) { var data = await Context.SearchAsync(x => x @@ -134,11 +139,12 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract DeleteTrackAsync(int orderId, List trackCodes) { var r = await Context.DeleteByQueryAsync(x => x - .Query( - q => - q.Term(t => t.OrderId, orderId) - && q.Term(t => t.IsCanDelete, true) - && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) + .Query( + q => + q.Term(t => t.OrderId, orderId) + && q.Term(t => t.IsCanDelete, true) + && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) + .Refresh() // 可选:立即刷新索引使更改立即可见 ); if (!r.IsValid)