fix: 修复删除轨迹失败
This commit is contained in:
parent
c98e1e7d8a
commit
ea77583ce4
@ -5,9 +5,9 @@ namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
|
||||
public class BatchDeleteTrackInput : OrderNosInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 轨迹code,必填
|
||||
/// 轨迹标识符集合,必填
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MaxLength(500)]
|
||||
public List<string> TrackCodes { get; set; } = new();
|
||||
public List<TrackIdentifierDto> TrackIdentifiers { get; set; } = new();
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@ public class DeleteOrderInput : OrderNoInfo
|
||||
public class DeleteTrackInput : OrderNoInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 轨迹code
|
||||
/// 轨迹标识符集合,必填
|
||||
/// </summary>
|
||||
[Required]
|
||||
public List<string> TrackCodes { get; set; } = new();
|
||||
public List<TrackIdentifierDto> TrackIdentifiers { get; set; } = new();
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹标识符,用于唯一标识一个轨迹
|
||||
/// </summary>
|
||||
public sealed class TrackIdentifierDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 轨迹code
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string TrackCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹发生时间
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateTime TrackTime { get; set; }
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
|
||||
|
||||
namespace SJZY.Track.Application.Contract.Events;
|
||||
|
||||
public class TrackDeleteEvent
|
||||
@ -18,9 +20,9 @@ public class TrackDeleteEvent
|
||||
public int[] OrderIds { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹代码
|
||||
/// 轨迹标识符
|
||||
/// </summary>
|
||||
public List<string> TrackCodes { get; set; } = null!;
|
||||
public List<TrackIdentifierDto> TrackIdentifiers { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 操作人
|
||||
@ -40,6 +42,6 @@ public class TrackDeleteEvent
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[TrackDelete by {OperationMan}] SubSystemId: {SubSystemId}, OrderIds: {string.Join(",",
|
||||
OrderIds)}, TrackCodes: {string.Join(",", TrackCodes)}";
|
||||
OrderIds)}, TrackCodes: {string.Join(",", TrackIdentifiers.Select(x=>x.TrackCode))}";
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ using BSI.Stack.Rabbit;
|
||||
using DotNetCore.CAP;
|
||||
using SJZY.Expand.ABP.Core.Logger;
|
||||
using SJZY.Expand.ABP.Core.PublicMethords;
|
||||
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
|
||||
using SJZY.Track.Application.Contract.Events;
|
||||
using SJZY.Track.Domain.Aggregates.OrderAggregate;
|
||||
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
|
||||
@ -67,22 +68,29 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
|
||||
{
|
||||
var nextEvent = @event.DeepCopy();
|
||||
nextEvent.Visited.AddRange(@event.OrderIds);
|
||||
nextEvent.TrackCodes = @event.TrackCodes;
|
||||
nextEvent.TrackIdentifiers = @event.TrackIdentifiers;
|
||||
nextEvent.SubSystemId = group.Key;
|
||||
|
||||
// 不同子系统需要做内容映射
|
||||
if (@event.SubSystemId != nextEvent.SubSystemId)
|
||||
{
|
||||
var mapCodes = await _provideQueries
|
||||
.MapTrackCodesAsync(@event.SubSystemId, nextEvent.SubSystemId, @event.TrackCodes.ToArray());
|
||||
var codeMaps = await _provideQueries
|
||||
.GetTrackCodeMapsAsync(@event.SubSystemId, nextEvent.SubSystemId,
|
||||
@event.TrackIdentifiers.Select(x => x.TrackCode).ToArray());
|
||||
|
||||
if (mapCodes.Count == 0)
|
||||
if (codeMaps.Count == 0)
|
||||
{
|
||||
LogHelper.Warn($"订单跨子系统,未配置内容映射,请联系管理员:{@event}", true);
|
||||
continue;
|
||||
}
|
||||
|
||||
nextEvent.TrackCodes = mapCodes;
|
||||
//映射轨迹code
|
||||
foreach (var trackIdentity in nextEvent.TrackIdentifiers)
|
||||
{
|
||||
var match = codeMaps.FirstOrDefault(x => x.MapTrackContentCode == trackIdentity.TrackCode);
|
||||
if (match == null) continue;
|
||||
trackIdentity.TrackCode = match.TrackContentCode;
|
||||
}
|
||||
}
|
||||
|
||||
var identifiers = group.Select(x => x.OrderId).ToList();
|
||||
@ -172,7 +180,11 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
|
||||
tracks = await _trackDetailsEsRepository.GetDataByIds(@event.EsIds);
|
||||
orderIds = tracks.Select(m => m.OrderId).Distinct().ToList();
|
||||
@event.OrderIds = orderIds.ToArray();
|
||||
@event.TrackCodes = tracks.Select(x => x.TrackCode).Distinct().ToList();
|
||||
@event.TrackIdentifiers = tracks.Select(x => new TrackIdentifierDto
|
||||
{
|
||||
TrackCode = x.TrackCode,
|
||||
TrackTime = x.TrackTime
|
||||
}).ToList();
|
||||
|
||||
// 外部api获取的轨迹不允许删除
|
||||
if (tracks.Any(m => m.Source == TrackSourceEnum.ExternalServiceProvide.GetHashCode()))
|
||||
@ -189,11 +201,24 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
|
||||
}
|
||||
else //原有逻辑,根据轨迹code和订单进行删除
|
||||
{
|
||||
var trackCodes = @event.TrackIdentifiers.Select(x => x.TrackCode).ToList();
|
||||
// 删除轨迹(删的是同子系统下的单,所以code是统一的)
|
||||
tracks = await _trackDetailsEsRepository.GetLatestListAsync(@event.OrderIds, @event.TrackCodes);
|
||||
tracks = await _trackDetailsEsRepository.GetListAsync(@event.OrderIds, trackCodes,null);
|
||||
|
||||
orderIds = await _trackDetailsEsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes);
|
||||
if (orderIds.Count == 0) return tracks;
|
||||
//构建标识符集合
|
||||
var ids = @event.TrackIdentifiers.Select(x => $"{x.TrackCode}{x.TrackTime}").ToList();
|
||||
//根据标识符选出要删除的轨迹明细
|
||||
var deleteTracks = tracks.Where(x => ids.Contains($"{x.TrackCode}{x.TrackTime}")).ToList();
|
||||
|
||||
if (deleteTracks.Count == 0) return deleteTracks;
|
||||
|
||||
foreach (var track in deleteTracks)
|
||||
{
|
||||
await _trackDetailsEsRepository.DeleteTrackByIdAsync(track.Id, track.IndexName);
|
||||
}
|
||||
|
||||
orderIds = tracks.Select(m => m.OrderId).Distinct().ToList();
|
||||
tracks = deleteTracks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -163,8 +163,14 @@ public partial class TrackService : ApplicationService, ITrackService
|
||||
|
||||
//删除轨迹约束,只要其中有一条来源是外部的就立即返回错误
|
||||
var tracks = await _trackDetailsEsRepository
|
||||
.GetListAsync(new[] { orderId }, input.TrackCodes, TrackSourceEnum.ExternalServiceProvide);
|
||||
if (tracks.Count > 0)
|
||||
.GetListAsync(new[] { orderId },
|
||||
input.TrackIdentifiers.Select(x => x.TrackCode).ToList(),
|
||||
TrackSourceEnum.ExternalServiceProvide);
|
||||
|
||||
//当要删除的轨迹标识出现交叉则不允许删除
|
||||
var intersect = tracks.Select(x => $"{x.TrackCode}{x.TrackTime}")
|
||||
.Intersect(input.TrackIdentifiers.Select(y => $"{y.TrackCode}{y.TrackTime}")).ToList();
|
||||
if (intersect.Count > 0)
|
||||
{
|
||||
throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除");
|
||||
}
|
||||
@ -173,7 +179,7 @@ public partial class TrackService : ApplicationService, ITrackService
|
||||
var @event = new TrackDeleteEvent
|
||||
{
|
||||
OrderIds = new[] { orderId },
|
||||
TrackCodes = input.TrackCodes,
|
||||
TrackIdentifiers = input.TrackIdentifiers,
|
||||
SubSystemId = input.SubSystemId,
|
||||
OperationMan = name
|
||||
};
|
||||
@ -254,8 +260,14 @@ public partial class TrackService : ApplicationService, ITrackService
|
||||
|
||||
//删除轨迹约束,只要其中有一条来源是外部的就立即返回错误
|
||||
var tracks = await _trackDetailsEsRepository
|
||||
.GetListAsync(orderIds.ToArray(), input.TrackCodes, TrackSourceEnum.ExternalServiceProvide);
|
||||
if (tracks.Count > 0)
|
||||
.GetListAsync(orderIds.ToArray(),
|
||||
input.TrackIdentifiers.Select(x => x.TrackCode).ToList(),
|
||||
TrackSourceEnum.ExternalServiceProvide);
|
||||
|
||||
//当要删除的轨迹标识出现交叉则不允许删除
|
||||
var intersect = tracks.Select(x => $"{x.TrackCode}{x.TrackTime}")
|
||||
.Intersect(input.TrackIdentifiers.Select(y => $"{y.TrackCode}{y.TrackTime}")).ToList();
|
||||
if (intersect.Count > 0)
|
||||
{
|
||||
throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除");
|
||||
}
|
||||
@ -264,7 +276,7 @@ public partial class TrackService : ApplicationService, ITrackService
|
||||
var @event = new TrackDeleteEvent
|
||||
{
|
||||
OrderIds = orderIds.ToArray(),
|
||||
TrackCodes = input.TrackCodes,
|
||||
TrackIdentifiers = input.TrackIdentifiers,
|
||||
SubSystemId = input.SubSystemId,
|
||||
OperationMan = userInfo.Data.UserName,
|
||||
};
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using SJZY.Expand.ElasticSearch.Services;
|
||||
using SJZY.Track.Domain.Dtos.TrackContents;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
@ -23,7 +24,7 @@ public interface ITrackDetailsEsRepository : IElasticsearchClientService<TrackDe
|
||||
|
||||
Task<List<TrackDetailsIndex>> GetListAsync(int orderId);
|
||||
|
||||
Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds, List<string> trackCodes, TrackSourceEnum source);
|
||||
Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds, List<string> trackCodes, TrackSourceEnum? source);
|
||||
|
||||
Task<List<int>> DeleteTrackAsync(int[] orderIds, List<string> trackCodes);
|
||||
|
||||
|
||||
27
src/SJZY.Track.Domain/Dtos/TrackContents/TrackCodeMapVO.cs
Normal file
27
src/SJZY.Track.Domain/Dtos/TrackContents/TrackCodeMapVO.cs
Normal file
@ -0,0 +1,27 @@
|
||||
namespace SJZY.Track.Domain.Dtos.TrackContents;
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹代码映射
|
||||
/// </summary>
|
||||
public sealed class TrackCodeMapVO
|
||||
{
|
||||
/// <summary>
|
||||
/// 源子系统id
|
||||
/// </summary>
|
||||
public int SubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 源轨迹内容code
|
||||
/// </summary>
|
||||
public string TrackContentCode { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 映射子系统id
|
||||
/// </summary>
|
||||
public int MapSubSystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 映射轨迹内容code
|
||||
/// </summary>
|
||||
public string MapTrackContentCode { get; set; } = null!;
|
||||
}
|
||||
@ -18,6 +18,14 @@ public interface IProvideQueries
|
||||
/// <returns></returns>
|
||||
Task<List<string>> MapTrackCodesAsync(int upSubSystemId, int subSystemId, params string[] trackCodes);
|
||||
|
||||
/// <summary>
|
||||
/// 获取子系统内容Code映射
|
||||
/// </summary>
|
||||
/// <param name="upSubSystemId"></param>
|
||||
/// <param name="subSystemId"></param>
|
||||
/// <param name="trackCodes"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<TrackCodeMapVO>> GetTrackCodeMapsAsync(int upSubSystemId, int subSystemId, params string[] trackCodes);
|
||||
/// <summary>
|
||||
/// 根据订单模板找对应服务商
|
||||
/// </summary>
|
||||
|
||||
@ -33,6 +33,22 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<List<TrackCodeMapVO>> GetTrackCodeMapsAsync(int upSubSystemId, int subSystemId, params string[] trackCodes)
|
||||
{
|
||||
// 根据上游code得到下游code
|
||||
return await Context.Queryable<TrackContentMapEntity>()
|
||||
.Where(x => x.SubSystemId == subSystemId && x.MapSubSystemId == upSubSystemId &&
|
||||
trackCodes.Contains(x.MapTrackContentCode))
|
||||
.Select(x => new TrackCodeMapVO()
|
||||
{
|
||||
SubSystemId = x.SubSystemId,
|
||||
TrackContentCode = x.TrackContentCode,
|
||||
MapSubSystemId = x.MapSubSystemId,
|
||||
MapTrackContentCode = x.MapTrackContentCode
|
||||
})
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<OrderWithServiceProviderVO>> FindOrderWithServiceProviderAsync(int subSystemId,
|
||||
List<string> orderNos)
|
||||
@ -46,7 +62,7 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen
|
||||
.Select((a, b, c) => new OrderWithServiceProviderVO
|
||||
{
|
||||
//优先使用第三方的订单号,为空时才使用主单号
|
||||
OrderNo = b.OrderNo ?? a.OrderNo,
|
||||
OrderNo = b.OrderNo.IsNullOrWhiteSpace() ? a.OrderNo : b.OrderNo!,
|
||||
OrderType = a.OrderType,
|
||||
SubSystemId = a.SubSystemId,
|
||||
ServiceProviderCode = b.ServiceProviderCode,
|
||||
@ -67,7 +83,7 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen
|
||||
.Select((a, b) => new OrderWithServiceProviderVO
|
||||
{
|
||||
//优先使用第三方的订单号,为空时才使用主单号
|
||||
OrderNo = b.OrderNo ?? a.OrderNo,
|
||||
OrderNo = b.OrderNo.IsNullOrWhiteSpace() ? a.OrderNo : b.OrderNo!,
|
||||
OrderType = a.OrderType,
|
||||
SubSystemId = a.SubSystemId,
|
||||
ServiceProviderCode = b.ServiceProviderCode
|
||||
|
||||
@ -3,6 +3,7 @@ using SJZY.Expand.ABP.Core.PublicMethords;
|
||||
using SJZY.Expand.ElasticSearch.Services;
|
||||
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
|
||||
using SJZY.Track.Domain.Consts;
|
||||
using SJZY.Track.Domain.Dtos.TrackContents;
|
||||
using SJZY.Track.Domain.Enums;
|
||||
|
||||
namespace SJZY.Track.Repository.Repositories;
|
||||
@ -75,6 +76,8 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract<TrackDetail
|
||||
.Field(f => f.TrackTimeZone)
|
||||
.Field(f => f.OrderId)
|
||||
.Field(f => f.TrackCode)
|
||||
.Field(f => f.Id)
|
||||
.Field(f => f.IndexName)
|
||||
))
|
||||
.Query(q => q
|
||||
.Bool(b => b
|
||||
@ -99,6 +102,17 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract<TrackDetail
|
||||
.Sort(so => so
|
||||
.Field(f => f.ZeroTrackTime, SortOrder.Descending)
|
||||
)
|
||||
.Source(s2 => s2.Includes(fd2 => fd2
|
||||
.Field(f => f.TrackEnContent)
|
||||
.Field(f => f.TrackContent)
|
||||
.Field(f => f.TrackPlace)
|
||||
.Field(f => f.TrackTime)
|
||||
.Field(f => f.TrackTimeZone)
|
||||
.Field(f => f.OrderId)
|
||||
.Field(f => f.TrackCode)
|
||||
.Field(f => f.Id)
|
||||
.Field(f => f.IndexName)
|
||||
))
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -343,15 +357,26 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract<TrackDetail
|
||||
return r.ToIdList();
|
||||
}
|
||||
|
||||
public async Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds, List<string> trackCodes, TrackSourceEnum source)
|
||||
public async Task<List<TrackDetailsIndex>> GetListAsync(int[] orderIds, List<string> trackCodes, TrackSourceEnum? source)
|
||||
{
|
||||
var query = new QueryContainer();
|
||||
|
||||
if (orderIds.Length > 0)
|
||||
{
|
||||
query &= Query<TrackDetailsIndex>.Terms(t => t.Field(f => f.OrderId).Terms(orderIds));
|
||||
}
|
||||
if (trackCodes.Count > 0)
|
||||
{
|
||||
query &= Query<TrackDetailsIndex>.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes));
|
||||
}
|
||||
if (source.HasValue)
|
||||
{
|
||||
query &= Query<TrackDetailsIndex>.Term(t => t.Field(f => f.Source).Value(source.Value));
|
||||
}
|
||||
|
||||
var r = await Context.SearchAsync<TrackDetailsIndex>(x => x
|
||||
.Index(GlobalConst.TrackDetailsIndex)
|
||||
.Query(q =>
|
||||
q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds))
|
||||
&& q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))
|
||||
&& q.Term(t => t.Source, (int) source)
|
||||
)
|
||||
.Query(q => query)
|
||||
.Size(SafelyLimit)
|
||||
.Sort(s => s.Field(f => f.ZeroTrackTime, SortOrder.Descending)));
|
||||
|
||||
@ -474,5 +499,4 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract<TrackDetail
|
||||
|
||||
return res.Documents.FirstOrDefault();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user