Sfoglia il codice sorgente

Merge branch 'test' into release

xf 1 mese fa
parent
commit
88199eb92b
62 ha cambiato i file con 1679 aggiunte e 698 eliminazioni
  1. 2 1
      src/Hotline.Api/Controllers/HomeController.cs
  2. 1 1
      src/Hotline.Api/Controllers/KnowledgeController.cs
  3. 86 73
      src/Hotline.Api/Controllers/OrderController.cs
  4. 3 12
      src/Hotline.Api/Controllers/OrderControllers/OrderCarbonCopyController.cs
  5. 1 1
      src/Hotline.Api/Controllers/OrderControllers/OrderComplementController.cs
  6. 1 1
      src/Hotline.Api/Controllers/OrderTerminateController.cs
  7. 106 0
      src/Hotline.Api/Controllers/SpecialController.cs
  8. 4 1
      src/Hotline.Api/Controllers/TestController.cs
  9. 1 1
      src/Hotline.Api/Controllers/WorkflowController.cs
  10. 1 1
      src/Hotline.Api/config/appsettings.Development.json
  11. 102 100
      src/Hotline.Application/FlowEngine/WorkflowApplication.cs
  12. 1 1
      src/Hotline.Application/Orders/Handlers/OrderHandler/AddOrderPushMessageNotifyHandler.cs
  13. 2 7
      src/Hotline.Application/Orders/Handlers/OrderHandler/GetOrderDetailNotifyHandler.cs
  14. 1 9
      src/Hotline.Application/Orders/Handlers/OrderHandler/OrderRelateCallHandler.cs
  15. 2 10
      src/Hotline.Application/Orders/Handlers/OrderHandler/OrderVisitSmsHandler.cs
  16. 1 5
      src/Hotline.Application/Orders/Handlers/OrderHandler/TranspondCityNotifyHandler.cs
  17. 1 1
      src/Hotline.Application/Orders/Handlers/OrderHandler/UpdateOrderPushMessageNotifyHandler.cs
  18. 34 3
      src/Hotline.Application/Orders/Handlers/OrderScreenHandler/OrderScreenEndWorkflowHandler.cs
  19. 1 1
      src/Hotline.Application/Orders/Handlers/OrderScreenHandler/OrderScreenNextWorkflowHandler.cs
  20. 1 1
      src/Hotline.Application/Orders/Handlers/OrderScreenHandler/OrderScreenStartWorkflowHandler.cs
  21. 2 16
      src/Hotline.Application/Orders/Handlers/SnapshotHandler/GuiderSystemTimeoutHandler.cs
  22. 7 1
      src/Hotline.Application/Orders/IOrderApplication.cs
  23. 208 90
      src/Hotline.Application/Orders/OrderApplication.cs
  24. 2 2
      src/Hotline.Application/Orders/OrderSecondaryHandlingApplication.cs
  25. 54 0
      src/Hotline.Application/SpecialNumber/ISpecialNumberApplication.cs
  26. 167 0
      src/Hotline.Application/SpecialNumber/SpecialNumberApplication.cs
  27. 2 2
      src/Hotline.Application/StatisticalReport/CallReport/YiBinCallReportApplication.cs
  28. 63 38
      src/Hotline.Application/Subscribers/DatasharingSubscriber.cs
  29. 19 1
      src/Hotline.Repository.SqlSugar/File/FileRepository.cs
  30. 8 3
      src/Hotline.Share/Dtos/FlowEngine/NextStepsDto.cs
  31. 2 0
      src/Hotline.Share/Dtos/Order/OrderVisitDto.cs
  32. 13 1
      src/Hotline.Share/Dtos/Order/QueryOrderDto.cs
  33. 87 0
      src/Hotline.Share/Dtos/Special/SpecialNumberDto.cs
  34. 6 0
      src/Hotline.Share/Enums/FlowEngine/EHandleMode.cs
  35. 3 0
      src/Hotline.Share/Enums/Push/EPushBusiness.cs
  36. 1 1
      src/Hotline.Share/Requests/PagedKeywordRequest.cs
  37. 27 0
      src/Hotline/Article/CircularRecordDomainService.cs
  38. 2 0
      src/Hotline/Article/ICircularRecordDomainService.cs
  39. 0 57
      src/Hotline/Authentications/ChangeSessionProvider.cs
  40. 10 0
      src/Hotline/Authentications/FakeSessionContext.cs
  41. 10 0
      src/Hotline/Authentications/Police110SessionContext.cs
  42. 10 0
      src/Hotline/Authentications/ProvinceSessionContext.cs
  43. 59 19
      src/Hotline/Authentications/SessionContextCreator.cs
  44. 112 0
      src/Hotline/Authentications/SessionContextManager.cs
  45. 85 7
      src/Hotline/Authentications/SessionContextProvider.cs
  46. 10 0
      src/Hotline/Authentications/YbEnterpriseSessionContext.cs
  47. 10 0
      src/Hotline/Authentications/ZzptSessionContext.cs
  48. 3 1
      src/Hotline/File/IFileRepository.cs
  49. 3 1
      src/Hotline/FlowEngine/Workflows/IWorkflowDomainService.cs
  50. 123 118
      src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs
  51. 1 0
      src/Hotline/FlowEngine/Workflows/WorkflowStep.cs
  52. 12 9
      src/Hotline/Orders/DatabaseEventHandler/OrderVisitDetailEventHandler.cs
  53. 53 50
      src/Hotline/Orders/OrderDomainService.cs
  54. 16 9
      src/Hotline/Orders/OrderVisitDetail.cs
  55. 10 0
      src/Hotline/Settings/SettingConstants.cs
  56. 22 0
      src/Hotline/Special/SpecialNumber.cs
  57. 82 19
      src/XF.Domain/Authentications/DefaultSessionContext.cs
  58. 0 12
      src/XF.Domain/Authentications/IChangeSessionProvider.cs
  59. 3 0
      src/XF.Domain/Authentications/ISessionContext.cs
  60. 8 4
      src/XF.Domain/Authentications/ISessionContextProvider.cs
  61. 12 2
      test/Hotline.Tests/Controller/TestSessionContext.cs
  62. 0 5
      test/Hotline.Tests/Startup.cs

+ 2 - 1
src/Hotline.Api/Controllers/HomeController.cs

@@ -195,7 +195,8 @@ public class HomeController : BaseController
             CallInOpenType = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.CallInOpenType).SettingValue[0]),
             Snapshot = _systemSettingCacheManager.Snapshot,
             IsTelRest = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsTelRest).SettingValue[0]),
-            TelRestNum = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.TelRestNum).SettingValue[0])
+            TelRestNum = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.TelRestNum).SettingValue[0]),
+            IsOpenSpecialPhone = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsOpenSpecialPhone).SettingValue[0])
         };
         return rsp;
     }

+ 1 - 1
src/Hotline.Api/Controllers/KnowledgeController.cs

@@ -505,7 +505,7 @@ namespace Hotline.Api.Controllers
                     nextWorkflowDto.NextStepCode = next.Steps.First().Key;
                     nextWorkflowDto.NextStepName = next.Steps.First().Value;
                     if (dto.IsPass)
-                        await _workflowDomainService.NextAsync(_sessionContext, nextWorkflowDto,
+                        await _workflowDomainService.NextAsync(nextWorkflowDto,
                             cancellationToken: HttpContext.RequestAborted);
                     else
                     {

+ 86 - 73
src/Hotline.Api/Controllers/OrderController.cs

@@ -62,6 +62,7 @@ using Hotline.Validators.FlowEngine;
 using Hotline.YbEnterprise.Sdk;
 using Mapster;
 using MapsterMapper;
+using MathNet.Numerics.LinearAlgebra.Factorization;
 using MediatR;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
@@ -98,6 +99,7 @@ public class OrderController : BaseController
     private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
     private readonly ITypedCache<string> _typeCache;
     private readonly ISessionContext _sessionContext;
+    private readonly ISessionContextManager _sessionContextManager;
     private readonly IMapper _mapper;
     private readonly IMediator _mediator;
     private readonly IRepository<OrderPublish> _orderPublishRepository;
@@ -170,6 +172,7 @@ public class OrderController : BaseController
         IDefinitionDomainService definitionDomainService,
         ISystemDicDataCacheManager sysDicDataCacheManager,
         ISessionContext sessionContext,
+        ISessionContextManager sessionContextManager,
         IMapper mapper,
         IMediator mediator,
         IRepository<OrderPublish> orderPublishRepository,
@@ -244,6 +247,7 @@ public class OrderController : BaseController
         _definitionDomainService = definitionDomainService;
         _sysDicDataCacheManager = sysDicDataCacheManager;
         _sessionContext = sessionContext;
+        _sessionContextManager = sessionContextManager;
         _mapper = mapper;
         _mediator = mediator;
         _orderPublishRepository = orderPublishRepository;
@@ -1968,6 +1972,21 @@ public class OrderController : BaseController
         return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
     }
 
+    /// <summary>
+    /// 工单延期修改延期时限
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpPost("alter_delay_day")]
+    [LogFilter("工单延期修改延期时限")]
+    public async Task AlterDelayDay([FromBody] AlterDelayDayDto dto)
+    {
+        if (dto.DelayNum < 1) throw UserFriendlyException.SameMessage("延期申请天数需大于等于1天!");
+        var deday = await _orderDelayRepository.Queryable().Includes(x => x.Order).FirstAsync(x => x.Id == dto.Id, HttpContext.RequestAborted);
+        if (_appOptions.Value.IsLuZhou && dto.DelayNum > deday.Order.TimeLimitCount) throw UserFriendlyException.SameMessage("申请天数需小于等于工单办理时限!");
+        await _orderDelayRepository.Updateable().SetColumns(x => new OrderDelay { DelayNum = dto.DelayNum }).Where(x => x.Id == dto.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+    }
+
     /// <summary>
     /// 申请延期
     /// </summary>
@@ -2086,7 +2105,7 @@ public class OrderController : BaseController
         try
         {
             dto.NextWorkflow.WorkflowId = delay.WorkflowId;
-            await _workflowDomainService.NextAsync(_sessionContext, dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
+            await _workflowDomainService.NextAsync(dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
         }
         catch (Exception e)
         {
@@ -2184,7 +2203,7 @@ public class OrderController : BaseController
 
                 if (workflow.ReviewResult == EReviewResult.Approval)
                 {
-                    await _workflowDomainService.NextAsync(_sessionContext, workflow, cancellationToken: HttpContext.RequestAborted);
+                    await _workflowDomainService.NextAsync(workflow, cancellationToken: HttpContext.RequestAborted);
                 }
                 else
                 {
@@ -2210,7 +2229,7 @@ public class OrderController : BaseController
     /// <param name="workflowId"></param>
     /// <returns></returns>
     [HttpGet("delay/{workflowId}/nextsteps")]
-    public async Task<NextStepsDto> OrderDelayNextsteps(string workflowId)
+    public async Task<object> OrderDelayNextsteps(string workflowId)
     {
         //var workflow = await _workflowRepository.GetAsync(workflowId, HttpContext.RequestAborted);
         var workflow = await _workflowDomainService.GetWorkflowAsync(workflowId, withDefine: true, withSteps: true,
@@ -2239,7 +2258,7 @@ public class OrderController : BaseController
                         result.Steps.Remove(result.Steps.First(x => x.Value == "中心终审"));
                     }
                 }
-
+                result.IsAlterDay = _appOptions.Value.IsLuZhou && currentStep.Name == "班长审批";
                 return result;
             }
         }
@@ -2491,7 +2510,10 @@ public class OrderController : BaseController
 
         var (total, items) = await _orderApplication.MayScreenList(dto)
             .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
-        return new PagedDto<OrderVisitDetailDto>(total, _mapper.Map<IReadOnlyList<OrderVisitDetailDto>>(items));
+        var data = _mapper.Map<List<OrderVisitDetailDto>>(items);
+        var isAdmin = _orderDomainService.IsCheckAdmin();
+        data.ForEach(d => d.IsShowOperate = isAdmin == true || (d.VisitOrgCode == _sessionContext.OrgId));
+        return new PagedDto<OrderVisitDetailDto>(total, data);
     }
 
     /// <summary>
@@ -2704,8 +2726,7 @@ public class OrderController : BaseController
         {
             dto.NextWorkflow.WorkflowId = screen.WorkflowId;
             //await _workflowApplication.NextAsync(dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
-            await _workflowDomainService.NextAsync(_sessionContext, dto.NextWorkflow,
-                cancellationToken: HttpContext.RequestAborted);
+            await _workflowDomainService.NextAsync(dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
         }
         catch (Exception e)
         {
@@ -3709,6 +3730,7 @@ public class OrderController : BaseController
                 if (acceptTime != null)
                 {
                     order.ActualHandleStepAcceptTime = acceptTime;
+                    order.CurrentStepAcceptTime = acceptTime;
                     await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
                 }
             }
@@ -3947,33 +3969,6 @@ public class OrderController : BaseController
         return _sessionContext.OrgIsCenter ? dto : dto.DataMask();
     }
 
-
-    /// <summary>
-    /// 上传附件
-    /// </summary>
-    /// <param name="dto"></param>
-    /// <returns></returns>
-    //[HttpPost]
-    //[LogFilterAlpha("上传附件")]
-    //public async Task UploadFiles(OrderUploadFiles dto) { 
-
-    //       var fileJson = await _fileRepository.AddFileAsync(dto.Files, dto.Id, "", HttpContext.RequestAborted);
-
-    //       if (fileJson.Any())
-    //       {
-    //		var order = await _orderRepository.GetAsync(dto.Id);
-    //           if (order.FileJson != null && order.FileJson.Any())
-    //           {
-    //               order.FileJson.AddRange(fileJson);
-    //           }
-    //           else {
-    //               order.FileJson = fileJson;
-    //		}
-    //           await _orderRepository.Updateable().SetColumns(x => new Order { FileJson = order.FileJson }).Where(x => x.Id == dto.Id).ExecuteCommandAsync();
-    //	}
-    //}
-
-
     /// <summary>
     /// 新增工单
     /// </summary>
@@ -4685,13 +4680,13 @@ public class OrderController : BaseController
 
                 if (workflowDto.BusinessType == EBusinessType.Send)
                 {
-                    // 宜宾需求: 1.是否是派单节点  2.是否存在历史派单节点  3.存在获取上个派单节点  4.不存在走平均派单 
+                    // 宜宾需求: 1.是否是派单节点  2.是否存在历史派单节点  3.存在获取上个派单节点  4.不存在走平均派单   过滤历史派单节点不为派单池
                     if (_appOptions.Value.IsYiBin || _appOptions.Value.IsZiGong)
                     {
-                        var sendOrderTraces = workflow.Traces.Where(x => x.BusinessType == EBusinessType.Send);
+                        var sendOrderTraces = workflow.Traces.Where(x => x.BusinessType == EBusinessType.Send && x.HandlerId != AppDefaults.SendPoolId);
                         if (sendOrderTraces.Any())
                         {
-                            var sendOrderTrace = workflow.Traces.Where(x => x.BusinessType == EBusinessType.Send)
+                            var sendOrderTrace = workflow.Traces.Where(x => x.BusinessType == EBusinessType.Send && x.HandlerId != AppDefaults.SendPoolId)
                                 .OrderByDescending(x => x.CreationTime)
                                 .FirstOrDefault();
                             nextDto.NextHandlers = new List<StepAssignInfo>
@@ -4723,8 +4718,10 @@ public class OrderController : BaseController
                     // }).Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
                 }
 
-                var (_, currentStep, _, _) = await _workflowDomainService.NextAsync(_sessionContext, nextDto, order.ExpiredTime,
-                    isAutoFillSummaryOpinion, cancellationToken: cancellationToken);
+                var (_, currentStep, _, _) = await _workflowDomainService.NextAsync(nextDto,
+                    expiredTime: order.ExpiredTime,
+                    isAutoFillSummaryOpinion: isAutoFillSummaryOpinion,
+                    cancellationToken: cancellationToken);
                 if (currentStep.BusinessType is EBusinessType.Send)
                 {
                     await _orderRepository.Updateable().SetColumns(o => new Order()
@@ -4758,12 +4755,20 @@ public class OrderController : BaseController
                         if (unhandleStep.Id != startStep.Id)
                             nextflowDto.Opinion = "跨级派单,自动办理";
 
-                        var operater = new FakeSessionContext
+                        //var operater = new FakeSessionContext
+                        //{
+                        //    OrgId = unhandleStep.HandlerOrgId,
+                        //    OrgName = unhandleStep.HandlerOrgName,
+                        //};
+                        if (unhandleStep.BusinessType is EBusinessType.Department)
                         {
-                            OrgId = unhandleStep.HandlerOrgId,
-                            OrgName = unhandleStep.HandlerOrgName,
-                        };
-                        var (_, _, _, nextSteps) = await _workflowDomainService.NextAsync(operater, nextflowDto, order.ExpiredTime,
+                            var operater = await _orderApplication.GetHandlerRandomAsync(unhandleStep, cancellationToken);
+                            // await _sessionContext.ChangeSessionAsync(operater.Id, cancellationToken);
+                            await _sessionContextManager.ChangeSessionContextByUserIdAsync(operater.Id, cancellationToken);
+                        }
+
+                        var (_, _, _, nextSteps) = await _workflowDomainService.NextAsync(nextflowDto,
+                            EHandleMode.CrossLevel, order.ExpiredTime,
                             isAutoFillSummaryOpinion, cancellationToken: cancellationToken);
                         tempSteps.AddRange(nextSteps);
                     }
@@ -4794,7 +4799,7 @@ public class OrderController : BaseController
                     }));
                 nextDto.IsStartCountersign = nextDto.NextHandlers.Count > 1;
 
-                await HandleNextInMainAndSecondaryAsync(_sessionContext, workflow.WorkflowDefinition,
+                await HandleNextInMainAndSecondaryAsync(workflow.WorkflowDefinition,
                     secondaryOrgs, nextDto, order.ExpiredTime, isAutoFillSummaryOpinion,
                     cancellationToken);
 
@@ -4815,12 +4820,14 @@ public class OrderController : BaseController
         }
     }
 
-    private async Task HandleNextInMainAndSecondaryAsync(ISessionContext current, WorkflowDefinition definition, List<OrgDto> orgs,
+    private async Task HandleNextInMainAndSecondaryAsync(WorkflowDefinition definition, List<OrgDto> orgs,
         NextWorkflowDto? flowDto, DateTime? expiredTime, bool isAutoFillSummaryOpinion, CancellationToken cancellation)
     {
         if (flowDto is null || !flowDto.NextHandlers.Any()) return;
-        var (_, _, _, currentSteps) = await _workflowDomainService.NextAsync(current, flowDto, expiredTime,
-            isAutoFillSummaryOpinion, cancellationToken: cancellation);
+        var (_, _, _, currentSteps) = await _workflowDomainService.NextAsync(flowDto,
+            expiredTime: expiredTime,
+            isAutoFillSummaryOpinion: isAutoFillSummaryOpinion,
+            cancellationToken: cancellation);
 
         foreach (var currentStep in currentSteps)
         {
@@ -4862,7 +4869,13 @@ public class OrderController : BaseController
                     BusinessType = nextStepDefine.BusinessType,
                 };
 
-                await HandleNextInMainAndSecondaryAsync(current, definition, orgs, nextDto, expiredTime, isAutoFillSummaryOpinion, cancellation);
+                if (currentStep.BusinessType is EBusinessType.Department)
+                {
+                    var operater = await _orderApplication.GetHandlerRandomAsync(currentStep, cancellation);
+                    // await _sessionContext.ChangeSessionAsync(operater.Id, cancellation);
+                    await _sessionContextManager.ChangeSessionContextByUserIdAsync(operater.Id,cancellation);
+                }
+                await HandleNextInMainAndSecondaryAsync(definition, orgs, nextDto, expiredTime, isAutoFillSummaryOpinion, cancellation);
             }
         }
     }
@@ -5538,7 +5551,7 @@ public class OrderController : BaseController
             if (order.Workflow.IsInCountersign) throw UserFriendlyException.SameMessage("工单会签中,无法进行退回!");
 
             var (currentStep, prevStep, steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
-               dto.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles,dto.AssignStepId, HttpContext.RequestAborted);
+               dto.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles, dto.AssignStepId, HttpContext.RequestAborted);
 
             if (oneSendBack && isOrgToCenter && _appOptions.Value.IsZiGong)
             {
@@ -5618,20 +5631,20 @@ public class OrderController : BaseController
             var order = await _orderRepository.Queryable().Includes(d => d.Workflow).FirstAsync(d => d.Id == sendBack.OrderId);
             if (_appOptions.Value.IsZiGong)
             {
-                var (currentStep, prevStep, steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
-                    order.WorkflowId, sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(), sendBack.AssignStepId,
-					HttpContext.RequestAborted);
+                //var (currentStep, prevStep, steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
+                //    order.WorkflowId, sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(), sendBack.AssignStepId,
+                //    HttpContext.RequestAborted);
 
-                if (prevStep.BusinessType == EBusinessType.Send)
-                {
-                    // 平均派单
-                    var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
-                    if (averageSendOrder)
-                    {
-                        var handler = await _orderDomainService.AverageOrder(HttpContext.RequestAborted);
-                        sendBack.SendBackData.Handler = handler;
-                    }
-                }
+                //if (prevStep.BusinessType == EBusinessType.Send)
+                //{
+                //    // 平均派单
+                //    var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
+                //    if (averageSendOrder)
+                //    {
+                //        var handler = await _orderDomainService.AverageOrder(HttpContext.RequestAborted);
+                //        sendBack.SendBackData.Handler = handler;
+                //    }
+                //}
             }
             sendBack.SendBackData.ExpiredTime = order.ExpiredTime;
             await _orderApplication.OrderPrevious(sendBack, order, HttpContext.RequestAborted);
@@ -5677,7 +5690,7 @@ public class OrderController : BaseController
                 {
                     var (currentStep, prevStep, steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
                         order.WorkflowId, sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(), sendBack.AssignStepId,
-						HttpContext.RequestAborted);
+                        HttpContext.RequestAborted);
                     if (prevStep.BusinessType == EBusinessType.Send)
                     {
                         // 平均派单
@@ -5798,7 +5811,7 @@ public class OrderController : BaseController
             throw UserFriendlyException.SameMessage("该工单未开启流程");
 
         var (currentStep, prevStep, steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
-            order.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles,string.Empty, HttpContext.RequestAborted);
+            order.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles, string.Empty, HttpContext.RequestAborted);
         ///查询上一节点是否是领导节点
         ///ture 流程排除领导节点 排除当前节点 prevStep.BusinessType == EBusinessType.DepartmentLeader
         if (_appOptions.Value.IsYiBin && prevStep.Name.Contains("领导"))
@@ -6107,8 +6120,8 @@ public class OrderController : BaseController
                 async (workflow, currentStep, targetStepDefine, targetStep, targetStepNew) =>
                 {
                     var basicWorkflowDto = _mapper.Map<BasicWorkflowDto>(dto);
-                    var stepAssignInfo = await _orderApplication.GetOrderRecallAssignInfoAsync(workflow, targetStepDefine, targetStep,
-                        basicWorkflowDto, HttpContext.RequestAborted);
+                    var stepAssignInfo = _orderApplication.GetOrderRecallAssignInfoAsync(workflow, targetStepDefine, targetStep,
+                        basicWorkflowDto, HttpContext.RequestAborted).Result;
                     if (stepAssignInfo is null) return;
                     var validator = new StepAssignInfoValidator();
                     await validator.ValidateAndThrowAsync(stepAssignInfo, HttpContext.RequestAborted);
@@ -6117,10 +6130,10 @@ public class OrderController : BaseController
                 },
                 HttpContext.RequestAborted);
 
-   //         if (order.ActualHandleOrgCode != OrgSeedData.CenterId && order.Status < EOrderStatus.Filed)
-   //         {
-   //             await _circularRecordDomainService.OrderSpecialCircularMessage(special, order, HttpContext.RequestAborted);
-			//}
+            if (_appOptions.Value.IsYiBin && order.ActualHandleOrgCode != OrgSeedData.CenterId && order.Status < EOrderStatus.Filed)
+            {
+                await _circularRecordDomainService.OrderSpecialCircularMessage(special, order, HttpContext.RequestAborted);
+            }
 
             if (string.IsNullOrEmpty(currentStep?.HandlerOrgId))
             {
@@ -6897,9 +6910,9 @@ public class OrderController : BaseController
         if (_appOptions.Value.IsZiGong)
         {
             step.Steps = step.Steps.Where(x => x.Key.ToLower() != "start").ToList();
-            if (step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.OrgLevel == 1).Any())
+            if (step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.StepType == EStepType.Normal && x.OrgLevel == 1).Any())
             {
-                var stepdDefault = step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.OrgLevel == 1)
+                var stepdDefault = step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.StepType == EStepType.Normal && x.OrgLevel == 1)
                     .FirstOrDefault();
                 defaultStepKey = stepdDefault.Key;
             }

+ 3 - 12
src/Hotline.Api/Controllers/OrderModuleControllers/OrderCarbonCopyController.cs → src/Hotline.Api/Controllers/OrderControllers/OrderCarbonCopyController.cs

@@ -1,23 +1,14 @@
 using Hotline.Application.Orders;
-using Hotline.Caching.Services;
-using Hotline.FlowEngine.WorkflowModules;
-using Hotline.Orders;
+using Hotline.Caching.Interfaces;
 using Hotline.Repository.SqlSugar.Extensions;
-using Hotline.Settings.TimeLimits;
 using Hotline.Settings;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Order.CarbonCopy;
-using Hotline.Share.Enums.Order;
-using Hotline.Share.Requests;
+using Mapster;
 using MapsterMapper;
 using Microsoft.AspNetCore.Mvc;
-using XF.Domain.Authentications;
-using XF.Domain.Repository;
-using XF.Utility.EnumExtensions;
-using Hotline.Caching.Interfaces;
-using Mapster;
 
-namespace Hotline.Api.Controllers.OrderModuleControllers
+namespace Hotline.Api.Controllers.OrderControllers
 {
     /// <summary>
     /// 工单抄送

+ 1 - 1
src/Hotline.Api/Controllers/OrderModuleControllers/OrderComplementController.cs → src/Hotline.Api/Controllers/OrderControllers/OrderComplementController.cs

@@ -2,7 +2,7 @@
 using Hotline.Share.Dtos.Order;
 using Microsoft.AspNetCore.Mvc;
 
-namespace Hotline.Api.Controllers.OrderModuleControllers;
+namespace Hotline.Api.Controllers.OrderControllers;
 
 public class OrderComplementController : BaseController
 {

+ 1 - 1
src/Hotline.Api/Controllers/OrderTerminateController.cs

@@ -209,7 +209,7 @@ namespace Hotline.Api.Controllers
 			try
 			{
 				dto.NextWorkflow.WorkflowId = model.WorkflowId;
-				await _workflowDomainService.NextAsync(_sessionContext, dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
+				await _workflowDomainService.NextAsync(dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
 			}
 			catch (Exception e)
 			{

+ 106 - 0
src/Hotline.Api/Controllers/SpecialController.cs

@@ -0,0 +1,106 @@
+using MapsterMapper;
+using Microsoft.AspNetCore.Mvc;
+using XF.Domain.Authentications;
+using Hotline.Share.Dtos;
+using Hotline.Share.Tools;
+using Hotline.Application.SpecialNumber;
+using Hotline.Share.Dtos.Special;
+
+namespace Hotline.Api.Controllers
+{
+    /// <summary>
+    /// 特殊号码
+    /// </summary>
+    public class SpecialController : BaseController
+    {
+        #region 注入
+
+        private readonly IMapper _mapper;
+        private readonly ISessionContext _sessionContext;
+        private readonly ISpecialNumberApplication _specialNumberApplication;
+
+
+        public SpecialController(
+           IMapper mapper,
+           ISessionContext sessionContext,
+           ISpecialNumberApplication specialNumberApplication)
+        {
+            _mapper = mapper;
+            _sessionContext = sessionContext;
+            _specialNumberApplication = specialNumberApplication;
+        }
+
+        #endregion
+
+        #region 特殊号码
+
+        /// <summary>
+        /// 特殊号码列表
+        /// </summary>
+        /// <param name="pagedDto"></param>
+        /// <returns></returns>
+        [HttpGet("number/list")]
+        public async Task<PagedDto<SpecialNumberInfoDto>> QueryAllSpecialNumberListAsync([FromQuery] SpecialNumberDto pagedDto)
+        {
+            return (await _specialNumberApplication.QueryAllSpecialNumberListAsync(pagedDto, HttpContext.RequestAborted)).ToPaged();
+        }
+
+        /// <summary>
+        /// 特殊号码新增
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("number/add")]
+        public async Task<string> AddSpecialNumberAsync([FromBody] AddSpecialNumberDto dto)
+        {
+            return await _specialNumberApplication.AddSpecialNumberAsync(dto, HttpContext.RequestAborted);
+        }
+
+        /// <summary>
+        /// 特殊号码编辑
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPut("number/update")]
+        public async Task UpdateSpecialNumberAsync([FromBody] UpdateSpecialNumberDto dto)
+        {
+            await _specialNumberApplication.UpdateSpecialNumberAsync(dto, HttpContext.RequestAborted);
+        }
+
+        /// <summary>
+        /// 特殊号码删除
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpDelete("number/remove")]
+        public async Task RemoveSpecialNumberAsync([FromBody] DelSpecialNumberDto dto)
+        {
+            await _specialNumberApplication.RemoveSpecialNumberAsync(dto, HttpContext.RequestAborted);
+        }
+
+        /// <summary>
+        /// 特殊号码详情根据id查询
+        /// </summary>
+        /// <param name="Id"></param>
+        /// <returns></returns>
+        [HttpGet("number/info")]
+        public async Task<SpecialNumberInfoDto> GetSpecialNumberAsync(string Id)
+        {
+            return await _specialNumberApplication.GetSpecialNumberAsync(Id, HttpContext.RequestAborted);
+        }
+
+        /// <summary>
+        /// 特殊号码详情根据号码查询
+        /// </summary>
+        /// <param name="PhoneNumber"></param>
+        /// <returns></returns>
+        [HttpGet("number/info/num")]
+        public async Task<SpecialNumberInfoDto> GetSpecialNumberByAsync(string PhoneNumber)
+        {
+            return await _specialNumberApplication.GetSpecialNumberByAsync(PhoneNumber, HttpContext.RequestAborted);
+        }
+
+        #endregion
+    }
+}
+

+ 4 - 1
src/Hotline.Api/Controllers/TestController.cs

@@ -539,11 +539,13 @@ ICallApplication callApplication,
         //var r = _timeLimitDomainService.CalcExpiredTime(DateTime.Now, EFlowDirection.CenterToCenter, batchId);
         //var r = _timeLimitDomainService.CalcEndTime(DateTime.Parse("2024-09-12 14:45:47"), Share.Enums.Settings.ETimeType.WorkDay, 2, 80, 50);
         //_capPublisher.PublishDelay((DateTime.Now.AddMinutes(2) - DateTime.Now), EventNames.OrderRelateCall, "123");
-        var times = await _expireTime.CalcExpiredTime(DateTime.Parse("2025-01-14 09:45:00"), DateTime.Parse("2025-01-07 09:16:53.691249"), EFlowDirection.CenterToOrg, new OrderTimeClacInfo() { AcceptTypeCode = "20" });
+        //var times = await _expireTime.CalcExpiredTime(DateTime.Parse("2025-01-14 09:45:00"), DateTime.Parse("2025-01-07 09:16:53.691249"), EFlowDirection.CenterToOrg, new OrderTimeClacInfo() { AcceptTypeCode = "20" });
         //await _expireTime.CalcWorkTimeToDecimal(visit.VisitTime.Value, DateTime.Now, false);
         //var times = await _expireTime.CalcWorkTimeToDecimal(DateTime.Parse("2024-12-16 21:36:27"), DateTime.Parse("2024-12-17 12:47:05"), false);
         //var query = _userRepository.Queryable().Where(x => false);
         //await _capPublisher.PublishDelay(EventNames.OrderRelateCall, "123", cancellationToken: HttpContext.RequestAborted);
+        var times = await _expireTime.CalcWorkTimeEx(
+                       DateTime.Parse("2025-02-21 16:00:11.154098"),DateTime.Parse("2025-02-28 11:27:11.441577"),false);
         return OpenResponse.Ok(times);
     }
 
@@ -1422,4 +1424,5 @@ ICallApplication callApplication,
 
     //    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFiled, orderFlowDto, cancellationToken: cancellationToken);
     //}
+
 }

+ 1 - 1
src/Hotline.Api/Controllers/WorkflowController.cs

@@ -347,7 +347,7 @@ public class WorkflowController : BaseController
     [LogFilterAlpha("审核开始")]
     public async Task Next([FromBody] NextWorkflowDto dto)
     {
-        await _workflowDomainService.NextAsync(_sessionContext, dto, cancellationToken: HttpContext.RequestAborted);
+        await _workflowDomainService.NextAsync(dto, cancellationToken: HttpContext.RequestAborted);
     }
 
     /// <summary>

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

@@ -1,7 +1,7 @@
 {
   "AllowedHosts": "*",
   "AppConfiguration": {
-    "AppScope": "YiBin",
+    "AppScope": "ZiGong",
     "YiBin": {
       "AreaCode": "511500",
       "CallCenterType": "TianRun", //XunShi、WeiErXin、TianRun、XingTang

+ 102 - 100
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -43,6 +43,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     private readonly IRepository<Role> _roleRepository;
     private readonly IWfModuleCacheManager _wfModuleCacheManager;
     private readonly ISessionContextProvider _sessionContextProvider;
+    private readonly ISessionContext _sessionContext;
     private readonly IMapper _mapper;
     private readonly IFileRepository _fileRepository;
     private readonly ILogger<WorkflowApplication> _logger;
@@ -58,6 +59,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         IRepository<Role> roleRepository,
         IWfModuleCacheManager wfModuleCacheManager,
         ISessionContextProvider sessionContextProvider,
+        ISessionContext sessionContext,
         IMapper mapper,
         IFileRepository fileRepository,
         ISystemSettingCacheManager systemSettingCacheManager,
@@ -72,6 +74,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         _roleRepository = roleRepository;
         _wfModuleCacheManager = wfModuleCacheManager;
         _sessionContextProvider = sessionContextProvider;
+        _sessionContext = sessionContext;
         _mapper = mapper;
         _fileRepository = fileRepository;
         _logger = logger;
@@ -99,7 +102,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     //
     //     //下一节点是否为动态节点
     //     var isNextDynamic = startStepDefine.InstanceMode is EInstanceMode.Dynamic &&
-    //                         !_workflowDomainService.DynamicShouldTerminal(startStepDefine, _sessionContextProvider.SessionContext.OrgLevel);
+    //                         !_workflowDomainService.DynamicShouldTerminal(startStepDefine, _sessionContext.OrgLevel);
     //     var firstStepDefine = isNextDynamic
     //         ? startStepDefine
     //         : definition.FindStepDefine(dto.NextStepCode);
@@ -125,7 +128,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     //     }
     //
     //     var workflow = await _workflowDomainService.CreateWorkflowAsync(wfModule, dto.Title,
-    //         _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.RequiredOrgId,
+    //         _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId,
     //         externalId, cancellationToken);
     //
     //     //var startStepHandles = new List<WorkflowStepHandler>{WorkflowStepHandler.Create(workflow.Id, workflow.ExternalId,
@@ -135,22 +138,22 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     //     var defineHandler = startStepDefine.HandlerTypeItems.First();
     //
     //     var assigner = new UserInfo(
-    //         _sessionContextProvider.SessionContext.UserId,
-    //         _sessionContextProvider.SessionContext.UserName,
-    //         _sessionContextProvider.SessionContext.OrgId,
-    //         _sessionContextProvider.SessionContext.OrgName,
-    //         _sessionContextProvider.SessionContext.OrgIsCenter
+    //         _sessionContext.UserId,
+    //         _sessionContext.UserName,
+    //         _sessionContext.OrgId,
+    //         _sessionContext.OrgName,
+    //         _sessionContext.OrgIsCenter
     //     );
     //
     //     var startStep = _workflowDomainService.CreateStartStep(workflow, startStepDefine, dto, assigner,
     //         new FlowStepHandler
     //         {
-    //             Key = _sessionContextProvider.SessionContext.RequiredUserId,
-    //             Value = _sessionContextProvider.SessionContext.UserName,
-    //             UserId = _sessionContextProvider.SessionContext.UserId,
-    //             Username = _sessionContextProvider.SessionContext.UserName,
-    //             OrgId = _sessionContextProvider.SessionContext.RequiredOrgId,
-    //             OrgName = _sessionContextProvider.SessionContext.OrgName,
+    //             Key = _sessionContext.RequiredUserId,
+    //             Value = _sessionContext.UserName,
+    //             UserId = _sessionContext.UserId,
+    //             Username = _sessionContext.UserName,
+    //             OrgId = _sessionContext.RequiredOrgId,
+    //             OrgName = _sessionContext.OrgName,
     //             RoleId = defineHandler.Key,
     //             RoleName = defineHandler.Value,
     //         }, expiredTime);
@@ -181,11 +184,11 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     //
     //     //更新受理人信息
     //     workflow.UpdateAcceptor(
-    //         _sessionContextProvider.SessionContext.RequiredUserId,
-    //         _sessionContextProvider.SessionContext.UserName,
-    //         _sessionContextProvider.SessionContext.StaffNo,
-    //         _sessionContextProvider.SessionContext.RequiredOrgId,
-    //         _sessionContextProvider.SessionContext.OrgName);
+    //         _sessionContext.RequiredUserId,
+    //         _sessionContext.UserName,
+    //         _sessionContext.StaffNo,
+    //         _sessionContext.RequiredOrgId,
+    //         _sessionContext.OrgName);
     //
     //     await _workflowDomainService.StartAsync(workflow, startStep, dto, firstStepDefine, isNextDynamic,
     //         flowAssignInfo, counterSignType, expiredTime, cancellationToken);
@@ -216,29 +219,29 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         var startStepDefine = definition.FindStartStepDefine();
 
         var workflow = await _workflowDomainService.CreateWorkflowAsync(wfModule, dto.Title,
-            _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.RequiredOrgId,
+            _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId,
             externalId, cancellationToken);
 
         var defineHandler = startStepDefine.HandlerTypeItems.First();
 
         var assigner = new UserInfo(
-            _sessionContextProvider.SessionContext.UserId,
-            _sessionContextProvider.SessionContext.UserName,
-            _sessionContextProvider.SessionContext.OrgId,
-            _sessionContextProvider.SessionContext.OrgName,
-            _sessionContextProvider.SessionContext.OrgIsCenter
+            _sessionContext.UserId,
+            _sessionContext.UserName,
+            _sessionContext.OrgId,
+            _sessionContext.OrgName,
+            _sessionContext.OrgIsCenter
         );
 
         //todo 需求:所有坐席都可以办,临时方案,后期重构:依据策略决定指派对象
         var startStep = _workflowDomainService.CreateStartStep(workflow, startStepDefine, dto, assigner,
             new StepAssignInfo
             {
-                Key = _sessionContextProvider.SessionContext.RequiredUserId,
-                Value = _sessionContextProvider.SessionContext.UserName,
-                UserId = _sessionContextProvider.SessionContext.UserId,
-                Username = _sessionContextProvider.SessionContext.UserName,
-                OrgId = _sessionContextProvider.SessionContext.RequiredOrgId,
-                OrgName = _sessionContextProvider.SessionContext.OrgName,
+                Key = _sessionContext.RequiredUserId,
+                Value = _sessionContext.UserName,
+                UserId = _sessionContext.UserId,
+                Username = _sessionContext.UserName,
+                OrgId = _sessionContext.RequiredOrgId,
+                OrgName = _sessionContext.OrgName,
                 RoleId = defineHandler.Key,
                 RoleName = defineHandler.Value,
                 FlowAssignType = EFlowAssignType.Role,
@@ -261,11 +264,11 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
         //更新受理人信息
         workflow.UpdateAcceptor(
-            _sessionContextProvider.SessionContext.RequiredUserId,
-            _sessionContextProvider.SessionContext.UserName,
-            _sessionContextProvider.SessionContext.StaffNo,
-            _sessionContextProvider.SessionContext.RequiredOrgId,
-            _sessionContextProvider.SessionContext.OrgName);
+            _sessionContext.RequiredUserId,
+            _sessionContext.UserName,
+            _sessionContext.StaffNo,
+            _sessionContext.RequiredOrgId,
+            _sessionContext.OrgName);
 
         return workflow.Id;
     }
@@ -296,7 +299,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
     //    //下一节点是否为动态节点
     //    var isNextDynamic = currentStepDefine.InstanceMode is EInstanceMode.Dynamic &&
-    //                        !_workflowDomainService.DynamicShouldTerminal(currentStepDefine, _sessionContextProvider.SessionContext.OrgLevel);
+    //                        !_workflowDomainService.DynamicShouldTerminal(currentStepDefine, _sessionContext.OrgLevel);
 
     //    StepDefine nextStepDefine;
     //    if (isNextDynamic
@@ -355,11 +358,11 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
             withTraces: true, withCountersigns: true, cancellationToken: cancellationToken);
 
         return await _workflowDomainService.PreviousAsync(workflow, dto, new OperatorInfo(
-            _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-            _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-            _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName,
-            _sessionContextProvider.SessionContext.OrgIsCenter, _sessionContextProvider.SessionContext.Roles,
-            _sessionContextProvider.SessionContext.OrgLevel), handleMode, newStepConfig, cancellationToken);
+            _sessionContext.RequiredUserId, _sessionContext.UserName,
+            _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+            _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
+            _sessionContext.OrgIsCenter, _sessionContext.Roles,
+            _sessionContext.OrgLevel), handleMode, newStepConfig, cancellationToken);
     }
 
     /// <summary>
@@ -462,7 +465,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
             StepId = unHandleStep.Id
         };
         //await NextAsync(dto, cancellationToken: cancellationToken);
-        await _workflowDomainService.NextAsync(_sessionContextProvider.SessionContext, dto, expiredTime: expiredTime,
+        await _workflowDomainService.NextAsync(dto, expiredTime: expiredTime,
             cancellationToken: cancellationToken);
     }
 
@@ -480,7 +483,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
         var startStepDefine = definition.FindStartStepDefine();
         if (startStepDefine.InstanceMode is EInstanceMode.Dynamic &&
-            !_workflowDomainService.DynamicShouldTerminal(startStepDefine, _sessionContextProvider.SessionContext.OrgLevel))
+            !_workflowDomainService.DynamicShouldTerminal(startStepDefine, _sessionContext.OrgLevel))
         {
             var settingHandle = _systemSettingCacheManager.GetSetting(SettingConstants.RoleJingBanRen);
             var settingLead = _systemSettingCacheManager.GetSetting(SettingConstants.RoleLingDao);
@@ -525,8 +528,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         var workflow = await _workflowDomainService.GetWorkflowAsync(workflowId, withDefine: true, withSteps: true,
             cancellationToken: cancellationToken);
         var currentStep = _workflowDomainService.FindCurrentStepWaitForHandle(workflow,
-            _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.RequiredOrgId,
-            _sessionContextProvider.SessionContext.Roles);
+            _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId,
+            _sessionContext.Roles);
         if (currentStep.StepType is EStepType.End)
             throw new UserFriendlyException("结束节点无需办理");
 
@@ -638,7 +641,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         var currentStepDefine = _workflowDomainService.GetStepDefine(workflow.WorkflowDefinition, currentStep.Code);
 
         if (currentStep.InstanceMode is EInstanceMode.Dynamic &&
-            !_workflowDomainService.DynamicShouldTerminal(currentStepDefine, _sessionContextProvider.SessionContext.OrgLevel))
+            !_workflowDomainService.DynamicShouldTerminal(currentStepDefine, _sessionContext.OrgLevel))
         {
             var settingHandle = _systemSettingCacheManager.GetSetting(SettingConstants.RoleJingBanRen);
             var settingLead = _systemSettingCacheManager.GetSetting(SettingConstants.RoleLingDao);
@@ -827,13 +830,12 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         nextDto.ReviewResult = EReviewResult.Failed;
         nextDto.NextStepCode = endStepDefine.Code;
         nextDto.NextStepName = endStepDefine.Name;
-        nextDto.FlowDirection = _sessionContextProvider.SessionContext.OrgIsCenter
+        nextDto.FlowDirection = _sessionContext.OrgIsCenter
             ? EFlowDirection.CenterToFile
             : EFlowDirection.OrgToFile;
 
         //await NextAsync(nextDto, cancellationToken: cancellationToken);
-        await _workflowDomainService.NextAsync(_sessionContextProvider.SessionContext, nextDto,
-            cancellationToken: cancellationToken);
+        await _workflowDomainService.NextAsync(nextDto, cancellationToken: cancellationToken);
     }
 
     //供开启流程调用
@@ -970,7 +972,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
             };
         }
 
-        var orgId = _sessionContextProvider.SessionContext.RequiredOrgId;
+        var orgId = _sessionContext.RequiredOrgId;
         var levelOneOrgId = orgId.GetHigherOrgId();
         var isCenter = levelOneOrgId.IsCenter();
         switch (stepDefine.HandlerType)
@@ -1066,8 +1068,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 }
                 else
                 {
-                    var upLevels = levels.Where(d => d <= _sessionContextProvider.SessionContext.OrgLevel).ToList();
-                    var lowLevels = levels.Where(d => d > _sessionContextProvider.SessionContext.OrgLevel).ToList();
+                    var upLevels = levels.Where(d => d <= _sessionContext.OrgLevel).ToList();
+                    var lowLevels = levels.Where(d => d > _sessionContext.OrgLevel).ToList();
                     orgs1 = await query
                         .Where(d => (upLevels.Contains(d.Level) && d.Id.StartsWith(levelOneOrgId)) ||
                                     (lowLevels.Contains(d.Level) && d.Id.StartsWith(orgId)))
@@ -1184,7 +1186,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         switch (policy)
         {
             case EDynamicPolicy.OrgUpCenterTop:
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                orgLevel = _sessionContext.OrgLevel - 1;
                 if (orgLevel < 0) orgLevel = 0;
 
                 if (orgLevel == 0)
@@ -1210,7 +1212,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     businessType = EBusinessType.Department;
 
                     //上级部门Id
-                    upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
+                    upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
                     items = await _organizeRepository.Queryable()
                         .Where(d => d.Id == upperOrgId)
                         .Select(d => new StepAssignInfo
@@ -1226,15 +1228,15 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
                 break;
             case EDynamicPolicy.OrgUp:
-                businessType = _sessionContextProvider.SessionContext.OrgIsCenter
+                businessType = _sessionContext.OrgIsCenter
                     ? EBusinessType.Send
-                    : _sessionContextProvider.SessionContext.RequiredOrgId.CalcOrgLevel() == 1
+                    : _sessionContext.RequiredOrgId.CalcOrgLevel() == 1
                         ? EBusinessType.Send
                         : EBusinessType.Department;
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                orgLevel = _sessionContext.OrgLevel - 1;
                 if (orgLevel <= 0) orgLevel = 1;
                 //上级部门Id
-                upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
+                upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
                 items = await _organizeRepository.Queryable()
                     .Where(d => d.Id == upperOrgId)
                     .Select(d => new StepAssignInfo
@@ -1248,7 +1250,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     .ToListAsync(cancellationToken);
                 break;
             case EDynamicPolicy.OrgUpHandleCenterTop:
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                orgLevel = _sessionContext.OrgLevel - 1;
                 if (orgLevel < 0) orgLevel = 0;
 
                 if (orgLevel == 0)
@@ -1274,7 +1276,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     businessType = EBusinessType.Department;
                     roleName = handleRoleName;
                     //上级部门Id
-                    upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
+                    upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
                     items = await _organizeRepository.Queryable()
                         .Where(d => d.Id == upperOrgId)
                         .Select(d => new StepAssignInfo
@@ -1292,16 +1294,16 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
                 break;
             case EDynamicPolicy.OrgUpHandle:
-                businessType = _sessionContextProvider.SessionContext.OrgIsCenter
+                businessType = _sessionContext.OrgIsCenter
                     ? EBusinessType.Send
-                    : _sessionContextProvider.SessionContext.RequiredOrgId.CalcOrgLevel() == 1
+                    : _sessionContext.RequiredOrgId.CalcOrgLevel() == 1
                         ? EBusinessType.Send
                         : EBusinessType.Department;
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                orgLevel = _sessionContext.OrgLevel - 1;
                 if (orgLevel <= 0) orgLevel = 1;
                 roleName = handleRoleName;
                 //上级部门Id
-                upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
+                upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
                 items = await _organizeRepository.Queryable()
                     .Where(d => d.Id == upperOrgId)
                     .Select(d => new StepAssignInfo
@@ -1317,11 +1319,11 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     .ToListAsync(cancellationToken);
                 break;
             case EDynamicPolicy.OrgUpLeadCenterTop:
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                orgLevel = _sessionContext.OrgLevel - 1;
                 if (orgLevel < 0) orgLevel = 0;
-                isLead = _sessionContextProvider.SessionContext.Roles.Any(x => x == leadRoleCode);
+                isLead = _sessionContext.Roles.Any(x => x == leadRoleCode);
                 isSkip = await _userRepository.Queryable()
-                    .AnyAsync(x => x.OrgId == _sessionContextProvider.SessionContext.RequiredOrgId && x.Roles.Any(r => r.Name == leadRoleCode),
+                    .AnyAsync(x => x.OrgId == _sessionContext.RequiredOrgId && x.Roles.Any(r => r.Name == leadRoleCode),
                         cancellationToken);
                 if (orgLevel == 0 && (isLead || !isSkip))
                 {
@@ -1344,7 +1346,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 else
                 {
                     businessType = EBusinessType.Department;
-                    upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(_sessionContextProvider.SessionContext.OrgLevel);
+                    upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(_sessionContext.OrgLevel);
                     if (!isLead)
                     {
                         if (isSkip)
@@ -1357,7 +1359,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     if (isLead || !isSkip)
                     {
                         //上级部门Id
-                        upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
+                        upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
                         roleId = handleRoleCode;
                         roleName = handleRoleName;
                     }
@@ -1383,19 +1385,19 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
                 break;
             case EDynamicPolicy.OrgUpLead:
-                businessType = _sessionContextProvider.SessionContext.OrgIsCenter
+                businessType = _sessionContext.OrgIsCenter
                     ? EBusinessType.Send
-                    : _sessionContextProvider.SessionContext.RequiredOrgId.CalcOrgLevel() == 1
+                    : _sessionContext.RequiredOrgId.CalcOrgLevel() == 1
                         ? EBusinessType.Send
                         : EBusinessType.Department;
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                orgLevel = _sessionContext.OrgLevel - 1;
                 if (orgLevel <= 0) orgLevel = 1;
-                upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(_sessionContextProvider.SessionContext.OrgLevel);
-                isLead = _sessionContextProvider.SessionContext.Roles.Any(x => x == leadRoleCode);
+                upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(_sessionContext.OrgLevel);
+                isLead = _sessionContext.Roles.Any(x => x == leadRoleCode);
                 if (!isLead)
                 {
                     isSkip = await _userRepository.Queryable()
-                        .AnyAsync(x => x.OrgId == _sessionContextProvider.SessionContext.RequiredOrgId && x.Roles.Any(r => r.Name == leadRoleCode),
+                        .AnyAsync(x => x.OrgId == _sessionContext.RequiredOrgId && x.Roles.Any(r => r.Name == leadRoleCode),
                             cancellationToken);
                     if (isSkip)
                     {
@@ -1407,7 +1409,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 if (isLead || !isSkip)
                 {
                     //上级部门Id
-                    upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
+                    upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
                     roleId = handleRoleCode;
                     roleName = handleRoleName;
                 }
@@ -1431,12 +1433,12 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     .ToListAsync(cancellationToken);
                 break;
             case EDynamicPolicy.ArriveCenter:
-                businessType = _sessionContextProvider.SessionContext.OrgIsCenter
+                businessType = _sessionContext.OrgIsCenter
                     ? EBusinessType.Send
-                    : _sessionContextProvider.SessionContext.RequiredOrgId.CalcOrgLevel() == 1
+                    : _sessionContext.RequiredOrgId.CalcOrgLevel() == 1
                         ? EBusinessType.Send
                         : EBusinessType.Department;
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                orgLevel = _sessionContext.OrgLevel - 1;
                 if (orgLevel <= 0) orgLevel = 1;
                 items = await _organizeRepository.Queryable()
                     .Where(d => d.IsCenter)
@@ -1451,12 +1453,12 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     .ToListAsync(cancellationToken);
                 break;
             case EDynamicPolicy.ArriveOneOrg:
-                businessType = _sessionContextProvider.SessionContext.OrgIsCenter ? EBusinessType.Send : EBusinessType.Department;
-                orgLevel = _sessionContextProvider.SessionContext.OrgIsCenter ? 0 : 1;
+                businessType = _sessionContext.OrgIsCenter ? EBusinessType.Send : EBusinessType.Department;
+                orgLevel = _sessionContext.OrgIsCenter ? 0 : 1;
                 //上级部门Id
-                upperOrgId = _sessionContextProvider.SessionContext.OrgIsCenter
-                    ? _sessionContextProvider.SessionContext.RequiredOrgId.Substring(0, 3)
-                    : _sessionContextProvider.SessionContext.RequiredOrgId.Substring(0, 6);
+                upperOrgId = _sessionContext.OrgIsCenter
+                    ? _sessionContext.RequiredOrgId.Substring(0, 3)
+                    : _sessionContext.RequiredOrgId.Substring(0, 6);
                 items = await _organizeRepository.Queryable()
                     .Where(d => d.Id == upperOrgId)
                     .Select(d => new StepAssignInfo
@@ -1471,7 +1473,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 break;
             case EDynamicPolicy.OrgDownCenterTop:
                 businessType = EBusinessType.Department;
-                if (_sessionContextProvider.SessionContext.OrgIsCenter)
+                if (_sessionContext.OrgIsCenter)
                 {
                     orgLevel = 1;
                     items = await _organizeRepository.Queryable()
@@ -1488,10 +1490,10 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 }
                 else
                 {
-                    orgLevel = _sessionContextProvider.SessionContext.OrgLevel + 1;
+                    orgLevel = _sessionContext.OrgLevel + 1;
                     items = await _organizeRepository.Queryable()
                         .Where(d => !d.IsCenter && d.Level == orgLevel &&
-                                    d.Id.StartsWith(_sessionContextProvider.SessionContext.RequiredOrgId))
+                                    d.Id.StartsWith(_sessionContext.RequiredOrgId))
                         .Select(d => new StepAssignInfo
                         {
                             Key = d.Id,
@@ -1506,9 +1508,9 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 break;
             case EDynamicPolicy.OrgDown:
                 businessType = EBusinessType.Department;
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel + 1;
+                orgLevel = _sessionContext.OrgLevel + 1;
                 items = await _organizeRepository.Queryable()
-                    .Where(d => d.Level == orgLevel && d.Id.StartsWith(_sessionContextProvider.SessionContext.RequiredOrgId))
+                    .Where(d => d.Level == orgLevel && d.Id.StartsWith(_sessionContext.RequiredOrgId))
                     .Select(d => new StepAssignInfo
                     {
                         Key = d.Id,
@@ -1553,7 +1555,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         switch (policy)
         {
             case ECountersignPolicy.OrgUpCenterTop:
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                orgLevel = _sessionContext.OrgLevel - 1;
                 if (orgLevel < 0) orgLevel = 0;
 
                 if (orgLevel == 0)
@@ -1579,7 +1581,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     businessType = EBusinessType.Department;
 
                     //上级部门Id
-                    upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
+                    upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
                     items = await _organizeRepository.Queryable()
                         .Where(d => d.Id == upperOrgId)
                         .Select(d => new StepAssignInfo
@@ -1595,15 +1597,15 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
                 break;
             case ECountersignPolicy.OrgUp:
-                businessType = _sessionContextProvider.SessionContext.OrgIsCenter
+                businessType = _sessionContext.OrgIsCenter
                     ? EBusinessType.Send
-                    : _sessionContextProvider.SessionContext.RequiredOrgId.CalcOrgLevel() == 1
+                    : _sessionContext.RequiredOrgId.CalcOrgLevel() == 1
                         ? EBusinessType.Send
                         : EBusinessType.Department;
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                orgLevel = _sessionContext.OrgLevel - 1;
                 if (orgLevel <= 0) orgLevel = 1;
                 //上级部门Id
-                upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
+                upperOrgId = _sessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
                 items = await _organizeRepository.Queryable()
                     .Where(d => d.Id == upperOrgId)
                     .Select(d => new StepAssignInfo
@@ -1618,7 +1620,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 break;
             case ECountersignPolicy.OrgDownCenterTop:
                 businessType = EBusinessType.Department;
-                if (_sessionContextProvider.SessionContext.OrgIsCenter)
+                if (_sessionContext.OrgIsCenter)
                 {
                     orgLevel = 1;
                     items = await _organizeRepository.Queryable()
@@ -1635,10 +1637,10 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 }
                 else
                 {
-                    orgLevel = _sessionContextProvider.SessionContext.OrgLevel + 1;
+                    orgLevel = _sessionContext.OrgLevel + 1;
                     items = await _organizeRepository.Queryable()
                         .Where(d => !d.IsCenter && d.Level == orgLevel &&
-                                    d.Id.StartsWith(_sessionContextProvider.SessionContext.RequiredOrgId))
+                                    d.Id.StartsWith(_sessionContext.RequiredOrgId))
                         .Select(d => new StepAssignInfo
                         {
                             Key = d.Id,
@@ -1653,9 +1655,9 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 break;
             case ECountersignPolicy.OrgDown:
                 businessType = EBusinessType.Department;
-                orgLevel = _sessionContextProvider.SessionContext.OrgLevel + 1;
+                orgLevel = _sessionContext.OrgLevel + 1;
                 items = await _organizeRepository.Queryable()
-                    .Where(d => d.Level == orgLevel && d.Id.StartsWith(_sessionContextProvider.SessionContext.RequiredOrgId))
+                    .Where(d => d.Level == orgLevel && d.Id.StartsWith(_sessionContext.RequiredOrgId))
                     .Select(d => new StepAssignInfo
                     {
                         Key = d.Id,

+ 1 - 1
src/Hotline.Application/Orders/Handles/OrderHandler/AddOrderPushMessageNotifyHandler.cs → src/Hotline.Application/Orders/Handlers/OrderHandler/AddOrderPushMessageNotifyHandler.cs

@@ -6,7 +6,7 @@ using Hotline.Share.Enums.Push;
 using MediatR;
 using Microsoft.Extensions.Logging;
 
-namespace Hotline.Application.Orders.Handles.Order
+namespace Hotline.Application.Orders.Handlers.OrderHandler
 {
     /// <summary>
     /// 新增工单发送短信

+ 2 - 7
src/Hotline.Application/Orders/Handles/OrderHandler/GetOrderDetailNotifyHandler.cs → src/Hotline.Application/Orders/Handlers/OrderHandler/GetOrderDetailNotifyHandler.cs

@@ -1,13 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Hotline.FlowEngine.Workflows;
+using Hotline.FlowEngine.Workflows;
 using Hotline.Orders.Notifications;
 using MediatR;
 
-namespace Hotline.Application.Orders.Handles.Order
+namespace Hotline.Application.Orders.Handlers.OrderHandler
 {
     public class GetOrderDetailNotifyHandler : INotificationHandler<GetOrderDetailNotify>
     {

+ 1 - 9
src/Hotline.Application/Orders/Handles/OrderHandler/OrderRelateCallHandler.cs → src/Hotline.Application/Orders/Handlers/OrderHandler/OrderRelateCallHandler.cs

@@ -1,18 +1,10 @@
 using DotNetCore.CAP;
 using Hotline.Application.CallCenter;
-using Hotline.CallCenter.Calls;
-using Hotline.Orders;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Mq;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using XF.Domain.Dependency;
-using XF.Domain.Repository;
 
-namespace Hotline.Application.Orders.Handles.Order
+namespace Hotline.Application.Orders.Handlers.OrderHandler
 {
     public class OrderRelateCallHandler : ICapSubscribe, ITransientDependency
     {

+ 2 - 10
src/Hotline.Application/Orders/Handles/OrderHandler/OrderVisitSmsHandler.cs → src/Hotline.Application/Orders/Handlers/OrderHandler/OrderVisitSmsHandler.cs

@@ -1,23 +1,15 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using DotNetCore.CAP;
-using Hotline.FlowEngine.Workflows;
+using DotNetCore.CAP;
 using Hotline.Orders;
-using Hotline.Orders.Notifications;
 using Hotline.Push.FWMessage;
 using Hotline.Push.Notifies;
 using Hotline.Share.Dtos.Push;
 using Hotline.Share.Enums.Push;
 using Hotline.Share.Mq;
-using Hotline.Share.Tools;
 using MediatR;
 using XF.Domain.Dependency;
 using XF.Domain.Repository;
 
-namespace Hotline.Application.Orders.Handles.Order;
+namespace Hotline.Application.Orders.Handlers.OrderHandler;
 public class OrderVisitSmsHandler : INotificationHandler<ReceiveMessageNotify>
 {
     private readonly IOrderVisitDomainService _orderVisitDomainService;

+ 1 - 5
src/Hotline.Application/Orders/Handles/OrderHandler/TranspondCityNotifyHandler.cs → src/Hotline.Application/Orders/Handlers/OrderHandler/TranspondCityNotifyHandler.cs

@@ -1,5 +1,4 @@
 using DotNetCore.CAP;
-using Hotline.EventBus;
 using Hotline.Orders;
 using Hotline.Orders.Notifications;
 using Hotline.OrderTranspond;
@@ -7,13 +6,10 @@ using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.Order;
 using MapsterMapper;
 using MediatR;
-using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
-using System;
-using Hotline.DI;
 using XF.Domain.Repository;
 
-namespace Hotline.Application.Orders.Handles.Order
+namespace Hotline.Application.Orders.Handlers.OrderHandler
 {
     // [Injection(AppScopes = EAppScope.YiBin)]
     public class TranspondCityNotifyHandler : INotificationHandler<OrderStartWorkflowNotify>

+ 1 - 1
src/Hotline.Application/Orders/Handles/OrderHandler/UpdateOrderPushMessageNotifyHandler.cs → src/Hotline.Application/Orders/Handlers/OrderHandler/UpdateOrderPushMessageNotifyHandler.cs

@@ -6,7 +6,7 @@ using Hotline.Share.Enums.Push;
 using MediatR;
 using Microsoft.Extensions.Logging;
 
-namespace Hotline.Application.Orders.Handles.Order
+namespace Hotline.Application.Orders.Handlers.OrderHandler
 {
     public class UpdateOrderPushMessageNotifyHandler : INotificationHandler<UpdateOrderNotify>
     {

+ 34 - 3
src/Hotline.Application/Orders/Handles/OrderScreenHandler/OrderScreenEndWorkflowHandler.cs → src/Hotline.Application/Orders/Handlers/OrderScreenHandler/OrderScreenEndWorkflowHandler.cs

@@ -3,16 +3,19 @@ using Hotline.Configurations;
 using Hotline.FlowEngine.Notifications;
 using Hotline.FlowEngine.WorkflowModules;
 using Hotline.Orders;
+using Hotline.Push.Notifies;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.Order;
+using Hotline.Share.Enums.Push;
+using Hotline.Users;
 using MapsterMapper;
 using MediatR;
 using Microsoft.Extensions.Options;
 using XF.Domain.Authentications;
 using XF.Domain.Repository;
 
-namespace Hotline.Application.Orders.Handles.OrderScreenHandler;
+namespace Hotline.Application.Orders.Handlers.OrderScreenHandler;
 public class OrderScreenEndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
 {
     private readonly IOrderRepository _orderRepository;
@@ -24,6 +27,8 @@ public class OrderScreenEndWorkflowHandler : INotificationHandler<EndWorkflowNot
     private readonly ISessionContext _sessionContext;
     private readonly IRepository<OrderScreenDetail> _orderScreenDetailRepository;
     private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
+    private readonly IMediator _mediator;
+    private readonly IRepository<User> _userRepository;
 
     public OrderScreenEndWorkflowHandler(
         IOrderRepository orderRepository,
@@ -34,7 +39,9 @@ public class OrderScreenEndWorkflowHandler : INotificationHandler<EndWorkflowNot
         IRepository<OrderVisit> orderVisitRepository,
         ISessionContext sessionContext,
         IRepository<OrderScreenDetail> orderScreenDetailRepository,
-         IOptionsSnapshot<AppConfiguration> appOptions)
+        IOptionsSnapshot<AppConfiguration> appOptions,
+        IMediator mediator,
+        IRepository<User> userRepository)
     {
         _orderRepository = orderRepository;
         _capPublisher = capPublisher;
@@ -45,7 +52,8 @@ public class OrderScreenEndWorkflowHandler : INotificationHandler<EndWorkflowNot
         _sessionContext = sessionContext;
         _orderScreenDetailRepository = orderScreenDetailRepository;
         _appOptions = appOptions;
-
+        _mediator = mediator;
+        _userRepository = userRepository;
     }
 
     /// <summary>Handles a notification</summary>
@@ -142,6 +150,29 @@ public class OrderScreenEndWorkflowHandler : INotificationHandler<EndWorkflowNot
                 };
                 detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 1);
                 await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);
+
+                //这里处理甄别完成后发送短信
+                if (_appOptions.Value.IsZiGong)
+                {
+                    var user = await _userRepository.GetAsync(p => p.Id == screen.CreatorId, cancellationToken);
+                    if (user != null)
+                    {
+                        var isReviewPassText = isReviewPass == true ? "审批通过" : "审批拒绝";
+                        var messageDto = new Share.Dtos.Push.MessageDto
+                        {
+                            PushBusiness = EPushBusiness.ScreenEnd,
+                            ExternalId = screen.Id,
+                            OrderId = screen.Id,
+                            PushPlatform = EPushPlatform.Sms,
+                            Remark = screen.No + isReviewPassText,
+                            Name = screen.CreatorName,
+                            TemplateCode = "1019",
+                            Params = new List<string>() { screen.No, isReviewPassText },
+                            TelNumber = user.PhoneNo,
+                        };
+                        await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
+                    }
+                }
             }
         }
     }

+ 1 - 1
src/Hotline.Application/Orders/Handles/OrderScreenHandler/OrderScreenNextWorkflowHandler.cs → src/Hotline.Application/Orders/Handlers/OrderScreenHandler/OrderScreenNextWorkflowHandler.cs

@@ -13,7 +13,7 @@ using XF.Domain.Authentications;
 using XF.Domain.Extensions;
 using XF.Domain.Repository;
 
-namespace Hotline.Application.Orders.Handles.OrderScreen;
+namespace Hotline.Application.Orders.Handlers.OrderScreenHandler;
 public class OrderScreenNextWorkflowHandler : INotificationHandler<NextStepNotify>
 {
     private readonly ICapPublisher _capPublisher;

+ 1 - 1
src/Hotline.Application/Orders/Handles/OrderScreenHandler/OrderScreenStartWorkflowHandler.cs → src/Hotline.Application/Orders/Handlers/OrderScreenHandler/OrderScreenStartWorkflowHandler.cs

@@ -3,7 +3,7 @@ using Hotline.FlowEngine.WorkflowModules;
 using Hotline.Orders;
 using MediatR;
 
-namespace Hotline.Application.Orders.Handles.OrderScreen;
+namespace Hotline.Application.Orders.Handlers.OrderScreenHandler;
 
 public class OrderScreenStartWorkflowHandler : INotificationHandler<StartWorkflowNotify>
 {

+ 2 - 16
src/Hotline.Application/Orders/Handles/SnapshotHandler/GuiderSystemTimeoutHandler.cs → src/Hotline.Application/Orders/Handlers/SnapshotHandler/GuiderSystemTimeoutHandler.cs

@@ -1,24 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Hotline.Application.Orders;
-using Hotline.Authentications;
-using Hotline.Caching.Interfaces;
-using Hotline.EventBus;
-using Hotline.FlowEngine.Notifications;
-using Hotline.FlowEngine.Workflows;
-using Hotline.Orders;
+using Hotline.Caching.Interfaces;
 using Hotline.Settings;
-using Hotline.Share.Dtos.FlowEngine;
-using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Tools;
 using Hotline.Snapshot.Notifications;
 using MediatR;
-using XF.Domain.Exceptions;
 
-namespace Hotline.Application.Orders.Handles.Snapshot
+namespace Hotline.Application.Orders.Handlers.SnapshotHandler
 {
     /// <summary>
     /// 需求:坐席派给网格员的安全隐患工单若未推送成功超过4小时或者网格员超过4小时没回复,则自动流转到标注节点待标注列表

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

@@ -14,8 +14,10 @@ using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Settings;
 using Hotline.Share.Requests;
+using Hotline.Users;
 using SqlSugar;
 using XF.Domain.Authentications;
+using XF.Domain.Exceptions;
 
 namespace Hotline.Application.Orders
 {
@@ -457,5 +459,9 @@ namespace Hotline.Application.Orders
 
         Task OrderPrevious(OrderSendBackAudit sendBack, Order order, CancellationToken cancellationToken);
 
-	}
+        /// <summary>
+        /// 依据当前待办节点随意获取一个合法办理人
+        /// </summary>
+        Task<User> GetHandlerRandomAsync(WorkflowStep step, CancellationToken cancellationToken);
+    }
 }

+ 208 - 90
src/Hotline.Application/Orders/OrderApplication.cs

@@ -45,6 +45,7 @@ using PanGu;
 using SqlSugar;
 using System.Data;
 using System.Dynamic;
+using ExtendedNumerics.Exceptions;
 using FluentValidation;
 using Hotline.FlowEngine.Definitions;
 using Hotline.FlowEngine.Notifications;
@@ -61,6 +62,7 @@ using Quartz.Simpl;
 using J2N.Text;
 using Hotline.Application.FlowEngine;
 using Hotline.Article;
+using Hotline.Share.Dtos.CallCenter;
 
 namespace Hotline.Application.Orders;
 
@@ -110,8 +112,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly IRepository<OrderTsDetails> _orderTsDetailsRepository;
     private readonly IRepository<KnowledgeQuote> _knowledgeQuoteRepository;
     private readonly IRepository<OrderSpecial> _orderSpecialRepository;
+    private readonly IRepository<User> _userRepository;
     private readonly IWorkflowApplication _workflowApplication;
     private readonly ICircularRecordDomainService _circularRecordDomainService;
+    private readonly ISessionContextManager _sessionContextManager;
 
     public OrderApplication(
         IOrderDomainService orderDomainService,
@@ -157,8 +161,12 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         IRepository<OrderTsDetails> orderTsDetailsRepository,
         IRepository<KnowledgeQuote> knowledgeQuoteRepository,
         IRepository<OrderSpecial> orderSpecialRepository,
+        IRepository<User> userRepository,
         IWorkflowApplication workflowApplication,
-        ICircularRecordDomainService circularRecordDomainService)
+        ICircularRecordDomainService circularRecordDomainService,
+        ISessionContextCreator sessionContextCreator,
+        ISessionContextManager sessionContextManager
+        )
     {
         _orderDomainService = orderDomainService;
         _workflowDomainService = workflowDomainService;
@@ -203,8 +211,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _orderTsDetailsRepository = orderTsDetailsRepository;
         _knowledgeQuoteRepository = knowledgeQuoteRepository;
         _orderSpecialRepository = orderSpecialRepository;
+        _userRepository = userRepository;
         _workflowApplication = workflowApplication;
         _circularRecordDomainService = circularRecordDomainService;
+        _sessionContextManager = sessionContextManager;
     }
 
     /// <summary>
@@ -343,9 +353,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     public ISugarQueryable<Order> GetAboutToExpireAsync(AboutToExpireListDto dto)
     {
         DateTime? dateTime = DateTime.Now;
-        var IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
-        int orgLevel = _sessionContextProvider.SessionContext.OrgLevel;
-        var orgCode = _sessionContextProvider.SessionContext.OrgId;
+        var IsCenter = _sessionContext.OrgIsCenter;
+        int orgLevel = _sessionContext.OrgLevel;
+        var orgCode = _sessionContext.OrgId;
         var query = _orderRepository.Queryable();
         if (IsCenter == true)
             query = _orderRepository.Queryable(canView: !IsCenter);
@@ -354,11 +364,11 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .WhereIF(orgLevel == 3, d => SqlFunc.Subqueryable<WorkflowStep>()
                 .Where(step => step.ExternalId == d.Id && step.Status != EWorkflowStepStatus.Handled &&
                                ((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) &&
-                                 step.HandlerId == _sessionContextProvider.SessionContext.RequiredUserId) ||
+                                 step.HandlerId == _sessionContext.RequiredUserId) ||
                                 (step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) &&
-                                 step.HandlerOrgId == _sessionContextProvider.SessionContext.RequiredOrgId) ||
+                                 step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
                                 (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) &&
-                                 _sessionContextProvider.SessionContext.Roles.Contains(step.RoleId))))
+                                 _sessionContext.Roles.Contains(step.RoleId))))
                 .Any())
             .WhereIF(orgLevel == 2 || orgLevel == 1, d => SqlFunc.Subqueryable<WorkflowStep>()
                 .Where(step => step.ExternalId == d.Id &&
@@ -428,9 +438,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     //    //stTime = _timeLimitDomainService.WorkDay(stTime);
     //    //DateTime stTime2 = _timeLimitDomainService.WorkDay(DateTime.Now);
     //    DateTime? dateTime = DateTime.Now;
-    //    var IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
-    //    int orgLevel = _sessionContextProvider.SessionContext.OrgLevel;
-    //    var orgCode = _sessionContextProvider.SessionContext.OrgId;
+    //    var IsCenter = _sessionContext.OrgIsCenter;
+    //    int orgLevel = _sessionContext.OrgLevel;
+    //    var orgCode = _sessionContext.OrgId;
     //    //var query = _orderRepository.Queryable();
     //    //if (IsCenter == true)
     //    //    query = _orderRepository.Queryable(canView: !IsCenter);
@@ -440,11 +450,11 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     //        .WhereIF(orgLevel == 3, d => SqlFunc.Subqueryable<WorkflowStep>()
     //            .Where(step => step.ExternalId == d.Id && step.Status != EWorkflowStepStatus.Handled &&
     //                           ((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) &&
-    //                             step.HandlerId == _sessionContextProvider.SessionContext.RequiredUserId) ||
+    //                             step.HandlerId == _sessionContext.RequiredUserId) ||
     //                            (step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) &&
-    //                             step.HandlerOrgId == _sessionContextProvider.SessionContext.RequiredOrgId) ||
+    //                             step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
     //                            (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) &&
-    //                             _sessionContextProvider.SessionContext.Roles.Contains(step.RoleId))))
+    //                             _sessionContext.Roles.Contains(step.RoleId))))
     //            .Any())
     //         .WhereIF(orgLevel == 2 || orgLevel == 1, d => SqlFunc.Subqueryable<WorkflowStep>()
     //            .Where(step => step.ExternalId == d.Id &&
@@ -533,18 +543,18 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     {
         // DateTime stTime = _timeLimitDomainService.WorkDay(DateTime.Now);
         DateTime stTime = _expireTime.WorkDay(DateTime.Now).GetAwaiter().GetResult();
-        var IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
-        int orgLevel = _sessionContextProvider.SessionContext.OrgLevel;
-        var orgCode = _sessionContextProvider.SessionContext.OrgId;
+        var IsCenter = _sessionContext.OrgIsCenter;
+        int orgLevel = _sessionContext.OrgLevel;
+        var orgCode = _sessionContext.OrgId;
         return _orderRepository.Queryable(canView: false).Includes(d => d.OrderDelays)
             .WhereIF(orgLevel == 3, d => SqlFunc.Subqueryable<WorkflowStep>()
                 .Where(step => step.ExternalId == d.Id && step.Status != EWorkflowStepStatus.Handled &&
                                ((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) &&
-                                 step.HandlerId == _sessionContextProvider.SessionContext.RequiredUserId) ||
+                                 step.HandlerId == _sessionContext.RequiredUserId) ||
                                 (step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) &&
-                                 step.HandlerOrgId == _sessionContextProvider.SessionContext.RequiredOrgId) ||
+                                 step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
                                 (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) &&
-                                 _sessionContextProvider.SessionContext.Roles.Contains(step.RoleId))))
+                                 _sessionContext.Roles.Contains(step.RoleId))))
                 .Any())
             // .WhereIF(orgLevel == 2 || orgLevel == 1, d =>  d.ActualHandleOrgCode.StartsWith(orgCode))
             .WhereIF(orgLevel == 2 || orgLevel == 1, d => SqlFunc.Subqueryable<WorkflowStep>()
@@ -699,13 +709,16 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// <summary>
     /// 接收外部平台工单
     /// </summary>
-    public Task<AddOrderResponse> ReceiveOrderFromExternalAsync(AddOrderDto dto, CancellationToken cancellationToken)
+    public async Task<AddOrderResponse> ReceiveOrderFromExternalAsync(AddOrderDto dto, CancellationToken cancellationToken)
     {
         switch (dto.Source)
         {
             case ESource.ProvinceStraight:
-                SessionContextCreator.CreateSessionContext(_sessionContextProvider, "province");
-                return ReceiveOrderFromProvinceAsync(dto, dto.Files, cancellationToken);
+                //SessionContextCreator.CreateSessionContext(_sessionContextProvider, "province");
+                //await _sessionContextCreator.CreateSessionContextAsync("province", cancellationToken);
+                _sessionContextManager.ChangeSessionContext("province");
+
+                return await ReceiveOrderFromProvinceAsync(dto, dto.Files, cancellationToken);
             case ESource.Police110:
             case ESource.CityDataExchangeLz:
             case ESource.CityDataExchangeYB:
@@ -723,11 +736,11 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             case ESource.ZGGC:
             case ESource.ZGTFTB:
             case ESource.YBHumanSocietyAPP:
-                return ReceiveOrderFromOtherPlatformAsync(dto, dto.Files, cancellationToken);
+                return await ReceiveOrderFromOtherPlatformAsync(dto, dto.Files, cancellationToken);
             case ESource.Hotline:
             case ESource.HotlineImport:
             default:
-                return ReceiveOrderFromOtherPlatformAsync(dto, dto.Files, cancellationToken);
+                return await ReceiveOrderFromOtherPlatformAsync(dto, dto.Files, cancellationToken);
         }
     }
 
@@ -741,9 +754,13 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 
         var order = await _orderRepository.Queryable()
             .FirstAsync(d => d.Id == dto.Id || d.No == dto.OrderNo, cancellationToken);
+
         if (order != null && dto.Files != null && dto.Files.Any())
         {
-            order.FileJson = await _fileRepository.AddFileAsync(dto.Files, order.Id, "", cancellationToken);
+            List<FileJson> file = order.FileJson;
+            List<FileJson> fileNew = await _fileRepository.AddFileAsync(dto.Files, order.Id, cancellationToken);
+            file.AddRange(fileNew);
+            order.FileJson = file;
             await _orderRepository.UpdateAsync(order, cancellationToken);
         }
     }
@@ -1155,7 +1172,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 expiredTimeConfig.TimeText, expiredTimeConfig.Count,
                 expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime,
                 expiredTimeConfig.NearlyExpiredTime, expiredTimeConfig.NearlyExpiredTimeOne, dto.Workflow.Opinion,
-                _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
+                _sessionContext.RequiredUserId, _sessionContext.UserName,
                 canUpdateOrderSender);
             //TODO发送短信即将超期
             //_capPublisher.PublishDelay(expiredTimeConfig.NearlyExpiredTime - DateTime.Now, EventNames.HotlineOrderNearlyExpiredTimeSms, new PublishNearlyExpiredTimeSmsDto() { OrderId = order.Id });
@@ -1188,7 +1205,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 expiredTimeConfig.TimeText, expiredTimeConfig.Count,
                 expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime,
                 expiredTimeConfig.NearlyExpiredTime, expiredTimeConfig.NearlyExpiredTimeOne, dto.Workflow.Opinion,
-                _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
+                _sessionContext.RequiredUserId, _sessionContext.UserName,
                 canUpdateOrderSender);
             //TODO发送短信即将超期
             //_capPublisher.PublishDelay(expiredTimeConfig.NearlyExpiredTime - DateTime.Now, EventNames.HotlineOrderNearlyExpiredTimeSms, new PublishNearlyExpiredTimeSmsDto() { OrderId = order.Id });
@@ -1270,11 +1287,11 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         if (_appOptions.Value.IsZiGong == true)
         {
             if (string.IsNullOrEmpty(visit.EmployeeId))
-                visit.EmployeeId = _sessionContextProvider.SessionContext.UserId;
+                visit.EmployeeId = _sessionContext.UserId;
         }
         else
         {
-            visit.EmployeeId = _sessionContextProvider.SessionContext.UserId;
+            visit.EmployeeId = _sessionContext.UserId;
         }
 
         visit.CallId = dto.CallId;
@@ -1332,10 +1349,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         //handle visit trace
         //上面取得当前操作人,需求变动前暂时可以这样写
         var visitor = new UserInfo(
-            _sessionContextProvider.SessionContext.UserId,
-            _sessionContextProvider.SessionContext.UserName,
-            _sessionContextProvider.SessionContext.OrgId,
-            _sessionContextProvider.SessionContext.OrgName);
+            _sessionContext.UserId,
+            _sessionContext.UserName,
+            _sessionContext.OrgId,
+            _sessionContext.OrgName);
         await _workflowDomainService.HandleVisitTraceAsync(visit.Id, visitor, visit.VisitTime ?? DateTime.Now, cancellationToken);
 
         var orderDto = _mapper.Map<OrderDto>(visit.Order);
@@ -1363,7 +1380,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 Id = visit.Id,
                 Order = orderDto,
                 OrderVisitDetails = _mapper.Map<List<VisitDetailDto>>(visit.OrderVisitDetails),
-                VisitName = _sessionContextProvider.SessionContext.UserName,
+                VisitName = _sessionContext.UserName,
                 VisitTime = visit.VisitTime,
                 VisitType = visit.VisitType,
                 VisitState = visit.VisitState,
@@ -1414,7 +1431,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 .Where(m => m.Id == item.Id)
                 .SetColumns(m => m.VisitState == EVisitState.SMSVisiting)
                 // .SetColumns(m => m.VisitType == EVisitType.SmsVisit)
-                .SetColumns(m => m.EmployeeId == _sessionContextProvider.SessionContext.RequiredUserId)
+                .SetColumns(m => m.EmployeeId == _sessionContext.RequiredUserId)
                 .ExecuteCommandAsync(cancellationToken);
 
             // 发送短信后推送一个 48小时的延迟消息队列. 当消息队列收到消息时, 判断用户是否回复了, 如果未回复短信就 默认满意
@@ -1459,7 +1476,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 
     public ISugarQueryable<Order> QueryOrders(QueryOrderDto dto)
     {
-        var isCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
+        var isCenter = _sessionContext.OrgIsCenter;
 
         var query = _orderRepository.Queryable(canView: false);
         if (!isCenter)
@@ -1467,7 +1484,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             query.Where(d => SqlFunc.Subqueryable<WorkflowStep>()
                 .Where(step => step.ExternalId == d.Id &&
                                !string.IsNullOrEmpty(step.HandlerOrgId) &&
-                               step.HandlerOrgId.StartsWith(_sessionContextProvider.SessionContext.RequiredOrgId)).Any());
+                               step.HandlerOrgId.StartsWith(_sessionContext.RequiredOrgId)).Any());
         }
 
         query = query.Includes(d => d.OrderScreens).Includes(d => d.OrderTags);
@@ -1597,8 +1614,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 .OrderByIF(dto is { SortField: "hotspotName", SortRule: 1 }, d => d.HotspotName, OrderByType.Desc) //热点分类降序
                 .OrderByIF(dto is { SortField: "acceptorName", SortRule: 0 }, d => d.AcceptorName, OrderByType.Asc) //受理人升序
                 .OrderByIF(dto is { SortField: "acceptorName", SortRule: 1 }, d => d.AcceptorName, OrderByType.Desc) //受理人降序
-                .OrderByIF(dto is { SortField: "actualHandleTime", SortRule: 0 }, d => d.ActualHandleTime, OrderByType.Asc) //接办时间升序
-                .OrderByIF(dto is { SortField: "actualHandleTime", SortRule: 1 }, d => d.ActualHandleTime, OrderByType.Desc) //接办时间降序
+                .OrderByIF(dto is { SortField: "currentStepAcceptTime", SortRule: 0 }, d => d.CurrentStepAcceptTime, OrderByType.Asc) //接办时间升序
+                .OrderByIF(dto is { SortField: "currentStepAcceptTime", SortRule: 1 }, d => d.CurrentStepAcceptTime, OrderByType.Desc) //接办时间降序
             ;
 
         return query;
@@ -1611,14 +1628,14 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// <returns></returns>
     public ISugarQueryable<Order, WorkflowStep> QueryUnsignedOrders(QueryUnsignedOrdersRequest dto)
     {
-        var IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
+        var IsCenter = _sessionContext.OrgIsCenter;
         return _orderRepository.Queryable()
             .LeftJoin<WorkflowStep>((x, ws) => x.Id == ws.ExternalId)
             .WhereIF(dto.StartTime.HasValue, (x, ws) => ws.CreationTime >= dto.StartTime)
             .WhereIF(dto.EndTime.HasValue, (x, ws) => ws.CreationTime <= dto.EndTime)
-            .WhereIF(dto.Level == 0 && IsCenter == false, (x, ws) => ws.AcceptorOrgId.StartsWith(_sessionContextProvider.SessionContext.OrgId))
-            .WhereIF(dto.Level == 1, (x, ws) => ws.AcceptorOrgId == _sessionContextProvider.SessionContext.OrgId)
-            .WhereIF(dto.Level == 2, (x, ws) => ws.AcceptorOrgId.StartsWith(_sessionContextProvider.SessionContext.OrgId))
+            .WhereIF(dto.Level == 0 && IsCenter == false, (x, ws) => ws.AcceptorOrgId.StartsWith(_sessionContext.OrgId))
+            .WhereIF(dto.Level == 1, (x, ws) => ws.AcceptorOrgId == _sessionContext.OrgId)
+            .WhereIF(dto.Level == 2, (x, ws) => ws.AcceptorOrgId.StartsWith(_sessionContext.OrgId))
             .WhereIF(dto.Signed == 0, (x, ws) => ws.Status == Share.Enums.FlowEngine.EWorkflowStepStatus.WaitForAccept)
             .WhereIF(dto.Signed == 1, (x, ws) => ws.Status == Share.Enums.FlowEngine.EWorkflowStepStatus.WaitForHandle)
             .Where((x, ws) => ws.CountersignPosition == Share.Enums.FlowEngine.ECountersignPosition.None && x.Status > EOrderStatus.WaitForAccept)
@@ -1666,7 +1683,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 
         //dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
 
-        var IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
+        var IsCenter = _sessionContext.OrgIsCenter;
 
 
         var queryOrder = _systemOrganizeRepository.Queryable()
@@ -1675,7 +1692,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= dto.EndTime)
             .WhereIF(dto.TypeId != null && dto.TypeId == 1, (x, o) => o.IdentityType == EIdentityType.Citizen)
             .WhereIF(dto.TypeId != null && dto.TypeId == 2, (x, o) => o.IdentityType == EIdentityType.Enterprise)
-            .WhereIF(IsCenter == false, (x, o) => o.ActualHandleOrgCode == _sessionContextProvider.SessionContext.RequiredOrgId)
+            .WhereIF(IsCenter == false, (x, o) => o.ActualHandleOrgCode == _sessionContext.RequiredOrgId)
             .GroupBy((x, o) => new { x.Id, x.Name })
             .Select((x, o) => new OrderBiOrgDataListVo
             {
@@ -1795,7 +1812,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// <returns></returns>
     public ISugarQueryable<Order> QueryOrgDataListDetail(OrgDataListAllDetailRequest dto)
     {
-        bool IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
+        bool IsCenter = _sessionContext.OrgIsCenter;
 
         var quer = _orderRepository.Queryable()
             .InnerJoin<SystemOrganize>((x, so) => x.ActualHandleOrgCode == so.Id && so.Level == 1)
@@ -1805,7 +1822,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .Where((x, so) =>
                 (x.Status >= EOrderStatus.Filed && x.ExpiredTime < x.FiledTime) ||
                 (x.Status < EOrderStatus.Filed && x.ExpiredTime < SqlFunc.GetDate()))
-            .WhereIF(IsCenter == false, (x, so) => x.ActualHandleOrgCode == _sessionContextProvider.SessionContext.RequiredOrgId)
+            .WhereIF(IsCenter == false, (x, so) => x.ActualHandleOrgCode == _sessionContext.RequiredOrgId)
             .WhereIF(!string.IsNullOrEmpty(dto.OrgName), (x, so) => x.AcceptorOrgName == dto.OrgName)
             .Select(x => new Order { DaysOverdueOrgName = x.ActualHandleOrgName, Id = x.Id.SelectAll() });
 
@@ -1817,7 +1834,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .Where((x, so) => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime)
             .Where((x, so) => (x.Status == Share.Enums.FlowEngine.EWorkflowStepStatus.Handled && x.StepExpiredTime < x.HandleTime) ||
                               (x.Status != Share.Enums.FlowEngine.EWorkflowStepStatus.Handled && x.StepExpiredTime < SqlFunc.GetDate()))
-            .WhereIF(IsCenter == false, (x, so) => x.HandlerOrgId == _sessionContextProvider.SessionContext.RequiredOrgId)
+            .WhereIF(IsCenter == false, (x, so) => x.HandlerOrgId == _sessionContext.RequiredOrgId)
             .WhereIF(dto.ExpiredType is 2, (x, so, o) => o.OrderDelays.Any(x => x.DelayState == EDelayState.Pass))
             .GroupBy(x => new { x.ExternalId, x.HandlerOrgName })
             .Select(x => new { Id = x.ExternalId, WorkflowId = x.ExternalId, HandlerOrgName = x.HandlerOrgName });
@@ -1927,9 +1944,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// <returns></returns>
     public async Task<List<VisitAndOrgSatisfactionStatisticsDto>> VisitAndOrgSatisfactionStatistics(PagedKeywordSonRequest dto)
     {
-        bool IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
-        var orgLevel = _sessionContextProvider.SessionContext.OrgLevel;
-        string orgLevelStr = (_sessionContextProvider.SessionContext.RequiredOrgId.Length + 3).ToString();
+        bool IsCenter = _sessionContext.OrgIsCenter;
+        var orgLevel = _sessionContext.OrgLevel;
+        string orgLevelStr = (_sessionContext.RequiredOrgId.Length + 3).ToString();
 
         var list = _orderVisitDetailRepository.Queryable()
             .Where(x => x.OrderVisit.VisitTime >= dto.StartTime.Value && x.OrderVisit.VisitTime <= dto.EndTime.Value &&
@@ -1938,7 +1955,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .WhereIF(string.IsNullOrEmpty(dto.LineNum) == false, x => x.OrderVisit.Order.CallRecord.Gateway.Contains(dto.LineNum))
             .WhereIF(dto.TypeCode != null && dto.TypeCode == 1, x => x.OrderVisit.Order.IdentityType == EIdentityType.Citizen)
             .WhereIF(dto.TypeCode != null && dto.TypeCode == 2, x => x.OrderVisit.Order.IdentityType == EIdentityType.Enterprise)
-            .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContextProvider.SessionContext.OrgId))
+            .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContext.OrgId))
             .WhereIF(dto.VisitType != null, x => x.OrderVisit.VisitType == dto.VisitType)
             .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.OrderVisit.Order.Title.Contains(dto.Title)) // 工单标题
             .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.OrderVisit.Order.No == dto.No) // 工单编号
@@ -2092,7 +2109,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         {
             var query = _statisticsDepartSatisfiedRepository.Queryable()
                 .LeftJoin<SystemOrganize>((x, so) => x.DepartmentId == so.oldBmid)
-                .WhereIF(IsCenter == false, (x, so) => so.Id.StartsWith(_sessionContextProvider.SessionContext.OrgId))
+                .WhereIF(IsCenter == false, (x, so) => so.Id.StartsWith(_sessionContext.OrgId))
                 .Where((x, so) => x.Time >= dto.StartTime.Value && x.Time <= dto.EndTime.Value);
             if (IsCenter)
             {
@@ -2195,7 +2212,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// <returns></returns>
     public async Task<List<VisitAndOrgSatisfactionStatisticsDto>> VisitAndOrgStatisfactionOrgDetail(PagedKeywordSonRequest dto)
     {
-        bool IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
+        bool IsCenter = _sessionContext.OrgIsCenter;
         var org = await _systemOrganizeRepository.Queryable().FirstAsync(x => x.Id == dto.OrgCode);
 
         string orgLevelStr = (dto.OrgCode.Length + 3).ToString();
@@ -2215,7 +2232,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .WhereIF(dto.TypeCode != null && dto.TypeCode == 2,
                 (x, it) => it.OrderVisit.Order.IdentityType == EIdentityType.Enterprise)
             .WhereIF(IsCenter == false,
-                (x, it) => it.VisitOrgCode.StartsWith(_sessionContextProvider.SessionContext.OrgId))
+                (x, it) => it.VisitOrgCode.StartsWith(_sessionContext.OrgId))
             .WhereIF(dto.VisitType != null, (x, it) => it.OrderVisit.VisitType == dto.VisitType)
             .GroupBy((x, it) => new
             {
@@ -2647,7 +2664,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// <returns></returns>
     public async Task<List<VisitAndHotspotSatisfactionStatisticsDto>> VisitAndHotspotSatisfactionStatistics(VisitAndHotspotPagedKeywordRequest dto)
     {
-        bool IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
+        bool IsCenter = _sessionContext.OrgIsCenter;
 
         var list = _orderVisitDetailRepository.Queryable()
             .Includes(x => x.OrderVisit, v => v.Order)
@@ -2657,7 +2674,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .Where(x => x.OrderVisit.VisitTime >= dto.StartTime.Value && x.OrderVisit.VisitTime <= dto.EndTime.Value &&
                         x.VisitTarget == EVisitTarget.Org && x.OrderVisit.VisitState == EVisitState.Visited && !string.IsNullOrEmpty(x.VisitOrgCode))
             .WhereIF(string.IsNullOrEmpty(dto.HotspotName) == false, (x, h) => h.HotSpotName == dto.HotspotName)
-            .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContextProvider.SessionContext.OrgId))
+            .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContext.OrgId))
             .WhereIF(dto.TypeId == 1, x => x.OrgProcessingResults != null)
             .WhereIF(dto.TypeId == 2, x => x.OrgHandledAttitude != null);
 
@@ -2796,7 +2813,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// <returns></returns>
     public ISugarQueryable<OrderVisitDetail> VisitAndHotspotSatisfactionDetail(VisitAndHotspotPagedKeywordRequest dto)
     {
-        bool IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
+        bool IsCenter = _sessionContext.OrgIsCenter;
         var key = string.Empty;
         if (!string.IsNullOrEmpty(dto.TitleCode))
         {
@@ -2831,7 +2848,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .Where(x => x.OrderVisit.VisitTime >= dto.StartTime && x.OrderVisit.VisitTime <= dto.EndTime && x.VisitTarget == EVisitTarget.Org &&
                         x.OrderVisit.VisitState == EVisitState.Visited)
             .WhereIF(!string.IsNullOrEmpty(dto.HotspotName), x => x.OrderVisit.Order.Hotspot.HotSpotFullName.StartsWith(dto.HotspotName))
-            .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContextProvider.SessionContext.OrgId))
+            .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContext.OrgId))
             .WhereIF(dto.TypeId is 1, x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == key)
             .WhereIF(dto.TypeId is 2, x => SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == key);
     }
@@ -3078,6 +3095,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .Where(x => x.HandlerName != null && x.HandlerName != "")
             .WhereIF(dto.AuditType is 1, x => x.Name == "班长审批")
             .WhereIF(dto.AuditType is 2, x => x.Name == "中心领导")
+             .WhereIF(_appOptions.Value.IsZiGong && dto.AuditType is 3, x => x.Name == "中心初审")
             .GroupBy(x => new { x.HandlerName })
             .Select(x => new OrderScreenAuditVo
             {
@@ -3269,33 +3287,30 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             //    x => SqlFunc.JsonListObjectAny(x.OrgHandledAttitude, "Key", dto.OrgHandledAttitude))
             //.WhereIF(!string.IsNullOrEmpty(dto.OrgNoSatisfiedReason),
             //    x => SqlFunc.JsonField(x.OrgNoSatisfiedReason, "Key") == dto.OrgNoSatisfiedReason)
-            .Where(x => x.OrderVisit.VisitState == EVisitState.Visited && x.OrderVisit.IsCanHandle);
+            .Where(x => x.OrderVisit.VisitState == EVisitState.Visited && x.OrderVisit.IsCanHandle)
+            .WhereIF(dto.DataScope is 1, x => x.VisitOrgCode == _sessionContext.OrgId);
         if (_sessionContext.OrgId != null && !_sessionContext.OrgIsCenter)
         {
-            query.WhereIF(!string.IsNullOrEmpty(dto.Keyword),
-                    x => x.OrderVisit.Order.Title.Contains(dto.Keyword!) ||
-                         x.OrderVisit.Order.No.Contains(dto.Keyword!))
-                .Where(x => x.VisitTarget == EVisitTarget.Org && x.VisitOrgCode == _sessionContext.OrgId && (
+            query.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrderVisit.Order.Title.Contains(dto.Keyword!) || x.OrderVisit.Order.No.Contains(dto.Keyword!))
+                .Where(x => x.VisitTarget == EVisitTarget.Org && (
                     SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1" ||
                     SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "2" ||
                     SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "1" ||
                     SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2"
-                ));
+                ))
+                .WhereIF(dto.DataScope is 0, x => x.VisitOrgCode.StartsWith(_sessionContext.OrgId))
+                ;
         }
         else
         {
-            query.WhereIF(!string.IsNullOrEmpty(dto.Keyword),
-                    x => x.OrderVisit.Order.Title.Contains(dto.Keyword!) ||
-                         x.OrderVisit.Order.No.Contains(dto.Keyword!))
+            query.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrderVisit.Order.Title.Contains(dto.Keyword!) || x.OrderVisit.Order.No.Contains(dto.Keyword!))
                 .WhereIF(dto.ScreenType == EOrderScreenType.Org, x => x.VisitTarget == EVisitTarget.Org && (
                     SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1" ||
                     SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "2" ||
                     SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "1" ||
                     SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2"
                 ))
-                .WhereIF(dto.ScreenType == EOrderScreenType.Seat,
-                    x => x.VisitTarget == EVisitTarget.Seat &&
-                         (x.SeatEvaluate == ESeatEvaluate.VeryNoSatisfied || x.SeatEvaluate == ESeatEvaluate.NoSatisfied))
+                .WhereIF(dto.ScreenType == EOrderScreenType.Seat, x => x.VisitTarget == EVisitTarget.Seat && (x.SeatEvaluate == ESeatEvaluate.VeryNoSatisfied || x.SeatEvaluate == ESeatEvaluate.NoSatisfied))
                 ;
         }
 
@@ -3307,7 +3322,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .OrderByIF(dto is { SortRule: 1, SortField: "order.filedTime" }, x => x.OrderVisit.Order.FiledTime, OrderByType.Desc)
             .OrderByIF(dto is { SortRule: 0, SortField: "orderVisit.visitTime" }, x => x.OrderVisit.VisitTime, OrderByType.Asc)
             .OrderByIF(dto is { SortRule: 1, SortField: "orderVisit.visitTime" }, x => x.OrderVisit.VisitTime, OrderByType.Desc)
-            .OrderByIF(dto is { SortRule: 0, SortField: "screenByEndTime" }, x => x.ScreenByEndTime, OrderByType.Asc)
+            .OrderByIF(dto is { SortRule: 0, SortField: "screenByEndTime" }, x => x.ScreenByEndTime, OrderByType.Asc)//截止申请日期排序
             .OrderByIF(dto is { SortRule: 1, SortField: "screenByEndTime" }, x => x.ScreenByEndTime, OrderByType.Desc)
             .OrderByIF(dto.SortRule is null, x => x.CreationTime, OrderByType.Desc);
     }
@@ -3470,8 +3485,17 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .WhereIF(!string.IsNullOrEmpty(dto.OrderTagCode),
                 d => SqlFunc.Subqueryable<OrderRelationTag>().InnerJoin<SystemDicData>((s, p) => s.TagId == p.Id)
                     .Where((s, p) => p.DicDataValue == dto.OrderTagCode && d.OrderId == s.OrderId).Any()) //工单标签
-            .OrderByIF(dto.VisitStateQuery != EVisitStateQuery.Visited, d => d.Order.IsUrgent, OrderByType.Desc)
-            .OrderByDescending(d => d.PublishTime);
+            .OrderByIF(_appOptions.Value.IsYiBin && dto.VisitStateQuery != EVisitStateQuery.Visited, d => d.Order.IsUrgent, OrderByType.Desc)
+             .OrderByIF(_appOptions.Value.IsZiGong == false, d => d.PublishTime, OrderByType.Desc)
+            //.OrderByDescending(d => d.PublishTime)
+            .OrderByIF(dto is { SortField: "publishTime", SortRule: 0 }, x => x.PublishTime, OrderByType.Asc) // 发布时间升序
+            .OrderByIF(dto is { SortField: "publishTime", SortRule: 1 }, x => x.PublishTime, OrderByType.Desc)// 发布时间升序
+            .OrderByIF(dto is { SortField: "order.creationTime", SortRule: 0 }, x => x.Order.CreationTime, OrderByType.Asc) // 受理时间升序
+            .OrderByIF(dto is { SortField: "order.creationTime", SortRule: 1 }, x => x.Order.CreationTime, OrderByType.Desc) // 受理时间升序
+            .OrderByIF(dto is { SortField: "order.filedTime", SortRule: 0 }, x => x.Order.FiledTime, OrderByType.Asc) // 办结时间升序
+            .OrderByIF(dto is { SortField: "order.filedTime", SortRule: 1 }, x => x.Order.FiledTime, OrderByType.Desc) // 办结时间升序
+            .OrderByIF(_appOptions.Value.IsZiGong && string.IsNullOrEmpty(dto.SortField), d => d.PublishTime, OrderByType.Desc)
+            ;
         return query;
     }
 
@@ -3637,7 +3661,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _sessionContext.ChangeSession(startStep.HandlerId);
         var isAutoFillSummaryOpinion = _systemSettingCacheManager.IsAutoFillSummaryOpinion;
 
-        await _workflowDomainService.NextAsync(operater, nextDto, order.ExpiredTime, isAutoFillSummaryOpinion,
+        await _workflowDomainService.NextAsync(nextDto,
+            expiredTime: order.ExpiredTime,
+            isAutoFillSummaryOpinion: isAutoFillSummaryOpinion,
             cancellationToken: cancellationToken);
     }
 
@@ -4097,8 +4123,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 async (workflow, currentStep, targetStepDefine, targetStep, targetStepNew) =>
                 {
                     var stepAssignInfo = recall.NextHandlers.FirstOrDefault()
-                                         ?? await GetOrderRecallAssignInfoAsync(workflow, targetStepDefine, targetStep,
-                                             recall, cancellation);
+                                         ?? GetOrderRecallAssignInfoAsync(workflow, targetStepDefine, targetStep,
+                                             recall, cancellation).Result;
                     if (stepAssignInfo is null) return;
                     var validator = new StepAssignInfoValidator();
                     await validator.ValidateAndThrowAsync(stepAssignInfo, cancellation);
@@ -4107,10 +4133,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 cancellation);
 
 
-		//if (order.ActualHandleOrgCode != OrgSeedData.CenterId && order.Status < EOrderStatus.Filed)
-		//{
-		//	await _circularRecordDomainService.OrderSpecialCircularMessage(special, order, cancellation);
-		//}
+        if (_appOptions.Value.IsYiBin && order.ActualHandleOrgCode != OrgSeedData.CenterId && order.Status < EOrderStatus.Filed)
+        {
+            await _circularRecordDomainService.OrderSpecialCircularMessage(special, order, cancellation);
+        }
 
         if (_appOptions.Value.IsZiGong && dto.BusinessType == EBusinessType.Send)
         {
@@ -4545,7 +4571,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 d => d.CreationTime >= dto.ApplyStartTime && d.CreationTime <= dto.ApplyEndTime)
             //.WhereIF(dto.AuditStatus is 1 , d=>d.Status == ETerminateStatus.Approval || d.Status == ETerminateStatus.SendBack )
             //.WhereIF(dto.AuditStatus is 2, d => d.Status == ETerminateStatus.End || dto.Status == ETerminateStatus.Refuse)
-            .WhereIF(dto.QueryType is 1, d => d.CreatorId == _sessionContextProvider.SessionContext.UserId)
+            .WhereIF(dto.QueryType is 1, d => d.CreatorId == _sessionContext.UserId)
             .WhereIF(dto.Status.HasValue, d => d.Status == dto.Status)
             .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, d => d.Order.StartTime >= dto.StartTime && d.Order.StartTime <= dto.EndTime)
             .OrderByDescending(d => d.CreationTime);
@@ -4630,7 +4656,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             case 2: //办结: 当前登录坐席作为最初受理人已办结的工单
                 query.Where(d =>
                     d.Status >= EOrderStatus.Filed
-                    && d.AcceptorId == _sessionContextProvider.SessionContext.RequiredUserId);
+                    && d.AcceptorId == _sessionContext.RequiredUserId);
                 break;
         }
 
@@ -4640,10 +4666,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         //    (hasHandled || step.Status != EWorkflowStepStatus.Handled) &&
         //    (!hasHandled || step.Status == EWorkflowStepStatus.Handled &&
         //    step.TraceState != EWorkflowTraceState.StepRemoveByPrevious) &&
-        //    ((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) && step.HandlerId == _sessionContextProvider.SessionContext.RequiredUserId) ||
-        //    (step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) && step.HandlerOrgId == _sessionContextProvider.SessionContext.RequiredOrgId) ||
-        //    (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) && _sessionContextProvider.SessionContext.Roles.Contains(step.RoleId)))).Any() ||
-        //    (string.IsNullOrEmpty(d.WorkflowId) && (string.IsNullOrEmpty(d.SignerId) || d.SignerId == _sessionContextProvider.SessionContext.RequiredUserId))
+        //    ((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) && step.HandlerId == _sessionContext.RequiredUserId) ||
+        //    (step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) && step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
+        //    (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) && _sessionContext.Roles.Contains(step.RoleId)))).Any() ||
+        //    (string.IsNullOrEmpty(d.WorkflowId) && (string.IsNullOrEmpty(d.SignerId) || d.SignerId == _sessionContext.RequiredUserId))
         //);
 
         //随手拍
@@ -4659,7 +4685,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 //// 交办件:已派单其他节点的工单,该选项卡下工单若办结就不显示
                 //.WhereIF(dto.TypeCode.HasValue == true && dto.TypeCode == 1, d => /*d.ProcessType == EProcessType.Jiaoban &&*/ d.Status < EOrderStatus.Filed)
                 //// 办结件:当前登录坐席作为最初受理人已办结的工单
-                //.WhereIF(dto.TypeCode.HasValue == true && dto.TypeCode == 2, d => d.Status >= EOrderStatus.Filed && d.AcceptorId == _sessionContextProvider.SessionContext.RequiredUserId)
+                //.WhereIF(dto.TypeCode.HasValue == true && dto.TypeCode == 2, d => d.Status >= EOrderStatus.Filed && d.AcceptorId == _sessionContext.RequiredUserId)
                 .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
                 //.WhereIF(dto.IsHandled.HasValue, d => handleStatuses.Contains(d.Status))
                 .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword!))
@@ -5021,7 +5047,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     {
         var query = _orderSendBackAuditRepository.Queryable()
             .Where(x => x.ApplyOrgId.Length == 6 && x.CreationTime > x.OrderExpiredTime)
-            .WhereIF(!_sessionContext.OrgIsCenter, x=>x.ApplyOrgId == _sessionContext.OrgId)
+            .WhereIF(!_sessionContext.OrgIsCenter, x => x.ApplyOrgId == _sessionContext.OrgId)
             .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime)
             .GroupBy(x => new { x.ApplyOrgId, x.ApplyOrgName })
             .Select(x => new ExtendedSendBackVo()
@@ -5180,7 +5206,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                     async (workflow1, currentStep1, prevStepDefine, prevStep1, newStep) =>
                     {
                         var stepAssignInfo =
-                            await GetOrderPreviousAssignInfoAsync(workflow1, prevStepDefine, prevStep1, cancellationToken);
+                            GetOrderPreviousAssignInfoAsync(workflow1, prevStepDefine, prevStep1, cancellationToken).Result;
                         if (stepAssignInfo is null) return;
                         var validator = new StepAssignInfoValidator();
                         await validator.ValidateAndThrowAsync(stepAssignInfo);
@@ -5230,6 +5256,98 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             await _orderRepository.Updateable().SetColumns(o => new Order() { ProcessType = processType, SendBackNum = order.SendBackNum })
                 .Where(o => o.Id == order.Id).ExecuteCommandAsync(cancellationToken);
         }
+
+        if (_appOptions.Value.IsYiBin && order.IsProvince && sendBack.ApplyOrgId.Length == 6 && sendBack.SendBackOrgId == OrgSeedData.CenterId)
+        {
+            if (currentStep.FlowAssignType == EFlowAssignType.User)
+            {
+                await _circularRecordDomainService.OrderSendBackCircularMessage(currentStep.HandlerId, currentStep.HandlerName, order, cancellationToken);
+            }
+            else if (currentStep.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(currentStep.RoleId))
+            {
+
+                var users = await _userRepository.Queryable().Includes(x => x.Roles).Where(x => x.Roles.Where(x => x.Id == currentStep.RoleId).Any()).ToListAsync();
+                foreach (var user in users)
+                {
+                    await _circularRecordDomainService.OrderSendBackCircularMessage(user.Id, user.Name, order, cancellationToken);
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// 依据当前待办节点获取任意一个合法办理人
+    /// </summary>
+    public async Task<User> GetHandlerRandomAsync(WorkflowStep step, CancellationToken cancellationToken)
+    {
+        User user;
+        switch (step.BusinessType)
+        {
+            case EBusinessType.Seat:
+                var roleSeat = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi)?.SettingValue.FirstOrDefault();
+                if (string.IsNullOrEmpty(roleSeat))
+                    throw new UserFriendlyException($"未配置坐席角色, {SettingConstants.RoleZuoXi}", "未配置坐席角色");
+                user = await _userRepository.Queryable()
+                    .Where(d => d.Roles.Any(x => x.Name == roleSeat))
+                    .FirstAsync(cancellationToken);
+                if (user is null)
+                    throw UserFriendlyException.SameMessage("坐席角色未设置用户");
+                break;
+            case EBusinessType.Send:
+                var roleSend = _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan)?.SettingValue.FirstOrDefault();
+                if (string.IsNullOrEmpty(roleSend))
+                    throw new UserFriendlyException($"未配置派单角色, {SettingConstants.RolePaiDan}", "未配置派单角色");
+                user = await _userRepository.Queryable()
+                    .Where(d => d.Roles.Any(x => x.Name == roleSend))
+                    .FirstAsync(cancellationToken);
+                if (user is null)
+                    throw UserFriendlyException.SameMessage("派单角色未设置用户");
+                break;
+            case EBusinessType.CenterMonitor:
+                var roleCenterMonitor = _systemSettingCacheManager.GetSetting(SettingConstants.SeatsMonitor)?.SettingValue.FirstOrDefault();
+                if (string.IsNullOrEmpty(roleCenterMonitor))
+                    throw new UserFriendlyException($"未配置中心班长角色, {SettingConstants.SeatsMonitor}", "未配置中心班长角色");
+                user = await _userRepository.Queryable()
+                    .Where(d => d.Roles.Any(x => x.Name == roleCenterMonitor))
+                    .FirstAsync(cancellationToken);
+                if (user is null)
+                    throw UserFriendlyException.SameMessage("中心班长角色未设置用户");
+                break;
+            case EBusinessType.CenterLeader:
+                var roleCenterLeader = _systemSettingCacheManager.GetSetting(SettingConstants.RoleCenterLeader)?.SettingValue.FirstOrDefault();
+                if (string.IsNullOrEmpty(roleCenterLeader))
+                    throw new UserFriendlyException($"未配置中心领导角色, {SettingConstants.RoleCenterLeader}", "未配置中心领导角色");
+                user = await _userRepository.Queryable()
+                    .Where(d => d.Roles.Any(x => x.Name == roleCenterLeader))
+                    .FirstAsync(cancellationToken);
+                if (user is null)
+                    throw UserFriendlyException.SameMessage("中心领导角色未设置用户");
+                break;
+            case EBusinessType.Department:
+                var roleJingBanRen = _systemSettingCacheManager.GetSetting(SettingConstants.RoleJingBanRen)?.SettingValue.FirstOrDefault();
+                if (string.IsNullOrEmpty(roleJingBanRen))
+                    throw new UserFriendlyException($"未配置部门经办人角色, {SettingConstants.RoleJingBanRen}", "未配置部门经办人角色");
+                user = await _userRepository.Queryable()
+                    .Where(d => d.OrgId == step.HandlerOrgId && d.Roles.Any(x => x.Name == roleJingBanRen))
+                    .FirstAsync(cancellationToken);
+                if (user is null)
+                    throw new UserFriendlyException($"该部门经办人角色未设置用户,部门:{step.HandlerOrgId}, 角色:{SettingConstants.RoleJingBanRen}");
+                break;
+            case EBusinessType.DepartmentLeader:
+                var roleBuMenLingDao = _systemSettingCacheManager.GetSetting(SettingConstants.RoleLingDao)?.SettingValue.FirstOrDefault();
+                if (string.IsNullOrEmpty(roleBuMenLingDao))
+                    throw new UserFriendlyException($"未配置部门领导角色, {SettingConstants.RoleJingBanRen}", "未配置部门领导角色");
+                user = await _userRepository.Queryable()
+                    .Where(d => d.OrgId == step.HandlerOrgId && d.Roles.Any(x => x.Name == roleBuMenLingDao))
+                    .FirstAsync(cancellationToken);
+                if (user is null)
+                    throw new UserFriendlyException($"该部门领导角色未设置用户,部门:{step.HandlerOrgId}, 角色:{SettingConstants.RoleJingBanRen}");
+                break;
+            default:
+                throw new OutOfRangeException(nameof(GetHandlerRandomAsync));
+        }
+
+        return user;
     }
 
     #endregion

+ 2 - 2
src/Hotline.Application/Orders/OrderSecondaryHandlingApplication.cs

@@ -239,8 +239,8 @@ namespace Hotline.Application.Orders
                         async (workflow, currentStep, targetStepDefine, targetStep, targetStepNew) =>
                         {
                             var basicWorkflowDto = _mapper.Map<BasicWorkflowDto>(dto);
-                            var stepAssignInfo = await _orderApplication.GetOrderRecallAssignInfoAsync(workflow, targetStepDefine, targetStep,
-                                basicWorkflowDto, cancellationToken);
+                            var stepAssignInfo = _orderApplication.GetOrderRecallAssignInfoAsync(workflow, targetStepDefine, targetStep,
+                                basicWorkflowDto, cancellationToken).Result;
                             if (stepAssignInfo is null) return;
                             var validator = new StepAssignInfoValidator();
                             await validator.ValidateAndThrowAsync(stepAssignInfo, cancellationToken);

+ 54 - 0
src/Hotline.Application/SpecialNumber/ISpecialNumberApplication.cs

@@ -0,0 +1,54 @@
+using Hotline.Share.Dtos.Special;
+
+namespace Hotline.Application.SpecialNumber
+{
+    public interface ISpecialNumberApplication
+    {
+        #region 特殊号码
+
+        /// <summary>
+        /// 特殊号码 - 列表
+        /// </summary>
+        /// <param name="pagedDto"></param>
+        /// <returns></returns>
+        Task<(int, IList<SpecialNumberInfoDto>)> QueryAllSpecialNumberListAsync(SpecialNumberDto pagedDto, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// 特殊号码 - 新增
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        Task<string> AddSpecialNumberAsync(AddSpecialNumberDto dto, CancellationToken cancellationToken);
+
+        /// <summary>
+        ///特殊号码 - 编辑
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        Task UpdateSpecialNumberAsync(UpdateSpecialNumberDto dto, CancellationToken cancellationToken);
+
+        /// <summary>
+        ///特殊号码 - 删除
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        Task RemoveSpecialNumberAsync(DelSpecialNumberDto dto, CancellationToken cancellationToken);
+
+        /// <summary>
+        ///特殊号码 - 详情
+        /// </summary>
+        /// <param name="Id"></param>
+        /// <returns></returns>
+        Task<SpecialNumberInfoDto> GetSpecialNumberAsync(string Id, CancellationToken cancellationToken);
+
+        /// <summary>
+        ///特殊号码 - 详情
+        /// </summary>
+        /// <param name="PhoneNumber"></param>
+        /// <returns></returns>
+        Task<SpecialNumberInfoDto> GetSpecialNumberByAsync(string PhoneNumber, CancellationToken cancellationToken);
+
+        #endregion
+    }
+}

+ 167 - 0
src/Hotline.Application/SpecialNumber/SpecialNumberApplication.cs

@@ -0,0 +1,167 @@
+using MapsterMapper;
+using SqlSugar;
+using XF.Domain.Authentications;
+using XF.Domain.Dependency;
+using XF.Domain.Exceptions;
+using XF.Domain.Repository;
+using Hotline.Repository.SqlSugar.Extensions;
+using Hotline.Share.Dtos.Special;
+
+namespace Hotline.Application.SpecialNumber
+{
+    public class SpecialNumberApplication : ISpecialNumberApplication, IScopeDependency
+    {
+        #region 注册
+
+        private readonly IRepository<Hotline.Special.SpecialNumber> _specialNumberRepository;
+        private readonly ISessionContext _sessionContext;
+        private readonly IMapper _mapper;
+
+        public SpecialNumberApplication(
+            IRepository<Hotline.Special.SpecialNumber> specialNumberRepository,
+            ISessionContext sessionContext,
+            IMapper mapper)
+        {
+            _specialNumberRepository = specialNumberRepository;
+            _sessionContext = sessionContext;
+            _mapper = mapper;
+        }
+
+        #endregion
+
+        #region 特殊号码
+
+        #region 特殊号码 - 列表
+
+        /// <summary>
+        /// 特殊号码 - 列表
+        /// </summary>
+        /// <param name="pagedDto"></param>
+        /// <returns></returns>
+        public async Task<(int, IList<SpecialNumberInfoDto>)> QueryAllSpecialNumberListAsync(SpecialNumberDto dto, CancellationToken cancellationToken)
+        {
+            var typeSpliceName = string.Empty;
+
+            //单表分页
+            var (total, temp) = await _specialNumberRepository.Queryable()
+
+                .WhereIF(!string.IsNullOrEmpty(dto.PhoneNumber), x => x.PhoneNumber.Contains(dto.PhoneNumber))
+                .WhereIF(!string.IsNullOrEmpty(dto.Notes), x => x.Notes.Contains(dto.Notes))
+                .WhereIF(dto.CreationTimeStart.HasValue, x => x.CreationTime >= dto.CreationTimeStart)
+                .WhereIF(dto.CreationTimeEnd.HasValue, x => x.CreationTime <= dto.CreationTimeEnd)
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, x => x.CreationTime, OrderByType.Asc)  //创建时间升序
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.CreationTime, OrderByType.Desc) //创建时间降序
+                .ToPagedListAsync(dto.PageIndex, dto.PageSize, cancellationToken);
+            return (total, _mapper.Map<IList<SpecialNumberInfoDto>>(temp));
+            //return (total, temp);
+        }
+
+        #endregion
+
+        #region 特殊号码 - 新增
+
+        /// <summary>
+        /// 新增
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        public async Task<string> AddSpecialNumberAsync(AddSpecialNumberDto dto, CancellationToken cancellationToken)
+        {
+            var data = _mapper.Map<Hotline.Special.SpecialNumber>(dto);
+
+            var any = await _specialNumberRepository.Queryable().Where(x => x.PhoneNumber == dto.PhoneNumber).AnyAsync();
+            if (any)
+                throw UserFriendlyException.SameMessage("特殊号码已存在!");
+
+            data.InitId();
+
+            return await _specialNumberRepository.AddAsync(data, cancellationToken);
+        }
+
+        #endregion
+
+        #region 特殊号码 - 修改
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        public async Task UpdateSpecialNumberAsync(UpdateSpecialNumberDto dto, CancellationToken cancellationToken)
+        {
+            var data = await _specialNumberRepository.GetAsync(dto.Id);
+
+            if (data == null)
+                throw UserFriendlyException.SameMessage("特殊号码查询失败");
+
+            var any = await _specialNumberRepository.Queryable().Where(x => x.PhoneNumber == dto.PhoneNumber && x.Id != dto.Id).AnyAsync();
+            if (any)
+                throw UserFriendlyException.SameMessage("特殊号码已存在!");
+
+            data.PhoneNumber = dto.PhoneNumber;
+            data.Notes = dto.Notes;
+
+            await _specialNumberRepository.UpdateAsync(data, cancellationToken);
+        }
+
+        #endregion
+
+        #region 特殊号码 - 删除
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        public async Task RemoveSpecialNumberAsync(DelSpecialNumberDto dto, CancellationToken cancellationToken)
+        {
+            var data = await _specialNumberRepository.GetAsync(dto.Id);
+
+            if (data == null)
+                throw UserFriendlyException.SameMessage("特殊号码查询失败");
+
+            await _specialNumberRepository.RemoveAsync(data, false, cancellationToken);
+        }
+
+        #endregion
+
+        #region 特殊号码 - 详情
+
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="Id"></param>
+        /// <returns></returns>
+        public async Task<SpecialNumberInfoDto> GetSpecialNumberAsync(string Id, CancellationToken cancellationToken)
+        {
+            var data = await _specialNumberRepository.Queryable()
+                .FirstAsync(x => x.Id == Id, cancellationToken);
+            if (data == null) return new();
+            return _mapper.Map<SpecialNumberInfoDto>(data);
+        }
+
+        #endregion
+
+        #region 特殊号码 - 详情
+
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="PhoneNumber"></param>
+        /// <returns></returns>
+        public async Task<SpecialNumberInfoDto> GetSpecialNumberByAsync(string PhoneNumber, CancellationToken cancellationToken)
+        {
+            var data = await _specialNumberRepository.Queryable()
+                .FirstAsync(x => x.PhoneNumber == PhoneNumber, cancellationToken);
+            if (data == null) return new();
+            return _mapper.Map<SpecialNumberInfoDto>(data);
+        }
+
+        #endregion
+
+        #endregion
+    }
+}

+ 2 - 2
src/Hotline.Application/StatisticalReport/CallReport/YiBinCallReportApplication.cs

@@ -318,7 +318,7 @@ public class YiBinCallReportApplication : CallReportApplicationBase, ICallReport
                   InTimeImmediate = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime != null && c.RingTimes <= ringTimes, 1, 0)),//按时接通量
                   InHanguped = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime == null, 1, 0)), //呼入未接通
                   InHangupImmediate = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime == null && c.RingTimes <= noConnectByeTimes, 1, 0)),//未接通秒挂量
-                  OverTimeInHanguped = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime == null && c.RingTimes > noConnectByeTimes, 1, 0)), //超时未接通量
+                  OverTimeInHanguped = SqlFunc.AggregateSum(SqlFunc.IIF(c.AnsweredTime == null && c.RingTimes > ringTimes, 1, 0)), //超时未接通量
               }).ToListAsync();
         return list;
     }
@@ -354,7 +354,7 @@ public class YiBinCallReportApplication : CallReportApplicationBase, ICallReport
             .WhereIF(dto.QueryType.HasValue && dto.QueryType == 5,x=> x.AnsweredTime != null && x.RingTimes <= ringTimes) //按时接通量
             .WhereIF(dto.QueryType.HasValue && dto.QueryType == 6,x=> x.AnsweredTime == null) //呼入未接通量
             .WhereIF(dto.QueryType.HasValue && dto.QueryType == 7,x=> x.AnsweredTime == null && x.RingTimes <= noConnectByeTimes) //未接通秒挂量
-            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 8,x=> x.AnsweredTime == null && x.RingTimes > noConnectByeTimes) //超时未接通量
+            .WhereIF(dto.QueryType.HasValue && dto.QueryType == 8,x=> x.AnsweredTime == null && x.RingTimes > ringTimes) //超时未接通量
             .Where(x => x.CallDirection == ECallDirection.In)
             .OrderBy(x => x.BeginRingTime)
             .MergeTable()

+ 63 - 38
src/Hotline.Application/Subscribers/DatasharingSubscriber.cs

@@ -81,6 +81,8 @@ namespace Hotline.Application.Subscribers
         private readonly IOptions<CityBaseConfiguration> _cityBaseConfiguration;
         private readonly ICalcExpireTime _expireTime;
         private readonly ISessionContextProvider _sessionContextProvider;
+        private readonly ISessionContext _sessionContext;
+        private readonly ISessionContextManager _sessionContextManager;
         private readonly ILogger<DataSharingSubscriber> _logger;
 
         public DataSharingSubscriber(
@@ -116,6 +118,9 @@ namespace Hotline.Application.Subscribers
             IOptions<CityBaseConfiguration> cityBaseConfiguration,
             ICalcExpireTime expireTime,
             ISessionContextProvider sessionContextProvider,
+            ISessionContext sessionContext,
+            ISessionContextCreator sessionContextCreator,
+            ISessionContextManager sessionContextManager,
             ILogger<DataSharingSubscriber> logger)
         {
             _orderSendBackRepository = orderSendBackRepository;
@@ -150,6 +155,8 @@ namespace Hotline.Application.Subscribers
             _cityBaseConfiguration = cityBaseConfiguration;
             _expireTime = expireTime;
             _sessionContextProvider = sessionContextProvider;
+            _sessionContext = sessionContext;
+            _sessionContextManager = sessionContextManager;
             _logger = logger;
         }
 
@@ -255,6 +262,10 @@ namespace Hotline.Application.Subscribers
             if (order is null)
                 throw new UserFriendlyException("未查询到工单");
 
+            //SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
+            // await _sessionContextCreator.CreateSessionContextAsync(dto.Source, cancellationToken);
+            _sessionContextManager.ChangeSessionContext(dto.Source);
+
             OrderRevoke orderRevoke = new()
             {
                 OrderId = order.Id,
@@ -282,20 +293,22 @@ namespace Hotline.Application.Subscribers
             if (_appOptions.Value.IsZiGong)
             {
                 //expiredTimeConfig = await _expireTime.CalcExpiredTime(DateTime.Now, order.StartTime.Value, EFlowDirection.CenterToCenter, order.Adapt<OrderTimeClacInfo>());
-                expiredTimeConfig = await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToCenter, order.Adapt<OrderTimeClacInfo>());
+                expiredTimeConfig = await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToCenter,
+                    order.Adapt<OrderTimeClacInfo>());
             }
             else
             {
                 //期满时间
                 //expiredTimeConfig = _timeLimitDomainService.CalcExpiredTime(DateTime.Now, EFlowDirection.CenterToOrg, order.AcceptTypeCode);
                 //expiredTimeConfig = await _expireTime.CalcExpiredTime(DateTime.Now, order.CenterToOrgTime.Value, EFlowDirection.CenterToOrg, order.Adapt<OrderTimeClacInfo>());
-                expiredTimeConfig = await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToOrg, order.Adapt<OrderTimeClacInfo>());
+                expiredTimeConfig =
+                    await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToOrg, order.Adapt<OrderTimeClacInfo>());
             }
 
             _mapper.Map(expiredTimeConfig, order);
             await _orderRepository.UpdateAsync(order, cancellationToken);
+
             //宜宾需求:特提至中心(优先派单组无派单组节点就特提至坐席),由派单员归档
-            SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
             if (string.IsNullOrEmpty(order?.WorkflowId))
             {
                 var startDto = new StartWorkflowDto
@@ -504,21 +517,17 @@ namespace Hotline.Application.Subscribers
         [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderScreen)]
         public async Task RecOrderScreenResultAsync(ProvinceSendScreenResultDto dto, CancellationToken cancellationToken)
         {
-            //var order = await _orderRepository.Queryable()
-            //    .Where(x => x.ProvinceNo == dto.ProvinceScreenResult!.CaseSerial)
-            //    .FirstAsync(cancellationToken);
-            //var orderScreen = await _orderScreenRepository.Queryable()
-            //    .Where(x => x.OrderId == order.Id && x.Status == Share.Enums.Order.EScreenStatus.Approval)
-            //    .FirstAsync(cancellationToken);
-
             var orderScreen = await _orderScreenRepository.Queryable()
-                .Where(x => x.Order.ReceiveProvinceNo == dto.ProvinceScreenResult.CaseSerial &&
-                            x.Status == EScreenStatus.Approval)
-                .FirstAsync(cancellationToken);
+                .FirstAsync(x => x.Order.ReceiveProvinceNo == dto.ProvinceScreenResult.CaseSerial &&
+                                 x.Status == EScreenStatus.Approval, cancellationToken);
+            if (orderScreen is null)
+                throw new UserFriendlyException($"收到ds推送:{EventNames.SharingOrderScreen}, 未查询到甄别数据, 省交办编号:{dto.ProvinceScreenResult.CaseSerial}");
+
+            //SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
+            // await _sessionContextCreator.CreateSessionContextAsync(dto.Source, cancellationToken);
+            _sessionContextManager.ChangeSessionContext(dto.Source);
+
 
-            //var setting = _systemSettingCacheManager.GetSetting(SettingConstants.CityBaseConfiguration)?.SettingValue[0];
-            //CityBaseConfiguration cityBase = JsonConvert.DeserializeObject<CityBaseConfiguration>(setting);
-            SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
             if (int.Parse(dto.ProvinceScreenResult.AuditResult) == 0)
             {
                 PreviousWorkflowDto previous = new PreviousWorkflowDto();
@@ -530,10 +539,12 @@ namespace Hotline.Application.Subscribers
             if (int.Parse(dto.ProvinceScreenResult.AuditResult) > 0)
             {
                 await _workflowApplication.HandleToEndAsync(orderScreen.WorkflowId, dto.ProvinceScreenResult.AuditOpinion, null,
-                 reviewResult: int.Parse(dto.ProvinceScreenResult.AuditResult) == 1
-                    ? Share.Enums.FlowEngine.EReviewResult.Approval
-                    : Share.Enums.FlowEngine.EReviewResult.Failed, cancellationToken: cancellationToken);
-                orderScreen.Status = int.Parse(dto.ProvinceScreenResult.AuditResult) == 1 ? Share.Enums.Order.EScreenStatus.End : Share.Enums.Order.EScreenStatus.Refuse;
+                    reviewResult: int.Parse(dto.ProvinceScreenResult.AuditResult) == 1
+                        ? Share.Enums.FlowEngine.EReviewResult.Approval
+                        : Share.Enums.FlowEngine.EReviewResult.Failed, cancellationToken: cancellationToken);
+                orderScreen.Status = int.Parse(dto.ProvinceScreenResult.AuditResult) == 1
+                    ? Share.Enums.Order.EScreenStatus.End
+                    : Share.Enums.Order.EScreenStatus.Refuse;
                 //if (orderScreen.Status == Share.Enums.Order.EScreenStatus.End)
                 //{
                 //    var visitDetail = await _orderVisitedDetailRepository.GetAsync(orderScreen.VisitDetailId, cancellationToken);
@@ -559,15 +570,20 @@ namespace Hotline.Application.Subscribers
                 {
                     var visitDetails = await _orderVisitedDetailRepository.Queryable().Where(x => x.OrderVisit.OrderId == orderScreen.OrderId &&
                                                                                                   x.VisitTarget == EVisitTarget.Org && (
-                                                                                                      SqlFunc.JsonField(x.OrgProcessingResults, "Key") ==
+                                                                                                      SqlFunc.JsonField(x.OrgProcessingResults,
+                                                                                                          "Key") ==
                                                                                                       "1" ||
-                                                                                                      SqlFunc.JsonField(x.OrgProcessingResults, "Key") ==
+                                                                                                      SqlFunc.JsonField(x.OrgProcessingResults,
+                                                                                                          "Key") ==
                                                                                                       "2" ||
-                                                                                                      SqlFunc.JsonField(x.OrgHandledAttitude, "Key") ==
+                                                                                                      SqlFunc.JsonField(x.OrgHandledAttitude,
+                                                                                                          "Key") ==
                                                                                                       "1" ||
-                                                                                                      SqlFunc.JsonField(x.OrgHandledAttitude, "Key") ==
+                                                                                                      SqlFunc.JsonField(x.OrgHandledAttitude,
+                                                                                                          "Key") ==
                                                                                                       "2"
-                                                                                                  ) && x.Id != orderScreen.VisitDetailId).ToListAsync();
+                                                                                                  ) && x.Id != orderScreen.VisitDetailId)
+                        .ToListAsync();
                     foreach (var visitDetail in visitDetails)
                     {
                         if (visitDetail != null)
@@ -789,6 +805,10 @@ namespace Hotline.Application.Subscribers
             var order = await _orderRepository.GetAsync(x => x.ReceiveProvinceNo == dto.No, cancellationToken);
             if (order != null)
             {
+                //SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
+                // await _sessionContextCreator.CreateSessionContextAsync(dto.Source, cancellationToken);
+                _sessionContextManager.ChangeSessionContext(dto.Source);
+
                 //查询延期
                 var orderDelay = await _orderDelayRepository
                     .GetAsync(x => x.OrderId == order.Id && x.DelayState == EDelayState.Examining, cancellationToken);
@@ -803,12 +823,8 @@ namespace Hotline.Application.Subscribers
                         orderDelay.FileJson = await _fileRepository.AddFileAsync(dto.Files, orderDelay.Id, orderDelay.WorkflowId, cancellationToken);
                     await _orderDelayRepository.UpdateAsync(orderDelay, cancellationToken);
 
-                    //var setting = _systemSettingCacheManager.GetSetting(SettingConstants.CityBaseConfiguration)?.SettingValue[0];
-                    //CityBaseConfiguration cityBase = JsonConvert.DeserializeObject<CityBaseConfiguration>(setting);
-
-                    SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
                     await _workflowApplication.HandleToEndAsync(orderDelay.WorkflowId, dto.Opinion, dto.Files,
-                      reviewResult: dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed, cancellationToken: cancellationToken);
+                        reviewResult: dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed, cancellationToken: cancellationToken);
                 }
             }
         }
@@ -819,7 +835,6 @@ namespace Hotline.Application.Subscribers
         [CapSubscribe(EventNames.SharingOrderReultSend)]
         public async Task RecOrderResultAsync(OrderResultDto dto, CancellationToken cancellationToken)
         {
-            SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
             var order = await _orderRepository.Queryable().Includes(x => x.OrderExtension).FirstAsync(x => x.Id == dto.OrderId, cancellationToken);
             if (order is null)
                 throw new UserFriendlyException($"无效工单编号, orderId: {dto.OrderId}");
@@ -835,6 +850,10 @@ namespace Hotline.Application.Subscribers
             //var setting = _systemSettingCacheManager.GetSetting(SettingConstants.CityBaseConfiguration)?.SettingValue[0];
             //CityBaseConfiguration cityBase = JsonConvert.DeserializeObject<CityBaseConfiguration>(setting);
 
+            //SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
+            //await _sessionContextCreator.CreateSessionContextAsync(dto.Source, cancellationToken);
+            _sessionContextManager.ChangeSessionContext(dto.Source);
+
             switch (dto.FinishType)
             {
                 case "0":
@@ -844,14 +863,16 @@ namespace Hotline.Application.Subscribers
                     if (_appOptions.Value.IsZiGong)
                     {
                         expiredTimeConfig =
-                            await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToCenter, order.Adapt<OrderTimeClacInfo>());
+                            await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToCenter,
+                                order.Adapt<OrderTimeClacInfo>());
                     }
                     else
                     {
                         //期满时间
                         //expiredTimeConfig = _timeLimitDomainService.CalcExpiredTime(DateTime.Now, EFlowDirection.CenterToOrg, order.AcceptTypeCode);
                         expiredTimeConfig =
-                            await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToOrg, order.Adapt<OrderTimeClacInfo>());
+                            await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToOrg,
+                                order.Adapt<OrderTimeClacInfo>());
                     }
 
                     _mapper.Map(expiredTimeConfig, order);
@@ -867,9 +888,9 @@ namespace Hotline.Application.Subscribers
 
                     var handleMode = order.OrderExtension is null ? EHandleMode.Recall : EHandleMode.ProvinceHandlePrevious;
 
-
                     var (isPaiDan, workflow) = await _workflowDomainService.RecallToCenterFirstToSendAsync(order.WorkflowId, dto.Opinion,
-                        order.Status >= EOrderStatus.Filed, order.ExpiredTime, EHandleMode.ProvinceHandlePrevious, cancellationToken: cancellationToken);
+                        order.Status >= EOrderStatus.Filed, order.ExpiredTime, EHandleMode.ProvinceHandlePrevious,
+                        cancellationToken: cancellationToken);
 
                     order.Status = isPaiDan ? EOrderStatus.Special : EOrderStatus.WaitForAccept;
                     order.CurrentStepName = workflow.CurrentStepName;
@@ -901,13 +922,16 @@ namespace Hotline.Application.Subscribers
                         {
                             order.ActualOpinion += dto.Opinion;
                         }
+
                         order.FileOpinion = order.ActualOpinion;
-                        await _orderRepository.Updateable(order).UpdateColumns(d => d.ActualOpinion).UpdateColumns(d => d.FileOpinion).ExecuteCommandAsync(cancellationToken);
+                        await _orderRepository.Updateable(order).UpdateColumns(d => d.ActualOpinion).UpdateColumns(d => d.FileOpinion)
+                            .ExecuteCommandAsync(cancellationToken);
                         await _workflowDomainService.AppendFileOpinionAsync(order.WorkflowId, dto.Opinion, dto.Files, cancellationToken);
                     }
                     else
                     {
-                        await _workflowApplication.HandleToEndAsync(order.WorkflowId, dto.Opinion, dto.Files, expiredTime: order.ExpiredTime, cancellationToken: cancellationToken);
+                        await _workflowApplication.HandleToEndAsync(order.WorkflowId, dto.Opinion, dto.Files, expiredTime: order.ExpiredTime,
+                            cancellationToken: cancellationToken);
                     }
 
                     break;
@@ -1289,7 +1313,8 @@ namespace Hotline.Application.Subscribers
                         orderData.SourceChannelCode = "QT";
 
                         var orderDto = _mapper.Map<OrderDto>(orderData);
-                        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto, cancellationToken: cancellationToken);
+                        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
+                            cancellationToken: cancellationToken);
                     }
                 }
             }

+ 19 - 1
src/Hotline.Repository.SqlSugar/File/FileRepository.cs

@@ -45,7 +45,25 @@ namespace Hotline.Repository.SqlSugar.File
             return entities.Select(x => new FileJson { Id = x.Id, FileId = x.Additions, Path = x.Path, FileName = x.Name, FileType = x.Type }).ToList();
         }
 
-        public async Task<List<FileJson>> AddFileAsync(List<FileDto> files, string id, string flowId = "", CancellationToken cancellationToken = default) 
+		public async Task<List<FileJson>> AddFileAsync(IList<FileDto> files, string id, CancellationToken requestAborted)
+		{
+			var entities = files.Adapt<List<Hotline.File.File>>();
+			foreach (var file in entities)
+			{
+				var names = file.FileName.Split(".");
+				file.Name = names[0];
+				file.Type = names[1];
+				file.Key = id;
+				file.OrgName = _sessionContext.OrgName;
+				file.OrgId = _sessionContext.OrgId;
+				file.UserId = _sessionContext.UserId;
+				file.UserName = _sessionContext.UserName;
+			}
+			await AddRangeAsync(entities, requestAborted);
+			return entities.Select(x => new FileJson { Id = x.Id, FileId = x.Additions, Path = x.Path, FileName = x.Name, FileType = x.Type }).ToList();
+		}
+
+		public async Task<List<FileJson>> AddFileAsync(List<FileDto> files, string id, string flowId = "", CancellationToken cancellationToken = default) 
 		{
 			List<Hotline.File.File> newFiles =  new List<Hotline.File.File>();
 			var classify = files[0].Classify;

+ 8 - 3
src/Hotline.Share/Dtos/FlowEngine/NextStepsDto.cs

@@ -98,11 +98,16 @@ public class NextStepsWithOpinionDto<TSteps> : NextStepsDto<TSteps>
     /// </summary>
     public ECounterSignType? CounterSignType { get; set; }
 
-    #region 随手拍
     /// <summary>
-    /// 线索分类
+    /// 泸州需求 :是否能修改延期时限
     /// </summary>
-    public List<Kv>? IndustryCase { get; set; }
+    public bool? IsAlterDay { get; set; }
+
+	#region 随手拍
+	/// <summary>
+	/// 线索分类
+	/// </summary>
+	public List<Kv>? IndustryCase { get; set; }
 
     /// <summary>
     /// 补充奖励类型

+ 2 - 0
src/Hotline.Share/Dtos/Order/OrderVisitDto.cs

@@ -982,6 +982,8 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public DateTime? ScreenByEndTime { get; set; }
 
+        public bool? IsShowOperate { get; set; }
+
     }
 
     /// <summary>

+ 13 - 1
src/Hotline.Share/Dtos/Order/QueryOrderDto.cs

@@ -265,7 +265,14 @@ namespace Hotline.Share.Dtos.Order
         public string Id { get; set; }
     }
 
-    public record ApplyDelayDto
+    public record AlterDelayDayDto {
+		public string Id { get; set; }
+        public int DelayNum { get; set; }
+
+	}
+
+
+	public record ApplyDelayDto
     {
         public string OrderId { get; set; }
 
@@ -855,6 +862,11 @@ namespace Hotline.Share.Dtos.Order
         /// 受理坐席名字或工号(×)
         /// </summary>
         public string? NameOrNo { get; set; }
+
+        /// <summary>
+        /// 0 全部  1 我的(本部门)
+        /// </summary>
+        public int? DataScope { get; set; }
     }
 
     public record UrgeListDto : PagedKeywordRequest

+ 87 - 0
src/Hotline.Share/Dtos/Special/SpecialNumberDto.cs

@@ -0,0 +1,87 @@
+using Hotline.Share.Requests;
+
+namespace Hotline.Share.Dtos.Special
+{
+    public record AddSpecialNumberDto
+    {
+        /// <summary>
+        /// 电话号码
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        public string? Notes { get; set; }
+    }
+
+    public record UpdateSpecialNumberDto : AddSpecialNumberDto
+    {
+        /// <summary>
+        /// 案例库ID
+        /// </summary>
+        public string Id { get; set; }
+    }
+
+    public record DelSpecialNumberDto
+    {
+        public string Id { get; set; }
+    }
+
+    public record SpecialNumberDto : PagedRequest
+    {
+        /// <summary>
+        /// 电话号码
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+
+        public string? Notes { get; set; }
+
+        /// <summary>
+        /// 创建开始时间
+        /// </summary>
+        public DateTime? CreationTimeStart { get; set; }
+
+        /// <summary>
+        /// 创建结束时间
+        /// </summary>
+        public DateTime? CreationTimeEnd { get; set; }
+
+        /// <summary>
+        /// 排序字段
+        /// </summary>
+        public string? SortField { get; set; } = "creationTime";
+
+        /// <summary>
+        /// 排序方式 // 0 升序 1 降序
+        /// </summary>
+        public int? SortRule { get; set; } = 0;
+    }
+
+    public record SpecialNumberInfoDto
+    {
+        /// <summary>
+        /// 特殊电话ID
+        /// </summary>
+        public string Id { get; set; }
+
+        /// <summary>
+        /// 电话号码
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        public string? Notes { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime? CreationTime { get; set; }
+    }
+}

+ 6 - 0
src/Hotline.Share/Enums/FlowEngine/EHandleMode.cs

@@ -13,6 +13,12 @@ public enum EHandleMode
     [Description("正常")]
     Normal = 0,
 
+    /// <summary>
+    /// 跨级派单
+    /// </summary>
+    [Description("跨级派单")]
+    CrossLevel = 1,
+
     /// <summary>
     /// 审核通过(审批流程特有)
     /// </summary>

+ 3 - 0
src/Hotline.Share/Enums/Push/EPushBusiness.cs

@@ -87,4 +87,7 @@ public enum EPushBusiness
 
     [Description("随手拍短信")]
     Snapshot = 13,
+
+    [Description("甄别完成")]
+    ScreenEnd=14,
 }

+ 1 - 1
src/Hotline.Share/Requests/PagedKeywordRequest.cs

@@ -1008,7 +1008,7 @@ public record OrderScreenAuditPagedRequest : PagedKeywordRequest
     public string AuditUserName { get; set; }
 
     /// <summary>
-    ///  1 中心班长   2 中心领导
+    ///  1 中心班长   2 中心领导 3中心初审
     /// </summary>
     public int? AuditType { get; set; }
 

+ 27 - 0
src/Hotline/Article/CircularRecordDomainService.cs

@@ -202,5 +202,32 @@ namespace Hotline.Article
 
 		}
 
+        /// <summary>
+        /// 信件退回公告通知
+        /// </summary>
+        /// <returns></returns>
+		public async Task OrderSendBackCircularMessage(string userId,string userName, Order order, CancellationToken cancellationToken = default)
+		{
+
+			var cMessage = new AddCircularDto
+			{
+				Title = "信件退回信息",
+				Content = $"工单编码为{order.No}的工单,已被退回,请及时处理!",
+				CircularTypeId = "1",
+				CircularTypeName = "公告通知",
+				CircularType = ECircularType.Person,
+				IsMustRead = false,
+				SourceOrgId = _sessionContext.RequiredOrgId,
+				SourceOrgName = _sessionContext.OrgName
+			};
+			var groups = new CircularReadGroupDto
+			{
+				UserId = userId,
+				UserName = userName
+			};
+			cMessage.CircularReadGroups = new List<CircularReadGroupDto> { groups };
+
+		}
+
 	}
 }

+ 2 - 0
src/Hotline/Article/ICircularRecordDomainService.cs

@@ -21,5 +21,7 @@ namespace Hotline.Article
 
         Task OrderSpecialCircularMessage(OrderSpecial special, Order order, CancellationToken cancellationToken = default);
 
+        Task OrderSendBackCircularMessage(string userId, string userName, Order order, CancellationToken cancellationToken = default);
+
 	}
 }

+ 0 - 57
src/Hotline/Authentications/ChangeSessionProvider.cs

@@ -1,57 +0,0 @@
-using Hotline.Identity.Accounts;
-using Hotline.Settings;
-using Hotline.Share.Dtos.CallCenter;
-using Hotline.Users;
-using IdentityModel;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Claims;
-using System.Text;
-using System.Threading.Tasks;
-using XF.Domain.Authentications;
-using XF.Domain.Dependency;
-using XF.Domain.Repository;
-
-namespace Hotline.Authentications;
-public class ChangeSessionProvider : IChangeSessionProvider, IScopeDependency
-{
-    private readonly IServiceProvider _serviceProvider;
-
-    public ChangeSessionProvider(IServiceProvider serviceProvider)
-    {
-        _serviceProvider = serviceProvider;
-    }
-
-    public HttpContext ChangeSessionByUserId(string id, HttpContext httpContext)
-    {
-        if (httpContext == null) 
-        {
-            httpContext = new DefaultHttpContext();
-        }
-        var userRepository = _serviceProvider.GetService<IRepository<User>>();
-        var accountRepository = _serviceProvider.GetService<IAccountRepository>();
-        var user = userRepository.Queryable().Where(m => m.Id == id).First();
-        if (user == null) return null;
-        var account = accountRepository.GetExtAsync(m => m.Id == user.Id, m => m.Includes(x => x.Roles)).GetAwaiter().GetResult();
-
-        List<Claim> userClaims = [
-            new(JwtClaimTypes.Subject, account.Id),
-                new(JwtClaimTypes.PhoneNumber, account.PhoneNo ?? string.Empty),
-                new(ClaimTypes.NameIdentifier, user.Id),
-                new(AppClaimTypes.UserDisplayName, account.Name),
-                new(AppClaimTypes.DepartmentId, user.OrgId ?? string.Empty),
-                new(AppClaimTypes.DepartmentIsCenter, user.Organization?.IsCenter.ToString() ?? string.Empty),
-                new(AppClaimTypes.DepartmentName, user.Organization?.Name ?? string.Empty),
-                new(AppClaimTypes.DepartmentAreaCode, user.Organization?.AreaCode ?? string.Empty),
-                new(AppClaimTypes.DepartmentAreaName, user.Organization?.AreaName ?? string.Empty),
-                new(AppClaimTypes.DepartmentLevel, user.Organization?.Level.ToString() ?? string.Empty),
-                new(AppClaimTypes.AreaId, user.OrgId?.GetHigherOrgId() ?? string.Empty),
-            ];
-        userClaims.AddRange(account.Roles.Select(d => new Claim(JwtClaimTypes.Role, d.Name)));
-        httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(userClaims));
-        return httpContext;
-    }
-}

+ 10 - 0
src/Hotline/Authentications/FakeSessionContext.cs

@@ -55,5 +55,15 @@ namespace Hotline.Authentications
         {
             throw new NotImplementedException();
         }
+
+        public async Task ChangeSessionAsync(string userId, CancellationToken cancellation)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void ChangeSession(string userId, string username, string orgId, string orgname, int orgLevel)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 10 - 0
src/Hotline/Authentications/Police110SessionContext.cs

@@ -67,5 +67,15 @@ namespace Hotline.Authentications
         {
             throw new NotImplementedException();
         }
+
+        public async Task ChangeSessionAsync(string userId, CancellationToken cancellation)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void ChangeSession(string userId, string username, string orgId, string orgname, int orgLevel)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 10 - 0
src/Hotline/Authentications/ProvinceSessionContext.cs

@@ -72,5 +72,15 @@ namespace Hotline.Authentications
         {
             throw new NotImplementedException();
         }
+
+        public async Task ChangeSessionAsync(string userId, CancellationToken cancellation)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void ChangeSession(string userId, string username, string orgId, string orgname, int orgLevel)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 59 - 19
src/Hotline/Authentications/SessionContextCreator.cs

@@ -1,29 +1,69 @@
-using XF.Domain.Authentications;
+using Hotline.Caching.Interfaces;
+using Hotline.Caching.Services;
+using Hotline.Configurations;
+using Hotline.Settings;
+using Hotline.Users;
+using Newtonsoft.Json;
+using XF.Domain.Authentications;
+using XF.Domain.Dependency;
 
 
 namespace Hotline.Authentications
 {
-    public class SessionContextCreator
+    public interface ISessionContextCreator
     {
-        public static void CreateSessionContext(ISessionContextProvider sessionContextProvider, string source)
+        Task CreateSessionContextAsync(string source, CancellationToken cancellation);
+    }
+
+    public class SessionContextCreator : ISessionContextCreator, IScopeDependency
+    {
+        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
+        private readonly ISessionContext _sessionContext;
+
+        public SessionContextCreator(
+            ISystemSettingCacheManager systemSettingCacheManager,
+            ISessionContext sessionContext
+            )
         {
-            switch (source)
+            _systemSettingCacheManager = systemSettingCacheManager;
+            _sessionContext = sessionContext;
+        }
+
+        //public static void CreateSessionContext(ISessionContextProvider sessionContextProvider, string source)
+        //{
+        //    switch (source)
+        //    {
+        //        case "province":
+        //            sessionContextProvider.SetContext(ProvinceSessionContext.Key);
+        //            break;
+        //        case "110":
+        //            sessionContextProvider.SetContext(Police110SessionContext.Key);
+        //            break;
+        //        case "yb-enterprise":
+        //            sessionContextProvider.SetContext(YbEnterpriseSessionContext.Key);
+        //            break;
+        //        case "zzpt":
+        //            sessionContextProvider.SetContext(ZzptSessionContext.Key);
+        //            break;
+        //        default:
+        //            throw new ArgumentOutOfRangeException(nameof(source), source, null);
+        //    }
+        //}
+
+        public async Task CreateSessionContextAsync(string source, CancellationToken cancellation)
+        {
+            var setting = _systemSettingCacheManager.GetSetting(SettingConstants.CityBaseConfiguration)?.SettingValue[0];
+            var cityBase = JsonConvert.DeserializeObject<CityBaseConfiguration>(setting);
+            DefaultCityBaseConfiguration config = source switch
             {
-                case "province":
-                    sessionContextProvider.SetContext(ProvinceSessionContext.Key);
-                    break;
-                case "110":
-                    sessionContextProvider.SetContext(Police110SessionContext.Key);
-                    break;
-                case "yb-enterprise":
-                    sessionContextProvider.SetContext(YbEnterpriseSessionContext.Key);
-                    break;
-                case "zzpt":
-                    sessionContextProvider.SetContext(ZzptSessionContext.Key);
-                    break;
-                default:
-                    throw new ArgumentOutOfRangeException(nameof(source), source, null);
-            }
+                "province" => cityBase.CityProvince,
+                "110" => cityBase.PublicSecurity,
+                "yb-enterprise" => cityBase.CityEnterprise,
+                "zzpt" => cityBase.ComprehensiveTreatment,
+                _ => throw new ArgumentOutOfRangeException(nameof(source), source, null)
+            };
+
+            //_sessionContext.ChangeSession(config.UserId, config.UserName, config.OrgId, config.OrgName, config.OrgId.CalcOrgLevel());
         }
     }
 }

+ 112 - 0
src/Hotline/Authentications/SessionContextManager.cs

@@ -0,0 +1,112 @@
+using System.Security.Claims;
+using Hotline.Caching.Interfaces;
+using Hotline.Configurations;
+using Hotline.Identity.Accounts;
+using Hotline.Settings;
+using IdentityModel;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Newtonsoft.Json;
+using XF.Domain.Authentications;
+using XF.Domain.Dependency;
+using XF.Domain.Exceptions;
+using XF.Domain.Repository;
+
+namespace Hotline.Authentications;
+
+public interface ISessionContextManager
+{
+    Task ChangeSessionContextByUserIdAsync(string userId, CancellationToken cancellation);
+
+    /// <summary>
+    /// 依据source创建对应Session
+    /// </summary>
+    void ChangeSessionContext(string source);
+}
+
+public class SessionContextManager : ISessionContextManager, IScopeDependency
+{
+    private readonly IServiceProvider _serviceProvider;
+    private readonly ISystemSettingCacheManager _systemSettingCacheManager;
+
+    public SessionContextManager(
+        IServiceProvider serviceProvider,
+        ISystemSettingCacheManager systemSettingCacheManager)
+    {
+        _serviceProvider = serviceProvider;
+        _systemSettingCacheManager = systemSettingCacheManager;
+    }
+
+    public async Task ChangeSessionContextByUserIdAsync(string userId, CancellationToken cancellation)
+    {
+        var httpContextAccessor = _serviceProvider.GetRequiredService<IHttpContextAccessor>();
+        if (httpContextAccessor.HttpContext == null)
+            throw new UserFriendlyException("current httpContext is null");
+        var accountRepository = _serviceProvider.GetService<IRepository<Account>>();
+
+        var account = await accountRepository.Queryable()
+            .Includes(d => d.User, x => x.Organization)
+            .Includes(d => d.Roles)
+            .FirstAsync(d => d.Id == userId, cancellation);
+
+        List<Claim> userClaims =
+        [
+            new(JwtClaimTypes.Subject, account.Id),
+            new(JwtClaimTypes.PhoneNumber, account.PhoneNo ?? string.Empty),
+            new(ClaimTypes.NameIdentifier, account.Id),
+            new(AppClaimTypes.UserDisplayName, account.Name),
+            new(AppClaimTypes.DepartmentId, account.User?.OrgId ?? string.Empty),
+            new(AppClaimTypes.DepartmentIsCenter, account.User?.Organization?.IsCenter.ToString() ?? string.Empty),
+            new(AppClaimTypes.DepartmentName, account.User?.Organization?.Name ?? string.Empty),
+            new(AppClaimTypes.DepartmentAreaCode, account.User?.Organization?.AreaCode ?? string.Empty),
+            new(AppClaimTypes.DepartmentAreaName, account.User?.Organization?.AreaName ?? string.Empty),
+            new(AppClaimTypes.DepartmentLevel, account.User?.Organization?.Level.ToString() ?? string.Empty),
+            new(AppClaimTypes.AreaId, account.User?.OrgId?.GetHigherOrgId() ?? string.Empty),
+        ];
+        userClaims.AddRange(account.Roles.Select(d => new Claim(JwtClaimTypes.Role, d.Name)));
+        httpContextAccessor.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(userClaims));
+    }
+
+    /// <summary>
+    /// 依据source创建对应Session
+    /// </summary>
+    public void ChangeSessionContext(string source)
+    {
+        var setting = _systemSettingCacheManager.GetSetting(SettingConstants.CityBaseConfiguration)?.SettingValue[0];
+        var cityBase = JsonConvert.DeserializeObject<CityBaseConfiguration>(setting);
+        DefaultCityBaseConfiguration config = source switch
+        {
+            "province" => cityBase.CityProvince,
+            "110" => cityBase.PublicSecurity,
+            "yb-enterprise" => cityBase.CityEnterprise,
+            "zzpt" => cityBase.ComprehensiveTreatment,
+            _ => throw new ArgumentOutOfRangeException(nameof(source), source, null)
+        };
+
+        ChangeSession(config.UserId, config.UserName, config.OrgId, config.OrgName, config.OrgId.CalcOrgLevel());
+    }
+
+    #region private
+
+    private void ChangeSession(string userId, string username, string orgId, string orgname, int orgLevel)
+    {
+        var httpContextAccessor = _serviceProvider.GetRequiredService<IHttpContextAccessor>();
+        if (httpContextAccessor.HttpContext == null)
+            throw new UserFriendlyException("current httpContext is null");
+
+        List<Claim> userClaims =
+        [
+            new(JwtClaimTypes.Subject, userId),
+            new(ClaimTypes.NameIdentifier, userId),
+            new(AppClaimTypes.UserDisplayName, username),
+            new(AppClaimTypes.DepartmentId, orgId ?? string.Empty),
+            new(AppClaimTypes.DepartmentIsCenter, orgId?.IsCenter().ToString() ?? string.Empty),
+            new(AppClaimTypes.DepartmentName, orgname ?? string.Empty),
+            new(AppClaimTypes.DepartmentLevel, orgLevel.ToString() ?? string.Empty),
+            new(AppClaimTypes.AreaId, orgId?.GetHigherOrgId() ?? string.Empty),
+        ];
+        httpContextAccessor.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(userClaims));
+    }
+
+    #endregion
+}

+ 85 - 7
src/Hotline/Authentications/SessionContextProvider.cs

@@ -1,28 +1,106 @@
 using Hotline.Configurations;
+using Hotline.Users;
+using IdentityModel;
+using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
+using System.Security.Claims;
+using Hotline.Settings;
 using XF.Domain.Authentications;
 using XF.Domain.Dependency;
+using XF.Domain.Repository;
+using Hotline.Identity.Accounts;
+using Hotline.Share.Dtos.FlowEngine;
+using Hotline.Share.Dtos.FlowEngine.Workflow;
 
 namespace Hotline.Authentications;
 
 public class SessionContextProvider : ISessionContextProvider, IScopeDependency
 {
     private readonly IServiceProvider _serviceProvider;
-    public ISessionContext SessionContext { get; set; }
 
-    public SessionContextProvider(IServiceProvider serviceProvider, ISessionContext sessionContext)
+    public SessionContextProvider(IServiceProvider serviceProvider)
     {
         _serviceProvider = serviceProvider;
-        SessionContext = sessionContext;
     }
 
-    public void SetContext(string key)
+    public HttpContext ChangeSessionByUserId(string id, HttpContext httpContext)
     {
-        SessionContext = _serviceProvider.GetRequiredKeyedService<ISessionContext>(key);
+        if (httpContext == null)
+        {
+            httpContext = new DefaultHttpContext();
+        }
+
+        var userRepository = _serviceProvider.GetService<IRepository<User>>();
+        var accountRepository = _serviceProvider.GetService<IAccountRepository>();
+        var user = userRepository.Queryable().Where(m => m.Id == id).First();
+        if (user == null) return null;
+        var account = accountRepository.GetExtAsync(m => m.Id == user.Id, m => m.Includes(x => x.Roles)).GetAwaiter().GetResult();
+
+        List<Claim> userClaims =
+        [
+            new(JwtClaimTypes.Subject, account.Id),
+            new(JwtClaimTypes.PhoneNumber, account.PhoneNo ?? string.Empty),
+            new(ClaimTypes.NameIdentifier, user.Id),
+            new(AppClaimTypes.UserDisplayName, account.Name),
+            new(AppClaimTypes.DepartmentId, user.OrgId ?? string.Empty),
+            new(AppClaimTypes.DepartmentIsCenter, user.Organization?.IsCenter.ToString() ?? string.Empty),
+            new(AppClaimTypes.DepartmentName, user.Organization?.Name ?? string.Empty),
+            new(AppClaimTypes.DepartmentAreaCode, user.Organization?.AreaCode ?? string.Empty),
+            new(AppClaimTypes.DepartmentAreaName, user.Organization?.AreaName ?? string.Empty),
+            new(AppClaimTypes.DepartmentLevel, user.Organization?.Level.ToString() ?? string.Empty),
+            new(AppClaimTypes.AreaId, user.OrgId?.GetHigherOrgId() ?? string.Empty),
+        ];
+        userClaims.AddRange(account.Roles.Select(d => new Claim(JwtClaimTypes.Role, d.Name)));
+        httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(userClaims));
+        return httpContext;
     }
 
-    public void SetContext(ISessionContext sessionContext)
+    public async Task ChangeSessionByUserIdAsync(string userId, CancellationToken cancellation)
     {
-        SessionContext = sessionContext;
+        var httpContext = _serviceProvider.GetRequiredService<IHttpContextAccessor>().HttpContext;
+        var accountRepository = _serviceProvider.GetService<IRepository<Account>>();
+        httpContext ??= new DefaultHttpContext();
+
+        var account = await accountRepository.Queryable()
+            .Includes(d => d.User, x=>x.Organization)
+            .Includes(d => d.Roles)
+            .FirstAsync(d => d.Id == userId, cancellation);
+
+        List<Claim> userClaims =
+        [
+            new(JwtClaimTypes.Subject, account.Id),
+            new(JwtClaimTypes.PhoneNumber, account.PhoneNo ?? string.Empty),
+            new(ClaimTypes.NameIdentifier, account.Id),
+            new(AppClaimTypes.UserDisplayName, account.Name),
+            new(AppClaimTypes.DepartmentId, account.User?.OrgId ?? string.Empty),
+            new(AppClaimTypes.DepartmentIsCenter, account.User?.Organization?.IsCenter.ToString() ?? string.Empty),
+            new(AppClaimTypes.DepartmentName, account.User?.Organization?.Name ?? string.Empty),
+            new(AppClaimTypes.DepartmentAreaCode, account.User?.Organization?.AreaCode ?? string.Empty),
+            new(AppClaimTypes.DepartmentAreaName, account.User?.Organization?.AreaName ?? string.Empty),
+            new(AppClaimTypes.DepartmentLevel, account.User?.Organization?.Level.ToString() ?? string.Empty),
+            new(AppClaimTypes.AreaId, account.User?.OrgId?.GetHigherOrgId() ?? string.Empty),
+        ];
+        userClaims.AddRange(account.Roles.Select(d => new Claim(JwtClaimTypes.Role, d.Name)));
+        httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(userClaims));
     }
+
+    public void ChangeSession(string userId, string username, string orgId, string orgname, int orgLevel)
+    {
+        var httpContext = _serviceProvider.GetRequiredService<IHttpContextAccessor>().HttpContext;
+        httpContext ??= new DefaultHttpContext();
+
+        List<Claim> userClaims =
+        [
+            new(JwtClaimTypes.Subject, userId),
+            new(ClaimTypes.NameIdentifier, userId),
+            new(AppClaimTypes.UserDisplayName, username),
+            new(AppClaimTypes.DepartmentId, orgId ?? string.Empty),
+            new(AppClaimTypes.DepartmentIsCenter, orgId?.IsCenter().ToString() ?? string.Empty),
+            new(AppClaimTypes.DepartmentName, orgname ?? string.Empty),
+            new(AppClaimTypes.DepartmentLevel, orgLevel.ToString() ?? string.Empty),
+            new(AppClaimTypes.AreaId, orgId?.GetHigherOrgId() ?? string.Empty),
+        ];
+        httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(userClaims));
+    }
+
 }

+ 10 - 0
src/Hotline/Authentications/YbEnterpriseSessionContext.cs

@@ -68,5 +68,15 @@ namespace Hotline.Authentications
         {
             throw new NotImplementedException();
         }
+
+        public async Task ChangeSessionAsync(string userId, CancellationToken cancellation)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void ChangeSession(string userId, string username, string orgId, string orgname, int orgLevel)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 10 - 0
src/Hotline/Authentications/ZzptSessionContext.cs

@@ -67,5 +67,15 @@ namespace Hotline.Authentications
         {
             throw new NotImplementedException();
         }
+
+        public async Task ChangeSessionAsync(string userId, CancellationToken cancellation)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void ChangeSession(string userId, string username, string orgId, string orgname, int orgLevel)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 3 - 1
src/Hotline/File/IFileRepository.cs

@@ -18,5 +18,7 @@ namespace Hotline.File
 		Task<List<WorkflowTraceDto>> WorkflowTraceRecursion(List<WorkflowTraceDto> dto, CancellationToken cancellationToken);
 		Task<List<Hotline.File.File>> GetByKeyAsync(string key, CancellationToken cancellationToken);
         Task<List<FileJson>> AddFileAsync(IList<SnapshotFileInDto> files, string id, CancellationToken requestAborted);
-    }
+		Task<List<FileJson>> AddFileAsync(IList<FileDto> files, string id, CancellationToken requestAborted);
+
+	}
 }

+ 3 - 1
src/Hotline/FlowEngine/Workflows/IWorkflowDomainService.cs

@@ -38,7 +38,9 @@ namespace Hotline.FlowEngine.Workflows
         /// <summary>
         /// new
         /// </summary>
-        Task<(Workflow, WorkflowStep, StepDefine, List<WorkflowStep>)> NextAsync(ISessionContext current, NextWorkflowDto dto,
+        Task<(Workflow, WorkflowStep, StepDefine, List<WorkflowStep>)> NextAsync(
+            NextWorkflowDto dto,
+            EHandleMode handleMode = EHandleMode.Normal,
             DateTime? expiredTime = null, bool isAutoFillSummaryOpinion = false,
             Action<Workflow, WorkflowStep, StepDefine>? currentStepConfig = null,
             Action<Workflow, WorkflowStep, StepDefine, WorkflowStep>? newStepConfig = null,

+ 123 - 118
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -43,7 +43,7 @@ namespace Hotline.FlowEngine.Workflows
         private readonly IRepository<User> _userRepository;
         private readonly ISystemSettingCacheManager _systemSettingCacheManager;
         private readonly IWfModuleCacheManager _wfModuleCacheManager;
-        private readonly ISessionContextProvider _sessionContextProvider;
+        private readonly ISessionContext _sessionContext;
         private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
 
         public WorkflowDomainService(
@@ -53,7 +53,7 @@ namespace Hotline.FlowEngine.Workflows
             IRepository<WorkflowCountersign> workflowCountersignRepository,
             ISystemSettingCacheManager systemSettingCacheManager,
             IWfModuleCacheManager wfModuleCacheManager,
-            ISessionContextProvider sessionContextProvider,
+            ISessionContext sessionContext,
             IMapper mapper,
             Publisher publisher,
             ILogger<WorkflowDomainService> logger,
@@ -70,7 +70,7 @@ namespace Hotline.FlowEngine.Workflows
             _fileRepository = fileRepository;
             _systemSettingCacheManager = systemSettingCacheManager;
             _wfModuleCacheManager = wfModuleCacheManager;
-            _sessionContextProvider = sessionContextProvider;
+            _sessionContext = sessionContext;
             _appOptions = appOptions;
         }
 
@@ -117,23 +117,23 @@ namespace Hotline.FlowEngine.Workflows
         //             PublishStrategy.ParallelWhenAll, cancellationToken);
         //
         //         //firstStep是否为end,t: 实际办理节点为startStep, 并且handlerId赋值 f: 实际办理节点为firstStep, handlerId未赋值
-        //         workflow.UpdateActualStepWhenHandle(startStep, _sessionContextProvider.SessionContext.OrgAreaCode,
-        //             _sessionContextProvider.SessionContext.OrgAreaName, _sessionContextProvider.SessionContext.OrgLevel);
+        //         workflow.UpdateActualStepWhenHandle(startStep, _sessionContext.OrgAreaCode,
+        //             _sessionContext.OrgAreaName, _sessionContext.OrgLevel);
         //
-        //         workflow.UpdateCurrentStepWhenHandle(startStep, _sessionContextProvider.SessionContext.OrgAreaCode,
-        //             _sessionContextProvider.SessionContext.OrgAreaName, _sessionContextProvider.SessionContext.OrgLevel);
+        //         workflow.UpdateCurrentStepWhenHandle(startStep, _sessionContext.OrgAreaCode,
+        //             _sessionContext.OrgAreaName, _sessionContext.OrgLevel);
         //
-        //         var endTrace = await EndAsync(_sessionContextProvider.SessionContext, workflow, dto, firstStepDefine, startStep, expiredTime,
+        //         var endTrace = await EndAsync(_sessionContext, workflow, dto, firstStepDefine, startStep, expiredTime,
         //             cancellationToken);
         //         return;
         //     }
         //
         //     var assigner = new UserInfo(
-        //         _sessionContextProvider.SessionContext.UserId,
-        //         _sessionContextProvider.SessionContext.UserName,
-        //         _sessionContextProvider.SessionContext.OrgId,
-        //         _sessionContextProvider.SessionContext.OrgName,
-        //         _sessionContextProvider.SessionContext.OrgIsCenter
+        //         _sessionContext.UserId,
+        //         _sessionContext.UserName,
+        //         _sessionContext.OrgId,
+        //         _sessionContext.OrgName,
+        //         _sessionContext.OrgIsCenter
         //     );
         //
         //     //firststeps
@@ -188,7 +188,7 @@ namespace Hotline.FlowEngine.Workflows
 
             //下一节点是否为动态节点
             var isNextDynamic = startStepDefine.InstanceMode is EInstanceMode.Dynamic &&
-                                !DynamicShouldTerminal(startStepDefine, _sessionContextProvider.SessionContext.OrgLevel);
+                                !DynamicShouldTerminal(startStepDefine, _sessionContext.OrgLevel);
             var firstStepDefine = isNextDynamic
                 ? startStepDefine
                 : definition.FindStepDefine(dto.NextStepCode);
@@ -217,21 +217,21 @@ namespace Hotline.FlowEngine.Workflows
 
             var defineHandler = startStepDefine.HandlerTypeItems.First();
             var assigner = new UserInfo(
-                _sessionContextProvider.SessionContext.UserId,
-                _sessionContextProvider.SessionContext.UserName,
-                _sessionContextProvider.SessionContext.OrgId,
-                _sessionContextProvider.SessionContext.OrgName,
-                _sessionContextProvider.SessionContext.OrgIsCenter
+                _sessionContext.UserId,
+                _sessionContext.UserName,
+                _sessionContext.OrgId,
+                _sessionContext.OrgName,
+                _sessionContext.OrgIsCenter
             );
 
             var handler = new StepAssignInfo
             {
-                Key = _sessionContextProvider.SessionContext.RequiredUserId,
-                Value = _sessionContextProvider.SessionContext.UserName,
-                UserId = _sessionContextProvider.SessionContext.UserId,
-                Username = _sessionContextProvider.SessionContext.UserName,
-                OrgId = _sessionContextProvider.SessionContext.RequiredOrgId,
-                OrgName = _sessionContextProvider.SessionContext.OrgName,
+                Key = _sessionContext.RequiredUserId,
+                Value = _sessionContext.UserName,
+                UserId = _sessionContext.UserId,
+                Username = _sessionContext.UserName,
+                OrgId = _sessionContext.RequiredOrgId,
+                OrgName = _sessionContext.OrgName,
                 RoleId = defineHandler.Key,
                 RoleName = defineHandler.Value,
                 FlowAssignType = EFlowAssignType.User
@@ -258,11 +258,11 @@ namespace Hotline.FlowEngine.Workflows
 
             //更新受理人信息
             workflow.UpdateAcceptor(
-                _sessionContextProvider.SessionContext.RequiredUserId,
-                _sessionContextProvider.SessionContext.UserName,
-                _sessionContextProvider.SessionContext.StaffNo,
-                _sessionContextProvider.SessionContext.RequiredOrgId,
-                _sessionContextProvider.SessionContext.OrgName);
+                _sessionContext.RequiredUserId,
+                _sessionContext.UserName,
+                _sessionContext.StaffNo,
+                _sessionContext.RequiredOrgId,
+                _sessionContext.OrgName);
 
             workflow.UpdateActualStepWhenAssign(startStep, handler);
             workflow.UpdateCurrentStepWhenAssign(startStep, handler);
@@ -284,7 +284,8 @@ namespace Hotline.FlowEngine.Workflows
         /// workflow, currentStep, nextStepDefine, nextSteps
         /// </summary>
         public async Task<(Workflow, WorkflowStep, StepDefine, List<WorkflowStep>)> NextAsync(
-            ISessionContext current, NextWorkflowDto dto,
+            NextWorkflowDto dto, 
+            EHandleMode handleMode = EHandleMode.Normal,
             DateTime? expiredTime = null, bool isAutoFillSummaryOpinion = false,
             Action<Workflow, WorkflowStep, StepDefine>? currentStepConfig = null,
             Action<Workflow, WorkflowStep, StepDefine, WorkflowStep>? newStepConfig = null,
@@ -307,7 +308,7 @@ namespace Hotline.FlowEngine.Workflows
             //下一节点是否为动态节点
             var isNextDynamic = (string.IsNullOrEmpty(dto.NextStepCode) || dto.NextStepCode.ToLower() != "end")
                                 && currentStepDefine.InstanceMode is EInstanceMode.Dynamic
-                                && !DynamicShouldTerminal(currentStepDefine, current.OrgLevel);
+                                && !DynamicShouldTerminal(currentStepDefine, _sessionContext.OrgLevel);
 
             StepDefine nextStepDefine;
             if (isNextDynamic
@@ -369,8 +370,8 @@ namespace Hotline.FlowEngine.Workflows
                             Value = handler.Value,
                             RoleId = handler.Key,
                             RoleName = handler.Value,
-                            OrgId = _sessionContextProvider.SessionContext.RequiredOrgId,
-                            OrgName = _sessionContextProvider.SessionContext.OrgName,
+                            OrgId = _sessionContext.RequiredOrgId,
+                            OrgName = _sessionContext.OrgName,
                             FlowAssignType = EFlowAssignType.OrgAndRole
                         });
                     }
@@ -427,14 +428,14 @@ namespace Hotline.FlowEngine.Workflows
 
                     //结束会签
                     currentCountersign.End(currentStep.Id, currentStep.Code, currentStep.BusinessType,
-                        current.UserId, current.UserName,
-                        current.OrgId, current.OrgName,
-                        current.OrgAreaCode, current.OrgAreaName);
+                        _sessionContext.RequiredUserId, _sessionContext.UserName,
+                        _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                        _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
                     await _workflowCountersignRepository.UpdateAsync(currentCountersign, cancellationToken);
                 }
             }
 
-            await HandleStepAsync(currentStep, workflow, dto, counterSignType, expiredTime, EHandleMode.Normal, cancellationToken);
+            await HandleStepAsync(currentStep, workflow, dto, counterSignType, expiredTime, handleMode, cancellationToken);
 
             currentStep.IsActualHandled = CheckIsActualHandle(workflow, currentStep, nextStepDefine, dto);
 
@@ -453,7 +454,7 @@ namespace Hotline.FlowEngine.Workflows
                         //throw new UserFriendlyException(
                         //    $"会签数据异常, workflowId: {currentStep.WorkflowId}, countersignId: {currentStep.CountersignId}",
                         //    "会签数据异常");
-                        countersign.MemberHandled(current.UserId, current.OrgId);
+                        countersign.MemberHandled(_sessionContext.UserId, _sessionContext.OrgId);
                         //update cs
                         await _workflowCountersignRepository.UpdateNav(countersign)
                             .Include(d => d.Members)
@@ -479,14 +480,14 @@ namespace Hotline.FlowEngine.Workflows
             if (workflow.ActualHandleStepId == currentStep.Id)
             {
                 //更新实际办理节点信息
-                workflow.UpdateActualStepWhenHandle(currentStep, _sessionContextProvider.SessionContext.OrgAreaCode,
-                    _sessionContextProvider.SessionContext.OrgAreaName, _sessionContextProvider.SessionContext.OrgLevel);
+                workflow.UpdateActualStepWhenHandle(currentStep, _sessionContext.OrgAreaCode,
+                    _sessionContext.OrgAreaName, _sessionContext.OrgLevel);
             }
 
             if (workflow.CurrentStepId == currentStep.Id)
             {
-                workflow.UpdateCurrentStepWhenHandle(currentStep, _sessionContextProvider.SessionContext.OrgAreaCode,
-                    _sessionContextProvider.SessionContext.OrgAreaName, _sessionContextProvider.SessionContext.OrgLevel);
+                workflow.UpdateCurrentStepWhenHandle(currentStep, _sessionContext.OrgAreaCode,
+                    _sessionContext.OrgAreaName, _sessionContext.OrgLevel);
             }
 
             //var trace = await NextTraceAsync(workflow, dto, currentStep, cancellationToken);
@@ -511,13 +512,13 @@ namespace Hotline.FlowEngine.Workflows
                     || string.IsNullOrEmpty(workflow.ActualHandleOrgCode)) //开始流程直接归档
                 {
                     //更新实际办理节点信息
-                    workflow.UpdateActualStepWhenHandle(currentStep, _sessionContextProvider.SessionContext.OrgAreaCode,
-                        _sessionContextProvider.SessionContext.OrgAreaName, _sessionContextProvider.SessionContext.OrgLevel);
+                    workflow.UpdateActualStepWhenHandle(currentStep, _sessionContext.OrgAreaCode,
+                        _sessionContext.OrgAreaName, _sessionContext.OrgLevel);
                     workflow.ActualHandleStepAcceptTime = currentStep.AcceptTime;
                     workflow.ActualHandleTime = currentStep.HandleTime;
                 }
 
-                var (endStep, _) = await EndAsync(current, workflow, dto, nextStepDefine, currentStep, expiredTime, cancellationToken);
+                var (endStep, _) = await EndAsync(_sessionContext, workflow, dto, nextStepDefine, currentStep, expiredTime, cancellationToken);
                 return (workflow, currentStep, nextStepDefine, new List<WorkflowStep> { endStep });
             }
 
@@ -536,10 +537,10 @@ namespace Hotline.FlowEngine.Workflows
             if (isStartCountersign)
             {
                 var exists = workflow.Countersigns.Any(d =>
-                    !d.IsCompleted() && !string.IsNullOrEmpty(current.UserId) && d.StarterId == current.UserId);
+                    !d.IsCompleted() && !string.IsNullOrEmpty(_sessionContext.UserId) && d.StarterId == _sessionContext.UserId);
                 if (exists)
-                    throw new UserFriendlyException($"该用户在当前流程存在未结束会签, workflowId: {workflow.Id}, userId: {current.UserId}");
-                var countersign = await StartCountersignAsync(current, workflow, currentStep, dto,
+                    throw new UserFriendlyException($"该用户在当前流程存在未结束会签, workflowId: {workflow.Id}, userId: {_sessionContext.UserId}");
+                var countersign = await StartCountersignAsync(_sessionContext, workflow, currentStep, dto,
                     counterSignType, expiredTime, cancellationToken);
                 currentTrace.StartCountersign(countersign.Id);
                 await _workflowStepRepository.UpdateAsync(currentStep, cancellationToken);
@@ -551,11 +552,11 @@ namespace Hotline.FlowEngine.Workflows
                 workflow.StartCountersign(currentStep.Id, counterSignType);
 
             var assigner = new UserInfo(
-                _sessionContextProvider.SessionContext.UserId,
-                _sessionContextProvider.SessionContext.UserName,
-                _sessionContextProvider.SessionContext.OrgId,
-                _sessionContextProvider.SessionContext.OrgName,
-                _sessionContextProvider.SessionContext.OrgIsCenter
+                _sessionContext.UserId,
+                _sessionContext.UserName,
+                _sessionContext.OrgId,
+                _sessionContext.OrgName,
+                _sessionContext.OrgIsCenter
             );
 
             //创建下一/N个节点(会签汇总节点:会签未全部办理时不创建,最后一个会签办理节点创建会签汇总节点)
@@ -575,7 +576,7 @@ namespace Hotline.FlowEngine.Workflows
 
             //更新会签实际办理对象信息
             if (currentStep.IsActualHandled)
-                workflow.AddCsActualHandler(current.UserId, current.OrgId);
+                workflow.AddCsActualHandler(_sessionContext.UserId, _sessionContext.OrgId);
 
             await _workflowRepository.UpdateAsync(workflow, cancellationToken);
 
@@ -589,7 +590,7 @@ namespace Hotline.FlowEngine.Workflows
 
             await _publisher.PublishAsync(
                 new NextStepNotify(workflow, dto, currentTrace, nextStepDefine,
-                    current.OrgId, expiredTime.HasValue), PublishStrategy.ParallelWhenAll,
+                    _sessionContext.OrgId, expiredTime.HasValue), PublishStrategy.ParallelWhenAll,
                 cancellationToken);
 
             return (workflow, currentStep, nextStepDefine, nextSteps);
@@ -608,7 +609,9 @@ namespace Hotline.FlowEngine.Workflows
             nextDto.WorkflowId = workflow.Id;
             nextDto.StepId = startStep.Id;
             var (_, _, _, nextSteps) =
-                await NextAsync(_sessionContextProvider.SessionContext, nextDto, expiredTime, true,
+                await NextAsync(nextDto, 
+                    expiredTime: expiredTime, 
+                    isAutoFillSummaryOpinion: true,
                     newStepConfig: newStepConfig, cancellationToken: cancellationToken);
             return nextSteps;
         }
@@ -699,13 +702,13 @@ namespace Hotline.FlowEngine.Workflows
             string? orgAreaCode, string? orgAreaName,
             CancellationToken cancellationToken)
         {
-            if (!workflow.IsCanHandle(_sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.RequiredOrgId,
-                    _sessionContextProvider.SessionContext.Roles)) return null;
+            if (!workflow.IsCanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId,
+                    _sessionContext.Roles)) return null;
             //工单完成以后查看的场景
             if (workflow.Status != EWorkflowStatus.Runnable) return null;
 
-            var currentStep = GetUnHandleStep(workflow.Steps, _sessionContextProvider.SessionContext.RequiredOrgId,
-                _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.Roles);
+            var currentStep = GetUnHandleStep(workflow.Steps, _sessionContext.RequiredOrgId,
+                _sessionContext.RequiredUserId, _sessionContext.Roles);
             if (currentStep.Status is not EWorkflowStepStatus.WaitForAccept) return null;
 
             //if (currentStep.Handlers.All(d => d.Key != orgId && d.Key != userId)) return null;
@@ -726,6 +729,7 @@ namespace Hotline.FlowEngine.Workflows
                 .ExecuteCommandAsync();
 
             workflow.ActualHandleStepAcceptTime = currentStep.AcceptTime;
+            workflow.CurrentStepAcceptTime = currentStep.AcceptTime;
             await _workflowRepository.Updateable(workflow).ExecuteCommandAsync(cancellationToken);
 
             return workflow.ActualHandleStepAcceptTime;
@@ -984,7 +988,8 @@ namespace Hotline.FlowEngine.Workflows
                 newPrevStep.Assign(handle.UserId, handle.Username, handle.OrgId, handle.OrgName, handle.RoleId, handle.RoleName);
             }
 
-            await Task.Run(() => newStepConfig?.Invoke(workflow, currentStep, prevStepDefine, prevStep, newPrevStep), cancellationToken);
+            //await Task.Run(() => newStepConfig?.Invoke(workflow, currentStep, prevStepDefine, prevStep, newPrevStep), cancellationToken);
+            newStepConfig?.Invoke(workflow, currentStep, prevStepDefine, prevStep, newPrevStep);
             await _workflowStepRepository.AddAsync(newPrevStep, cancellationToken);
             await CreateTraceAsync(workflow, newPrevStep, EWorkflowTraceType.Previous, cancellationToken);
 
@@ -1613,10 +1618,10 @@ namespace Hotline.FlowEngine.Workflows
                 foreach (var trace in uncompleteTraces)
                 {
                     trace.Handle(
-                        _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-                        _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-                        _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName,
-                        _sessionContextProvider.SessionContext.OrgIsCenter, handleMode, dto.Opinion);
+                        _sessionContext.RequiredUserId, _sessionContext.UserName,
+                        _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                        _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
+                        _sessionContext.OrgIsCenter, handleMode, dto.Opinion);
                 }
 
                 //await _workflowTraceRepository.UpdateRangeAsync(uncompleteTraces, cancellationToken);
@@ -1671,9 +1676,9 @@ namespace Hotline.FlowEngine.Workflows
                 foreach (var unCompleteCountersign in unCompleteCountersigns)
                 {
                     unCompleteCountersign.End(null, null, EBusinessType.File,
-                        _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-                        _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-                        _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName);
+                        _sessionContext.RequiredUserId, _sessionContext.UserName,
+                        _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                        _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
                 }
 
                 await _workflowCountersignRepository.UpdateRangeAsync(unCompleteCountersigns, cancellationToken);
@@ -1685,11 +1690,11 @@ namespace Hotline.FlowEngine.Workflows
                 workflow.SetStatusRunnable();
 
             var assigner = new UserInfo(
-                _sessionContextProvider.SessionContext.UserId,
-                _sessionContextProvider.SessionContext.UserName,
-                _sessionContextProvider.SessionContext.OrgId,
-                _sessionContextProvider.SessionContext.OrgName,
-                _sessionContextProvider.SessionContext.OrgIsCenter
+                _sessionContext.UserId,
+                _sessionContext.UserName,
+                _sessionContext.OrgId,
+                _sessionContext.OrgName,
+                _sessionContext.OrgIsCenter
             );
 
             //var targetStepNew = targetIsStartStep
@@ -2119,7 +2124,7 @@ namespace Hotline.FlowEngine.Workflows
                 _ => throw new ArgumentOutOfRangeException(nameof(currentStepBusinessType), currentStepBusinessType, null)
             };
 
-            // return _sessionContextProvider.SessionContext.OrgIsCenter ? ECounterSignType.Center : ECounterSignType.Department;
+            // return _sessionContext.OrgIsCenter ? ECounterSignType.Center : ECounterSignType.Department;
         }
 
         /// <summary>
@@ -2753,10 +2758,10 @@ namespace Hotline.FlowEngine.Workflows
         private void HandleStep(WorkflowStep step, EHandleMode handleMode, string opinion, string nextStepCode)
         {
             //todo 重构:ISessionContext传入
-            step.Handle(_sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-                _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-                _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName,
-                _sessionContextProvider.SessionContext.OrgIsCenter, handleMode, opinion, nextStepCode);
+            step.Handle(_sessionContext.RequiredUserId, _sessionContext.UserName,
+                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
+                _sessionContext.OrgIsCenter, handleMode, opinion, nextStepCode);
 
             //var handler = step.FindActualHandler(current.Roles, current.RequiredUserId, current.RequiredOrgId);
             //if (handler is not null)
@@ -3144,10 +3149,10 @@ namespace Hotline.FlowEngine.Workflows
         //         foreach (var trace in uncompleteTraces)
         //         {
         //             trace.Handle(
-        //                 _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-        //                 _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-        //                 _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName,
-        //                 _sessionContextProvider.SessionContext.OrgIsCenter, handleMode, dto.Opinion);
+        //                 _sessionContext.RequiredUserId, _sessionContext.UserName,
+        //                 _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+        //                 _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
+        //                 _sessionContext.OrgIsCenter, handleMode, dto.Opinion);
         //         }
         //
         //         //await _workflowTraceRepository.UpdateRangeAsync(uncompleteTraces, cancellationToken);
@@ -3202,9 +3207,9 @@ namespace Hotline.FlowEngine.Workflows
         //         foreach (var unCompleteCountersign in unCompleteCountersigns)
         //         {
         //             unCompleteCountersign.End(null, null, EBusinessType.File,
-        //                 _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-        //                 _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-        //                 _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName);
+        //                 _sessionContext.RequiredUserId, _sessionContext.UserName,
+        //                 _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+        //                 _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
         //         }
         //
         //         await _workflowCountersignRepository.UpdateRangeAsync(unCompleteCountersigns, cancellationToken);
@@ -3216,11 +3221,11 @@ namespace Hotline.FlowEngine.Workflows
         //         workflow.SetStatusRunnable();
         //
         //     var assigner = new UserInfo(
-        //         _sessionContextProvider.SessionContext.UserId,
-        //         _sessionContextProvider.SessionContext.UserName,
-        //         _sessionContextProvider.SessionContext.OrgId,
-        //         _sessionContextProvider.SessionContext.OrgName,
-        //         _sessionContextProvider.SessionContext.OrgIsCenter
+        //         _sessionContext.UserId,
+        //         _sessionContext.UserName,
+        //         _sessionContext.OrgId,
+        //         _sessionContext.OrgName,
+        //         _sessionContext.OrgIsCenter
         //     );
         //
         //     var targetStepNew = targetIsStartStep
@@ -3303,29 +3308,29 @@ namespace Hotline.FlowEngine.Workflows
 
             var handler = new StepAssignInfo
             {
-                Key = _sessionContextProvider.SessionContext.UserId,
-                Value = _sessionContextProvider.SessionContext.UserName,
-                UserId = _sessionContextProvider.SessionContext.RequiredUserId,
-                Username = _sessionContextProvider.SessionContext.UserName,
-                OrgId = _sessionContextProvider.SessionContext.OrgId,
-                OrgName = _sessionContextProvider.SessionContext.OrgName,
+                Key = _sessionContext.UserId,
+                Value = _sessionContext.UserName,
+                UserId = _sessionContext.RequiredUserId,
+                Username = _sessionContext.UserName,
+                OrgId = _sessionContext.OrgId,
+                OrgName = _sessionContext.OrgName,
                 FlowAssignType = EFlowAssignType.User,
             };
 
             var assigner = new UserInfo(
-                _sessionContextProvider.SessionContext.UserId,
-                _sessionContextProvider.SessionContext.UserName,
-                _sessionContextProvider.SessionContext.OrgId,
-                _sessionContextProvider.SessionContext.OrgName,
-                _sessionContextProvider.SessionContext.OrgIsCenter
+                _sessionContext.UserId,
+                _sessionContext.UserName,
+                _sessionContext.OrgId,
+                _sessionContext.OrgName,
+                _sessionContext.OrgIsCenter
             );
             var step = CreateStep(workflow, endStepDefine, prevStep, handler, assigner,
                 null, null, EWorkflowStepStatus.WaitForAccept,
                 ECountersignPosition.None, expiredTime, endStepDefine.Name, true, businessType: EBusinessType.File, flowDirection: dto.FlowDirection);
 
-            //step.Accept(_sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-            //    _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-            //    _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName);
+            //step.Accept(_sessionContext.RequiredUserId, _sessionContext.UserName,
+            //    _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+            //    _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
 
             HandleStep(step, EHandleMode.Normal, "流程归档", string.Empty);
 
@@ -3582,8 +3587,8 @@ namespace Hotline.FlowEngine.Workflows
                         throw new UserFriendlyException(
                             $"TerminalDynamicMark parse to int failed, tMark: {currentStepDefine.TerminalDynamicMark}");
                     var leadRoleCode = _systemSettingCacheManager.GetSetting(SettingConstants.RoleLingDao)?.SettingValue[0];
-                    var isLead = _sessionContextProvider.SessionContext.Roles.Any(x => x == leadRoleCode);
-                    return (currentOrgLevel <= tMark2) && (isLead || _sessionContextProvider.SessionContext.OrgIsCenter);
+                    var isLead = _sessionContext.Roles.Any(x => x == leadRoleCode);
+                    return (currentOrgLevel <= tMark2) && (isLead || _sessionContext.OrgIsCenter);
                 case EDynamicPolicy.OrgDownCenterTop:
                 case EDynamicPolicy.OrgDown:
                     if (!int.TryParse(currentStepDefine.TerminalDynamicMark, out var tMark1))
@@ -3737,16 +3742,16 @@ namespace Hotline.FlowEngine.Workflows
             ref List<WorkflowStep> updateSteps, ref List<WorkflowTrace> updateTraces)
         {
             var isHandled = step.Status is EWorkflowStepStatus.Handled;
-            var opinion = $"会签未办理完成,由 {_sessionContextProvider.SessionContext.OrgName} 的 {_sessionContextProvider.SessionContext.UserName} 终止办理";
+            var opinion = $"会签未办理完成,由 {_sessionContext.OrgName} 的 {_sessionContext.UserName} 终止办理";
             if (step.IsStartCountersign)
                 step.CountersignEnd();
 
             if (step.Status is not EWorkflowStepStatus.Handled)
             {
-                step.Handle(_sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-                    _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-                    _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName,
-                    _sessionContextProvider.SessionContext.OrgIsCenter, EHandleMode.Normal, opinion);
+                step.Handle(_sessionContext.RequiredUserId, _sessionContext.UserName,
+                    _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                    _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
+                    _sessionContext.OrgIsCenter, EHandleMode.Normal, opinion);
             }
 
             updateSteps.Add(step);
@@ -3789,9 +3794,9 @@ namespace Hotline.FlowEngine.Workflows
             //todo 1. trace? 先确定展现形式 2. end cs
 
             countersign.End(null, null, businessType,
-                _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-                _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-                _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName);
+                _sessionContext.RequiredUserId, _sessionContext.UserName,
+                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
 
             /*
             * //结束step会签信息
@@ -3800,9 +3805,9 @@ namespace Hotline.FlowEngine.Workflows
 
                    //结束会签
                    currentCountersign.End(currentStep.Id, currentStep.Code, currentStep.BusinessType,
-                       _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
-                       _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
-                       _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName);
+                       _sessionContext.RequiredUserId, _sessionContext.UserName,
+                       _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                       _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
                    await _workflowCountersignRepository.UpdateAsync(currentCountersign, cancellationToken);
             */
 

+ 1 - 0
src/Hotline/FlowEngine/Workflows/WorkflowStep.cs

@@ -42,6 +42,7 @@ public class WorkflowStep : StepBasicEntity
         AcceptorOrgAreaCode = null;
         AcceptorOrgAreaName = null;
         AcceptTime = null;
+        HandleMode = null;
 
         IsStartCountersign = false;
 

+ 12 - 9
src/Hotline/Orders/DatabaseEventHandler/OrderVisitDetailEventHandler.cs

@@ -45,12 +45,13 @@ public class OrderVisitDetailEventHandler : IUpdateDatabaseEvent<OrderVisitDetai
         var name = "回填Order回访字段";
         if (visit.VisitTarget == EVisitTarget.Org && visit.OrgProcessingResults != null)
         {
-            if (visit.OrgProcessingResults.Value == "不满意") return;
-
             var orderId = _orderVisitRepository.Queryable()
-                .Where(m => m.Id == visit.VisitId)
-                .Select(m => new { m.OrderId, m.No })
-                .First();
+               .Where(m => m.Id == visit.VisitId)
+               .Select(m => new { m.OrderId, m.No, m.VisitState })
+               .First();
+
+            if (visit.OrgProcessingResults.Value == "不满意" && orderId.VisitState!= EVisitState.Visited) return;
+           
             _orderRepository.Updateable()
                 .SetColumns(m => m.OrgProcessingResults == visit.OrgProcessingResults)
                 .Where(m => m.Id == orderId.OrderId && m.Status == EOrderStatus.Visited)
@@ -60,11 +61,13 @@ public class OrderVisitDetailEventHandler : IUpdateDatabaseEvent<OrderVisitDetai
 
         if (visit.VisitTarget == EVisitTarget.Seat && visit.SeatEvaluate != null)
         {
-            if (visit.SeatEvaluate == ESeatEvaluate.NoSatisfied || visit.SeatEvaluate == ESeatEvaluate.VeryNoSatisfied) return;
             var orderId = _orderVisitRepository.Queryable()
-                .Where(m => m.Id == visit.VisitId)
-                .Select(m => new { m.OrderId, m.No })
-                .First();
+               .Where(m => m.Id == visit.VisitId)
+               .Select(m => new { m.OrderId, m.No,m.VisitState })
+               .First();
+
+            if ((visit.SeatEvaluate == ESeatEvaluate.NoSatisfied || visit.SeatEvaluate == ESeatEvaluate.VeryNoSatisfied) && orderId.VisitState!= EVisitState.Visited) return;
+           
             _orderRepository.Updateable()
                 .SetColumns(m => m.SeatEvaluate == visit.SeatEvaluate)
                 .Where(m => m.Id == orderId.OrderId && m.Status == EOrderStatus.Visited)

+ 53 - 50
src/Hotline/Orders/OrderDomainService.cs

@@ -70,9 +70,9 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
     private readonly IRepository<WorkflowStep> _workflowStepRepository;
     private readonly ISystemLogRepository _systemLogRepository;
     private readonly IOrderSnapshotRepository _orderSnapshotRepository;
-	private readonly ICalcExpireTime _expireTime;
+    private readonly ICalcExpireTime _expireTime;
 
-	public OrderDomainService(
+    public OrderDomainService(
         IOrderRepository orderRepository,
         IRepository<OrderRedo> orderRedoRepository,
         IRepository<OrderPublish> orderPublishRepository,
@@ -98,7 +98,7 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         ISystemLogRepository systemLogRepository,
         IOptionsSnapshot<AppConfiguration> appOptions,
         IOrderSnapshotRepository orderSnapshotRepository,
-		ICalcExpireTime expireTime)
+        ICalcExpireTime expireTime)
     {
         _orderRepository = orderRepository;
         _orderRedoRepository = orderRedoRepository;
@@ -124,9 +124,9 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         _systemLogRepository = systemLogRepository;
         _appOptions = appOptions;
         _orderSnapshotRepository = orderSnapshotRepository;
-		_expireTime = expireTime;
+        _expireTime = expireTime;
 
-	}
+    }
 
     /// <summary>
     /// 归档后自动发布
@@ -603,33 +603,33 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
             .Where(x => x.SchedulingTime == time).CountAsync(cancellationToken);
         if (schedulings > 0)
         {
-			var sendNum = steps.Count / schedulings;
-			scheduling.SendOrderNum += sendNum;
-			if (!scheduling.LoginSendOrderNum.HasValue)
-			{
-				scheduling.LoginSendOrderNum = scheduling.LoginSendOrderNum.HasValue && scheduling.LoginSendOrderNum > sendNum ? scheduling.LoginSendOrderNum : sendNum;
-				await _schedulingRepository.Updateable()
-					.SetColumns(s => new Scheduling() { LoginSendOrderNum = scheduling.LoginSendOrderNum })
-					.Where(s => s.SchedulingTime == scheduling.SchedulingTime).ExecuteCommandAsync(cancellationToken);
-			}
-			sendNum = scheduling.LoginSendOrderNum.Value;
-			await _schedulingRepository.Updateable()
-				.SetColumns(s => new Scheduling() { SendOrderNum = scheduling.SendOrderNum, AtWork = scheduling.AtWork })
-				.Where(s => s.Id == scheduling.Id).ExecuteCommandAsync(cancellationToken);
-
-			if (sendNum <= 0) return;
-			var sendSteps = steps.Take(sendNum).ToList();
-			await _orderRepository.Updateable().SetColumns(o => new Order()
-			{
-				CenterToOrgHandlerId = user.OrgId,
-				CenterToOrgHandlerName = user.Name
-			}).Where(o => sendSteps.Any(s => s.ExternalId == o.Id)).ExecuteCommandAsync(cancellationToken);
-
-			await _workflowDomainService.ChangeHandlerBatchAsync(new List<(string userId, string username, string orgId, string orgName, string? roleId, string? roleName, ICollection<WorkflowStep> steps)>
-			{
-				new(user.Id, user.Name, user.OrgId, user.Organization.Name,roleId,"派单员", sendSteps)
-			}, cancellationToken);
-		}
+            var sendNum = steps.Count / schedulings;
+            scheduling.SendOrderNum += sendNum;
+            if (!scheduling.LoginSendOrderNum.HasValue)
+            {
+                scheduling.LoginSendOrderNum = scheduling.LoginSendOrderNum.HasValue && scheduling.LoginSendOrderNum > sendNum ? scheduling.LoginSendOrderNum : sendNum;
+                await _schedulingRepository.Updateable()
+                    .SetColumns(s => new Scheduling() { LoginSendOrderNum = scheduling.LoginSendOrderNum })
+                    .Where(s => s.SchedulingTime == scheduling.SchedulingTime).ExecuteCommandAsync(cancellationToken);
+            }
+            sendNum = scheduling.LoginSendOrderNum.Value;
+            await _schedulingRepository.Updateable()
+                .SetColumns(s => new Scheduling() { SendOrderNum = scheduling.SendOrderNum, AtWork = scheduling.AtWork })
+                .Where(s => s.Id == scheduling.Id).ExecuteCommandAsync(cancellationToken);
+
+            if (sendNum <= 0) return;
+            var sendSteps = steps.Take(sendNum).ToList();
+            await _orderRepository.Updateable().SetColumns(o => new Order()
+            {
+                CenterToOrgHandlerId = user.OrgId,
+                CenterToOrgHandlerName = user.Name
+            }).Where(o => sendSteps.Any(s => s.ExternalId == o.Id)).ExecuteCommandAsync(cancellationToken);
+
+            await _workflowDomainService.ChangeHandlerBatchAsync(new List<(string userId, string username, string orgId, string orgName, string? roleId, string? roleName, ICollection<WorkflowStep> steps)>
+            {
+                new(user.Id, user.Name, user.OrgId, user.Organization.Name,roleId,"派单员", sendSteps)
+            }, cancellationToken);
+        }
 
     }
 
@@ -702,7 +702,7 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
     {
         var valid = new OrderValidation { Validation = false, Result = "" };
         var hotspot = await _hotspotRepository.GetAsync(dto.HotspotId, cancellationToken);
-        if (hotspot.TrunkNum.Equals(AppDefaults.TrafficTrunkNum))
+        if (hotspot != null && hotspot.TrunkNum.Equals(AppDefaults.TrafficTrunkNum))
         {
             switch (dto.AcceptTypeCode)
             {
@@ -771,7 +771,7 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         return valid;
     }
     #endregion
-    
+
     #region 即将超期和超期短信
 
     /// <summary>
@@ -830,35 +830,38 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
 
     #region  计算甄别申请截至日期
 
-    public async Task<DateTime>  GetScreenByEndTime() {
+    public async Task<DateTime> GetScreenByEndTime()
+    {
 
         var endTime = DateTime.Now;
         var beginTime = DateTime.Now;
         var timeValue = 1;
-		if (_appOptions.Value.IsZiGong)
+        if (_appOptions.Value.IsZiGong)
         {
             timeValue = 2;
-		}
+        }
         else if (_appOptions.Value.IsLuZhou)
         {
-			DateTime firstDayOfMonth = new DateTime(beginTime.Year, beginTime.Month, 1);
-			DateTime lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);
+            DateTime firstDayOfMonth = new DateTime(beginTime.Year, beginTime.Month, 1);
+            DateTime lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);
             beginTime = new DateTime(lastDayOfMonth.Year, lastDayOfMonth.Month, lastDayOfMonth.Day, 23, 59, 59);
-		}
-        else {
-			var setting = _systemSettingCacheManager.GetSetting(SettingConstants.ScreenApplyEndTime);
-            if (int.Parse(setting?.SettingValue[0]) > 0) {
+        }
+        else
+        {
+            var setting = _systemSettingCacheManager.GetSetting(SettingConstants.ScreenApplyEndTime);
+            if (int.Parse(setting?.SettingValue[0]) > 0)
+            {
                 timeValue = int.Parse(setting?.SettingValue[0]);
-			}
-		}
-		endTime = (await _expireTime.CalcEndTime(beginTime, beginTime, ETimeType.WorkDay, timeValue, 0, 0)).EndTime;
-		return endTime;
+            }
+        }
+        endTime = (await _expireTime.CalcEndTime(beginTime, beginTime, ETimeType.WorkDay, timeValue, 0, 0)).EndTime;
+        return endTime;
     }
-	#endregion
+    #endregion
 
-	#region private
+    #region private
 
-	private async Task<Order> GetOrderByFlowIdAsync(string workflowId, CancellationToken cancellationToken)
+    private async Task<Order> GetOrderByFlowIdAsync(string workflowId, CancellationToken cancellationToken)
     {
         if (string.IsNullOrEmpty(workflowId))
             throw UserFriendlyException.SameMessage("无效流程编号");

+ 16 - 9
src/Hotline/Orders/OrderVisitDetail.cs

@@ -8,10 +8,10 @@ using XF.Utility.EnumExtensions;
 
 namespace Hotline.Orders
 {
-	[SugarIndex("index_visitDetail_creationtime", nameof(OrderVisitDetail.CreationTime), OrderByType.Desc)]
-	[SugarIndex("index_visitDetail_visitId", nameof(OrderVisitDetail.VisitId), OrderByType.Desc)]
-	[SugarIndex("index_visitDetail_visitOrgCode", nameof(OrderVisitDetail.VisitOrgCode), OrderByType.Desc)]
-	public class OrderVisitDetail : CreationEntity
+    [SugarIndex("index_visitDetail_creationtime", nameof(OrderVisitDetail.CreationTime), OrderByType.Desc)]
+    [SugarIndex("index_visitDetail_visitId", nameof(OrderVisitDetail.VisitId), OrderByType.Desc)]
+    [SugarIndex("index_visitDetail_visitOrgCode", nameof(OrderVisitDetail.VisitOrgCode), OrderByType.Desc)]
+    public class OrderVisitDetail : CreationEntity
     {
 
         /// <summary>
@@ -99,9 +99,16 @@ namespace Hotline.Orders
         /// </summary>
         public EVisitTarget VisitTarget { get; set; }
 
-		/// <summary>
-		/// 截至甄别时间
-		/// </summary>
-		public DateTime? ScreenByEndTime { get; set; }
-	}
+        /// <summary>
+        /// 截至甄别时间
+        /// </summary>
+        public DateTime? ScreenByEndTime { get; set; }
+
+        ///// <summary>
+        ///// 查询数据用
+        ///// </summary>
+        //[SugarColumn(IsIgnore = true)]
+        //public bool? IsShowOperate { get; set; }
+
+    }
 }

+ 10 - 0
src/Hotline/Settings/SettingConstants.cs

@@ -190,6 +190,11 @@ namespace Hotline.Settings
         /// </summary>
         public const string RoleLingDao = "RoleLingDao";
 
+        /// <summary>
+        /// 中心领导
+        /// </summary>
+        public const string RoleCenterLeader = "RoleCenterLeader";
+
         /// <summary>
         /// 是否开启登录短信
         /// </summary>
@@ -728,5 +733,10 @@ namespace Hotline.Settings
         /// 是否不推送呼出的无文件的通话记录
         /// </summary>
         public const string IsNoPushCallNativeOutNoFile = "IsNoPushCallNativeOutNoFile";
+
+        /// <summary>
+        /// 是否开启特殊号码功能
+        /// </summary>
+        public const string IsOpenSpecialPhone = "IsOpenSpecialPhone";
     }
 }

+ 22 - 0
src/Hotline/Special/SpecialNumber.cs

@@ -0,0 +1,22 @@
+using SqlSugar;
+using System.ComponentModel;
+using XF.Domain.Repository;
+
+namespace Hotline.Special
+{
+    [Description("特殊号码管理")]
+    public class SpecialNumber : CreationEntity
+    {
+        /// <summary>
+        /// 电话号码
+        /// </summary>
+        [SugarColumn(ColumnDescription = "电话号码")]
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        [SugarColumn(ColumnDescription = "备注")]
+        public string? Notes { get; set; }
+    }
+}

+ 82 - 19
src/XF.Domain/Authentications/DefaultSessionContext.cs

@@ -10,19 +10,24 @@ namespace XF.Domain.Authentications
 {
     public class DefaultSessionContext : ISessionContext, IScopeDependency
     {
-        private readonly IChangeSessionProvider _changeSessionProvider;
         private readonly IHttpContextAccessor _contextAccessor;
+        private readonly ISessionContextProvider _sessionContextProvider;
+
         public DefaultSessionContext(IHttpContextAccessor httpContextAccessor, IServiceProvider serviceProvider)
         {
-            _changeSessionProvider = serviceProvider.GetService<IChangeSessionProvider>();
             _contextAccessor = httpContextAccessor;
-
+            _sessionContextProvider = serviceProvider.GetService<ISessionContextProvider>();
+            _contextAccessor.HttpContext ??= new DefaultHttpContext();
         }
 
         /// <summary>
         /// Id of current tenant or null for host
         /// </summary>
-        public string? UserId { get => _contextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier); init { } }
+        public string? UserId
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier);
+            init { }
+        }
 
         /// <summary>
         /// Id of current user or throw Exception for guest
@@ -30,9 +35,17 @@ namespace XF.Domain.Authentications
         /// <exception cref="AuthenticationException"></exception>
         public string RequiredUserId => UserId ?? throw new ArgumentNullException();
 
-        public string? UserName { get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.UserDisplayName); init { } }
+        public string? UserName
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.UserDisplayName);
+            init { }
+        }
 
-        public string? Phone { get => _contextAccessor.HttpContext?.User.FindFirstValue(JwtClaimTypes.PhoneNumber); init { } }
+        public string? Phone
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(JwtClaimTypes.PhoneNumber);
+            init { }
+        }
 
         /// <summary>
         /// Roles
@@ -40,41 +53,91 @@ namespace XF.Domain.Authentications
         /// 在 JwtBearerHandler 处理 JWT 令牌时,它会使用 Microsoft.AspNetCore.Authentication.JwtBearer 自动转换 Claim 名称。
         /// </summary>
         // public string[] Roles { get => _contextAccessor.HttpContext?.User.Claims.Where(d => d.Type == JwtClaimTypes.Role).Select(d => d.Value).ToArray(); init { } }
-        public string[] Roles { get => _contextAccessor.HttpContext?.User.Claims.Where(d => d.Type == ClaimTypes.Role).Select(d => d.Value).ToArray(); init { } }
+        public string[] Roles
+        {
+            get => _contextAccessor.HttpContext?.User.Claims.Where(d => d.Type == ClaimTypes.Role).Select(d => d.Value).ToArray();
+            init { }
+        }
 
-        public string? OrgId { get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.DepartmentId); init { } }
-        public string? OrgName { get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.DepartmentName); init { } }
+        public string? OrgId
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.DepartmentId);
+            init { }
+        }
 
-        public int OrgLevel { get => _contextAccessor.HttpContext?.User.FindIntValue(AppClaimTypes.DepartmentLevel) ?? 0; init { } }
-        public string? OrgAreaCode { get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.DepartmentAreaCode); init { } }
-        public bool OrgIsCenter { get => _contextAccessor.HttpContext?.User.FindBoolValue(AppClaimTypes.DepartmentIsCenter)??false; init { } }
+        public string? OrgName
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.DepartmentName);
+            init { }
+        }
+
+        public int OrgLevel
+        {
+            get => _contextAccessor.HttpContext?.User.FindIntValue(AppClaimTypes.DepartmentLevel) ?? 0;
+            init { }
+        }
+
+        public string? OrgAreaCode
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.DepartmentAreaCode);
+            init { }
+        }
+
+        public bool OrgIsCenter
+        {
+            get => _contextAccessor.HttpContext?.User.FindBoolValue(AppClaimTypes.DepartmentIsCenter) ?? false;
+            init { }
+        }
 
         /// <summary>
         /// 部门行政区划名称
         /// </summary>
-        public string? OrgAreaName { get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.DepartmentAreaName); init { } }
+        public string? OrgAreaName
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.DepartmentAreaName);
+            init { }
+        }
 
-        public string? AreaId { get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.AreaId); init { } }
+        public string? AreaId
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.AreaId);
+            init { }
+        }
 
         public string RequiredOrgId => OrgId ?? throw new ArgumentNullException();
-        
-        public string? ClientId { get => _contextAccessor.HttpContext?.User.FindFirstValue(JwtClaimTypes.ClientId); init { } }
+
+        public string? ClientId
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(JwtClaimTypes.ClientId);
+            init { }
+        }
 
         /// <summary>
         /// 工号
         /// </summary>
-        public string? StaffNo { get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.StaffNo); init { } }
+        public string? StaffNo
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.StaffNo);
+            init { }
+        }
 
         /// <summary>
         /// 第三方平台用户唯一标识
         /// 例如: 微信的OpenId
         /// </summary>
-        public string? OpenId { get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.OpenId); init { } }
+        public string? OpenId
+        {
+            get => _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.OpenId);
+            init { }
+        }
 
         public void ChangeSession(string id)
         {
-            _contextAccessor.HttpContext = _changeSessionProvider.ChangeSessionByUserId(id, _contextAccessor.HttpContext);
+            _contextAccessor.HttpContext = _sessionContextProvider.ChangeSessionByUserId(id, _contextAccessor.HttpContext);
         }
+
+        public async Task ChangeSessionAsync(string userId, CancellationToken cancellation) =>
+            await _sessionContextProvider.ChangeSessionByUserIdAsync(userId, cancellation);
     }
 
     public static class ClaimsPrincipalExtensions

+ 0 - 12
src/XF.Domain/Authentications/IChangeSessionProvider.cs

@@ -1,12 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace XF.Domain.Authentications;
-public interface IChangeSessionProvider
-{
-    HttpContext ChangeSessionByUserId(string id, HttpContext httpContext);
-}

+ 3 - 0
src/XF.Domain/Authentications/ISessionContext.cs

@@ -53,4 +53,7 @@ public interface ISessionContext
     string? OpenId { get; init; }
 
     void ChangeSession(string id);
+
+    // Task ChangeSessionAsync(string userId, CancellationToken cancellation);
+
 }

+ 8 - 4
src/XF.Domain/Authentications/ISessionContextProvider.cs

@@ -1,4 +1,5 @@
-using System;
+using Microsoft.AspNetCore.Http;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -8,10 +9,13 @@ namespace XF.Domain.Authentications
 {
     public interface ISessionContextProvider
     {
-        public ISessionContext SessionContext { get; set; }
+        //public ISessionContext SessionContext { get; set; }
 
-        public void SetContext(string key);
+        //public void SetContext(string key);
 
-        public void SetContext(ISessionContext sessionContext);
+        HttpContext ChangeSessionByUserId(string id, HttpContext httpContext);
+
+        Task ChangeSessionByUserIdAsync(string userId, CancellationToken cancellation);
+        void ChangeSession(string userId, string username, string orgId, string orgname, int orgLevel);
     }
 }

+ 12 - 2
test/Hotline.Tests/Controller/TestSessionContext.cs

@@ -11,11 +11,11 @@ namespace Hotline.Tests.Controller;
 public class TestSessionContext : ISessionContext, IScopeDependency
 {
     private readonly IHttpContextAccessor _contextAccessor;
-    private readonly IChangeSessionProvider _changeSessionProvider;
+    private readonly ISessionContextProvider _changeSessionProvider;
     public TestSessionContext(IHttpContextAccessor httpContextAccessor, IServiceProvider serviceProvider)
     {
         _contextAccessor = httpContextAccessor;
-        _changeSessionProvider = serviceProvider.GetService<IChangeSessionProvider>();
+        _changeSessionProvider = serviceProvider.GetService<ISessionContextProvider>();
         //if (httpContextAccessor.HttpContext == null) _contextAccessor.HttpContext = new DefaultHttpContext();
     }
 
@@ -24,6 +24,16 @@ public class TestSessionContext : ISessionContext, IScopeDependency
         _contextAccessor.HttpContext = _changeSessionProvider.ChangeSessionByUserId(id, _contextAccessor.HttpContext);
     }
 
+    public async Task ChangeSessionAsync(string userId, CancellationToken cancellation)
+    {
+        throw new NotImplementedException();
+    }
+
+    public void ChangeSession(string userId, string username, string orgId, string orgname, int orgLevel)
+    {
+        throw new NotImplementedException();
+    }
+
     public string? OpenId { get { return _contextAccessor.HttpContext?.User.FindFirstValue(AppClaimTypes.OpenId); } init { } }
 
     /// <summary>

+ 0 - 5
test/Hotline.Tests/Startup.cs

@@ -11,7 +11,6 @@ using Hotline.Application.Jobs;
 using Hotline.Application.StatisticalReport.CallReport;
 using Hotline.Authentications;
 using Hotline.CallCenter.Configs;
-using Hotline.CallCenter.Tels;
 using Hotline.Configurations;
 using Hotline.DI;
 using Hotline.EventBus;
@@ -19,7 +18,6 @@ using Hotline.File;
 using Hotline.FlowEngine.Workflows;
 using Hotline.Orders;
 using Hotline.Orders.DatabaseEventHandler;
-using Hotline.Pdf;
 using Hotline.Repository.SqlSugar;
 using Hotline.Repository.SqlSugar.DataPermissions;
 using Hotline.Repository.SqlSugar.Extensions;
@@ -35,7 +33,6 @@ using Mapster;
 using MediatR;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
@@ -183,8 +180,6 @@ public class Startup
             services.AddXingTangDb(callCenterConfiguration.XingTang);
             services.AddScoped<IGuiderSystemService, TiqnQueService>();
             services.AddScoped<IWorkflowDomainService, WorkflowDomainService>();
-            services.AddScoped<IPdfManager, QuestPdfManager>();
-            services.AddScoped<ICallTelClient, XingTang.CallTelClient>();
 
             //ServiceLocator.Instance = services.BuildServiceProvider();
         }