|
@@ -100,13 +100,12 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
/// 流程开始
|
|
|
/// </summary>
|
|
|
public async Task StartAsync(Workflow workflow, WorkflowStep startStep, BasicWorkflowDto dto,
|
|
|
- StepDefine firstStepDefine, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
|
|
|
+ StepDefine firstStepDefine, bool isNextDynamic, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
|
|
|
{
|
|
|
//1. 创建first节点 (和trace)2.办理开始节点
|
|
|
|
|
|
//firststeps
|
|
|
- var firstSteps = await CreateNextStepsAsync(workflow, firstStepDefine, startStep, dto, flowAssignInfo,
|
|
|
- cancellationToken);
|
|
|
+ var firstSteps = await CreateNextStepsAsync(workflow, startStep, dto, firstStepDefine, isNextDynamic, flowAssignInfo, cancellationToken);
|
|
|
if (firstSteps.Any())
|
|
|
workflow.Steps.AddRange(firstSteps);
|
|
|
|
|
@@ -273,7 +272,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
/// 办理(流转至下一节点)
|
|
|
/// </summary>
|
|
|
public async Task NextAsync(Workflow workflow, WorkflowStep currentStep, NextWorkflowDto dto,
|
|
|
- StepDefine nextStepDefine, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
|
|
|
+ StepDefine nextStepDefine, bool isNextDynamic, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
|
|
|
{
|
|
|
ValidatePermission(workflow, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
|
|
|
CheckWhetherRunnable(workflow.Status);
|
|
@@ -404,8 +403,8 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
//// workflow.CenterToOrg(CalculateExpiredTime(workflow.WorkflowDefinition.Code));//todo 过期时间
|
|
|
|
|
|
//创建下一/N个节点(会签汇总节点:会签未全部办理时不创建,最后一个会签办理节点创建会签汇总节点)
|
|
|
- var nextSteps = await CreateNextStepsAsync(workflow, nextStepDefine, currentStep, dto, flowAssignInfo,
|
|
|
- cancellationToken);
|
|
|
+ var nextSteps = await CreateNextStepsAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic,
|
|
|
+ flowAssignInfo, cancellationToken);
|
|
|
|
|
|
//赋值当前节点的下级办理节点
|
|
|
if (dto.IsStartCountersign
|
|
@@ -900,9 +899,8 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
/// <summary>
|
|
|
/// 创建下1/N个节点
|
|
|
/// </summary>
|
|
|
- private async Task<List<WorkflowStep>> CreateNextStepsAsync(Workflow workflow, StepDefine nextStepDefine,
|
|
|
- WorkflowStep currentStep, BasicWorkflowDto dto, FlowAssignInfo flowAssignInfo,
|
|
|
- CancellationToken cancellationToken)
|
|
|
+ private async Task<List<WorkflowStep>> CreateNextStepsAsync(Workflow workflow, WorkflowStep currentStep, BasicWorkflowDto dto,
|
|
|
+ StepDefine nextStepDefine, bool isNextDynamic, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
|
|
|
{
|
|
|
List<WorkflowStep> nextSteps = new();
|
|
|
if (currentStep.IsInCountersign())
|
|
@@ -915,13 +913,13 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
{
|
|
|
if (dto.IsStartCountersign)
|
|
|
{
|
|
|
- //todo 依据会签策略创建会签下一级节点
|
|
|
+ //依据会签策略创建会签下一级节点
|
|
|
nextSteps = await CreateCountersignStepsAsync(workflow, nextStepDefine, currentStep, dto,
|
|
|
flowAssignInfo.FlowAssignType, cancellationToken);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- //todo 创建普通节点(根据配置)
|
|
|
+ //创建普通节点(根据配置)
|
|
|
nextSteps = await CreateConfigStepsAsync(workflow, nextStepDefine, currentStep, dto,
|
|
|
flowAssignInfo, EWorkflowTraceStatus.Normal, cancellationToken);
|
|
|
}
|
|
@@ -948,7 +946,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- //todo 依据会签策略创建会签下一级节点
|
|
|
+ //依据会签策略创建会签下一级节点
|
|
|
nextSteps = await CreateCountersignStepsAsync(workflow, nextStepDefine, currentStep, dto,
|
|
|
flowAssignInfo.FlowAssignType, cancellationToken);
|
|
|
}
|
|
@@ -956,20 +954,19 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
}
|
|
|
else if (dto.IsStartCountersign) //top
|
|
|
{
|
|
|
- //todo 依据会签策略创建会签下一级节点
|
|
|
+ //依据会签策略创建会签下一级节点
|
|
|
nextSteps = await CreateCountersignStepsAsync(workflow, nextStepDefine, currentStep, dto,
|
|
|
flowAssignInfo.FlowAssignType, cancellationToken);
|
|
|
}
|
|
|
- else if (currentStep.InstanceMode is EInstanceMode.Dynamic && !currentStep.DynamicShouldTerminal())
|
|
|
+ else if (isNextDynamic)
|
|
|
{
|
|
|
- //todo 创建动态下一级节点
|
|
|
- nextSteps = await CreateStepsAsync(workflow, nextStepDefine, currentStep, dto,
|
|
|
- flowAssignInfo.FlowAssignType, dto.NextHandlers, null, EWorkflowStepStatus.WaitForAccept,
|
|
|
- ECountersignPosition.None, false, EWorkflowTraceStatus.Normal, cancellationToken);
|
|
|
+ //创建动态下一级节点
|
|
|
+ nextSteps = await CreateDynamicStepsAsync(workflow, nextStepDefine, currentStep, dto, flowAssignInfo,
|
|
|
+ cancellationToken);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- //todo 创建普通节点(根据配置)
|
|
|
+ //创建普通节点(根据配置)
|
|
|
nextSteps = await CreateConfigStepsAsync(workflow, nextStepDefine, currentStep, dto, flowAssignInfo,
|
|
|
EWorkflowTraceStatus.Normal, cancellationToken);
|
|
|
}
|
|
@@ -977,6 +974,29 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
return nextSteps;
|
|
|
}
|
|
|
|
|
|
+ private async Task<List<WorkflowStep>> CreateDynamicStepsAsync(
|
|
|
+ Workflow workflow,
|
|
|
+ StepDefine nextStepDefine,
|
|
|
+ WorkflowStep prevStep,
|
|
|
+ BasicWorkflowDto dto,
|
|
|
+ FlowAssignInfo flowAssignInfo,
|
|
|
+ CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var handlerType = nextStepDefine.InstancePolicy switch
|
|
|
+ {
|
|
|
+ EDynamicPolicy.OrgUpCenterTop => EHandlerType.OrgLevel,
|
|
|
+ EDynamicPolicy.OrgUp => EHandlerType.OrgLevel,
|
|
|
+ EDynamicPolicy.OrgDownCenterTop => EHandlerType.OrgLevel,
|
|
|
+ EDynamicPolicy.OrgDown => EHandlerType.OrgLevel,
|
|
|
+ null => throw new ArgumentOutOfRangeException(),
|
|
|
+ _ => throw new ArgumentOutOfRangeException()
|
|
|
+ };
|
|
|
+
|
|
|
+ return await CreateStepsAsync(workflow, nextStepDefine, prevStep, dto,
|
|
|
+ flowAssignInfo.FlowAssignType, dto.NextHandlers, null, EWorkflowStepStatus.WaitForAccept,
|
|
|
+ ECountersignPosition.None, false, EWorkflowTraceStatus.Normal, handlerType, cancellationToken);
|
|
|
+ }
|
|
|
+
|
|
|
private Task<List<WorkflowStep>> CreateCountersignStepsAsync(
|
|
|
Workflow workflow,
|
|
|
StepDefine stepDefine,
|
|
@@ -989,10 +1009,20 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
{
|
|
|
var countersignId = prevStep.IsStartCountersign ? prevStep.StartCountersignId : prevStep.CountersignId;
|
|
|
|
|
|
+ var handlerType = stepDefine.CountersignPolicy switch
|
|
|
+ {
|
|
|
+ EDynamicPolicy.OrgUpCenterTop => EHandlerType.OrgLevel,
|
|
|
+ EDynamicPolicy.OrgUp => EHandlerType.OrgLevel,
|
|
|
+ EDynamicPolicy.OrgDownCenterTop => EHandlerType.OrgLevel,
|
|
|
+ EDynamicPolicy.OrgDown => EHandlerType.OrgLevel,
|
|
|
+ null => throw new ArgumentOutOfRangeException(),
|
|
|
+ _ => throw new ArgumentOutOfRangeException()
|
|
|
+ };
|
|
|
+
|
|
|
return CreateStepsAsync(workflow, stepDefine, prevStep, dto, flowAssignType, dto.NextHandlers,
|
|
|
countersignId,
|
|
|
EWorkflowStepStatus.WaitForAccept, prevStep.GetNextStepCountersignPosition(),
|
|
|
- false, EWorkflowTraceStatus.Normal, cancellationToken);
|
|
|
+ false, EWorkflowTraceStatus.Normal, handlerType, cancellationToken);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1441,7 +1471,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
: (await CreateStepsAsync(workflow, targetStepDefine, targetPrevStep, dto,
|
|
|
flowAssignInfo.FlowAssignType, dto.NextHandlers,
|
|
|
null, EWorkflowStepStatus.WaitForAccept, ECountersignPosition.None, true, traceStatus,
|
|
|
- cancellationToken)).First();
|
|
|
+ null, cancellationToken)).First();
|
|
|
|
|
|
|
|
|
//更新当前办理节点信息
|
|
@@ -1538,7 +1568,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
|
|
|
return await CreateStepsAsync(workflow, stepDefine, prevStep, dto, flowAssignInfo.FlowAssignType, handlers,
|
|
|
null, EWorkflowStepStatus.WaitForAccept, ECountersignPosition.None, true, traceStatus,
|
|
|
- cancellationToken);
|
|
|
+ null, cancellationToken);
|
|
|
}
|
|
|
|
|
|
private async Task<List<WorkflowStep>> CreateStepsAsync(
|
|
@@ -1554,7 +1584,8 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
//DateTime expiredTime,
|
|
|
bool isOrigin,
|
|
|
EWorkflowTraceStatus traceStatus,
|
|
|
- CancellationToken cancellationToken
|
|
|
+ EHandlerType? handlerType = null,
|
|
|
+ CancellationToken cancellationToken = default
|
|
|
)
|
|
|
{
|
|
|
//var countersignId = prevStep.IsStartCountersign
|
|
@@ -1568,7 +1599,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
{
|
|
|
var step = CreateStep(stepDefine, prevStep, workflow.Id, flowAssignType, new List<Kv> { handler },
|
|
|
dto.NextStepCode, dto.NextMainHandler, countersignId,
|
|
|
- stepStatus, csPosition, workflow.ExpiredTime, dto.NextStepName, isOrigin);
|
|
|
+ stepStatus, csPosition, workflow.ExpiredTime, dto.NextStepName, isOrigin, handlerType);
|
|
|
|
|
|
steps.Add(step);
|
|
|
}
|
|
@@ -1577,7 +1608,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
{
|
|
|
var step = CreateStep(stepDefine, prevStep, workflow.Id, flowAssignType, handlers,
|
|
|
dto.NextStepCode, dto.NextMainHandler, countersignId,
|
|
|
- stepStatus, csPosition, workflow.ExpiredTime, dto.NextStepName, isOrigin);
|
|
|
+ stepStatus, csPosition, workflow.ExpiredTime, dto.NextStepName, isOrigin, handlerType);
|
|
|
|
|
|
steps.Add(step);
|
|
|
}
|
|
@@ -1617,10 +1648,34 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
public async Task<bool> CheckCurrentIsStartStepAsync(string workflowId, string userId, string orgId, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var workflow = await GetWorkflowAsync(workflowId, withSteps: true, cancellationToken: cancellationToken);
|
|
|
- //var currentStep = FindCurrentStepWaitForHandle(workflow, userId, orgId);
|
|
|
- //if (currentStep.StepType is EStepType.End)
|
|
|
- // throw new UserFriendlyException("结束节点无需办理");
|
|
|
- return workflow.Steps.Count == 1;
|
|
|
+ var currentStep = FindCurrentStepWaitForHandle(workflow, userId, orgId);
|
|
|
+ return workflow.Steps.Count == 1 && currentStep.StepType is EStepType.Start && currentStep.IsOrigin;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 检查动态节点是否该终止
|
|
|
+ /// </summary>
|
|
|
+ public bool DynamicShouldTerminal(StepDefine currentStepDefine, int currentOrgLevel)
|
|
|
+ {
|
|
|
+ if (currentStepDefine.InstanceMode is not EInstanceMode.Dynamic)
|
|
|
+ throw new UserFriendlyException("非动态节点");
|
|
|
+ switch (currentStepDefine.InstancePolicy)
|
|
|
+ {
|
|
|
+ case EDynamicPolicy.OrgUpCenterTop:
|
|
|
+ case EDynamicPolicy.OrgUp:
|
|
|
+ if (!int.TryParse(currentStepDefine.TerminalDynamicMark, out var tMark))
|
|
|
+ throw new UserFriendlyException(
|
|
|
+ $"TerminalDynamicMark parse to int failed, tMark: {currentStepDefine.TerminalDynamicMark}");
|
|
|
+ return currentOrgLevel <= tMark;
|
|
|
+ case EDynamicPolicy.OrgDownCenterTop:
|
|
|
+ case EDynamicPolicy.OrgDown:
|
|
|
+ if (!int.TryParse(currentStepDefine.TerminalDynamicMark, out var tMark1))
|
|
|
+ throw new UserFriendlyException(
|
|
|
+ $"TerminalDynamicMark parse to int failed, tMark: {currentStepDefine.TerminalDynamicMark}");
|
|
|
+ return currentOrgLevel >= tMark1;
|
|
|
+ default:
|
|
|
+ throw new ArgumentOutOfRangeException();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private WorkflowStep? GetStep(List<WorkflowStep> steps, string orgCode, string userId,
|
|
@@ -1641,7 +1696,8 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
ECountersignPosition countersignPosition,
|
|
|
DateTime expiredTime,
|
|
|
string stepName,
|
|
|
- bool isOrigin
|
|
|
+ bool isOrigin,
|
|
|
+ EHandlerType? handlerType = null//动态节点依据动态策略判断
|
|
|
)
|
|
|
{
|
|
|
if (!handlers.Any())
|
|
@@ -1665,6 +1721,9 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
step.IsOrigin = isOrigin;
|
|
|
step.Name = stepName;
|
|
|
|
|
|
+ if (handlerType.HasValue)
|
|
|
+ step.HandlerType = handlerType.Value;
|
|
|
+
|
|
|
return step;
|
|
|
}
|
|
|
|