|
@@ -18,6 +18,7 @@ using Hotline.Share.Enums.Identity;
|
|
|
using Hotline.Share.Enums.Order;
|
|
|
using Hotline.Users;
|
|
|
using MapsterMapper;
|
|
|
+using System.Threading;
|
|
|
using XF.Domain.Authentications;
|
|
|
using XF.Domain.Dependency;
|
|
|
using XF.Domain.Entities;
|
|
@@ -420,7 +421,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
//var nextStepOption = CreateDynamicStep(startStep.InstancePolicy);
|
|
|
//dto.Steps = new List<NextStepOption> { nextStepOption };
|
|
|
//return dto;
|
|
|
- var nextStepOption = await CreateDynamicStepAsync(startStep.InstancePolicy.Value, cancellationToken);
|
|
|
+ var nextStepOption = await GetDynamicStepAsync(startStep.InstancePolicy.Value, cancellationToken);
|
|
|
return new NextStepsDto
|
|
|
{
|
|
|
Steps = new List<NextStepOption> { nextStepOption }
|
|
@@ -436,7 +437,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
// .ToList();
|
|
|
return new NextStepsDto
|
|
|
{
|
|
|
- Steps = await CreateConfigStepsAsync(startStep.StepType, firstStepDefines, cancellationToken)
|
|
|
+ Steps = await GetConfigStepsAsync(startStep.StepType, startStep.BusinessType, firstStepDefines, cancellationToken)
|
|
|
};
|
|
|
//dto.Steps = steps;
|
|
|
//return dto;
|
|
@@ -463,7 +464,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
if (currentStep.InstanceMode is EInstanceMode.Dynamic && !DynamicShouldTerminal(currentStep))
|
|
|
{
|
|
|
//动态生成下一步
|
|
|
- var nextStepOption = await CreateDynamicStepAsync(currentStep.InstancePolicy.Value, cancellationToken);
|
|
|
+ var nextStepOption = await GetDynamicStepAsync(currentStep.InstancePolicy.Value, cancellationToken);
|
|
|
dto.Steps = new List<NextStepOption> { nextStepOption };
|
|
|
return dto;
|
|
|
}
|
|
@@ -482,7 +483,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
throw new UserFriendlyException(
|
|
|
$"未查询到会签开始节点,workflowId: {workflow.Id}, startStepId: {currentStep.CountersignStartStepId}",
|
|
|
"未查询到会签开始节点,数据异常");
|
|
|
- var countersignEndOption = CreateCsEndStepByPrev(workflow.Steps, startCountersignStep);
|
|
|
+ var countersignEndOption = GetCsEndStepByPrev(workflow.Steps, startCountersignStep);
|
|
|
|
|
|
dto.Steps = new List<NextStepOption> { countersignEndOption };
|
|
|
return dto;
|
|
@@ -491,10 +492,10 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
else
|
|
|
{
|
|
|
//汇总节点
|
|
|
- var countersignEndOption = CreateCsEndStepByPrev(workflow.Steps, currentStep);
|
|
|
+ var countersignEndOption = GetCsEndStepByPrev(workflow.Steps, currentStep);
|
|
|
//按会签策略
|
|
|
var nextStepOption =
|
|
|
- await CreateDynamicStepAsync(currentStep.CountersignPolicy.Value, cancellationToken);
|
|
|
+ await GetDynamicStepAsync(currentStep.CountersignPolicy.Value, currentStep.IsOrigin, currentStep.BusinessType, cancellationToken);
|
|
|
dto.Steps = new List<NextStepOption> { nextStepOption, countersignEndOption };
|
|
|
return dto;
|
|
|
}
|
|
@@ -504,7 +505,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
if (!nextDefines.Any())
|
|
|
throw new UserFriendlyException("未正确配置下一节点");
|
|
|
|
|
|
- dto.Steps = await CreateConfigStepsAsync(currentStep.StepType, nextDefines, cancellationToken);
|
|
|
+ dto.Steps = await GetConfigStepsAsync(currentStep.StepType, currentStep.BusinessType, nextDefines, cancellationToken);
|
|
|
|
|
|
if (currentStep.IsInCountersign() && currentStep.IsTopCountersignEndStep(workflow.TopCountersignStepId))
|
|
|
{
|
|
@@ -535,10 +536,36 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
var stepDefines = workflow.WorkflowDefinition.FindStepDefines(stepCodes);
|
|
|
return new NextStepsDto
|
|
|
{
|
|
|
- Steps = await CreateConfigStepsAsync(null, stepDefines, cancellationToken)
|
|
|
+ Steps = await GetRecallConfigStepsAsync(stepDefines, cancellationToken)
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ private async Task<IReadOnlyList<NextStepOption>> GetRecallConfigStepsAsync(List<StepDefine> stepDefines, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var stepOptions = new List<NextStepOption>();
|
|
|
+ foreach (var stepDefine in stepDefines)
|
|
|
+ {
|
|
|
+ var nextStepOption = await GetConfigStepAsync(stepDefine, cancellationToken);
|
|
|
+ if (stepDefine.StepType is EStepType.End)
|
|
|
+ {
|
|
|
+ stepOptions.Add(nextStepOption);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ nextStepOption.InputRealHandler = false;
|
|
|
+ //todo thk 派单->坐席, 会签中怎么界定当前节点?
|
|
|
+ nextStepOption.FlowDirection =
|
|
|
+ stepDefine.BusinessType is EBusinessType.Center or EBusinessType.Send
|
|
|
+ ? EFlowDirection.OrgToCenter
|
|
|
+ : stepDefine.BusinessType is EBusinessType.Department
|
|
|
+ ? EFlowDirection.CenterToOrg
|
|
|
+ : null;
|
|
|
+ stepOptions.Add(nextStepOption);
|
|
|
+ }
|
|
|
+
|
|
|
+ return stepOptions;
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 查询跳转可选节点
|
|
|
/// </summary>
|
|
@@ -548,7 +575,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
await _workflowDomainService.GetWorkflowAsync(workflowId, true, cancellationToken: cancellationToken);
|
|
|
return new NextStepsDto
|
|
|
{
|
|
|
- Steps = await CreateConfigStepsAsync(null, workflow.WorkflowDefinition.Steps, cancellationToken)
|
|
|
+ //Steps = await GetConfigStepsAsync(null, workflow.WorkflowDefinition.Steps, cancellationToken)
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -563,7 +590,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
var stepDefines = workflow.WorkflowDefinition.FindStepDefines(steps.Select(d => d.Code));
|
|
|
return new NextStepsDto
|
|
|
{
|
|
|
- Steps = await CreateConfigStepsAsync(null, stepDefines, cancellationToken)
|
|
|
+ //Steps = await GetConfigStepsAsync(null, stepDefines, cancellationToken)
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -580,84 +607,121 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
await _workflowDomainService.RejectAsync(workflow, basicDto, cancellationToken);
|
|
|
}
|
|
|
|
|
|
- private async Task<List<NextStepOption>> CreateConfigStepsAsync(EStepType? currentStepType,
|
|
|
- List<StepDefine> stepDefines, CancellationToken cancellationToken)
|
|
|
+ private async Task<List<NextStepOption>> GetConfigStepsAsync(EStepType? currentStepType,
|
|
|
+ EBusinessType? currentBusinessType, List<StepDefine> stepDefines, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var stepOptions = new List<NextStepOption>();
|
|
|
foreach (var stepDefine in stepDefines)
|
|
|
{
|
|
|
- var handlers = new List<Kv>();
|
|
|
+ var nextStepOption = await GetConfigStepAsync(stepDefine, cancellationToken);
|
|
|
if (stepDefine.StepType is EStepType.End)
|
|
|
{
|
|
|
- stepOptions.Add(new NextStepOption
|
|
|
- {
|
|
|
- Key = stepDefine.Code,
|
|
|
- Value = stepDefine.Name,
|
|
|
- Items = handlers
|
|
|
- });
|
|
|
+ stepOptions.Add(nextStepOption);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- var levelOneOrgCode = _sessionContext.RequiredOrgId.GetHigherOrgCode();
|
|
|
- switch (stepDefine.HandlerType)
|
|
|
- {
|
|
|
- case EHandlerType.AssignedUser:
|
|
|
- case EHandlerType.AssignedOrg:
|
|
|
- handlers = stepDefine.HandlerTypeItems;
|
|
|
- break;
|
|
|
- case EHandlerType.Role:
|
|
|
- //当前操作人所属部门的下级部门并且属于配置包含角色
|
|
|
- var roles = await _roleRepository.Queryable()
|
|
|
- .Includes(
|
|
|
- d => d.Accounts.Where(
|
|
|
- x => !x.IsDeleted && x.Status == EAccountStatus.Normal).ToList(),
|
|
|
- x => x.User)
|
|
|
- .Where(d => stepDefine.HandlerTypeItems.Select(x => x.Key).Contains(d.Name))
|
|
|
- .ToListAsync(cancellationToken);
|
|
|
- var users1 = roles.SelectMany(d => d.Accounts).Select(d => d.User);
|
|
|
-
|
|
|
- //解决当前为一级部门选择中心汇总
|
|
|
- if (stepDefine.StepType != EStepType.Summary || stepDefine.BusinessType != EBusinessType.Center)
|
|
|
- users1 = users1.Where(d => d.OrgId.StartsWith(levelOneOrgCode));
|
|
|
-
|
|
|
- handlers = users1.Select(d => new Kv(d.Id, d.Name)).ToList();
|
|
|
- break;
|
|
|
- case EHandlerType.OrgLevel:
|
|
|
- //当前操作人所属部门的垂直部门并且属于配置orgLevel的部门
|
|
|
- var levels = stepDefine.HandlerTypeItems.Select(d => d.Key).Select(d => int.Parse(d));
|
|
|
- var orgs1 = await _organizeRepository.Queryable()
|
|
|
- .Where(d => d.IsEnable && levels.Contains(d.Level))
|
|
|
- .WhereIF(!levelOneOrgCode.IsCenter(), d => d.Id.StartsWith(levelOneOrgCode))
|
|
|
- .ToListAsync(cancellationToken);
|
|
|
-
|
|
|
- handlers = orgs1.Select(d => new Kv(d.Id, d.Name)).ToList();
|
|
|
- break;
|
|
|
- case EHandlerType.OrgType:
|
|
|
- var types = stepDefine.HandlerTypeItems.Select(d => d.Key)
|
|
|
- .Select(d => Enum.Parse<EOrgType>(d));
|
|
|
- var orgs2 = await _organizeRepository.Queryable()
|
|
|
- .Where(d => d.IsEnable && types.Contains(d.OrgType))
|
|
|
- .WhereIF(!levelOneOrgCode.IsCenter(), d => d.Id.StartsWith(levelOneOrgCode))
|
|
|
- .ToListAsync(cancellationToken);
|
|
|
+ nextStepOption.InputRealHandler = currentStepType.HasValue &&
|
|
|
+ (currentStepType != EStepType.Summary && stepDefine.StepType == EStepType.Summary);
|
|
|
+ nextStepOption.FlowDirection = currentBusinessType.HasValue
|
|
|
+ ? CheckFlowDirection(currentBusinessType.Value, stepDefine.BusinessType)
|
|
|
+ : null;
|
|
|
+ stepOptions.Add(nextStepOption);
|
|
|
+ }
|
|
|
|
|
|
- handlers = orgs2.Select(d => new Kv(d.Id, d.Name)).ToList();
|
|
|
- break;
|
|
|
- default:
|
|
|
- throw new ArgumentOutOfRangeException();
|
|
|
- }
|
|
|
+ return stepOptions;
|
|
|
+ }
|
|
|
|
|
|
- stepOptions.Add(new NextStepOption
|
|
|
+ public async Task<NextStepOption> GetConfigStepAsync(StepDefine stepDefine, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var handlers = new List<Kv>();
|
|
|
+ if (stepDefine.StepType is EStepType.End)
|
|
|
+ {
|
|
|
+ return new NextStepOption
|
|
|
{
|
|
|
Key = stepDefine.Code,
|
|
|
Value = stepDefine.Name,
|
|
|
- InputRealHandler = currentStepType.HasValue &&
|
|
|
- (currentStepType != EStepType.Summary && stepDefine.StepType == EStepType.Summary),
|
|
|
- BusinessType = stepDefine.BusinessType,
|
|
|
Items = handlers
|
|
|
- });
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
- return stepOptions;
|
|
|
+ var levelOneOrgCode = _sessionContext.RequiredOrgId.GetHigherOrgCode();
|
|
|
+ switch (stepDefine.HandlerType)
|
|
|
+ {
|
|
|
+ case EHandlerType.AssignedUser:
|
|
|
+ case EHandlerType.AssignedOrg:
|
|
|
+ handlers = stepDefine.HandlerTypeItems;
|
|
|
+ break;
|
|
|
+ case EHandlerType.Role:
|
|
|
+ //当前操作人所属部门的下级部门并且属于配置包含角色
|
|
|
+ var roles = await _roleRepository.Queryable()
|
|
|
+ .Includes(
|
|
|
+ d => d.Accounts.Where(
|
|
|
+ x => !x.IsDeleted && x.Status == EAccountStatus.Normal).ToList(),
|
|
|
+ x => x.User)
|
|
|
+ .Where(d => stepDefine.HandlerTypeItems.Select(x => x.Key).Contains(d.Name))
|
|
|
+ .ToListAsync(cancellationToken);
|
|
|
+ var users1 = roles.SelectMany(d => d.Accounts).Select(d => d.User);
|
|
|
+
|
|
|
+ //解决当前为一级部门选择中心汇总
|
|
|
+ if (stepDefine.StepType != EStepType.Summary || stepDefine.BusinessType != EBusinessType.Center)
|
|
|
+ users1 = users1.Where(d => d.OrgId.StartsWith(levelOneOrgCode));
|
|
|
+
|
|
|
+ handlers = users1.Select(d => new Kv(d.Id, d.Name)).ToList();
|
|
|
+ break;
|
|
|
+ case EHandlerType.OrgLevel:
|
|
|
+ //当前操作人所属部门的垂直部门并且属于配置orgLevel的部门
|
|
|
+ var levels = stepDefine.HandlerTypeItems.Select(d => d.Key).Select(d => int.Parse(d));
|
|
|
+ var orgs1 = await _organizeRepository.Queryable()
|
|
|
+ .Where(d => d.IsEnable && levels.Contains(d.Level))
|
|
|
+ .WhereIF(!levelOneOrgCode.IsCenter(), d => d.Id.StartsWith(levelOneOrgCode))
|
|
|
+ .ToListAsync(cancellationToken);
|
|
|
+
|
|
|
+ handlers = orgs1.Select(d => new Kv(d.Id, d.Name)).ToList();
|
|
|
+ break;
|
|
|
+ case EHandlerType.OrgType:
|
|
|
+ var types = stepDefine.HandlerTypeItems.Select(d => d.Key)
|
|
|
+ .Select(d => Enum.Parse<EOrgType>(d));
|
|
|
+ var orgs2 = await _organizeRepository.Queryable()
|
|
|
+ .Where(d => d.IsEnable && types.Contains(d.OrgType))
|
|
|
+ .WhereIF(!levelOneOrgCode.IsCenter(), d => d.Id.StartsWith(levelOneOrgCode))
|
|
|
+ .ToListAsync(cancellationToken);
|
|
|
+
|
|
|
+ handlers = orgs2.Select(d => new Kv(d.Id, d.Name)).ToList();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new ArgumentOutOfRangeException();
|
|
|
+ }
|
|
|
+
|
|
|
+ return new NextStepOption
|
|
|
+ {
|
|
|
+ Key = stepDefine.Code,
|
|
|
+ Value = stepDefine.Name,
|
|
|
+ Items = handlers
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ private EFlowDirection? CheckFlowDirection(EBusinessType sourceStepBusinessType, EBusinessType directionStepBusinessType)
|
|
|
+ {
|
|
|
+ switch (sourceStepBusinessType)
|
|
|
+ {
|
|
|
+ case EBusinessType.Center:
|
|
|
+ case EBusinessType.Send:
|
|
|
+ return directionStepBusinessType is EBusinessType.Department
|
|
|
+ ? EFlowDirection.CenterToOrg
|
|
|
+ : directionStepBusinessType is EBusinessType.File
|
|
|
+ ? EFlowDirection.CenterToFile
|
|
|
+ : EFlowDirection.CenterToCenter;
|
|
|
+ case EBusinessType.Department:
|
|
|
+ return directionStepBusinessType is EBusinessType.Center or EBusinessType.Send
|
|
|
+ ? EFlowDirection.OrgToCenter
|
|
|
+ : directionStepBusinessType is EBusinessType.Department
|
|
|
+ ? EFlowDirection.OrgToOrg
|
|
|
+ : null;
|
|
|
+ case EBusinessType.File:
|
|
|
+ return null;
|
|
|
+ default:
|
|
|
+ throw new ArgumentOutOfRangeException(nameof(sourceStepBusinessType), sourceStepBusinessType, null);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private bool DynamicShouldTerminal(WorkflowStep step)
|
|
@@ -828,7 +892,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
}
|
|
|
|
|
|
|
|
|
- private NextStepOption CreateCsEndStepByPrev(List<WorkflowStep> steps, WorkflowStep step)
|
|
|
+ private NextStepOption GetCsEndStepByPrev(List<WorkflowStep> steps, WorkflowStep step)
|
|
|
{
|
|
|
var prevStep = steps.FirstOrDefault(d => d.Id == step.PrevStepId);
|
|
|
if (prevStep is null)
|
|
@@ -884,12 +948,12 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- private async Task<NextStepOption> CreateDynamicStepAsync(EDynamicPolicy policy,
|
|
|
- CancellationToken cancellationToken)
|
|
|
+ private async Task<NextStepOption> GetDynamicStepAsync(EDynamicPolicy policy, bool isOrigin,
|
|
|
+ EBusinessType currentBusinessType, CancellationToken cancellationToken)
|
|
|
{
|
|
|
int orgLevel;
|
|
|
List<Kv> items;
|
|
|
- EBusinessType businessType;
|
|
|
+ EFlowDirection flowDirection;
|
|
|
var levelOneOrgCode = _sessionContext.RequiredOrgId.GetHigherOrgCode();
|
|
|
switch (policy)
|
|
|
{
|
|
@@ -903,7 +967,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
.Where(d => d.IsCenter)
|
|
|
.Select(d => new Kv { Key = d.Id, Value = d.Name })
|
|
|
.ToListAsync(cancellationToken);
|
|
|
- businessType = EBusinessType.Center;
|
|
|
+ flowDirection =
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -969,7 +1033,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- //private async Task<IReadOnlyList<NextStepOption>> CreateConfigStepsAsync(List<StepDefine> stepDefines,
|
|
|
+ //private async Task<IReadOnlyList<NextStepOption>> GetConfigStepsAsync(List<StepDefine> stepDefines,
|
|
|
// CancellationToken cancellationToken)
|
|
|
//{
|
|
|
// foreach (var stepDefine in stepDefines)
|