Procházet zdrojové kódy

perf: 优化平均派单

xf před 10 měsíci
rodič
revize
14b505ba88

+ 2 - 2
src/Hotline.Api/config/appsettings.Development.json

@@ -16,7 +16,7 @@
     }
   },
   "ConnectionStrings": {
-    "Hotline": "PORT=5432;DATABASE=hotline_dev;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;",
+    "Hotline": "PORT=5432;DATABASE=hotline;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;",
     "Redis": "110.188.24.182:50179",
     "MongoDB": "mongodb://192.168.100.121:27017",
     "Wex": "server=222.212.82.225;Port=4509;Database=fs_kft;Uid=root;Pwd=Wex@12345;"
@@ -25,7 +25,7 @@
     "Host": "110.188.24.182",
     "Port": 50179,
     //"Password": "fengwo22@@",
-    "Database": 5
+    "Database": 3
   },
   "Swagger": true,
   "Cors": {

+ 2 - 2
src/Hotline.Api/config/appsettings.json

@@ -16,7 +16,7 @@
     }
   },
   "ConnectionStrings": {
-    "Hotline": "PORT=5432;DATABASE=hotline_dev;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;",
+    "Hotline": "PORT=5432;DATABASE=hotline;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;",
     "Redis": "110.188.24.182:50179,password=fengwo22@@",
     "MongoDB": "mongodb://192.168.100.121:27017",
     "Wex": "server=222.212.82.225;Port=4509;Database=fs_kft;Uid=root;Pwd=Wex@12345;"
@@ -25,7 +25,7 @@
     "Host": "110.188.24.182",
     "Port": 50179,
     "Password": "fengwo22@@",
-    "Database": 5
+    "Database": 3
   },
   "Swagger": true,
   "Cors": {

+ 8 - 3
src/Hotline.Application/Identity/IdentityAppService.cs

@@ -141,11 +141,16 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
         try
         {
             DateTime time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
-
+            
             //&& x.AtWork!.Value != true
             //根据当前时间获取排班信息
-            var scheduling = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
-                .Where(x => x.SchedulingTime == time && x.WorkingTime <= DateTime.Now.TimeOfDay && x.OffDutyTime >= DateTime.Now.TimeOfDay && (x.AtWork == true || x.AtWork == null) && x.SchedulingUser.UserId == id)
+            var scheduling = await _schedulingRepository.Queryable()
+                .Includes(x => x.SchedulingUser)
+                .Where(x => x.SchedulingTime == time &&
+                            x.WorkingTime <= DateTime.Now.TimeOfDay && 
+                            x.OffDutyTime >= DateTime.Now.TimeOfDay && 
+                            (x.AtWork == true || x.AtWork == null) && 
+                            x.SchedulingUser.UserId == id)
                 .OrderBy(x => x.SendOrderNum).FirstAsync(cancellationToken);
             if (scheduling != null)
             {

+ 12 - 0
src/Hotline/FlowEngine/Workflows/IWorkflowDomainService.cs

@@ -214,6 +214,11 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         Task<IReadOnlyList<string>> GetUnhandleStepIdsFromSendPoolAsync(string sendPoolId, CancellationToken cancellationToken);
 
+        /// <summary>
+        /// 查询归属某用户的所有流程节点
+        /// </summary>
+        Task<List<WorkflowStep>> GetStepsBelongsToAsync(string userId, CancellationToken cancellationToken);
+
         /// <summary>
         /// 批量改派工单至指定用户
         /// </summary>
@@ -221,6 +226,13 @@ namespace Hotline.FlowEngine.Workflows
             IReadOnlyList<(string userId, string username, string orgId, string orgName, IReadOnlyList<string> stepIds)> handlers,
             CancellationToken cancellationToken);
 
+        /// <summary>
+        /// 批量修改工单办理对象
+        /// </summary>
+        Task ChangeHandlerBatchAsync(
+            IReadOnlyList<(string userId, string username, string orgId, string orgName, ICollection<WorkflowStep> steps)> handlers,
+            CancellationToken cancellationToken);
+
         /// <summary>
         /// 查询工单办理中的一级部门
         /// </summary>

+ 32 - 0
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -647,6 +647,17 @@ namespace Hotline.FlowEngine.Workflows
                 .ToListAsync(cancellationToken);
         }
 
+        /// <summary>
+        /// 查询归属某用户的所有流程节点
+        /// </summary>
+        public async Task<List<WorkflowStep>> GetStepsBelongsToAsync(string userId, CancellationToken cancellationToken)
+        {
+            return await _workflowStepRepository.Queryable()
+                .Where(d => d.HandlerId == userId)
+                .OrderBy(d=>d.CreationTime)
+                .ToListAsync(cancellationToken);
+        }
+
         /// <summary>
         /// 批量改变办理对象
         /// </summary>
@@ -705,6 +716,27 @@ namespace Hotline.FlowEngine.Workflows
             return steps.Select(d => d.WorkflowId).ToList();
         }
 
+        /// <summary>
+        /// 批量修改工单办理对象
+        /// </summary>
+        public async Task ChangeHandlerBatchAsync(
+            IReadOnlyList<(string userId, string username, string orgId, string orgName, ICollection<WorkflowStep> steps)> handlers,
+            CancellationToken cancellationToken)
+        {
+            foreach (var handler in handlers)
+            {
+                foreach (var step in handler.steps)
+                {
+                    step.FlowAssignType = EFlowAssignType.User;
+                    step.Assign(handler.userId, handler.username, 
+                        handler.orgId, handler.orgName);
+                }
+            }
+
+            await _workflowStepRepository.UpdateRangeAsync(handlers.SelectMany(d => d.steps).ToList(),
+                cancellationToken);
+        }
+
         /// <summary>
         /// 查询工单办理中的一级部门
         /// </summary>

+ 96 - 57
src/Hotline/Orders/OrderDomainService.cs

@@ -227,40 +227,53 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         //1.获取默认派单员所属的工单
         //2.获取今天上班的人员
         //3.给当前这个用户平均派单
-        var steps = await _workflowDomainService.GetUnhandleStepIdsFromSendPoolAsync(OrderDefaults.SourceChannel.SendPoolId, cancellationToken);
-        var stepsList = steps.ToList();
+        //var steps = await _workflowDomainService.GetUnhandleStepIdsFromSendPoolAsync(OrderDefaults.SourceChannel.SendPoolId, cancellationToken);
+        //var stepsList = steps.ToList();
+
+        var steps = await _workflowDomainService.GetStepsBelongsToAsync(OrderDefaults.SourceChannel.SendPoolId,
+            cancellationToken);
 
         var user = await _userRepository.Queryable()
             .Includes(d => d.Organization)
             .FirstAsync(d => d.Id == userId, cancellationToken);
-        DateTime time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
+        var time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
         var schedulings = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
             .Where(x => x.SchedulingTime == time && x.WorkingTime <= DateTime.Now.TimeOfDay && x.OffDutyTime >= DateTime.Now.TimeOfDay).CountAsync(cancellationToken);
 
         if (schedulings > 0)
         {
-            List<string> stepIds = new List<string>();
-            var sendNum = stepsList.Count() / schedulings;
-            for (int i = 0; i < sendNum; i++)
+            var sendNum = steps.Count / schedulings;
+            if (sendNum <= 0) return;
+            var sendSteps = steps.Take(sendNum).ToList();
+            await _workflowDomainService.ChangeHandlerBatchAsync(new List<(string userId, string username, string orgId, string orgName, ICollection<WorkflowStep> steps)>
             {
-                stepIds.Add(stepsList[0]);
-                stepsList.Remove(stepsList[0]);
-            }
-            List<(string, string, string, string, IReadOnlyList<string> stepIds)> handlers = new();
-            ; handlers.Add(new ValueTuple<string, string, string, string, IReadOnlyList<string>>(user.Id, user.Name, user.OrgId, user.Organization.Name, stepIds));
-            var workflowIds = await _workflowDomainService.ChangeHandlerRangeAsync(OrderDefaults.SourceChannel.SendPoolId, handlers, cancellationToken);
-            var orders = await _orderRepository.Queryable().Includes(d => d.Workflow).Where(d => workflowIds.Contains(d.WorkflowId))
-                .ToListAsync(cancellationToken);
-            foreach (var order in orders)
-            {
-                _mapper.Map(order.Workflow, order);
-            }
+                new(user.Id, user.Name, user.OrgId, user.Organization.Name, sendSteps)
+            }, cancellationToken);
+
+
+            //List<string> stepIds = new List<string>();
+            //var sendNum = stepsList.Count() / schedulings;
+            //for (int i = 0; i < sendNum; i++)
+            //{
+            //    stepIds.Add(stepsList[0]);
+            //    stepsList.Remove(stepsList[0]);
+            //}
+            //List<(string, string, string, string, IReadOnlyList<string> stepIds)> handlers = new();
+            //handlers.Add(new ValueTuple<string, string, string, string, IReadOnlyList<string>>(user.Id, user.Name, user.OrgId, user.Organization.Name, stepIds));
+            //var workflowIds = await _workflowDomainService.ChangeHandlerRangeAsync(OrderDefaults.SourceChannel.SendPoolId, handlers, cancellationToken);
+            //var orders = await _orderRepository.Queryable().Includes(d => d.Workflow).Where(d => workflowIds.Contains(d.WorkflowId))
+            //    .ToListAsync(cancellationToken);
+            //foreach (var order in orders)
+            //{
+            //    _mapper.Map(order.Workflow, order);
+            //}
             var scheduling = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
                 .Where(x => x.SchedulingTime == time && x.WorkingTime <= DateTime.Now.TimeOfDay && x.OffDutyTime >= DateTime.Now.TimeOfDay && x.SchedulingUser.UserId == userId).FirstAsync(cancellationToken);
             scheduling.SendOrderNum += sendNum;
             await _schedulingRepository.UpdateAsync(scheduling, cancellationToken);
-            await _orderRepository.UpdateRangeAsync(orders, cancellationToken);
+            //await _orderRepository.UpdateRangeAsync(orders, cancellationToken);
         }
+
     }
 
     /// <summary>
@@ -279,49 +292,75 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
 
         if (schedulings.Any())
         {
-            var steps = await _workflowDomainService.GetUnhandleStepIdsFromSendPoolAsync(OrderDefaults.SourceChannel.SendPoolId, cancellationToken);
-            var stepsList = steps.ToList();
-
-            var sendNum = steps.Count() / schedulings.Count();
-            List<(string userId, string username, string orgId, string orgName, IReadOnlyList<string> stepIds)> handlers = new();
-            if (sendNum > 0)
+            var steps = await _workflowDomainService.GetStepsBelongsToAsync(OrderDefaults.SourceChannel.SendPoolId,
+                cancellationToken);
+            if (steps.Any())
             {
-
-                foreach (var scheduling in schedulings)
+                List<(string userId, string username, string orgId, string orgName, ICollection<WorkflowStep> steps)> handlers = new();
+                var avg = steps.Count / schedulings.Count;
+                var remaining = steps.Count % schedulings.Count;
+                for (var i = 0; i < schedulings.Count; i++)
                 {
-                    List<string> stepIds = new List<string>();
-                    for (int i = 0; i < sendNum; i++)
-                    {
-                        stepIds.Add(stepsList[0]);
-                        stepsList.Remove(stepsList[0]);
-                    }
-                    handlers.Add(new ValueTuple<string, string, string, string, IReadOnlyList<string>>(scheduling.SchedulingUser.UserId, scheduling.SchedulingUser.UserName, scheduling.SchedulingUser.OrgId, scheduling.SchedulingUser.OrgIdName, stepIds));
-
-                }
-            }
-            sendNum = steps.Count() % schedulings.Count();
-            if (sendNum > 0)
-            {
-                List<string> stepIds = new List<string>();
-                for (int i = 0; i < sendNum; i++)
-                {
-                    stepIds.Add(stepsList[0]);
-                    stepsList.Remove(stepsList[0]);
-                }
-                handlers.Add(new ValueTuple<string, string, string, string, IReadOnlyList<string>>(schedulings[0].SchedulingUser.UserId, schedulings[0].SchedulingUser.UserName, schedulings[0].SchedulingUser.OrgId, schedulings[0].SchedulingUser.OrgIdName, stepIds));
-            }
-            if (handlers.Any())
-            {
-                var workflowIds = await _workflowDomainService.ChangeHandlerRangeAsync(OrderDefaults.SourceChannel.SendPoolId, handlers, cancellationToken);
-                var orders = await _orderRepository.Queryable().Includes(d => d.Workflow).Where(d => workflowIds.Contains(d.WorkflowId))
-                    .ToListAsync(cancellationToken);
-                foreach (var order in orders)
-                {
-                    _mapper.Map(order.Workflow, order);
+                    var scheduling = schedulings[i];
+                    var size = avg + (i < remaining ? 1 : 0);
+                    handlers.Add(new(
+                        scheduling.SchedulingUser.UserId,
+                        scheduling.SchedulingUser.UserName,
+                        scheduling.SchedulingUser.OrgId,
+                        scheduling.SchedulingUser.OrgIdName,
+                        steps.Take(size).ToList()));
                 }
 
-                await _orderRepository.UpdateRangeAsync(orders, cancellationToken);
+                if (handlers.Any())
+                    await _workflowDomainService.ChangeHandlerBatchAsync(handlers, cancellationToken);
             }
+
+
+
+            ////
+            //var steps = await _workflowDomainService.GetUnhandleStepIdsFromSendPoolAsync(OrderDefaults.SourceChannel.SendPoolId, cancellationToken);
+            //var stepsList = steps.ToList();
+
+            //var sendNum = steps.Count() / schedulings.Count();
+            //List<(string userId, string username, string orgId, string orgName, IReadOnlyList<string> stepIds)> handlers = new();
+            //if (sendNum > 0)
+            //{
+
+            //    foreach (var scheduling in schedulings)
+            //    {
+            //        List<string> stepIds = new List<string>();
+            //        for (int i = 0; i < sendNum; i++)
+            //        {
+            //            stepIds.Add(stepsList[0]);
+            //            stepsList.Remove(stepsList[0]);
+            //        }
+            //        handlers.Add(new ValueTuple<string, string, string, string, IReadOnlyList<string>>(scheduling.SchedulingUser.UserId, scheduling.SchedulingUser.UserName, scheduling.SchedulingUser.OrgId, scheduling.SchedulingUser.OrgIdName, stepIds));
+
+            //    }
+            //}
+            //sendNum = steps.Count() % schedulings.Count();
+            //if (sendNum > 0)
+            //{
+            //    List<string> stepIds = new List<string>();
+            //    for (int i = 0; i < sendNum; i++)
+            //    {
+            //        stepIds.Add(stepsList[0]);
+            //        stepsList.Remove(stepsList[0]);
+            //    }
+            //    handlers.Add(new ValueTuple<string, string, string, string, IReadOnlyList<string>>(schedulings[0].SchedulingUser.UserId, schedulings[0].SchedulingUser.UserName, schedulings[0].SchedulingUser.OrgId, schedulings[0].SchedulingUser.OrgIdName, stepIds));
+            //}
+            //if (handlers.Any())
+            //{
+            //    var workflowIds = await _workflowDomainService.ChangeHandlerRangeAsync(OrderDefaults.SourceChannel.SendPoolId, handlers, cancellationToken);
+            //    var orders = await _orderRepository.Queryable().Includes(d => d.Workflow).Where(d => workflowIds.Contains(d.WorkflowId))
+            //        .ToListAsync(cancellationToken);
+            //    foreach (var order in orders)
+            //    {
+            //        _mapper.Map(order.Workflow, order);
+            //    }
+
+            //    await _orderRepository.UpdateRangeAsync(orders, cancellationToken);
+            //}
         }
     }
     #endregion