diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs
index 633a550e..4f1795c3 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs
@@ -11,12 +11,12 @@ public class DeleteTrackInput : OrderNoInfo
///
/// 轨迹标识符集合,为支持esid删除,所以非必填
///
- public List? TrackIdentifiers { get; set; } = new();
+ public List TrackIdentifiers { get; set; } = new();
///
/// 轨迹ESId集合,非必填,如果有优先级最高
///
- public List? EsIds { get; set; }
+ public List EsIds { get; set; } = new();
///
/// 重复的情况下,用什么字段比较
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
index 22970d3e..0b0ce375 100644
--- a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
+++ b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
@@ -4,20 +4,20 @@ namespace SJZY.Track.Application.Contract.Events;
public class TrackDeleteEvent
{
+ ///
+ /// 根据esId定位轨迹,优先级最高
+ ///
+ public string[] EsIds { get; set; } = Array.Empty();
+
///
/// 子系统id
///
public int SubSystemId { get; set; }
- ///
- /// es中的id
- ///
- public string[]? EsIds { get; set; }
-
///
/// 订单ids
///
- public int[] OrderIds { get; set; } = null!;
+ public int[] OrderIds { get; set; } = Array.Empty();
///
/// 重复的情况下,用什么字段比较
@@ -37,7 +37,7 @@ public class TrackDeleteEvent
///
/// 轨迹标识符
///
- public List? TrackIdentifiers { get; set; }
+ public List TrackIdentifiers { get; set; } = new();
///
/// 操作人
@@ -57,6 +57,6 @@ public class TrackDeleteEvent
public override string ToString()
{
return $"[TrackDelete by {OperationMan}] SubSystemId: {SubSystemId}, OrderIds: {string.Join(",",
- OrderIds)}, TrackCodes: {string.Join(",", TrackIdentifiers.Select(x=>x.TrackCode))}";
+ OrderIds)}, TrackCodes: {string.Join(",", TrackIdentifiers.Select(x => x.TrackCode))}";
}
}
diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs
index 571599b4..89207bee 100644
--- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs
+++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs
@@ -26,11 +26,15 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
private readonly IBroadcastingService _broadcastingService;
private readonly IServiceProvider _serviceProvider;
- public TrackDeleteEventHandler(IProvideQueries provideQueries,
- IOrderRepository orderRepository, ICapPublisher capPublisher,
+ public TrackDeleteEventHandler(
+ IProvideQueries provideQueries,
+ IOrderRepository orderRepository,
+ ICapPublisher capPublisher,
ITrackDetailsEsRepository trackDetailsEsRepository,
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
- IBroadcastingService broadcastingService, IServiceProvider serviceProvider)
+ IBroadcastingService broadcastingService,
+ IServiceProvider serviceProvider
+ )
{
_provideQueries = provideQueries;
_orderRepository = orderRepository;
@@ -65,8 +69,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderIds);
foreach (var orderId in @event.OrderIds)
{
- foreach (var group in linkedOrders.Where(x => x.OwnerOrderId == orderId)
- .GroupBy(x => x.SubSystemId))
+ foreach (var group in linkedOrders.Where(x => x.OwnerOrderId == orderId).GroupBy(x => x.SubSystemId))
{
var nextEvent = @event.DeepCopy();
nextEvent.Visited.AddRange(@event.OrderIds);
@@ -76,9 +79,11 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
// 不同子系统需要做内容映射
if (@event.SubSystemId != nextEvent.SubSystemId)
{
- var codeMaps = await _provideQueries
- .GetTrackCodeMapsAsync(@event.SubSystemId, nextEvent.SubSystemId,
- @event.TrackIdentifiers.Select(x => x.TrackCode).ToArray());
+ var codeMaps = await _provideQueries.GetTrackCodeMapsAsync(
+ @event.SubSystemId,
+ nextEvent.SubSystemId,
+ @event.TrackIdentifiers.Select(x => x.TrackCode).ToArray()
+ );
if (codeMaps.Count == 0)
{
@@ -133,7 +138,8 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
List orderIds;
List tracks;
List deleteTracks;
- if (@event.EsIds != null && @event.EsIds.Any()) //根据明确的esid进行删除
+ // 优先根据EsId查询轨迹
+ if (@event.EsIds.Length > 0) //根据明确的esid进行删除
{
deleteTracks = await _trackDetailsEsRepository.GetDataByIds(@event.EsIds);
orderIds = deleteTracks.Select(m => m.OrderId).Distinct().ToList();
@@ -145,17 +151,14 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
}).ToList();
// 外部api获取的轨迹不允许删除
- if (deleteTracks.Any(m => m.Source == TrackSourceEnum.ExternalServiceProvide.GetHashCode()))
+ if (deleteTracks.Any(m => m.Source == (int) TrackSourceEnum.ExternalServiceProvide))
return deleteTracks;
//查出订单下的所有轨迹,以供后面回退使用
tracks = await _trackDetailsEsRepository.GetListAsync(@event.OrderIds);
- // 删除轨迹
- foreach (var item in deleteTracks)
- {
- await _trackDetailsEsRepository.DeleteTrackByIdAsync(item.Id, item.IndexName);
- }
+ // 删除轨迹批量
+ await _trackDetailsEsRepository.DeleteTrackByIdsAsync(deleteTracks.Select(x => x.Id).ToHashSet());
//清理已经删除过的esid
@event.EsIds = Array.Empty();
@@ -202,10 +205,8 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
if (deleteTracks.Count == 0) return deleteTracks;
- foreach (var track in deleteTracks)
- {
- await _trackDetailsEsRepository.DeleteTrackByIdAsync(track.Id, track.IndexName);
- }
+ // 删除轨迹批量
+ await _trackDetailsEsRepository.DeleteTrackByIdsAsync(deleteTracks.Select(x => x.Id).ToHashSet());
//从被删除轨迹寻找订单id,稍后会更新订单主表
orderIds = deleteTracks.Select(m => m.OrderId).Distinct().ToList();
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
index 77f06254..5c2f4da7 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
@@ -20,11 +20,13 @@ public partial class OrderService : ApplicationService, IOrderService
private readonly IOrderRepository _orderRepository;
private readonly IServiceProvider _serviceProvider;
- public OrderService(IOrderRepository orderRepository,
- ICapPublisher capPublisher
- , ITrackDetailsEsRepository trackDetailsEsRepository,
+ public OrderService(
+ IOrderRepository orderRepository,
+ ICapPublisher capPublisher,
+ ITrackDetailsEsRepository trackDetailsEsRepository,
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
- IServiceProvider serviceProvider)
+ IServiceProvider serviceProvider
+ )
{
_orderRepository = orderRepository;
_orderOperationRecordEsRepository = orderOperationRecordEsRepository;
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
index 8e1de010..dd4d3b9f 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
@@ -31,14 +31,16 @@ public partial class TrackService : ApplicationService, ITrackService
private readonly IHttpClientProxy _requestCurrentUserService;
private readonly ITrackContentRepository _trackContentRepository;
- public TrackService(IOrderRepository orderRepository,
+ public TrackService(
+ IOrderRepository orderRepository,
ICapPublisher capPublisher,
ITrackDetailsEsRepository trackDetailsEsRepository,
ITrackContentRepository trackContentRepository,
IHttpClientProxy requestCurrentUserService,
ITrackTemplateRepository trackTemplateRepository,
IHttpContextAccessor contextAccessor,
- IVSystemQueries vSystemQueries)
+ IVSystemQueries vSystemQueries
+ )
{
_orderRepository = orderRepository;
_capPublisher = capPublisher;
@@ -59,10 +61,12 @@ public partial class TrackService : ApplicationService, ITrackService
[HttpPost("Track/Delete")]
public async Task DeleteTrackAsync(DeleteTrackInput input)
{
- var orderId = await _orderRepository.GetFirstAsync(
- x => x.SubSystemId == input.SubSystemId && x.OrderType == input.OrderType && x.OrderNo == input.OrderNo,
+ var orderId = await _orderRepository.GetFirstAsync(x =>
+ x.SubSystemId == input.SubSystemId
+ && x.OrderType == input.OrderType
+ && x.OrderNo == input.OrderNo,
x => x.Id);
- if (orderId == null)
+ if (orderId == 0)
{
throw new BusinessException(message: $"订单:{input.OrderNo}不存在");
}
@@ -73,38 +77,29 @@ public partial class TrackService : ApplicationService, ITrackService
throw new BusinessException(message: $"调用用户中心,获取用户信息失败:{userInfo.Msg}");
}
- var name = userInfo.Data.UserName;
-
- List tracks;
- bool existsExternal;
- var esIds = input.EsIds?.Distinct().ToArray();
- //优先使用esId
- if (esIds != null && esIds.Length > 0)
+ // 查询轨迹优先使用esId,tips:考虑删除事件处理直接通过EsId而不是再查询一遍?
+ List? tracks = null;
+ var esIds = input.EsIds.Distinct().ToArray();
+ if (esIds.Length > 0)
{
tracks = await _trackDetailsEsRepository.GetDataByIds(esIds);
- existsExternal = tracks.Any(x => x.Source == (int) TrackSourceEnum.ExternalServiceProvide);
}
- else
+ else if (input.TrackIdentifiers.Count > 0)
{
- var trackCodes = input.TrackIdentifiers?.Select(x => x.TrackCode).ToList();
- var trackIds = input.TrackIdentifiers?.Select(y => $"{y.TrackCode}{y.TrackTime}").ToHashSet();
- //没有任何需要操作的轨迹
- if (trackIds == null || trackIds.Count == 0)
- {
- throw new BusinessException(message: "没有任何轨迹要删除,请检查输入参数");
- }
-
- //删除轨迹约束,只要其中有一条来源是外部的就立即返回错误
+ // todo:漏洞,使用标识符(code+时间)删除缺少时区补充
+ var trackCodes = input.TrackIdentifiers.Select(x => x.TrackCode).ToList();
+ var trackIds = input.TrackIdentifiers.Select(y => $"{y.TrackCode}{y.TrackTime}").ToHashSet();
tracks = await _trackDetailsEsRepository.GetListAsync(new[] { orderId }, trackCodes);
- //检查删除的轨迹中是否包含外部轨迹
- existsExternal = tracks
- .Where(x => x.Source == (int) TrackSourceEnum.ExternalServiceProvide)
+
+ // todo:漏洞,如果是外部服务商轨迹(拉取得到的轨迹),没有扩展?
+ tracks = tracks
+ // 先通过code+时间初步过滤
+ .Where(y => trackIds.Contains($"{y.TrackCode}{y.TrackTime}"))
+ // 如果提供了比较字段,则进一步过滤,但要求这个code的所有轨迹都要包含Extra!
.WhereIf(!input.CompareFields.IsNullOrWhiteSpace(), y =>
{
if (string.IsNullOrWhiteSpace(y.Extra))
- {
throw new BusinessException(message: "轨迹extra为空无法使用比较字段比较,请检查轨迹");
- }
var extraDict = System.Text.Json.JsonSerializer.Deserialize>(y.Extra);
if (extraDict!.TryGetValue(input.CompareFields!, out var compareValueJsonElement))
@@ -112,47 +107,47 @@ public partial class TrackService : ApplicationService, ITrackService
return false;
})
- .Select(x => $"{x.TrackCode}{x.TrackTime}")
- .Any(x => trackIds.Contains(x));
+ .ToList();
}
- if (existsExternal)
- {
- throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除");
- }
-
- if (tracks.Count == 0)
+ if (tracks == null || tracks.Count == 0)
{
throw new BusinessException(message: "没有任何轨迹要删除,请检查输入参数");
}
- // 删除轨迹
- await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe,
- new TrackDeleteEvent
- {
- EsIds = input.EsIds?.ToArray(),
- OrderIds = new[] { orderId },
- CompareFields = input.CompareFields,
- CompareValue = input.CompareValue,
- Source = input.Source,
- TrackIdentifiers = input.TrackIdentifiers,
- SubSystemId = input.SubSystemId,
- OperationMan = name
- });
+ //删除轨迹约束,只要其中有一条来源是外部的就立即返回错误
+ if (tracks.Any(x => x.Source == (int) TrackSourceEnum.ExternalServiceProvide))
+ {
+ throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除");
+ }
+
+ // 删除轨迹(异步)
+ await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, new TrackDeleteEvent
+ {
+ EsIds = esIds,
+ OrderIds = new[] { orderId },
+ SubSystemId = input.SubSystemId,
+ CompareFields = input.CompareFields,
+ CompareValue = input.CompareValue,
+ Source = input.Source,
+ TrackIdentifiers = input.TrackIdentifiers,
+ OperationMan = userInfo.Data.UserName
+ });
return new UnifyResultDto(true, true);
}
///
- /// 根据esid删除轨迹内容
+ /// 根据esid删除轨迹内容(FBA专用)
///
///
///
[HttpPost("Track/BatchDeleteByEsId")]
public async Task BatchDeleteTrackByEsIdAsync(BatchDeleteTrackByEsIdInput input)
{
- var tracks = await _trackDetailsEsRepository.GetDataByIds(input.TrackContentEsIds.ToArray());
- if (tracks == null || tracks.Count == 0)
+ var esIds = input.TrackContentEsIds.ToArray();
+ var tracks = await _trackDetailsEsRepository.GetDataByIds(esIds);
+ if (tracks.Count == 0)
return new UnifyResultDto(false, "未找到指定id下的轨迹内容");
if (tracks.Any(m => m.Source == TrackSourceEnum.ExternalServiceProvide.GetHashCode()))
@@ -176,7 +171,7 @@ public partial class TrackService : ApplicationService, ITrackService
var @event = new TrackDeleteEvent
{
- EsIds = input.TrackContentEsIds.ToArray(),
+ EsIds = esIds,
SubSystemId = tracks.First().SubSystemId,
Source = input.Source,
OperationMan = userName,
@@ -198,36 +193,28 @@ public partial class TrackService : ApplicationService, ITrackService
{
input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空
var orderIds = await _orderRepository.GetListAsync(x =>
- x.SubSystemId == input.SubSystemId && x.OrderType == input.OrderType &&
- input.OrderNos.Contains(x.OrderNo)
- , x => x.Id);
+ x.SubSystemId == input.SubSystemId
+ && x.OrderType == input.OrderType
+ && input.OrderNos.Contains(x.OrderNo),
+ x => x.Id);
if (orderIds.Count == 0)
{
throw new BusinessException(message: "订单一个都不存在");
}
- // 获取用户name
- var userInfo = await _requestCurrentUserService.Service.GetCurrentUserBasicInfoAsync();
- if (userInfo.Code != GlobalConst.SuccessCode || userInfo.Data is null)
- {
- throw new BusinessException(message: $"调用用户中心,获取用户信息失败:{userInfo.Msg}");
- }
-
//删除轨迹约束,只要其中有一条来源是外部的就立即返回错误
- var tracks = await _trackDetailsEsRepository
- .GetListAsync(orderIds.ToArray(),
- input.TrackIdentifiers.Select(x => x.TrackCode).ToList(),
- TrackSourceEnum.ExternalServiceProvide);
+ var tracks = await _trackDetailsEsRepository.GetListAsync(orderIds.ToArray(),
+ input.TrackIdentifiers.Select(x => x.TrackCode).ToList(),
+ TrackSourceEnum.ExternalServiceProvide
+ );
//当要删除的轨迹标识出现交叉则不允许删除
var intersect = tracks
.WhereIf(!input.CompareFields.IsNullOrWhiteSpace(), y =>
{
if (string.IsNullOrWhiteSpace(y.Extra))
- {
throw new BusinessException(message: "轨迹extra为空无法使用比较字段比较,请检查轨迹");
- }
var extraDict = TextJsonHelper.DeserializeToDictionary(y.Extra);
if (extraDict!.TryGetValue(input.CompareFields!, out var compareValueJsonElement))
@@ -236,12 +223,20 @@ public partial class TrackService : ApplicationService, ITrackService
return false;
})
.Select(x => $"{x.TrackCode}{x.TrackTime}")
- .Intersect(input.TrackIdentifiers.Select(y => $"{y.TrackCode}{y.TrackTime}")).ToList();
+ .Intersect(input.TrackIdentifiers.Select(y => $"{y.TrackCode}{y.TrackTime}"))
+ .ToList();
if (intersect.Count > 0)
{
throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除");
}
+ // 获取用户name
+ var userInfo = await _requestCurrentUserService.Service.GetCurrentUserBasicInfoAsync();
+ if (userInfo.Code != GlobalConst.SuccessCode || userInfo.Data is null)
+ {
+ throw new BusinessException(message: $"调用用户中心,获取用户信息失败:{userInfo.Msg}");
+ }
+
// 删除轨迹
var @event = new TrackDeleteEvent
{
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs
index 72f49807..840b2d51 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs
@@ -41,6 +41,8 @@ public interface ITrackDetailsEsRepository : IElasticsearchClientService esIds);
+
Task> GetDataByIds(string[] ids);
Task GetDetailAsync(string orderNo, string trackCode, int orderType, int subSystemId, DateTime trackTime);
diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs
index 22998be5..e6415867 100644
--- a/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs
@@ -691,7 +691,7 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract(x => x
.Index(GlobalConst.TrackDetailsIndex)
.Version()
- .Query(q => query)
+ .Query(_ => query)
.Size(SafelyLimit)
.Sort(s => s
.Field(f => f.ZeroTrackTime, SortOrder.Descending)
@@ -774,16 +774,34 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract esIds)
+ {
+ var r = await Context.DeleteByQueryAsync(x => x
+ .Index(GlobalConst.TrackDetailsIndex)
+ .Query(q => q.Ids(i => i.Values(esIds)))
+ );
+
+ if (!r.IsValid)
+ {
+ throw new InvalidOperationException($"轨迹删除失败,ids:[{string.Join(", ", esIds)}],原因:{r.DebugInformation}。");
+ }
+ }
+
public async Task> GetDataByIds(string[] ids)
{
- var res = await Context.SearchAsync(m => m
+ var r = await Context.SearchAsync(m => m
.Index(GlobalConst.TrackDetailsIndex)
.Version()
.Query(
q => q.Ids(i => i.Values(ids))
));
- return res.ToIdAndVersionList();
+ if (!r.IsValid)
+ {
+ throw new InvalidOperationException($"轨迹查询失败,ids:[{string.Join(", ", ids)}],原因:{r.DebugInformation}。");
+ }
+
+ return r.ToIdAndVersionList();
}
public async Task GetDetailAsync(string orderNo, string trackCode, int orderType, int subSystemId, DateTime trackTime)