diff --git a/src/SJZY.Track.Api/appsettings.Test.json b/src/SJZY.Track.Api/appsettings.Test.json index 825693ce..c62fc382 100644 --- a/src/SJZY.Track.Api/appsettings.Test.json +++ b/src/SJZY.Track.Api/appsettings.Test.json @@ -7,8 +7,8 @@ } }, "ConnectionStrings": { - "DefaultConnection": "server=192.168.80.84;Database=sjzy_package_setting;Uid=sjzy_test_user;Pwd=848c1c31;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;", - "canalView": "server=192.168.80.84;Database=sjzy_data_center;Uid=sjzy_test_user;Pwd=848c1c31;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;" + "DefaultConnection": "server=mysql-test.default.svc.cluster.local;Database=sjzy_track;Uid=sjzy_test_user;Pwd=848c1c31;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;", + "canalView": "server=mysql-test.default.svc.cluster.local;Database=sjzy_track;Uid=sjzy_test_user;Pwd=848c1c31;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;" }, "Redis": { "ConnectionString": "192.168.80.58:6379,abortConnect=false", 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/Dtos/TrackTemplates/GetTrackDetailDto.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackTemplates/GetTrackDetailDto.cs index 86e5db45..08f7824d 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/TrackTemplates/GetTrackDetailDto.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/TrackTemplates/GetTrackDetailDto.cs @@ -56,6 +56,11 @@ /// public string SubSystem { set; get; } + /// + /// 子系统id + /// + public int SubSystemId { set; get; } + /// /// 创建时间 /// 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..aaf59008 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; } /// @@ -94,7 +94,6 @@ public class OrderService : ApplicationService #endregion #region 轨迹订单列表 - /// /// 获取分页的轨迹订单 /// @@ -109,7 +108,6 @@ public class OrderService : ApplicationService ObjectMapper.Map, UnifyPageResultDto>(pageList); return pageResultDto; } - #endregion private async Task UpdateOrderAsync(UpdateOrderInput input, OrderEntity order) diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackQueryService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackQueryService.cs index 02f6d9b0..aa554a9a 100644 --- a/src/SJZY.Track.Application/Services/ProvideServices/TrackQueryService.cs +++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackQueryService.cs @@ -1,5 +1,7 @@ using SJZY.Track.Application.Contract.Dtos.ProvideServices; +using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; +using SJZY.Track.Domain.Dtos.Order; using SJZY.Track.Domain.Queries; namespace SJZY.Track.Application.Services.ProvideServices; @@ -11,12 +13,15 @@ namespace SJZY.Track.Application.Services.ProvideServices; public class TrackQueryService : ApplicationService { private readonly ITrackDetailsRepository _trackDetailsRepository; + private readonly IOrderRepository _orderRepository; private readonly IProvideQueries _provideQueries; public TrackQueryService(ITrackDetailsRepository trackDetailsRepository, + IOrderRepository orderRepository, IProvideQueries provideQueries) { _trackDetailsRepository = trackDetailsRepository; + _orderRepository=orderRepository; _provideQueries = provideQueries; } @@ -63,6 +68,43 @@ public class TrackQueryService : ApplicationService return res; } + #region 轨迹订单明细列表 + /// + /// 根据轨迹订单id获取轨迹订单明细列表 + /// + /// + /// + [HttpPost("/Track/GetDetails")] + public async Task> GetOrderDetails(GetOrderDetailsInput input) + { + var trackDetails = await _trackDetailsRepository.GetListAsync(input.OrderId); + if (!trackDetails.IsNullOrEmpty()) + { + var list = ObjectMapper.Map, List>(trackDetails); + return list; + } + + return new List(); + } + #endregion + + #region 轨迹订单分页 + /// + /// 获取分页的轨迹订单 + /// + /// + /// + [HttpPost("/Track/GetTrackOrderList")] + public async Task> GetPageTrackOrder(GetPageTrackOrderInput input) + { + var vo = ObjectMapper.Map(input); + var pageList = await _orderRepository.GetPageTrackOrder(vo); + var pageResultDto = + ObjectMapper.Map, UnifyPageResultDto>(pageList); + return pageResultDto; + } + #endregion + private async Task TrackDetailSort(List list, GetTrackInput input) { switch (input.SortMethod) 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.Application/Services/TrackContents/TrackContentService.cs b/src/SJZY.Track.Application/Services/TrackContents/TrackContentService.cs index cac9a7a6..f4946435 100644 --- a/src/SJZY.Track.Application/Services/TrackContents/TrackContentService.cs +++ b/src/SJZY.Track.Application/Services/TrackContents/TrackContentService.cs @@ -101,7 +101,22 @@ namespace SJZY.Track.Application.Services.TrackContents if (trackContentEntitys.Any()) { //throw new BusinessException(message: _stringLocalizer["TrackContentExist"]); - throw new BusinessException(message: "当前子系统下,轨迹代码或轨迹内容或轨迹内容英文存在"); + var codes = trackContentEntitys.FirstOrDefault(a => a.Code==input.Code); + if (codes!=null) + { + throw new BusinessException(message: "该子系统下轨迹代码已存在"); + } + var contents = trackContentEntitys.FirstOrDefault(a => a.Content==input.Content); + if (contents!=null) + { + throw new BusinessException(message: "该子系统下轨迹内容已存在"); + } + var contentEns = trackContentEntitys.FirstOrDefault(a => a.EnContent==input.EnContent); + if (contentEns!=null) + { + throw new BusinessException(message: "该子系统下轨迹内容英文已存在"); + } + //throw new BusinessException(message: "当前子系统下,轨迹代码或轨迹内容或轨迹内容英文存在"); } #endregion 业务逻辑校验 @@ -122,7 +137,22 @@ namespace SJZY.Track.Application.Services.TrackContents if (trackContentEntitys.Any()) { //throw new BusinessException(message: _stringLocalizer["TrackContentExist"]); - throw new BusinessException(message: "当前子系统下,轨迹代码或轨迹内容或轨迹内容英文存在"); + //throw new BusinessException(message: "当前子系统下,轨迹代码或轨迹内容或轨迹内容英文存在"); + var codes = trackContentEntitys.FirstOrDefault(a => a.Code==input.Code); + if (codes!=null) + { + throw new BusinessException(message: "该子系统下轨迹代码已存在"); + } + var contents = trackContentEntitys.FirstOrDefault(a => a.Content==input.Content); + if (contents!=null) + { + throw new BusinessException(message: "该子系统下轨迹内容已存在"); + } + var contentEns = trackContentEntitys.FirstOrDefault(a => a.EnContent==input.EnContent); + if (contentEns!=null) + { + throw new BusinessException(message: "该子系统下轨迹内容英文已存在"); + } } #endregion 业务逻辑校验 @@ -163,21 +193,24 @@ namespace SJZY.Track.Application.Services.TrackContents private async Task DeleteAsync(EditTrackContentInput input) { #region 业务校验 - //查询是否关联了轨迹模版内容 - var trackTemplateContents = await _trackTemplateContentBasicQuery.GetListAsync(a => a.TrackContentId == input.Id); - if (trackTemplateContents.Any()) + var isExistTemplate = await _trackContentRepository.GetTemplateIsExist(input.Id); + if (isExistTemplate) { throw new BusinessException(message: "该轨迹内容关联轨迹模板,禁止删除"); } + //var trackTemplateContents = await _trackTemplateContentBasicQuery.GetListAsync(a => a.TrackContentId == input.Id); + //if (trackTemplateContents.Any()) + //{ + // throw new BusinessException(message: "该轨迹内容关联轨迹模板,禁止删除"); + //} //需要加个判断,存在内容映射,则出提示 - var trackContentMapEntities = await _trackContentMapBasicQuery.GetListAsync(a => a.TrackContentId == input.Id || a.MapTrackContentId == input.Id); - if (trackContentMapEntities.Any()) - { - throw new BusinessException(message: "无法删除该内容,该轨迹内容已在轨迹内容映射中使用了,请检查"); - } - + //var trackContentMapEntities = await _trackContentMapBasicQuery.GetListAsync(a => a.TrackContentId == input.Id || a.MapTrackContentId == input.Id); + //if (trackContentMapEntities.Any()) + //{ + // throw new BusinessException(message: "无法删除该内容,该轨迹内容已在轨迹内容映射中使用了,请检查"); + //} #endregion 业务校验 var isTrue = await _trackContentRepository.SoftDeleteAsync(x => x.Id == input.Id); diff --git a/src/SJZY.Track.Application/Services/TrackFlags/TrackFlagService.cs b/src/SJZY.Track.Application/Services/TrackFlags/TrackFlagService.cs index bc3f68ad..9e7d4056 100644 --- a/src/SJZY.Track.Application/Services/TrackFlags/TrackFlagService.cs +++ b/src/SJZY.Track.Application/Services/TrackFlags/TrackFlagService.cs @@ -86,12 +86,22 @@ namespace SJZY.Track.Application.Services.TrackFlags private async Task AddAsync(EditTrackFlagInput input) { #region 业务校验 - var trackStatusEntitys = await _trackFlagRepository.GetListAsync(a => + var trackFlagsEntitys = await _trackFlagRepository.GetListAsync(a => a.SubSystemId == input.SubSystemId && (a.Code == input.Code || a.Name == input.Flag)); - if (trackStatusEntitys.Any()) + if (trackFlagsEntitys.Any()) { //throw new BusinessException(message: _stringLocalizer["TrackFlagExist"]); - throw new BusinessException(message: "当前子系统下已存在轨迹标记代码"); + //throw new BusinessException(message: "当前子系统下已存在轨迹标记代码"); + var trackFlagCode = trackFlagsEntitys.FirstOrDefault(a => a.Code==input.Code); + if (trackFlagCode!=null) + { + throw new BusinessException(message: "该子系统下代码已存在"); + } + var trackFlagName = trackFlagsEntitys.FirstOrDefault(a => a.Name==input.Flag); + if (trackFlagName!=null) + { + throw new BusinessException(message: "该子系统下标记已存在"); + } } #endregion @@ -105,13 +115,23 @@ namespace SJZY.Track.Application.Services.TrackFlags { #region 业务校验 - var trackStatusEntitys = await _trackFlagRepository.GetListAsync(a => a.Id != input.Id && + var trackFlagsEntitys = await _trackFlagRepository.GetListAsync(a => a.Id != input.Id && a.SubSystemId == input.SubSystemId && (a.Code == input.Code || a.Name == input.Flag)); - if (trackStatusEntitys.Any()) + if (trackFlagsEntitys.Any()) { //throw new BusinessException(message: _stringLocalizer["TrackFlagExist"]); - throw new BusinessException(message: "当前子系统下已存在轨迹标记代码"); + //throw new BusinessException(message: "当前子系统下已存在轨迹标记代码"); + var trackFlagCode = trackFlagsEntitys.FirstOrDefault(a => a.Code==input.Code); + if (trackFlagCode!=null) + { + throw new BusinessException(message: "该子系统下代码已存在"); + } + var trackFlagName = trackFlagsEntitys.FirstOrDefault(a => a.Name==input.Flag); + if (trackFlagName!=null) + { + throw new BusinessException(message: "该子系统下标记已存在"); + } } #endregion diff --git a/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs b/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs index f1bc092a..47baadb0 100644 --- a/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs +++ b/src/SJZY.Track.Application/Services/TrackPull/TrackPullService.cs @@ -169,7 +169,7 @@ public class TrackPullService : ApplicationService, ITransientDependency await _trackPullConfigRepository.UpdateAsync(oldTrackPullEntity); await _trackPullConfigRepository.UpdateParamsAsync(oldTrackPullParamsEntity); - if (oldTrackPullEntity.TrackTemplateId != input.TrackTemplateId) + if (trackPullContentEntities.Count > 0) { await _trackPullConfigRepository.SoftDeleteContentAsync(x => x.TrackPullConfigId == input.Id); await _trackPullConfigRepository.InsertContentRangeAsync(trackPullContentEntities); diff --git a/src/SJZY.Track.Application/Services/TrackStatus/TrackStatusService.cs b/src/SJZY.Track.Application/Services/TrackStatus/TrackStatusService.cs index 5dad92e8..979d412d 100644 --- a/src/SJZY.Track.Application/Services/TrackStatus/TrackStatusService.cs +++ b/src/SJZY.Track.Application/Services/TrackStatus/TrackStatusService.cs @@ -93,7 +93,22 @@ public class TrackStatusService : ApplicationService, ITransientDependency if (trackStatusEntitys.Any()) { //throw new BusinessException(message: _stringLocalizer["TrackStatusExist"]); - throw new BusinessException(message: "当前子系统下,轨迹状态代码或轨迹状态或轨迹状态英文存在"); + //throw new BusinessException(message: "当前子系统下,轨迹状态代码或轨迹状态或轨迹状态英文存在"); + var trackStatusCode = trackStatusEntitys.FirstOrDefault(t => t.Code==input.Code); + if (trackStatusCode!=null) + { + throw new BusinessException(message: "该子系统下轨迹状态代码已存在"); + } + var trackStatusName = trackStatusEntitys.FirstOrDefault(t => t.Status==input.TrackStatus); + if (trackStatusName!=null) + { + throw new BusinessException(message: "该子系统下轨迹状态已存在"); + } + var trackStatusEnName = trackStatusEntitys.FirstOrDefault(t => t.EnStatus==input.EntrackStatus); + if (trackStatusEnName!=null) + { + throw new BusinessException(message: "该子系统下轨迹状态英文已存在"); + } } #endregion @@ -114,7 +129,22 @@ public class TrackStatusService : ApplicationService, ITransientDependency if (trackStatusEntitys.Any()) { //throw new BusinessException(message: _stringLocalizer["TrackStatusExist"]); - throw new BusinessException(message: "当前子系统下,轨迹状态代码或轨迹状态或轨迹状态英文存在"); + //throw new BusinessException(message: "当前子系统下,轨迹状态代码或轨迹状态或轨迹状态英文存在"); + var trackStatusCode = trackStatusEntitys.FirstOrDefault(t => t.Code==input.Code); + if (trackStatusCode!=null) + { + throw new BusinessException(message: "该子系统下轨迹状态代码已存在"); + } + var trackStatusName = trackStatusEntitys.FirstOrDefault(t => t.Status==input.TrackStatus); + if (trackStatusName!=null) + { + throw new BusinessException(message: "该子系统下轨迹状态已存在"); + } + var trackStatusEnName = trackStatusEntitys.FirstOrDefault(t => t.EnStatus==input.EntrackStatus); + if (trackStatusEnName!=null) + { + throw new BusinessException(message: "该子系统下轨迹状态英文已存在"); + } } #endregion @@ -133,7 +163,7 @@ public class TrackStatusService : ApplicationService, ITransientDependency if (isExistStatus!=null) { //throw new BusinessException(message: _stringLocalizer["IsExistTrackStatus"]); - throw new BusinessException(message: "轨迹内容已经绑定了该轨迹状态,请先删除轨迹内容后再删除该轨迹状态"); + throw new BusinessException(message: "该状态关联轨迹内容,禁止删除"); } #endregion var isTrue = await _trackStatusRepository.SoftDeleteAsync(x => x.Id == input.Id); diff --git a/src/SJZY.Track.Application/Services/TrackTemplates/TrackTemplateService.cs b/src/SJZY.Track.Application/Services/TrackTemplates/TrackTemplateService.cs index 831a17e0..525add23 100644 --- a/src/SJZY.Track.Application/Services/TrackTemplates/TrackTemplateService.cs +++ b/src/SJZY.Track.Application/Services/TrackTemplates/TrackTemplateService.cs @@ -96,13 +96,24 @@ public class TrackTemplateService : ApplicationService, ITransientDependency #region 业务校验 //校验模版代码唯一性 - var templateEntity = - await _trackTemplateRepository.GetFirstAsync( - a => a.SubSystemId == input.SubSystemId && a.Code == input.Code); - if (templateEntity != null) + //var templateEntity = + // await _trackTemplateRepository.GetFirstAsync( + // a => a.SubSystemId == input.SubSystemId && a.Code == input.Code); + var templateEntitys = await _trackTemplateRepository.GetListAsync(a => a.SubSystemId == input.SubSystemId && (a.Code == input.Code|| a.Name==input.Name)); + if (templateEntitys.Any()) { //throw new BusinessException(message: _stringLocalizer["TemplateExist"]); - throw new BusinessException(message: "模板代码已存在于当前选择的子系统下"); + //throw new BusinessException(message: "模板代码已存在于当前选择的子系统下"); + var trackTemplateCode = templateEntitys.FirstOrDefault(t => t.Code==input.Code); + if (trackTemplateCode!=null) + { + throw new BusinessException(message: "该子系统下模板代码已存在"); + } + var trackTemplateName = templateEntitys.FirstOrDefault(t => t.Name==input.Name); + if (trackTemplateName!=null) + { + throw new BusinessException(message: "该子系统下模板名称已存在"); + } } #endregion 业务校验 @@ -117,11 +128,21 @@ public class TrackTemplateService : ApplicationService, ITransientDependency { #region 业务校验 - var isExist = await _trackTemplateRepository.GetFirstAsync(a => - a.Id != input.Id && a.SubSystemId == input.SubSystemId && a.Code == input.Code); - if (isExist != null) + var templateEntitys = await _trackTemplateRepository.GetListAsync(a => + a.Id != input.Id && a.SubSystemId == input.SubSystemId && (a.Code == input.Code || a.Name==input.Name)); + if (templateEntitys.Any()) { - throw new BusinessException(message: "模板代码已存在于当前选择的子系统下"); + //throw new BusinessException(message: "模板代码已存在于当前选择的子系统下"); + var trackTemplateCode = templateEntitys.FirstOrDefault(t => t.Code==input.Code); + if (trackTemplateCode!=null) + { + throw new BusinessException(message: "该子系统下模板代码已存在"); + } + var trackTemplateName = templateEntitys.FirstOrDefault(t => t.Name==input.Name); + if (trackTemplateName!=null) + { + throw new BusinessException(message: "该子系统下模板名称已存在"); + } } #endregion 业务校验 @@ -142,13 +163,13 @@ public class TrackTemplateService : ApplicationService, ITransientDependency if (isExisistTrackPullConfigs.Any()) { //throw new BusinessException(message: _stringLocalizer["IsExistTrackPullConfig"]); - throw new BusinessException(message: "轨迹拉取配置里已经绑定模版,请检查"); + throw new BusinessException(message: "该模板存在映射,禁止删除"); } //轨迹推送里看看是否被占用 var isExisistTrackPushConfigs = await _trackPushConfigRepository.GetListAsync(a => a.TrackTemplateId.Contains(input.Id.ToString())); if (isExisistTrackPushConfigs.Any()) { - throw new BusinessException(message: "轨迹推送配置里已经绑定模版,请检查"); + throw new BusinessException(message: "该模板存在映射,禁止删除"); } #endregion 业务校验 diff --git a/src/SJZY.Track.Application/Validations/TrackContents/EditTrackContentMapInputValidation.cs b/src/SJZY.Track.Application/Validations/TrackContents/EditTrackContentMapInputValidation.cs index 90a334a9..b4cf3ed8 100644 --- a/src/SJZY.Track.Application/Validations/TrackContents/EditTrackContentMapInputValidation.cs +++ b/src/SJZY.Track.Application/Validations/TrackContents/EditTrackContentMapInputValidation.cs @@ -12,7 +12,7 @@ public class EditTrackContentMapInputValidation : AbstractValidator x.Options).IsInEnum().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_IsInEnum, nameof(EditTrackContentMapInput.Options)]); - //RuleFor(x => x.Id).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackContentMapInput.Id), 0]); + RuleFor(x => x.Id).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackContentMapInput.Id), 0]); RuleFor(x => x.MapSubSystemId).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackContentMapInput.MapSubSystemId), 0]); @@ -22,10 +22,10 @@ public class EditTrackContentMapInputValidation : AbstractValidator x.TrackContentId).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackContentMapInput.TrackContentId), 0]); - //When(x => x.Options != OptionTypeNoNull.新增, () => - //{ - // RuleFor(x => x.Id).NotNull().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_NotNull, nameof(EditTrackContentMapInput.Id)]); - //}); + When(x => x.Options != OptionTypeNoNull.新增, () => + { + RuleFor(x => x.Id).NotNull().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_NotNull, nameof(EditTrackContentMapInput.Id)]); + }); When(x => x.Options != OptionTypeNoNull.删除, () => { diff --git a/src/SJZY.Track.Application/Validations/TrackPull/EditTrackPullConfigInputValidation.cs b/src/SJZY.Track.Application/Validations/TrackPull/EditTrackPullConfigInputValidation.cs index fc540b38..9b0a4503 100644 --- a/src/SJZY.Track.Application/Validations/TrackPull/EditTrackPullConfigInputValidation.cs +++ b/src/SJZY.Track.Application/Validations/TrackPull/EditTrackPullConfigInputValidation.cs @@ -16,7 +16,8 @@ public class EditTrackPullConfigInputValidation : AbstractValidator x.ParseMethod).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackPullConfigInput.ParseMethod), 0]); - RuleFor(x => x.PullInterval).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackPullConfigInput.PullInterval), 0]); + RuleFor(x => x.PullInterval) + .GreaterThanOrEqualTo(30).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThanOrEqualTo, nameof(EditTrackPullConfigInput.PullInterval), 30]); RuleFor(x => x.SubSystemId).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackPullConfigInput.SubSystemId), 0]); diff --git a/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs index cc7a54e9..511d4feb 100644 --- a/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs +++ b/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs @@ -23,4 +23,5 @@ public interface ITrackContentRepository : IBasicRepository Task SoftDeleteMapAsync(Expression> whereExpression); Task UpdateMapAsync(Expression> columns, Expression> whereExpression); + Task GetTemplateIsExist(int trackContentId); } \ 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/Dtos/TrackTemplate/GetTrackTemplateDetailVO.cs b/src/SJZY.Track.Domain/Dtos/TrackTemplate/GetTrackTemplateDetailVO.cs index 1fa28d92..46677e0e 100644 --- a/src/SJZY.Track.Domain/Dtos/TrackTemplate/GetTrackTemplateDetailVO.cs +++ b/src/SJZY.Track.Domain/Dtos/TrackTemplate/GetTrackTemplateDetailVO.cs @@ -56,6 +56,11 @@ public class GetTrackTemplateListVO /// public string SubSystem { set; get; } + /// + /// 子系统id + /// + public int SubSystemId { set; get; } + /// /// 创建时间 /// 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/TrackContentRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs index fcd51bd1..b1a0cda0 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs @@ -1,6 +1,7 @@ using SJZY.Track.Domain.Aggregates.TrackContentAggregate; using SJZY.Track.Domain.Aggregates.TrackFlagAggregate; using SJZY.Track.Domain.Aggregates.TrackStatusAggregate; +using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate; using SJZY.Track.Domain.Dtos.TrackContents; using SJZY.Track.Domain.VEntities; using System.Linq; @@ -88,6 +89,32 @@ public class TrackContentRepository : BasicRepository, ITrac return pagedList; } + /// + /// 获取轨迹模版是否存在 + /// + /// + /// + public async Task GetTemplateIsExist(int trackContentId) + { + //var trackTemplateContents = await _trackTemplateContentBasicQuery.GetListAsync(a => a.TrackContentId == input.Id); + var trackContentEntities = await Context.Queryable().LeftJoin((a, b) => a.Id==b.TrackContentId && b.IsDeleted==false) + .LeftJoin((a, b, c) => b.TrackTemplateId==c.Id&& c.IsDeleted==false) + .Where((a, b, c) => a.Id==trackContentId) + .Select((a, b, c) => new + { + TrackContentId = a.Id, + TemplateId = c.Id + }) + .ToListAsync(); + + if (trackContentEntities.Any(a => a.TemplateId>0)) + { + return true; + } + + return false; + } + public async Task> GetMapPageAsync(GetTrackContentMapPageInputVO input) { return await Context.Queryable() 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) diff --git a/src/SJZY.Track.Repository/Repositories/TrackTemplateRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackTemplateRepository.cs index d414e5c8..3bb1cfd9 100644 --- a/src/SJZY.Track.Repository/Repositories/TrackTemplateRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/TrackTemplateRepository.cs @@ -55,7 +55,8 @@ public class TrackTemplateRepository : BasicRepository, ITr Code = a.Code, CreateTime = a.CreateTime, Name = a.Name, - SubSystem = b.CnName + SubSystem = b.CnName, + SubSystemId = b.Id }) .ToPagedListAsync(input.PageIndex, input.PageSize); //.OrderByIF(input.TrackTemplateId > 0,