Browse Source

terminal countersign

xf 1 year ago
parent
commit
01e6470d35

+ 34 - 36
src/Hotline.Api/Controllers/OrderController.cs

@@ -1183,29 +1183,29 @@ public class OrderController : BaseController
     [LogFilter("开始工单延期流程")]
     public async Task InitialNextFlow([FromBody] DelayNextFlowDto dto)
     {
-	    var delay = await _orderDelayRepository.GetAsync(dto.Data.Id);
-	    _mapper.Map(dto.Data, delay);
-	    if (dto.Data.Files.Any())
-		    delay.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, delay.Id, "", HttpContext.RequestAborted);
-	    await _orderDelayRepository.UpdateAsync(delay, HttpContext.RequestAborted);
-	    try
-	    {
-		    dto.NextWorkflow.WorkflowId = delay.WorkflowId;
-		    await _workflowApplication.NextAsync(dto.NextWorkflow,
-			    cancellationToken: HttpContext.RequestAborted);
-	    }
-	    catch (Exception e)
-	    {
-		    throw new UserFriendlyException($"工单延期下一步流程失败!, {e.Message}", "工单延期下一步流程失败");
-	    }
-    }
-
-	/// <summary>
-	/// 延期列表
-	/// </summary>
-	/// <returns></returns>
-	//[Permission(EPermission.DelayList)]
-	[HttpGet("delay")]
+        var delay = await _orderDelayRepository.GetAsync(dto.Data.Id);
+        _mapper.Map(dto.Data, delay);
+        if (dto.Data.Files.Any())
+            delay.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, delay.Id, "", HttpContext.RequestAborted);
+        await _orderDelayRepository.UpdateAsync(delay, HttpContext.RequestAborted);
+        try
+        {
+            dto.NextWorkflow.WorkflowId = delay.WorkflowId;
+            await _workflowApplication.NextAsync(dto.NextWorkflow,
+                cancellationToken: HttpContext.RequestAborted);
+        }
+        catch (Exception e)
+        {
+            throw new UserFriendlyException($"工单延期下一步流程失败!, {e.Message}", "工单延期下一步流程失败");
+        }
+    }
+
+    /// <summary>
+    /// 延期列表
+    /// </summary>
+    /// <returns></returns>
+    //[Permission(EPermission.DelayList)]
+    [HttpGet("delay")]
     public async Task<PagedDto<OrderDelayDto>> DelayList([FromQuery] DelayListDto dto)
     {
         var (total, items) = await _orderDelayRepository.Queryable(viewFilter: false)
@@ -1261,7 +1261,7 @@ public class OrderController : BaseController
         var rspModel = _mapper.Map<OrderDelayDto>(model);
         rspModel.IsCanHandle = model.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
         rspModel.Handle = await _workflowDomainService.CheckCurrentIsStartStepAsync(rspModel.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, HttpContext.RequestAborted);
-		if (rspModel.FileJson != null && rspModel.FileJson.Any())
+        if (rspModel.FileJson != null && rspModel.FileJson.Any())
         {
             var ids = rspModel.FileJson.Select(x => x.Id).ToList();
             rspModel.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
@@ -1369,7 +1369,7 @@ public class OrderController : BaseController
         var view = dto.source == 1;
         var handler = dto.source == 1 && dto.Status is EScreenStatus.Apply;
 
-		var query = _orderScreenRepository.Queryable(viewFilter: view, handlerFilter: handler)
+        var query = _orderScreenRepository.Queryable(viewFilter: view, handlerFilter: handler)
             .Includes(x => x.Order)
             .Includes(x => x.VisitDetail)
             .Includes(x => x.Visit, d => d.Order)
@@ -1396,10 +1396,10 @@ public class OrderController : BaseController
     }
 
 
-	/// <summary>
-	/// 开始工单甄别流程
-	/// </summary>
-	[Permission(EPermission.ApplyScreen)]
+    /// <summary>
+    /// 开始工单甄别流程
+    /// </summary>
+    [Permission(EPermission.ApplyScreen)]
     [HttpPost("screen/startflow")]
     [LogFilter("开始工单甄别流程")]
     public async Task StartFlow([FromBody] ScreenStartFlowDto dto)
@@ -1997,23 +1997,21 @@ public class OrderController : BaseController
     {
         var order = await _orderRepository.Queryable()
             .Includes(d => d.OrderExtension)
-            .Includes(d => d.OrderDelays)
-            .Includes(d => d.OrderScreens)
+            //.Includes(d => d.OrderDelays)
+            //.Includes(d => d.OrderScreens)
             .Includes(d => d.OrderVisits, x => x.OrderVisitDetails)
             .Includes(d => d.OrderVisits, x => x.Employee)
             .FirstAsync(d => d.Id == id);
         if (order == null)
             return new();
 
-        var canHandle = false;
         var canEndCs = false;
         if (!string.IsNullOrEmpty(order.WorkflowId))
         {
-            var (workflow, handlePermission, canEndCountersign) = await _workflowDomainService.GetWorkflowHandlePermissionAsync(
+            var (workflow, canEndCountersign) = await _workflowDomainService.GetWorkflowHandlePermissionAsync(
                 order.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId,
                 cancellationToken: HttpContext.RequestAborted);
             order.Workflow = workflow;
-            canHandle = handlePermission;
             canEndCs = canEndCountersign;
 
             await _mediator.Publish(new GetOrderDetailNotify(order.Workflow,
@@ -2024,6 +2022,7 @@ public class OrderController : BaseController
 
         var dto = _mapper.Map<OrderDto>(order!);
         dto.CanEndCountersign = canEndCs;
+        dto.CanHandle = order.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
 
         if (dto.FileJson != null && dto.FileJson.Any())
         {
@@ -2037,7 +2036,6 @@ public class OrderController : BaseController
 
         if (order.Workflow != null)
         {
-            dto.Workflow.CanHandle = canHandle;
             dto.CanPrevious = !order.Workflow.IsInCountersign;
         }
         var repeatablesMap = await _repeatableEventDetailRepository.Queryable()
@@ -2104,7 +2102,7 @@ public class OrderController : BaseController
                     Remark = order.Title,
                     Name = order.FromName,
                     TelNumber = order.Contact,
-                    
+
                 };
                 await _mediator.Publish(new PushMessageNotify(messageDto), HttpContext.RequestAborted);
                 //await _pushDomainService.PushAsync(MessageDto, HttpContext.RequestAborted);

+ 8 - 3
src/Hotline.Share/Dtos/Order/OrderDto.cs

@@ -30,7 +30,7 @@ namespace Hotline.Share.Dtos.Order
         /// 过期状态
         /// </summary>
         public string ExpiredStatusText => ExpiredStatus?.GetDescription() ?? string.Empty;
-
+            
         /// <summary>
         /// 处理方式(直办、交办)
         /// </summary>
@@ -400,6 +400,11 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public bool CanPrevious { get; set; }
 
+        /// <summary>
+        /// 是否可办理
+        /// </summary>
+        public bool CanHandle { get; set; }
+
         /// <summary>
         /// 延期申请数量
         /// </summary>
@@ -422,14 +427,14 @@ namespace Hotline.Share.Dtos.Order
                     return "超期不到1天";
             }
 
-           
+
 
         }
 
         public EExpiredStatus? CalculateExpiredState()
         {
             DateTime? dateTime = DateTime.Now;
-            if (Status>= EOrderStatus.Filed)
+            if (Status >= EOrderStatus.Filed)
             {
                 dateTime = ActualHandleTime;
             }

+ 1 - 1
src/Hotline/FlowEngine/Workflows/IWorkflowDomainService.cs

@@ -35,7 +35,7 @@ namespace Hotline.FlowEngine.Workflows
         /// <summary>
         /// 查询工作流包含当前用户办理权限(是否可办理)
         /// </summary>
-        Task<(Workflow, bool, bool)> GetWorkflowHandlePermissionAsync(string workflowId, string userId, string orgCode,
+        Task<(Workflow, bool)> GetWorkflowHandlePermissionAsync(string workflowId, string userId, string orgCode,
             CancellationToken cancellationToken = default);
 
         /// <summary>

+ 1 - 0
src/Hotline/FlowEngine/Workflows/WorkflowCountersign.cs

@@ -57,6 +57,7 @@ namespace Hotline.FlowEngine.Workflows
 
         /// <summary>
         /// 会签汇总节点id
+        /// 人工结束会签为null
         /// </summary>
         public string? EndStepId { get; set; }
 

+ 63 - 27
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -207,16 +207,20 @@ namespace Hotline.FlowEngine.Workflows
         }
 
         /// <summary>
-        /// 查询工作流包含当前用户办理权限(是否可办理
+        /// 查询工作流包含当前用户结束会签权限(是否可结束
         /// </summary>
-        public async Task<(Workflow, bool, bool)> GetWorkflowHandlePermissionAsync(
+        public async Task<(Workflow, bool)> GetWorkflowHandlePermissionAsync(
             string workflowId, string userId, string orgCode, CancellationToken cancellationToken = default)
         {
-            var workflow = await GetWorkflowAsync(workflowId, withSteps: true, withSupplements: true,
-                withCountersigns: true, cancellationToken: cancellationToken);
-            var canHandle = workflow.CanHandle(userId, orgCode);
-            var canEndCountersign = workflow.Countersigns.Any(d => !d.IsCompleted() && d.StarterId == userId);
-            return (workflow, canHandle, canEndCountersign);
+            var workflow = await GetWorkflowAsync(workflowId, withSteps: true, withCountersigns: true,
+                cancellationToken: cancellationToken);
+            var upCompletedCountersign = workflow.Countersigns.FirstOrDefault(d=> !d.IsCompleted() && d.StarterId == userId);
+            if(upCompletedCountersign is null) return (workflow, false);
+
+            var existCountersignEndStep = workflow.Steps.Exists(d =>
+                d.IsCountersignEndStep && d.CountersignStartStepId == upCompletedCountersign.StartStepId);
+            var canEndCountersign = !existCountersignEndStep;
+            return (workflow, canEndCountersign);
         }
 
         /// <summary>
@@ -1665,39 +1669,44 @@ namespace Hotline.FlowEngine.Workflows
 
             var workflow = await GetWorkflowAsync(countersign.WorkflowId, withSteps: true, withTraces: true,
                 withCountersigns: true, cancellationToken: cancellationToken);
+            if (!workflow.IsInCountersign)
+                throw new UserFriendlyException("该流程未处于会签中");
 
-            var startStep = workflow.Steps.Find(d => d.StartCountersignId == countersignId);
-            if (startStep is null)
+            var startCountersignStep = workflow.Steps.Find(d => d.StartCountersignId == countersignId);
+            if (startCountersignStep is null)
                 throw new UserFriendlyException("未查询到发起会签节点");
-            if (startStep.IsStartedCountersignEnd)
+            if (startCountersignStep.IsStartedCountersignEnd)
                 throw new UserFriendlyException("该会签已汇总");
-            
+
             var updateCountersigns = new List<WorkflowCountersign>();
-            EndCountersignWithCascade(countersign, workflow.Countersigns, ref updateCountersigns);
+            EndCountersignWithCascade(countersign, workflow.Countersigns, startCountersignStep.BusinessType, ref updateCountersigns);
 
             if (updateCountersigns.Any())
             {
                 var updateSteps = new List<WorkflowStep>();
                 var updateTraces = new List<WorkflowTrace>();
-                HandleStepsWithCascade(startStep, workflow.Steps, workflow.Traces, ref updateSteps, ref updateTraces);
+                HandleStepsByTerminalCs(startCountersignStep, workflow.Steps, workflow.Traces, ref updateSteps, ref updateTraces);
                 if (updateSteps.Any())
-                    await _workflowStepRepository.UpdateRangeAsync(updateSteps, cancellationToken);
+                    await _workflowStepRepository.RemoveRangeAsync(updateSteps, cancellationToken);
                 if (updateTraces.Any())
                     await _workflowTraceRepository.UpdateRangeAsync(updateTraces, cancellationToken);
 
-                if (workflow.IsInCountersign && workflow.CheckIfCountersignOver())
+                if (workflow.CheckIfCountersignOver())
                     workflow.EndCountersign();
-                await _workflowRepository.UpdateAsync(workflow, cancellationToken);
 
                 await _workflowCountersignRepository.UpdateRangeAsync(updateCountersigns, cancellationToken);
             }
 
             //cp会签发起节点变为待办节点
+            //todo 1. create terminal trace 2. 撤回至startStep
+            var newPrevStep = await CreatePrevStepAsync(workflow, startCountersignStep, cancellationToken);
+            await _workflowStepRepository.RemoveAsync(startCountersignStep, cancellationToken: cancellationToken);
 
 
+            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
         }
 
-        private void HandleStepsWithCascade(WorkflowStep step, List<WorkflowStep> steps, List<WorkflowTrace> traces, ref List<WorkflowStep> updateSteps, ref List<WorkflowTrace> updateTraces)
+        private void HandleStepsByTerminalCs(WorkflowStep step, List<WorkflowStep> steps, List<WorkflowTrace> traces, ref List<WorkflowStep> updateSteps, ref List<WorkflowTrace> updateTraces)
         {
             if (step == null) return;
             var nextSteps = steps.Where(d => d.PrevStepId == step.Id && d.Status != EWorkflowStepStatus.Handled).ToList();
@@ -1705,18 +1714,39 @@ namespace Hotline.FlowEngine.Workflows
             {
                 foreach (var nextStep in nextSteps)
                 {
-                    HandleStepsWithCascade(nextStep, steps, traces, ref updateSteps, ref updateTraces);
+                    HandleStepsByTerminalCs(nextStep, steps, traces, ref updateSteps, ref updateTraces);
                 }
             }
             else
             {
-                EndStep(step, ref updateSteps, ref updateTraces);
+                EndStepByTeminalCs(step, traces, ref updateSteps, ref updateTraces);
             }
         }
 
-        private void EndStep(WorkflowStep step, ref List<WorkflowStep> updateSteps, ref List<WorkflowTrace> updateTraces)
+        private void EndStepByTeminalCs(WorkflowStep step, List<WorkflowTrace> traces, ref List<WorkflowStep> updateSteps, ref List<WorkflowTrace> updateTraces)
         {
-            //todo 1. traces 2. status 3. csStatus
+            var opinion = $"该会签未办理完成,由{_sessionContext.OrgName}的{_sessionContext.UserName}手动结束";
+            if (step.IsStartCountersign)
+            {
+                step.CountersignEnd();
+            }
+
+            if (step.Status is not EWorkflowStepStatus.Handled)
+            {
+                step.Handle(_sessionContext.RequiredUserId, _sessionContext.UserName,
+                    _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                    _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
+                    _sessionContext.OrgIsCenter, null);
+                step.Opinion = opinion;
+            }
+            updateSteps.Add(step);
+
+            var trace = traces.FirstOrDefault(d => d.StepId == step.Id);
+            if (trace != null)
+            {
+                _mapper.Map(step, trace);
+                updateTraces.Add(trace);
+            }
         }
 
         /// <summary>
@@ -1724,7 +1754,8 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         /// <param name="countersign"></param>
         /// <param name="updateCountersigns"></param>
-        private void EndCountersignWithCascade(WorkflowCountersign countersign, List<WorkflowCountersign> countersigns, ref List<WorkflowCountersign> updateCountersigns)
+        private void EndCountersignWithCascade(WorkflowCountersign countersign, List<WorkflowCountersign> countersigns,
+            EBusinessType businessType, ref List<WorkflowCountersign> updateCountersigns)
         {
             if (countersign is null) return;
 
@@ -1733,19 +1764,25 @@ namespace Hotline.FlowEngine.Workflows
             {
                 foreach (var childCountersign in childCountersigns)
                 {
-                    EndCountersignWithCascade(childCountersign, countersigns, ref updateCountersigns);
+                    EndCountersignWithCascade(childCountersign, countersigns, businessType, ref updateCountersigns);
                 }
             }
             else
             {
-                EndCountersign(countersign, ref updateCountersigns);
+                EndCountersign(countersign, countersigns, businessType, ref updateCountersigns);
             }
         }
 
-        private void EndCountersign(WorkflowCountersign countersign, ref List<WorkflowCountersign> updateCountersigns)
+        private void EndCountersign(WorkflowCountersign countersign, List<WorkflowCountersign> countersigns,
+            EBusinessType businessType, ref List<WorkflowCountersign> updateCountersigns)
         {
             //todo 1. trace? 先确定展现形式 2. end cs
 
+            countersign.End(null, null, businessType,
+                _sessionContext.RequiredUserId, _sessionContext.UserName,
+                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
+
             /*
             * //结束step会签信息
                    countersignStartStep.CountersignEnd();
@@ -1759,8 +1796,7 @@ namespace Hotline.FlowEngine.Workflows
                    await _workflowCountersignRepository.UpdateAsync(currentCountersign, cancellationToken);
             */
 
-            updateCountersigns.Add();
-            throw new NotImplementedException();
+            updateCountersigns.Add(countersign);
         }
 
         private WorkflowStep? GetStep(List<WorkflowStep> steps, string orgCode, string userId,