This commit is contained in:
xiaolipro 2025-08-21 14:50:11 +08:00
parent d4716e3faf
commit a7d824151e
3 changed files with 155 additions and 48 deletions

View File

@ -2,6 +2,8 @@ using AutoMapper;
using TrackCenter.Application.Dtos.Warning.Complete; using TrackCenter.Application.Dtos.Warning.Complete;
using TrackCenter.Application.Dtos.Warning.Return; using TrackCenter.Application.Dtos.Warning.Return;
using TrackCenter.Application.Dtos.Warning.Transport; using TrackCenter.Application.Dtos.Warning.Transport;
using TrackCenter.Domain.Aggregates.KPIAreaAggregate;
using TrackCenter.Domain.Dtos.Forewarning;
using TrackCenter.Domain.Dtos.Warning; using TrackCenter.Domain.Dtos.Warning;
namespace TrackCenter.Application.AutoMapper; namespace TrackCenter.Application.AutoMapper;
@ -13,5 +15,27 @@ public class WarningMapperProfile : Profile
CreateMap<GetPageCompleteWarningDetailsInput, GetPageCompleteWarningDetailsInputVO>(MemberList.None); CreateMap<GetPageCompleteWarningDetailsInput, GetPageCompleteWarningDetailsInputVO>(MemberList.None);
CreateMap<GetPageReturnWarningDetailsInput, GetPageReturnWarningDetailsInputVO>(MemberList.None); CreateMap<GetPageReturnWarningDetailsInput, GetPageReturnWarningDetailsInputVO>(MemberList.None);
CreateMap<GetPageTransportWarningDetailsInput, GetPageTransportWarningDetailsInputVO>(MemberList.None); CreateMap<GetPageTransportWarningDetailsInput, GetPageTransportWarningDetailsInputVO>(MemberList.None);
// kpi区域
CreateMap<UpdateRuleAreaRequest, RuleAreaEntity>(MemberList.None);
CreateMap<AddRuleAreaInfoRequest, RuleAreaInfoEntity>(MemberList.None)
.ForMember(dest => dest.CountryCode, opt => opt.MapFrom(src => src.CountryCode))
.ForMember(dest => dest.CountryName, opt => opt.MapFrom(src => src.CountryName))
.ForMember(dest => dest.Province, opt => opt.MapFrom(src => src.Province))
.ForMember(dest => dest.City, opt => opt.MapFrom(src => src.City))
.ForMember(dest => dest.LeftPostcode, opt => opt.MapFrom(src => src.LeftPostCode))
.ForMember(dest => dest.RightPostcode, opt => opt.MapFrom(src => src.RightPostCode))
.ForMember(dest => dest.AreaId, opt => opt.MapFrom(src => src.AreaId));
CreateMap<CreateRuleAreaRequest, RuleAreaEntity>(MemberList.None)
.ForMember(dest => dest.AppKey, opt => opt.MapFrom(src => src.AppKey))
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name));
CreateMap<UpdateRuleAreaInfoRequest, RuleAreaInfoEntity>(MemberList.None)
.ForMember(dest => dest.CountryCode, opt => opt.MapFrom(src => src.CountryCode))
.ForMember(dest => dest.CountryName, opt => opt.MapFrom(src => src.CountryName))
.ForMember(dest => dest.Province, opt => opt.MapFrom(src => src.Province))
.ForMember(dest => dest.City, opt => opt.MapFrom(src => src.City))
.ForMember(dest => dest.LeftPostcode, opt => opt.MapFrom(src => src.LeftPostCode))
.ForMember(dest => dest.RightPostcode, opt => opt.MapFrom(src => src.RightPostCode));
} }
} }

View File

@ -0,0 +1,92 @@
using System.ComponentModel;
using System.Reflection;
namespace TrackCenter.Application.Services;
/// <summary>
/// 字典服务
/// </summary>
[ApiExplorerSettings(GroupName = "应用服务")]
public class DictionaryService : ApplicationService
{
private static readonly Dictionary<string, List<EnumCacheEntry>> EnumCache = new();
/// <summary>
/// 列表
/// </summary>
/// <param name="type">枚举类型</param>
/// <returns></returns>
[HttpGet("Dictionary/GetList")]
public List<EnumCacheEntry> GetList(string type)
{
// 优先读枚举值
return GetKvsByEnumTypeName(type);
}
/// <summary>
/// 清除缓存
/// </summary>
/// <param name="type"></param>
[HttpPost("Dictionary/CleanCache")]
public void CleanCache(string type)
{
EnumCache.Clear();
}
/// <summary>
/// 获取枚举下拉列表
/// </summary>
/// <param name="enumTypeName">枚举类型名称</param>
/// <returns></returns>
[NonAction]
private List<EnumCacheEntry> GetKvsByEnumTypeName(string enumTypeName)
{
// Check if the type is already cached
if (EnumCache.TryGetValue(enumTypeName, out var res))
{
return res;
}
// Load the assembly
var assemblyName = "TrackCenter.Domain";
var assembly = Assembly.Load(assemblyName);
if (assembly == null)
{
throw new ArgumentException($"Assembly '{assemblyName}' could not be loaded.");
}
// Get the enum type
var enumType = assembly.GetType("TrackCenter.Domain.Enums." + enumTypeName);
if (enumType == null || !enumType.IsEnum)
{
throw new ArgumentException($"The type '{enumTypeName}' is not a valid enum.");
}
// Retrieve the descriptions and values
var list = new List<EnumCacheEntry>();
foreach (var value in enumType.GetEnumValues())
{
var name = value.ToString();
var fieldInfo = enumType.GetField(name);
var descriptionAttribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>();
string description = descriptionAttribute != null ? descriptionAttribute.Description : name;
list.Add(new EnumCacheEntry
{
Key = (int)value,
Value = description
});
}
// Cache the result
EnumCache[enumTypeName] = list;
return list;
}
public class EnumCacheEntry
{
public int Key { get; set; }
public string Value { get; set; } = null!;
}
}

View File

@ -4,6 +4,7 @@ using InterfaceForward.Domain.Shared.Helpers;
using TrackCenter.Application.Dtos.TrackPush; using TrackCenter.Application.Dtos.TrackPush;
using TrackCenter.Application.Helpers; using TrackCenter.Application.Helpers;
using TrackCenter.Application.Services.Warning.Handlers; using TrackCenter.Application.Services.Warning.Handlers;
using TrackCenter.Domain.Aggregates.OrderAggregate;
using TrackCenter.Domain.Aggregates.TrackPushAggregate; using TrackCenter.Domain.Aggregates.TrackPushAggregate;
using TrackCenter.Domain.Dtos.TrackPush; using TrackCenter.Domain.Dtos.TrackPush;
@ -14,22 +15,12 @@ namespace TrackCenter.Application.Services.TrackPush;
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "轨迹推送")] [ApiExplorerSettings(GroupName = "轨迹推送")]
[Route("/Track/PushConfig")] [Route("/Track/PushConfig")]
public class TrackPushService : ApplicationServiceBase, ISingletonDependency public class TrackPushService(
ITrackPushConfigRepository trackPushConfigRepository,
TrackPushCacheService trackPushCacheService,
IServiceProvider serviceProvider)
: ApplicationServiceBase, ISingletonDependency
{ {
private readonly TrackPushCacheService _trackPushCacheService;
private readonly ITrackPushConfigRepository _trackPushConfigRepository;
private readonly IServiceProvider _serviceProvider;
public TrackPushService(
ITrackPushConfigRepository trackPushConfigRepository,
TrackPushCacheService trackPushCacheService,
IServiceProvider serviceProvider)
{
_trackPushConfigRepository = trackPushConfigRepository;
_trackPushCacheService = trackPushCacheService;
_serviceProvider = serviceProvider;
}
/// <summary> /// <summary>
/// 轨迹推送配置列表 /// 轨迹推送配置列表
/// </summary> /// </summary>
@ -38,7 +29,7 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
[HttpPost("GetPage")] [HttpPost("GetPage")]
public async Task<PagedResult<GetTrackPushConfigPageOutputVO>> GetPageAsync([FromBody] KeywordsInputVO input) public async Task<PagedResult<GetTrackPushConfigPageOutputVO>> GetPageAsync([FromBody] KeywordsInputVO input)
{ {
return await _trackPushConfigRepository.GetPageAsync(input); return await trackPushConfigRepository.GetPageAsync(input);
} }
/// <summary> /// <summary>
@ -50,7 +41,7 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
public async Task<PagedResult<GetTrackPushContentPageOutputVO>> GetContentPageAsync( public async Task<PagedResult<GetTrackPushContentPageOutputVO>> GetContentPageAsync(
[FromBody] GetTrackPushContentPageInputVO input) [FromBody] GetTrackPushContentPageInputVO input)
{ {
return await _trackPushConfigRepository.GetContentPageAsync(input); return await trackPushConfigRepository.GetContentPageAsync(input);
} }
/// <summary> /// <summary>
@ -61,7 +52,7 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
[HttpGet("GetDetail")] [HttpGet("GetDetail")]
public async Task<GetTrackPushConfigDetailOutputVO> GetDetailAsync(int id) public async Task<GetTrackPushConfigDetailOutputVO> GetDetailAsync(int id)
{ {
return await _trackPushConfigRepository.GetDetailAsync(id); return await trackPushConfigRepository.GetDetailAsync(id);
} }
/// <summary> /// <summary>
@ -72,7 +63,7 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
[HttpGet("GetContentDetail")] [HttpGet("GetContentDetail")]
public async Task<GetTrackPushContentDetailOutputVO> GetContentDetailAsync(int id) public async Task<GetTrackPushContentDetailOutputVO> GetContentDetailAsync(int id)
{ {
return await _trackPushConfigRepository.GetContentDetailAsync(id); return await trackPushConfigRepository.GetContentDetailAsync(id);
} }
/// <summary> /// <summary>
@ -88,7 +79,7 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
Expression<Func<TrackPushConfigEntity, bool>> isAnyExp = x => x.Customer == input.Customer; Expression<Func<TrackPushConfigEntity, bool>> isAnyExp = x => x.Customer == input.Customer;
if (input.Options == OptionTypeNoNull.修改) isAnyExp = isAnyExp.And(x => x.Id != input.Id); if (input.Options == OptionTypeNoNull.修改) isAnyExp = isAnyExp.And(x => x.Id != input.Id);
if (await _trackPushConfigRepository.IsAnyAsync(isAnyExp)) if (await trackPushConfigRepository.IsAnyAsync(isAnyExp))
throw new BusinessException(message: "配置已存在"); throw new BusinessException(message: "配置已存在");
} }
@ -107,28 +98,28 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
case OptionTypeNoNull.新增: case OptionTypeNoNull.新增:
var trackPushEntity = ObjectMapper.Map<EditTrackPushConfigInput, TrackPushConfigEntity>(input); var trackPushEntity = ObjectMapper.Map<EditTrackPushConfigInput, TrackPushConfigEntity>(input);
await _trackPushConfigRepository.InsertReturnIdentityAsync(trackPushEntity); await trackPushConfigRepository.InsertReturnIdentityAsync(trackPushEntity);
await _trackPushCacheService.SetPushContentConfigsAsync(trackPushEntity.AppKey, await trackPushCacheService.SetPushContentConfigsAsync(trackPushEntity.AppKey,
trackPushEntity.Customer); trackPushEntity.Customer);
break; break;
case OptionTypeNoNull.修改: case OptionTypeNoNull.修改:
var oldTrackPushEntity = await _trackPushConfigRepository.GetFirstAsync(x => x.Id == input.Id) ?? var oldTrackPushEntity = await trackPushConfigRepository.GetFirstAsync(x => x.Id == input.Id) ??
throw new BusinessException(message: "找不到数据"); throw new BusinessException(message: "找不到数据");
ObjectMapper.Map(input, oldTrackPushEntity); ObjectMapper.Map(input, oldTrackPushEntity);
await _trackPushConfigRepository.UpdateAsync(oldTrackPushEntity); await trackPushConfigRepository.UpdateAsync(oldTrackPushEntity);
await _trackPushCacheService.SetPushContentConfigsAsync(oldTrackPushEntity.AppKey, await trackPushCacheService.SetPushContentConfigsAsync(oldTrackPushEntity.AppKey,
oldTrackPushEntity.Customer); oldTrackPushEntity.Customer);
break; break;
case OptionTypeNoNull.删除: case OptionTypeNoNull.删除:
var entity = await _trackPushConfigRepository.GetFirstAsync(x => x.Id == input.Id) ?? var entity = await trackPushConfigRepository.GetFirstAsync(x => x.Id == input.Id) ??
throw new BusinessException(message: "找不到数据"); throw new BusinessException(message: "找不到数据");
await _trackPushConfigRepository.SoftDeleteAsync(x => x.Id == input.Id); await trackPushConfigRepository.SoftDeleteAsync(x => x.Id == input.Id);
await _trackPushConfigRepository.SoftDeleteContentAsync(x => x.TrackPushConfigId == input.Id); await trackPushConfigRepository.SoftDeleteContentAsync(x => x.TrackPushConfigId == input.Id);
await _trackPushCacheService.SetPushContentConfigsAsync(entity.AppKey, entity.Customer); await trackPushCacheService.SetPushContentConfigsAsync(entity.AppKey, entity.Customer);
break; break;
default: default:
@ -154,23 +145,23 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
&& x.OrderNoType == input.OrderNoType; && x.OrderNoType == input.OrderNoType;
if (input.Options == OptionTypeNoNull.修改) isContentAnyExp = isContentAnyExp.And(x => x.Id != input.Id); if (input.Options == OptionTypeNoNull.修改) isContentAnyExp = isContentAnyExp.And(x => x.Id != input.Id);
if (await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => if (await trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x =>
x.TrackContentId == input.TrackContentId))) x.TrackContentId == input.TrackContentId)))
throw new BusinessException(message: "TrackContentId配置已存在"); throw new BusinessException(message: "TrackContentId配置已存在");
if (!input.TrackContentCodeValue.IsNullOrWhiteSpace() && if (!input.TrackContentCodeValue.IsNullOrWhiteSpace() &&
await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => await trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x =>
x.TrackContentCodeValue == input.TrackContentCodeValue))) x.TrackContentCodeValue == input.TrackContentCodeValue)))
throw new BusinessException(message: "TrackContentCodeValue配置已存在"); throw new BusinessException(message: "TrackContentCodeValue配置已存在");
if (!input.TrackStatusValue.IsNullOrWhiteSpace() && if (!input.TrackStatusValue.IsNullOrWhiteSpace() &&
await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => await trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x =>
x.TrackStatusValue == input.TrackStatusValue))) x.TrackStatusValue == input.TrackStatusValue)))
throw new BusinessException(message: "TrackStatusValue配置已存在"); throw new BusinessException(message: "TrackStatusValue配置已存在");
if (!input.TrackContentValue.IsNullOrWhiteSpace() && if (!input.TrackContentValue.IsNullOrWhiteSpace() &&
await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => await trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x =>
x.TrackContentValue == input.TrackContentValue))) x.TrackContentValue == input.TrackContentValue)))
throw new BusinessException(message: "TrackContentValue配置已存在"); throw new BusinessException(message: "TrackContentValue配置已存在");
if (!input.TrackEnContentValue.IsNullOrWhiteSpace() && if (!input.TrackEnContentValue.IsNullOrWhiteSpace() &&
await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => await trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x =>
x.TrackEnContentValue == input.TrackEnContentValue))) x.TrackEnContentValue == input.TrackEnContentValue)))
throw new BusinessException(message: "TrackEnContentValue配置已存在"); throw new BusinessException(message: "TrackEnContentValue配置已存在");
} }
@ -185,36 +176,36 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
{ {
case OptionTypeNoNull.新增: case OptionTypeNoNull.新增:
{ {
var maxSort = await _trackPushConfigRepository.ContentMaxAsync(x => x.Sort, x => var maxSort = await trackPushConfigRepository.ContentMaxAsync(x => x.Sort, x =>
x.OrderNoType == input.OrderNoType x.OrderNoType == input.OrderNoType
&& x.TrackPushConfigId == input.TrackPushConfigId && x.TrackPushConfigId == input.TrackPushConfigId
); );
var entity = ObjectMapper.Map<EditTrackPushContentInput, TrackPushContentConfigEntity>(input); var entity = ObjectMapper.Map<EditTrackPushContentInput, TrackPushContentConfigEntity>(input);
entity.Sort = maxSort + 1; entity.Sort = maxSort + 1;
await _trackPushConfigRepository.InsertContentAsync(entity); await trackPushConfigRepository.InsertContentAsync(entity);
break; break;
} }
case OptionTypeNoNull.修改: case OptionTypeNoNull.修改:
{ {
var entity = await _trackPushConfigRepository.GetContentByIdAsync(input.Id!.Value) ?? var entity = await trackPushConfigRepository.GetContentByIdAsync(input.Id!.Value) ??
throw new BusinessException(message: "找不到数据"); throw new BusinessException(message: "找不到数据");
oldContentConfig = entity.DeepCopy(); oldContentConfig = entity.DeepCopy();
ObjectMapper.Map(input, entity); ObjectMapper.Map(input, entity);
await _trackPushConfigRepository.UpdateContentAsync(entity); await trackPushConfigRepository.UpdateContentAsync(entity);
postContentConfig = entity; postContentConfig = entity;
break; break;
} }
case OptionTypeNoNull.删除: case OptionTypeNoNull.删除:
{ {
var entity = await _trackPushConfigRepository.GetContentByIdAsync(input.Id!.Value) ?? var entity = await trackPushConfigRepository.GetContentByIdAsync(input.Id!.Value) ??
throw new BusinessException(message: "找不到数据"); throw new BusinessException(message: "找不到数据");
oldContentConfig = entity; oldContentConfig = entity;
trackPushConfigId = entity.TrackPushConfigId; trackPushConfigId = entity.TrackPushConfigId;
await _trackPushConfigRepository.SoftDeleteContentAsync(x => x.Id == input.Id); await trackPushConfigRepository.SoftDeleteContentAsync(x => x.Id == input.Id);
await _trackPushConfigRepository.UpdateContentAsync(x => x.Sort == x.Sort - 1, x => await trackPushConfigRepository.UpdateContentAsync(x => x.Sort == x.Sort - 1, x =>
x.OrderNoType == entity.OrderNoType x.OrderNoType == entity.OrderNoType
&& x.TrackPushConfigId == entity.TrackPushConfigId && x.TrackPushConfigId == entity.TrackPushConfigId
&& x.Sort > entity.Sort && x.Sort > entity.Sort
@ -226,10 +217,10 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
var pushConfig = await _trackPushConfigRepository.GetFirstAsync(x => x.Id == trackPushConfigId); var pushConfig = await trackPushConfigRepository.GetFirstAsync(x => x.Id == trackPushConfigId);
if (pushConfig != null) if (pushConfig != null)
{ {
await _trackPushCacheService.SetPushContentConfigsAsync(pushConfig.AppKey, pushConfig.Customer); await trackPushCacheService.SetPushContentConfigsAsync(pushConfig.AppKey, pushConfig.Customer);
} }
ts.Complete(); ts.Complete();
@ -250,7 +241,7 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
{ {
var ids = input.SortInfo.Select(x => int.Parse(x.Key)).ToList(); var ids = input.SortInfo.Select(x => int.Parse(x.Key)).ToList();
var trackPushContentEntities = await _trackPushConfigRepository.GetContentListAsync(x => ids.Contains(x.Id)); var trackPushContentEntities = await trackPushConfigRepository.GetContentListAsync(x => ids.Contains(x.Id));
trackPushContentEntities.ForEach(item => { item.Sort = input.SortInfo.Single(x => x.Key == item.Id.ToString()).Value; }); trackPushContentEntities.ForEach(item => { item.Sort = input.SortInfo.Single(x => x.Key == item.Id.ToString()).Value; });
@ -258,9 +249,9 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
{ {
using var ts = TransacationHelper.GetReadCommitted(); using var ts = TransacationHelper.GetReadCommitted();
await _trackPushConfigRepository.UpdateContentRangeAsync(trackPushContentEntities); await trackPushConfigRepository.UpdateContentRangeAsync(trackPushContentEntities);
var pushConfig = await _trackPushConfigRepository.GetFirstAsync( var pushConfig = await trackPushConfigRepository.GetFirstAsync(
x => x.Id == trackPushContentEntities[0].TrackPushConfigId, x => x.Id == trackPushContentEntities[0].TrackPushConfigId,
y => new y => new
{ {
@ -269,7 +260,7 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
}); });
if (pushConfig != null) if (pushConfig != null)
{ {
await _trackPushCacheService.SetPushContentConfigsAsync(pushConfig.AppKey, pushConfig.Customer); await trackPushCacheService.SetPushContentConfigsAsync(pushConfig.AppKey, pushConfig.Customer);
} }
ts.Complete(); ts.Complete();
@ -292,7 +283,7 @@ public class TrackPushService : ApplicationServiceBase, ISingletonDependency
_ = Task.Run(async () => _ = Task.Run(async () =>
{ {
var scope = _serviceProvider.CreateScope(); var scope = serviceProvider.CreateScope();
try try
{ {
var handler = scope.ServiceProvider.GetRequiredService<IReturnWarningHandler>(); var handler = scope.ServiceProvider.GetRequiredService<IReturnWarningHandler>();