diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackByEsIdInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackByEsIdInput.cs
new file mode 100644
index 00000000..681b3b75
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackByEsIdInput.cs
@@ -0,0 +1,13 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
+
+public class BatchDeleteTrackByEsIdInput
+{
+
+ ///
+ /// 轨迹内容es id,必填
+ ///
+ [MaxLength(500)]
+ public List TrackContentEsIds { get; set; } = new();
+}
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackChangeEto.cs b/src/SJZY.Track.Application.Contract/Events/TrackChangeEto.cs
index 9d3a0a49..e1559126 100644
--- a/src/SJZY.Track.Application.Contract/Events/TrackChangeEto.cs
+++ b/src/SJZY.Track.Application.Contract/Events/TrackChangeEto.cs
@@ -14,6 +14,11 @@ public class TrackChangeEto
///
public int SubSystemId { get; set; }
+ ///
+ /// 单号
+ ///
+ public string OrderNo { get; set; }
+
///
/// 客户id
///
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
index f395e972..7fba7153 100644
--- a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
+++ b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
@@ -7,6 +7,11 @@ public class TrackDeleteEvent
///
public int SubSystemId { get; set; }
+ ///
+ /// es中的id
+ ///
+ public string[] EsIds { get; set; }
+
///
/// 订单ids
///
diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs
index 127305ac..92ca0dee 100644
--- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs
+++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs
@@ -1,9 +1,14 @@
+using System.Text;
+using BSI.Stack.Rabbit;
using DotNetCore.CAP;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
+using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
+using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
+using SJZY.Track.Domain.Enums;
using SJZY.Track.Domain.Queries;
using Volo.Abp.DependencyInjection;
@@ -13,17 +18,26 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
{
private readonly ICapPublisher _capPublisher;
private readonly IOrderRepository _orderRepository;
+ private readonly ITrackStatusRepository _trackStatusRepository;
+ private readonly ITrackContentRepository _trackContentRepository;
private readonly IProvideQueries _provideQueries;
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
+ private readonly RabbitClientBus _rabbitClientBus;
public TrackDeleteEventHandler(IProvideQueries provideQueries,
IOrderRepository orderRepository, ICapPublisher capPublisher,
- ITrackDetailsEsRepository trackDetailsEsRepository)
+ ITrackDetailsEsRepository trackDetailsEsRepository,
+ RabbitClientBus rabbitClientBus,
+ ITrackStatusRepository trackStatusRepository,
+ ITrackContentRepository trackContentRepository)
{
_provideQueries = provideQueries;
_orderRepository = orderRepository;
_capPublisher = capPublisher;
_trackDetailsEsRepository = trackDetailsEsRepository;
+ _rabbitClientBus = rabbitClientBus;
+ _trackStatusRepository = trackStatusRepository;
+ _trackContentRepository = trackContentRepository;
}
[CapSubscribe(GlobalConst.TrackDeleteSubscribe, Group = GlobalConst.TrackDeleteSubscribe)]
@@ -31,7 +45,10 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
{
if (!CanDelete(@event)) return;
- await DeleteTrackAsync(@event);
+ var trackList = await DeleteTrackAsync(@event);
+
+ //发布事件
+ await PublicTrackTopicAsync(@event, trackList);
// 根据订单关联关系异步向下刷(异步)
await DownByOrderLink(@event);
@@ -84,12 +101,8 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
private bool CanDelete(TrackDeleteEvent @event)
{
- // 系统创建的轨迹不允许删除
- if (@event.Visited.IsNullOrEmpty() && @event.OperationMan == GlobalConst.SystemUser)
- {
- LogHelper.Warn($"系统创建的轨迹不允许被删除:{@event}", true);
- return false;
- }
+ if (@event.OrderIds == null)
+ return true;
// 订单循环关联检测
var dup = @event.Visited.Intersect(@event.OrderIds).ToArray();
@@ -102,14 +115,79 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
return true;
}
- private async Task DeleteTrackAsync(TrackDeleteEvent @event)
+ private async Task PublicTrackTopicAsync(TrackDeleteEvent eto, List trackList)
{
- // 删除轨迹(删的是同子系统下的单,所以code是统一的)
- var tracks = await _trackDetailsEsRepository.GetLatestListAsync(@event.OrderIds, @event.TrackCodes);
+ if (trackList == null)
+ return;
- var orderIds = await _trackDetailsEsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes);
+ var statusList = await _trackStatusRepository.GetListAsync(m => m.SubSystemId == eto.SubSystemId);
+ if (statusList == null)
+ return;
+
+ var contentList = await _trackContentRepository.GetTrackContentBySyetemIdAsync(eto.SubSystemId);
+ if (contentList == null)
+ return;
+
+ foreach (var dataItem in trackList.GroupBy(m => new
+ {
+ m.TrackCode,
+ m.OrderNo
+ }))
+ {
+ var item = dataItem.First();
+ var status = statusList.FirstOrDefault(m => m.Code == item.TrackStatusCode);
+ if (status == null || !status.IsToMq)
+ continue;
+
+ var content = contentList.FirstOrDefault(m => m.TrackContentCode == item.TrackCode);
+
+ var data = new TrackChangeEto()
+ {
+ OrderIdentifiers = dataItem.Select(m => new OrderIdentifier
+ {
+ OrderId = m.OrderId,
+ OrderNo = m.OrderNo,
+ OrderType = m.OrderType
+ }).ToArray(),
+ TrackStatusCode = item.TrackStatusCode,
+ TrackCode = item.TrackCode,
+ OperationMan = eto.OperationMan,
+ SubSystemId = eto.SubSystemId,
+ Option = 2
+ };
+
+ _rabbitClientBus.Publish(GlobalConst.TrackChangeExchange, $"TrackChange.{content.SubSystemCode}", Encoding.UTF8.GetBytes(data.ToJson()));
+ }
+ }
+
+ private async Task> DeleteTrackAsync(TrackDeleteEvent @event)
+ {
+ List orderIds;
+ List tracks;
+ if (@event.EsIds != null && @event.EsIds.Any()) //根据明确的esid进行删除
+ {
+ tracks = await _trackDetailsEsRepository.GetDataByIds(@event.EsIds);
+ orderIds = tracks.Select(m => m.OrderId).Distinct().ToList();
+
+ // 外部api获取的轨迹不允许删除
+ if (tracks.Any(m => m.Source == TrackSourceEnum.ExternalServiceProvide.GetHashCode()))
+ return tracks;
+
+ // 删除轨迹
+ foreach (var item in tracks)
+ {
+ await _trackDetailsEsRepository.DeleteTrackByIdAsync(item.Id, item.IndexName);
+ }
+ }
+ else //原有逻辑,根据轨迹code和订单进行删除
+ {
+ // 删除轨迹(删的是同子系统下的单,所以code是统一的)
+ tracks = await _trackDetailsEsRepository.GetLatestListAsync(@event.OrderIds, @event.TrackCodes);
+
+ orderIds = await _trackDetailsEsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes);
+ if (orderIds.Count == 0) return tracks;
+ }
- if (orderIds.Count == 0) return;
var orders = await _orderRepository.GetListAsync(x => orderIds.Contains(x.Id),
x => new OrderEntity
@@ -121,8 +199,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
LatestTrackTime = x.LatestTrackTime,
LatestTrackTimeZone = x.LatestTrackTimeZone,
});
-
- if (orders.Count == 0) return;
+ if (orders.Count == 0) return tracks;
foreach (var order in orders)
{
@@ -157,5 +234,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
x.LatestTrackTime,
x.LatestTrackTimeZone
});
+
+ return tracks;
}
}
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
index 07859810..ce0c265e 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
@@ -43,6 +43,8 @@ public partial class OrderService : ApplicationService, IOrderService
throw new BusinessException(message: "【目的地时区】和【预计到达时间】必须同时输入");
}
+ var currentUser = CurrentUserRequest.CurrentUser;
+
// 校验订单是否已存在,存在则更新
var order = await _orderRepository.GetFirstAsync(x =>
x.SubSystemId == input.SubSystemId && x.OrderType == input.OrderType && x.OrderNo == input.OrderNo);
@@ -55,8 +57,10 @@ public partial class OrderService : ApplicationService, IOrderService
{
OrderId = order.Id,
OrderNo = input.OrderNo,
- OptionType = OptionType.修改.ToString(),
+ OptionType = OrderOperationType.修改订单.ToString(),
Content = input.ToJson(),
+ CreateUserId = currentUser.UserId,
+ CreateUserString = currentUser.Name,
};
_ = _orderOperationRecordEsRepository.AddAsync(index);
@@ -71,18 +75,20 @@ public partial class OrderService : ApplicationService, IOrderService
order.SubSystemId = input.SubSystemId;
order.OrderFlights = ObjectMapper.Map, List>(input.FlightInfos);
order.OrderPullStatus = BuiltOrderPullStatus(input.PullConfigInfos);
- order.OrderPlatformNumbers = BuiltOrderPlatformNumbers(input.PullConfigInfos);
+ order.OrderPlatformNumbers = BuiltOrderPlatformNumbers(input.PullConfigInfos);
var orderId = await _orderRepository.CreateOrderAsync(order);
// 写入操作日志
+
var indexForAdd = new OrderOperationRecordIndex
{
OrderId = orderId,
OrderNo = input.OrderNo,
- OptionType = OptionType.新增.ToString(),
+ OptionType = OrderOperationType.创建订单.ToString(),
Content = input.ToJson(),
- CreateUserId = CurrentUserRequest.CurrentUser.UserId,
+ CreateUserId = currentUser.UserId,
+ CreateUserString = currentUser.Name,
CreateTime = DateTime.Now
};
_ = _orderOperationRecordEsRepository.AddAsync(indexForAdd);
@@ -156,7 +162,8 @@ public partial class OrderService : ApplicationService, IOrderService
return status;
}).ToList();
}
- private List BuiltOrderPlatformNumbers(List? pullConfigInfos)
+
+ private List BuiltOrderPlatformNumbers(List? pullConfigInfos)
{
if (pullConfigInfos == null) return new List();
@@ -165,9 +172,9 @@ public partial class OrderService : ApplicationService, IOrderService
var status = new OrderPlatformNumberEntity
{
//三方单号
- OrderNumber = x.OrderNo,
- //三方平台名称,目前认为是服务商code
- Platform = x.ServiceCode,
+ OrderNumber = x.OrderNo,
+ //三方平台名称,目前认为是服务商code
+ Platform = x.ServiceCode,
};
return status;
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
index 37a6e394..a1d373f0 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
@@ -175,6 +175,42 @@ public partial class TrackService : ApplicationService, ITrackService
return new UnifyResultDto(true, true);
}
+ ///
+ /// 根据esid删除轨迹内容
+ ///
+ ///
+ ///
+ [HttpPost("Track/BatchDeleteByEsId")]
+ public async Task BatchDeleteTrackByEsIdAsync(BatchDeleteTrackByEsIdInput input)
+ {
+ var tracks = await _trackDetailsEsRepository.GetDataByIds(input.TrackContentEsIds.ToArray());
+ if (tracks == null || tracks.Count == 0)
+ return new UnifyResultDto(false, "未找到指定id下的轨迹内容");
+
+ if (tracks.Any(m => m.Source == TrackSourceEnum.ExternalServiceProvide.GetHashCode()))
+ return new UnifyResultDto(false, "存在来源于外部服务商的轨迹,不允许删除");
+
+ if (tracks.GroupBy(m => m.SubSystemId).Count() > 1)
+ return new UnifyResultDto(false, "暂不支持跨子系统批量删除");
+
+ // 获取用户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
+ {
+ EsIds = input.TrackContentEsIds.ToArray(),
+ SubSystemId = tracks.First().SubSystemId,
+ OperationMan = userInfo.Data.UserName,
+ };
+ await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, @event);
+
+ return new UnifyResultDto(true);
+ }
///
/// 批量删除轨迹
@@ -217,7 +253,7 @@ public partial class TrackService : ApplicationService, ITrackService
OrderIds = orderIds.ToArray(),
TrackCodes = input.TrackCodes,
SubSystemId = input.SubSystemId,
- OperationMan = userInfo.Data.UserName
+ OperationMan = userInfo.Data.UserName,
};
await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, @event);
diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderOperationRecordIndex.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderOperationRecordIndex.cs
index cedba47d..df044ff6 100644
--- a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderOperationRecordIndex.cs
+++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderOperationRecordIndex.cs
@@ -40,8 +40,22 @@ public class OrderOperationRecordIndex : IdBaseIndex
///
public int CreateUserId { get; set; }
+ ///
+ /// 创建人姓名
+ ///
+ public string CreateUserString { get; set; }
+
///
/// 创建时间
///
public DateTime CreateTime { get; set; }
}
+
+public enum OrderOperationType
+{
+ 创建订单 = 1,
+ 修改订单 = 2,
+ 创建轨迹 = 3,
+ 修改轨迹 = 4,
+ 删除轨迹 = 5
+}
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs
index b321e87b..fe3a81d7 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs
@@ -28,4 +28,5 @@ public interface ITrackContentRepository : IBasicRepository
Task GetTemplateIsExist(int trackContentId);
Task GetByCodeAsync(int systemId, string code);
Task> GetListBySystemIdAsync(int systemId);
+ Task> GetTrackContentBySyetemIdAsync(int subSystemId);
}
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs
index f68269ff..a8da5185 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs
@@ -28,4 +28,5 @@ public interface ITrackDetailsEsRepository : IElasticsearchClientService> DeleteTrackAsync(int[] orderIds, List trackCodes);
Task DeleteTrackByIdAsync(string id, string indexName);
+ Task> GetDataByIds(string[] ids);
}
diff --git a/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs b/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs
index f084b0a8..8b7cdf3f 100644
--- a/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs
+++ b/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs
@@ -56,4 +56,9 @@ public class TrackContentVO
/// 是否广播
///
public bool IsToMq { get; set; }
+
+ ///
+ /// 轨迹内容code
+ ///
+ public string TrackContentCode { get; set; }
}
diff --git a/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs
index 6ce6a15c..d619613b 100644
--- a/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs
@@ -248,4 +248,27 @@ public class TrackContentRepository : BasicRepository, ITrac
})
.ToListAsync();
}
+
+ public Task> GetTrackContentBySyetemIdAsync(int subSystemId)
+ {
+ return Context.Queryable()
+ .LeftJoin((x, y) => x.TrackStatusId == y.Id)
+ .LeftJoin((x, y, z) => x.SubSystemId == z.Id)
+ .Where(x => x.SubSystemId == subSystemId)
+ .Select((x, y, z) => new TrackContentVO
+ {
+ SubSystemCode = z.Key,
+ TrackStatusId = x.TrackStatusId,
+ TrackStatus = y.Status,
+ TrackStatusCode = y.Code,
+ TrackContent = x.Content,
+ TrackContentCode = x.Code,
+ TrackEnContent = x.EnContent,
+ IsCompleted = y.IsCompleted,
+ IsRepeatable = x.IsRepeatable,
+ IsAllowManuallyUpdate = x.IsAllowManuallyUpdate,
+ IsAllowManuallyCreate = x.IsAllowManuallyCreate,
+ IsToMq = y.IsToMq,
+ }).ToListAsync();
+ }
}
diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs
index 014c0c45..beb8dc0a 100644
--- a/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs
@@ -408,6 +408,7 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract x.OrderId).ToList();
}
+
public async Task DeleteTrackByIdAsync(string id, string indexName)
{
var r = await Context.DeleteAsync(id, u => u
@@ -419,4 +420,15 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract> GetDataByIds(string[] ids)
+ {
+ var res = await Context.SearchAsync(m => m
+ .Index(GlobalConst.TrackDetailsIndex)
+ .Query(
+ q => q.Ids(i => i.Values(ids))
+ ));
+
+ return res.ToIdList();
+ }
}