Эх сурвалжийг харах

fixed: 修复开启流程直接归档

xf 1 жил өмнө
parent
commit
5a8e51b524

+ 2 - 39
src/Hotline.Api/Controllers/OrderController.cs

@@ -2219,46 +2219,9 @@ public class OrderController : BaseController
 
     [HttpPost("add-anonymous")]
     [AllowAnonymous]
-    public async Task<string> AddAnonymous([FromBody] AddOrderDto dto)
+    public async Task<AddOrderResponse> AddAnonymous([FromBody] AddOrderDto dto)
     {
-        var order = await _orderRepository.GetAsync(d => d.ExternalId == dto.ExternalId, HttpContext.RequestAborted);
-        if (order is not null)
-        {
-            if (order.Source == ESource.ProvinceStraight)
-            {
-                //todo 标记为重办
-            }
-            else
-            {
-                _mapper.Map(dto, order);
-            }
-
-            if (dto.Files.Any())
-                order.FileJson = await _fileRepository.AddFileAsync(dto.Files, order.Id, "", HttpContext.RequestAborted);
-
-            await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
-        }
-        else
-        {
-            order = _mapper.Map<Order>(dto);
-            order.InitId();
-            if (dto.Files.Any())
-                order.FileJson = await _fileRepository.AddFileAsync(dto.Files, order.Id, "", HttpContext.RequestAborted);
-            await _orderDomainService.AddAsync(order, HttpContext.RequestAborted);
-        }
-
-        if (dto.RepeatableEventDetails?.Any() ?? false)
-        {
-            dto.RepeatableEventDetails.ForEach(x => x.OrderId = order.Id);
-            List<RepeatableEventDetail> repeatables =
-                _mapper.Map<List<RepeatableEventDetail>>(dto.RepeatableEventDetails);
-            await _repeatableEventDetailRepository.AddRangeAsync(repeatables, HttpContext.RequestAborted);
-        }
-
-        //内容分词
-        await _orderApplication.OrderParticiple(dto.Content, order.Id, HttpContext.RequestAborted);
-
-        return order.Id;
+        return await _orderApplication.ReceiveOrderFromExternalAsync(dto, HttpContext.RequestAborted);
     }
 
     /// <summary>

+ 5 - 0
src/Hotline.Application/Orders/IOrderApplication.cs

@@ -38,5 +38,10 @@ namespace Hotline.Application.Orders
         Task<PagedDto<OrderDto>> GetAboutToExpireAsync(AboutToExpireListDto dto, CancellationToken cancellationToken);
         //Task<PagedDto<WorkflowOrderDto>> GetAboutToExpireNodeAsync(AboutToExpireListDto dto, CancellationToken cancellationToken);
         Task OrderParticiple(string inputStr, string orderId, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// 接收外部平台工单
+        /// </summary>
+        Task<AddOrderResponse> ReceiveOrderFromExternalAsync(AddOrderDto dto, CancellationToken cancellationToken);
     }
 }

+ 100 - 1
src/Hotline.Application/Orders/OrderApplication.cs

@@ -1,10 +1,12 @@
 using Hotline.Caching.Interfaces;
+using Hotline.File;
 using Hotline.FlowEngine.Workflows;
 using Hotline.Orders;
 using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Repository.SqlSugar.Ts;
 using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.File;
 using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Dtos.Order;
@@ -32,6 +34,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly ISystemSettingCacheManager _systemSettingCacheManager;
     private readonly IRepository<OrderWord> _orderWrodRepository;
     private readonly IRepositoryTextSearch<OrderTs> _repositoryts;
+    private readonly IFileRepository _fileRepository;
 
     public OrderApplication(
         IOrderDomainService orderDomainService,
@@ -41,7 +44,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         ISystemSettingCacheManager systemSettingCacheManager,
         IMapper mapper,
         IRepository<OrderWord> orderWrodRepository,
-        IRepositoryTextSearch<OrderTs> repositoryts
+        IRepositoryTextSearch<OrderTs> repositoryts,
+        IFileRepository fileRepository
     )
     {
         _orderDomainService = orderDomainService;
@@ -52,6 +56,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _systemSettingCacheManager = systemSettingCacheManager;
         _orderWrodRepository = orderWrodRepository;
         _repositoryts = repositoryts;
+        _fileRepository = fileRepository;
     }
 
     /// <summary>
@@ -243,4 +248,98 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             else await _repositoryts.AddVectorAsync(orderId, DateTime.Now, tags, cancellationToken);
         }
     }
+
+    /// <summary>
+    /// 接收外部平台工单
+    /// </summary>
+    public Task<AddOrderResponse> ReceiveOrderFromExternalAsync(AddOrderDto dto, CancellationToken cancellationToken)
+    {
+        switch (dto.Source)
+        {
+            case ESource.ProvinceStraight:
+                return ReceiveOrderFromProvinceAsync(dto, dto.Files, cancellationToken);
+            case ESource.Police110:
+            case ESource.CityDataExchangeLz:
+            case ESource.ConvergenceMedia:
+            case ESource.WebPortal:
+                return ReceiveOrderFromOtherPlatformAsync(dto, dto.Files, cancellationToken);
+            case ESource.Hotline:
+            case ESource.HotlineImport:
+            default:
+                throw new ArgumentOutOfRangeException();
+        }
+    }
+
+
+    #region private
+
+    /// <summary>
+    /// 接受外部工单(除省平台)
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    private async Task<AddOrderResponse> ReceiveOrderFromOtherPlatformAsync(AddOrderDto dto, List<FileDto> files, CancellationToken cancellationToken)
+    {
+        if (string.IsNullOrEmpty(dto.ExternalId))
+            throw new UserFriendlyException("工单外部编号不能为空");
+
+        var order = await _orderRepository.Queryable()
+            .FirstAsync(d => d.ExternalId == dto.ExternalId, cancellationToken);
+        if (order == null)
+        {
+            order = _mapper.Map<Order>(dto);
+            order.InitId();
+            if (files != null && files.Any())
+                order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
+            await _orderDomainService.AddAsync(order, cancellationToken);
+        }
+        else
+        {
+            _mapper.Map(dto, order);
+            if (files != null && files.Any())
+                order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
+            await _orderRepository.FileAsync(order, cancellationToken);
+        }
+
+        return _mapper.Map<AddOrderResponse>(order);
+    }
+
+    /// <summary>
+    /// 接受省平台工单
+    /// </summary>
+    private async Task<AddOrderResponse> ReceiveOrderFromProvinceAsync(AddOrderDto dto, List<FileDto> files, CancellationToken cancellationToken)
+    {
+        if (string.IsNullOrEmpty(dto.ProvinceNo))
+            throw new UserFriendlyException("无效省工单编号");
+
+        var order = await _orderRepository.GetAsync(d => d.ProvinceNo == dto.ProvinceNo, cancellationToken);
+        if (order is null)
+        {
+            order = _mapper.Map<Order>(dto);
+            order.InitId();
+            if (files != null && files.Any())
+                order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
+            await _orderDomainService.AddAsync(order, cancellationToken);
+
+            var orderExtension = await _orderDomainService.GetOrderExtensionsAsync(dto.ProvinceNo, cancellationToken);
+            if (orderExtension is not null)
+            {
+                orderExtension.Id = order.Id;
+                await _orderDomainService.UpdateExtensionAsync(orderExtension, cancellationToken);
+            }
+        }
+        else
+        {
+            if (files != null && files.Any())
+                order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
+            await _orderRepository.FileAsync(order, cancellationToken);
+            // 特提(撤回至发起)todo
+            //if (!string.IsNullOrEmpty(order.WorkflowId))
+            //    await _workflowApplication.RecallToStartAsync(order.WorkflowId, "省工单重派", cancellationToken);
+        }
+        return _mapper.Map<AddOrderResponse>(order);
+    }
+
+    #endregion
 }

+ 30 - 19
src/Hotline.Application/Subscribers/DatasharingSubscriber.cs

@@ -1,28 +1,19 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using DotNetCore.CAP;
+using DotNetCore.CAP;
 using Hotline.Application.FlowEngine;
 using Hotline.Application.Quality;
 using Hotline.Orders;
-using Hotline.Application.FlowEngine;
 using Hotline.File;
 using Hotline.FlowEngine.Workflows;
-using Hotline.Orders;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Quality;
+using Hotline.Share.Mq;
 using MapsterMapper;
-using Microsoft.AspNetCore.Http;
 using XF.Domain.Authentications;
 using XF.Domain.Dependency;
 using XF.Domain.Repository;
-using Hotline.Repository.SqlSugar.Orders;
-using static StackExchange.Redis.Role;
 
 namespace Hotline.Application.Subscribers
 {
@@ -47,13 +38,7 @@ namespace Hotline.Application.Subscribers
         private readonly IRepository<OrderSupervise> _orderSuperviseRepository;
         private readonly IRepository<OrderVisitDetail> _orderVisitedDetailRepository;
         private readonly IOrderScreenRepository _orderScreenRepository;
-
-		public DataSharingSubscriber()
-        {
-           
-        }
-	    
-
+        
 		public DataSharingSubscriber(
 			IRepository<OrderVisit> orderVisitRepository,
             IRepository<OrderVisitDetail> orderVisitDetailRepository,
@@ -337,7 +322,33 @@ namespace Hotline.Application.Subscribers
                 var orderDelay = await _orderDelayRepository.GetAsync(x => x.OrderId == order.Id && x.DelayState == EDelayState.Examining, cancellationToken);
                 await _workflowApplication.JumpToEndAsync(orderDelay.WorkflowId, dto.Opinion, null);
             }
-            
+        }
+
+        /// <summary>
+        /// 接收工单处理结果
+        /// </summary>
+        [CapSubscribe(EventNames.SharingOrderReultSend)]
+        public async Task RecOrderResultAsync(OrderResultDto dto, CancellationToken cancellationToken)
+        {
+            throw new NotImplementedException();
+        }
+
+        /// <summary>
+        /// 接收工单扩展信息
+        /// </summary>
+        [CapSubscribe(EventNames.SharingOrderExtends)]
+        public async Task RecOrderExtentionAsync(OrderExtensionDto dto, CancellationToken cancellationToken)
+        {
+            throw new NotImplementedException();
+        }
+
+        /// <summary>
+        /// 接收工单办理流程
+        /// </summary>
+        [CapSubscribe(EventNames.SharingOrderAddTraces)]
+        public async Task RecOrderTracesAsync(AddOrderTracesDto dto, CancellationToken cancellationToken)
+        {
+            throw new NotImplementedException();
         }
     }
 }

+ 12 - 1
src/Hotline/FlowEngine/Workflows/Workflow.cs

@@ -486,7 +486,18 @@ public partial class Workflow
     public void UpdateActualOption()
     {
         if (FlowType is EFlowType.Review) return;
-        var step = Steps.FirstOrDefault(d => d.Id == ActualHandleStepId);
+
+        WorkflowStep step;
+        if (Steps.Count == 2
+           && Steps.Exists(d => d.StepType == EStepType.Start)
+           && Steps.Exists(d => d.StepType == EStepType.End))
+        {
+            step = Steps.FirstOrDefault(d => d.StepType == EStepType.Start);
+        }
+        else
+        {
+            step = Steps.FirstOrDefault(d => d.Id == ActualHandleStepId);
+        }
         if (step is null)
             throw new UserFriendlyException($"未查询到对应实际办理子节点,workflowId: {Id}");
         ActualOpinion = step.Opinion;

+ 14 - 6
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -104,6 +104,12 @@ namespace Hotline.FlowEngine.Workflows
         {
             //1. 创建first节点 (和trace)2.办理开始节点 
 
+            if (firstStepDefine.StepType is EStepType.End)
+            {
+                var endTrace = await EndAsync(workflow, dto, firstStepDefine, startStep, cancellationToken: cancellationToken);
+                return;
+            }
+
             //firststeps
             var firstSteps = await CreateNextStepsAsync(workflow, startStep, dto, firstStepDefine, isNextDynamic, flowAssignInfo, cancellationToken);
             if (firstSteps.Any())
@@ -836,6 +842,7 @@ namespace Hotline.FlowEngine.Workflows
             }
 
             var startStep = _mapper.Map<WorkflowStep>(startStepDefine);
+            _mapper.Map(dto, startStep);
             startStep.WorkflowId = workflow.Id;
             startStep.Handlers = handles;
             startStep.NextSteps = nextSteps;
@@ -849,15 +856,15 @@ namespace Hotline.FlowEngine.Workflows
             return startStep;
         }
 
-        public Task<List<SystemOrganize>> GetCurrentHandOrganizeAsync(string workflowId, CancellationToken cancellationToken) {
-            return  Task.FromResult(new List<SystemOrganize>());
+        public Task<List<SystemOrganize>> GetCurrentHandOrganizeAsync(string workflowId, CancellationToken cancellationToken)
+        {
+            return Task.FromResult(new List<SystemOrganize>());
         }
 
-		#region private method
+        #region private method
 
-		public async Task<WorkflowStep> CreateStartStepAsync(Workflow workflow, StepDefine startStepDefine,
-            BasicWorkflowDto dto,
-            List<Kv> handles, EWorkflowTraceStatus traceStatus, CancellationToken cancellationToken)
+        public async Task<WorkflowStep> CreateStartStepAsync(Workflow workflow, StepDefine startStepDefine,
+            BasicWorkflowDto dto, List<Kv> handles, EWorkflowTraceStatus traceStatus, CancellationToken cancellationToken)
         {
             var startStep = CreateStartStep(workflow, startStepDefine, dto, handles);
             await _workflowStepRepository.AddAsync(startStep, cancellationToken);
@@ -1072,6 +1079,7 @@ namespace Hotline.FlowEngine.Workflows
         {
             //create endStep
             var endStep = await CreateEndStepAsync(workflow, endStepDefine, currentStep, cancellationToken);
+            workflow.Steps.Add(endStep);
 
             //update endTrace
             var endTrace = await NextTraceAsync(workflow, dto, endStep, cancellationToken);

+ 1 - 2
src/Hotline/Orders/OrderDomainService.cs

@@ -128,8 +128,7 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
 
     #region 工单扩展信息
 
-    public async Task<OrderExtension?>
-        GetOrderExtensionsAsync(string provinceNo, CancellationToken cancellationToken) =>
+    public async Task<OrderExtension?> GetOrderExtensionsAsync(string provinceNo, CancellationToken cancellationToken) =>
         await _orderExtensionRepository.GetAsync(d => d.ProvinceNo == provinceNo, cancellationToken);
 
     public Task UpdateExtensionAsync(OrderExtension orderExtension, CancellationToken cancellationToken) =>