Bläddra i källkod

流程指派到角色处理方式调整为指派到用户

xf 2 år sedan
förälder
incheckning
935bfb78dd

+ 0 - 2
src/Hotline.Api/Controllers/OrderController.cs

@@ -58,8 +58,6 @@ public class OrderController : BaseController
     public async Task<PagedDto<OrderDto>> Query([FromQuery] QueryOrderDto dto)
     {
         var (total, items) = await _orderRepository.Queryable()
-            //.Includes(d => d.Employee)
-            //.Includes(d => d.Workflow, d => d.Assigns)
             .Where(d => d.Workflows.Any(x => x.ModuleCode == WorkflowModuleConsts.OrderManage))
             .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.Contains(dto.Keyword) || d.No.Contains(dto.Keyword))
             .WhereIF(!string.IsNullOrEmpty(dto.Content), d => d.Content.Contains(dto.Content))

+ 1 - 1
src/Hotline.Api/appsettings.Development.json

@@ -94,7 +94,7 @@
     }
   },
   "DatabaseConfiguration": {
-    "ApplyDbMigrations": true,
+    "ApplyDbMigrations": false,
     "ApplySeed": false
   }
 }

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

@@ -31,6 +31,6 @@ namespace Hotline.Application.FlowEngine
         /// <summary>
         /// 查询指派办理人的处理方式及实际办理人
         /// </summary>
-        Task<FlowAssignMode> GetFlowAssignModeAsync(StepDefine StepDefine, List<IdName> Handlers, CancellationToken cancellationToken);
+        Task<FlowAssignMode> GetFlowAssignModeAsync(StepDefine StepDefine, List<string> Handlers, CancellationToken cancellationToken);
     }
 }

+ 23 - 19
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -1,4 +1,5 @@
-using Hotline.FlowEngine.Definitions;
+using Hotline.FlowEngine;
+using Hotline.FlowEngine.Definitions;
 using Hotline.FlowEngine.Workflows;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
@@ -165,29 +166,32 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     }
 
     /// <summary>
-    /// 指派下一节点办理人
+    /// 查询指派办理人的处理方式及实际办理人
     /// </summary>
-    public async Task AssignAsync<TEntity>(TEntity entity, EFlowAssignType flowAssignType, IEnumerable<string> handlers, CancellationToken cancellationToken) 
-        where TEntity : IWorkflow
+    public async Task<FlowAssignMode> GetFlowAssignModeAsync(StepDefine stepDefine, List<string> handlers, CancellationToken cancellationToken)
     {
-        switch (flowAssignType)
+        switch (stepDefine.HandlerType)
         {
-            case EFlowAssignType.Org:
-            case EFlowAssignType.User:
-                entity.Assign(flowAssignType, handlers);
-                break;
-            case EFlowAssignType.Role:
-                var roles = await _roleRepository.Queryable()
-                    .Includes(d => d.Accounts)
-                    .Where(d => handlers.Contains(d.Name))
-                    .ToListAsync();
-                var userIds = roles.SelectMany(d => d.Accounts).Select(d => d.Id);
-                entity.Assign(EFlowAssignType.User, userIds);
-                break;
+            case EHandlerType.Role:
+                if (!handlers.Any())
+                {
+                    var roles = await _roleRepository.Queryable()
+                        .Includes(d => d.Accounts)
+                        .Where(d => stepDefine.HandlerClassifies.Select(d => d.Id).Contains(d.Name))
+                        .ToListAsync();
+                    handlers = roles.SelectMany(d => d.Accounts).Select(d => d.Id).ToList();
+                }
+
+                return new FlowAssignMode(EFlowAssignType.User, handlers);
+            case EHandlerType.OrgLevel:
+            case EHandlerType.OrgType:
+            case EHandlerType.AssignOrg:
+                return new FlowAssignMode(EFlowAssignType.Org, handlers);
+            case EHandlerType.AssignUser:
+                return new FlowAssignMode(EFlowAssignType.User, handlers);
             default:
-                throw new ArgumentOutOfRangeException(nameof(flowAssignType), flowAssignType, null);
+                throw new ArgumentOutOfRangeException();
         }
-
     }
 
 

+ 13 - 6
src/Hotline.Application/Handlers/FlowEngine/NextStepHandler.cs

@@ -1,4 +1,5 @@
-using Hotline.FlowEngine.Notifies;
+using Hotline.Application.FlowEngine;
+using Hotline.FlowEngine.Notifies;
 using Hotline.FlowEngine.Workflows;
 using Hotline.Orders;
 using Hotline.Settings;
@@ -12,10 +13,14 @@ namespace Hotline.Application.Handlers.FlowEngine;
 
 public class NextStepHandler : INotificationHandler<NextStepNotify>
 {
+    private readonly IWorkflowApplication _workflowApplication;
     private readonly IOrderDomainService _orderDomainService;
 
-    public NextStepHandler(IOrderDomainService orderDomainService)
+    public NextStepHandler(
+        IWorkflowApplication workflowApplication,
+        IOrderDomainService orderDomainService)
     {
+        _workflowApplication = workflowApplication;
         _orderDomainService = orderDomainService;
     }
 
@@ -26,13 +31,15 @@ public class NextStepHandler : INotificationHandler<NextStepNotify>
     {
         var workflow = notification.Workflow;
         var data = notification.Dto;
+        var assignMode = await _workflowApplication.GetFlowAssignModeAsync(notification.StepDefine,
+            data.Handlers.Select(d => d.Id).ToList(), cancellationToken);
+
         switch (workflow.ModuleCode)
         {
             case WorkflowModuleConsts.OrderManage:
-                await _orderDomainService.OrderManageAsync(EOrderStatus.WaitForSign, 
-                    notification.FlowAssignType, notification.IsCountersignEnd, notification.IsCountersignStart,
-                    workflow.ExternalId, workflow.CurrentStepTime, workflow.CurrentStepName, 
-                    data.Handlers.Select(d => d.Id), cancellationToken);
+                await _orderDomainService.OrderManageAsync(EOrderStatus.WaitForSign,
+                    assignMode, notification.IsCountersignEnd, notification.IsCountersignStart,
+                    workflow.ExternalId, workflow.CurrentStepTime, workflow.CurrentStepName, cancellationToken);
                 break;
         }
     }

+ 3 - 4
src/Hotline.Application/Handlers/FlowEngine/StartWorkflowHandler.cs

@@ -38,15 +38,14 @@ namespace Hotline.Application.Handlers.FlowEngine
             var workflow = notification.Workflow;
             var data = notification.Dto;
             var assignMode = await _workflowApplication.GetFlowAssignModeAsync(notification.StepDefine,
-                data.Handlers.ToList(), cancellationToken);
+                data.Handlers.Select(d => d.Id).ToList(), cancellationToken);
 
             switch (workflow.ModuleCode)
             {
                 case WorkflowModuleConsts.OrderManage:
-                    await _orderDomainService.OrderManageAsync(EOrderStatus.WaitForSign, notification.FlowAssignType,
+                    await _orderDomainService.OrderManageAsync(EOrderStatus.WaitForSign, assignMode,
                         false, notification.IsCountersignStart,
-                        workflow.ExternalId, workflow.CurrentStepTime, workflow.CurrentStepName,
-                        data.Handlers.Select(d => d.Id), cancellationToken);
+                        workflow.ExternalId, workflow.CurrentStepTime, workflow.CurrentStepName, cancellationToken);
                     break;
             }
         }

+ 1 - 6
src/Hotline.Application/Orders/IOrderApplication.cs

@@ -10,11 +10,6 @@ namespace Hotline.Application.Orders
 {
     public interface IOrderApplication
     {
-        /// <summary>
-        /// 工单办理(每个节点都会触发)
-        /// </summary>
-        Task OrderManageAsync(EOrderStatus status, EFlowAssignType assignType, bool isCountersignEnd, bool isCountersignStart,
-            string orderId, DateTime currentStepTime, string CurrentStepName,
-            IEnumerable<string> handlers, CancellationToken cancellationToken);
+       
     }
 }

+ 0 - 54
src/Hotline.Application/Orders/OrderApplication.cs

@@ -21,58 +21,4 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _workflowDomainService = workflowDomainService;
         _orderRepository = orderRepository;
     }
-
-    /// <summary>
-    /// 工单办理(每个节点都会触发)
-    /// </summary>
-    public async Task OrderManageAsync(EOrderStatus status, EFlowAssignType assignType, bool isCountersignEnd, bool isCountersignStart,
-        string orderId, DateTime currentStepTime, string CurrentStepName, IEnumerable<string> handlers,
-        CancellationToken cancellationToken)
-    {
-        var order = await _orderRepository.GetAsync(orderId, cancellationToken);
-        if (order == null)
-            throw new UserFriendlyException($"无效工单编号, orderId: {orderId}", "无效工单编号");
-        if (order.Status is EOrderStatus.Filed) return;
-
-        //order.Assign(assignType, handlers);
-        await AssignAsync(order, assignType, handlers, cancellationToken);
-
-        //1.如果order未处于会签中,则判断是否发起会签(isstartCountersign) 2.如果处于会签中,则判断会签是否结束(isCountersignEnd)
-        if (order.Status is EOrderStatus.Countersigning && isCountersignEnd)
-        {
-            order.Status = EOrderStatus.WaitForSign;
-        }
-        else if (order.Status is not EOrderStatus.Countersigning && isCountersignStart)
-        {
-            order.Status = EOrderStatus.Countersigning;
-        }
-
-        order.CurrentStepTime = currentStepTime;
-        order.CurrentStepName = CurrentStepName;
-        order.Status = status;
-
-        await _orderRepository.UpdateAsync(order, cancellationToken);
-    }
-
-    private async Task AssignAsync(Order order, EFlowAssignType assignType, IEnumerable<string> handlers, CancellationToken cancellationToken)
-    {
-        switch (assignType)
-        {
-            case EFlowAssignType.Org:
-                order.AssignOrgCodes.AddRange(handlers);
-                order.AssignOrgCodes = order.AssignOrgCodes.Distinct().ToList();
-                break;
-            case EFlowAssignType.User:
-                order.AssignUserIds.AddRange(handlers);
-                order.AssignUserIds = order.AssignUserIds.Distinct().ToList();
-                break;
-            case EFlowAssignType.Role:
-                var users =
-                    AssignRoles.AddRange(handlers);
-                AssignRoles = AssignRoles.Distinct().ToList();
-                break;
-            default:
-                throw new ArgumentOutOfRangeException(nameof(type), type, null);
-        }
-    }
 }

+ 21 - 17
src/Hotline.Repository.SqlSugar/DataPermissions/DataPermissionFilterBuilder.cs

@@ -44,39 +44,43 @@ public class DataPermissionFilterBuilder : IDataPermissionFilterBuilder, IScopeD
         var roles = _sessionContext.Roles;
         var orgCode = _sessionContext.RequiredOrgCode;
         var scheme = DataPermissionManager.GetQueryFilter<TEntity>(_sessionContext);
-        //var (_, orgCode, _, _) = DataPermissionManager.GetDataPermissionOptions();
 
         switch (scheme.QueryFilter)
         {
             case EAuthorityType.Create:
-                return d => d.CreatorId == userId || FlowDataFiltering(d, userId, orgCode, roles);
+                return d => d.CreatorId == userId
+                            || d.AssignUserIds.Contains(userId)
+                            || d.AssignOrgCodes.Contains(orgCode);
             case EAuthorityType.Org:
                 return d => d.CreatorOrgCode == scheme.OrgCode
                             || d.AssignUserIds.Contains(userId)
                             || d.AssignOrgCodes.Contains(orgCode)
-                            
+
                             //todo 扩展sqlfunc || d.AssignRoles.Intersect(roles).Any()
                             ;
             case EAuthorityType.OrgAndBelow:
-                return d => d.CreatorOrgCode.StartsWith(scheme.OrgCode) || FlowDataFiltering(d, userId, orgCode, roles);
+                return d => d.CreatorOrgCode.StartsWith(scheme.OrgCode)
+                            || d.AssignUserIds.Contains(userId)
+                            || d.AssignOrgCodes.Contains(orgCode);
             case EAuthorityType.All:
                 return d => true;
             default:
-                return d => FlowDataFiltering(d, userId, orgCode, roles);
+                return d => d.AssignUserIds.Contains(userId) || d.AssignOrgCodes.Contains(orgCode);
         }
     }
 
-    private static bool FlowDataFiltering<TEntity>(TEntity entity, string userId, string orgCode, string[] roles) where TEntity : class, IEntity<string>, IDataPermission, IWorkflow, new()
-    {
-        if (entity.AssignUserIds.Contains(userId)) return true;
-        foreach (var assignOrgCode in entity.AssignOrgCodes)
-        {
-            if (assignOrgCode == orgCode) return true;
-            var baseOrg = assignOrgCode.Substring(0, 3);
-            if (orgCode.StartsWith(baseOrg) && orgCode.Length < assignOrgCode.Length)
-                return true;
-        }
+    //private static bool FlowDataFiltering<TEntity>(TEntity entity, string userId, string orgCode, string[] roles) where TEntity : class, IEntity<string>, IDataPermission, IWorkflow, new()
+    //{
+    //    if (entity.AssignUserIds.Contains(userId)) return true;
+    //    foreach (var assignOrgCode in entity.AssignOrgCodes)
+    //    {
+    //        if (assignOrgCode == orgCode) return true;
+    //        var baseOrg = assignOrgCode.Substring(0, 3);
+    //        if (orgCode.StartsWith(baseOrg) && orgCode.Length < assignOrgCode.Length)
+    //            return true;
+    //    }
 
-        return entity.AssignRoles.Intersect(roles).Any();
-    }
+    //    return false;
+    //    //return entity.AssignRoles.Intersect(roles).Any();
+    //}
 }

+ 13 - 11
src/Hotline.Repository.SqlSugar/DataPermissions/DataPermissionManager.cs

@@ -28,17 +28,19 @@ public class DataPermissionManager : IDataPermissionManager, IScopeDependency
 
     public (string orgId, string orgCode, string creatorId, string? areaId) GetDataPermissionOptions()
     {
-        using var scope = _serviceScopeFactory.CreateScope();
-        var userRepository = scope.ServiceProvider.GetRequiredService<IUserRepository>();
-        var user = userRepository.GetAsync(_sessionContext.RequiredUserId).GetAwaiter().GetResult();
-        if (!string.IsNullOrEmpty(user!.OrgId))
-        {
-            var orgRepository = scope.ServiceProvider.GetRequiredService<ISystemOrganizeRepository>();
-            var org = orgRepository!.GetAsync(user!.OrgId).GetAwaiter().GetResult();
-
-            return (org!.Id, org.OrgCode, _sessionContext.RequiredUserId, org.OrgCode);
-        }
-        return ("", "", _sessionContext.RequiredUserId, "");
+        //using var scope = _serviceScopeFactory.CreateScope();
+        //var userRepository = scope.ServiceProvider.GetRequiredService<IUserRepository>();
+        //var user = userRepository.GetAsync(_sessionContext.RequiredUserId).GetAwaiter().GetResult();
+        //if (!string.IsNullOrEmpty(user!.OrgId))
+        //{
+        //    var orgRepository = scope.ServiceProvider.GetRequiredService<ISystemOrganizeRepository>();
+        //    var org = orgRepository!.GetAsync(user!.OrgId).GetAwaiter().GetResult();
+
+        //    return (org!.Id, org.OrgCode, _sessionContext.RequiredUserId, org.OrgCode);
+        //}
+        //return ("", "", _sessionContext.RequiredUserId, "");
+        return (_sessionContext.RequiredOrgId, _sessionContext.RequiredOrgCode, 
+            _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
     }
 
     private EAuthorityType GetCurrentQueryFilter(string[] roles, string entityName)

+ 0 - 17
src/Hotline/FlowEngine/Definitions/StepDefine.cs

@@ -22,21 +22,4 @@ public class StepDefine : StepBasic
         if (HandlerType is EHandlerType.Role) return false;
         return handlerCount > 1;
     }
-
-    public (EFlowAssignType assignType, List<IdName> handlers) GetFlowAssignMode(List<IdName> handlers)
-    {
-        switch (HandlerType)
-        {
-            case EHandlerType.Role:
-                return handlers.Any() ? (EFlowAssignType.User, handlers) : (EFlowAssignType.Role, HandlerClassifies);
-            case EHandlerType.OrgLevel:
-            case EHandlerType.OrgType:
-            case EHandlerType.AssignOrg:
-                return (EFlowAssignType.Org, handlers);
-            case EHandlerType.AssignUser:
-                return (EFlowAssignType.User, handlers);
-            default:
-                throw new ArgumentOutOfRangeException();
-        }
-    }
 }

+ 6 - 0
src/Hotline/FlowEngine/FlowAssignMode.cs

@@ -4,6 +4,12 @@ namespace Hotline.FlowEngine;
 
 public class FlowAssignMode
 {
+    public FlowAssignMode(EFlowAssignType flowAssignType, List<string> handlers)
+    {
+        FlowAssignType = flowAssignType;
+        Handlers = handlers;
+    }
+
     /// <summary>
     /// 流程指派类型
     /// </summary>

+ 1 - 1
src/Hotline/FlowEngine/Notifies/WorkflowNotify.cs

@@ -10,7 +10,7 @@ public record WorkflowNotify(Workflow Workflow, StepDefine StepDefine, BasicWork
 
 public record StartWorkflowNotify(Workflow Workflow, StepDefine StepDefine, BasicWorkflowDto Dto, bool IsCountersignStart) : WorkflowNotify(Workflow, StepDefine, Dto);
 
-public record NextStepNotify(Workflow Workflow, EFlowAssignType FlowAssignType, List<IdName> Handlers, BasicWorkflowDto Dto, bool IsCountersignStart, bool IsCountersignEnd) : WorkflowNotify(Workflow, FlowAssignType, Handlers);
+public record NextStepNotify(Workflow Workflow, StepDefine StepDefine, BasicWorkflowDto Dto, bool IsCountersignStart, bool IsCountersignEnd) : WorkflowNotify(Workflow, StepDefine, Dto);
 
 public record AcceptWorkflowNotify(Workflow Workflow) : INotification;
 

+ 1 - 4
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -96,7 +96,6 @@ namespace Hotline.FlowEngine.Workflows
             await CreateStepAsync(workflow, nextStepBoxDefine, dto, cancellationToken: cancellationToken);
 
             //publish
-            var assignMode = nextStepBoxDefine.GetFlowAssignMode(dto.Handlers);
             _mediator.Publish(new StartWorkflowNotify(workflow, nextStepBoxDefine, dto, isStartCountersign), cancellationToken);
         }
 
@@ -302,9 +301,7 @@ namespace Hotline.FlowEngine.Workflows
 
             #endregion
 
-            var assignMode = nextStepBoxDefine.GetFlowAssignMode(dto.Handlers);
-            _mediator.Publish(new NextStepNotify(workflow, assignMode.assignType, assignMode.handlers, dto,
-                isStartCountersign, isCountersignOver));
+            _mediator.Publish(new NextStepNotify(workflow, nextStepBoxDefine, dto, isStartCountersign, isCountersignOver));
         }
 
         /// <summary>

+ 6 - 4
src/Hotline/Orders/OrderDomainService.cs

@@ -1,4 +1,5 @@
-using Hotline.Share.Enums.Order;
+using Hotline.FlowEngine;
+using Hotline.Share.Enums.Order;
 using XF.Domain.Authentications;
 using XF.Domain.Cache;
 using XF.Domain.Dependency;
@@ -52,10 +53,9 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
     /// <summary>
     /// 工单办理(每个节点都会触发)
     /// </summary>
-    public async Task OrderManageAsync(EOrderStatus status, EFlowAssignType assignType,
+    public async Task OrderManageAsync(EOrderStatus status, FlowAssignMode assignMode,
         bool isCountersignEnd, bool isCountersignStart,
         string orderId, DateTime currentStepTime, string CurrentStepName,
-        IEnumerable<string> handlers,
         CancellationToken cancellationToken)
     {
         var order = await _orderRepository.GetAsync(orderId, cancellationToken);
@@ -63,7 +63,9 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
             throw new UserFriendlyException($"无效工单编号, orderId: {orderId}", "无效工单编号");
         if (order.Status is EOrderStatus.Filed) return;
 
-        order.Assign(assignType, handlers);
+        //更新指派信息
+        order.Assign(assignMode.FlowAssignType, assignMode.Handlers);
+
         //1.如果order未处于会签中,则判断是否发起会签(isstartCountersign) 2.如果处于会签中,则判断会签是否结束(isCountersignEnd)
         if (order.Status is EOrderStatus.Countersigning && isCountersignEnd)
         {

+ 0 - 20
src/XF.Domain.Repository/Entity.cs

@@ -162,11 +162,6 @@ public abstract class WorkflowEntity : FullStateEntity, IWorkflow
                 if (!AssignUserIds.Exists(d => d == handler))
                     AssignUserIds.Add(handler);
                 break;
-            case EFlowAssignType.Role:
-                //if (!AssignRoles.Exists(d => d == handler))
-                //    AssignRoles.Add(handler);
-                throw new NotImplementedException();
-                break;
             default:
                 throw new ArgumentOutOfRangeException(nameof(type), type, null);
         }
@@ -185,11 +180,6 @@ public abstract class WorkflowEntity : FullStateEntity, IWorkflow
                 AssignUserIds.AddRange(handlers);
                 AssignUserIds = AssignUserIds.Distinct().ToList();
                 break;
-            case EFlowAssignType.Role:
-                //AssignRoles.AddRange(handlers);
-                //AssignRoles = AssignRoles.Distinct().ToList();
-                throw new NotImplementedException();
-                break;
             default:
                 throw new ArgumentOutOfRangeException(nameof(type), type, null);
         }
@@ -259,11 +249,6 @@ public abstract class PositionWorkflowEntity : PositionEntity, IWorkflow
                 if (!AssignUserIds.Exists(d => d == handler))
                     AssignUserIds.Add(handler);
                 break;
-            case EFlowAssignType.Role:
-                //if (!AssignRoles.Exists(d => d == handler))
-                //    AssignRoles.Add(handler);
-                throw new NotImplementedException();
-                break;
             default:
                 throw new ArgumentOutOfRangeException(nameof(type), type, null);
         }
@@ -282,11 +267,6 @@ public abstract class PositionWorkflowEntity : PositionEntity, IWorkflow
                 AssignUserIds.AddRange(handlers);
                 AssignUserIds = AssignUserIds.Distinct().ToList();
                 break;
-            case EFlowAssignType.Role:
-                //AssignRoles.AddRange(handlers);
-                //AssignRoles = AssignRoles.Distinct().ToList();
-                throw new NotImplementedException();
-                break;
             default:
                 throw new ArgumentOutOfRangeException(nameof(type), type, null);
         }