Pārlūkot izejas kodu

fixed: flowAssignInfo

xf 1 gadu atpakaļ
vecāks
revīzija
5b07448829

+ 92 - 140
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -1,6 +1,5 @@
 using Hotline.Application.Contracts.Validators.FlowEngine;
 using Hotline.Caching.Interfaces;
-using Hotline.Caching.Services;
 using Hotline.FlowEngine;
 using Hotline.FlowEngine.Definitions;
 using Hotline.FlowEngine.WorkflowModules;
@@ -8,9 +7,7 @@ using Hotline.FlowEngine.Workflows;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Orders;
-using Hotline.SeedData;
 using Hotline.Settings;
-using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.FlowEngine.Definition;
@@ -18,16 +15,12 @@ using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Identity;
 using Hotline.Users;
 using MapsterMapper;
-using Microsoft.AspNetCore.Http;
-using SqlSugar;
-using System.Threading;
 using XF.Domain.Authentications;
 using XF.Domain.Dependency;
 using XF.Domain.Entities;
 using XF.Domain.Exceptions;
 using XF.Domain.Extensions;
 using XF.Domain.Repository;
-using XF.Utility.EnumExtensions;
 
 namespace Hotline.Application.FlowEngine;
 
@@ -38,7 +31,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     private readonly IOrderDomainService _orderDomainService;
     private readonly IWorkflowRepository _workflowRepository;
     private IRepository<WorkflowDefinition> _definitionRepository;
-    private readonly IRepository<WorkflowAssign> _workflowAssignRepository;
+    private IRepository<WorkflowStep> _workflowStepRepository;
+    private IRepository<WorkflowTrace> _workflowTraceRepository;
     private readonly IRepository<User> _userRepository;
     private readonly IAccountRepository _accountRepository;
     private readonly ISystemOrganizeRepository _organizeRepository;
@@ -56,7 +50,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         IOrderDomainService orderDomainService,
         IWorkflowRepository workflowRepository,
         IRepository<WorkflowDefinition> definitionRepository,
-        IRepository<WorkflowAssign> workflowAssignRepository,
+        IRepository<WorkflowStep> workflowStepRepository,
+        IRepository<WorkflowTrace> workflowTraceRepository,
         IRepository<User> userRepository,
         IAccountRepository accountRepository,
         ISystemOrganizeRepository organizeRepository,
@@ -72,7 +67,6 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         _orderDomainService = orderDomainService;
         _workflowRepository = workflowRepository;
         _definitionRepository = definitionRepository;
-        _workflowAssignRepository = workflowAssignRepository;
         _userRepository = userRepository;
         _accountRepository = accountRepository;
         _organizeRepository = organizeRepository;
@@ -81,6 +75,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         _systemDomainService = systemDomainService;
         _sessionContext = sessionContext;
         _mapper = mapper;
+        _workflowStepRepository = workflowStepRepository;
+        _workflowTraceRepository = workflowTraceRepository;
     }
 
     public async Task<string> StartWorkflowAsync(StartWorkflowDto dto, string externalId, CancellationToken cancellationToken)
@@ -128,10 +124,35 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         var workflow = await _workflowDomainService.CreateWorkflowAsync(wfModule, dto.Title,
             _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, externalId, cancellationToken);
 
-        var flowAssignInfo = await GetFlowAssignInfoAsync(firstStepDefine, dto.IsStartCountersign, dto.NextHandlers,
-            cancellationToken);
+        //startstep
+        var nextSteps = _mapper.Map<List<StepSimple>>(startStepDefine.NextSteps);
+        nextSteps.First(d => d.Code == dto.NextStepCode).Selected = true;
+        var startStep = new WorkflowStep
+        {
+            WorkflowId = workflow.Id,
+            Handlers = new List<Kv> { new(_sessionContext.RequiredUserId, _sessionContext.UserName) },
+            NextSteps = nextSteps,
+            IsMain = true,
+            IsOrigin = true,
+            Status = EWorkflowStepStatus.WaitForHandle,
+            PrevChosenStepCode = null,
+        };
+        var startDefine = workflow.WorkflowDefinition.FindStartStepDefine();
+        _mapper.Map(startDefine, startStep);
+        await _workflowStepRepository.AddAsync(startStep, cancellationToken);
+        workflow.Steps.Add(startStep);
+
+        //starttrace
+        var startTrace = _mapper.Map<WorkflowTrace>(startStep);
+        startTrace.StepId = startStep.Id;
+        startTrace.Status = EWorkflowTraceStatus.Normal;
+        _mapper.Map(dto, startTrace);
+        await _workflowTraceRepository.AddAsync(startTrace, cancellationToken);
+        workflow.Traces.Add(startTrace);
+
+        var flowAssignInfo = await GetNextStepFlowAssignInfoAsync(workflow, startStep, firstStepDefine, dto, cancellationToken);
 
-        await _workflowDomainService.StartAsync(workflow, dto, startStepDefine, firstStepDefine, flowAssignInfo, cancellationToken);
+        await _workflowDomainService.StartAsync(workflow, startStep, dto, firstStepDefine, flowAssignInfo, cancellationToken);
 
         ////更新接办部门(详情页面展示)
         //await AddOrUpdateAssignAsync(workflow, dto, nextStepBoxDefine, cancellationToken);
@@ -191,10 +212,9 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 throw new UserFriendlyException("下一节点不允许发起会签");
         }
 
-        var flowAssignMode = await GetFlowAssignInfoAsync(nextStepDefine, dto.IsStartCountersign, dto.NextHandlers,
-            cancellationToken);
+        var flowAssignInfo = await GetNextStepFlowAssignInfoAsync(workflow, currentStep, nextStepDefine, dto, cancellationToken);
 
-        await _workflowDomainService.NextAsync(workflow, currentStep, dto, nextStepDefine, flowAssignMode, dto.StepExpiredTime,
+        await _workflowDomainService.NextAsync(workflow, currentStep, dto, nextStepDefine, flowAssignInfo, dto.StepExpiredTime,
             cancellationToken);
     }
 
@@ -211,9 +231,9 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
         var targetStepDefine = _workflowDomainService.GetStepDefine(workflow.WorkflowDefinition, dto.NextStepCode);
         //var isStartCountersign = targetStepDefine.CouldPrevStartCountersign(dto.NextHandlers.Count);
-        var flowAssignMode = await GetFlowAssignInfoAsync(targetStepDefine, dto.IsStartCountersign, dto.NextHandlers,
-            cancellationToken);
-        await _workflowDomainService.RecallAsync(workflow, dto, targetStepDefine, flowAssignMode, cancellationToken);
+        var flowAssignInfo = await GetNextStepFlowAssignInfoByDefineAsync(targetStepDefine, dto.IsStartCountersign,
+            dto.NextHandlers, cancellationToken);
+        await _workflowDomainService.RecallAsync(workflow, dto, targetStepDefine, flowAssignInfo, cancellationToken);
     }
 
     /// <summary>
@@ -229,9 +249,9 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
         var targetStepDefine = _workflowDomainService.GetStepDefine(workflow.WorkflowDefinition, dto.NextStepCode);
         //var isStartCountersign = targetStepDefine.CouldPrevStartCountersign(dto.NextHandlers.Count);
-        var flowAssignMode = await GetFlowAssignInfoAsync(targetStepDefine, dto.IsStartCountersign, dto.NextHandlers,
-            cancellationToken);
-        await _workflowDomainService.JumpAsync(workflow, dto, targetStepDefine, flowAssignMode, cancellationToken);
+        var flowAssignInfo = await GetNextStepFlowAssignInfoByDefineAsync(targetStepDefine, dto.IsStartCountersign,
+            dto.NextHandlers, cancellationToken);
+        await _workflowDomainService.JumpAsync(workflow, dto, targetStepDefine, flowAssignInfo, cancellationToken);
     }
 
     /// <summary>
@@ -243,8 +263,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
             await _workflowDomainService.GetWorkflowAsync(dto.WorkflowId, true, true,
                 cancellationToken: cancellationToken);
         var targetStepDefine = _workflowDomainService.GetStepDefine(workflow.WorkflowDefinition, dto.NextStepCode);
-        var flowAssignInfo = await GetFlowAssignInfoAsync(targetStepDefine, dto.IsStartCountersign, dto.NextHandlers,
-            cancellationToken);
+        var flowAssignInfo = await GetNextStepFlowAssignInfoByDefineAsync(targetStepDefine, dto.IsStartCountersign,
+            dto.NextHandlers, cancellationToken);
         await _workflowDomainService.RedoAsync(workflow, dto, targetStepDefine, flowAssignInfo, cancellationToken);
     }
 
@@ -983,56 +1003,61 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     //}
 
     /// <summary>
-    /// 查询指派办理人的处理方式及实际办理人
+    /// 查询下一节点办理对象类型(user or org)及实际办理对象
     /// </summary>
-    public async Task<FlowAssignInfo> GetFlowAssignInfoAsync(StepDefine stepDefine, bool isStartCountersign,
-        List<Kv> handlers, CancellationToken cancellationToken)
+    public async Task<FlowAssignInfo> GetNextStepFlowAssignInfoAsync(Workflow workflow, WorkflowStep currentStep, StepDefine nextStepDefine, BasicWorkflowDto dto, CancellationToken cancellationToken)
     {
-        if (stepDefine.StepType is EStepType.End) return new();
+        if (nextStepDefine.StepType is EStepType.End) return new();
+
+        var isStartCountersign = dto.IsStartCountersign;
+        var handlers = dto.NextHandlers;
 
         if (isStartCountersign)
-        {
+            //按会签策略判断,目前所有策略为org
             return FlowAssignInfo.Create(EFlowAssignType.Org, handlers, isStartCountersign);
-        }
-        else
+
+        if (currentStep.IsInCountersign() && !currentStep.IsTopCountersignEndStep(workflow.TopCountersignStepId))
+            return FlowAssignInfo.Create(EFlowAssignType.Org, handlers, isStartCountersign);
+
+        if (currentStep.InstanceMode is EInstanceMode.Dynamic && !currentStep.DynamicShouldTerminal())
+            return FlowAssignInfo.Create(EFlowAssignType.Org, handlers, isStartCountersign);
+
+        return await GetNextStepFlowAssignInfoByDefineAsync(nextStepDefine, isStartCountersign, handlers, cancellationToken);
+    }
+
+    /// <summary>
+    /// 按流程模板配置创建下一步办理对象
+    /// </summary>
+    private async Task<FlowAssignInfo> GetNextStepFlowAssignInfoByDefineAsync(StepDefine nextStepDefine, bool isStartCountersign,
+    List<Kv> handlers, CancellationToken cancellationToken)
+    {
+        switch (nextStepDefine.HandlerType)
         {
-            switch (stepDefine.InstanceMode)
-            {
-                case EInstanceMode.Config:
-                    switch (stepDefine.HandlerType)
-                    {
-                        case EHandlerType.Role:
-                            if (!handlers.Any())
-                            {
-                                var roles = await _roleRepository.Queryable()
-                                    .Includes(d => d.Accounts, x => x.User)
-                                    .Where(d => stepDefine.HandlerTypeItems.Select(d => d.Key).Contains(d.Name))
-                                    .ToListAsync(cancellationToken);
-                                handlers = roles.SelectMany(d => d.Accounts).Distinct()
-                                    .Select(d => new Kv(d.Id, d.User.Name))
-                                    .ToList();
-                            }
-
-                            return FlowAssignInfo.Create(EFlowAssignType.User, handlers, isStartCountersign);
-
-                        case EHandlerType.OrgLevel:
-                        case EHandlerType.OrgType:
-                        case EHandlerType.AssignedOrg:
-                            return FlowAssignInfo.Create(EFlowAssignType.Org, handlers, isStartCountersign);
-
-                        case EHandlerType.AssignedUser:
-                            return FlowAssignInfo.Create(EFlowAssignType.User, handlers, isStartCountersign);
-
-                        default:
-                            throw new ArgumentOutOfRangeException();
-                    }
-                case EInstanceMode.Dynamic:
-                    return FlowAssignInfo.Create(EFlowAssignType.Org, handlers, isStartCountersign);
-                default:
-                    throw new ArgumentOutOfRangeException();
-            }
-        }
+            case EHandlerType.Role:
+                if (!handlers.Any())
+                {
+                    var roles = await _roleRepository.Queryable()
+                        .Includes(d => d.Accounts, x => x.User)
+                        .Where(d => nextStepDefine.HandlerTypeItems.Select(d => d.Key).Contains(d.Name))
+                        .ToListAsync(cancellationToken);
+                    handlers = roles.SelectMany(d => d.Accounts).Distinct()
+                        .Select(d => new Kv(d.Id, d.User.Name))
+                        .ToList();
+                }
+
+                return FlowAssignInfo.Create(EFlowAssignType.User, handlers, isStartCountersign);
+
+            case EHandlerType.OrgLevel:
+            case EHandlerType.OrgType:
+            case EHandlerType.AssignedOrg:
+                return FlowAssignInfo.Create(EFlowAssignType.Org, handlers, isStartCountersign);
+
+            case EHandlerType.AssignedUser:
+                return FlowAssignInfo.Create(EFlowAssignType.User, handlers, isStartCountersign);
 
+            default:
+                throw new ArgumentOutOfRangeException();
+        }
     }
 
 
@@ -1055,78 +1080,5 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         return wfModule;
     }
 
-    /// <summary>
-    /// 更新接办部门
-    /// </summary>
-    private async Task AddOrUpdateAssignAsync(Workflow workflow, BasicWorkflowDto dto, StepDefine nextStepBoxDefine,
-        CancellationToken cancellationToken)
-    {
-        if (nextStepBoxDefine.StepType is EStepType.Normal)
-        {
-            await _workflowAssignRepository.RemoveAsync(d =>
-                    d.WorkflowId == workflow.Id && d.OrgCode == _sessionContext.RequiredOrgId,
-                cancellationToken: cancellationToken);
-
-            var assigns = new List<WorkflowAssign>();
-            switch (nextStepBoxDefine.HandlerType)
-            {
-                case EHandlerType.Role:
-                    if (dto.NextHandlers.Any())
-                    {
-                        //选了handler,handler为userId 
-                        var users1 = await _userRepository.Queryable()
-                            .Includes(d => d.Organization)
-                            .Where(d => dto.NextHandlers.Select(x => x.Key).Contains(d.Id))
-                            .ToListAsync(cancellationToken);
-                        assigns = users1.Select(d => WorkflowAssign.Create(workflow.Id, d.Id, d.Organization.Name))
-                            .ToList();
-                    }
-                    else
-                    {
-                        ////如果模板配置为本部门办理,则为当前办理人orgCode,非本部门办理:属于该角色的所有用户所属部门
-                        //if (nextStepBoxDefine.OnlySelfOrg.HasValue && nextStepBoxDefine.OnlySelfOrg.Value)
-                        //{
-                        //    assigns = new List<WorkflowAssign>
-                        //    {
-                        //        WorkflowAssign.Create(workflow.Id, _sessionContext.RequiredOrgCode, _sessionContext.OrgName)
-                        //    };
-                        //}
-                        //else
-                        //{
-                        var accounts = await _accountRepository.Queryable()
-                            .Includes(d => d.User, d => d.Organization)
-                            .Where(d => dto.NextHandlers.Select(d => d.Key).Contains(d.Name))
-                            .ToListAsync(cancellationToken);
-                        assigns = accounts.Select(d => d.User.Organization).Select(d =>
-                            WorkflowAssign.Create(workflow.Id, d.Id, d.Name)).ToList();
-                        //}
-                    }
-
-                    break;
-
-                case EHandlerType.OrgLevel:
-                case EHandlerType.OrgType:
-                case EHandlerType.AssignedOrg:
-                    assigns = dto.NextHandlers.Select(d => WorkflowAssign.Create(workflow.Id, d.Key, d.Value)).ToList();
-                    break;
-
-                case EHandlerType.AssignedUser:
-                    //指定人所属部门
-                    var users = await _userRepository.Queryable()
-                        .Includes(d => d.Organization)
-                        .Where(d => dto.NextHandlers.Select(x => x.Key).Contains(d.Id))
-                        .ToListAsync(cancellationToken);
-                    assigns = users.Select(d => WorkflowAssign.Create(workflow.Id, d.Id, d.Organization.Name))
-                        .ToList();
-                    break;
-                default:
-                    throw new ArgumentOutOfRangeException();
-            }
-
-            if (assigns.Any())
-                await _workflowAssignRepository.AddRangeAsync(assigns, cancellationToken);
-        }
-    }
-
     #endregion
 }

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

@@ -17,8 +17,8 @@ namespace Hotline.FlowEngine.Workflows
         /// <summary>
         /// 进行流程的开始节点
         /// </summary>
-        Task StartAsync(Workflow workflow, BasicWorkflowDto dto, StepDefine startStepDefine,
-            StepDefine firstStepDefine, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken);
+        Task StartAsync(Workflow workflow, WorkflowStep startStep, BasicWorkflowDto dto, StepDefine firstStepDefine, 
+            FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken);
 
         /// <summary>
         /// 查询工作流

+ 28 - 28
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -92,36 +92,36 @@ namespace Hotline.FlowEngine.Workflows
         /// <summary>
         /// 流程开始
         /// </summary>
-        public async Task StartAsync(Workflow workflow, BasicWorkflowDto dto, StepDefine startStepDefine,
-            StepDefine firstStepDefine, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
+        public async Task StartAsync(Workflow workflow, WorkflowStep startStep, BasicWorkflowDto dto, StepDefine firstStepDefine,
+            FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
         {
-            //todo 1. 创建开始节点,first节点 (和trace)2.办理开始节点 
+            //1. 创建first节点 (和trace)2.办理开始节点 
 
-            //startstep
-            var nextSteps = _mapper.Map<List<StepSimple>>(startStepDefine.NextSteps);
-            nextSteps.First(d => d.Code == dto.NextStepCode).Selected = true;
-            var startStep = new WorkflowStep
-            {
-                WorkflowId = workflow.Id,
-                Handlers = new List<Kv> { new(_sessionContext.RequiredUserId, _sessionContext.UserName) },
-                NextSteps = nextSteps,
-                IsMain = true,
-                IsOrigin = true,
-                Status = EWorkflowStepStatus.WaitForHandle,
-                PrevChosenStepCode = null,
-            };
-            var startDefine = workflow.WorkflowDefinition.FindStartStepDefine();
-            _mapper.Map(startDefine, startStep);
-            await _workflowStepRepository.AddAsync(startStep, cancellationToken);
-            workflow.Steps.Add(startStep);
-
-            //starttrace
-            var startTrace = _mapper.Map<WorkflowTrace>(startStep);
-            startTrace.StepId = startStep.Id;
-            startTrace.Status = EWorkflowTraceStatus.Normal;
-            _mapper.Map(dto, startTrace);
-            await _workflowTraceRepository.AddAsync(startTrace, cancellationToken);
-            workflow.Traces.Add(startTrace);
+            ////startstep
+            //var nextSteps = _mapper.Map<List<StepSimple>>(startStepDefine.NextSteps);
+            //nextSteps.First(d => d.Code == dto.NextStepCode).Selected = true;
+            //var startStep = new WorkflowStep
+            //{
+            //    WorkflowId = workflow.Id,
+            //    Handlers = new List<Kv> { new(_sessionContext.RequiredUserId, _sessionContext.UserName) },
+            //    NextSteps = nextSteps,
+            //    IsMain = true,
+            //    IsOrigin = true,
+            //    Status = EWorkflowStepStatus.WaitForHandle,
+            //    PrevChosenStepCode = null,
+            //};
+            //var startDefine = workflow.WorkflowDefinition.FindStartStepDefine();
+            //_mapper.Map(startDefine, startStep);
+            //await _workflowStepRepository.AddAsync(startStep, cancellationToken);
+            //workflow.Steps.Add(startStep);
+
+            ////starttrace
+            //var startTrace = _mapper.Map<WorkflowTrace>(startStep);
+            //startTrace.StepId = startStep.Id;
+            //startTrace.Status = EWorkflowTraceStatus.Normal;
+            //_mapper.Map(dto, startTrace);
+            //await _workflowTraceRepository.AddAsync(startTrace, cancellationToken);
+            //workflow.Traces.Add(startTrace);
 
             //firststeps
             var firstSteps = await CreateNextStepsAsync(workflow, firstStepDefine, startStep, dto, workflow.ExpiredTime,

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

@@ -236,7 +236,7 @@ public class WorkflowStep : StepBasicEntity
     /// 动态实例化节点是否应该终止
     /// </summary>
     /// <returns></returns>
-    public bool DynamicShouldTerminal() => TerminalDynamicMark == PrevChosenStepCode;
+    public bool DynamicShouldTerminal() => TerminalDynamicMark == NextStepCode;
 
     /// <summary>
     /// 是否是顶级会签汇总节点