xf 1 year ago
parent
commit
eeffeabf34

+ 5 - 3
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -155,7 +155,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         var flowAssignInfo =
         var flowAssignInfo =
             await GetNextStepFlowAssignInfoAsync(workflow, startStep, dto, firstStepDefine, isNextDynamic, cancellationToken);
             await GetNextStepFlowAssignInfoAsync(workflow, startStep, dto, firstStepDefine, isNextDynamic, cancellationToken);
 
 
-        
+        var firstStepHandlers = await GetNextStepHandlersAsync(workflow, firstStepDefine, dto, cancellationToken);
 
 
         var counterSignType = _workflowDomainService.GetCounterSignType(startStep.BusinessType);
         var counterSignType = _workflowDomainService.GetCounterSignType(startStep.BusinessType);
 
 
@@ -191,7 +191,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
             _sessionContext.OrgName);
             _sessionContext.OrgName);
 
 
         await _workflowDomainService.StartAsync(workflow, startStep, dto, firstStepDefine, isNextDynamic,
         await _workflowDomainService.StartAsync(workflow, startStep, dto, firstStepDefine, isNextDynamic,
-            flowAssignInfo, counterSignType, expiredTime, cancellationToken);
+            flowAssignInfo, counterSignType, expiredTime, firstStepHandlers, cancellationToken);
 
 
         return workflow.Id;
         return workflow.Id;
     }
     }
@@ -259,8 +259,10 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         var flowAssignInfo =
         var flowAssignInfo =
             await GetNextStepFlowAssignInfoAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic, cancellationToken);
             await GetNextStepFlowAssignInfoAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic, cancellationToken);
 
 
+        var nextStepHandlers = await GetNextStepHandlersAsync(workflow, nextStepDefine, dto, cancellationToken);
+
         await _workflowDomainService.NextAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic,
         await _workflowDomainService.NextAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic,
-            flowAssignInfo, expiredTime, cancellationToken);
+            flowAssignInfo, expiredTime, nextStepHandlers, cancellationToken);
 
 
         return workflow;
         return workflow;
     }
     }

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

@@ -23,7 +23,7 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         /// </summary>
         Task StartAsync(Workflow workflow, WorkflowStep startStep, BasicWorkflowDto dto, StepDefine firstStepDefine,
         Task StartAsync(Workflow workflow, WorkflowStep startStep, BasicWorkflowDto dto, StepDefine firstStepDefine,
             bool isNextDynamic, FlowAssignInfo flowAssignInfo, ECounterSignType? counterSignType, DateTime? expiredTime,
             bool isNextDynamic, FlowAssignInfo flowAssignInfo, ECounterSignType? counterSignType, DateTime? expiredTime,
-            CancellationToken cancellationToken);
+            List<WorkflowStepHandler> stepHandlers, CancellationToken cancellationToken);
 
 
         /// <summary>
         /// <summary>
         /// 查询工作流
         /// 查询工作流
@@ -48,7 +48,7 @@ namespace Hotline.FlowEngine.Workflows
         /// 办理(流转至下一节点)
         /// 办理(流转至下一节点)
         /// </summary>
         /// </summary>
         Task NextAsync(Workflow workflow, WorkflowStep currentStep, NextWorkflowDto dto, StepDefine nextStepDefine,
         Task NextAsync(Workflow workflow, WorkflowStep currentStep, NextWorkflowDto dto, StepDefine nextStepDefine,
-            bool isNextDynamic, FlowAssignInfo flowAssignInfo, DateTime? expiredTime,
+            bool isNextDynamic, FlowAssignInfo flowAssignInfo, DateTime? expiredTime, List<WorkflowStepHandler> stepHandlers,
             CancellationToken cancellationToken);
             CancellationToken cancellationToken);
 
 
         /// <summary>
         /// <summary>

+ 50 - 25
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -98,7 +98,8 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         /// </summary>
         public async Task StartAsync(Workflow workflow, WorkflowStep startStep, BasicWorkflowDto dto,
         public async Task StartAsync(Workflow workflow, WorkflowStep startStep, BasicWorkflowDto dto,
             StepDefine firstStepDefine, bool isNextDynamic, FlowAssignInfo flowAssignInfo,
             StepDefine firstStepDefine, bool isNextDynamic, FlowAssignInfo flowAssignInfo,
-            ECounterSignType? counterSignType, DateTime? expiredTime, CancellationToken cancellationToken)
+            ECounterSignType? counterSignType, DateTime? expiredTime, List<WorkflowStepHandler> stepHandlers,
+            CancellationToken cancellationToken)
         {
         {
             //1. 创建first节点 (和trace)2.办理开始节点 
             //1. 创建first节点 (和trace)2.办理开始节点 
 
 
@@ -121,7 +122,7 @@ namespace Hotline.FlowEngine.Workflows
 
 
             //firststeps
             //firststeps
             var firstSteps = await CreateNextStepsAsync(workflow, startStep, dto, firstStepDefine,
             var firstSteps = await CreateNextStepsAsync(workflow, startStep, dto, firstStepDefine,
-                isNextDynamic, flowAssignInfo, expiredTime, cancellationToken);
+                isNextDynamic, flowAssignInfo, expiredTime, stepHandlers, cancellationToken);
             if (firstSteps.Any())
             if (firstSteps.Any())
                 workflow.Steps.AddRange(firstSteps);
                 workflow.Steps.AddRange(firstSteps);
 
 
@@ -193,7 +194,7 @@ namespace Hotline.FlowEngine.Workflows
             if (withCountersigns)
             if (withCountersigns)
                 query = query.Includes(d => d.Countersigns, x => x.Members);
                 query = query.Includes(d => d.Countersigns, x => x.Members);
             if (withSteps)
             if (withSteps)
-                query = query.Includes(d => d.Steps);
+                query = query.Includes(d => d.Steps, x => x.StepHandlers);
             //if (withTraces)
             //if (withTraces)
             //    query = query.Includes(d => d.Traces);
             //    query = query.Includes(d => d.Traces);
 
 
@@ -313,7 +314,7 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         /// </summary>
         public async Task NextAsync(Workflow workflow, WorkflowStep currentStep, NextWorkflowDto dto,
         public async Task NextAsync(Workflow workflow, WorkflowStep currentStep, NextWorkflowDto dto,
             StepDefine nextStepDefine, bool isNextDynamic, FlowAssignInfo flowAssignInfo,
             StepDefine nextStepDefine, bool isNextDynamic, FlowAssignInfo flowAssignInfo,
-            DateTime? expiredTime, CancellationToken cancellationToken)
+            DateTime? expiredTime, List<WorkflowStepHandler> stepHandlers, CancellationToken cancellationToken)
         {
         {
             ValidatePermission(workflow, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
             ValidatePermission(workflow, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
             //CheckWhetherRunnable(workflow.Status);
             //CheckWhetherRunnable(workflow.Status);
@@ -405,7 +406,10 @@ namespace Hotline.FlowEngine.Workflows
                     .ExecuteCommandAsync();
                     .ExecuteCommandAsync();
             }
             }
 
 
-            await _workflowStepRepository.UpdateRangeAsync(updateSteps, cancellationToken);
+            //await _workflowStepRepository.UpdateRangeAsync(updateSteps, cancellationToken);
+            await _workflowStepRepository.UpdateNav(updateSteps)
+                .Include(d => d.StepHandlers)
+                .ExecuteCommandAsync();
 
 
             await NextTraceAsync(workflow, dto, currentStep, cancellationToken);
             await NextTraceAsync(workflow, dto, currentStep, cancellationToken);
 
 
@@ -454,7 +458,7 @@ namespace Hotline.FlowEngine.Workflows
 
 
             //创建下一/N个节点(会签汇总节点:会签未全部办理时不创建,最后一个会签办理节点创建会签汇总节点)
             //创建下一/N个节点(会签汇总节点:会签未全部办理时不创建,最后一个会签办理节点创建会签汇总节点)
             var nextSteps = await CreateNextStepsAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic,
             var nextSteps = await CreateNextStepsAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic,
-                flowAssignInfo, expiredTime, cancellationToken);
+                flowAssignInfo, expiredTime, stepHandlers, cancellationToken);
 
 
             //赋值当前节点的下级办理节点
             //赋值当前节点的下级办理节点
             if (dto.IsStartCountersign
             if (dto.IsStartCountersign
@@ -1117,8 +1121,12 @@ namespace Hotline.FlowEngine.Workflows
             WorkflowStep currentStep, EReviewResult? reviewResult = EReviewResult.Unknown,
             WorkflowStep currentStep, EReviewResult? reviewResult = EReviewResult.Unknown,
             CancellationToken cancellationToken = default)
             CancellationToken cancellationToken = default)
         {
         {
+            var endStepHandles = new List<WorkflowStepHandler>{WorkflowStepHandler.Create(workflow.Id, workflow.ExternalId,
+                EFlowAssignType.User, _sessionContext.RequiredUserId, _sessionContext.UserName,
+                _sessionContext.RequiredOrgId, _sessionContext.OrgName)};
+
             //create endStep
             //create endStep
-            var endStep = await CreateEndStepAsync(workflow, endStepDefine, currentStep, cancellationToken);
+            var endStep = await CreateEndStepAsync(workflow, endStepDefine, currentStep, endStepHandles, cancellationToken);
             workflow.Steps.Add(endStep);
             workflow.Steps.Add(endStep);
 
 
             //update endTrace
             //update endTrace
@@ -1228,7 +1236,10 @@ namespace Hotline.FlowEngine.Workflows
             DateTime? expiredTime, CancellationToken cancellationToken)
             DateTime? expiredTime, CancellationToken cancellationToken)
         {
         {
             var startStep = CreateStartStep(workflow, startStepDefine, dto, handles, stepHandlers, expiredTime);
             var startStep = CreateStartStep(workflow, startStepDefine, dto, handles, stepHandlers, expiredTime);
-            await _workflowStepRepository.AddAsync(startStep, cancellationToken);
+            //await _workflowStepRepository.AddAsync(startStep, cancellationToken);
+            await _workflowStepRepository.AddNav(startStep)
+                .Include(d => d.StepHandlers)
+                .ExecuteCommandAsync();
             await CreateTraceAsync(workflow, startStep, traceStatus, cancellationToken);
             await CreateTraceAsync(workflow, startStep, traceStatus, cancellationToken);
             return startStep;
             return startStep;
         }
         }
@@ -1252,7 +1263,7 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         /// </summary>
         private async Task<List<WorkflowStep>> CreateNextStepsAsync(Workflow workflow, WorkflowStep currentStep,
         private async Task<List<WorkflowStep>> CreateNextStepsAsync(Workflow workflow, WorkflowStep currentStep,
             BasicWorkflowDto dto, StepDefine nextStepDefine, bool isNextDynamic, FlowAssignInfo flowAssignInfo,
             BasicWorkflowDto dto, StepDefine nextStepDefine, bool isNextDynamic, FlowAssignInfo flowAssignInfo,
-            DateTime? expiredTime, CancellationToken cancellationToken)
+            DateTime? expiredTime, List<WorkflowStepHandler> stepHandlers, CancellationToken cancellationToken)
         {
         {
             List<WorkflowStep> nextSteps = new();
             List<WorkflowStep> nextSteps = new();
             if (currentStep.IsInCountersign())
             if (currentStep.IsInCountersign())
@@ -1267,13 +1278,13 @@ namespace Hotline.FlowEngine.Workflows
                         {
                         {
                             //依据会签策略创建会签下一级节点
                             //依据会签策略创建会签下一级节点
                             nextSteps = await CreateCountersignStepsAsync(workflow, nextStepDefine, currentStep, dto,
                             nextSteps = await CreateCountersignStepsAsync(workflow, nextStepDefine, currentStep, dto,
-                                flowAssignInfo.FlowAssignType, expiredTime, cancellationToken);
+                                flowAssignInfo.FlowAssignType, expiredTime, stepHandlers, cancellationToken);
                         }
                         }
                         else
                         else
                         {
                         {
                             //创建普通节点(根据配置)
                             //创建普通节点(根据配置)
                             nextSteps = await CreateConfigStepsAsync(workflow, nextStepDefine, currentStep, dto,
                             nextSteps = await CreateConfigStepsAsync(workflow, nextStepDefine, currentStep, dto,
-                                flowAssignInfo, EWorkflowTraceStatus.Normal, expiredTime, cancellationToken);
+                                flowAssignInfo, EWorkflowTraceStatus.Normal, expiredTime, stepHandlers, cancellationToken);
                         }
                         }
                     }
                     }
                     else
                     else
@@ -1300,7 +1311,7 @@ namespace Hotline.FlowEngine.Workflows
                     {
                     {
                         //依据会签策略创建会签下一级节点
                         //依据会签策略创建会签下一级节点
                         nextSteps = await CreateCountersignStepsAsync(workflow, nextStepDefine, currentStep, dto,
                         nextSteps = await CreateCountersignStepsAsync(workflow, nextStepDefine, currentStep, dto,
-                            flowAssignInfo.FlowAssignType, expiredTime, cancellationToken);
+                            flowAssignInfo.FlowAssignType, expiredTime, stepHandlers, cancellationToken);
                     }
                     }
                 }
                 }
             }
             }
@@ -1308,19 +1319,19 @@ namespace Hotline.FlowEngine.Workflows
             {
             {
                 //依据会签策略创建会签下一级节点
                 //依据会签策略创建会签下一级节点
                 nextSteps = await CreateCountersignStepsAsync(workflow, nextStepDefine, currentStep, dto,
                 nextSteps = await CreateCountersignStepsAsync(workflow, nextStepDefine, currentStep, dto,
-                    flowAssignInfo.FlowAssignType, expiredTime, cancellationToken);
+                    flowAssignInfo.FlowAssignType, expiredTime, stepHandlers, cancellationToken);
             }
             }
             else if (isNextDynamic)
             else if (isNextDynamic)
             {
             {
                 //创建动态下一级节点
                 //创建动态下一级节点
                 nextSteps = await CreateDynamicStepsAsync(workflow, nextStepDefine, currentStep, dto, flowAssignInfo,
                 nextSteps = await CreateDynamicStepsAsync(workflow, nextStepDefine, currentStep, dto, flowAssignInfo,
-                    expiredTime, cancellationToken);
+                    expiredTime, stepHandlers, cancellationToken);
             }
             }
             else
             else
             {
             {
                 //创建普通节点(根据配置)
                 //创建普通节点(根据配置)
                 nextSteps = await CreateConfigStepsAsync(workflow, nextStepDefine, currentStep, dto, flowAssignInfo,
                 nextSteps = await CreateConfigStepsAsync(workflow, nextStepDefine, currentStep, dto, flowAssignInfo,
-                    EWorkflowTraceStatus.Normal, expiredTime, cancellationToken);
+                    EWorkflowTraceStatus.Normal, expiredTime, stepHandlers, cancellationToken);
             }
             }
 
 
             return nextSteps;
             return nextSteps;
@@ -1333,6 +1344,7 @@ namespace Hotline.FlowEngine.Workflows
             BasicWorkflowDto dto,
             BasicWorkflowDto dto,
             FlowAssignInfo flowAssignInfo,
             FlowAssignInfo flowAssignInfo,
             DateTime? expiredTime,
             DateTime? expiredTime,
+            List<WorkflowStepHandler> stepHandlers,
             CancellationToken cancellationToken)
             CancellationToken cancellationToken)
         {
         {
             var handlerType = nextStepDefine.InstancePolicy switch
             var handlerType = nextStepDefine.InstancePolicy switch
@@ -1346,7 +1358,7 @@ namespace Hotline.FlowEngine.Workflows
             };
             };
 
 
             return await CreateStepsAsync(workflow, nextStepDefine, prevStep, dto,
             return await CreateStepsAsync(workflow, nextStepDefine, prevStep, dto,
-                flowAssignInfo.FlowAssignType, dto.NextHandlers, null, EWorkflowStepStatus.WaitForAccept,
+                flowAssignInfo.FlowAssignType, dto.NextHandlers, stepHandlers, null, EWorkflowStepStatus.WaitForAccept,
                 ECountersignPosition.None, false, EWorkflowTraceStatus.Normal, handlerType, expiredTime, cancellationToken);
                 ECountersignPosition.None, false, EWorkflowTraceStatus.Normal, handlerType, expiredTime, cancellationToken);
         }
         }
 
 
@@ -1357,6 +1369,7 @@ namespace Hotline.FlowEngine.Workflows
             BasicWorkflowDto dto,
             BasicWorkflowDto dto,
             EFlowAssignType flowAssignType,
             EFlowAssignType flowAssignType,
             DateTime? expiredTime,
             DateTime? expiredTime,
+            List<WorkflowStepHandler> stepHandlers,
             CancellationToken cancellationToken
             CancellationToken cancellationToken
         )
         )
         {
         {
@@ -1372,7 +1385,7 @@ namespace Hotline.FlowEngine.Workflows
                 _ => throw new ArgumentOutOfRangeException()
                 _ => throw new ArgumentOutOfRangeException()
             };
             };
 
 
-            return CreateStepsAsync(workflow, stepDefine, prevStep, dto, flowAssignType, dto.NextHandlers,
+            return CreateStepsAsync(workflow, stepDefine, prevStep, dto, flowAssignType, dto.NextHandlers, stepHandlers,
                 countersignId, EWorkflowStepStatus.WaitForAccept, prevStep.GetNextStepCountersignPosition(),
                 countersignId, EWorkflowStepStatus.WaitForAccept, prevStep.GetNextStepCountersignPosition(),
                 false, EWorkflowTraceStatus.Normal, handlerType, expiredTime, cancellationToken);
                 false, EWorkflowTraceStatus.Normal, handlerType, expiredTime, cancellationToken);
         }
         }
@@ -1458,6 +1471,10 @@ namespace Hotline.FlowEngine.Workflows
                 _sessionContext.RequiredOrgId, _sessionContext.OrgName,
                 _sessionContext.RequiredOrgId, _sessionContext.OrgName,
                 _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
                 _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
                 _sessionContext.OrgIsCenter, opinion, nextStepCode);
                 _sessionContext.OrgIsCenter, opinion, nextStepCode);
+
+            var handler = step.GetActualHandler(_sessionContext.Roles, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
+            if (handler is not null)
+                handler.IsActualHandler = true;
         }
         }
 
 
 
 
@@ -1755,7 +1772,7 @@ namespace Hotline.FlowEngine.Workflows
                 ? await CreateStartStepAsync(workflow, targetStepDefine, dto, dto.NextHandlers, stepHandlers, traceStatus, expiredTime,
                 ? await CreateStartStepAsync(workflow, targetStepDefine, dto, dto.NextHandlers, stepHandlers, traceStatus, expiredTime,
                     cancellationToken)
                     cancellationToken)
                 : (await CreateStepsAsync(workflow, targetStepDefine, targetPrevStep, dto,
                 : (await CreateStepsAsync(workflow, targetStepDefine, targetPrevStep, dto,
-                    flowAssignInfo.FlowAssignType, dto.NextHandlers,
+                    flowAssignInfo.FlowAssignType, dto.NextHandlers, stepHandlers,
                     null, EWorkflowStepStatus.WaitForAccept, ECountersignPosition.None, true, traceStatus,
                     null, EWorkflowStepStatus.WaitForAccept, ECountersignPosition.None, true, traceStatus,
                     null, expiredTime, cancellationToken)).First();
                     null, expiredTime, cancellationToken)).First();
 
 
@@ -1806,6 +1823,7 @@ namespace Hotline.FlowEngine.Workflows
             Workflow workflow,
             Workflow workflow,
             StepDefine endStepDefine,
             StepDefine endStepDefine,
             WorkflowStep prevStep,
             WorkflowStep prevStep,
+            List<WorkflowStepHandler> stepHandlers,
             CancellationToken cancellationToken)
             CancellationToken cancellationToken)
         {
         {
             if (workflow.Steps.Any(d => d.StepType == EStepType.End))
             if (workflow.Steps.Any(d => d.StepType == EStepType.End))
@@ -1814,8 +1832,8 @@ namespace Hotline.FlowEngine.Workflows
             var handler = new Kv { Key = _sessionContext.RequiredUserId, Value = _sessionContext.UserName };
             var handler = new Kv { Key = _sessionContext.RequiredUserId, Value = _sessionContext.UserName };
 
 
             var step = CreateStep(workflow, endStepDefine, prevStep, null, new List<Kv> { handler },
             var step = CreateStep(workflow, endStepDefine, prevStep, null, new List<Kv> { handler },
-                null, null, null, EWorkflowStepStatus.WaitForAccept, ECountersignPosition.None, DateTime.Now,
-                endStepDefine.Name, true);
+              stepHandlers, null, null, null, EWorkflowStepStatus.WaitForAccept,
+              ECountersignPosition.None, DateTime.Now, endStepDefine.Name, true);
 
 
             //step.Accept(_sessionContext.RequiredUserId, _sessionContext.UserName,
             //step.Accept(_sessionContext.RequiredUserId, _sessionContext.UserName,
             //    _sessionContext.RequiredOrgId, _sessionContext.OrgName,
             //    _sessionContext.RequiredOrgId, _sessionContext.OrgName,
@@ -1839,6 +1857,7 @@ namespace Hotline.FlowEngine.Workflows
             FlowAssignInfo flowAssignInfo,
             FlowAssignInfo flowAssignInfo,
             EWorkflowTraceStatus traceStatus,
             EWorkflowTraceStatus traceStatus,
             DateTime? expiredTime,
             DateTime? expiredTime,
+            List<WorkflowStepHandler> stepHandlers,
             CancellationToken cancellationToken)
             CancellationToken cancellationToken)
         {
         {
             List<Kv> handlers;
             List<Kv> handlers;
@@ -1861,8 +1880,8 @@ namespace Hotline.FlowEngine.Workflows
             }
             }
 
 
             return await CreateStepsAsync(workflow, stepDefine, prevStep, dto, flowAssignInfo.FlowAssignType, handlers,
             return await CreateStepsAsync(workflow, stepDefine, prevStep, dto, flowAssignInfo.FlowAssignType, handlers,
-                null, EWorkflowStepStatus.WaitForAccept, ECountersignPosition.None, true, traceStatus,
-                null, expiredTime, cancellationToken);
+                stepHandlers, null, EWorkflowStepStatus.WaitForAccept, ECountersignPosition.None,
+                true, traceStatus, null, expiredTime, cancellationToken);
         }
         }
 
 
         private async Task<List<WorkflowStep>> CreateStepsAsync(
         private async Task<List<WorkflowStep>> CreateStepsAsync(
@@ -1872,6 +1891,7 @@ namespace Hotline.FlowEngine.Workflows
             BasicWorkflowDto dto,
             BasicWorkflowDto dto,
             EFlowAssignType? flowAssignType,
             EFlowAssignType? flowAssignType,
             List<Kv> handlers,
             List<Kv> handlers,
+            List<WorkflowStepHandler> stepHandlers,
             string? countersignId,
             string? countersignId,
             EWorkflowStepStatus stepStatus,
             EWorkflowStepStatus stepStatus,
             ECountersignPosition csPosition,
             ECountersignPosition csPosition,
@@ -1892,7 +1912,7 @@ namespace Hotline.FlowEngine.Workflows
                 foreach (var handler in handlers)
                 foreach (var handler in handlers)
                 {
                 {
                     var step = CreateStep(workflow, stepDefine, prevStep, flowAssignType, new List<Kv> { handler },
                     var step = CreateStep(workflow, stepDefine, prevStep, flowAssignType, new List<Kv> { handler },
-                        dto.NextStepCode, dto.NextMainHandler, countersignId,
+                        stepHandlers, dto.NextStepCode, dto.NextMainHandler, countersignId,
                         stepStatus, csPosition, expiredTime, dto.NextStepName, isOrigin, handlerType);
                         stepStatus, csPosition, expiredTime, dto.NextStepName, isOrigin, handlerType);
 
 
                     steps.Add(step);
                     steps.Add(step);
@@ -1900,14 +1920,17 @@ namespace Hotline.FlowEngine.Workflows
             }
             }
             else
             else
             {
             {
-                var step = CreateStep(workflow, stepDefine, prevStep, flowAssignType, handlers,
+                var step = CreateStep(workflow, stepDefine, prevStep, flowAssignType, handlers, stepHandlers,
                     dto.NextStepCode, dto.NextMainHandler, countersignId,
                     dto.NextStepCode, dto.NextMainHandler, countersignId,
                     stepStatus, csPosition, expiredTime, dto.NextStepName, isOrigin, handlerType);
                     stepStatus, csPosition, expiredTime, dto.NextStepName, isOrigin, handlerType);
 
 
                 steps.Add(step);
                 steps.Add(step);
             }
             }
 
 
-            await _workflowStepRepository.AddRangeAsync(steps, cancellationToken);
+            //await _workflowStepRepository.AddRangeAsync(steps, cancellationToken);
+            await _workflowStepRepository.AddNav(steps)
+                .Include(d => d.StepHandlers)
+                .ExecuteCommandAsync();
 
 
             //create traces todo add range traces
             //create traces todo add range traces
             foreach (var step in steps)
             foreach (var step in steps)
@@ -2160,6 +2183,7 @@ namespace Hotline.FlowEngine.Workflows
             WorkflowStep prevStep,
             WorkflowStep prevStep,
             EFlowAssignType? flowAssignType,
             EFlowAssignType? flowAssignType,
             List<Kv> handlers,
             List<Kv> handlers,
+            List<WorkflowStepHandler> stepHandlers,
             string nextStepCode,
             string nextStepCode,
             string? nextMainHandler,
             string? nextMainHandler,
             string? countersignId,
             string? countersignId,
@@ -2180,6 +2204,7 @@ namespace Hotline.FlowEngine.Workflows
 
 
             step.FlowAssignType = flowAssignType;
             step.FlowAssignType = flowAssignType;
             step.Handlers = handlers;
             step.Handlers = handlers;
+            step.StepHandlers = stepHandlers;
             step.NextStepCode = step.StepType is EStepType.End ? string.Empty : nextStepCode;
             step.NextStepCode = step.StepType is EStepType.End ? string.Empty : nextStepCode;
             step.IsMain = isMain;
             step.IsMain = isMain;
             step.PrevStepId = prevStep.Id;
             step.PrevStepId = prevStep.Id;

+ 5 - 1
src/Hotline/FlowEngine/Workflows/WorkflowStep.cs

@@ -92,7 +92,7 @@ public class WorkflowStep : StepBasicEntity
     [Navigate(NavigateType.ManyToOne, nameof(WorkflowId))]
     [Navigate(NavigateType.ManyToOne, nameof(WorkflowId))]
     public Workflow Workflow { get; set; }
     public Workflow Workflow { get; set; }
 
 
-    [Navigate(NavigateType.OneToOne, nameof(Id), 
+    [Navigate(NavigateType.OneToOne, nameof(Id),
         nameof(Workflows.WorkflowTrace.StepId))]
         nameof(Workflows.WorkflowTrace.StepId))]
     public WorkflowTrace WorkflowTrace { get; set; }
     public WorkflowTrace WorkflowTrace { get; set; }
 
 
@@ -260,6 +260,10 @@ public class WorkflowStep : StepBasicEntity
         return IsCountersignEndStep && CountersignStartStepId == topCountersignStepId;
         return IsCountersignEndStep && CountersignStartStepId == topCountersignStepId;
     }
     }
 
 
+    public WorkflowStepHandler?
+        GetActualHandler(ICollection<string> roles, string? userId = null, string? orgId = null) =>
+        StepHandlers.FirstOrDefault(d => d.IsHandler(roles, userId, orgId));
+
     #endregion
     #endregion
 }
 }