|
@@ -99,7 +99,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
throw UserFriendlyException.SameMessage("未指派办理人");
|
|
|
|
|
|
//开始节点
|
|
|
- var (startStepBox, startStep) = await CreateStartStepAsync(workflow, dto, cancellationToken);
|
|
|
+ var (startStepBox, startStep) = await CreateStartStepAsync(workflow, dto, isStartCountersign, cancellationToken);
|
|
|
|
|
|
if (isStartCountersign)
|
|
|
{
|
|
@@ -114,7 +114,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
await NextTraceAsync(workflow, dto, startStep, cancellationToken);
|
|
|
|
|
|
//第二节点(创建即为 已指派/待接办 状态)
|
|
|
- var nextStepBox = await CreateStepAsync(workflow, nextStepBoxDefine, dto, EWorkflowStepStatus.Assigned,
|
|
|
+ var nextStepBox = await CreateStepAsync(isStartCountersign, workflow, nextStepBoxDefine, dto, EWorkflowStepStatus.Assigned,
|
|
|
startStepBox, startStep, cancellationToken);
|
|
|
|
|
|
//更新当前节点名称、时间、会签节点code 等字段
|
|
@@ -186,12 +186,12 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
if (currentStep.HandlerType is EHandlerType.AssignUser or EHandlerType.Role)
|
|
|
{
|
|
|
//userId
|
|
|
- if (currentStep.HandlerId != userId) return;
|
|
|
+ if (!currentStep.HandlerIds.Contains(userId)) return;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//orgId
|
|
|
- if (currentStep.HandlerId != orgCode) return;
|
|
|
+ if (!currentStep.HandlerIds.Contains(orgCode)) return;
|
|
|
}
|
|
|
if (currentStep.StepType is EStepType.End)
|
|
|
throw new UserFriendlyException("当前流程已流转到最终步骤");
|
|
@@ -347,7 +347,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
}
|
|
|
|
|
|
//创建下一节点(会签汇总节点不重复创建)
|
|
|
- var nextStepBox = await CreateStepAsync(workflow, nextStepBoxDefine, dto, EWorkflowStepStatus.Created,
|
|
|
+ var nextStepBox = await CreateStepAsync(isStartCountersign, workflow, nextStepBoxDefine, dto, EWorkflowStepStatus.Created,
|
|
|
currentStepBox, currentStep, cancellationToken);
|
|
|
|
|
|
//下一节点为汇总节点时,检查下一节点是否可办理
|
|
@@ -455,7 +455,8 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
{
|
|
|
//向后跳转
|
|
|
var nextStepBoxDefine = GetStepBoxDefine(workflow.Definition, dto.NextStepCode);
|
|
|
- var nextStepBox = await CreateStepAsync(workflow, nextStepBoxDefine, dto, EWorkflowStepStatus.Assigned, currentStepBox, currentStep, cancellationToken);
|
|
|
+ var isStartCountersign = nextStepBoxDefine.IsStartCountersign(dto.NextHandlers.Count);
|
|
|
+ var nextStepBox = await CreateStepAsync(isStartCountersign, workflow, nextStepBoxDefine, dto, EWorkflowStepStatus.Assigned, currentStepBox, currentStep, cancellationToken);
|
|
|
|
|
|
await ResetWorkflowCurrentStepInfo(workflow, dto, nextStepBox, cancellationToken);
|
|
|
|
|
@@ -571,23 +572,19 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
/// <returns></returns>
|
|
|
private async Task SetNextCountersignEndAssignedAsync(WorkflowStep nextStepBox, WorkflowStep currentStep, CancellationToken cancellationToken)
|
|
|
{
|
|
|
- WorkflowStep? nextStep;
|
|
|
- if (currentStep.StepCountersignStatus is EStepCountersignStatus.InCountersign)
|
|
|
- {
|
|
|
- nextStep = nextStepBox.Steps.FirstOrDefault(d => d.CountersignId == currentStep.CountersignId);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- nextStep = nextStepBox.Steps.FirstOrDefault(d => d.ParentId == currentStep.Id);
|
|
|
- }
|
|
|
+ var nextSteps = currentStep.StepCountersignStatus is EStepCountersignStatus.InCountersign
|
|
|
+ ? nextStepBox.Steps.Where(d => d.CountersignId == currentStep.CountersignId).ToList()
|
|
|
+ : nextStepBox.Steps.Where(d => d.PreviousId == currentStep.Id).ToList();
|
|
|
|
|
|
- if (nextStep == null)
|
|
|
- throw new UserFriendlyException(
|
|
|
- $"未查询到下一节点, workflowId:{currentStep.WorkflowId}, currentStepId: {currentStep.Id}");
|
|
|
+ if (!nextSteps.Any())
|
|
|
+ throw new UserFriendlyException($"未查询到下一节点, currentStepId: {currentStep.Id}");
|
|
|
|
|
|
- nextStep.SetAssigned();
|
|
|
+ foreach (var nextStep in nextSteps)
|
|
|
+ {
|
|
|
+ nextStep.SetAssigned();
|
|
|
+ }
|
|
|
|
|
|
- await _workflowStepRepository.UpdateAsync(nextStep, cancellationToken);
|
|
|
+ await _workflowStepRepository.UpdateRangeAsync(nextSteps, cancellationToken);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -704,7 +701,8 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
|
|
|
//recreate targetStep
|
|
|
var nextStepBoxDefine = GetStepBoxDefine(workflow.Definition, dto.NextStepCode);
|
|
|
- await CreateStepAsync(workflow, nextStepBoxDefine, dto, EWorkflowStepStatus.Assigned, targetStepBox, targetStepBox.Steps.First(), cancellationToken);
|
|
|
+ var isStartCountersign = nextStepBoxDefine.IsStartCountersign(dto.NextHandlers.Count);
|
|
|
+ await CreateStepAsync(isStartCountersign, workflow, nextStepBoxDefine, dto, EWorkflowStepStatus.Assigned, targetStepBox, targetStepBox.Steps.First(), cancellationToken);
|
|
|
|
|
|
//flow manage
|
|
|
if (workflow.IsInCountersign())
|
|
@@ -745,7 +743,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
/// <summary>
|
|
|
/// 创建开始节点(保存开始流程的办理意见,对应definition的start节点)
|
|
|
/// </summary>
|
|
|
- private async Task<(WorkflowStep stepBox, WorkflowStep step)> CreateStartStepAsync(Workflow workflow, BasicWorkflowDto dto, CancellationToken cancellationToken)
|
|
|
+ private async Task<(WorkflowStep stepBox, WorkflowStep step)> CreateStartStepAsync(Workflow workflow, BasicWorkflowDto dto, bool isStartCountersign, CancellationToken cancellationToken)
|
|
|
{
|
|
|
if (workflow.StepBoxes.Any())
|
|
|
throw UserFriendlyException.SameMessage("无法反复开始流程");
|
|
@@ -759,14 +757,14 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
|
|
|
//start节点的办理人分类默认为用户,即为当前发起流程的操作员
|
|
|
var handler = new IdName { Id = _sessionContext.RequiredUserId, Name = _sessionContext.UserName };
|
|
|
- await CreateStartSubStepAsync(handler, dto, stepBox, null, cancellationToken);
|
|
|
+ await CreateStartSubStepAsync(handler, dto, stepBox, cancellationToken);
|
|
|
return (stepBox, stepBox.Steps.First());
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 创建节点(不含开始、结束节点)
|
|
|
/// </summary>
|
|
|
- private async Task<WorkflowStep> CreateStepAsync(Workflow workflow, StepDefine stepBoxDefine, BasicWorkflowDto dto, EWorkflowStepStatus status,
|
|
|
+ private async Task<WorkflowStep> CreateStepAsync(bool isPrevStartCountersign, Workflow workflow, StepDefine stepBoxDefine, BasicWorkflowDto dto, EWorkflowStepStatus status,
|
|
|
WorkflowStep? prevStepBox = null, WorkflowStep? prevStep = null, CancellationToken cancellationToken = default)
|
|
|
{
|
|
|
if (stepBoxDefine.StepType is EStepType.Start or EStepType.End)
|
|
@@ -792,7 +790,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
return stepBox;
|
|
|
}
|
|
|
|
|
|
- await CreateSubStepsAsync(stepBoxDefine, dto, stepBox, status, prevStep, cancellationToken);
|
|
|
+ await CreateSubStepsAsync(isPrevStartCountersign, stepBoxDefine, dto, stepBox, status, prevStep, cancellationToken);
|
|
|
|
|
|
return stepBox;
|
|
|
}
|
|
@@ -801,15 +799,13 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
IdName handler,
|
|
|
BasicWorkflowDto dto,
|
|
|
WorkflowStep stepBox,
|
|
|
- string? startCountersignId = null,
|
|
|
- CancellationToken cancellationToken = default)
|
|
|
+ CancellationToken cancellationToken)
|
|
|
{
|
|
|
- var nextCountersignStatus = string.IsNullOrEmpty(startCountersignId)
|
|
|
- ? EStepCountersignStatus.None
|
|
|
- : EStepCountersignStatus.InCountersign;
|
|
|
- var subStep = CreateSubStep(stepBox, handler, dto.NextStepCode, dto.NextMainHandler, null, startCountersignId, null,
|
|
|
- EWorkflowStepStatus.Completed, nextCountersignStatus);
|
|
|
- subStep.Accept(_sessionContext.RequiredUserId, _sessionContext.UserName, _sessionContext.RequiredOrgCode, _sessionContext.OrgName);
|
|
|
+ //开始节点既不发起会签,也不处于会签中
|
|
|
+ var subStep = CreateSubStep(stepBox, new List<IdName> { handler }, dto.NextStepCode, dto.NextMainHandler,
|
|
|
+ null, null, EWorkflowStepStatus.Completed, EStepCountersignStatus.None);
|
|
|
+ subStep.Accept(_sessionContext.RequiredUserId, _sessionContext.UserName,
|
|
|
+ _sessionContext.RequiredOrgCode, _sessionContext.OrgName);
|
|
|
//step办理状态
|
|
|
subStep.StepComplete(
|
|
|
_sessionContext.RequiredUserId, _sessionContext.UserName,
|
|
@@ -822,26 +818,26 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
}
|
|
|
|
|
|
private async Task CreateSubStepsAsync(
|
|
|
+ bool isPrevStartCountersign,
|
|
|
StepDefine stepBoxDefine,
|
|
|
BasicWorkflowDto dto,
|
|
|
WorkflowStep stepBox,
|
|
|
EWorkflowStepStatus stepStatus,
|
|
|
- WorkflowStep? prevStep = null,
|
|
|
+ WorkflowStep prevStep,
|
|
|
CancellationToken cancellationToken = default)
|
|
|
{
|
|
|
- //开始节点无会签
|
|
|
- var countersignStatus = prevStep?.GetNextStepCountersignStatus() ?? EStepCountersignStatus.None;
|
|
|
+ var countersignStatus = prevStep.GetNextStepCountersignStatus();
|
|
|
List<WorkflowStep> subSteps;
|
|
|
if (stepBoxDefine.HandlerType is EHandlerType.AssignUser or EHandlerType.AssignOrg)
|
|
|
{
|
|
|
- subSteps = CreateSubSteps(stepBox, stepBox.HandlerClassifies, dto.NextStepCode, dto.NextMainHandler,
|
|
|
+ subSteps = CreateSubSteps(isPrevStartCountersign, stepBox, stepBox.HandlerClassifies, dto.NextStepCode, dto.NextMainHandler,
|
|
|
prevStep?.Id, prevStep?.StartCountersignId, stepStatus, countersignStatus);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (stepBoxDefine.HandlerType != EHandlerType.Role && !dto.NextHandlers.Any())
|
|
|
throw new UserFriendlyException("未指定节点处理者");
|
|
|
- subSteps = CreateSubSteps(stepBox, dto.NextHandlers, dto.NextStepCode, dto.NextMainHandler,
|
|
|
+ subSteps = CreateSubSteps(isPrevStartCountersign, stepBox, dto.NextHandlers, dto.NextStepCode, dto.NextMainHandler,
|
|
|
prevStep?.Id, prevStep?.StartCountersignId, stepStatus, countersignStatus);
|
|
|
}
|
|
|
stepBox.Steps.AddRange(subSteps);
|
|
@@ -887,7 +883,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
{
|
|
|
foreach (var step in stepBox.Steps)
|
|
|
{
|
|
|
- if (predicate(step.Status) && (step.HandlerId == orgCode || step.HandlerId == userId))
|
|
|
+ if (predicate(step.Status) && (step.HandlerIds.Contains(orgCode) || step.HandlerIds.Contains(userId)))
|
|
|
return (stepBox, step);
|
|
|
}
|
|
|
}
|
|
@@ -906,6 +902,7 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
}
|
|
|
|
|
|
private List<WorkflowStep> CreateSubSteps(
|
|
|
+ bool isPrevStartContersign,
|
|
|
WorkflowStep stepBox,
|
|
|
List<IdName> handlers,
|
|
|
string nextStepCode,
|
|
@@ -920,20 +917,23 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
if (countersignStatus is not EStepCountersignStatus.None && string.IsNullOrEmpty(countersignId))
|
|
|
throw UserFriendlyException.SameMessage("非法参数");
|
|
|
|
|
|
+ //依据是否发起会签创建step,发起会签表示一个handler创建一个step,未发起会签表示多人处理同一个节点,只创建一个step
|
|
|
var steps = new List<WorkflowStep>();
|
|
|
- foreach (var handler in handlers)
|
|
|
- {
|
|
|
- //var step = _mapper.Map<WorkflowStep>(stepBox);
|
|
|
- //step.ParentId = stepBox.Id;
|
|
|
- //step.HandlerId = handler.Id;
|
|
|
- //step.IsMain = handler.Id == nextMainHandler;
|
|
|
- //step.PreviousId = prevStepId;
|
|
|
- //step.StartCountersignId = startCountersignId;
|
|
|
- //step.CountersignId = countersignId;
|
|
|
- //step.Status = stepStatus;
|
|
|
-
|
|
|
- var step = CreateSubStep(stepBox, handler, nextMainHandler, nextStepCode,
|
|
|
- prevStepId, null, countersignId, stepStatus, countersignStatus);
|
|
|
+ if (isPrevStartContersign)
|
|
|
+ {
|
|
|
+ foreach (var handler in handlers)
|
|
|
+ {
|
|
|
+ var step = CreateSubStep(stepBox, new List<IdName> { handler }, nextMainHandler, nextStepCode,
|
|
|
+ prevStepId, countersignId, stepStatus, countersignStatus);
|
|
|
+
|
|
|
+ steps.Add(step);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var step = CreateSubStep(stepBox, handlers, nextMainHandler, nextStepCode,
|
|
|
+ prevStepId, countersignId, stepStatus, countersignStatus);
|
|
|
+
|
|
|
steps.Add(step);
|
|
|
}
|
|
|
|
|
@@ -942,22 +942,25 @@ namespace Hotline.FlowEngine.Workflows
|
|
|
|
|
|
private WorkflowStep CreateSubStep(
|
|
|
WorkflowStep stepBox,
|
|
|
- IdName handler,
|
|
|
+ List<IdName> handlers,
|
|
|
string nextStepCode,
|
|
|
string? nextMainHandler,
|
|
|
string? prevStepId,
|
|
|
- string? startCountersignId,
|
|
|
string? countersignId,
|
|
|
EWorkflowStepStatus stepStatus,
|
|
|
EStepCountersignStatus countersignStatus)
|
|
|
{
|
|
|
+ if (!handlers.Any())
|
|
|
+ throw new UserFriendlyException("非法参数");
|
|
|
var step = _mapper.Map<WorkflowStep>(stepBox);
|
|
|
+ var handlerIds = handlers.Select(d => d.Id).ToList();
|
|
|
+ var isMain = handlers.Count > 1 || handlerIds.First() == nextMainHandler;
|
|
|
+
|
|
|
step.ParentId = stepBox.Id;
|
|
|
- step.HandlerId = handler.Id;
|
|
|
+ step.HandlerIds = handlerIds;
|
|
|
step.NextStepCode = nextStepCode;
|
|
|
- step.IsMain = handler.Id == nextMainHandler;
|
|
|
+ step.IsMain = isMain;
|
|
|
step.PreviousId = prevStepId;
|
|
|
- step.StartCountersignId = startCountersignId;
|
|
|
step.CountersignId = countersignId;
|
|
|
step.Status = stepStatus;
|
|
|
step.StepCountersignStatus = countersignStatus;
|