Prechádzať zdrojové kódy

Merge branch 'test_Guardian' into test

田爽 2 mesiacov pred
rodič
commit
8a834c8623

+ 62 - 214
src/Hotline.Api/Controllers/OrderController.cs

@@ -5190,6 +5190,7 @@ public class OrderController : BaseController
             .Includes(d => d.OrderPublish)
             .Includes(d => d.OrderVisit, x => x.OrderVisitDetails)
             .Where(d => d.WorkflowId == workflowId)
+            .Where(d=>d.HandleMode != EHandleMode.PreviousNoDisplay)
             .OrderBy(d => d.CreationTime)
             .ToTreeAsync(d => d.Traces, d => d.ParentId, null);
 
@@ -5506,54 +5507,25 @@ public class OrderController : BaseController
         var oneSendBack = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.OneOrgSendBack)?.SettingValue[0]);
         var twoSendBack = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.TwoOrgSendBack)?.SettingValue[0]);
         //var workflow = await _workflowDomainService.GetWorkflowAsync(dto.WorkflowId, withSteps: true, cancellationToken: HttpContext.RequestAborted);
-        var order = await _orderRepository
-            .Queryable()
-            .Includes(d => d.Workflow)
-            .FirstAsync(d => d.Id == dto.OrderId);
+        var order = await _orderRepository.Queryable().Includes(d => d.Workflow).FirstAsync(d => d.Id == dto.OrderId);
         dto.ExpiredTime = order.ExpiredTime;
-        var (currentStep, prevStep, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
-            dto.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles, HttpContext.RequestAborted);
         var audit = new OrderSendBackAudit
         {
             OrderId = dto.OrderId,
             State = ESendBackAuditState.Apply,
             Content = dto.Opinion,
             SendBackData = dto,
-            ApplyOrgId = currentStep.AcceptorOrgId,
-            ApplyOrgName = currentStep!.AcceptorOrgName,
-            SendBackOrgId = prevStep.HandlerOrgId, //prevStep.AcceptorOrgId,
-            SendBackOrgName = prevStep.HandlerOrgName, //prevStep!.AcceptorOrgName,
-            SendBackStepName = prevStep.Name,
-            WorkflowStepSendBackCrTime = currentStep.CreationTime,
             WorkflowOrgId = _sessionContext.RequiredOrgId,
             WorkflowUserId = _sessionContext.RequiredUserId,
             WorkflowRoleIds = _sessionContext.Roles.ToList(),
             Status = order.Status,
-            TraceId = currentStep.Id,
-            OrderExpiredTime = order.ExpiredTime
+            OrderExpiredTime = order.ExpiredTime,
+            AssignStepId = dto.AssignStepId,
+            IsAssign = !string.IsNullOrEmpty(dto.AssignStepId),
         };
         audit.InitId();
         if (dto.Files.Any())
             audit.FileJson = await _fileRepository.AddFileAsync(dto.Files, audit.Id, "", HttpContext.RequestAborted);
-        // if (_appOptions.Value.IsZiGong && prevStep.BusinessType == EBusinessType.Send)
-        // {
-        //     // 平均派单
-        //     var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
-        //     if (averageSendOrder)
-        //     {
-        //         var handler = await _orderDomainService.AverageOrder(HttpContext.RequestAborted);
-        //         dto.Handler = handler;
-        //     }
-        // }
-
-        //todo 需整理各个地市退回业务的需求(指派类型及指派对象)
-        //if (workflow.FlowType == EFlowType.Handle) //该逻辑需放在退回操作前依据业务判断
-        //{
-        //    prevStep.FlowAssignType = prevStep.BusinessType is EBusinessType.Seat ? EFlowAssignType.Role :
-        //        prevStep.BusinessType is EBusinessType.Send ? EFlowAssignType.User : EFlowAssignType.Org;
-        //}
-
-
         if (oneSendBack || twoSendBack)
         {
             var sendBack = await _orderSendBackAuditRepository.Queryable()
@@ -5565,13 +5537,16 @@ public class OrderController : BaseController
                 .AnyAsync();
             if (specialAny) throw UserFriendlyException.SameMessage("工单已存在待审批特提信息!");
             if (order.Workflow.IsInCountersign) throw UserFriendlyException.SameMessage("工单会签中,无法进行退回!");
-            if (oneSendBack && isOrgToCenter && _appOptions.Value.IsZiGong)
+
+			var (currentStep, prevStep, steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
+			   dto.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles, HttpContext.RequestAborted);
+
+			if (oneSendBack && isOrgToCenter && _appOptions.Value.IsZiGong)
             {
                 if (order.SendBackAuditEndTime.HasValue && order.SendBackAuditEndTime.Value < DateTime.Now)
-                    throw UserFriendlyException.SameMessage("工单截至退回时间【" + order.SendBackAuditEndTime.Value.ToString("yyyy-MM-dd HH:mm:ss") +
-                                                            "】,无法进行退回!");
-                var sendBackAgain = await _orderSendBackAuditRepository.Queryable()
-                    .Where(x => x.OrderId == dto.OrderId && x.IsReturnAgain == false).AnyAsync();
+                    throw UserFriendlyException.SameMessage("工单截至退回时间【" + order.SendBackAuditEndTime.Value.ToString("yyyy-MM-dd HH:mm:ss") +"】,无法进行退回!");
+
+                var sendBackAgain = await _orderSendBackAuditRepository.Queryable().Where(x => x.OrderId == dto.OrderId && x.IsReturnAgain == false).AnyAsync();
                 if (sendBackAgain)
                     throw UserFriendlyException.SameMessage("工单已不允许退回!");
             }
@@ -5580,102 +5555,39 @@ public class OrderController : BaseController
             {
                 await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { Status = EOrderStatus.SendBackAudit })
                     .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-            }
+				audit.ApplyOrgId = currentStep.AcceptorOrgId;
+				audit.ApplyOrgName = currentStep!.AcceptorOrgName;
+				///判断是否指定
+				
+                var assignStep = new WorkflowStep();
+				if (audit.IsAssign.Value)
+                {
+                    assignStep = steps.FirstOrDefault(x => x.Id == dto.AssignStepId);
+				}
+				audit.SendBackOrgId = audit.IsAssign.Value ? assignStep .HandlerOrgId: prevStep.HandlerOrgId;
+				audit.SendBackOrgName = audit.IsAssign.Value ? assignStep.HandlerOrgName : prevStep.HandlerOrgName;
+				audit.SendBackStepName = audit.IsAssign.Value ? assignStep.Name : prevStep.Name;
+
+				audit.WorkflowStepSendBackCrTime = currentStep.CreationTime;
+				audit.TraceId = currentStep.Id;
+				await _orderSendBackAuditRepository.AddAsync(audit, HttpContext.RequestAborted);
+			}
             else
             {
                 audit.State = ESendBackAuditState.End;
                 audit.AuditUser = "默认通过";
                 audit.AuditTime = DateTime.Now;
-                // if (prevStep.BusinessType == EBusinessType.Send && dto.Handler != null)
-                // {
-                //     await _orderRepository.Updateable().SetColumns(o => new Orders.Order()
-                //             { CenterToOrgHandlerId = dto.Handler.UserId, CenterToOrgHandlerName = dto.Handler.Username })
-                //         .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-                // }
-
-                var (workflow, currentStep1, prevDefine, prevStep1, newStep, flowDirection) =
-                    await _workflowApplication.PreviousAsync(dto,
-                        async (workflow1, currentStep1, prevStepDefine, prevStep1, newStep) =>
-                        {
-                            var stepAssignInfo =
-                                await _orderApplication.GetOrderPreviousAssignInfoAsync(workflow1, prevStepDefine, prevStep1,
-                                    HttpContext.RequestAborted);
-                            if (stepAssignInfo is null) return;
-                            var validator = new StepAssignInfoValidator();
-                            await validator.ValidateAndThrowAsync(stepAssignInfo);
-                            newStep.Assign(stepAssignInfo);
-                        },
-                        HttpContext.RequestAborted);
-
-                //记录退回后最新的流程节点
-                if (newStep != null && !string.IsNullOrEmpty(newStep.Id))
-                    audit.NewCurrentStepId = newStep.Id;
-
-                if (prevStep.BusinessType == EBusinessType.Send)
-                {
-                    await _orderRepository.Updateable().SetColumns(o => new Order()
-                    { CenterToOrgHandlerId = newStep.HandlerId, CenterToOrgHandlerName = newStep.HandlerName })
-                        .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-                }
-
-                var processType = flowDirection == EFlowDirection.OrgToCenter || flowDirection == EFlowDirection.CenterToCenter
-                    ? EProcessType.Zhiban
-                    : EProcessType.Jiaoban;
-                if (currentStep.AcceptorOrgId != OrgSeedData.CenterId && prevStep.BusinessType == EBusinessType.Send)
-                    order.SendBackNum = order.SendBackNum.HasValue ? order.SendBackNum.Value + 1 : 1;
-                await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { ProcessType = processType, SendBackNum = order.SendBackNum })
-                    .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-                //发送短信TODO
-            }
+				await _orderApplication.OrderPrevious(audit, order, HttpContext.RequestAborted);
+			}
         }
         else
         {
             audit.State = ESendBackAuditState.End;
             audit.AuditUser = "默认通过";
             audit.AuditTime = DateTime.Now;
-            // if (prevStep.BusinessType == EBusinessType.Send && dto.Handler != null)
-            // {
-            //     await _orderRepository.Updateable().SetColumns(o => new Orders.Order()
-            //             { CenterToOrgHandlerId = dto.Handler.UserId, CenterToOrgHandlerName = dto.Handler.Username })
-            //         .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-            // }
-
-            var (workflow, currentStep1, prevDefine, prevStep1, newStep, flowDirection) =
-                await _workflowApplication.PreviousAsync(dto,
-                    async (workflow1, currentStep1, prevStepDefine, prevStep1, newStep) =>
-                    {
-                        var stepAssignInfo =
-                            await _orderApplication.GetOrderPreviousAssignInfoAsync(workflow1, prevStepDefine, prevStep1, HttpContext.RequestAborted);
-                        if (stepAssignInfo is null) return;
-                        var validator = new StepAssignInfoValidator();
-                        await validator.ValidateAndThrowAsync(stepAssignInfo);
-                        newStep.Assign(stepAssignInfo);
-                    },
-                    HttpContext.RequestAborted);
-
-            //记录退回后最新的流程节点
-            if (newStep != null && !string.IsNullOrEmpty(newStep.Id))
-                audit.NewCurrentStepId = newStep.Id;
+            await _orderApplication.OrderPrevious(audit, order, HttpContext.RequestAborted);
 
-            if (prevStep.BusinessType == EBusinessType.Send)
-            {
-                await _orderRepository.Updateable().SetColumns(o => new Order()
-                { CenterToOrgHandlerId = newStep.HandlerId, CenterToOrgHandlerName = newStep.HandlerName })
-                    .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-            }
-
-            var processType = flowDirection == EFlowDirection.OrgToCenter || flowDirection == EFlowDirection.CenterToCenter
-                ? EProcessType.Zhiban
-                : EProcessType.Jiaoban;
-            if (currentStep.AcceptorOrgId != OrgSeedData.CenterId && prevStep.BusinessType == EBusinessType.Send)
-                order.SendBackNum = order.SendBackNum.HasValue ? order.SendBackNum.Value + 1 : 1;
-            await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { ProcessType = processType, SendBackNum = order.SendBackNum })
-                .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-
-            //发送短信TODO
-        }
-
-        await _orderSendBackAuditRepository.AddAsync(audit, HttpContext.RequestAborted);
+		}
     }
 
     /// <summary>
@@ -5706,7 +5618,7 @@ public class OrderController : BaseController
             var order = await _orderRepository.Queryable().Includes(d => d.Workflow).FirstAsync(d => d.Id == sendBack.OrderId);
             if (_appOptions.Value.IsZiGong)
             {
-                var (currentStep, prevStep, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
+                var (currentStep, prevStep,steps ,isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
                     order.WorkflowId, sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(),
                     HttpContext.RequestAborted);
 
@@ -5719,60 +5631,17 @@ public class OrderController : BaseController
                         var handler = await _orderDomainService.AverageOrder(HttpContext.RequestAborted);
                         sendBack.SendBackData.Handler = handler;
                     }
-
-                    await _orderRepository.Updateable().SetColumns(o => new Orders.Order()
-                    {
-                        CenterToOrgHandlerId = sendBack.SendBackData.Handler.UserId,
-                        CenterToOrgHandlerName = sendBack.SendBackData.Handler.Username
-                    })
-                        .Where(o => o.Id == sendBack.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
                 }
             }
-
-            //string applicantId, string applicantOrgId, string[] applicantRoleIds,
-            //    ISessionContext current, CancellationToken cancellationToken);
             sendBack.SendBackData.ExpiredTime = order.ExpiredTime;
-            //var result = await _workflowApplication.PreviousAsync(sendBack.SendBackData, sendBack.WorkflowUserId,
-            //    sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(),
-            //    cancellationToken: HttpContext.RequestAborted);
-
-            var (workflow, currentStep1, prevDefine, prevStep1, newStep, flowDirection) =
-                await _workflowApplication.PreviousAsync(sendBack.SendBackData,
-                    sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(),
-                    async (workflow1, currentStep1, prevStepDefine, prevStep1, newStep) =>
-                    {
-                        var stepAssignInfo =
-                            await _orderApplication.GetOrderPreviousAssignInfoAsync(workflow1, prevStepDefine,
-                                prevStep1, HttpContext.RequestAborted);
-                        if (stepAssignInfo is null) return;
-                        var validator = new StepAssignInfoValidator();
-                        await validator.ValidateAndThrowAsync(stepAssignInfo);
-                        newStep.Assign(stepAssignInfo);
-                    },
-                    HttpContext.RequestAborted);
-
-            //var flowDirection = await _workflowApplication.PreviousAsync(sendBack.SendBackData, sendBack.WorkflowUserId, HttpContext.RequestAborted);
-            var processType = flowDirection == EFlowDirection.OrgToCenter ||
-                              flowDirection == EFlowDirection.CenterToCenter
-                ? EProcessType.Zhiban
-                : EProcessType.Jiaoban;
-            if (sendBack.ApplyOrgId != OrgSeedData.CenterId && sendBack.SendBackOrgId == OrgSeedData.CenterId)
-                order.SendBackNum = order.SendBackNum.HasValue ? order.SendBackNum.Value + 1 : 1;
-            await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { ProcessType = processType, SendBackNum = order.SendBackNum })
-                .Where(o => o.Id == sendBack.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
-
-            //记录退回后最新的流程节点
-            if (newStep != null && !string.IsNullOrEmpty(newStep.Id))
-                sendBack.NewCurrentStepId = newStep.Id;
-            //发送短信TODO
-        }
+			await _orderApplication.OrderPrevious(sendBack, order, HttpContext.RequestAborted);
+		}
         else
         {
             await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { Status = sendBack.Status.Value })
                 .Where(o => o.Id == sendBack.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
-        }
-
-        await _orderSendBackAuditRepository.UpdateAsync(sendBack, HttpContext.RequestAborted);
+			await _orderSendBackAuditRepository.UpdateAsync(sendBack, HttpContext.RequestAborted);
+		}
     }
 
     /// <summary>
@@ -5804,7 +5673,7 @@ public class OrderController : BaseController
                 var order = await _orderRepository.Queryable().Includes(d => d.Workflow).FirstAsync(d => d.Id == sendBack.OrderId);
                 if (_appOptions.Value.IsZiGong)
                 {
-                    var (currentStep, prevStep, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
+                    var (currentStep, prevStep,steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
                         order.WorkflowId, sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(),
                         HttpContext.RequestAborted);
                     if (prevStep.BusinessType == EBusinessType.Send)
@@ -5816,57 +5685,20 @@ public class OrderController : BaseController
                             var handler = await _orderDomainService.AverageOrder(HttpContext.RequestAborted);
                             sendBack.SendBackData.Handler = handler;
                         }
-
-                        await _orderRepository.Updateable().SetColumns(o => new Orders.Order()
-                        {
-                            CenterToOrgHandlerId = sendBack.SendBackData.Handler.UserId,
-                            CenterToOrgHandlerName = sendBack.SendBackData.Handler.Username
-                        })
-                            .Where(o => o.Id == sendBack.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
                     }
                 }
 
                 sendBack.SendBackData.ExpiredTime = order.ExpiredTime;
-                //var result = await _workflowApplication.PreviousAsync(sendBack.SendBackData,
-                //    sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(),
-                //    cancellationToken: HttpContext.RequestAborted);
-                //var flowDirection = await _workflowApplication.PreviousAsync(sendBack.SendBackData, sendBack.WorkflowUserId, HttpContext.RequestAborted);
-
-                var (workflow, currentStep1, prevDefine, prevStep1, newStep, flowDirection) =
-                    await _workflowApplication.PreviousAsync(sendBack.SendBackData,
-                        sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(),
-                        async (workflow1, currentStep1, prevStepDefine, prevStep1, newStep) =>
-                        {
-                            var stepAssignInfo =
-                                await _orderApplication.GetOrderPreviousAssignInfoAsync(workflow1, prevStepDefine,
-                                    prevStep1, HttpContext.RequestAborted);
-                            if (stepAssignInfo is null) return;
-                            var validator = new StepAssignInfoValidator();
-                            await validator.ValidateAndThrowAsync(stepAssignInfo);
-                            newStep.Assign(stepAssignInfo);
-                        },
-                        HttpContext.RequestAborted);
-
-                var processType = flowDirection == EFlowDirection.OrgToCenter || flowDirection == EFlowDirection.CenterToCenter
-                    ? EProcessType.Zhiban
-                    : EProcessType.Jiaoban;
-                if (sendBack.ApplyOrgId != OrgSeedData.CenterId && sendBack.SendBackOrgId == OrgSeedData.CenterId)
-                    order.SendBackNum = order.SendBackNum.HasValue ? order.SendBackNum.Value + 1 : 1;
-                await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { ProcessType = processType, SendBackNum = order.SendBackNum })
-                    .Where(o => o.Id == sendBack.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
-
-                //记录退回后最新的流程节点
-                if (newStep != null && !string.IsNullOrEmpty(newStep.Id))
-                    sendBack.NewCurrentStepId = newStep.Id;
-                //发送短信TODO
-            }
+				await _orderApplication.OrderPrevious(sendBack, order, HttpContext.RequestAborted);
+			}
             else
             {
                 await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { Status = sendBack.Status.Value })
                     .Where(o => o.Id == sendBack.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
-            }
+				await _orderSendBackAuditRepository.UpdateAsync(sendBack, HttpContext.RequestAborted);
+			}
 
-            await _orderSendBackAuditRepository.UpdateAsync(sendBack, HttpContext.RequestAborted);
+           
         }
     }
 
@@ -5965,8 +5797,24 @@ public class OrderController : BaseController
         if (string.IsNullOrEmpty(order.WorkflowId))
             throw UserFriendlyException.SameMessage("该工单未开启流程");
 
-        var (currentStep, prevStep, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
+        var (currentStep, prevStep,steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
             order.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles, HttpContext.RequestAborted);
+		///查询上一节点是否是领导节点
+		///ture 流程排除领导节点 排除当前节点 prevStep.BusinessType == EBusinessType.DepartmentLeader
+		if (_appOptions.Value.IsYiBin  && prevStep.Name.Contains("领导"))
+        {
+            var step = steps.Where(x=> !x.Name.Contains("领导") && x.Code != currentStep.Code).OrderByDescending(x=>x.CreationTime).FirstOrDefault();
+            var resStep = new List<WorkflowStep>
+			{
+				step,
+				prevStep
+			};
+            return new TargetStepInfo {
+				CurrentBusinessType = currentStep.BusinessType,
+				TargetBusinessType = prevStep.BusinessType,
+                Steps = _mapper.Map<List<TargetStep>>(resStep)
+			};
+		}
 
         return new TargetStepInfo
         {

+ 1 - 1
src/Hotline.Api/Controllers/WorkflowController.cs

@@ -443,7 +443,7 @@ public class WorkflowController : BaseController
     {
         var workflow = await _workflowDomainService.GetWorkflowAsync(workflowId, withTracesTree: true,
             cancellationToken: HttpContext.RequestAborted);
-        workflow.Traces = workflow.Traces.Where(d => d.TraceStyle == ETraceStyle.Flow).ToList();
+        workflow.Traces = workflow.Traces.Where(d => d.TraceStyle == ETraceStyle.Flow).Where(d => d.HandleMode != EHandleMode.PreviousNoDisplay).ToList();
 
         var workflowDto = _mapper.Map<WorkflowDto>(workflow);
         if (workflowDto.Traces.Any())

+ 1 - 1
src/Hotline.Application/FlowEngine/IWorkflowApplication.cs

@@ -115,7 +115,7 @@ namespace Hotline.Application.FlowEngine
         /// <summary>
         /// 检查退回节点信息
         /// </summary>
-        Task<(WorkflowStep currentStep, WorkflowStep prevStep, bool isOrgToCenter, bool isSecondToFirstOrgLevel)>
+        Task<(WorkflowStep currentStep, WorkflowStep prevStep,List<WorkflowStep> steps, bool isOrgToCenter, bool isSecondToFirstOrgLevel)>
             GetPreviousInformationAsync(string workflowId, string operatorId, string operatorOrgId, string[] roles,
                 CancellationToken cancellationToken);
 

+ 2 - 2
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -1867,7 +1867,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     /// <summary>
     /// 检查退回节点信息
     /// </summary>
-    public async Task<(WorkflowStep currentStep, WorkflowStep prevStep, bool isOrgToCenter, bool isSecondToFirstOrgLevel)>
+    public async Task<(WorkflowStep currentStep, WorkflowStep prevStep,List<WorkflowStep> steps, bool isOrgToCenter, bool isSecondToFirstOrgLevel)>
         GetPreviousInformationAsync(string workflowId, string operatorId, string operatorOrgId, string[] roles,
             CancellationToken cancellationToken)
     {
@@ -1881,7 +1881,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                                       prevStep.HandlerType is EHandlerType.OrgLevel &&
                                       prevStep.Handlers.First().Key.CheckIfOrgLevelIs(1) &&
                                       !prevStep.Handlers.First().Key.IsCenter();
-        return (currentStep, prevStep, isOrgToCenter, isSecondToFirstOrgLevel);
+        return (currentStep, prevStep, workflow.Steps, isOrgToCenter, isSecondToFirstOrgLevel);
     }
 
     /// <summary>

+ 4 - 1
src/Hotline.Application/Orders/IOrderApplication.cs

@@ -454,5 +454,8 @@ namespace Hotline.Application.Orders
         /// </summary>
         /// <returns></returns>
         ISugarQueryable<OrderDelay> WaitDelayList(DelayListDto dto);
-    }
+
+        Task OrderPrevious(OrderSendBackAudit sendBack, Order order, CancellationToken cancellationToken);
+
+	}
 }

+ 79 - 3
src/Hotline.Application/Orders/OrderApplication.cs

@@ -59,6 +59,7 @@ using WordInfo = PanGu.WordInfo;
 using Hotline.Repository.SqlSugar.Orders;
 using Quartz.Simpl;
 using J2N.Text;
+using Hotline.Application.FlowEngine;
 
 namespace Hotline.Application.Orders;
 
@@ -108,8 +109,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly IRepository<OrderTsDetails> _orderTsDetailsRepository;
     private readonly IRepository<KnowledgeQuote> _knowledgeQuoteRepository;
     private readonly IRepository<OrderSpecial> _orderSpecialRepository;
+	private readonly IWorkflowApplication _workflowApplication;
 
-    public OrderApplication(
+	public OrderApplication(
         IOrderDomainService orderDomainService,
         IOrderRepository orderRepository,
         IWorkflowDomainService workflowDomainService,
@@ -152,7 +154,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         IOrderDelayRepository orderDelayRepository,
         IRepository<OrderTsDetails> orderTsDetailsRepository,
         IRepository<KnowledgeQuote> knowledgeQuoteRepository,
-        IRepository<OrderSpecial> orderSpecialRepository)
+        IRepository<OrderSpecial> orderSpecialRepository,
+		IWorkflowApplication workflowApplication)
     {
         _orderDomainService = orderDomainService;
         _workflowDomainService = workflowDomainService;
@@ -197,7 +200,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _orderTsDetailsRepository = orderTsDetailsRepository;
         _knowledgeQuoteRepository = knowledgeQuoteRepository;
         _orderSpecialRepository = orderSpecialRepository;
-    }
+        _workflowApplication = workflowApplication;
+
+	}
 
     /// <summary>
     /// 更新工单办理期满时间(延期调用,其他不调用)
@@ -5145,4 +5150,75 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 
         return query;
     }
+
+    #region 退回重写
+
+	public async Task OrderPrevious(OrderSendBackAudit sendBack,Order order, CancellationToken cancellationToken) {
+
+		var (workflow, currentStep, prevDefine, prevStep, newStep, flowDirection) =
+			   await _workflowApplication.PreviousAsync(sendBack.SendBackData,
+				   async (workflow1, currentStep1, prevStepDefine, prevStep1, newStep) =>
+				   {
+					   var stepAssignInfo =
+						   await GetOrderPreviousAssignInfoAsync(workflow1, prevStepDefine, prevStep1, cancellationToken);
+					   if (stepAssignInfo is null) return;
+					   var validator = new StepAssignInfoValidator();
+					   await validator.ValidateAndThrowAsync(stepAssignInfo);
+					   newStep.Assign(stepAssignInfo);
+					   if (sendBack.AssignStepId != prevStep1.Id) prevStep1.HandleMode = EHandleMode.PreviousNoDisplay;
+				   },
+				   cancellationToken);
+
+		if (sendBack.IsAssign.Value)
+        {
+			while (sendBack.AssignStepId != prevStep.Id)
+			{
+                (workflow, currentStep, prevDefine, prevStep, newStep, flowDirection) =
+               await _workflowApplication.PreviousAsync(sendBack.SendBackData,
+                   async (workflow1, currentStep1, prevStepDefine, prevStep1, newStep) =>
+                   {
+                       var stepAssignInfo =
+                           await GetOrderPreviousAssignInfoAsync(workflow1, prevStepDefine, prevStep1, cancellationToken);
+                       if (stepAssignInfo is null) return;
+                       var validator = new StepAssignInfoValidator();
+                       await validator.ValidateAndThrowAsync(stepAssignInfo);
+                       newStep.Assign(stepAssignInfo);
+                       if (sendBack.AssignStepId != prevStep.Id) prevStep1.HandleMode = EHandleMode.PreviousNoDisplay;
+                   },
+                   cancellationToken);
+			}
+		}
+
+        sendBack.ApplyOrgId = currentStep.AcceptorOrgId;
+        sendBack.ApplyOrgName = currentStep!.AcceptorOrgName;
+        sendBack.SendBackOrgId = prevStep.HandlerOrgId;
+        sendBack.SendBackOrgName = prevStep.HandlerOrgName;
+        sendBack.SendBackStepName = prevStep.Name;
+        sendBack.WorkflowStepSendBackCrTime = currentStep.CreationTime;
+        sendBack.TraceId = currentStep.Id;
+		//记录退回后最新的流程节点
+		if (newStep != null && !string.IsNullOrEmpty(newStep.Id))
+			sendBack.NewCurrentStepId = newStep.Id;
+
+		var processType = flowDirection == EFlowDirection.OrgToCenter || flowDirection == EFlowDirection.CenterToCenter
+			? EProcessType.Zhiban
+			: EProcessType.Jiaoban;
+		if (currentStep.AcceptorOrgId != OrgSeedData.CenterId && prevStep.BusinessType == EBusinessType.Send)
+			order.SendBackNum = order.SendBackNum.HasValue ? order.SendBackNum.Value + 1 : 1;
+
+		if (prevStep.BusinessType == EBusinessType.Send)
+        {
+            await _orderRepository.Updateable().SetColumns(o => new Order()
+            { CenterToOrgHandlerId = newStep.HandlerId, CenterToOrgHandlerName = newStep.HandlerName, ProcessType = processType, SendBackNum = order.SendBackNum })
+                .Where(o => o.Id == order.Id).ExecuteCommandAsync(cancellationToken);
+        }
+        else {
+			await _orderRepository.Updateable().SetColumns(o => new Order() { ProcessType = processType, SendBackNum = order.SendBackNum })
+			.Where(o => o.Id == order.Id).ExecuteCommandAsync(cancellationToken);
+		}
+	
+
+		await _orderSendBackAuditRepository.AddAsync(sendBack, cancellationToken);
+	}
+	#endregion
 }

+ 3 - 0
src/Hotline.Share/Dtos/Order/OrderPreviousDto.cs

@@ -7,4 +7,7 @@ public class OrderPreviousDto : PreviousWorkflowDto
 {
     public string OrderId { get; set; }
 
+    public string? AssignStepId { get; set; }
+
+
 }

+ 10 - 1
src/Hotline.Share/Dtos/Order/TargetStepInfo.cs

@@ -1,4 +1,6 @@
-using Hotline.Share.Enums.FlowEngine;
+using Hotline.Share.Dtos.FlowEngine;
+using Hotline.Share.Dtos.FlowEngine.Workflow;
+using Hotline.Share.Enums.FlowEngine;
 
 namespace Hotline.Share.Dtos.Order;
 
@@ -6,4 +8,11 @@ public class TargetStepInfo
 {
     public EBusinessType CurrentBusinessType { get; set; }
     public EBusinessType TargetBusinessType { get; set; }
+
+    public List<TargetStep> Steps { get; set; }
+}
+public class TargetStep {
+	public string Id { get; set; }
+	public string Name { get; set; }
+
 }

+ 13 - 0
src/Hotline/Orders/OrderSendBackAudit.cs

@@ -162,5 +162,18 @@ namespace Hotline.Orders
 		[SugarColumn(ColumnDescription = "工单超期时间")]
 		public DateTime? OrderExpiredTime { get; set; }
 
+
+		/// <summary>
+		/// 指定节点Id
+		/// </summary>
+		[SugarColumn(ColumnDescription = "指定节点Id")]
+		public string? AssignStepId { get; set; }
+
+		/// <summary>
+		/// 是否指定节点
+		/// </summary>
+		[SugarColumn(ColumnDescription = "是否指定节点")]
+		public bool? IsAssign { get; set; }
+
 	}
 }