Przeglądaj źródła

Merge branch 'release' of http://git.12345lm.cn/Fengwo/hotline into release

Dun.Jason 9 miesięcy temu
rodzic
commit
faa6285af9

+ 78 - 71
src/Hotline.Api/Controllers/OrderController.cs

@@ -322,47 +322,50 @@ public class OrderController : BaseController
                     publishPublishOrder.Order = _mapper.Map<OrderDto>(order);
                     await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderPublishOrder, publishPublishOrder);
 
-                    try
+                    var isOpenContingencyManagement = _systemSettingCacheManager.GetSetting(SettingConstants.IsOpenContingencyManagement)?.SettingValue[0];
+                    if (isOpenContingencyManagement == "true")
                     {
-                        //应急管理局业务处理
-                        //是否是指定热点
-                        if (await _contingencyManagementHotspotRepository.AnyAsync(p => p.Id == order.HotspotId, HttpContext.RequestAborted))
+                        try
                         {
-                            var orderData = await _contingencyManagementOrdersRepository.GetAsync(p => p.Id == order.Id, HttpContext.RequestAborted);
-                            //不存在新增
-                            if (orderData == null)
-                            {
-                                orderData = new ContingencyManagementOrders();
-                                orderData = _mapper.Map<ContingencyManagementOrders>(order);
-                                orderData.Id = order.Id;
-                                orderData.ArrangementOpinion = order.ActualOpinion;
-                                orderData.ArrangeTitle = order.Title;
-                                orderData.ArrangeContent = order.Content;
-                                orderData.PushState = "0";
-                                await _contingencyManagementOrdersRepository.AddAsync(orderData, HttpContext.RequestAborted);
-                            }
-                            else
+                            //应急管理局业务处理
+                            //是否是指定热点
+                            if (await _contingencyManagementHotspotRepository.AnyAsync(p => p.Id == order.HotspotId, HttpContext.RequestAborted))
                             {
-                                //存在修改
-                                _mapper.Map(order, orderData);
-                                orderData.ArrangementOpinion = order.ActualOpinion;
-                                orderData.ArrangeTitle = order.Title;
-                                orderData.ArrangeContent = order.Content;
-                                orderData.PushState = "0";
-                                await _contingencyManagementOrdersRepository.UpdateAsync(orderData, HttpContext.RequestAborted);
+                                var orderData = await _contingencyManagementOrdersRepository.GetAsync(p => p.Id == order.Id, HttpContext.RequestAborted);
+                                //不存在新增
+                                if (orderData == null)
+                                {
+                                    orderData = new ContingencyManagementOrders();
+                                    orderData = _mapper.Map<ContingencyManagementOrders>(order);
+                                    orderData.Id = order.Id;
+                                    orderData.ArrangementOpinion = order.ActualOpinion;
+                                    orderData.ArrangeTitle = order.Title;
+                                    orderData.ArrangeContent = order.Content;
+                                    orderData.PushState = "0";
+                                    await _contingencyManagementOrdersRepository.AddAsync(orderData, HttpContext.RequestAborted);
+                                }
+                                else
+                                {
+                                    //存在修改
+                                    _mapper.Map(order, orderData);
+                                    orderData.ArrangementOpinion = order.ActualOpinion;
+                                    orderData.ArrangeTitle = order.Title;
+                                    orderData.ArrangeContent = order.Content;
+                                    orderData.PushState = "0";
+                                    await _contingencyManagementOrdersRepository.UpdateAsync(orderData, HttpContext.RequestAborted);
+                                }
+                                //推送消息
+                                var pushaData = _mapper.Map<ContingencyManagementOrdersDto>(orderData);
+                                pushaData.Id = orderData.Id;
+                                //推送消息
+                                await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderContingencyManagement,
+                                 pushaData, Hotline.Share.Mq.EventNames.HotlineOrderContingencyManagementState);
                             }
-                            //推送消息
-                            var pushaData = _mapper.Map<ContingencyManagementOrdersDto>(orderData);
-                            pushaData.Id = orderData.Id;
-                            //推送消息
-                            await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderContingencyManagement,
-                             pushaData, Hotline.Share.Mq.EventNames.HotlineOrderContingencyManagementState);
+                        }
+                        catch (Exception)
+                        {
                         }
                     }
-                    catch (Exception)
-                    {
-                    }
-
                     var orderVisit = new OrderVisit();
                     orderVisit.No = order.No;
                     orderVisit.OrderId = order.Id;
@@ -497,46 +500,50 @@ public class OrderController : BaseController
         }
         await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderPublishOrder, publishPublishOrder);
 
-        try
+        var isOpenContingencyManagement = _systemSettingCacheManager.GetSetting(SettingConstants.IsOpenContingencyManagement)?.SettingValue[0];
+        if (isOpenContingencyManagement == "true")
         {
-            //应急管理局业务处理
-            //是否是指定热点
-            if (await _contingencyManagementHotspotRepository.AnyAsync(p => p.Id == order.HotspotId, HttpContext.RequestAborted))
+            try
             {
-                var orderData = await _contingencyManagementOrdersRepository.GetAsync(p => p.Id == order.Id, HttpContext.RequestAborted);
-                //不存在新增
-                if (orderData == null)
+                //应急管理局业务处理
+                //是否是指定热点
+                if (await _contingencyManagementHotspotRepository.AnyAsync(p => p.Id == order.HotspotId, HttpContext.RequestAborted))
                 {
-                    orderData = new ContingencyManagementOrders();
-                    orderData = _mapper.Map<ContingencyManagementOrders>(order);
-                    orderData.Id = order.Id;
-                    orderData.ArrangementOpinion = dto.ArrangeOpinion;
-                    orderData.ArrangeTitle = dto.ArrangeTitle;
-                    orderData.ArrangeContent = dto.ArrangeContent;
-                    orderData.PushState = "0";
-                    await _contingencyManagementOrdersRepository.AddAsync(orderData, HttpContext.RequestAborted);
-                }
-                else
-                {
-                    //存在修改
-                    _mapper.Map(order, orderData);
-                    orderData.ArrangementOpinion = dto.ArrangeOpinion;
-                    orderData.ArrangeTitle = dto.ArrangeTitle;
-                    orderData.ArrangeContent = dto.ArrangeContent;
-                    orderData.PushState = "0";
-                    await _contingencyManagementOrdersRepository.UpdateAsync(orderData, HttpContext.RequestAborted);
-                }
-                var pushaData = _mapper.Map<ContingencyManagementOrdersDto>(orderData);
-                pushaData.Id = order.Id;
-                pushaData.CreationTime = order.CreationTime;
-                //推送消息
-                await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderContingencyManagement,
-                 pushaData, Hotline.Share.Mq.EventNames.HotlineOrderContingencyManagementState, HttpContext.RequestAborted);
+                    var orderData = await _contingencyManagementOrdersRepository.GetAsync(p => p.Id == order.Id, HttpContext.RequestAborted);
+                    //不存在新增
+                    if (orderData == null)
+                    {
+                        orderData = new ContingencyManagementOrders();
+                        orderData = _mapper.Map<ContingencyManagementOrders>(order);
+                        orderData.Id = order.Id;
+                        orderData.ArrangementOpinion = dto.ArrangeOpinion;
+                        orderData.ArrangeTitle = dto.ArrangeTitle;
+                        orderData.ArrangeContent = dto.ArrangeContent;
+                        orderData.PushState = "0";
+                        await _contingencyManagementOrdersRepository.AddAsync(orderData, HttpContext.RequestAborted);
+                    }
+                    else
+                    {
+                        //存在修改
+                        _mapper.Map(order, orderData);
+                        orderData.ArrangementOpinion = dto.ArrangeOpinion;
+                        orderData.ArrangeTitle = dto.ArrangeTitle;
+                        orderData.ArrangeContent = dto.ArrangeContent;
+                        orderData.PushState = "0";
+                        await _contingencyManagementOrdersRepository.UpdateAsync(orderData, HttpContext.RequestAborted);
+                    }
+                    var pushaData = _mapper.Map<ContingencyManagementOrdersDto>(orderData);
+                    pushaData.Id = order.Id;
+                    pushaData.CreationTime = order.CreationTime;
+                    //推送消息
+                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderContingencyManagement,
+                     pushaData, Hotline.Share.Mq.EventNames.HotlineOrderContingencyManagementState, HttpContext.RequestAborted);
 
+                }
+            }
+            catch (Exception)
+            {
             }
-        }
-        catch (Exception)
-        {
         }
 
         var orderVisit = new OrderVisit();
@@ -3269,7 +3276,7 @@ public class OrderController : BaseController
                 _sessionContext.RequiredUserId, _sessionContext.UserName,
                 canUpdateOrderSender);
             //发送短信即将超期
-           _capPublisher.PublishDelay(expiredTimeConfig.NearlyExpiredTime - DateTime.Now, EventNames.HotlineOrderNearlyExpiredTimeSms, new PublishNearlyExpiredTimeSmsDto() { OrderId = order.Id });
+            _capPublisher.PublishDelay(expiredTimeConfig.NearlyExpiredTime - DateTime.Now, EventNames.HotlineOrderNearlyExpiredTimeSms, new PublishNearlyExpiredTimeSmsDto() { OrderId = order.Id });
             //写入质检
             await _qualityApplication.AddQualityAsync(EQualitySource.Send, order.Id, HttpContext.RequestAborted);
         }

+ 219 - 209
src/Hotline.Application/Handlers/FlowEngine/WorkflowEndHandler.cs

@@ -126,231 +126,241 @@ public class WorkflowEndHandler : INotificationHandler<EndWorkflowNotify>
     /// <param name="cancellationToken">Cancellation token</param>
     public async Task Handle(EndWorkflowNotify notification, CancellationToken cancellationToken)
     {
-        var workflow = notification.Workflow;
-        //审批是否通过
-        var isReviewPass = workflow.IsReviewPass();
-
-        switch (workflow.ModuleCode)
+        try
         {
-            case WorkflowModuleConsts.KnowledgeAdd://新增知识库
-            case WorkflowModuleConsts.KnowledgeUpdate://修改知识库
-            case WorkflowModuleConsts.KnowledgeDelete://删除知识库
-                var knowledgeWork = await _knowledgeWorkFlowRepository.Queryable().Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
-                var knowledge = await _knowledgeRepository.Queryable().Where(x => x.Id == knowledgeWork.KnowledgeId).FirstAsync(cancellationToken);
-                knowledge.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-                await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
-                if (isReviewPass)
-                {
-                    await _knowledgeDomainService.EndWorkKnowledge(workflow, cancellationToken);
-                }
-                else
-                {
-                    await _knowledgeDomainService.TerminateWorkKnowledge(workflow, cancellationToken);
-                }
-                break;
-            case WorkflowModuleConsts.TelRestApply:
-                await _telDomainService.TelRestApplyPassAsync(workflow.ExternalId, cancellationToken);
-                break;
-            case WorkflowModuleConsts.OrderHandle:
-                var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId,
-                    withExtension: true, cancellationToken: cancellationToken);
-				//order.CheckIfFiled();
-				order.UpdateHandlingStatus(workflow.IsInCountersign);
-				_mapper.Map(workflow, order);
-                var now = DateTime.Now;
-                var handleDuration = order.CenterToOrgTime.HasValue && order.ActualHandleTime.HasValue
-                    ? _timeLimitDomainService.CalcWorkTime(order.CenterToOrgTime.Value,
-                    order.ActualHandleTime.Value, order.ProcessType is EProcessType.Zhiban)
-                    : 0;
-                var fileDuration = order.CenterToOrgTime.HasValue
-                    ? _timeLimitDomainService.CalcWorkTime(order.CenterToOrgTime.Value,
-                        now, order.ProcessType is EProcessType.Zhiban)
-                    : 0;
-                var allDuration = order.StartTime.HasValue
-                    ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value, now,
-                    order.ProcessType is EProcessType.Zhiban)
-                    : 0;
-                var creationTimeHandleDurationWorkday = order.ActualHandleTime.HasValue
-                    ? _timeLimitDomainService.CalcWorkTimeEx(order.CreationTime, now,
-                    order.ProcessType is EProcessType.Zhiban)
-                    : 0;
-                var centerToOrgHandleDurationWorkday = order.ActualHandleTime.HasValue && order.CenterToOrgTime.HasValue
-                    ? _timeLimitDomainService.CalcWorkTimeEx(order.CenterToOrgTime.Value, now,
-                    order.ProcessType is EProcessType.Zhiban)
-                    : 0;
 
-                order.File(now, handleDuration, fileDuration, allDuration, creationTimeHandleDurationWorkday, centerToOrgHandleDurationWorkday);
-                order.FileUserId = notification.Trace.HandlerId;
-                order.FileUserName = notification.Trace.HandlerName;
-                order.FileUserOrgId = notification.Trace.HandlerOrgId;
-                order.FileUserOrgName = notification.Trace.HandlerOrgName;
-                order.FileOrgIsCenter = notification.Trace.HandlerOrgIsCenter;
-                order.FileOpinion = notification.Dto.Opinion;
+            var workflow = notification.Workflow;
+            //审批是否通过
+            var isReviewPass = workflow.IsReviewPass();
 
-                //记录冗余归档数据
-                if (notification.Workflow.Steps.Any(x => x.BusinessType == Share.Enums.FlowEngine.EBusinessType.Send))
-                {
-                    order.FileUserRole = EFileUserType.Dispatch;
-                }
-                else
-                {
-                    order.FileUserRole = EFileUserType.Seat;
-                }
-                if (order.ProcessType == EProcessType.Jiaoban)
-                {
-                    order.FileUserRole = EFileUserType.Org;
-                }
+            switch (workflow.ModuleCode)
+            {
+                case WorkflowModuleConsts.KnowledgeAdd://新增知识库
+                case WorkflowModuleConsts.KnowledgeUpdate://修改知识库
+                case WorkflowModuleConsts.KnowledgeDelete://删除知识库
+                    var knowledgeWork = await _knowledgeWorkFlowRepository.Queryable().Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
+                    var knowledge = await _knowledgeRepository.Queryable().Where(x => x.Id == knowledgeWork.KnowledgeId).FirstAsync(cancellationToken);
+                    knowledge.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                    await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
+                    if (isReviewPass)
+                    {
+                        await _knowledgeDomainService.EndWorkKnowledge(workflow, cancellationToken);
+                    }
+                    else
+                    {
+                        await _knowledgeDomainService.TerminateWorkKnowledge(workflow, cancellationToken);
+                    }
+                    break;
+                case WorkflowModuleConsts.TelRestApply:
+                    await _telDomainService.TelRestApplyPassAsync(workflow.ExternalId, cancellationToken);
+                    break;
+                case WorkflowModuleConsts.OrderHandle:
+                    var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId,
+                        withExtension: true, cancellationToken: cancellationToken);
+                    //order.CheckIfFiled();
+                    order.UpdateHandlingStatus(workflow.IsInCountersign);
+                    _mapper.Map(workflow, order);
+                    var now = DateTime.Now;
+                    var handleDuration = order.CenterToOrgTime.HasValue && order.ActualHandleTime.HasValue
+                        ? _timeLimitDomainService.CalcWorkTime(order.CenterToOrgTime.Value,
+                        order.ActualHandleTime.Value, order.ProcessType is EProcessType.Zhiban)
+                        : 0;
+                    var fileDuration = order.CenterToOrgTime.HasValue
+                        ? _timeLimitDomainService.CalcWorkTime(order.CenterToOrgTime.Value,
+                            now, order.ProcessType is EProcessType.Zhiban)
+                        : 0;
+                    var allDuration = order.StartTime.HasValue
+                        ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value, now,
+                        order.ProcessType is EProcessType.Zhiban)
+                        : 0;
+                    var creationTimeHandleDurationWorkday = order.ActualHandleTime.HasValue
+                        ? _timeLimitDomainService.CalcWorkTimeEx(order.CreationTime, now,
+                        order.ProcessType is EProcessType.Zhiban)
+                        : 0;
+                    var centerToOrgHandleDurationWorkday = order.ActualHandleTime.HasValue && order.CenterToOrgTime.HasValue
+                        ? _timeLimitDomainService.CalcWorkTimeEx(order.CenterToOrgTime.Value, now,
+                        order.ProcessType is EProcessType.Zhiban)
+                        : 0;
 
-                //是否已解决
-                order.IsResolved = notification.Dto.External == null ? false : notification.Dto.External.IsResolved;
+                    order.File(now, handleDuration, fileDuration, allDuration, creationTimeHandleDurationWorkday, centerToOrgHandleDurationWorkday);
+                    order.FileUserId = notification.Trace.HandlerId;
+                    order.FileUserName = notification.Trace.HandlerName;
+                    order.FileUserOrgId = notification.Trace.HandlerOrgId;
+                    order.FileUserOrgName = notification.Trace.HandlerOrgName;
+                    order.FileOrgIsCenter = notification.Trace.HandlerOrgIsCenter;
+                    order.FileOpinion = notification.Dto.Opinion;
 
-                await _orderRepository.UpdateAsync(order, cancellationToken);
-                //var callRecord = await _trCallRecordRepository.GetAsync(p => p.CallAccept == order.CallId, cancellationToken); //由CallAccept改为OtherAccept
-                //var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
-                var orderFlowDto = new OrderFlowDto
-                {
-                    Order = _mapper.Map<OrderDto>(order),
-                    WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace)
-                };
-                // if (callRecord != null)
-                // {
-                //     orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
-                // }
-                if (order.SourceChannelCode == AppDefaults.SourceChannel.DianHua &&
-                    !string.IsNullOrEmpty(order.CallId))
-                {
-                    if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.TianRun)
+                    //记录冗余归档数据
+                    if (notification.Workflow.Steps.Any(x => x.BusinessType == Share.Enums.FlowEngine.EBusinessType.Send))
                     {
-                        // var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
-                        var callRecord = await _callApplication.GetTianrunCallAsync(order.CallId, cancellationToken);
-                        if (callRecord != null)
-                        {
-                            orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
-                        }
+                        order.FileUserRole = EFileUserType.Dispatch;
                     }
-                    else if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.XingTang)
+                    else
+                    {
+                        order.FileUserRole = EFileUserType.Seat;
+                    }
+                    if (order.ProcessType == EProcessType.Jiaoban)
                     {
-                        var call = await _callApplication.GetCallAsync(order.CallId, cancellationToken);
-                        if (call is not null)
-                            orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(call);
+                        order.FileUserRole = EFileUserType.Org;
                     }
-                }
 
-                //这里需要判断是否是警情退回
-                orderFlowDto.IsNonPoliceReturn = notification.Dto.External == null ? false : notification.Dto.External.IsPoliceReturn;
-                await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFiled, orderFlowDto, cancellationToken: cancellationToken);
+                    //是否已解决
+                    order.IsResolved = notification.Dto.External == null ? false : notification.Dto.External.IsResolved;
 
-                //try
-                //{
-                //    //写入质检  针对受理之后直接结束的工单
-                //    await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
-                //}
-                //catch (Exception e)
-                //{
-                //    _logger.LogError($"写入质检异常!orderId: {order.Id}, \r\n{e.Message}");
-                //}
+                    await _orderRepository.UpdateAsync(order, cancellationToken);
+                    //var callRecord = await _trCallRecordRepository.GetAsync(p => p.CallAccept == order.CallId, cancellationToken); //由CallAccept改为OtherAccept
+                    //var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
+                    var orderFlowDto = new OrderFlowDto
+                    {
+                        Order = _mapper.Map<OrderDto>(order),
+                        WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace)
+                    };
+                    // if (callRecord != null)
+                    // {
+                    //     orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
+                    // }
+                    if (order.SourceChannelCode == AppDefaults.SourceChannel.DianHua &&
+                        !string.IsNullOrEmpty(order.CallId))
+                    {
+                        if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.TianRun)
+                        {
+                            // var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
+                            var callRecord = await _callApplication.GetTianrunCallAsync(order.CallId, cancellationToken);
+                            if (callRecord != null)
+                            {
+                                orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
+                            }
+                        }
+                        else if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.XingTang)
+                        {
+                            var call = await _callApplication.GetCallAsync(order.CallId, cancellationToken);
+                            if (call is not null)
+                                orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(call);
+                        }
+                    }
 
-                //司法行政监督管理-工单处理
-                await _enforcementApplication.AddEnforcementOrderAsync(order, cancellationToken);
-                //推诿工单
-                // await _enforcementApplication.AddPassTheBuckOrderAsync(order, _sessionContext.OrgId, _sessionContext.OrgName, cancellationToken);
-                break;
-            //case WorkflowModuleConsts.OrderScreen:
-            //    var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
-            //    if (screen != null)
-            //    {
-            //        screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-            //        if (isReviewPass)
-            //        {
-            //            screen.Status = EScreenStatus.End;
-            //            screen.ReplyContent = workflow.ActualOpinion;
-            //            await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
-            //            var visitDetail =
-            //                await _orderVisitedDetailRepository.GetAsync(screen.VisitDetailId, cancellationToken);
-            //            if (visitDetail != null)
-            //            {
-            //                var screenSatisfy = new Kv() { Key = "-1", Value = "视为满意" };
-            //                visitDetail.OrgProcessingResults = screenSatisfy;
-            //                //visitDetail.OrgHandledAttitude = screenSatisfy;
-            //                await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
-            //                // 修改主表当前评价结果
-            //                await _orderVisitRepository.Updateable().SetColumns(v => new OrderVisit() { NowEvaluate = screenSatisfy }).Where(v => v.Id == visitDetail.VisitId).ExecuteCommandAsync(cancellationToken);
-            //                //获取回访信息
-            //                var visit = await _orderVisitRepository.Queryable().Includes(x => x.Order)
-            //                    .Includes(x => x.OrderVisitDetails)
-            //                    .Where(x => x.Id == screen.VisitId).FirstAsync(cancellationToken);
-            //                if (visit != null)
-            //                {
-            //                    //获取回访明细
-            //                    var visitDe = visit.OrderVisitDetails.First(x => x.Id == screen.VisitDetailId);
-            //                    //推省上
-            //                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderScreenApplyed,
-            //                          new PublishVisitDto()
-            //                          {
-            //                              Order = _mapper.Map<OrderDto>(visit.Order),
-            //                              No = visit.No,
-            //                              VisitType = visit.VisitType,
-            //                              VisitName = visit.CreatorName,
-            //                              VisitTime = visit.VisitTime,
-            //                              VisitRemark = string.IsNullOrEmpty(visitDe.VisitContent) ? screenSatisfy.Value : visitDe.VisitContent,
-            //                              AreaCode = visit.Order.AreaCode!,
-            //                              SubjectResultSatifyCode = visitDe.OrgProcessingResults?.Key,
-            //                              FirstSatisfactionCode = visit.Order.FirstVisitResultCode!,
-            //                              ClientGuid = ""
-            //                          });
+                    //这里需要判断是否是警情退回
+                    orderFlowDto.IsNonPoliceReturn = notification.Dto.External == null ? false : notification.Dto.External.IsPoliceReturn;
+                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFiled, orderFlowDto, cancellationToken: cancellationToken);
 
-            //                    //推门户
-            //                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisitedWeb, new PublishVisitAllDto()
-            //                    {
-            //                        Id = visit.Id,
-            //                        Order = _mapper.Map<OrderDto>(visit.Order),
-            //                        OrderVisitDetails = _mapper.Map<List<VisitDetailDto>>(visit.OrderVisitDetails),
-            //                        VisitName = visit.CreatorName,
-            //                        VisitTime = visit.VisitTime,
-            //                        VisitType = visit.VisitType,
-            //                        VisitState = visit.VisitState,
-            //                        PublishTime = visit.PublishTime,
-            //                    }, cancellationToken: cancellationToken);
-            //                }
-            //            }
-            //        }
-            //      else
-     //               {
-     //                   await _orderRepository.OrderScreenRevisionVisit(screen.VisitId, true, cancellationToken);
-     //                   screen.Status = EScreenStatus.Refuse;
-     //                   screen.ReplyContent = workflow.ActualOpinion;
-     //               }
-     //               screen.NewestAuditTime = DateTime.Now;
-					//await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
-					//OrderScreenDetail detail = new OrderScreenDetail
-					//{
-					//	ScreenId = screen.Id
-					//};
-					//detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 1);
-     //               await _orderScreenDetailRepository.AddAsync(detail, 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);
-                    if (isReviewPass)
-                    {
-                        delay.DelayState = isReviewPass ? EDelayState.Pass : EDelayState.NoPass;
-                        await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
+                    //try
+                    //{
+                    //    //写入质检  针对受理之后直接结束的工单
+                    //    await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
+                    //}
+                    //catch (Exception e)
+                    //{
+                    //    _logger.LogError($"写入质检异常!orderId: {order.Id}, \r\n{e.Message}");
+                    //}
 
-                        //处理工单延期
-                        await _orderApplication.DelayOrderExpiredTimeAsync(delay.OrderId, delay.DelayNum,
-                            delay.DelayUnit,delay.IsProDelay, cancellationToken);
-                    }
-                    else
+                    //司法行政监督管理-工单处理
+                    await _enforcementApplication.AddEnforcementOrderAsync(order, cancellationToken);
+                    //推诿工单
+                    // await _enforcementApplication.AddPassTheBuckOrderAsync(order, _sessionContext.OrgId, _sessionContext.OrgName, cancellationToken);
+                    break;
+                //case WorkflowModuleConsts.OrderScreen:
+                //    var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
+                //    if (screen != null)
+                //    {
+                //        screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                //        if (isReviewPass)
+                //        {
+                //            screen.Status = EScreenStatus.End;
+                //            screen.ReplyContent = workflow.ActualOpinion;
+                //            await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
+                //            var visitDetail =
+                //                await _orderVisitedDetailRepository.GetAsync(screen.VisitDetailId, cancellationToken);
+                //            if (visitDetail != null)
+                //            {
+                //                var screenSatisfy = new Kv() { Key = "-1", Value = "视为满意" };
+                //                visitDetail.OrgProcessingResults = screenSatisfy;
+                //                //visitDetail.OrgHandledAttitude = screenSatisfy;
+                //                await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
+                //                // 修改主表当前评价结果
+                //                await _orderVisitRepository.Updateable().SetColumns(v => new OrderVisit() { NowEvaluate = screenSatisfy }).Where(v => v.Id == visitDetail.VisitId).ExecuteCommandAsync(cancellationToken);
+                //                //获取回访信息
+                //                var visit = await _orderVisitRepository.Queryable().Includes(x => x.Order)
+                //                    .Includes(x => x.OrderVisitDetails)
+                //                    .Where(x => x.Id == screen.VisitId).FirstAsync(cancellationToken);
+                //                if (visit != null)
+                //                {
+                //                    //获取回访明细
+                //                    var visitDe = visit.OrderVisitDetails.First(x => x.Id == screen.VisitDetailId);
+                //                    //推省上
+                //                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderScreenApplyed,
+                //                          new PublishVisitDto()
+                //                          {
+                //                              Order = _mapper.Map<OrderDto>(visit.Order),
+                //                              No = visit.No,
+                //                              VisitType = visit.VisitType,
+                //                              VisitName = visit.CreatorName,
+                //                              VisitTime = visit.VisitTime,
+                //                              VisitRemark = string.IsNullOrEmpty(visitDe.VisitContent) ? screenSatisfy.Value : visitDe.VisitContent,
+                //                              AreaCode = visit.Order.AreaCode!,
+                //                              SubjectResultSatifyCode = visitDe.OrgProcessingResults?.Key,
+                //                              FirstSatisfactionCode = visit.Order.FirstVisitResultCode!,
+                //                              ClientGuid = ""
+                //                          });
+
+                //                    //推门户
+                //                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisitedWeb, new PublishVisitAllDto()
+                //                    {
+                //                        Id = visit.Id,
+                //                        Order = _mapper.Map<OrderDto>(visit.Order),
+                //                        OrderVisitDetails = _mapper.Map<List<VisitDetailDto>>(visit.OrderVisitDetails),
+                //                        VisitName = visit.CreatorName,
+                //                        VisitTime = visit.VisitTime,
+                //                        VisitType = visit.VisitType,
+                //                        VisitState = visit.VisitState,
+                //                        PublishTime = visit.PublishTime,
+                //                    }, cancellationToken: cancellationToken);
+                //                }
+                //            }
+                //        }
+                //      else
+                //               {
+                //                   await _orderRepository.OrderScreenRevisionVisit(screen.VisitId, true, cancellationToken);
+                //                   screen.Status = EScreenStatus.Refuse;
+                //                   screen.ReplyContent = workflow.ActualOpinion;
+                //               }
+                //               screen.NewestAuditTime = DateTime.Now;
+                //await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
+                //OrderScreenDetail detail = new OrderScreenDetail
+                //{
+                //	ScreenId = screen.Id
+                //};
+                //detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 1);
+                //               await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);
+                //    }
+                //    break;
+                case WorkflowModuleConsts.OrderDelay:
+                    var delay = await _orderDelayRepository.GetAsync(workflow.ExternalId, cancellationToken);
+                    if (delay != null)
                     {
-                        delay.DelayState = EDelayState.NoPass;
-                        await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
+                        delay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                        if (isReviewPass)
+                        {
+                            delay.DelayState = isReviewPass ? EDelayState.Pass : EDelayState.NoPass;
+                            await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
+
+                            //处理工单延期
+                            await _orderApplication.DelayOrderExpiredTimeAsync(delay.OrderId, delay.DelayNum,
+                                delay.DelayUnit, delay.IsProDelay, cancellationToken);
+                        }
+                        else
+                        {
+                            delay.DelayState = EDelayState.NoPass;
+                            await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
+                        }
                     }
-                }
-                break;
+                    break;
+            }
+
+        }
+        catch (Exception e)
+        {
+            _logger.LogError($"{nameof(WorkflowEndHandler)}异常,{e}");
+            throw;
         }
     }
 }

+ 208 - 199
src/Hotline.Application/Handlers/FlowEngine/WorkflowNextHandler.cs

@@ -93,82 +93,108 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
     /// <param name="cancellationToken">Cancellation token</param>
     public async Task Handle(NextStepNotify notification, CancellationToken cancellationToken)
     {
-        //_logger.LogInformation(
-        //    $"收到{nameof(NextStepNotify)}, notification: {JsonConvert.SerializeObject(notification)}");
-        var workflow = notification.Workflow;
-        var data = notification.Dto;
-        var assignInfo = notification.FlowAssignInfo;
+        try
+        {
+            //_logger.LogInformation(
+            //    $"收到{nameof(NextStepNotify)}, notification: {JsonConvert.SerializeObject(notification)}");
+            var workflow = notification.Workflow;
+            var data = notification.Dto;
+            var assignInfo = notification.FlowAssignInfo;
 
-        var currentTag = string.IsNullOrEmpty(notification.Trace.Tag)
-            ? null
-            : System.Text.Json.JsonSerializer.Deserialize<DefinitionTag>(notification.Trace.Tag);
-        var nextTag = string.IsNullOrEmpty(notification.NextStepDefine.Tag)
-            ? null
-            : System.Text.Json.JsonSerializer.Deserialize<DefinitionTag>(notification.NextStepDefine.Tag);
+            var currentTag = string.IsNullOrEmpty(notification.Trace.Tag)
+                ? null
+                : System.Text.Json.JsonSerializer.Deserialize<DefinitionTag>(notification.Trace.Tag);
+            var nextTag = string.IsNullOrEmpty(notification.NextStepDefine.Tag)
+                ? null
+                : System.Text.Json.JsonSerializer.Deserialize<DefinitionTag>(notification.NextStepDefine.Tag);
 
-        switch (workflow.ModuleCode)
-        {
-            case WorkflowModuleConsts.OrderHandle:
-                var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true,
-                    withAcceptor: true, withExtension: true, cancellationToken: cancellationToken);
-                order.CheckIfFiled();
-                order.UpdateHandlingStatus(workflow.IsInCountersign);
-                _mapper.Map(workflow, order);
+            switch (workflow.ModuleCode)
+            {
+                case WorkflowModuleConsts.OrderHandle:
+                    var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true,
+                        withAcceptor: true, withExtension: true, cancellationToken: cancellationToken);
+                    order.CheckIfFiled();
+                    order.UpdateHandlingStatus(workflow.IsInCountersign);
+                    _mapper.Map(workflow, order);
 
-                //var expiredTimeChanged = false;
-                //if (data.FlowDirection.HasValue
-                //    && data.External.TimeLimit.HasValue                   
-                //    && data.External.TimeLimitUnit.HasValue)
-                //{
-                //    // 1. calc expiredTime 2. update order.expiredTime 3. update workflow.expiredTime 4. publish province
+                    //var expiredTimeChanged = false;
+                    //if (data.FlowDirection.HasValue
+                    //    && data.External.TimeLimit.HasValue                   
+                    //    && data.External.TimeLimitUnit.HasValue)
+                    //{
+                    //    // 1. calc expiredTime 2. update order.expiredTime 3. update workflow.expiredTime 4. publish province
 
-                //    // var expiredTime = _timeLimitDomainService.CalcEndTime(DateTime.Now,
-                //    //     data.External.TimeLimitUnit.Value,
-                //    //     data.External.TimeLimit.Value, data.FlowDirection is EFlowDirection.OrgToCenter);
+                    //    // var expiredTime = _timeLimitDomainService.CalcEndTime(DateTime.Now,
+                    //    //     data.External.TimeLimitUnit.Value,
+                    //    //     data.External.TimeLimit.Value, data.FlowDirection is EFlowDirection.OrgToCenter);
 
-                //    var expiredTimeConfig = _timeLimitDomainService.CalcEndTime(DateTime.Now,
-                //        new TimeConfig(data.External.TimeLimit.Value, data.External.TimeLimitUnit.Value), order.AcceptTypeCode);
+                    //    var expiredTimeConfig = _timeLimitDomainService.CalcEndTime(DateTime.Now,
+                    //        new TimeConfig(data.External.TimeLimit.Value, data.External.TimeLimitUnit.Value), order.AcceptTypeCode);
 
-                //    if (data.FlowDirection is EFlowDirection.OrgToCenter)
-                //    {
-                //        order.OrgToCenter(expiredTimeConfig.TimeText, expiredTimeConfig.Count,
-                //            expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime, expiredTimeConfig.NearlyExpiredTime);
-                //    }
-                //    else if (data.FlowDirection is EFlowDirection.CenterToOrg)
-                //    {
-                //        order.CenterToOrg(expiredTimeConfig.TimeText, expiredTimeConfig.Count,
-                //            expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime, expiredTimeConfig.NearlyExpiredTime);
-                //        //写入质检
-                //        await _qualityApplication.AddQualityAsync(EQualitySource.Send, order.Id, cancellationToken);
-                //    }
+                    //    if (data.FlowDirection is EFlowDirection.OrgToCenter)
+                    //    {
+                    //        order.OrgToCenter(expiredTimeConfig.TimeText, expiredTimeConfig.Count,
+                    //            expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime, expiredTimeConfig.NearlyExpiredTime);
+                    //    }
+                    //    else if (data.FlowDirection is EFlowDirection.CenterToOrg)
+                    //    {
+                    //        order.CenterToOrg(expiredTimeConfig.TimeText, expiredTimeConfig.Count,
+                    //            expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime, expiredTimeConfig.NearlyExpiredTime);
+                    //        //写入质检
+                    //        await _qualityApplication.AddQualityAsync(EQualitySource.Send, order.Id, cancellationToken);
+                    //    }
 
-                //    await _workflowDomainService.UpdateExpiredTimeAsync(workflow,
-                //        expiredTimeConfig.ExpiredTime, expiredTimeConfig.TimeText,
-                //        expiredTimeConfig.Count, expiredTimeConfig.TimeType, expiredTimeConfig.NearlyExpiredTime, cancellationToken);
+                    //    await _workflowDomainService.UpdateExpiredTimeAsync(workflow,
+                    //        expiredTimeConfig.ExpiredTime, expiredTimeConfig.TimeText,
+                    //        expiredTimeConfig.Count, expiredTimeConfig.TimeType, expiredTimeConfig.NearlyExpiredTime, cancellationToken);
 
-                //    expiredTimeChanged = true;
-                //}
-                await _orderRepository.Updateable(order).ExecuteCommandAsync(cancellationToken);
-                //await _orderRepository.UpdateAsync(order, cancellationToken);
+                    //    expiredTimeChanged = true;
+                    //}
+                    await _orderRepository.Updateable(order).ExecuteCommandAsync(cancellationToken);
+                    //await _orderRepository.UpdateAsync(order, cancellationToken);
 
-                //司法行政监督管理-推诿工单
-                if (notification.Trace.StepType != EStepType.Summary && notification.Trace.StepType != EStepType.End && !notification.Trace.IsCountersignEndStep)
-                    await _enforcementApplication.AddPassTheBuckOrderAsync(order, _sessionContext.RequiredOrgId, _sessionContext.OrgName, cancellationToken);
+                    //司法行政监督管理-推诿工单
+                    if (notification.Trace.StepType != EStepType.Summary && notification.Trace.StepType != EStepType.End && !notification.Trace.IsCountersignEndStep)
+                        await _enforcementApplication.AddPassTheBuckOrderAsync(order, _sessionContext.RequiredOrgId, _sessionContext.OrgName, cancellationToken);
 
-                try
-                {
-                    if (notification.Dto.IsSms)
+                    try
                     {
-                        switch (notification.FlowAssignInfo.FlowAssignType)
+                        if (notification.Dto.IsSms)
                         {
-                            case EFlowAssignType.Org:
-                                var orgCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
-                                var orgList = await _userRepository.Queryable()
-                                    .Where(x => orgCodes.Contains(x.OrgId) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e"))
-                                    .ToListAsync(cancellationToken);
-                                foreach (var item in orgList)
-                                {
-                                    if (!string.IsNullOrEmpty(item.PhoneNo))
+                            switch (notification.FlowAssignInfo.FlowAssignType)
+                            {
+                                case EFlowAssignType.Org:
+                                    var orgCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
+                                    var orgList = await _userRepository.Queryable()
+                                        .Where(x => orgCodes.Contains(x.OrgId) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e"))
+                                        .ToListAsync(cancellationToken);
+                                    foreach (var item in orgList)
+                                    {
+                                        if (!string.IsNullOrEmpty(item.PhoneNo))
+                                        {
+                                            var messageDto = new Share.Dtos.Push.MessageDto
+                                            {
+                                                PushBusiness = EPushBusiness.OrderSend,
+                                                ExternalId = order.Id,
+                                                OrderId = order.Id,
+                                                PushPlatform = EPushPlatform.Sms,
+                                                Remark = order.Title,
+                                                Name = item.Name,
+                                                TemplateCode = "1007",
+                                                Params = new List<string>() { order.No },
+                                                TelNumber = item.PhoneNo,
+
+                                            };
+                                            await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
+                                        }
+                                    }
+                                    break;
+                                case EFlowAssignType.User:
+                                    var userCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
+                                    var userList = await _userRepository.Queryable()
+                                        .Where(x => userCodes.Contains(x.Id) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e"))
+                                        .ToListAsync(cancellationToken);
+                                    foreach (var item in userList)
                                     {
                                         var messageDto = new Share.Dtos.Push.MessageDto
                                         {
@@ -185,158 +211,141 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
                                         };
                                         await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
                                     }
-                                }
-                                break;
-                            case EFlowAssignType.User:
-                                var userCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
-                                var userList = await _userRepository.Queryable()
-                                    .Where(x => userCodes.Contains(x.Id) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e"))
-                                    .ToListAsync(cancellationToken);
-                                foreach (var item in userList)
-                                {
-                                    var messageDto = new Share.Dtos.Push.MessageDto
-                                    {
-                                        PushBusiness = EPushBusiness.OrderSend,
-                                        ExternalId = order.Id,
-                                        OrderId = order.Id,
-                                        PushPlatform = EPushPlatform.Sms,
-                                        Remark = order.Title,
-                                        Name = item.Name,
-                                        TemplateCode = "1007",
-                                        Params = new List<string>() { order.No },
-                                        TelNumber = item.PhoneNo,
-
-                                    };
-                                    await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
-                                }
-                                break;
-                            default:
-                                break;
+                                    break;
+                                default:
+                                    break;
+                            }
                         }
                     }
-                }
-                catch { }
-                var orderDto = _mapper.Map<OrderDto>(order);
-                await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFlowHandled, new OrderFlowDto
-                {
-                    Order = orderDto,
-                    WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace),
-                    ExpiredTimeChanged = notification.ExpiredTimeChanged,
-                    HandlerOrgLevel = notification.HandlerOrgId.CalcOrgLevel()
-                }, cancellationToken: cancellationToken);
+                    catch { }
+                    var orderDto = _mapper.Map<OrderDto>(order);
+                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFlowHandled, new OrderFlowDto
+                    {
+                        Order = orderDto,
+                        WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace),
+                        ExpiredTimeChanged = notification.ExpiredTimeChanged,
+                        HandlerOrgLevel = notification.HandlerOrgId.CalcOrgLevel()
+                    }, cancellationToken: cancellationToken);
 
 
-                break;
-            case WorkflowModuleConsts.KnowledgeAdd:
-            case WorkflowModuleConsts.KnowledgeUpdate:
-            case WorkflowModuleConsts.KnowledgeDelete:
-                var knowledgeWork = await _knowledgeWorkFlowRepository.Queryable().Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
-                var knowledge = await _knowledgeRepository.Queryable().Where(x => x.Id == knowledgeWork.KnowledgeId).FirstAsync(cancellationToken);
-                knowledge.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-                await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
-                break;
-				//case WorkflowModuleConsts.OrderScreen:
-				//    var screen = await _orderScreenRepository.Queryable().Includes(x => x.Order)
-				//        .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
-				//    if (screen != null)
-				//    {
-				//        screen.Status = EScreenStatus.Approval;
-				//        screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-				//        //如果下个节点是省审批,则修改为省甄别
-				//        if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org && nextTag.Value == TagDefaults.TagValue.Province)
-				//            screen.IsProScreen = true;
-				//        await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
-				//    }
+                    break;
+                case WorkflowModuleConsts.KnowledgeAdd:
+                case WorkflowModuleConsts.KnowledgeUpdate:
+                case WorkflowModuleConsts.KnowledgeDelete:
+                    var knowledgeWork = await _knowledgeWorkFlowRepository.Queryable().Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
+                    var knowledge = await _knowledgeRepository.Queryable().Where(x => x.Id == knowledgeWork.KnowledgeId).FirstAsync(cancellationToken);
+                    knowledge.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                    await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
+                    break;
+                //case WorkflowModuleConsts.OrderScreen:
+                //    var screen = await _orderScreenRepository.Queryable().Includes(x => x.Order)
+                //        .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
+                //    if (screen != null)
+                //    {
+                //        screen.Status = EScreenStatus.Approval;
+                //        screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                //        //如果下个节点是省审批,则修改为省甄别
+                //        if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org && nextTag.Value == TagDefaults.TagValue.Province)
+                //            screen.IsProScreen = true;
+                //        await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
+                //    }
 
-				//    if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org)
-				//    {
-				//        switch (nextTag.Value)
-				//        {
-				//            case TagDefaults.TagValue.Province:
-				//                if (screen != null)
-				//                {
-				//                    var screenDto = _mapper.Map<OrderScreenListDto>(screen);
-				//                    if (screen.Order != null && screen.Order.Source == ESource.ProvinceStraight)
-				//                    {
-				//                        var screenOrderDto = _mapper.Map<OrderDto>(screen.Order);
-				//                        //推省上
-				//                        _capPublisher.Publish(EventNames.HotlineOrderScreenApply, new PublishScreenDto()
-				//                        {
-				//                            Order = screenOrderDto,
-				//                            Screen = screenDto,
-				//                            ClientGuid = ""
-				//                        });
-				//                        //try
-				//                        //{
-				//                        //    await _provinceService.ScreenCaseInfoSend(new PublishScreenDto()
-				//                        //    {
-				//                        //        Order = screenOrderDto,
-				//                        //        Screen = screenDto,
-				//                        //        ClientGuid = ""
-				//                        //    }, cancellationToken);
-				//                        //}
-				//                        //catch (Exception e)
-				//                        //{
-				//                        //    _logger.LogError(
-				//                        //        "_provinceService.ScreenCaseInfoSend throw exception: {ex}", e.Message);
-				//                        //}
-				//                    }
-				//                }
+                //    if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org)
+                //    {
+                //        switch (nextTag.Value)
+                //        {
+                //            case TagDefaults.TagValue.Province:
+                //                if (screen != null)
+                //                {
+                //                    var screenDto = _mapper.Map<OrderScreenListDto>(screen);
+                //                    if (screen.Order != null && screen.Order.Source == ESource.ProvinceStraight)
+                //                    {
+                //                        var screenOrderDto = _mapper.Map<OrderDto>(screen.Order);
+                //                        //推省上
+                //                        _capPublisher.Publish(EventNames.HotlineOrderScreenApply, new PublishScreenDto()
+                //                        {
+                //                            Order = screenOrderDto,
+                //                            Screen = screenDto,
+                //                            ClientGuid = ""
+                //                        });
+                //                        //try
+                //                        //{
+                //                        //    await _provinceService.ScreenCaseInfoSend(new PublishScreenDto()
+                //                        //    {
+                //                        //        Order = screenOrderDto,
+                //                        //        Screen = screenDto,
+                //                        //        ClientGuid = ""
+                //                        //    }, cancellationToken);
+                //                        //}
+                //                        //catch (Exception e)
+                //                        //{
+                //                        //    _logger.LogError(
+                //                        //        "_provinceService.ScreenCaseInfoSend throw exception: {ex}", e.Message);
+                //                        //}
+                //                    }
+                //                }
 
-				//                break;
-				//        }
-				//    }
+                //                break;
+                //        }
+                //    }
 
-				//OrderScreenDetail detail = new OrderScreenDetail
-				//{
-				//	ScreenId = screen.Id
-				//};
-				//detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 1);
-				//await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);
+                //OrderScreenDetail detail = new OrderScreenDetail
+                //{
+                //	ScreenId = screen.Id
+                //};
+                //detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 1);
+                //await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);
                 //break;
-            case WorkflowModuleConsts.OrderDelay:
-	            var orderDelay = await _orderDelayRepository.Queryable().Includes(x => x.Order)
-		            .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
-	            if (orderDelay != null)
-	            {
-                    orderDelay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-                    await _orderDelayRepository.UpdateAsync(orderDelay, cancellationToken);
-                }
+                case WorkflowModuleConsts.OrderDelay:
+                    var orderDelay = await _orderDelayRepository.Queryable().Includes(x => x.Order)
+                        .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
+                    if (orderDelay != null)
+                    {
+                        orderDelay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                        await _orderDelayRepository.UpdateAsync(orderDelay, cancellationToken);
+                    }
 
 
-                if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org)
-                {
-                    switch (nextTag.Value)
+                    if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org)
                     {
-                        case TagDefaults.TagValue.Province:
-                            //TODO 发起省延期审批
-                            //var orderDelay = await _orderDelayRepository.Queryable().Includes(x => x.Order)
-                            //    .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
-                            try
-                            {
-                                if (orderDelay != null)
+                        switch (nextTag.Value)
+                        {
+                            case TagDefaults.TagValue.Province:
+                                //TODO 发起省延期审批
+                                //var orderDelay = await _orderDelayRepository.Queryable().Includes(x => x.Order)
+                                //    .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
+                                try
                                 {
-                                    orderDelay.DelayApplyType = EDelayApplyType.ProvinceApply;
-                                    orderDelay.IsProDelay = true;
-                                    await _orderDelayRepository.UpdateAsync(orderDelay);
-                                    //推送
-                                    var publishOrderDelay = _mapper.Map<PublishOrderDelayDto>(orderDelay);
-                                    await _capPublisher.PublishAsync(EventNames.HotlineOrderApplyDelay, publishOrderDelay, cancellationToken: cancellationToken);
+                                    if (orderDelay != null)
+                                    {
+                                        orderDelay.DelayApplyType = EDelayApplyType.ProvinceApply;
+                                        orderDelay.IsProDelay = true;
+                                        await _orderDelayRepository.UpdateAsync(orderDelay);
+                                        //推送
+                                        var publishOrderDelay = _mapper.Map<PublishOrderDelayDto>(orderDelay);
+                                        await _capPublisher.PublishAsync(EventNames.HotlineOrderApplyDelay, publishOrderDelay, cancellationToken: cancellationToken);
 
-                                    //await _provinceService.DelayCaseInfoSend(publishOrderDelay, cancellationToken);
+                                        //await _provinceService.DelayCaseInfoSend(publishOrderDelay, cancellationToken);
+                                    }
+                                }
+                                catch (Exception e)
+                                {
+                                    _logger.LogError("_provinceService.DelayCaseInfoSend throw exception: {ex}",
+                                        e.Message);
                                 }
-                            }
-                            catch (Exception e)
-                            {
-                                _logger.LogError("_provinceService.DelayCaseInfoSend throw exception: {ex}",
-                                    e.Message);
-                            }
 
-                            break;
+                                break;
+                        }
                     }
-                }
 
-                break;
+                    break;
+            }
+
+        }
+        catch (Exception e)
+        {
+            _logger.LogError($"{nameof(WorkflowNextHandler)}异常,{e}");
+            throw;
         }
     }
 }

+ 113 - 104
src/Hotline.Application/Handlers/FlowEngine/WorkflowPreviousHandler.cs

@@ -36,7 +36,7 @@ namespace Hotline.Application.Handlers.FlowEngine
         private readonly ISessionContext _sessionContext;
         private readonly IRepository<OrderScreenDetail> _orderScreenDetailRepository;
 
-		public WorkflowPreviousHandler(
+        public WorkflowPreviousHandler(
             IOrderDomainService orderDomainService,
             IOrderRepository orderRepository,
             IOrderScreenRepository orderScreenRepository,
@@ -50,7 +50,7 @@ namespace Hotline.Application.Handlers.FlowEngine
             IMediator mediator,
             ISessionContext sessionContext,
             IRepository<OrderScreenDetail> orderScreenDetailRepository
-			)
+            )
         {
             _orderDomainService = orderDomainService;
             _orderRepository = orderRepository;
@@ -65,125 +65,134 @@ namespace Hotline.Application.Handlers.FlowEngine
             _orderDelayRepository = orderDelayRepository;
             _sessionContext = sessionContext;
             _orderScreenDetailRepository = orderScreenDetailRepository;
-		}
+        }
 
         /// <summary>Handles a notification</summary>
         /// <param name="notification">The notification</param>
         /// <param name="cancellationToken">Cancellation token</param>
         public async Task Handle(PreviousNotify notification, CancellationToken cancellationToken)
         {
-            var workflow = notification.Workflow;
-            var data = notification.Dto;
-
-            switch (workflow.ModuleCode)
+            try
             {
-                case WorkflowModuleConsts.OrderHandle:
-                    var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true, withAcceptor: true,
-                        withExtension: true, cancellationToken: cancellationToken);
-                    order.CheckIfFiled();
-                    //order.UpdateHandlingStatus(workflow.IsInCountersign);
-					_mapper.Map(workflow, order);
-                    if (notification.TargetStep.StepType is EStepType.Start)
-                    {
-	                    order.Status = EOrderStatus.BackToUnAccept;
-                        //order.BackToUnsign();
-                    }
-                    else
-					{
-                        order.Status = EOrderStatus.SendBack;
-                    }
+                var workflow = notification.Workflow;
+                var data = notification.Dto;
 
-                    await _orderRepository.UpdateAsync(order, cancellationToken);
-                    //if (notification.IsOrgToCenter)
-                    //{
-                    //    var expiredTimeConfig = _timeLimitDomainService.CalcExpiredTime(DateTime.Now, EFlowDirection.OrgToCenter, order.AcceptTypeCode);
+                switch (workflow.ModuleCode)
+                {
+                    case WorkflowModuleConsts.OrderHandle:
+                        var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true, withAcceptor: true,
+                            withExtension: true, cancellationToken: cancellationToken);
+                        order.CheckIfFiled();
+                        //order.UpdateHandlingStatus(workflow.IsInCountersign);
+                        _mapper.Map(workflow, order);
+                        if (notification.TargetStep.StepType is EStepType.Start)
+                        {
+                            order.Status = EOrderStatus.BackToUnAccept;
+                            //order.BackToUnsign();
+                        }
+                        else
+                        {
+                            order.Status = EOrderStatus.SendBack;
+                        }
 
-                    //    await _workflowDomainService.UpdateExpiredTimeAsync(workflow, expiredTimeConfig.ExpiredTime,
-                    //        expiredTimeConfig.TimeText, expiredTimeConfig.Count, expiredTimeConfig.TimeType, expiredTimeConfig.NearlyExpiredTime, cancellationToken);
+                        await _orderRepository.UpdateAsync(order, cancellationToken);
+                        //if (notification.IsOrgToCenter)
+                        //{
+                        //    var expiredTimeConfig = _timeLimitDomainService.CalcExpiredTime(DateTime.Now, EFlowDirection.OrgToCenter, order.AcceptTypeCode);
 
-                    //    var dto = _mapper.Map<OrderDto>(order);
-                    //    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, dto, cancellationToken: cancellationToken);
-                    //    //try
-                    //    //{
-                    //    //    await _provinceService.HotlineOrderFlowRecalled(dto, cancellationToken);
-                    //    //}
-                    //    //catch (Exception e)
-                    //    //{
-                    //    //    _logger.LogError("_provinceService.HotlineOrderFlowRecalled throw exception: {ex}",
-                    //    //        e.Message);
-                    //    //}
-                    //}
-                    if (notification.Dto.AcceptSms)
-                    {
-                        var targetStep = notification.TargetStep;
+                        //    await _workflowDomainService.UpdateExpiredTimeAsync(workflow, expiredTimeConfig.ExpiredTime,
+                        //        expiredTimeConfig.TimeText, expiredTimeConfig.Count, expiredTimeConfig.TimeType, expiredTimeConfig.NearlyExpiredTime, cancellationToken);
 
-                        switch (targetStep.HandlerType)
+                        //    var dto = _mapper.Map<OrderDto>(order);
+                        //    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, dto, cancellationToken: cancellationToken);
+                        //    //try
+                        //    //{
+                        //    //    await _provinceService.HotlineOrderFlowRecalled(dto, cancellationToken);
+                        //    //}
+                        //    //catch (Exception e)
+                        //    //{
+                        //    //    _logger.LogError("_provinceService.HotlineOrderFlowRecalled throw exception: {ex}",
+                        //    //        e.Message);
+                        //    //}
+                        //}
+                        if (notification.Dto.AcceptSms)
                         {
-                            case EHandlerType.Role:
-                            case EHandlerType.AssignedUser:
-                                var users = await _userRepository.Queryable()
-                                    .Where(d => targetStep.Handlers.Select(x => x.Key).Contains(d.Id))
-                                    .ToListAsync(cancellationToken);
-                                foreach (var user in users)
-                                {
-                                    if (!string.IsNullOrEmpty(user.PhoneNo))
+                            var targetStep = notification.TargetStep;
+
+                            switch (targetStep.HandlerType)
+                            {
+                                case EHandlerType.Role:
+                                case EHandlerType.AssignedUser:
+                                    var users = await _userRepository.Queryable()
+                                        .Where(d => targetStep.Handlers.Select(x => x.Key).Contains(d.Id))
+                                        .ToListAsync(cancellationToken);
+                                    foreach (var user in users)
                                     {
-                                        var messageDto = new MessageDto()
+                                        if (!string.IsNullOrEmpty(user.PhoneNo))
                                         {
-                                            PushBusiness = EPushBusiness.OrderSendBack,
-                                            ExternalId = order.Id,
-                                            OrderId = order.Id,
-                                            PushPlatform = EPushPlatform.Sms,
-                                            Remark = order.Title,
-                                            Name = user.Name,
-                                            TemplateCode = "1004",
-                                            Params = new List<string>() { order.No },
-                                            TelNumber = user.PhoneNo,
-                                        };
-                                        await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
+                                            var messageDto = new MessageDto()
+                                            {
+                                                PushBusiness = EPushBusiness.OrderSendBack,
+                                                ExternalId = order.Id,
+                                                OrderId = order.Id,
+                                                PushPlatform = EPushPlatform.Sms,
+                                                Remark = order.Title,
+                                                Name = user.Name,
+                                                TemplateCode = "1004",
+                                                Params = new List<string>() { order.No },
+                                                TelNumber = user.PhoneNo,
+                                            };
+                                            await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
+                                        }
                                     }
-                                }
-                                break;
-                            case EHandlerType.OrgLevel:
-                            case EHandlerType.OrgType:
-                            case EHandlerType.AssignedOrg:
-                                //todo 部门经办人联系方式
-                                break;
-                            default:
-                                throw new ArgumentOutOfRangeException();
+                                    break;
+                                case EHandlerType.OrgLevel:
+                                case EHandlerType.OrgType:
+                                case EHandlerType.AssignedOrg:
+                                    //todo 部门经办人联系方式
+                                    break;
+                                default:
+                                    throw new ArgumentOutOfRangeException();
+                            }
+                        }
+
+
+                        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);
+                            await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
+                        }
+                        break;
+                    case WorkflowModuleConsts.OrderScreen:
+                        var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
+                        if (screen != null)
+                        {
+                            screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                            screen.SendBackTime = DateTime.Now;
+                            await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
                         }
-                    }
-                   
+                        OrderScreenDetail detail = new OrderScreenDetail
+                        {
+                            ScreenId = screen.Id
+                        };
+                        detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 2);
+                        await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);
+                        break;
+                    case WorkflowModuleConsts.KnowledgeAdd:
+                    case WorkflowModuleConsts.KnowledgeUpdate:
+                    case WorkflowModuleConsts.KnowledgeDelete:
+                    case WorkflowModuleConsts.TelRestApply:
+                        break;
+                }
 
-                    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);
-                        await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
-                    }
-                    break;
-                case WorkflowModuleConsts.OrderScreen:
-                    var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
-                    if (screen != null)
-                    {
-                        screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-                        screen.SendBackTime = DateTime.Now;
-                        await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
-                    }
-					OrderScreenDetail detail = new OrderScreenDetail
-					{
-						ScreenId = screen.Id
-					};
-					detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 2);
-                    await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);
-					break;
-                case WorkflowModuleConsts.KnowledgeAdd:
-                case WorkflowModuleConsts.KnowledgeUpdate:
-                case WorkflowModuleConsts.KnowledgeDelete:
-                case WorkflowModuleConsts.TelRestApply:
-                    break;
+            }
+            catch (Exception e)
+            {
+                _logger.LogError($"{nameof(WorkflowPreviousHandler)}异常,{e}");
+                throw;
             }
         }
     }

+ 70 - 62
src/Hotline.Application/Handlers/FlowEngine/WorkflowRecallHandler.cs

@@ -66,70 +66,78 @@ public class WorkflowRecallHandler : INotificationHandler<RecallNotify>
     /// <param name="cancellationToken">Cancellation token</param>
     public async Task Handle(RecallNotify notification, CancellationToken cancellationToken)
     {
-        var workflow = notification.Workflow;
-        var data = notification.Dto;
-
-        switch (workflow.ModuleCode)
+        try
         {
-            case WorkflowModuleConsts.OrderHandle:
-                var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true, withAcceptor: true,
-                    withExtension: true, cancellationToken: cancellationToken);
-                //order.UpdateHandlingStatus(workflow.IsInCountersign);
-				_mapper.Map(workflow, order);
-                if (notification.TargetStep.StepType is EStepType.Start)
-                {
-                    //if (!bool.TryParse(
-                    //        _systemSettingCacheManager.GetSetting(SettingConstants.IsRecallToSeatDesignated)?.SettingValue[0],
-                    //        out var isRecallToSeatDesignated))
-                    //    isRecallToSeatDesignated = false;
-                    //var isRecallToSeatDesignated = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsRecallToSeatDesignated).SettingValue[0]);
-                    order.Status = EOrderStatus.SpecialToUnAccept;
-                    order.FileEmpty();
-					//if (isRecallToSeatDesignated)
-					//{
-					//    if (data.HandlerType is EHandlerType.Role or EHandlerType.AssignedUser)
-					//    {
-					//        var handler = data.NextHandlers.FirstOrDefault();
-					//        if (handler != null)
-					//        {
-					//            order.SignerId = handler.Key;
-					//            order.SignerName = handler.Value;
-					//        }
-					//    }
-					//}
-					//else
-					//{
-					//    //order.BackToUnsign();
-					//}
-				}
-                await _orderRepository.UpdateAsync(order, false, cancellationToken);
-                var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == order.Id, cancellationToken);
-                if (publish != null)
-                {
-	                var publishHistory = _mapper.Map<OrderPublishHistory>(publish);
-	                publishHistory.OrderPublishId = publish.Id;
-	                publishHistory.ArrangeTitleAfter = publish.ArrangeTitle;
-	                publishHistory.ArrangeTitleBefor = publish.ArrangeTitle;
-	                publishHistory.ArrangeContentAfter = publish.ArrangeContent;
-	                publishHistory.ArrangeContentBefor = publish.ArrangeContent;
-	                publishHistory.ArrangeOpinionAfter = publish.ArrangeOpinion;
-	                publishHistory.ArrangeOpinionBefor = publish.ArrangeOpinion;
-	                await _orderPublishHistoryRepository.AddAsync(publishHistory, cancellationToken);
-	                await _orderPublishRepository.RemoveAsync(publish, false, cancellationToken);
-                }
+            var workflow = notification.Workflow;
+            var data = notification.Dto;
+
+            switch (workflow.ModuleCode)
+            {
+                case WorkflowModuleConsts.OrderHandle:
+                    var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true, withAcceptor: true,
+                        withExtension: true, cancellationToken: cancellationToken);
+                    //order.UpdateHandlingStatus(workflow.IsInCountersign);
+                    _mapper.Map(workflow, order);
+                    if (notification.TargetStep.StepType is EStepType.Start)
+                    {
+                        //if (!bool.TryParse(
+                        //        _systemSettingCacheManager.GetSetting(SettingConstants.IsRecallToSeatDesignated)?.SettingValue[0],
+                        //        out var isRecallToSeatDesignated))
+                        //    isRecallToSeatDesignated = false;
+                        //var isRecallToSeatDesignated = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsRecallToSeatDesignated).SettingValue[0]);
+                        order.Status = EOrderStatus.SpecialToUnAccept;
+                        order.FileEmpty();
+                        //if (isRecallToSeatDesignated)
+                        //{
+                        //    if (data.HandlerType is EHandlerType.Role or EHandlerType.AssignedUser)
+                        //    {
+                        //        var handler = data.NextHandlers.FirstOrDefault();
+                        //        if (handler != null)
+                        //        {
+                        //            order.SignerId = handler.Key;
+                        //            order.SignerName = handler.Value;
+                        //        }
+                        //    }
+                        //}
+                        //else
+                        //{
+                        //    //order.BackToUnsign();
+                        //}
+                    }
+                    await _orderRepository.UpdateAsync(order, false, cancellationToken);
+                    var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == order.Id, cancellationToken);
+                    if (publish != null)
+                    {
+                        var publishHistory = _mapper.Map<OrderPublishHistory>(publish);
+                        publishHistory.OrderPublishId = publish.Id;
+                        publishHistory.ArrangeTitleAfter = publish.ArrangeTitle;
+                        publishHistory.ArrangeTitleBefor = publish.ArrangeTitle;
+                        publishHistory.ArrangeContentAfter = publish.ArrangeContent;
+                        publishHistory.ArrangeContentBefor = publish.ArrangeContent;
+                        publishHistory.ArrangeOpinionAfter = publish.ArrangeOpinion;
+                        publishHistory.ArrangeOpinionBefor = publish.ArrangeOpinion;
+                        await _orderPublishHistoryRepository.AddAsync(publishHistory, cancellationToken);
+                        await _orderPublishRepository.RemoveAsync(publish, false, cancellationToken);
+                    }
 
-                var visit = await _orderVisitRepository.GetAsync(x => x.OrderId == order.Id && x.VisitState != EVisitState.None, cancellationToken);
-                if (visit != null)
-                {
-	                visit.VisitState = EVisitState.None;
-	                await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
-                }
-				break;
-            case WorkflowModuleConsts.KnowledgeAdd:
-            case WorkflowModuleConsts.KnowledgeUpdate:
-            case WorkflowModuleConsts.KnowledgeDelete:
-            case WorkflowModuleConsts.TelRestApply:
-                break;
+                    var visit = await _orderVisitRepository.GetAsync(x => x.OrderId == order.Id && x.VisitState != EVisitState.None, cancellationToken);
+                    if (visit != null)
+                    {
+                        visit.VisitState = EVisitState.None;
+                        await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
+                    }
+                    break;
+                case WorkflowModuleConsts.KnowledgeAdd:
+                case WorkflowModuleConsts.KnowledgeUpdate:
+                case WorkflowModuleConsts.KnowledgeDelete:
+                case WorkflowModuleConsts.TelRestApply:
+                    break;
+            }
+        }
+        catch (Exception e)
+        {
+            _logger.LogError($"{nameof(WorkflowEndHandler)}异常,{e}");
+            throw;
         }
     }
 }

+ 137 - 128
src/Hotline.Application/Handlers/FlowEngine/WorkflowStartHandler.cs

@@ -84,73 +84,98 @@ namespace Hotline.Application.Handlers.FlowEngine
         /// <param name="cancellationToken">Cancellation token</param>
         public async Task Handle(StartWorkflowNotify notification, CancellationToken cancellationToken)
         {
-            //基础拉丁字母和中日韩统一表意文字的基础Unicode 块(U+4E00-U+9FCC)。 基本涵盖了除使用西里尔字母以外所有西方国家的文字和亚洲中日韩越的文字
-            _logger.LogInformation(
-                //$"收到{nameof(StartWorkflowNotify)}, notification: {JsonSerializer.Serialize(notification, new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs) })}");
-                $"收到{nameof(StartWorkflowNotify)}, workflowId: {notification.Workflow.Id}");
-            var workflow = notification.Workflow;
-            var data = notification.Dto;
-
-            switch (workflow.ModuleCode)
+            try
             {
-                case WorkflowModuleConsts.OrderHandle:
-                    var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true, withAcceptor: true,
-                        withExtension: true, cancellationToken);
-                    order.CheckIfFiled();
-					//order.StartManageFlow();
-					order.UpdateHandlingStatus(workflow.IsInCountersign);
-					_mapper.Map(workflow, order);
-                    await _orderRepository.UpdateAsync(order, cancellationToken);
-
-                    var publishCallRecordDto = new PublishCallRecrodDto() { };
-                    //查询通话记录
-                    //var callRecord = await _trCallRecordRepository.GetAsync(p => p.CallAccept == order.CallId, cancellationToken); //由CallAccept改为OtherAccept
-                    // var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
-                    // if (callRecord != null)
-                    // {
-                    //     publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
-                    // }
-
-                    if (order.SourceChannelCode == AppDefaults.SourceChannel.DianHua &&
-                        !string.IsNullOrEmpty(order.CallId))
-                    {
-                        if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.TianRun)
+                //基础拉丁字母和中日韩统一表意文字的基础Unicode 块(U+4E00-U+9FCC)。 基本涵盖了除使用西里尔字母以外所有西方国家的文字和亚洲中日韩越的文字
+                _logger.LogInformation(
+                    //$"收到{nameof(StartWorkflowNotify)}, notification: {JsonSerializer.Serialize(notification, new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs) })}");
+                    $"收到{nameof(StartWorkflowNotify)}, workflowId: {notification.Workflow.Id}");
+                var workflow = notification.Workflow;
+                var data = notification.Dto;
+
+                switch (workflow.ModuleCode)
+                {
+                    case WorkflowModuleConsts.OrderHandle:
+                        var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true, withAcceptor: true,
+                            withExtension: true, cancellationToken);
+                        order.CheckIfFiled();
+                        //order.StartManageFlow();
+                        order.UpdateHandlingStatus(workflow.IsInCountersign);
+                        _mapper.Map(workflow, order);
+                        await _orderRepository.UpdateAsync(order, cancellationToken);
+
+                        var publishCallRecordDto = new PublishCallRecrodDto() { };
+                        //查询通话记录
+                        //var callRecord = await _trCallRecordRepository.GetAsync(p => p.CallAccept == order.CallId, cancellationToken); //由CallAccept改为OtherAccept
+                        // var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
+                        // if (callRecord != null)
+                        // {
+                        //     publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
+                        // }
+
+                        if (order.SourceChannelCode == AppDefaults.SourceChannel.DianHua &&
+                            !string.IsNullOrEmpty(order.CallId))
                         {
-                            // var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
-                            var callRecord = await _callApplication.GetTianrunCallAsync(order?.CallId, cancellationToken);
-                            if (callRecord != null)
+                            if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.TianRun)
                             {
-                                publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
+                                // var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
+                                var callRecord = await _callApplication.GetTianrunCallAsync(order?.CallId, cancellationToken);
+                                if (callRecord != null)
+                                {
+                                    publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
+                                }
+                            }
+                            else if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.XingTang)
+                            {
+                                var call = await _callApplication.GetCallAsync(order?.CallId, cancellationToken);
+                                if (call is not null)
+                                    publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(call);
                             }
                         }
-                        else if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.XingTang)
-                        {
-                            var call = await _callApplication.GetCallAsync(order?.CallId, cancellationToken);
-                            if (call is not null)
-                                publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(call);
-                        }
-                    }
 
 
-                    publishCallRecordDto.Order = _mapper.Map<OrderDto>(order);
-                    publishCallRecordDto.WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace);
+                        publishCallRecordDto.Order = _mapper.Map<OrderDto>(order);
+                        publishCallRecordDto.WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace);
 
-                    await _capPublisher.PublishAsync(EventNames.HotlineOrderFlowStarted, publishCallRecordDto,
-                        cancellationToken: cancellationToken);
+                        await _capPublisher.PublishAsync(EventNames.HotlineOrderFlowStarted, publishCallRecordDto,
+                            cancellationToken: cancellationToken);
 
-                    try
-                    {
-                        if (notification.Dto.IsSms)
+                        try
                         {
-                            switch (notification.FlowAssignInfo.FlowAssignType)
+                            if (notification.Dto.IsSms)
                             {
-                                case EFlowAssignType.Org:
-                                    var orgCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
-                                    var orgList = await _userRepository.Queryable().Where(x =>
-                                        orgCodes.Contains(x.OrgId) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e")).ToListAsync();
-                                    foreach (var item in orgList)
-                                    {
-                                        if (!string.IsNullOrEmpty(item.PhoneNo))
+                                switch (notification.FlowAssignInfo.FlowAssignType)
+                                {
+                                    case EFlowAssignType.Org:
+                                        var orgCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
+                                        var orgList = await _userRepository.Queryable().Where(x =>
+                                            orgCodes.Contains(x.OrgId) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e")).ToListAsync();
+                                        foreach (var item in orgList)
+                                        {
+                                            if (!string.IsNullOrEmpty(item.PhoneNo))
+                                            {
+                                                var messageDto = new Share.Dtos.Push.MessageDto
+                                                {
+                                                    PushBusiness = EPushBusiness.OrderSupervise,
+                                                    ExternalId = order.Id,
+                                                    OrderId = order.Id,
+                                                    PushPlatform = EPushPlatform.Sms,
+                                                    Remark = order.Title,
+                                                    Name = item.Name,
+                                                    TemplateCode = "1007",
+                                                    Params = new List<string>() { order.No },
+                                                    TelNumber = item.PhoneNo,
+                                                };
+                                                await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
+                                            }
+                                        }
+
+                                        break;
+                                    case EFlowAssignType.User:
+                                        var userCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
+                                        var userList = await _userRepository.Queryable().Where(x =>
+                                            userCodes.Contains(x.Id) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e")).ToListAsync();
+                                        foreach (var item in userList)
                                         {
                                             var messageDto = new Share.Dtos.Push.MessageDto
                                             {
@@ -166,80 +191,64 @@ namespace Hotline.Application.Handlers.FlowEngine
                                             };
                                             await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
                                         }
-                                    }
-
-                                    break;
-                                case EFlowAssignType.User:
-                                    var userCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
-                                    var userList = await _userRepository.Queryable().Where(x =>
-                                        userCodes.Contains(x.Id) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e")).ToListAsync();
-                                    foreach (var item in userList)
-                                    {
-                                        var messageDto = new Share.Dtos.Push.MessageDto
-                                        {
-                                            PushBusiness = EPushBusiness.OrderSupervise,
-                                            ExternalId = order.Id,
-                                            OrderId = order.Id,
-                                            PushPlatform = EPushPlatform.Sms,
-                                            Remark = order.Title,
-                                            Name = item.Name,
-                                            TemplateCode = "1007",
-                                            Params = new List<string>() { order.No },
-                                            TelNumber = item.PhoneNo,
-                                        };
-                                        await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
-                                    }
-
-                                    break;
-                                default:
-                                    break;
+
+                                        break;
+                                    default:
+                                        break;
+                                }
                             }
                         }
-                    }
-                    catch(Exception e)
-                    {
-                        _logger.LogError($"发送短信失败! orderId: {order.Id},\r\n{e.Message}");
-                    }
-
-                    try
-                    {
-                        //写入质检
-                        await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
-                    }
-                    catch (Exception e)
-                    {
-                        _logger.LogError($"写入质检异常!orderId: {order.Id}, \r\n{e.Message}");
-                    }
-                    break;
-                case WorkflowModuleConsts.KnowledgeAdd:
-                case WorkflowModuleConsts.KnowledgeUpdate:
-                case WorkflowModuleConsts.KnowledgeDelete:
-                    await _knowledgeDomainService.UpdateWorkFlowId(workflow.ExternalId, workflow.Id,
-                        workflow.HandlerUsers, workflow.HandlerOrgs, workflow.FlowedUserIds, workflow.FlowedOrgIds,
-                        cancellationToken);
-                    break;
-                //case WorkflowModuleConsts.OrderScreen:
-                //    var screen = await _orderScreenRepository.Queryable().Includes(x => x.Order)
-                //        .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
-                //    if (screen != null)
-                //    {
-                //        screen.WorkflowId = workflow.Id;
-                //        screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-                //        await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
-                //    }
-
-                //    break;
-                case WorkflowModuleConsts.OrderDelay:
-                    var orderDelay = await _orderDelayRepository.Queryable()
-                        .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
-                    if (orderDelay != null)
-                    {
-                        orderDelay.WorkflowId = workflow.Id;
-                        orderDelay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-                        await _orderDelayRepository.UpdateAsync(orderDelay, cancellationToken);
-                    }
-
-                    break;
+                        catch (Exception e)
+                        {
+                            _logger.LogError($"发送短信失败! orderId: {order.Id},\r\n{e.Message}");
+                        }
+
+                        try
+                        {
+                            //写入质检
+                            await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
+                        }
+                        catch (Exception e)
+                        {
+                            _logger.LogError($"写入质检异常!orderId: {order.Id}, \r\n{e.Message}");
+                        }
+                        break;
+                    case WorkflowModuleConsts.KnowledgeAdd:
+                    case WorkflowModuleConsts.KnowledgeUpdate:
+                    case WorkflowModuleConsts.KnowledgeDelete:
+                        await _knowledgeDomainService.UpdateWorkFlowId(workflow.ExternalId, workflow.Id,
+                            workflow.HandlerUsers, workflow.HandlerOrgs, workflow.FlowedUserIds, workflow.FlowedOrgIds,
+                            cancellationToken);
+                        break;
+                    //case WorkflowModuleConsts.OrderScreen:
+                    //    var screen = await _orderScreenRepository.Queryable().Includes(x => x.Order)
+                    //        .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
+                    //    if (screen != null)
+                    //    {
+                    //        screen.WorkflowId = workflow.Id;
+                    //        screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                    //        await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
+                    //    }
+
+                    //    break;
+                    case WorkflowModuleConsts.OrderDelay:
+                        var orderDelay = await _orderDelayRepository.Queryable()
+                            .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
+                        if (orderDelay != null)
+                        {
+                            orderDelay.WorkflowId = workflow.Id;
+                            orderDelay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                            await _orderDelayRepository.UpdateAsync(orderDelay, cancellationToken);
+                        }
+
+                        break;
+                }
+
+            }
+            catch (Exception e)
+            {
+                _logger.LogError($"{nameof(WorkflowStartHandler)}异常,{e}");
+                throw;
             }
         }
     }

+ 21 - 10
src/Hotline.Application/Handlers/FlowEngine/WorkflowTerminalHandler.cs

@@ -2,16 +2,21 @@
 using Hotline.FlowEngine.WorkflowModules;
 using Hotline.KnowledgeBase;
 using MediatR;
+using Microsoft.Extensions.Logging;
 
 namespace Hotline.Application.Handlers.FlowEngine;
 
 public class WorkflowTerminalHandler : INotificationHandler<TerminalWorkflowNotify>
 {
-
     private readonly IKnowledgeDomainService _knowledgeDomainService;
-    public WorkflowTerminalHandler(IKnowledgeDomainService knowledgeDomainService)
+    private readonly ILogger<WorkflowTerminalHandler> _logger;
+
+    public WorkflowTerminalHandler(
+        IKnowledgeDomainService knowledgeDomainService,
+        ILogger<WorkflowTerminalHandler> logger)
     {
         _knowledgeDomainService = knowledgeDomainService;
+        _logger = logger;
     }
 
     /// <summary>Handles a notification</summary>
@@ -19,16 +24,22 @@ public class WorkflowTerminalHandler : INotificationHandler<TerminalWorkflowNoti
     /// <param name="cancellationToken">Cancellation token</param>
     public async Task Handle(TerminalWorkflowNotify notification, CancellationToken cancellationToken)
     {
-        var workflow = notification.Workflow;
-
-        switch (workflow.ModuleCode)
+        try
         {
-            case WorkflowModuleConsts.KnowledgeAdd://新增知识库
-            case WorkflowModuleConsts.KnowledgeDelete://删除知识库
-                await _knowledgeDomainService.TerminateWorkKnowledge(workflow, cancellationToken);
-                break;
-
+            var workflow = notification.Workflow;
 
+            switch (workflow.ModuleCode)
+            {
+                case WorkflowModuleConsts.KnowledgeAdd://新增知识库
+                case WorkflowModuleConsts.KnowledgeDelete://删除知识库
+                    await _knowledgeDomainService.TerminateWorkKnowledge(workflow, cancellationToken);
+                    break;
+            }
+        }
+        catch (Exception e)
+        {
+            _logger.LogError($"{nameof(WorkflowTerminalHandler)}异常,{e}");
+            throw;
         }
     }
 }

+ 8 - 3
src/Hotline/Settings/SettingConstants.cs

@@ -323,13 +323,13 @@ namespace Hotline.Settings
         /// </summary>
         public const string CallOutContentKey = "CallOutContentKey";
 
-		#endregion
-		#endregion
+        #endregion
+        #endregion
 
         /// <summary>
         /// 录音文件前缀地址
         /// </summary>
-		public const string ViteRecordPrefix = "ViteRecordPrefix";
+        public const string ViteRecordPrefix = "ViteRecordPrefix";
 
         /// <summary>
         /// 派单员角色
@@ -374,5 +374,10 @@ namespace Hotline.Settings
         /// 智能语音URL头
         /// </summary>
         public const string AiVisitVoiceBaseUrl = "AiVisitVoiceBaseUrl";
+
+        /// <summary>
+        /// 是否开启应急管理局推送业务
+        /// </summary>
+        public const string IsOpenContingencyManagement = "IsOpenContingencyManagement";
     }
 }