diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackInput.cs index 5616f912..0a79e008 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackInput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackInput.cs @@ -2,21 +2,8 @@ namespace SJZY.Track.Application.Contract.Dtos.ProvideServices; -public class BatchDeleteTrackInput +public class BatchDeleteTrackInput : OrderNosInfo { - /// - /// 订单类型,必填 - /// - [Required] - [Range(1, int.MaxValue)] - public int OrderType { get; set; } - - /// - /// 订单号,必填 - /// - [Required] - public List OrderNos { get; set; } = new(); - /// /// 轨迹code,必填 /// diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs new file mode 100644 index 00000000..fa5d3880 --- /dev/null +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs @@ -0,0 +1,33 @@ +using System.ComponentModel.DataAnnotations; + +namespace SJZY.Track.Application.Contract.Dtos.ProvideServices; + +public class BatchUpsertTrackInput : OrderNosInfo +{ + /// + /// 轨迹内容代码 + /// + [Required] + [MaxLength(50)] + public string TrackCode { get; set; } = null!; + + /// + /// 轨迹发生地 + /// + [Required] + [MaxLength(200)] + public string TrackPlace { get; set; } = null!; + + /// + /// 轨迹发生时间 + /// + [Required] + public DateTime? TrackTime { get; set; } + + /// + /// 轨迹发生时区 + /// + [Required] + [Range(-12, 12)] + public float? TrackTimeZone { get; set; } +} \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetPageTrackOrderInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetPageTrackOrderInput.cs index 26e2e776..c6a143df 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetPageTrackOrderInput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetPageTrackOrderInput.cs @@ -17,6 +17,11 @@ public class GetPageTrackOrderInput : PageInfoInput /// public string? OrderNos { get; set; } + /// + /// tab标签类型 0 全部, 1 异常 2 预警 + /// + public int TabType { get; set; } + /// /// 订单类型 /// @@ -27,6 +32,11 @@ public class GetPageTrackOrderInput : PageInfoInput /// public int? CustomerId { get; set; } + ///// + ///// 当tab选中 0 默认不传 1 直接写死传值 [1,4] 2 传 [2,4] + ///// + //public List? QuestionTypeIds { get; set; } + /// /// 创建时间开始 /// @@ -128,5 +138,28 @@ public class TrackOrderDto /// public string SubSystem { get; set; } + /// + /// 子系统id + /// public int SubSystemId { get; set; } + + /// + /// 问题类型(主数据枚举TrackQuestionType) + /// + public int QuestionType { get; set; } + + /// + /// 问题类型名称 + /// + public string? QuestionTypeName { get; set; } + + /// + /// 问题描述(主数据枚举TrackProblemDescription) + /// + public int ProblemDescription { get; set; } + + /// + /// 问题描述名称 + /// + public string? ProblemDescriptionName { get; set; } } \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetTrackInput.cs index 598ee759..8fa3dec0 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetTrackInput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetTrackInput.cs @@ -2,20 +2,8 @@ using System.ComponentModel.DataAnnotations; namespace SJZY.Track.Application.Contract.Dtos.ProvideServices; -public class GetTrackInput +public class GetTrackInput : OrderNosInfo { - /// - /// 订单类型 - /// - [Required] - [Range(1, int.MaxValue)] - public int OrderType { get; set; } - - /// - /// 订单号 - /// - public List OrderNos { get; set; } = new(); - /// /// 时区 +8 +8.25 -8.5 -9 /// 不传默认+8 diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/OrderNoInfo.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/OrderNoInfo.cs index eda65e4a..3ec49a17 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/OrderNoInfo.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/OrderNoInfo.cs @@ -17,4 +17,20 @@ public class OrderNoInfo [Required] [MaxLength(100)] public string OrderNo { get; set; } = null!; +} + +public class OrderNosInfo +{ + /// + /// 订单类型 + /// + [Required] + [Range(1, int.MaxValue)] + public int OrderType { get; set; } + + /// + /// 订单号 + /// + [Required] + public List OrderNos { get; set; } = new(); } \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs index b62cf77b..8248c8e0 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs @@ -30,18 +30,4 @@ public class UpsertTrackInput : OrderNoInfo [Required] [Range(-12, 12)] public float? TrackTimeZone { get; set; } -} - -public class NotNullAttribute : ValidationAttribute -{ - protected override ValidationResult IsValid(object value, ValidationContext validationContext) - { - if (value == null) - { - return new ValidationResult(ErrorMessage ?? "The field is required.", - new[] { validationContext.MemberName }); - } - - return ValidationResult.Success; - } } \ No newline at end of file diff --git a/src/SJZY.Track.Application.Contract/Events/UpdateOrderTrackEvent.cs b/src/SJZY.Track.Application.Contract/Events/UpdateOrderTrackEvent.cs index f04cd86c..779415e2 100644 --- a/src/SJZY.Track.Application.Contract/Events/UpdateOrderTrackEvent.cs +++ b/src/SJZY.Track.Application.Contract/Events/UpdateOrderTrackEvent.cs @@ -7,11 +7,16 @@ public class UpdateOrderTrackEvent /// public int OrderId { get; set; } + /// + /// 是否删除引起的更新 + /// + public bool IsDelete { get; set; } + /// /// 此次发生的轨迹是否意味完成 /// public bool IsCompleted { get; set; } - + /// /// 轨迹内容 /// @@ -21,7 +26,7 @@ public class UpdateOrderTrackEvent /// 轨迹内容英文 /// public string TrackEnContent { get; set; } = null!; - + /// /// 轨迹发生地 /// @@ -31,7 +36,7 @@ public class UpdateOrderTrackEvent /// 轨迹发生时间 /// public DateTime TrackTime { get; set; } - + /// /// 轨迹时区 /// diff --git a/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj b/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj index 041d97e2..f13ee0b2 100644 --- a/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj +++ b/src/SJZY.Track.Application.Contract/SJZY.Track.Application.Contract.csproj @@ -4,6 +4,7 @@ net7.0 + True 1.0.0 True diff --git a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs index 55bb5b1d..1994118d 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackDeleteEventHandler.cs @@ -29,7 +29,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe { if (@event.Visited.Contains(@event.OrderId)) { - LogHelper.Error($"轨迹订单循环依赖预警:{@event.Visited.JoinAsString(",")}"); + LogHelper.Error($"删除轨迹订单时,发现循环依赖:{@event.Visited.JoinAsString(",")}"); return; } @@ -56,7 +56,30 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe private async Task DeleteTrackAsync(TrackDeleteEvent @event) { // 删除轨迹 - await _trackDetailsRepository.DeleteTrackAsync(@event.OrderId, @event.TrackCodes); + var isOk = await _trackDetailsRepository.DeleteTrackAsync(@event.OrderId, @event.TrackCodes); + + // 触发订单主表更新事件 + if (isOk) + { + var track = await _trackDetailsRepository.GetLatestAsync(@event.OrderId); + var updateOrderEvent = track == default + ? new UpdateOrderTrackEvent + { + OrderId = @event.OrderId, + IsDelete = true + } + : new UpdateOrderTrackEvent + { + OrderId = @event.OrderId, + IsCompleted = track.IsCompleted, + TrackContent = track.TrackContent, + TrackEnContent = track.TrackEnContent, + TrackPlace = track.TrackPlace, + TrackTime = track.TrackTime, + TrackTimeZone = track.TrackTimeZone + }; + await _capPublisher.PublishAsync(GlobalConst.UpdateOrderTrackSubscribe, updateOrderEvent); + } // 根据订单关联关系异步向下刷 var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderId); diff --git a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs index 50cabb23..e898fcf7 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackRefreshEventHandler.cs @@ -1,4 +1,5 @@ -using System.Linq.Expressions; +using System.Diagnostics; +using System.Linq.Expressions; using DotNetCore.CAP; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -94,47 +95,71 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe var trackUpsertEvent = @event.DeepCopy(); var paramConfig = config.ParamConfig; var contentConfigs = config.ContentConfigs; - TrackPullContentConfigDto? trackContent = null; + TrackPullContentConfigDto? matchedContentConfig = null; // 1、匹配轨迹代码 - var serviceProviderTrackCode = trackToken[paramConfig.TrackContentCodeName]?.Value(); - if (!serviceProviderTrackCode.IsNullOrWhiteSpace()) + var trackCode = trackToken[paramConfig.TrackContentCodeName]?.Value(); + if (!trackCode.IsNullOrWhiteSpace()) { - trackContent = contentConfigs.FirstOrDefault(x => x.TrackContentCodeValue == serviceProviderTrackCode); + matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackContentCodeValue == trackCode); } // 2、匹配轨迹状态 - if (trackContent is null) + if (matchedContentConfig is null) { - var serviceProviderTrackStatus = trackToken[paramConfig.TrackStatusName]?.Value(); - if (!serviceProviderTrackStatus.IsNullOrWhiteSpace()) + var trackStatus = trackToken[paramConfig.TrackStatusName]?.Value(); + if (!trackStatus.IsNullOrWhiteSpace()) { - trackContent = contentConfigs.FirstOrDefault(x => x.TrackStatusValue == serviceProviderTrackCode); + matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackStatusValue == trackCode); } } // 3、匹配轨迹内容 - if (trackContent is null) + if (matchedContentConfig is null) { - var serviceProviderTrackContent = trackToken[paramConfig.TrackContentName]?.Value(); - if (!serviceProviderTrackContent.IsNullOrWhiteSpace()) + var trackContent = trackToken[paramConfig.TrackContentName]?.Value(); + if (!trackContent.IsNullOrWhiteSpace()) { - trackContent = contentConfigs.FirstOrDefault(x => x.TrackContentValue == serviceProviderTrackCode); + Debug.Assert(trackContent != null, nameof(trackContent) + " != null"); + matchedContentConfig = contentConfigs.FirstOrDefault(x => x.TrackContentValue == trackCode); - // 3.1、按关键字匹配 - if (trackContent is null) + // 按关键字分析轨迹内容 + if (matchedContentConfig is null) { + foreach (var contentConfig in contentConfigs) + { + foreach (var keyword in contentConfig.TrackKeyword?.Split(',') ?? Enumerable.Empty()) + { + if (trackContent.Contains(keyword, StringComparison.OrdinalIgnoreCase)) + { + matchedContentConfig = contentConfig; + break; + } + } + + if (matchedContentConfig is null) continue; + + foreach (var keyword in contentConfig.TrackKeywordReverse?.Split(',') ?? + Enumerable.Empty()) + { + if (trackContent.Contains(keyword, StringComparison.OrdinalIgnoreCase)) + { + matchedContentConfig = null; + break; + } + } + } } } } - if (trackContent is null) return; + if (matchedContentConfig is null) return; var trackPlace = trackToken[paramConfig.TrackPlaceName]?.Value(); if (trackPlace.IsNullOrWhiteSpace()) { Expression> resultExpression = - (TrackLocationValue?)trackContent.TrackPlaceValue switch + (TrackLocationValue?)matchedContentConfig.TrackPlaceValue switch { TrackLocationValue.ArrivalPort => x => x.ArrivalPort, TrackLocationValue.ArriveCity => x => x.ArrivalCity, @@ -149,11 +174,11 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe } // 新增/更新轨迹 - trackUpsertEvent.TrackCode = trackContent.TrackContentCode; + trackUpsertEvent.TrackCode = matchedContentConfig.TrackContentCode; trackUpsertEvent.TrackPlace = trackPlace ?? "CN"; trackUpsertEvent.TrackTime = trackToken[paramConfig.TrackTimeName]?.Value() ?? DateTime.Now; trackUpsertEvent.TrackTimeZone = trackToken[paramConfig.TrackTimeZoneName]?.Value() ?? - trackContent.TrackTimeZoneValue ?? 8; + matchedContentConfig.TrackTimeZoneValue ?? 8; await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, trackUpsertEvent); } } \ 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 5784d125..21ddffc0 100644 --- a/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/TrackUpsertEventHandler.cs @@ -88,7 +88,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe TrackStatus = trackContent.Status, TrackCode = @event.TrackCode, TrackContent = trackContent.Content, - + IsCompleted = orderIsCompleted, TrackEnContent = trackContent.EnContent, TrackPlace = @event.TrackPlace, TrackTime = @event.TrackTime!.Value, diff --git a/src/SJZY.Track.Application/EventHandlers/UpdateOrderTrackEventHandler.cs b/src/SJZY.Track.Application/EventHandlers/UpdateOrderTrackEventHandler.cs index 0901b2a0..72316cef 100644 --- a/src/SJZY.Track.Application/EventHandlers/UpdateOrderTrackEventHandler.cs +++ b/src/SJZY.Track.Application/EventHandlers/UpdateOrderTrackEventHandler.cs @@ -20,16 +20,31 @@ public class UpdateOrderTrackEventHandler : ITransientDependency, ICapSubscribe var order = await _orderRepository.GetFirstAsync(x => x.Id == @event.OrderId); if (order == default) return; - if (order.IsCompleted) return; + if (@event.IsDelete) + { + if (@event.TrackTime == default) + { + if (order.LatestTrackTime == null) return; + // 删除全部轨迹导致的重置行为 + order.ResetTrackInfo(); + } + else if (order.LatestTrackTime != null && + order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0)) == + @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone))) return; + } + else // upsert引发的更新 + { + if (order.LatestTrackTime != null && + order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0)) > + @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone))) return; + } + + order.IsCompleted = @event.IsCompleted; order.LatestTrackContent = @event.TrackContent; order.LatestTrackEnContent = @event.TrackEnContent; order.LatestTrackPlace = @event.TrackPlace; order.LatestTrackTime = @event.TrackTime; order.LatestTrackTimeZone = @event.TrackTimeZone; - if (@event.IsCompleted) order.IsCompleted = true; - else if (order.LatestTrackTime != null && - order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0)) > - @event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone))) return; await _orderRepository.UpdateColumnAsync(order, x => new { diff --git a/src/SJZY.Track.Application/SJZY.Track.Application.csproj b/src/SJZY.Track.Application/SJZY.Track.Application.csproj index d2b2eafd..da60d1a4 100644 --- a/src/SJZY.Track.Application/SJZY.Track.Application.csproj +++ b/src/SJZY.Track.Application/SJZY.Track.Application.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs index 5c35b728..51f50f3b 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.Link.cs @@ -14,6 +14,12 @@ public partial class OrderService private readonly IBasicQuery _orderLinkQuery; private readonly ICapPublisher _capPublisher; + /// + /// 关联、解除关联订单 + /// + /// + /// + /// [HttpPost("Order/Link")] public async Task LinkOrderAsync(LinkOrderInput input) { diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs index 5c56337d..765ff6ad 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs @@ -24,6 +24,11 @@ public partial class OrderService : ApplicationService, IOrderService _orderLinkQuery = orderLinkQuery; } + /// + /// 新增、更新订单(存在就更新) + /// + /// + /// [HttpPost("Order/Upsert")] public async Task UpsertAsync(UpsertOrderInput input) { @@ -45,6 +50,12 @@ public partial class OrderService : ApplicationService, IOrderService return "创建成功"; } + /// + /// 删除订单 + /// + /// + /// + /// [HttpPost("Order/Delete")] public async Task DeleteOrderAsync(DeleteOrderInput input) { diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushPullService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushPullService.cs index 66625f36..8e32d1c1 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackPushPullService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackPushPullService.cs @@ -15,10 +15,10 @@ namespace SJZY.Track.Application.Services.ProvideServices; public class TrackPushPullService : ApplicationService { private readonly IOrderRepository _orderRepository; - private readonly IHttpClientProxy _httpClientProxy; + private readonly IHttpClientProxy _httpClientProxy; public TrackPushPullService(IOrderRepository orderRepository, - IHttpClientProxy httpClientProxy) + IHttpClientProxy httpClientProxy) { _orderRepository = orderRepository; _httpClientProxy = httpClientProxy; @@ -49,9 +49,9 @@ public class TrackPushPullService : ApplicationService x.OrderNo }).ToList(); - // 批量获取轨迹 + // 批量获取轨迹 这里报错了,我先随便给个 写死的主体值 await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( - "A012", group.Key.ServiceProviderCode, 42, data, + "A012", group.Key.ServiceProviderCode, data, GlobalConst.TrackRefreshSubscribe, JsonConvert.SerializeObject(group.Key)); } diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs index 372d3f01..35237196 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.Query.cs @@ -10,6 +10,12 @@ public partial class TrackService { private readonly ITrackDetailsRepository _trackDetailsRepository; + /// + /// 查询轨迹 + /// + /// + /// + /// [HttpPost("Track/Query")] public async Task> QueryAsync(GetTrackInput input) { diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs index 7c84dbc3..fbd0fd99 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs @@ -29,6 +29,12 @@ public partial class TrackService : ApplicationService, ITrackService _trackDetailsRepository = trackDetailsRepository; } + /// + /// 新增、更新轨迹(存在就更新) + /// + /// + /// + /// [HttpPost("Track/Upsert")] public async Task UpsertTrackAsync(UpsertTrackInput input) { @@ -52,24 +58,68 @@ public partial class TrackService : ApplicationService, ITrackService return true; } + /// + /// 批量新增、更新轨迹 + /// + /// + /// + /// + [HttpPost("Track/BatchUpsert")] + public async Task BatchUpsertTrackAsync(BatchUpsertTrackInput input) + { + input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空 + if (input.OrderNos.Count == 0) + { + throw new BusinessException(message: "订单一个都不存在"); + } + + var orders = await _orderRepository.GetListAsync(x => + x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => new + { + x.Id, x.OrderNo, x.SubSystemId, x.IsPushCompleted, x.CustomId + }); + + foreach (var order in orders) + { + // 新增/更新轨迹 + var @event = new TrackUpsertEvent + { + TrackCode = input.TrackCode, + TrackPlace = input.TrackPlace, + TrackTime = input.TrackTime, + TrackTimeZone = input.TrackTimeZone, + OrderType = input.OrderType, + OrderNo = order.OrderNo, + OrderId = order.Id, + SubSystemId = order.SubSystemId, + IsPushCompleted = order.IsPushCompleted, + CustomId = order.CustomId + }; + 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.IsCompleted + x.Id, x.SubSystemId }); if (order == default) { throw new BusinessException(message: $"订单:{input.OrderNo}不存在"); } - if (order.IsCompleted) - { - throw new BusinessException(message: $"订单:{input.OrderNo}已完成无法删除轨迹"); - } - var codes = await _provideQueries.GetCanDeleteTrackCodesAsync(new List(order.Id), input.TrackCodes); if (codes.Count == 0) @@ -89,6 +139,12 @@ public partial class TrackService : ApplicationService, ITrackService return true; } + /// + /// 批量删除轨迹 + /// + /// + /// + /// [HttpPost("Track/BatchDelete")] public async Task BatchDeleteTrackAsync(BatchDeleteTrackInput input) { diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderEntity.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderEntity.cs index 04432d30..66f704a3 100644 --- a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderEntity.cs +++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderEntity.cs @@ -41,7 +41,7 @@ public class OrderEntity : IFullAuditedBasicEntitys, IAggregateRoot /// [SugarColumn(ColumnName = "IsCompleted")] public bool IsCompleted { get; set; } - + /// /// 订单是否推送完成(异步维护) /// @@ -65,7 +65,7 @@ public class OrderEntity : IFullAuditedBasicEntitys, IAggregateRoot /// [SugarColumn(ColumnName = "LatestTrackTime")] public DateTime? LatestTrackTime { get; set; } - + /// /// 最新轨迹时区(异步维护) /// @@ -108,14 +108,34 @@ public class OrderEntity : IFullAuditedBasicEntitys, IAggregateRoot [SugarColumn(ColumnName = "LeaveCountry")] public string LeaveCountry { get; set; } = null!; + /// + /// 问题类型(主数据枚举TrackQuestionType) + /// + [SugarColumn(ColumnName = "QuestionType")] + public int QuestionType { get; set; } + + /// + /// 问题描述(主数据枚举TrackProblemDescription) + /// + [SugarColumn(ColumnName = "ProblemDescription")] + public int ProblemDescription { get; set; } + /// /// 起运港口 /// [SugarColumn(ColumnName = "LeavePort")] public string? LeavePort { get; set; } - [SugarColumn(IsIgnore = true)] - public List OrderFlights { get; set; } - [SugarColumn(IsIgnore = true)] - public List OrderTemplates { get; set; } + [SugarColumn(IsIgnore = true)] public List OrderFlights { get; set; } + [SugarColumn(IsIgnore = true)] public List OrderTemplates { get; set; } + + public void ResetTrackInfo() + { + IsCompleted = false; + LatestTrackContent = null; + LatestTrackEnContent = null; + LatestTrackTime = null; + LatestTrackPlace = null; + LatestTrackTimeZone = null; + } } \ 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 4025579e..34cdac01 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsRepository.cs @@ -19,7 +19,14 @@ public interface ITrackDetailsRepository /// /// /// - Task DeleteTrackAsync(int orderId, List trackCodes); + Task DeleteTrackAsync(int orderId, List trackCodes); Task?> GetListAsync(List orderIds); + + /// + /// 获取最近一条发生的轨迹 + /// + /// + /// + Task GetLatestAsync(int orderId); } \ No newline at end of file diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs index d4f5c9e1..d5909320 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs @@ -46,6 +46,11 @@ public class TrackDetailsIndex : IdBaseIndex /// public string TrackContent { get; set; } = null!; + /// + /// 是否意味着完成 + /// + public bool IsCompleted { get; set; } + /// /// 原轨迹内容 /// diff --git a/src/SJZY.Track.Domain/Dtos/Order/GetPageTrackOrderInputVO.cs b/src/SJZY.Track.Domain/Dtos/Order/GetPageTrackOrderInputVO.cs index 67d955f9..ccd9d467 100644 --- a/src/SJZY.Track.Domain/Dtos/Order/GetPageTrackOrderInputVO.cs +++ b/src/SJZY.Track.Domain/Dtos/Order/GetPageTrackOrderInputVO.cs @@ -18,6 +18,25 @@ namespace SJZY.Track.Domain.Dtos.Order ///// //public List? OrderNos { get; set; } + /// + /// 当tab选中 0 默认不传 1 直接写死传值 [1,4] 2 传 [2,4] + /// + public int TabType { get; set; } + + ///// + ///// 当tab选中 1 直接写死传值 [1,4] 2 传 [2,4] + ///// + //public List? QuestionTypeIds { get; set; } + + /// + /// 订单类型 + /// + public int? TrackOrderType { get; set; } + + /// + /// 客户id + /// + public int? CustomerId { get; set; } /// /// 单号 @@ -139,5 +158,25 @@ namespace SJZY.Track.Domain.Dtos.Order /// 轨迹模板Id数组 /// public List? TrackTemplateIds { get; set; } + + /// + /// 问题类型(主数据枚举TrackQuestionType) + /// + public int QuestionType { get; set; } + + /// + /// 问题类型名称 + /// + public string? QuestionTypeName { get; set; } + + /// + /// 问题描述(主数据枚举TrackProblemDescription) + /// + public int ProblemDescription { get; set; } + + /// + /// 问题描述名称 + /// + public string? ProblemDescriptionName { get; set; } } } diff --git a/src/SJZY.Track.Domain/GlobalConst.cs b/src/SJZY.Track.Domain/GlobalConst.cs index 27a07bb1..629149a8 100644 --- a/src/SJZY.Track.Domain/GlobalConst.cs +++ b/src/SJZY.Track.Domain/GlobalConst.cs @@ -27,6 +27,11 @@ public class GlobalConst /// public const string UpdateOrderTrackSubscribe = "SJZY.Track.UpdateOrderTrack"; + /// + /// 轨迹删除后触发更新订单轨迹 mq订阅名称 + /// + public const string DeleteTrackAfterUpdateOrderSubscribe = "SJZY.Track.DeleteTrackAfterUpdateOrder"; + /// /// 关联订单后补轨迹 mq订阅名称 /// diff --git a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs index 2516bb94..e160ec0b 100644 --- a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs @@ -5,6 +5,7 @@ using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate; using SJZY.Track.Domain.Dtos.Order; using SJZY.Track.Domain.VEntities; using SJZY.Track.Repository.VData.Entitys; +using SqlSugar; namespace SJZY.Track.Repository.Repositories; @@ -121,10 +122,22 @@ public class OrderRepository : BasicRepository, IOrderRepository, I public async Task> GetPageTrackOrder(GetPageTrackOrderInputVO input) { List orderNoList = new List(); + List questionTypeIds = new List(); + int ques = 0; if (!input.OrderNos.IsNullOrWhiteSpace()) { orderNoList = input.OrderNos.Split(new char[] { ',', ',', ':', ':' }).ToList(); } + if (input.TabType==1) + { + questionTypeIds= new List { 1, 4 }; + ques = questionTypeIds.Sum(); + } + else if (input.TabType==2) + { + questionTypeIds= new List { 2, 4 }; + ques = questionTypeIds.Sum(); + } var pageList = await Context.Queryable() .LeftJoin((a, b) => a.CustomId == b.Id && b.IsDeleted == false) @@ -139,6 +152,7 @@ public class OrderRepository : BasicRepository, IOrderRepository, I (a, b, c) => a.CreateTime <= input.CreateTimeEnd) .WhereIF(input.CustomerId>0, (a, b, c) => a.CustomId==input.CustomerId) .WhereIF(input.TrackOrderType>0, (a, b, c) => a.OrderType==input.TrackOrderType) + .WhereIF(input.TabType>0 && (!questionTypeIds.IsNullOrEmpty()), (a, b, c) => (a.QuestionType&ques)>0) .OrderByDescending((a, b, c) => a.CreateTime) .Select((a, b, c) => new TrackOrderVO { @@ -151,6 +165,10 @@ public class OrderRepository : BasicRepository, IOrderRepository, I CustomerShortName = b.Abbreviation, CustomerCode = b.Code, CustomerId = a.CustomId, + QuestionType = a.QuestionType, + QuestionTypeName = SqlFunc.IF(a.QuestionType == 1).Return("异常").ElseIF(a.QuestionType == 2).Return("预警").End(""), + ProblemDescription = a.ProblemDescription, + ProblemDescriptionName =SqlFunc.IF(a.ProblemDescription == 1).Return("推送异常").ElseIF(a.ProblemDescription == 2).Return("推送预警").End(""), //TrackTemplateNames = SqlFunc.Subqueryable() // .LeftJoin((aa, bb) => aa.TrackTemplateId == bb.Id) // .Where((aa, bb) => a.Id == aa.OrderId).SelectStringJoin((aa, bb) => bb.Name, ","), @@ -209,7 +227,7 @@ public class OrderRepository : BasicRepository, IOrderRepository, I a.TrackTemplateNames = trackTemplateList.Where(b => b.OrderId == a.Id).Select(a => a.Name) .JoinAsString(","); - a.TrackTemplateIds = trackTemplateList.Where(b => b.OrderId == a.Id).Select(a => a.TemplateId).ToList(); + a.TrackTemplateIds = trackTemplateList.Where(b => b.OrderId == a.Id).Where(b => b.TemplateId>0).Select(a => a.TemplateId).ToList(); }); } diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs index e6aae4f0..8bc2739d 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsRepository.cs @@ -1,4 +1,3 @@ -using Elasticsearch.Net; using Nest; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ElasticSearch.Services; @@ -40,7 +39,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract request .Index(index.IndexName) - .Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 + //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 ); if (!r.IsValid) @@ -111,7 +110,28 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract trackCodes) + public async Task GetLatestAsync(int orderId) + { + var data = await Context.SearchAsync(x => x + .Source(s => s.Includes(fd => fd + .Field(f => f.IsCompleted) + .Field(f => f.TrackEnContent) + .Field(f => f.TrackContent) + .Field(f => f.TrackPlace) + .Field(f => f.TrackTime) + .Field(f => f.TrackTimeZone) + )) + .Query(q => + q.Term(f => f.OrderId, orderId) + ) + .Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending)) + .Size(1) + ); + + return data.Documents.FirstOrDefault(); + } + + public async Task DeleteTrackAsync(int orderId, List trackCodes) { var r = await Context.DeleteByQueryAsync(x => x .Query( @@ -123,6 +143,8 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract 0; } public async Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input)