xf 1 rok pred
rodič
commit
3a90893422

+ 65 - 0
src/Hotline.Api/Controllers/WorkflowController.cs

@@ -444,6 +444,71 @@ public class WorkflowController : BaseController
         return _mapper.Map<WorkflowDto>(workflow);
     }
 
+    /// <summary>
+    /// 查询被督办/催办部门
+    /// </summary>
+    /// <param name="workflowId"></param>
+    /// <returns></returns>
+    [HttpGet("{workflowId}/urge")]
+    public async Task<IReadOnlyList<Kv>> GetUrgeOrgs(string workflowId)
+    {
+        /*
+         * 非会签:当前部门上至一级部门
+         * 中心会签:一级部门下至所有当前办理部门(遍历所有会签分支)
+         */
+        //var workflow = await _workflowDomainService.GetWorkflowAsync(workflowId, withSteps: true, cancellationToken: HttpContext.RequestAborted);
+        //var steps = workflow.Steps.Where(d => d.StepType is not EStepType.Start and not EStepType.End).ToList();
+        //if (workflow.CounterSignType is ECounterSignType.Center)
+        //{
+        //   var steps = workflow.Steps.Where(d=> d.StepType is not EStepType.Start and not EStepType.End)
+        //        .SelectMany(d=>d.Handlers)
+        //        .ToList();
+        //}
+        //else
+        //{
+
+        //}
+
+        //
+        var workflow = await _workflowDomainService.GetWorkflowAsync(workflowId, withSteps: true, cancellationToken: HttpContext.RequestAborted);
+        var stepBoxes = workflow.Steps.Where(d => d.StepType != EStepType.Start && d.StepType != EStepType.End).ToList();
+        var steps = stepBoxes.SelectMany(d => d.Steps);
+
+        var orgs = new List<Kv>();
+        foreach (var step in steps)
+        {
+            var orgCode = step.HandlerOrgId ?? step.AcceptorOrgId;
+            var orgName = step.HandlerOrgName ?? step.AcceptorOrgName;
+            if (string.IsNullOrEmpty(orgCode))
+            {
+                switch (step.HandlerType)
+                {
+                    case EHandlerType.Role:
+                    case EHandlerType.AssignedUser:
+                        //todo
+                        var users = await _userRepository.Queryable()
+                            .Includes(d => d.Organization)
+                            .Where(d => step.Handlers.Select(x => x.Key).Contains(d.Id))
+                            .ToListAsync(HttpContext.RequestAborted);
+                        orgs.AddRange(users.Select(d => new Kv(d.OrgId, d.Organization.Name)));
+                        break;
+                    case EHandlerType.OrgLevel:
+                    case EHandlerType.OrgType:
+                    case EHandlerType.AssignedOrg:
+                        orgs.AddRange(step.Handlers);
+                        break;
+                    default:
+                        throw new ArgumentOutOfRangeException();
+                }
+            }
+            else
+            {
+                orgs.Add(new Kv(orgCode, orgName));
+            }
+        }
+        return orgs.DistinctBy(d => d.Key).ToList();
+    }
+
     [HttpGet("base-data")]
     public async Task<dynamic> BaseData()
     {

+ 1 - 1
src/Hotline.Application/FlowEngine/IWorkflowApplication.cs

@@ -10,7 +10,7 @@ namespace Hotline.Application.FlowEngine
         /// <summary>
         /// 开始流程
         /// </summary>
-        Task StartWorkflowAsync(StartWorkflowDto dto, string externalId, CancellationToken cancellationToken);
+        Task<string> StartWorkflowAsync(StartWorkflowDto dto, string externalId, CancellationToken cancellationToken);
 
         /// <summary>
         /// 流转至下一节点(节点办理)

+ 4 - 4
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -83,7 +83,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         _mapper = mapper;
     }
 
-    public async Task StartWorkflowAsync(StartWorkflowDto dto, string externalId, CancellationToken cancellationToken)
+    public async Task<string> StartWorkflowAsync(StartWorkflowDto dto, string externalId, CancellationToken cancellationToken)
     {
         var validator = new StartWorkflowDtoValidator();
         var validResult = validator.Validate(dto);
@@ -135,6 +135,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
         ////更新接办部门(详情页面展示)
         //await AddOrUpdateAssignAsync(workflow, dto, nextStepBoxDefine, cancellationToken);
+
+        return workflow.Id;
     }
 
     /// <summary>
@@ -371,9 +373,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         if (definition.Status is not EDefinitionStatus.Enable)
             throw new UserFriendlyException("该模板不可用");
 
-        var startStep = definition.Steps.FirstOrDefault(d => d.StepType == EStepType.Start);
-        if (startStep == null)
-            throw new UserFriendlyException("未正确配置发起人节点");
+        var startStep = definition.FindStartStepDefine();
 
         //var dto = new NextStepsDto
         //{

+ 5 - 17
src/Hotline.Application/Handlers/FlowEngine/EndWorkflowHandler.cs

@@ -26,8 +26,6 @@ public class EndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
     private readonly IKnowledgeDomainService _knowledgeDomainService;
     private readonly IOrderDomainService _orderDomainService;
     private readonly ITelDomainService _telDomainService;
-    private readonly IWorkflowDomainService _workflowDomainService;
-    private readonly ISystemOrganizeRepository _orgRepository;
     private readonly IOrderRepository _orderRepository;
     private readonly ICapPublisher _capPublisher;
     private readonly IMapper _mapper;
@@ -42,8 +40,6 @@ public class EndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
         IKnowledgeDomainService knowledgeDomainService,
         IOrderDomainService orderDomainService,
         ITelDomainService telDomainService,
-        IWorkflowDomainService workflowDomainService,
-        ISystemOrganizeRepository orgRepository,
         IOrderRepository orderRepository,
         ICapPublisher capPublisher,
         IMapper mapper,
@@ -58,8 +54,6 @@ public class EndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
         _knowledgeDomainService = knowledgeDomainService;
         _orderDomainService = orderDomainService;
         _telDomainService = telDomainService;
-        _workflowDomainService = workflowDomainService;
-        _orgRepository = orgRepository;
         _orderRepository = orderRepository;
         _capPublisher = capPublisher;
         _mapper = mapper;
@@ -91,12 +85,6 @@ public class EndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
                 break;
 
             case WorkflowModuleConsts.OrderHandle:
-                var levelOneOrg = workflow.ActualHandleOrgCode.GetHigherOrgCode();
-                var org = await _orgRepository.GetAsync(d => d.Id == levelOneOrg, cancellationToken);
-                if (org is null)
-                    throw new UserFriendlyException($"无效部门编码, levelOneOrg: {levelOneOrg}", "无效部门编码");
-                await _workflowDomainService.UpdateOrgLevelOneAsync(workflow, org.Id, org.Name, cancellationToken);
-
                 var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, cancellationToken);
                 order.CheckIfFiled();
                 _mapper.Map(workflow, order);
@@ -136,7 +124,7 @@ public class EndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
                     await _bulletinRepository.UpdateAsync(bulletin, cancellationToken);
                 }
                 break;
-            case WorkflowModuleConsts.CircularApply: 
+            case WorkflowModuleConsts.CircularApply:
                 var circular = await _circularRepository.GetAsync(workflow.ExternalId, cancellationToken);
                 if (circular != null)
                 {
@@ -148,10 +136,10 @@ public class EndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
                     if (circular.CircularType == Share.Enums.Article.ECircularType.Person)
                     {
                         //个人
-                         var userlist = await _circularReadGroupRepository.Queryable()
-                            .Where(x => x.CircularId == circular.Id)
-                            .Select(x => x.UserId)
-                            .ToListAsync(cancellationToken);
+                        var userlist = await _circularReadGroupRepository.Queryable()
+                           .Where(x => x.CircularId == circular.Id)
+                           .Select(x => x.UserId)
+                           .ToListAsync(cancellationToken);
                         await _circularRecordRepository.Updateable()
                             .SetColumns(x => x.RecordCount == x.RecordCount + 1)
                             .Where(x => userlist.Contains(x.UserId))

+ 25 - 10
src/Hotline.Application/Handlers/FlowEngine/NextStepHandler.cs

@@ -2,9 +2,9 @@
 using Hotline.Application.FlowEngine;
 using Hotline.FlowEngine.Notifications;
 using Hotline.FlowEngine.WorkflowModules;
-using Hotline.FlowEngine.Workflows;
 using Hotline.KnowledgeBase;
 using Hotline.Orders;
+using Hotline.Repository.SqlSugar.CallCenter;
 using Hotline.Repository.SqlSugar.Orders;
 using Hotline.Settings;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
@@ -31,7 +31,7 @@ public class NextStepHandler : INotificationHandler<NextStepNotify>
     private readonly ILogger<NextStepHandler> _logger;
     private readonly IRepository<OrderScreen> _orderScreenRepository;
 
-	public NextStepHandler(
+    public NextStepHandler(
         IOrderDomainService orderDomainService,
         IKnowledgeDomainService knowledgeDomainService,
         IOrderRepository orderRepository,
@@ -47,7 +47,7 @@ public class NextStepHandler : INotificationHandler<NextStepNotify>
         _mapper = mapper;
         _logger = logger;
         _orderScreenRepository = orderScreenRepository;
-	}
+    }
 
     /// <summary>Handles a notification</summary>
     /// <param name="notification">The notification</param>
@@ -57,10 +57,12 @@ public class NextStepHandler : INotificationHandler<NextStepNotify>
         _logger.LogInformation($"收到{nameof(NextStepNotify)}, notification: {JsonConvert.SerializeObject(notification)}");
         var workflow = notification.Workflow;
         var data = notification.Dto;
-        
-        //if(!string.IsNullOrEmpty(notification.Trace.Tag))
 
-        
+        DefinitionTag? tag = null;
+        if (!string.IsNullOrEmpty(notification.Trace.Tag))
+            tag = System.Text.Json.JsonSerializer.Deserialize<DefinitionTag>(notification.Trace.Tag);
+
+
         switch (workflow.ModuleCode)
         {
             case WorkflowModuleConsts.OrderHandle:
@@ -80,6 +82,19 @@ public class NextStepHandler : INotificationHandler<NextStepNotify>
                         WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace)
                     }, cancellationToken: cancellationToken);
 
+                if (tag is not null)
+                {
+                    if (tag.Type == TagDefaults.TagType.Org)
+                    {
+                        switch (tag.Value)
+                        {
+                            case TagDefaults.TagValue.Province:
+                                
+                                break;
+                        }
+                    }
+                }
+
                 break;
             case WorkflowModuleConsts.KnowledgeAdd:
             case WorkflowModuleConsts.KnowledgeUpdate:
@@ -90,11 +105,11 @@ public class NextStepHandler : INotificationHandler<NextStepNotify>
                 var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
                 if (screen != null)
                 {
-	                screen.Status = EScreenStatus.Approval;
+                    screen.Status = EScreenStatus.Approval;
                     await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
-				}
-				break;
+                }
+                break;
 
-		}
+        }
     }
 }

+ 18 - 0
src/Hotline/FlowEngine/Notifications/DefinitionTag.cs

@@ -8,7 +8,25 @@ namespace Hotline.FlowEngine.Notifications
 {
     public class DefinitionTag
     {
+        /// <summary>
+        /// tagType
+        /// </summary>
         public string Type { get; set; }
+
         public string Value { get; set; }
     }
+
+    public class TagDefaults
+    {
+        public class TagType
+        {
+            public const string Org = "org";
+        }
+
+        public class TagValue
+        {
+            public const string Province = "province";
+
+        }
+    }
 }

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

@@ -17,7 +17,7 @@ namespace Hotline.FlowEngine.Workflows
         /// <summary>
         /// 进行流程的开始节点
         /// </summary>
-        Task StartAsync(Workflow workflow, BasicWorkflowDto dto, StepDefine startStepDefine, 
+        Task StartAsync(Workflow workflow, BasicWorkflowDto dto, StepDefine startStepDefine,
             StepDefine firstStepDefine, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken);
 
         /// <summary>
@@ -29,7 +29,7 @@ namespace Hotline.FlowEngine.Workflows
         /// <summary>
         /// 查询工作流包含当前用户办理权限(是否可办理)
         /// </summary>
-        Task<(Workflow, bool)> GetWorkflowHandlePermissionAsync(string workflowId, 
+        Task<(Workflow, bool)> GetWorkflowHandlePermissionAsync(string workflowId,
             string userId, string orgCode, bool withDefine = false, bool withSteps = false, bool withTraces = false,
             bool withSupplements = false, bool withCountersigns = false, CancellationToken cancellationToken = default);
 
@@ -92,11 +92,6 @@ namespace Hotline.FlowEngine.Workflows
         Task<(Kv, IReadOnlyList<Kv>)> GetUnvisitOrgsAsync(string workflowId,
             CancellationToken cancellationToken);
 
-        /// <summary>
-        /// 更新一级部门信息
-        /// </summary>
-        Task UpdateOrgLevelOneAsync(Workflow workflow, string orgCode, string orgName, CancellationToken cancellationToken);
-
         /// <summary>
         /// 依据配置过滤下一节点
         /// </summary>

+ 15 - 6
src/Hotline/FlowEngine/Workflows/Workflow.cs

@@ -1,4 +1,5 @@
 using Hotline.FlowEngine.Definitions;
+using Hotline.Settings;
 using Hotline.Share.Dtos;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
@@ -402,10 +403,14 @@ public partial class Workflow
     public void UpdateWorkflowActualHandleInfo(WorkflowStep currentStep,
         string actualHandlerId, string? actualHandlerName,
         string actualHandleOrgCode, string? actualHandleOrgName,
-        string? actualHandleOrgAreaCode, string? actualHandleOrgAreaName)
+        string? actualHandleOrgAreaCode, string? actualHandleOrgAreaName,
+        int currentHandlerOrgLevel)
     {
-        //a.会签中分为1.之前无会签,当前节点发起会签,记录当前节点 2. 之前有会签,不更新  b.非会签中,记录当前节点
-        if (IsInCountersign() && !currentStep.HasStartedCountersign()) return;
+        /*
+          a.会签中:记录顶级会签发起节点, 会签结束前不更新。会签结束后再发起会签才会记录下一次会签的顶级发起节点
+          b.非会签中,记录当前节点
+        */
+        if (currentStep.IsInCountersign()) return;
 
         if (currentStep.StepType is EStepType.Summary or EStepType.End) return;
 
@@ -415,6 +420,10 @@ public partial class Workflow
             actualHandleOrgAreaCode, actualHandleOrgAreaName);
 
         SetHandleDuration();
+
+        //实际办理部门为一级部门时记录
+        if (currentHandlerOrgLevel == 1)
+            UpdateLevelOneOrg(actualHandleOrgCode, actualHandleOrgName);
     }
 
     /// <summary>
@@ -628,11 +637,11 @@ public partial class Workflow
     }
 
     /// <summary>
-    /// 更新一级部门信息
+    /// 更新一级部门信息(实际办理部门为一级部门时记录)
     /// </summary>
-    public void UpdateOrgLevelOne(string orgCode, string orgName)
+    public void UpdateLevelOneOrg(string orgId, string? orgName)
     {
-        OrgLevelOneCode = orgCode;
+        OrgLevelOneCode = orgId;
         OrgLevelOneName = orgName;
     }
 

+ 14 - 21
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -136,12 +136,6 @@ namespace Hotline.FlowEngine.Workflows
             //handle trace
             await NextTraceAsync(workflow, dto, startStep, cancellationToken);
 
-            //更新实际办理节点信息
-            workflow.UpdateWorkflowActualHandleInfo(startStep,
-                _sessionContext.RequiredUserId, _sessionContext.UserName,
-                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
-                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
-
             //todo 计算办理工作时长
 
             //更新当前办理节点信息
@@ -151,6 +145,13 @@ namespace Hotline.FlowEngine.Workflows
             if (dto.IsStartCountersign && !workflow.IsInCountersign())
                 workflow.StartCountersign(startStep.Id, counterSignType);
 
+            //更新实际办理节点信息
+            workflow.UpdateWorkflowActualHandleInfo(startStep,
+                _sessionContext.RequiredUserId, _sessionContext.UserName,
+                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
+                _sessionContext.OrgLevel);
+
             //更新受理人信息
             workflow.UpdateAcceptor(
                 _sessionContext.RequiredUserId,
@@ -376,6 +377,13 @@ namespace Hotline.FlowEngine.Workflows
                     workflow.EndCountersign();
             }
 
+            //更新实际办理节点信息
+            workflow.UpdateWorkflowActualHandleInfo(currentStep,
+                _sessionContext.RequiredUserId, _sessionContext.UserName,
+                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
+                _sessionContext.OrgLevel);
+
             //检查是否流转到流程终点
             if (nextStepDefine.StepType is EStepType.End)
             {
@@ -395,12 +403,6 @@ namespace Hotline.FlowEngine.Workflows
             workflow.UpdateHandlers(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId,
                 flowAssignInfo.FlowAssignType, flowAssignInfo.HandlerObjects);
 
-            //更新实际办理节点名称、时间
-            workflow.UpdateWorkflowActualHandleInfo(currentStep,
-                _sessionContext.RequiredUserId, _sessionContext.UserName,
-                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
-                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
-
             //todo 计算办理工作时长
 
             //更新当前办理节点信息
@@ -746,15 +748,6 @@ namespace Hotline.FlowEngine.Workflows
             return (new Kv(workflow.ActualHandleOrgCode, workflow.ActualHandleOrgName), items);
         }
 
-        /// <summary>
-        /// 更新一级部门信息
-        /// </summary>
-        public async Task UpdateOrgLevelOneAsync(Workflow workflow, string orgCode, string orgName, CancellationToken cancellationToken)
-        {
-            workflow.UpdateOrgLevelOne(orgCode, orgName);
-            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-        }
-
         /// <summary>
         /// 依据配置过滤下一节点
         /// </summary>

+ 3 - 0
src/Hotline/Settings/SystemDomainService.cs

@@ -144,6 +144,9 @@ public class SystemDomainService : ISystemDomainService, IScopeDependency
         }
         else
         {
+            if (dto.ParentId.IsCenter())
+                throw new UserFriendlyException("暂不支持中心创建下级部门");
+
             var parentOrg = await _organizeRepository.GetAsync(dto.ParentId, cancellationToken);
             if (parentOrg == null)
                 throw new UserFriendlyException("无效上级部门编码");