Explorar o código

Merge branch 'test' of http://110.188.24.182:10023/Fengwo/hotline into test

tangjiang hai 2 semanas
pai
achega
e35e25c9f5

+ 192 - 180
src/Hotline.Api/Controllers/OrderController.cs

@@ -72,8 +72,10 @@ using MiniExcelLibs;
 using SqlSugar;
 using System.Text;
 using System.Text.Json;
+using System.Threading;
 using XF.Domain.Authentications;
 using XF.Domain.Cache;
+using XF.Domain.Entities;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
 using XF.Utility.EnumExtensions;
@@ -2349,142 +2351,41 @@ public class OrderController : BaseController
     /// <summary>
     /// 批量审批延期
     /// </summary>
-
-    //public async Task<string> BatchAuditDelay([FromBody] BatchDelayNextFlowDto dto)
-    //{
-    //    var result = new StringBuilder();
-    //    var fail = 0;
-    //    var success = 0;
-    //    var workflow = dto.NextWorkflow;
-    //    foreach (var item in dto.DelayId)
-    //    {
-    //        try
-    //        {
-    //            if (workflow.NextHandlers.Any() && workflow.NextHandlers.Count() == 1)
-    //            {
-    //                var handler = workflow.NextHandlers.FirstOrDefault();
-    //                if (string.IsNullOrEmpty(handler.UserId))
-    //                {
-    //                    workflow.NextHandlers = new List<StepAssignInfo>();
-    //                }
-    //            }
-
-    //            var delay = await _orderDelayRepository.Queryable().Includes(x => x.Order).Where(x => x.Id == item)
-    //                .FirstAsync(HttpContext.RequestAborted);
-    //            workflow.WorkflowId = delay.WorkflowId;
-    //            var workflowEntuty = await _workflowDomainService.GetWorkflowAsync(workflow.WorkflowId, withDefine: true, withSteps: true,
-    //                cancellationToken: HttpContext.RequestAborted);
-    //            var currentStep = workflowEntuty.Steps.FirstOrDefault(d =>
-    //                d.Status == EWorkflowStepStatus.WaitForAccept || d.Status == EWorkflowStepStatus.WaitForHandle);
-
-    //            NextStepsWithOpinionDto<NextStepOption> next = null;
-
-    //            try
-    //            {
-    //                next = await _workflowApplication.GetNextStepsAsync(delay.WorkflowId, HttpContext.RequestAborted);
-    //            }
-    //            catch (UserFriendlyException e)
-    //            {
-    //                if (e.Message.Contains("未找到对应节点"))
-    //                {
-    //                    result.Append("无权审核:" + delay.No);
-    //                    fail++;
-    //                }
-    //                else
-    //                {
-    //                    throw;
-    //                }
-    //            }
-
-    //            if (next == null) continue;
-
-    //            if (!delay.Order.IsProvince)
-    //            {
-    //                if (next.Steps.Any(x => x.Value == "省审批"))
-    //                {
-    //                    next.Steps.Remove(next.Steps.First(x => x.Value == "省审批"));
-    //                }
-    //            }
-
-    //            if (!_sessionContext.OrgIsCenter && currentStep.Name != "中心初审")
-    //            {
-    //                if (next.Steps.Any(x => x.Value == "中心终审"))
-    //                {
-    //                    next.Steps.Remove(next.Steps.First(x => x.Value == "中心终审"));
-    //                }
-    //            }
-
-    //            workflow.StepId = next.StepId;
-    //            workflow.ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed;
-
-    //            if (workflow.ReviewResult == EReviewResult.Approval)
-    //            {
-    //                var isBatch = next.Steps.Where(x => x.Value == workflow.NextStepName).Any();
-    //                if (isBatch)
-    //                {
-    //                    var step = next.Steps.Where(x => x.Value == workflow.NextStepName).FirstOrDefault();
-    //                    workflow.NextStepCode = step.Key;
-    //                    workflow.NextStepName = step.Value;
-    //                }
-    //                else
-    //                {
-    //                    result.Append("无权审核:" + delay.No);
-    //                    fail++;
-    //                    continue;
-    //                }
-
-    //                await _workflowDomainService.NextAsync(workflow, cancellationToken: HttpContext.RequestAborted);
-    //            }
-    //            else
-    //            {
-    //                var reject = workflow.Adapt<RejectDto>();
-    //                await _workflowApplication.RejectAsync(reject, HttpContext.RequestAborted);
-    //            }
-
-    //            success++;
-    //        }
-    //        catch (UserFriendlyException e)
-    //        {
-    //            result.Append(e.Message);
-    //            fail++;
-    //        }
-    //    }
-
-    //    return $"总共: {dto.DelayId.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result.ToString()}";
-    //}
-
     [HttpPost("delay/batch_audit")]
     [LogFilter("批量审批延期")]
-    [LogFilterAlpha("延期审核")]
+    //[LogFilterAlpha("延期审核")]
     public async Task<string> BatchAuditDelay([FromBody] BatchDelayNextFlowDto dto)
     {
         var result = new StringBuilder();
         var fail = 0;
         var success = 0;
-        var workflowDto = dto.NextWorkflow;
-        var delays = await _orderDelayRepository.Queryable()
-            .Includes(x => x.Order)
-            .Includes(x => x.Workflow, d => d.WorkflowDefinition)
-            .Includes(x => x.Workflow, d => d.Steps)
-            .Includes(x => x.Workflow, d => d.Traces)
-            .Includes(x => x.Workflow, d => d.Countersigns)
-            .Where(x => dto.DelayId.Contains(x.Id))
-            .ToListAsync(HttpContext.RequestAborted);
-
-        var updateDelays = new List<OrderDelay>();
-        var updateOrders = new List<Order>();
-        foreach (var delay in delays)
+        var workflow = dto.NextWorkflow;
+        foreach (var item in dto.DelayId)
         {
             try
             {
-                var currentStep = delay.Workflow.Steps.FirstOrDefault(d =>
+                if (workflow.NextHandlers.Any() && workflow.NextHandlers.Count() == 1)
+                {
+                    var handler = workflow.NextHandlers.FirstOrDefault();
+                    if (string.IsNullOrEmpty(handler.UserId))
+                    {
+                        workflow.NextHandlers = new List<StepAssignInfo>();
+                    }
+                }
+
+                var delay = await _orderDelayRepository.Queryable().Includes(x => x.Order).Where(x => x.Id == item)
+                    .FirstAsync(HttpContext.RequestAborted);
+                workflow.WorkflowId = delay.WorkflowId;
+                var workflowEntuty = await _workflowDomainService.GetWorkflowAsync(workflow.WorkflowId, withDefine: true, withSteps: true,
+                    cancellationToken: HttpContext.RequestAborted);
+                var currentStep = workflowEntuty.Steps.FirstOrDefault(d =>
                     d.Status == EWorkflowStepStatus.WaitForAccept || d.Status == EWorkflowStepStatus.WaitForHandle);
 
                 NextStepsWithOpinionDto<NextStepOption> next = null;
 
                 try
                 {
-                    next = await _workflowApplication.GetNextStepsAsync(delay.Workflow, HttpContext.RequestAborted);
+                    next = await _workflowApplication.GetNextStepsAsync(delay.WorkflowId, HttpContext.RequestAborted);
                 }
                 catch (UserFriendlyException e)
                 {
@@ -2517,81 +2418,33 @@ public class OrderController : BaseController
                     }
                 }
 
-                workflowDto.StepId = next.StepId;
-                workflowDto.ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed;
+                workflow.StepId = next.StepId;
+                workflow.ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed;
 
-                if (dto.IsPass)
+                if (workflow.ReviewResult == EReviewResult.Approval)
                 {
-                    //处理工单延期
-                    var order = delay.Order;
-                    var expiredTimeBase = DateTime.Now;
-                    if (_appOptions.Value.IsZiGong)
+                    var isBatch = next.Steps.Where(x => x.Value == workflow.NextStepName).Any();
+                    if (isBatch)
                     {
-                        expiredTimeBase = order.ExpiredTime.Value;
+                        var step = next.Steps.Where(x => x.Value == workflow.NextStepName).FirstOrDefault();
+                        workflow.NextStepCode = step.Key;
+                        workflow.NextStepName = step.Value;
                     }
-
-                    var startTime = DateTime.Now;
-                    if (order.CenterToOrgTime.HasValue)
-                    {
-                        startTime = order.CenterToOrgTime!.Value;
-                    }
-
-                    var expiredTimeConfig =
-                        await _expireTime.CalcEndTime(expiredTimeBase, startTime, new TimeConfig(delay.DelayNum, delay.DelayUnit),
-                            order.AcceptTypeCode);
-                    order.ExpiredTime = expiredTimeConfig.ExpiredTime;
-                    order.NearlyExpiredTime = expiredTimeConfig.NearlyExpiredTime;
-                    order.NearlyExpiredTimeOne = expiredTimeConfig.NearlyExpiredTimeOne;
-                    //TODO发送短信即将超期
-                    if (delay.IsProDelay)
-                    {
-                        order.ExpiredTimeProvince = expiredTimeConfig.ExpiredTime;
-                    }
-
-                    updateOrders.Add(order);
-
-                    var step = next.Steps.FirstOrDefault(x => x.Value == workflowDto.NextStepName);
-                    if (step is null)
+                    else
                     {
                         result.Append("无权审核:" + delay.No);
                         fail++;
                         continue;
                     }
 
-                    workflowDto.NextStepCode = step.Key;
-                    workflowDto.NextStepName = step.Value;
-
-                    await _workflowDomainService.NextAsync(delay.Workflow, workflowDto,
-                        expiredTime: order.ExpiredTime,
-                        cancellationToken: HttpContext.RequestAborted);
-
-                    var orderDto = _mapper.Map<OrderDto>(order);
-                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
-                        cancellationToken: HttpContext.RequestAborted);
+                    await _workflowDomainService.NextAsync(workflow, cancellationToken: HttpContext.RequestAborted);
                 }
                 else
                 {
-                    var reject = workflowDto.Adapt<RejectDto>();
+                    var reject = workflow.Adapt<RejectDto>();
                     await _workflowApplication.RejectAsync(reject, HttpContext.RequestAborted);
                 }
 
-
-                delay.DelayState = dto.IsPass ? EDelayState.Pass : EDelayState.NoPass;
-                updateDelays.Add(delay);
-
-                await _orderDelayRepository.Updateable(updateDelays)
-                    .UpdateColumns(d => d.DelayState)
-                    .ExecuteCommandAsync(HttpContext.RequestAborted);
-
-                await _orderRepository.Updateable(updateOrders)
-                    .UpdateColumns(d => new
-                    {
-                        d.ExpiredTime,
-                        d.NearlyExpiredTime,
-                        d.NearlyExpiredTimeOne,
-                        d.ExpiredTimeProvince
-                    })
-                    .ExecuteCommandAsync(HttpContext.RequestAborted);
                 success++;
             }
             catch (UserFriendlyException e)
@@ -2601,9 +2454,168 @@ public class OrderController : BaseController
             }
         }
 
-        return $"总共: {dto.DelayId.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result}";
+        return $"总共: {dto.DelayId.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result.ToString()}";
     }
 
+    //[HttpPost("delay/batch_audit")]
+    //[LogFilter("批量审批延期")]
+    //public async Task<string> BatchAuditDelay([FromBody] BatchDelayNextFlowDto dto)
+    //{
+    //    var result = new StringBuilder();
+    //    var fail = 0;
+    //    var success = 0;
+    //    var workflowDto = dto.NextWorkflow;
+    //    var delays = await _orderDelayRepository.Queryable()
+    //        .Includes(x => x.Order)
+    //        .Includes(x => x.Workflow, d => d.WorkflowDefinition)
+    //        .Includes(x => x.Workflow, d => d.Steps)
+    //        .Includes(x => x.Workflow, d => d.Traces)
+    //        .Includes(x => x.Workflow, d => d.Countersigns)
+    //        .Where(x => dto.DelayId.Contains(x.Id))
+    //        .ToListAsync(HttpContext.RequestAborted);
+
+    //    if (!delays.Any())
+    //        return string.Empty;
+
+    //    var currentStep = delays.First().Workflow.Steps.FirstOrDefault(d =>
+    //        d.Status == EWorkflowStepStatus.WaitForAccept || d.Status == EWorkflowStepStatus.WaitForHandle);
+
+    //    var updateDelays = new List<OrderDelay>();
+    //    var updateOrders = new List<Order>();
+    //    foreach (var delay in delays)
+    //    {
+    //        try
+    //        {
+    //            NextStepsWithOpinionDto<NextStepOption> next = null;
+
+    //            try
+    //            {
+    //                next = await _workflowApplication.GetNextStepsAsync(delay.Workflow, HttpContext.RequestAborted);
+    //            }
+    //            catch (UserFriendlyException e)
+    //            {
+    //                if (e.Message.Contains("未找到对应节点"))
+    //                {
+    //                    result.Append("无权审核:" + delay.No);
+    //                    fail++;
+    //                }
+    //                else
+    //                {
+    //                    throw;
+    //                }
+    //            }
+
+    //            if (next == null) continue;
+
+    //            if (!delay.Order.IsProvince)
+    //            {
+    //                if (next.Steps.Any(x => x.Value == "省审批"))
+    //                {
+    //                    next.Steps.Remove(next.Steps.First(x => x.Value == "省审批"));
+    //                }
+    //            }
+
+    //            if (!_sessionContext.OrgIsCenter && currentStep.Name != "中心初审")
+    //            {
+    //                if (next.Steps.Any(x => x.Value == "中心终审"))
+    //                {
+    //                    next.Steps.Remove(next.Steps.First(x => x.Value == "中心终审"));
+    //                }
+    //            }
+
+    //            workflowDto.StepId = next.StepId;
+    //            workflowDto.ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed;
+
+    //            if (dto.IsPass)
+    //            {
+    //                var step = next.Steps.FirstOrDefault(x => x.Value == workflowDto.NextStepName);
+    //                if (step is null)
+    //                {
+    //                    result.Append("无权审核:" + delay.No);
+    //                    fail++;
+    //                    continue;
+    //                }
+
+    //                workflowDto.NextStepCode = step.Key;
+    //                workflowDto.NextStepName = step.Value;
+
+    //                //处理工单延期
+    //                var order = delay.Order;
+    //                var expiredTimeBase = DateTime.Now;
+    //                if (_appOptions.Value.IsZiGong)
+    //                {
+    //                    expiredTimeBase = order.ExpiredTime.Value;
+    //                }
+
+    //                var startTime = DateTime.Now;
+    //                if (order.CenterToOrgTime.HasValue)
+    //                {
+    //                    startTime = order.CenterToOrgTime!.Value;
+    //                }
+
+    //                var expiredTimeConfig =
+    //                    await _expireTime.CalcEndTime(expiredTimeBase, startTime, new TimeConfig(delay.DelayNum, delay.DelayUnit),
+    //                        order.AcceptTypeCode);
+    //                order.ExpiredTime = expiredTimeConfig.ExpiredTime;
+    //                order.NearlyExpiredTime = expiredTimeConfig.NearlyExpiredTime;
+    //                order.NearlyExpiredTimeOne = expiredTimeConfig.NearlyExpiredTimeOne;
+    //                //TODO发送短信即将超期
+    //                if (delay.IsProDelay)
+    //                {
+    //                    order.ExpiredTimeProvince = expiredTimeConfig.ExpiredTime;
+    //                }
+
+    //                updateOrders.Add(order);
+
+    //                await _workflowDomainService.NextAsync(delay.Workflow, workflowDto,
+    //                    expiredTime: order.ExpiredTime,
+    //                    cancellationToken: HttpContext.RequestAborted);
+
+    //                await _workflowDomainService.UpdateUnhandleExpiredTimeAsync(order.WorkflowId, order.ExpiredTime, HttpContext.RequestAborted);
+
+    //                var orderDto = _mapper.Map<OrderDto>(order);
+    //                await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
+    //                    cancellationToken: HttpContext.RequestAborted);
+    //            }
+    //            else
+    //            {
+    //                var reject = workflowDto.Adapt<RejectDto>();
+    //                await _workflowApplication.RejectAsync(reject, HttpContext.RequestAborted);
+    //            }
+
+
+    //            delay.DelayState = dto.IsPass ? EDelayState.Pass : EDelayState.NoPass;
+    //            updateDelays.Add(delay);
+
+    //            success++;
+    //        }
+    //        catch (UserFriendlyException e)
+    //        {
+    //            result.Append(e.Message);
+    //            fail++;
+    //        }
+    //    }
+
+
+    //    await _orderDelayRepository.Updateable(updateDelays)
+    //        .UpdateColumns(d => d.DelayState)
+    //        .ExecuteCommandAsync(HttpContext.RequestAborted);
+
+    //    await _orderRepository.Updateable(updateOrders)
+    //        .UpdateColumns(d => new
+    //        {
+    //            d.ExpiredTime,
+    //            d.NearlyExpiredTime,
+    //            d.NearlyExpiredTimeOne,
+    //            d.ExpiredTimeProvince
+    //        })
+    //        .ExecuteCommandAsync(HttpContext.RequestAborted);
+
+    //    return $"总共: {dto.DelayId.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result}";
+    //}
+
+
+
     /// <summary>
     ///  延期查询流程办理下一步可选节点
     /// </summary>

+ 15 - 15
src/Hotline.Application/Handlers/FlowEngine/WorkflowEndHandler.cs

@@ -316,21 +316,21 @@ public class WorkflowEndHandler : INotificationHandler<EndWorkflowNotify>
                     // await _enforcementApplication.AddPassTheBuckOrderAsync(order, _sessionContext.OrgId, _sessionContext.OrgName, cancellationToken);
                     break;
                 case WorkflowModuleConsts.OrderDelay:
-                    // var delay = await _orderDelayRepository.GetAsync(workflow.ExternalId, cancellationToken);
-                    // if (delay != null)
-                    // {
-                    //     //delay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-                    //     delay.DelayState = isReviewPass ? EDelayState.Pass : EDelayState.NoPass;
-                    //     await _orderDelayRepository.Updateable(delay)
-                    //         .UpdateColumns(d => d.DelayState)
-                    //         .ExecuteCommandAsync(cancellationToken);
-                    //     if (isReviewPass)
-                    //     {
-                    //         //处理工单延期
-                    //         await _orderApplication.DelayOrderExpiredTimeAsync(delay.OrderId, delay.DelayNum,
-                    //             delay.DelayUnit, delay.IsProDelay, cancellationToken);
-                    //     }
-                    // }
+                    var delay = await _orderDelayRepository.GetAsync(workflow.ExternalId, cancellationToken);
+                    if (delay != null)
+                    {
+                        //delay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                        delay.DelayState = isReviewPass ? EDelayState.Pass : EDelayState.NoPass;
+                        await _orderDelayRepository.Updateable(delay)
+                            .UpdateColumns(d => d.DelayState)
+                            .ExecuteCommandAsync(cancellationToken);
+                        if (isReviewPass)
+                        {
+                            //处理工单延期
+                            await _orderApplication.DelayOrderExpiredTimeAsync(delay.OrderId, delay.DelayNum,
+                                delay.DelayUnit, delay.IsProDelay, cancellationToken);
+                        }
+                    }
                     break;
                 case WorkflowModuleConsts.OrderTerminate:
                     var orderTerminate = await _orderTerminateRepository.Queryable()

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

@@ -62,6 +62,14 @@ namespace Hotline.FlowEngine.Workflows
             Action<Workflow, WorkflowStep, StepDefine, WorkflowStep>? newStepConfig = null,
             CancellationToken cancellationToken = default);
 
+
+        /// <summary>
+        /// 开启流程直接归档
+        /// </summary>
+        Task StartToEndAsync(StartWorkflowDto dto, string externalId, DateTime? expiredTime = null,
+            CancellationToken cancellationToken = default);
+
+
         /// <summary>
         /// 查询工作流
         /// </summary>
@@ -290,12 +298,6 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         Task<List<WorkflowStep>> GetStepsBelongsToAsync(string userId, CancellationToken cancellationToken);
 
-        /// <summary>
-        /// 开启流程直接归档
-        /// </summary>
-        Task StartToEndAsync(StartWorkflowDto dto, string externalId, DateTime? expiredTime = null,
-            CancellationToken cancellationToken = default);
-
         /// <summary>
         /// 批量修改工单办理对象
         /// </summary>
@@ -312,7 +314,7 @@ namespace Hotline.FlowEngine.Workflows
         /// <summary>
         /// 更新未办理节点的期满时间
         /// </summary>
-        Task UpdateUnhandleExpiredTimeAsync(string workflowId, DateTime expiredTime, CancellationToken cancellation);
+        Task UpdateUnhandleExpiredTimeAsync(string workflowId, DateTime? expiredTime, CancellationToken cancellation);
 
         /// <summary>
         /// 查询该部门最后办理节点

+ 39 - 22
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -23,6 +23,7 @@ using Hotline.Configurations;
 using Hotline.Share.Dtos.File;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Microsoft.Extensions.Options;
+using Hotline.Share.Dtos.Users;
 
 namespace Hotline.FlowEngine.Workflows
 {
@@ -640,6 +641,43 @@ namespace Hotline.FlowEngine.Workflows
             return nextSteps;
         }
 
+
+        /// <summary>
+        /// 开启流程直接归档
+        /// </summary>
+        public async Task StartToEndAsync(StartWorkflowDto dto, string externalId, DateTime? expiredTime = null,
+            CancellationToken cancellationToken = default)
+        {
+            //var wfModule = await GetWorkflowModuleAsync(dto.DefinitionModuleCode, cancellationToken);
+            //var definition = wfModule.Definition;
+            //if (definition == null)
+            //    throw new UserFriendlyException("无效模板编码");
+            //if (definition.Status is not EDefinitionStatus.Enable)
+            //    throw new UserFriendlyException("该模板不可用");
+
+            //var endStepDefine = definition.FindEndStepDefine();
+            //dto.NextStepCode = endStepDefine.Code;
+            //dto.NextStepName = endStepDefine.Name;
+            //dto.FlowDirection = EFlowDirection.CenterToFile;
+
+            //await StartAsync(dto, externalId, expiredTime, cancellationToken: cancellationToken);
+
+            var (workflow, startStep) = await StartAsync(dto, externalId, expiredTime, cancellationToken: cancellationToken);
+            var nextDto = _mapper.Map<NextWorkflowDto>(dto);
+            nextDto.WorkflowId = workflow.Id;
+            nextDto.StepId = startStep.Id;
+
+            var endStepDefine = workflow.WorkflowDefinition.FindEndStepDefine();
+            nextDto.NextStepCode = endStepDefine.Code;
+            nextDto.NextStepName = endStepDefine.Name;
+
+            await NextAsync(workflow, nextDto,
+                expiredTime: expiredTime,
+                isAutoFillSummaryOpinion: true,
+                cancellationToken: cancellationToken);
+        }
+
+
         public async Task<Workflow> GetWorkflowAsync(string workflowId,
             bool withDefine = false, bool withSteps = false,
             bool withTraces = false, bool withTracesTree = false,
@@ -1136,27 +1174,6 @@ namespace Hotline.FlowEngine.Workflows
             return (currentStep, prevStep, countersignStartStep);
         }
 
-        /// <summary>
-        /// 开启流程直接归档
-        /// </summary>
-        public async Task StartToEndAsync(StartWorkflowDto dto, string externalId, DateTime? expiredTime = null,
-            CancellationToken cancellationToken = default)
-        {
-            var wfModule = await GetWorkflowModuleAsync(dto.DefinitionModuleCode, cancellationToken);
-            var definition = wfModule.Definition;
-            if (definition == null)
-                throw new UserFriendlyException("无效模板编码");
-            if (definition.Status is not EDefinitionStatus.Enable)
-                throw new UserFriendlyException("该模板不可用");
-
-            var endStepDefine = definition.FindEndStepDefine();
-            dto.NextStepCode = endStepDefine.Code;
-            dto.NextStepName = endStepDefine.Name;
-            dto.FlowDirection = EFlowDirection.CenterToFile;
-
-            await StartAsync(dto, externalId, expiredTime, cancellationToken: cancellationToken);
-        }
-
         /// <summary>
         /// 查询派单池中流程节点id
         /// </summary>
@@ -1260,7 +1277,7 @@ namespace Hotline.FlowEngine.Workflows
         /// <summary>
         /// 更新未办理节点的期满时间
         /// </summary>
-        public async Task UpdateUnhandleExpiredTimeAsync(string workflowId, DateTime expiredTime,
+        public async Task UpdateUnhandleExpiredTimeAsync(string workflowId, DateTime? expiredTime,
             CancellationToken cancellation)
         {
             var steps = await _workflowStepRepository.Queryable()

+ 18 - 0
src/Hotline/Validators/Ippbx/TrOnDutyDtoValidator.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using FluentValidation;
+using Hotline.Share.Dtos.TrCallCenter;
+
+namespace Hotline.Validators.Ippbx
+{
+    public class TrOnDutyDtoValidator : AbstractValidator<TrOnDutyDto>
+    {
+        public TrOnDutyDtoValidator()
+        {
+            RuleFor(d=>d.TelNo).NotEmpty().WithMessage("分机号不能为空");
+        }
+    }
+}