xf 1 gadu atpakaļ
vecāks
revīzija
ab70ff029c

+ 17 - 9
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -437,13 +437,19 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
         if (currentStep.IsInCountersign())
         {
-            var countersignEndOption = CreateCountersignEndStep(workflow.Steps, currentStep);
-
             if (currentStep.IsCountersignEndStep)
             {
                 //当前待办节点为会签汇总节点时:检查是否为顶级会签发起节点(csstate==none),t:按配置往下走,f:继续往上汇总,不需要重复往下指派
                 if (currentStep.CountersignStartStepId != workflow.TopCountersignStepId)
                 {
+                    //查找当前节点对应会签开始节点的上级作为下一个cs汇总节点的汇总对象
+                    var startCountersignStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.CountersignStartStepId);
+                    if (startCountersignStep is null)
+                        throw new UserFriendlyException(
+                            $"未查询到会签开始节点,workflowId: {workflow.Id}, startStepId: {currentStep.CountersignStartStepId}",
+                            "未查询到会签开始节点,数据异常");
+                    var countersignEndOption = CreateCsEndStepByPrev(workflow.Steps, startCountersignStep);
+
                     countersignEndOption.InputRealHandler = true;
                     dto.Steps = new List<NextStepOption> { countersignEndOption };
                     return dto;
@@ -462,6 +468,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
             }
             else
             {
+                //汇总节点
+                var countersignEndOption = CreateCsEndStepByPrev(workflow.Steps, currentStep);
                 //按会签策略
                 var nextStepOption = await CreateDynamicStepAsync(currentStep.CountersignPolicy.Value, cancellationToken);
                 dto.Steps = new List<NextStepOption> { nextStepOption, countersignEndOption };
@@ -777,20 +785,20 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     }
 
 
-    private NextStepOption CreateCountersignEndStep(List<WorkflowStep> steps, WorkflowStep step)
+    private NextStepOption CreateCsEndStepByPrev(List<WorkflowStep> steps, WorkflowStep step)
     {
-        var parentStep = steps.FirstOrDefault(d => d.Id == step.PrevStepId);
-        if (parentStep is null)
+        var prevStep = steps.FirstOrDefault(d => d.Id == step.PrevStepId);
+        if (prevStep is null)
             throw new UserFriendlyException("未查找到会签上级节点");
-        var text = parentStep.HandlerOrgIsCenter.Value
+        var text = prevStep.HandlerOrgIsCenter.Value
             ? "热线中心汇总"
-            : $"{parentStep.HandlerOrgId.CalcOrgLevel().ToChinese()}级部门汇总";
+            : $"{prevStep.HandlerOrgId.CalcOrgLevel().ToChinese()}级部门汇总";
         return new NextStepOption
         {
-            Key = parentStep.Code,
+            Key = prevStep.Code,
             Value = text,//parentStep.Name,//todo name不对,目前为definition.name,需改为x级部门办理
             BackToCountersignEnd = true,
-            Items = new List<Kv> { new(parentStep.HandlerId, parentStep.HandlerName) },
+            Items = new List<Kv> { new(prevStep.HandlerId, prevStep.HandlerName) },
         };
     }
 

+ 5 - 0
src/Hotline/FlowEngine/Workflows/StepBasicEntity.cs

@@ -224,6 +224,11 @@ public abstract class StepBasicEntity : CreationEntity
     /// </summary>
     public DateTime? StepExpiredTime { get; set; }
 
+    /// <summary>
+    /// 发起会签
+    /// </summary>
+    public bool IsStartCountersign { get; set; }
+
     #endregion
 
     #region method

+ 100 - 27
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -253,7 +253,7 @@ namespace Hotline.FlowEngine.Workflows
             var currentStep = GetUnHandleStep(workflow.Steps, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
             if (currentStep.Status is not EWorkflowStepStatus.WaitForAccept) return;
 
-            if(currentStep.HandlerType is EHandlerType.AssignedOrg or EHandlerType.OrgLevel or EHandlerType.OrgType
+            if (currentStep.HandlerType is EHandlerType.AssignedOrg or EHandlerType.OrgLevel or EHandlerType.OrgType
                || (currentStep.InstanceMode is EInstanceMode.Dynamic && !currentStep.DynamicShouldTerminal())//动态并且非结束节点
                    || (currentStep.IsInCountersign() && !currentStep.IsCountersignEndStep)//会签并且非会签节点
                    )
@@ -368,7 +368,7 @@ namespace Hotline.FlowEngine.Workflows
                 var countersignStartStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.PrevStepId);
                 if (countersignStartStep is null)
                     throw new UserFriendlyException("未查询到会签开始节点");
-                if (!countersignStartStep.HasStartedCountersign())
+                if (!countersignStartStep.IsStartCountersign)
                     throw new UserFriendlyException("查询到会签开始节点状态异常");
 
                 countersignStartStep.CountersignSteps.First(d => d.StepId == currentStep.Id).Completed = true;
@@ -415,7 +415,7 @@ namespace Hotline.FlowEngine.Workflows
             var nextSteps = await CreateNextStepsAsync(workflow, nextStepDefine, currentStep, dto, expiredTime, cancellationToken);
 
             //赋值当前节点的下级办理节点
-            if (dto.IsStartCountersign)
+            if (currentStep.IsInCountersign())
             {
                 currentStep.CreateCountersignSteps(nextSteps);
                 await _workflowStepRepository.UpdateAsync(currentStep, cancellationToken);
@@ -462,34 +462,107 @@ namespace Hotline.FlowEngine.Workflows
             List<WorkflowStep> nextSteps = new();
             if (currentStep.IsInCountersign())
             {
-                if (dto.BackToCountersignEnd)
-                {
-                    var countersignStartStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.PrevStepId);
-                    if (countersignStartStep is null)
-                        throw new UserFriendlyException("未查询到会签开始节点");
-                    if (!countersignStartStep.HasStartedCountersign())
-                        throw new UserFriendlyException("查询到会签开始节点状态异常");
-                    //会签未全部办理则不创建汇总节点
-                    if (countersignStartStep.StartedCountersignHasAllHandled()
-                        && !workflow.Steps.Any(d => d.IsCountersignEndStep && d.CountersignStartStepId == countersignStartStep.Id))
-                    {
-                        //todo 创建会签汇总节点
-                        var countersignEndStep = await CreateCountersignEndStepAsync(countersignStartStep, dto, cancellationToken);
-                        nextSteps = new List<WorkflowStep> { countersignEndStep };
+                //if (dto.BackToCountersignEnd)
+                //{
+                //    var countersignStartStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.PrevStepId);
+                //    if (countersignStartStep is null)
+                //        throw new UserFriendlyException("未查询到会签开始节点");
+                //    if (!countersignStartStep.HasStartedCountersign())
+                //        throw new UserFriendlyException("查询到会签开始节点状态异常");
+                //    //会签未全部办理则不创建汇总节点
+                //    if (countersignStartStep.StartedCountersignHasAllHandled()
+                //        && !workflow.Steps.Any(d => d.IsCountersignEndStep && d.CountersignStartStepId == countersignStartStep.Id))
+                //    {
+                //        //todo 创建会签汇总节点
+                //        var countersignEndStep = await CreateCountersignEndStepAsync(countersignStartStep, dto, cancellationToken);
+                //        nextSteps = new List<WorkflowStep> { countersignEndStep };
 
-                        //create trace
-                        await CreateTraceAsync(workflow, countersignEndStep, EWorkflowTraceStatus.Normal, cancellationToken);
+                //        //create trace
+                //        await CreateTraceAsync(workflow, countersignEndStep, EWorkflowTraceStatus.Normal, cancellationToken);
 
-                        await _mediator.Publish(new CountersignEndAssigned(workflow), cancellationToken);
+                //        await _mediator.Publish(new CountersignEndAssigned(workflow), cancellationToken);
+                //    }
+                //}
+                //else
+                //{
+                //    //todo 依据会签策略创建会签下一级节点
+                //    //考虑没有下级部门情况
+                //    nextSteps = await CreateStepsAsync(workflow, nextStepDefine, currentStep, dto, dto.NextHandlers,
+                //        EWorkflowStepStatus.WaitForAccept, currentStep.GetNextStepCountersignPosition(),
+                //        expiredTime, false, cancellationToken);
+                //}
+
+                if (currentStep.IsCountersignEndStep)
+                {
+                    //todo check if current is topend f: csStartStep.prev
+                    //todo t: check if dto.StartCs t: csconfig f: config
+                    if (currentStep.CountersignStartStepId == workflow.TopCountersignStepId)
+                    {
+                        if (dto.IsStartCountersign)
+                        {
+                            //todo 依据会签策略创建会签下一级节点
+                            nextSteps = await CreateStepsAsync(workflow, nextStepDefine, currentStep, dto, dto.NextHandlers,
+                                EWorkflowStepStatus.WaitForAccept, currentStep.GetNextStepCountersignPosition(),
+                                expiredTime, false, cancellationToken);
+                        }
+                        else
+                        {
+                            //todo 创建普通节点(根据配置)
+                            nextSteps = await CreateStepsByDefineAsync(workflow, nextStepDefine, currentStep, dto, expiredTime, cancellationToken);
+                        }
+                    }
+                    else
+                    {
+                        //todo csStartStep.prev
+                        var csStartStep =
+                            workflow.Steps.FirstOrDefault(d => d.Id == currentStep.CountersignStartStepId);
+                        if (csStartStep is null)
+                            throw new UserFriendlyException("未查询到会签节点");
+                        var prevStep = workflow.Steps.FirstOrDefault(d => d.Id == csStartStep.PrevStepId);
+                        if (prevStep is null)
+                            throw new UserFriendlyException("未查询到当前节点上级节点");
+                        //会签未全部办理则不创建汇总节点
+                        if (prevStep.StartedCountersignHasAllHandled())
+                        {
+                            //todo 创建会签汇总节点
+                            var countersignEndStep = await CreateCountersignEndStepAsync(prevStep, dto, cancellationToken);
+                            nextSteps = new List<WorkflowStep> { countersignEndStep };
+
+                            //create trace
+                            await CreateTraceAsync(workflow, countersignEndStep, EWorkflowTraceStatus.Normal, cancellationToken);
+
+                            await _mediator.Publish(new CountersignEndAssigned(workflow), cancellationToken);
+                        }
                     }
                 }
                 else
                 {
-                    //todo 依据会签策略创建会签下一级节点
-                    //考虑没有下级部门情况
-                    nextSteps = await CreateStepsAsync(workflow, nextStepDefine, currentStep, dto, dto.NextHandlers,
-                        EWorkflowStepStatus.WaitForAccept, currentStep.GetNextStepCountersignPosition(),
-                        expiredTime, false, cancellationToken);
+                    if (dto.BackToCountersignEnd)
+                    {
+                        //todo check if cs all complete, create next
+                        var prevStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.PrevStepId);
+                        if (prevStep is null)
+                            throw new UserFriendlyException("未查询到当前节点上级节点");
+                        //会签未全部办理则不创建汇总节点
+                        if (prevStep.StartedCountersignHasAllHandled())
+                        {
+                            //todo 创建会签汇总节点
+                            var countersignEndStep = await CreateCountersignEndStepAsync(prevStep, dto, cancellationToken);
+                            nextSteps = new List<WorkflowStep> { countersignEndStep };
+
+                            //create trace
+                            await CreateTraceAsync(workflow, countersignEndStep, EWorkflowTraceStatus.Normal, cancellationToken);
+
+                            await _mediator.Publish(new CountersignEndAssigned(workflow), cancellationToken);
+                        }
+                    }
+                    else
+                    {
+                        //todo 依据会签策略创建会签下一级节点
+                        nextSteps = await CreateStepsAsync(workflow, nextStepDefine, currentStep, dto, dto.NextHandlers,
+                            EWorkflowStepStatus.WaitForAccept, currentStep.GetNextStepCountersignPosition(),
+                            expiredTime, false, cancellationToken);
+                    }
                 }
             }
             else if (dto.IsStartCountersign)
@@ -519,7 +592,6 @@ namespace Hotline.FlowEngine.Workflows
             BasicWorkflowDto dto, CancellationToken cancellationToken)
         {
             var csEndStep = _mapper.Map<WorkflowStep>(countersignStartStep);
-            _mapper.Map(dto, csEndStep);
             csEndStep.Status = EWorkflowStepStatus.WaitForAccept;
             csEndStep.NextSteps = new();
             csEndStep.PrevStepId = null;
@@ -535,6 +607,7 @@ namespace Hotline.FlowEngine.Workflows
             csEndStep.TimeLimit = GetTimeLimit(""); //todo 过期时间
 
             csEndStep.Reset();
+            csEndStep.ResetParameters();
 
             await _workflowStepRepository.AddAsync(csEndStep, cancellationToken);
             return csEndStep;
@@ -1432,7 +1505,7 @@ namespace Hotline.FlowEngine.Workflows
             CancellationToken cancellationToken
             )
         {
-            var countersignId = prevStep.HasStartedCountersign() ? prevStep.StartCountersignId : prevStep.CountersignId;
+            var countersignId = prevStep.IsStartCountersign ? prevStep.StartCountersignId : prevStep.CountersignId;
 
             List<WorkflowStep> steps = new();
             if (dto.IsStartCountersign)

+ 32 - 15
src/Hotline/FlowEngine/Workflows/WorkflowStep.cs

@@ -16,7 +16,7 @@ public class WorkflowStep : StepBasicEntity
     public List<StepSimple> NextSteps { get; set; } = new();
 
     /// <summary>
-    /// 前一级节点Id(stepBox此字段为上级stepBoxId,step为上级stepId),汇总节点无此字段(因可能有多个上级来源)
+    /// 前一级节点Id,会签汇总节点无此字段(因可能有多个上级来源)
     /// </summary>
     public string? PrevStepId { get; set; }
     public string? PrevStepCode { get; set; }
@@ -57,17 +57,11 @@ public class WorkflowStep : StepBasicEntity
 
     /// <summary>
     /// 节点处于会签流程中的位置(区别直接办理会签和会签内非会签节点)
+    /// outer属于特殊会签
     /// 最顶层的发起会签节点为none
     /// </summary>
     public ECountersignPosition CountersignPosition { get; set; }
 
-    #region 发起会签节点特有
-
-    /// <summary>
-    /// 发起会签生成会签Id(不发起会签节点无此字段)
-    /// </summary>
-    public string? StartCountersignId { get; set; }
-
     /// <summary>
     /// 会签直属办理节点
     /// </summary>
@@ -79,6 +73,13 @@ public class WorkflowStep : StepBasicEntity
     /// </summary>
     public bool IsStartedCountersignEnd { get; set; }
 
+    #region 发起会签节点特有
+
+    /// <summary>
+    /// 发起会签生成会签Id(不发起会签节点无此字段)
+    /// </summary>
+    public string? StartCountersignId { get; set; }
+
     #endregion
 
     #region 会签汇总节点特有
@@ -104,10 +105,10 @@ public class WorkflowStep : StepBasicEntity
     /// </summary>
     public bool IsInCountersign() => CountersignPosition != ECountersignPosition.None;
 
-    /// <summary>
-    /// 是否发起过会签
-    /// </summary>
-    public bool HasStartedCountersign() => !string.IsNullOrEmpty(StartCountersignId);
+    ///// <summary>
+    ///// 是否发起过会签
+    ///// </summary>
+    //public bool HasStartedCountersign() => !string.IsNullOrEmpty(StartCountersignId);
 
     /// <summary>
     /// 接办
@@ -171,7 +172,7 @@ public class WorkflowStep : StepBasicEntity
     /// </summary>
     /// <returns></returns>
     public ECountersignPosition GetNextStepCountersignPosition() =>
-        HasStartedCountersign()
+        IsStartCountersign
             ? ECountersignPosition.Inner
             : IsInCountersign()
                 ? ECountersignPosition.Outer
@@ -203,14 +204,30 @@ public class WorkflowStep : StepBasicEntity
         AcceptTime = null;
     }
 
+    /// <summary>
+    /// 重置办理参数
+    /// </summary>
+    public void ResetParameters()
+    {
+        NextHandlers = new();
+        NextMainHandler = null;
+        NextStepCode = null;
+        BackToCountersignEnd = false;
+        IsSms = false;
+        Opinion = null;
+        Additions = new();
+        StepExpiredTime = null;
+    }
+
     /// <summary>
     /// 发起会签节点发起的会签是否全都办理完成
     /// </summary>
     /// <returns></returns>
     public bool StartedCountersignHasAllHandled()
     {
-        if (!HasStartedCountersign())
-            throw new UserFriendlyException("该节点未发起会签");
+        //if (!HasStartedCountersign())
+        //    throw new UserFriendlyException("该节点未发起会签");
+        //outer的情况也属于特殊会签
         return CountersignSteps.All(d => d.Completed);
     }