using System.Linq.Expressions; using SJZY.Expand.ABP.Core; using SJZY.Track.Application.Contract.Dtos.TrackPush; using SJZY.Track.Application.Contract.Services; using SJZY.Track.Domain.Aggregates.TrackPushAggregate; using SJZY.Track.Domain.Consts; using Volo.Abp.DependencyInjection; namespace SJZY.Track.Application.Services.TrackPush; public class TrackPushCacheService : ITrackPushCacheService, ITransientDependency { private readonly ITrackPushConfigRepository _trackPushConfigRepository; private string TrackPushContentKey(int subSystemId, int customId) => $"{GlobalConst.TrackPushKeyPrefix}:{subSystemId}:{customId}"; public TrackPushCacheService(ITrackPushConfigRepository trackPushConfigRepository) { _trackPushConfigRepository = trackPushConfigRepository; } public async Task?> GetPushContentConfigsAsync(int subSystemId, int customId) { var data = await RedisHelper.Client.GetAsync>( TrackPushContentKey(subSystemId, customId)); data ??= await SetPushContentConfigsAsync(subSystemId: subSystemId, customId: customId); return data; } public async Task GetPushContentConfigAsync(int subSystemId, int customId, string trackConde) { var configs = await GetPushContentConfigsAsync(subSystemId, customId); return configs?.FirstOrDefault(x => x.TrackCode == trackConde); } public async Task IsValidPushAsync(int subSystemId, int customId, string? latestPushTrackCode, string? trackCode) { var cache = await GetPushContentConfigsAsync(subSystemId, customId); if (cache == null || cache.Count < 1) return default; TrackPushContentConfigDto? matched; if (latestPushTrackCode == null) { matched = cache.First(); } else { var idx = cache.FindIndex(x => x.TrackCode == latestPushTrackCode); if (idx == -1) return default; // 是否预警? // find next if (idx + 1 < cache.Count && cache[idx + 1].TrackCode == trackCode) { matched = cache[idx + 1]; } else { // find swap matched = cache.FirstOrDefault(x => x.TrackCode == cache[idx].SwapTrackCode); } } return matched != null && matched.TrackCode == trackCode && matched.IsAutoPush ? matched : default; } public async Task?> SetPushContentConfigsAsync(int? id = null, int? subSystemId = null, int? customId = null) { 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; var trackPushConfig = await _trackPushConfigRepository.GetFirstAsync(exp, x => new { x.Id, x.IsAutoPush, x.IsAllPush, x.IsCanDelete, x.IsCanUpdate, x.SubSystemId, x.CustomId }); if (trackPushConfig == null) return null; var trackPushContentList = await _trackPushConfigRepository.GetContentListAsync(trackPushConfig.Id); if (trackPushContentList.Count == 0) return null; // tips:hot path,auto mapper性能不如原生 var res = trackPushContentList.Select(item => new TrackPushContentConfigDto { IsAutoPush = trackPushConfig.IsAutoPush, IsCanUpdate = trackPushConfig.IsCanUpdate, IsAllPush = trackPushConfig.IsAllPush, IsCanDelete = trackPushConfig.IsCanDelete, ServiceProviderCode = item.ServiceProviderCode, OrderType = item.OrderType, TrackCode = item.TrackCode, SwapTrackCode = item.SwapTrackCode, TrackStatusValue = item.TrackStatusValue, TrackContentCodeValue = item.TrackContentCodeValue, TrackContentValue = item.TrackContentValue, TrackEnContentValue = item.TrackEnContentValue, TrackTimeZone = item.TrackTimeZone, ExpandFieldsValue = item.ExpandFieldsValue, }).ToList(); await RedisHelper.Client.SetAsync(TrackPushContentKey(trackPushConfig.SubSystemId, trackPushConfig.CustomId), res); return res; } }