diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs
index 7d8d79c0..0e318811 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/DeleteOrderInput.cs
@@ -2,4 +2,12 @@
public class DeleteOrderInput : OrderNoInfo
{
+}
+
+public class DeleteTrackInput : OrderNoInfo
+{
+ ///
+ /// 轨迹code
+ ///
+ public List TrackCodes { get; set; } = new();
}
\ No newline at end of file
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
new file mode 100644
index 00000000..c88d5837
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
@@ -0,0 +1,24 @@
+namespace SJZY.Track.Application.Contract.Events;
+
+public class TrackDeleteEvent
+{
+ ///
+ /// 订单id
+ ///
+ public int OrderId { get; set; }
+
+ ///
+ /// 轨迹代码
+ ///
+ public List TrackCodes { get; set; } = null!;
+
+ ///
+ /// 子系统id
+ ///
+ public int SubSystemId { get; set; }
+
+ ///
+ /// 上游子系统id
+ ///
+ public int UpSubSystemId { get; set; }
+}
\ No newline at end of file
diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs
new file mode 100644
index 00000000..d4e48a10
--- /dev/null
+++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs
@@ -0,0 +1,67 @@
+using DotNetCore.CAP;
+using SJZY.Expand.ABP.Core.PublicMethords;
+using SJZY.Track.Application.Contract.Events;
+using SJZY.Track.Domain.Aggregates.OrderAggregate;
+using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
+using SJZY.Track.Domain.Queries;
+using Volo.Abp.DependencyInjection;
+
+namespace SJZY.Track.Application.EventHandlers;
+
+public class TrackDeleteEventHandler: ITransientDependency, ICapSubscribe
+{
+ private readonly IOrderRepository _orderRepository;
+ private readonly IProvideQueries _provideQueries;
+ private readonly ITrackDetailsRepository _trackDetailsRepository;
+ private readonly ICapPublisher _capPublisher;
+
+ public TrackDeleteEventHandler(IProvideQueries provideQueries, ITrackDetailsRepository trackDetailsRepository, IOrderRepository orderRepository, ICapPublisher capPublisher)
+ {
+ _provideQueries = provideQueries;
+ _trackDetailsRepository = trackDetailsRepository;
+ _orderRepository = orderRepository;
+ _capPublisher = capPublisher;
+ }
+
+ [CapSubscribe(GlobalConst.TrackUpsertSubscribe)]
+ public async Task ConsumerAsync(TrackDeleteEvent @event)
+ {
+ // 不同子系统需要做内容映射
+ if (@event.UpSubSystemId != 0 && @event.UpSubSystemId != @event.SubSystemId)
+ {
+ var mapCodes = await _provideQueries
+ .MapTrackCodesAsync(@event.UpSubSystemId, @event.SubSystemId, @event.TrackCodes.ToArray());
+
+ if (mapCodes.Count == 0)
+ {
+ //throw new BusinessException(message: "订单跨子系统,未配置内容映射,请联系管理员");
+ return;
+ }
+
+ @event.TrackCodes = mapCodes;
+ }
+
+ await DeleteTrackAsync(@event);
+ }
+
+ private async Task DeleteTrackAsync(TrackDeleteEvent @event)
+ {
+ // 删除轨迹
+ await _trackDetailsRepository.DeleteTrackAsync(@event.OrderId, @event.TrackCodes);
+
+ // 根据订单关联关系异步向下刷
+ var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderId);
+ foreach (var linkedOrder in linkedOrders)
+ {
+ var nextEvent = new TrackDeleteEvent
+ {
+ OrderId = linkedOrder.OrderId,
+ TrackCodes = @event.TrackCodes,
+ SubSystemId = linkedOrder.SubSystemId,
+ UpSubSystemId = @event.SubSystemId
+ };
+
+ await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, nextEvent);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs
index f354d19b..d8e480ef 100644
--- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs
+++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs
@@ -33,10 +33,11 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
public async Task ConsumerAsync(TrackUpsertEvent @event)
{
// 不同子系统需要做内容映射
- if (@event.UpSubSystemId != @event.SubSystemId)
+ if (@event.UpSubSystemId != 0 && @event.UpSubSystemId != @event.SubSystemId)
{
- var mapCode = await _provideQueries
- .MapTrackContentCodeAsync(@event.UpSubSystemId, @event.SubSystemId, @event.TrackCode);
+ var mapCode = (await _provideQueries
+ .MapTrackCodesAsync(@event.UpSubSystemId, @event.SubSystemId, @event.TrackCode))
+ .FirstOrDefault();
if (mapCode == default)
{
@@ -50,7 +51,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
await UpsertTrackAsync(@event);
}
- internal async Task UpsertTrackAsync(TrackUpsertEvent @event)
+ private async Task UpsertTrackAsync(TrackUpsertEvent @event)
{
// 不存在则新增轨迹,存在则更新
var track = await _trackDetailsRepository.GetFirstOrDefaultAsync(@event.OrderId, @event.TrackCode);
@@ -65,6 +66,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
//throw new BusinessException(message: $"订单:{@event.OrderNo} 所绑定的模板,没有一条内容可以匹配轨迹代码:{@event.TrackCode}");
return;
}
+
orderIsCompleted = trackContent.IsCompleted;
track = new TrackDetailsIndex
@@ -82,7 +84,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
CreateUser = CurrentUserRequest.CurrentUser.Name,
CreateTime = DateTime.Now
};
-
+
// todo:推送只做新增的,更新和删除的不做先
if (!@event.IsPushCompleted && await _trackPushCacheService.IsPushAsync(@event.CustomId))
{
@@ -99,7 +101,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
}
await _trackDetailsRepository.UpsertAsync(track);
-
+
// 触发订单主表更新事件
await _capPublisher.PublishAsync(GlobalConst.UpdateOrderTrackSubscribe, new UpdateOrderTrackEvent
{
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
index 0f5fa583..007e06d0 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
@@ -16,11 +16,11 @@ public class OrderService : ApplicationService
private readonly ITrackDetailsRepository _trackDetailsRepository;
public OrderService(IOrderRepository orderRepository,
- ITrackDetailsRepository trackDetailsRepository
- )
+ ITrackDetailsRepository trackDetailsRepository
+ )
{
_orderRepository = orderRepository;
- this._trackDetailsRepository=trackDetailsRepository;
+ _trackDetailsRepository = trackDetailsRepository;
}
///
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
index dacb87fe..9fdbb37e 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
@@ -1,7 +1,8 @@
-using SJZY.Track.Application.Contract.Dtos.ProvideServices;
+using DotNetCore.CAP;
+using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Events;
-using SJZY.Track.Application.EventHandlers;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
+using SJZY.Track.Domain.Queries;
namespace SJZY.Track.Application.Services.ProvideServices;
@@ -12,12 +13,14 @@ namespace SJZY.Track.Application.Services.ProvideServices;
public class TrackService : ApplicationService
{
private readonly IOrderRepository _orderRepository;
- private readonly TrackUpsertEventHandler _trackUpsertEventHandler;
+ private readonly IProvideQueries _provideQueries;
+ private readonly ICapPublisher _capPublisher;
- public TrackService(IOrderRepository orderRepository, TrackUpsertEventHandler trackUpsertEventHandler)
+ public TrackService(IOrderRepository orderRepository, IProvideQueries provideQueries, ICapPublisher capPublisher)
{
_orderRepository = orderRepository;
- _trackUpsertEventHandler = trackUpsertEventHandler;
+ _provideQueries = provideQueries;
+ _capPublisher = capPublisher;
}
///
@@ -45,7 +48,45 @@ public class TrackService : ApplicationService
@event.SubSystemId = order.SubSystemId;
@event.IsPushCompleted = order.IsPushCompleted;
@event.CustomId = order.CustomId;
- await _trackUpsertEventHandler.UpsertTrackAsync(@event);
+ await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event);
+ return true;
+ }
+
+ ///
+ /// 删除轨迹
+ ///
+ ///
+ ///
+ ///
+ [HttpPost("Track/Delete")]
+ public async Task DeleteTrackAsync(DeleteTrackInput input)
+ {
+ var order = await _orderRepository.GetFirstAsync(x =>
+ x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => new
+ {
+ x.Id, x.SubSystemId, x.IsPushCompleted, x.CustomId
+ });
+ if (order == default)
+ {
+ throw new BusinessException(message: $"订单:{input.OrderNo}不存在");
+ }
+
+ var codes = await _provideQueries.GetCanDeleteTrackCodesAsync(order.Id, input.TrackCodes);
+
+ if (codes.Count == 0)
+ {
+ throw new BusinessException(message: "没有一个轨迹代码是可删的");
+ }
+
+ // 删除轨迹
+ var @event = new TrackDeleteEvent
+ {
+ OrderId = order.Id,
+ TrackCodes = codes,
+ SubSystemId = order.SubSystemId,
+ };
+ await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event);
+
return true;
}
}
\ No newline at end of file
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs
index 3ab152d1..185f0874 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs
@@ -4,7 +4,7 @@ namespace SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
public interface ITrackDetailsRepository
{
- Task GetFirstOrDefaultAsync(int orderId, string inputTrackCode);
+ Task GetFirstOrDefaultAsync(int orderId, string trackCode);
Task UpsertAsync(TrackDetailsIndex index);
@@ -12,4 +12,12 @@ public interface ITrackDetailsRepository
Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input);
Task> GetListAsync(int orderId);
+
+ ///
+ /// 删除轨迹
+ ///
+ ///
+ ///
+ ///
+ Task DeleteTrackAsync(int orderId, List trackCodes);
}
\ No newline at end of file
diff --git a/src/SJZY.Track.Domain/Dtos/TrackDetails/MatchTrackContentsDto.cs b/src/SJZY.Track.Domain/Dtos/TrackDetails/MatchTrackContentsDto.cs
new file mode 100644
index 00000000..14441bc6
--- /dev/null
+++ b/src/SJZY.Track.Domain/Dtos/TrackDetails/MatchTrackContentsDto.cs
@@ -0,0 +1,14 @@
+namespace SJZY.Track.Domain.Dtos.TrackDetails;
+
+public class MatchTrackContentsDto
+{
+ ///
+ /// 轨迹代码
+ ///
+ public string TrackCode { get; set; } = null!;
+
+ ///
+ /// 是否支持删除
+ ///
+ public bool IsCanDelete { get; set; }
+}
\ No newline at end of file
diff --git a/src/SJZY.Track.Domain/GlobalConst.cs b/src/SJZY.Track.Domain/GlobalConst.cs
index 023db1aa..92545ea9 100644
--- a/src/SJZY.Track.Domain/GlobalConst.cs
+++ b/src/SJZY.Track.Domain/GlobalConst.cs
@@ -11,6 +11,11 @@ public class GlobalConst
/// 轨迹新增/更新 mq订阅名称
///
public const string TrackUpsertSubscribe = "SJZY.Track.TrackUpsert";
+
+ ///
+ /// 轨迹删除 mq订阅名称
+ ///
+ public const string TrackDeleteSubscribe = "SJZY.Track.TrackDelete";
///
/// 接口通批量轨迹刷新订阅
diff --git a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs
index 7814e949..9c17d1d4 100644
--- a/src/SJZY.Track.Domain/Queries/IProvideQueries.cs
+++ b/src/SJZY.Track.Domain/Queries/IProvideQueries.cs
@@ -32,15 +32,23 @@ public interface IProvideQueries
/// 轨迹代码
///
Task MatchTrackContentAsync(int orderId, string code);
+
+ ///
+ /// 获取可删除的订单轨迹代码
+ ///
+ ///
+ ///
+ ///
+ Task> GetCanDeleteTrackCodesAsync(int orderId, List trackCodes);
///
/// 根据子系统内容映射,得到映射后的轨迹code
///
///
///
- ///
+ ///
///
- Task MapTrackContentCodeAsync(int upSubSystemId, int subSystemId, string trackCode);
+ Task> MapTrackCodesAsync(int upSubSystemId, int subSystemId, params string[] trackCodes);
///
/// 获取服务商模板配置
diff --git a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs
index 0cb54b99..064f9445 100644
--- a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs
+++ b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs
@@ -70,7 +70,7 @@ public class ProvideQueries : ISugarRepository, IProvideQueries,
.LeftJoin((x, a, b, c) => b.TrackStatusId == c.Id)
.LeftJoin((x, a, b, c, d) => b.TrackFlagId == d.Id)
.Where((x, a, b) => x.OrderId == orderId && b.Code == code)
- .Select((x, a, b, c,d) => new MatchTrackContentDto
+ .Select((x, a, b, c, d) => new MatchTrackContentDto
{
Content = b.Content,
EnContent = b.EnContent,
@@ -80,13 +80,24 @@ public class ProvideQueries : ISugarRepository, IProvideQueries,
.FirstAsync();
}
- public async Task MapTrackContentCodeAsync(int upSubSystemId, int subSystemId, string trackCode)
+ public async Task> GetCanDeleteTrackCodesAsync(int orderId, List trackCodes)
+ {
+ return await Context.Queryable()
+ .LeftJoin((x, a) => x.TrackTemplateId == a.TrackTemplateId && a.IsCanDelete)
+ .LeftJoin((x, a, b) => a.TrackContentId == b.Id)
+ .Where((x, a, b) => x.OrderId == orderId
+ && trackCodes.Contains(b.Code))
+ .Select((x, a, b) => b.Code)
+ .ToListAsync();
+ }
+
+ public async Task> MapTrackCodesAsync(int upSubSystemId, int subSystemId, params string[] trackCodes)
{
return await Context.Queryable()
.Where(x => x.SubSystemId == upSubSystemId && x.MapSubSystemId == subSystemId &&
- x.TrackContentCode == trackCode)
+ trackCodes.Contains(x.TrackContentCode))
.Select(x => x.MapTrackContentCode)
- .FirstAsync();
+ .ToListAsync();
}
public async Task> GetPullContentConfigsAsync(int serviceProviderId)
diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs
index c0ca92e4..590cb749 100644
--- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs
@@ -22,6 +22,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract
q.Term(t => t.Field(f => f.OrderId).Value(orderId))
&& q.Term(t => t.Field(f => f.TrackCode).Value(trackCode))
+ && q.Term(t => t.Field(f => f.IsDeleted).Value(true))
)
);
@@ -39,7 +40,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract t
.Field(f => f.OrderNo)
.Terms(orderNos))
- && q.Term(f => f.OrderType, orderType))
+ && q.Term(f => f.OrderType, orderType)
+ && q.Term(t => t.Field(f => f.IsDeleted).Value(true))
+ )
);
return data.Documents.ToList();
@@ -71,18 +74,34 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract> GetListAsync(int orderId)
{
var data = await Context.SearchAsync(x => x
- .Source(s => s.Includes(fd => fd
- .Field(f => f.TrackStatus)
- .Field(f => f.TrackCode)
- .Field(f => f.TrackContent)
- .Field(f => f.TrackPlace)
- .Field(f => f.TrackTime)
- .Field(f => f.TraceTimeZone)
- )).Query(q => q.Terms(t => t.Field(f => f.OrderId).Terms(orderId))));
+ .Source(s => s.Includes(fd => fd
+ .Field(f => f.TrackStatus)
+ .Field(f => f.TrackCode)
+ .Field(f => f.TrackContent)
+ .Field(f => f.TrackPlace)
+ .Field(f => f.TrackTime)
+ .Field(f => f.TraceTimeZone)
+ )).Query(q =>
+ q.Terms(t => t.Field(f => f.OrderId).Terms(orderId))
+ && q.Term(t => t.Field(f => f.IsDeleted).Value(true))
+ )
+ );
return data?.Documents?.ToList();
}
+ public async Task DeleteTrackAsync(int orderId, List trackCodes)
+ {
+ await Context.UpdateByQueryAsync(x => x
+ .Query(
+ q =>
+ q.Term(t => t.OrderId, orderId)
+ && q.Terms(t => t.Field(f => f.TrackCode).Terms(trackCodes)))
+ .Script(s => s
+ .Source("ctx._source.IsDeleted = true"))
+ );
+ }
+
public async Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input)
{
if (input.OrderNos.Count < 1) return default;
@@ -91,9 +110,12 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract 500 ? 500 : input.PageSize;
var data = await Context.SearchAsync(x => x
- .Query(q => q.Terms(t => t
- .Field(f => f.OrderNo)
- .Terms(distinctOrderNumbers)))
+ .Query(q =>
+ q.Terms(t => t
+ .Field(f => f.OrderNo)
+ .Terms(distinctOrderNumbers))
+ && q.Term(t => t.Field(f => f.IsDeleted).Value(true))
+ )
.Sort(s => s.Field(f => f.CreateTime, SortOrder.Descending))
.From((input.PageIndex - 1) * input.PageSize)
.Size(finalSize)