Selaa lähdekoodia

合并 release

qinchaoyue 4 kuukautta sitten
vanhempi
commit
b63a476dbe
75 muutettua tiedostoa jossa 1474 lisäystä ja 715 poistoa
  1. 8 8
      src/Hotline.Api/Controllers/Bi/BiOrderController.cs
  2. 8 2
      src/Hotline.Api/Controllers/ExportWordController.cs
  3. 1 0
      src/Hotline.Api/Controllers/HomeController.cs
  4. 45 21
      src/Hotline.Api/Controllers/JudicialManagementOrdersController.cs
  5. 12 3
      src/Hotline.Api/Controllers/KnowledgeCommonController.cs
  6. 69 64
      src/Hotline.Api/Controllers/KnowledgeController.cs
  7. 291 198
      src/Hotline.Api/Controllers/OrderController.cs
  8. 1 1
      src/Hotline.Api/Controllers/OrderTerminateController.cs
  9. 229 3
      src/Hotline.Api/Controllers/TestController.cs
  10. 91 1
      src/Hotline.Api/Controllers/WebPortalController.cs
  11. 18 11
      src/Hotline.Api/Controllers/WorkflowController.cs
  12. 3 3
      src/Hotline.Api/Filter/LogFilterAttribute.cs
  13. 3 3
      src/Hotline.Application/CallCenter/DefaultCallApplication.cs
  14. 5 5
      src/Hotline.Application/FlowEngine/IWorkflowApplication.cs
  15. 182 197
      src/Hotline.Application/FlowEngine/WorkflowApplication.cs
  16. 2 2
      src/Hotline.Application/Knowledge/KnowApplication.cs
  17. 4 1
      src/Hotline.Application/Orders/IOrderApplication.cs
  18. 87 1
      src/Hotline.Application/Orders/OrderApplication.cs
  19. 1 0
      src/Hotline.Application/Orders/OrderScreenHandler/OrderScreenEndWorkflowHandler.cs
  20. 4 2
      src/Hotline.Application/Orders/OrderSecondaryHandlingApplication.cs
  21. 5 5
      src/Hotline.Application/Subscribers/DatasharingSubscriber.cs
  22. 8 1
      src/Hotline.Application/Subscribers/InternalCapSubscriber.cs
  23. 17 18
      src/Hotline.Repository.SqlSugar/CallCenter/CallNativeRepository.cs
  24. 50 35
      src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs
  25. 50 0
      src/Hotline.Share/Dtos/JudicialManagement/JudicialManagementAddOrderDto.cs
  26. 9 4
      src/Hotline.Share/Dtos/Knowledge/KnowledgeDto.cs
  27. 8 1
      src/Hotline.Share/Dtos/Knowledge/KnowledgeTypeDto.cs
  28. 9 4
      src/Hotline.Share/Dtos/Order/OrderBiDto.cs
  29. 9 0
      src/Hotline.Share/Dtos/Order/OrderSpecialDto.cs
  30. 4 0
      src/Hotline.Share/Dtos/Order/Publish/QueryOrderPublishDto.cs
  31. 39 2
      src/Hotline.Share/Dtos/WebPortal/GetOrderCodePwd.cs
  32. 7 1
      src/Hotline.Share/Enums/KnowledgeBase/EKnowledgeStatus.cs
  33. 10 0
      src/Hotline.Share/Requests/PagedKeywordRequest.cs
  34. 1 1
      src/Hotline/Ai/CallOut/CallOutTemplate.cs
  35. 5 0
      src/Hotline/Article/Bulletin.cs
  36. 5 0
      src/Hotline/FlowEngine/Workflows/IWorkflowDomainService.cs
  37. 11 6
      src/Hotline/FlowEngine/Workflows/WorkflowCountersign.cs
  38. 3 1
      src/Hotline/FlowEngine/Workflows/WorkflowCountersignMember.cs
  39. 54 38
      src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs
  40. 3 8
      src/Hotline/FlowEngine/Workflows/WorkflowStep.cs
  41. 1 1
      src/Hotline/FlowEngine/Workflows/WorkflowSupplement.cs
  42. 2 5
      src/Hotline/FlowEngine/Workflows/WorkflowTrace.cs
  43. 6 0
      src/Hotline/KnowledgeBase/Knowledge.cs
  44. 1 1
      src/Hotline/KnowledgeBase/KnowledgeComment.cs
  45. 2 2
      src/Hotline/KnowledgeBase/KnowledgeCorrection.cs
  46. 2 2
      src/Hotline/KnowledgeBase/KnowledgeQuestions.cs
  47. 0 7
      src/Hotline/KnowledgeBase/KnowledgeType.cs
  48. 2 2
      src/Hotline/KnowledgeBase/KnowledgeWord.cs
  49. 1 1
      src/Hotline/KnowledgeBase/KnowledgeWorkFlow.cs
  50. 1 1
      src/Hotline/Orders/Citizen.cs
  51. 1 1
      src/Hotline/Orders/IOrderRepository.cs
  52. 13 0
      src/Hotline/Orders/OldSendProData.cs
  53. 3 4
      src/Hotline/Orders/Order.cs
  54. 1 1
      src/Hotline/Orders/OrderComplement.cs
  55. 4 2
      src/Hotline/Orders/OrderCopy.cs
  56. 7 6
      src/Hotline/Orders/OrderDelay.cs
  57. 4 0
      src/Hotline/Orders/OrderDomainService.cs
  58. 2 2
      src/Hotline/Orders/OrderScreen.cs
  59. 3 3
      src/Hotline/Orders/OrderSecondaryHandling.cs
  60. 2 2
      src/Hotline/Orders/OrderSendBackAudit.cs
  61. 3 3
      src/Hotline/Orders/OrderSendback.cs
  62. 2 2
      src/Hotline/Orders/OrderSpecial.cs
  63. 2 2
      src/Hotline/Orders/OrderSupervise.cs
  64. 1 1
      src/Hotline/Orders/OrderTerminate.cs
  65. 2 2
      src/Hotline/Orders/OrderUrge.cs
  66. 2 1
      src/Hotline/Orders/OrderVisitDetail.cs
  67. 2 2
      src/Hotline/Orders/OrderWord.cs
  68. 1 1
      src/Hotline/Orders/RepeatableEvent.cs
  69. 1 1
      src/Hotline/Quality/Quality.cs
  70. 1 1
      src/Hotline/Quality/QualityDetail.cs
  71. 1 1
      src/Hotline/Quality/QualityItem.cs
  72. 15 0
      src/Hotline/Settings/SettingConstants.cs
  73. 3 2
      src/Hotline/Settings/SystemLog.cs
  74. 8 1
      src/Hotline/WebPortal/WebFlowAccept.cs
  75. 1 1
      src/XF.Domain.Repository/XF.Domain.Repository.csproj

+ 8 - 8
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -1269,14 +1269,14 @@ namespace Hotline.Api.Controllers.Bi
             var citySumModel = new VisitAndOrgSatisfactionStatisticsDto()
             {
                 OrgName = "市直合计",
-                TotalSumCount = data.Where(x => x.OrgType == EOrgType.City).Sum(x => x.TotalSumCount),
-                VerySatisfiedCount = data.Where(x => x.OrgType == EOrgType.City).Sum(x => x.VerySatisfiedCount),
-                SatisfiedCount = data.Where(x => x.OrgType == EOrgType.City).Sum(x => x.SatisfiedCount),
-                RegardedAsSatisfiedCount = data.Where(x => x.OrgType == EOrgType.City).Sum(x => x.RegardedAsSatisfiedCount),
-                DefaultSatisfiedCount = data.Where(x => x.OrgType == EOrgType.City).Sum(x => x.DefaultSatisfiedCount),
-                NoSatisfiedCount = data.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoSatisfiedCount),
-                NoEvaluateCount = data.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoEvaluateCount),
-                NoPutThroughCount = data.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoPutThroughCount),
+                TotalSumCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode!="001").Sum(x => x.TotalSumCount),
+                VerySatisfiedCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.VerySatisfiedCount),
+                SatisfiedCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.SatisfiedCount),
+                RegardedAsSatisfiedCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.RegardedAsSatisfiedCount),
+                DefaultSatisfiedCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.DefaultSatisfiedCount),
+                NoSatisfiedCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.NoSatisfiedCount),
+                NoEvaluateCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.NoEvaluateCount),
+                NoPutThroughCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode!="001").Sum(x => x.NoPutThroughCount),
             };
 
             var sumModel = new VisitAndOrgSatisfactionStatisticsDto()

+ 8 - 2
src/Hotline.Api/Controllers/ExportWordController.cs

@@ -1,6 +1,8 @@
 using Hotline.Application.ExportWord;
+using Hotline.Caching.Interfaces;
 using Hotline.Configurations;
 using Hotline.Orders;
+using Hotline.Settings;
 using Hotline.Share.Dtos.OrderExportWord;
 using Hotline.Share.Enums.Order;
 using MapsterMapper;
@@ -19,6 +21,7 @@ namespace Hotline.Api.Controllers
         private readonly IRepository<OrderVisitDetail> _orderVisitedDetailRepository;
         private readonly ILogger<ExportWordController> _logger;
         private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
+        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
 
         public ExportWordController(IOrderRepository orderRepository,
             IWordHelperService wordHelperService,
@@ -26,7 +29,8 @@ namespace Hotline.Api.Controllers
            IRepository<OrderVisit> orderVisitRepository,
            IRepository<OrderVisitDetail> orderVisitedDetailRepository,
            ILogger<ExportWordController> logger,
-            IOptionsSnapshot<AppConfiguration> appOptions)
+            IOptionsSnapshot<AppConfiguration> appOptions,
+            ISystemSettingCacheManager systemSettingCacheManager)
         {
             _orderRepository = orderRepository;
             _wordHelperService = wordHelperService;
@@ -35,6 +39,7 @@ namespace Hotline.Api.Controllers
             _orderVisitedDetailRepository = orderVisitedDetailRepository;
             _logger = logger;
             _appOptions = appOptions;
+            _systemSettingCacheManager = systemSettingCacheManager;
         }
 
         /// <summary>
@@ -47,6 +52,7 @@ namespace Hotline.Api.Controllers
             var streams = new Dictionary<string, Stream>();
             var path = $"{Directory.GetCurrentDirectory()}/Template/AssignmentForm.doc";
             int num = 1;
+            var isTheAssignmentFormConfidential = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsTheAssignmentFormConfidential).SettingValue[0]);
             foreach (var item in Ids)
             {
                 var order = await _orderRepository.GetAsync(item, HttpContext.RequestAborted);
@@ -54,7 +60,7 @@ namespace Hotline.Api.Controllers
                     continue;
 
                 //处理保密数据
-                if (_appOptions.Value.IsZiGong && order.IsSecret)
+                if (isTheAssignmentFormConfidential && order.IsSecret)
                 {
                     var maskString = "***";
                     order.Contact = maskString;

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

@@ -192,6 +192,7 @@ public class HomeController : BaseController
             FileExt = _systemSettingCacheManager.GetSetting(SettingConstants.FileExt).SettingValue[0],
             NationalPlatformWordLimit = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.NationalPlatformWordLimit).SettingValue[0]),
             HandleOpinionWordLimit= int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.HandleOpinionWordLimit).SettingValue[0]),
+            CallInOpenType = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.CallInOpenType).SettingValue[0]),
         };
         return rsp;
     }

+ 45 - 21
src/Hotline.Api/Controllers/JudicialManagementOrdersController.cs

@@ -3,6 +3,7 @@ using Hotline.Application.JudicialManagement;
 using Hotline.Caching.Interfaces;
 using Hotline.File;
 using Hotline.JudicialManagement;
+using Hotline.Orders;
 using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Settings;
 using Hotline.Settings.TimeLimits;
@@ -35,6 +36,7 @@ namespace Hotline.Api.Controllers
         private readonly IJudicialManagementOrdersService _judicialManagementOrdersService;
         private readonly IRepository<EnforcementOrdersHandler> _enforcementOrdersHandlerRepository;
         private readonly IEnforcementApplication _enforcementApplication;
+        private readonly IRepository<Order> _orderRepository;
 
         /// <summary>
         /// 
@@ -51,6 +53,7 @@ namespace Hotline.Api.Controllers
         /// <param name="judicialManagementOrdersService"></param>
         /// <param name="enforcementOrdersHandlerRepository"></param>
         /// <param name="enforcementApplication"></param>
+        /// <param name="orderRepository"></param>
         public JudicialManagementOrdersController(
          IRepository<JudicialComplaintsEventType> judicialComplaintsEventTypeRepository,
          IRepository<EnforcementHotspot> enforcementHotspotRepository,
@@ -63,7 +66,8 @@ namespace Hotline.Api.Controllers
           IFileRepository fileRepository,
           IJudicialManagementOrdersService judicialManagementOrdersService,
            IRepository<EnforcementOrdersHandler> enforcementOrdersHandlerRepository,
-           IEnforcementApplication enforcementApplication
+           IEnforcementApplication enforcementApplication,
+            IRepository<Order> orderRepository
          )
         {
             _judicialComplaintsEventTypeRepository = judicialComplaintsEventTypeRepository;
@@ -78,6 +82,7 @@ namespace Hotline.Api.Controllers
             _judicialManagementOrdersService = judicialManagementOrdersService;
             _enforcementOrdersHandlerRepository = enforcementOrdersHandlerRepository;
             _enforcementApplication = enforcementApplication;
+            _orderRepository = orderRepository;
         }
 
         /// <summary>
@@ -134,8 +139,8 @@ namespace Hotline.Api.Controllers
             if (dto.Files.Any())
                 order.FileJson = await _fileRepository.AddFileAsync(dto.Files, order.Id, "", HttpContext.RequestAborted);
             else
-	            order.FileJson = new List<Share.Dtos.File.FileJson>();
-			await _judicialManagementOrdersRepository.UpdateAsync(order, HttpContext.RequestAborted);
+                order.FileJson = new List<Share.Dtos.File.FileJson>();
+            await _judicialManagementOrdersRepository.UpdateAsync(order, HttpContext.RequestAborted);
 
             //处理执法部门
             if (dto.EnforcementOrdersHandler != null && dto.EnforcementOrdersHandler.Any())
@@ -193,6 +198,25 @@ namespace Hotline.Api.Controllers
                 return new();
             var dto = _mapper.Map<JudicialManagementOrderDto>(order);
 
+            //如果是12345创建的工单,查询办理信息
+            if (dto.OrderSoure == EOrderSoure.Hotline)
+            {
+                var data = await _orderRepository.GetAsync(p => p.No == order.No, HttpContext.RequestAborted);
+                if (data != null)
+                {
+                    dto.CenterToOrgTime = data.CenterToOrgTime;
+                    dto.ActualHandleOrgName = data.ActualHandleOrgName;
+                    dto.ActualHandleTime = data.ActualHandleTime;
+                    dto.TimeLimit = data.TimeLimit;
+                    dto.TimeLimitUnit = data.TimeLimitUnit;
+                    dto.TimeLimitCount = data.TimeLimitCount;
+                    dto.ExpiredTime = data.ExpiredTime;
+                    dto.IsResolved = data.IsResolved;
+                    dto.FileOpinion = data.FileOpinion;
+                    dto.CenterOpinion = data.CenterToOrgOpinion;
+                }
+            }
+
             if (dto.FileJson != null && dto.FileJson.Any())
             {
                 var ids = order.FileJson.Select(x => x.Id).ToList();
@@ -481,22 +505,22 @@ namespace Hotline.Api.Controllers
             else
                 areCodeText = AreaCode;
 
-             var items = await _judicialComplaintsEventTypeRepository.Queryable()
-             .LeftJoin<JudicialManagementOrders>((x, o) => o.EventTypeSpliceName != null &&
-             (x.EventTypeName == o.EventTypeSpliceName || o.EventTypeSpliceName.Contains(x.EventTypeName)))
-            .Where((x, o) => o.CreationTime >= StartTime && o.CreationTime <= EndTime && o.IsItCounted == true)
-            .WhereIF(!string.IsNullOrEmpty(areCodeText), (x, o) => o.AreaCode.StartsWith(areCodeText))
-             .Where((x, o) => x.ParentId == Id)
-             .GroupBy((x, o) => new { x.Id, x.EventTypeName })
-             .Select((x, o) => new
-             {
-                 Id = x.Id,
-                 Name = x.EventTypeName,
-                 Num = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
-                 Sublevel = SqlFunc.AggregateSum(SqlFunc.IIF(x.EventTypeName != o.EventTypeName, 1, 0)) > 0,
-             })
-             .MergeTable()
-             .ToListAsync();
+            var items = await _judicialComplaintsEventTypeRepository.Queryable()
+            .LeftJoin<JudicialManagementOrders>((x, o) => o.EventTypeSpliceName != null &&
+            (x.EventTypeName == o.EventTypeSpliceName || o.EventTypeSpliceName.Contains(x.EventTypeName)))
+           .Where((x, o) => o.CreationTime >= StartTime && o.CreationTime <= EndTime && o.IsItCounted == true)
+           .WhereIF(!string.IsNullOrEmpty(areCodeText), (x, o) => o.AreaCode.StartsWith(areCodeText))
+            .Where((x, o) => x.ParentId == Id)
+            .GroupBy((x, o) => new { x.Id, x.EventTypeName })
+            .Select((x, o) => new
+            {
+                Id = x.Id,
+                Name = x.EventTypeName,
+                Num = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
+                Sublevel = SqlFunc.AggregateSum(SqlFunc.IIF(x.EventTypeName != o.EventTypeName, 1, 0)) > 0,
+            })
+            .MergeTable()
+            .ToListAsync();
 
             var data = await _judicialManagementOrdersRepository.Queryable()
                 .Where(d => d.CreationTime >= StartTime && d.CreationTime <= EndTime)
@@ -675,11 +699,11 @@ namespace Hotline.Api.Controllers
         [HttpPost("regional_classification_statistics_export")]
         public async Task<FileStreamResult> GetRegionalClassificationStatisticsExportAsync([FromBody] ExportExcelDto<QueryRegionalClassificationStatisticsDto> dto)
         {
-            var list= await _enforcementApplication.GetRegionalClassificationStatisticsAsync(dto.QueryDto.StartTime, dto.QueryDto.EndTime).ToListAsync();
+            var list = await _enforcementApplication.GetRegionalClassificationStatisticsAsync(dto.QueryDto.StartTime, dto.QueryDto.EndTime).ToListAsync();
 
             list.Add(new RegionalClassificationStatisticsDto()
             {
-                AreaCode="",
+                AreaCode = "",
                 AreaName = "总计",
                 OrderCountNum = list.Sum(x => x.OrderCountNum),
                 TheClueIsTrue = list.Sum(x => x.TheClueIsTrue),

+ 12 - 3
src/Hotline.Api/Controllers/KnowledgeCommonController.cs

@@ -3,6 +3,7 @@ using Hotline.Permissions;
 using Hotline.Share.Dtos.Knowledge;
 using MapsterMapper;
 using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
 using XF.Domain.Authentications;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
@@ -137,10 +138,18 @@ namespace Hotline.Api.Controllers
         /// <param name="IsEnable">不传查询所有</param>
         /// <returns></returns>
         [HttpGet("treelist")]
-        public async Task<List<KnowledgeType>> GetTreeList(bool? IsEnable)
+        public async Task<List<KnowledgeTypeDto>> GetTreeList(bool? IsEnable)
         {
-            return await _knowledgeTypeRepository.Queryable().WhereIF(IsEnable.HasValue, p => p.IsEnable == IsEnable)
-				 .Where(x => x.KnowledgeTypeOrgs.Any(to => to.OrgId == _sessionContext.RequiredOrgId) || x.KnowledgeTypeOrgs.Any() == false).OrderBy(p => p.Sort).ToTreeAsync(it => it.children, it => it.ParentId, null,it=> it.Id);
+            return await _knowledgeTypeRepository.Queryable().WhereIF(IsEnable.HasValue, x =>x.IsEnable == IsEnable)
+				 //.Where(x => x.KnowledgeTypeOrgs.Any(to => to.OrgId == _sessionContext.RequiredOrgId) || x.KnowledgeTypeOrgs.Any() == false)
+				 .Where(x=> SqlFunc.Subqueryable<KnowledgeTypeOrg>().Where(to=>to.TypeId == x.Id && to.OrgId == _sessionContext.RequiredOrgId).Any())
+				 .Select(x=> new KnowledgeTypeDto()
+				 {
+                     Id = x.Id.SelectAll(),
+                     KnowledgeNum = SqlFunc.Subqueryable<KnowledgeRelationType>().Where(kr=>kr.KnowledgeTypeId == x.Id).DistinctCount(kr=>kr.KnowledgeId)
+
+				 })
+				 .OrderBy(x => x.Sort).ToTreeAsync(it => it.children, it => it.ParentId, null,it=> it.Id);
         }
 
         /// <summary>

+ 69 - 64
src/Hotline.Api/Controllers/KnowledgeController.cs

@@ -67,6 +67,7 @@ namespace Hotline.Api.Controllers
         private readonly IKnowApplication _knowApplication;
         private readonly IMediator _mediator;
         private readonly IWorkflowApplication _workflowApplication;
+        private readonly IWorkflowDomainService _workflowDomainService;
         private readonly IKnowledgeWorkFlowRepository _knowledgeWorkFlowRepository;
         private readonly IRepository<User> _userRepository;
         private readonly IRepository<KnowledgeType> _knowledgeTypeRepository;
@@ -88,7 +89,7 @@ namespace Hotline.Api.Controllers
         private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
 
 
-		public KnowledgeController(
+        public KnowledgeController(
            IKnowledgeRepository knowledgeRepository,
            ISessionContext sessionContext,
            IKnowledgeDomainService knowledgeDomainService,
@@ -96,6 +97,7 @@ namespace Hotline.Api.Controllers
            IKnowApplication knowApplication,
            IMediator mediator,
            IWorkflowApplication workflowApplication,
+           IWorkflowDomainService workflowDomainService,
            IKnowledgeWorkFlowRepository knowledgeWorkFlowRepository,
            IRepository<User> userRepository,
            IRepository<KnowledgeType> knowledgeTypeRepository,
@@ -120,7 +122,7 @@ namespace Hotline.Api.Controllers
             IRepository<KnowledgeWord> knowledgeWordRepository,
             IRepository<KnowledgeHotWord> knowledgeWordHotRepository,
            IOptionsSnapshot<AppConfiguration> appOptions,
-			IRepository<KnowledgeHotWord> knowledgeHotWordRepository)
+            IRepository<KnowledgeHotWord> knowledgeHotWordRepository)
         {
             _knowledgeRepository = knowledgeRepository;
             _sessionContext = sessionContext;
@@ -129,6 +131,7 @@ namespace Hotline.Api.Controllers
             _knowApplication = knowApplication;
             _mediator = mediator;
             _workflowApplication = workflowApplication;
+            _workflowDomainService = workflowDomainService;
             _knowledgeWorkFlowRepository = knowledgeWorkFlowRepository;
             _userRepository = userRepository;
             _knowledgeTypeRepository = knowledgeTypeRepository;
@@ -153,7 +156,7 @@ namespace Hotline.Api.Controllers
             _knowledgeWordRepository = knowledgeWordRepository;
             _knowledgeHotWordRepository = knowledgeHotWordRepository;
             _appOptions = appOptions;
-		}
+        }
 
         #endregion
 
@@ -219,7 +222,7 @@ namespace Hotline.Api.Controllers
             var know = await _knowledgeRepository.GetAsync(dto.Data.Id, HttpContext.RequestAborted);
             if (know != null && know.Status == EKnowledgeStatus.OnShelf)
             {
-                if (_sessionContext.OrgIsCenter ||  !_appOptions.Value.IsYiBin)
+                if (_sessionContext.OrgIsCenter || !_appOptions.Value.IsYiBin)
                 {
                     know.Status = EKnowledgeStatus.OffShelf;
                     know.OnShelfTime = null;
@@ -232,16 +235,17 @@ namespace Hotline.Api.Controllers
                     //推省上
                     await _capPublisher.PublishAsync(EventNames.HotlineKnowledgeRemove, pushKnowledge, cancellationToken: HttpContext.RequestAborted);
                 }
-                else {
-	                know.Status = EKnowledgeStatus.OffShelfAudit;
-	                await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
+                else
+                {
+                    know.Status = EKnowledgeStatus.OffShelfAudit;
+                    await _knowledgeRepository.UpdateAsync(know, HttpContext.RequestAborted);
 
-					var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
-					startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeOffshelf;
+                    var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
+                    startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeOffshelf;
                     startDto.Opinion = dto.Data.Opinion;
-					startDto.Title = "知识库下架";
-					await StartFlow(know.Id, WorkflowModuleConsts.KnowledgeOffshelf, EKnowledgeApplyType.Offshelf, startDto);
-				}
+                    startDto.Title = "知识库下架";
+                    await StartFlow(know.Id, WorkflowModuleConsts.KnowledgeOffshelf, EKnowledgeApplyType.Offshelf, startDto);
+                }
             }
             else
                 throw UserFriendlyException.SameMessage("知识下架失败");
@@ -308,24 +312,24 @@ namespace Hotline.Api.Controllers
             knowledge.HotspotId = dto.Data.HotspotId;
             knowledge.HotspotExternal = dto.Data.HotspotExternal;
 
-			if (dto.Data.Files.Any())
+            if (dto.Data.Files.Any())
                 knowledge.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, knowledge.Id, "", HttpContext.RequestAborted);
             else
                 knowledge.FileJson = new List<Share.Dtos.File.FileJson>();
             if (dto.Workflow != null) knowledge.Renewaln = knowledge.Status != EKnowledgeStatus.Drafts;
             if (_appOptions.Value.IsYiBin)
             {
-				//临时处理 修改后提交修改基本信息
-				if (!_sessionContext.OrgIsCenter)
-				{
-					knowledge.Attribution = "部门知识库";
-				}
-				knowledge.CreatorId = _sessionContext.UserId;
-				knowledge.CreatorName = _sessionContext.UserName;
-				knowledge.CreatorOrgId = _sessionContext.OrgId;
-				knowledge.CreatorOrgName = _sessionContext.OrgName;
-				knowledge.CreatorOrgLevel = _sessionContext.OrgLevel;
-			}
+                //临时处理 修改后提交修改基本信息
+                if (!_sessionContext.OrgIsCenter)
+                {
+                    knowledge.Attribution = "部门知识库";
+                }
+                knowledge.CreatorId = _sessionContext.UserId;
+                knowledge.CreatorName = _sessionContext.UserName;
+                knowledge.CreatorOrgId = _sessionContext.OrgId;
+                knowledge.CreatorOrgName = _sessionContext.OrgName;
+                knowledge.CreatorOrgLevel = _sessionContext.OrgLevel;
+            }
 
             await _knowledgeRepository.UpdateNullAsync(knowledge, HttpContext.RequestAborted);
             if (dto.Data.KnowledgeType.Any())
@@ -403,7 +407,8 @@ namespace Hotline.Api.Controllers
                     nextWorkflowDto.NextStepCode = next.Steps.First().Key;
                     nextWorkflowDto.NextStepName = next.Steps.First().Value;
                     if (dto.IsPass)
-                        await _workflowApplication.NextAsync(nextWorkflowDto, cancellationToken: HttpContext.RequestAborted);
+                        await _workflowDomainService.NextAsync(_sessionContext, nextWorkflowDto,
+                            cancellationToken: HttpContext.RequestAborted);
                     else
                     {
                         var reject = nextWorkflowDto.Adapt<RejectDto>();
@@ -455,7 +460,7 @@ namespace Hotline.Api.Controllers
                 var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
                 startDto.DefinitionModuleCode = WorkflowModuleConsts.KnowledgeDelete;
                 startDto.Title = "知识库删除";
-				//await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, knowledge.Id, cancellationToken: HttpContext.RequestAborted);
+                //await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, knowledge.Id, cancellationToken: HttpContext.RequestAborted);
                 await StartFlow(dto.Data.Id, WorkflowModuleConsts.KnowledgeDelete, EKnowledgeApplyType.Delete, startDto);
             }
         }
@@ -579,12 +584,12 @@ namespace Hotline.Api.Controllers
 
             if (knowledgeShowInfoDto.FileJson != null && knowledgeShowInfoDto.FileJson.Any())
             {
-	            var ids = knowledgeShowInfoDto.FileJson.Select(x => x.Id).ToList();
-	            knowledgeShowInfoDto.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
+                var ids = knowledgeShowInfoDto.FileJson.Select(x => x.Id).ToList();
+                knowledgeShowInfoDto.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
             }
 
-			//var files = await _fileRepository.Queryable().Where(x => x.Key == knowledge.Id).ToListAsync();
-   //         if (files.Any()) knowledgeShowInfoDto.Files = _mapper.Map<List<FileDto>>(files);
+            //var files = await _fileRepository.Queryable().Where(x => x.Key == knowledge.Id).ToListAsync();
+            //         if (files.Any()) knowledgeShowInfoDto.Files = _mapper.Map<List<FileDto>>(files);
 
             if (IsAddPv == true)
                 _mediator.Publish(new GetKnowledgeInfoNotify(knowledge));
@@ -674,37 +679,37 @@ namespace Hotline.Api.Controllers
         [HttpGet("knowledge-status-data")]
         public Dictionary<string, dynamic> KnowledgeStatus()
         {
-            var tabNames = new List<KeyValuePair<string, string>>
+            var tabNames = new List<KeyValuePair<int, string>>
             {
-                new KeyValuePair<string, string>("3", "已上架"),
-                new KeyValuePair<string, string>("4", "已下架"),
-                new KeyValuePair<string, string>("1", "审核中"),
-                new KeyValuePair<string, string>("8", "草稿"),
-                new KeyValuePair<string, string>("", "全部")
-			};
-
-            var tabNewDraftsNames = new List<KeyValuePair<string, string>>
+                new KeyValuePair<int, string>(3, "已上架"),
+                new KeyValuePair<int, string>(4, "已下架"),
+                new KeyValuePair<int, string>(1, "审核中"),
+                new KeyValuePair<int, string>(8, "草稿"),
+                new KeyValuePair<int, string>(-1, "全部")
+            };
+
+            var tabNewDraftsNames = new List<KeyValuePair<int, string>>
             {
-	            new KeyValuePair<string, string>("", "全部"),
-				new KeyValuePair<string, string>("0", "待提交"),
-	            new KeyValuePair<string, string>("5", "审核不通过"),
+                new KeyValuePair<int, string>(-1, "全部"),
+                new KeyValuePair<int, string>(0, "待提交"),
+                new KeyValuePair<int, string>(5, "审核不通过"),
             };
 
             var tabAuditingNames = new List<KeyValuePair<string, string>>
             {
-	            new KeyValuePair<string, string>("", "全部"),
-				new KeyValuePair<string, string>("KnowledgeAdd", "新增审核"),
-	            new KeyValuePair<string, string>("KnowledgeUpdate", "修改审核"),
-	            new KeyValuePair<string, string>("KnowledgeDelete", "删除审核"),
-	            new KeyValuePair<string, string>("KnowledgeOffshelf", "下架审核"),
-			};
-
-			return _baseDataApplication
+                new KeyValuePair<string, string>("", "全部"),
+                new KeyValuePair<string, string>("KnowledgeAdd", "新增审核"),
+                new KeyValuePair<string, string>("KnowledgeUpdate", "修改审核"),
+                new KeyValuePair<string, string>("KnowledgeDelete", "删除审核"),
+                new KeyValuePair<string, string>("KnowledgeOffshelf", "下架审核"),
+            };
+
+            return _baseDataApplication
                 .FileType(EFileType.excel | EFileType.pdf)
                 .Add("tabNames", tabNames)
                 .Add("tabNewDraftsNames", tabNewDraftsNames)
                 .Add("tabAuditingNames", tabAuditingNames)
-				.Build();
+                .Build();
         }
 
         /// <summary>
@@ -761,7 +766,7 @@ namespace Hotline.Api.Controllers
         public Dictionary<string, dynamic> GetKnowretrievalBaseData()
         {
             return _baseDataApplication
-                .KnowledgeRetrievalType(new[]{3, 4})
+                .KnowledgeRetrievalType(new[] { 3, 4 })
                 .Build();
         }
 
@@ -994,19 +999,19 @@ namespace Hotline.Api.Controllers
         [HttpGet("offshelf-flow-start")]
         public async Task<NextStepsDto> GetOffshelfFlowStartOptionsAsync()
         {
-	        return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeOffshelf,
-		        HttpContext.RequestAborted);
+            return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.KnowledgeOffshelf,
+                HttpContext.RequestAborted);
         }
 
-		/// <summary>
-		/// 开始流程
-		/// </summary>
-		/// <param name="id">知识ID</param>
-		/// <param name="moduleCode">知识模板编号</param>
-		/// <param name="eKnowledgeApplyType">申请类型</param>
-		/// <param name="dto">流程开启参数</param>
-		/// <returns></returns>
-		private async Task<string> StartFlow(string id, string moduleCode, EKnowledgeApplyType eKnowledgeApplyType, StartWorkflowDto dto)
+        /// <summary>
+        /// 开始流程
+        /// </summary>
+        /// <param name="id">知识ID</param>
+        /// <param name="moduleCode">知识模板编号</param>
+        /// <param name="eKnowledgeApplyType">申请类型</param>
+        /// <param name="dto">流程开启参数</param>
+        /// <returns></returns>
+        private async Task<string> StartFlow(string id, string moduleCode, EKnowledgeApplyType eKnowledgeApplyType, StartWorkflowDto dto)
         {
             var knowledge = await _knowledgeRepository.GetAsync(id, HttpContext.RequestAborted);
             if (knowledge == null)
@@ -1022,7 +1027,7 @@ namespace Hotline.Api.Controllers
             await _knowledgeDomainService.AddWorkFlowAsync(id, eKnowledgeApplyType, HttpContext.RequestAborted);
 
             dto.DefinitionModuleCode = moduleCode;
-			//dto.Title = knowledge.Title;
+            //dto.Title = knowledge.Title;
             return await _workflowApplication.StartWorkflowAsync(dto, id, cancellationToken: HttpContext.RequestAborted);
         }
         #endregion

+ 291 - 198
src/Hotline.Api/Controllers/OrderController.cs

@@ -65,16 +65,8 @@ using XF.Domain.Repository;
 using XF.Utility.EnumExtensions;
 using Hotline.Application.Contracts.Validators.FlowEngine;
 using Hotline.Authentications;
-using Microsoft.AspNetCore.Components;
-using Quartz.Simpl;
-using static Lucene.Net.Util.Fst.Util;
-using DocumentFormat.OpenXml.Spreadsheet;
-using System.Threading;
-using Hotline.Caching.Services;
-using Hotline.CallCenter.Calls;
-using Hotline.CallCenter.BlackLists;
-using Hotline.Share.Mq;
 using Hotline.Share.Dtos.CallCenter;
+using Hotline.Share.Dtos.File;
 using NPOI.SS.Formula.Functions;
 
 namespace Hotline.Api.Controllers;
@@ -288,12 +280,38 @@ public class OrderController : BaseController
 
     #region 工单发布
 
+    /// <summary>
+    /// 发布代办(集合)
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("publish/items")]
+    public async Task<IList<PublishDto>> GetPublishOrderListAsync([FromQuery] QueryOrderPublishDto dto)
+    { 
+        var fixedQueryCount = _systemSettingCacheManager.FixedQueryCount;
+        var query = _orderApplication.GetPublishOrderList(dto);
+        return (await query.ToFixedListAsync(dto.QueryIndex, fixedQueryCount, HttpContext.RequestAborted))
+            .Adapt<List<PublishDto>>();
+    }
+
+    /// <summary>
+    /// 发布代办
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("publish/count")]
+    public async Task<int> GetPublishOrderCount([FromQuery] QueryOrderPublishDto dto)
+    {
+        return await _orderApplication.GetPublishOrderList(dto).CountAsync(HttpContext.RequestAborted);
+    }
+
     /// <summary>
     /// 查询(工单发布)
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpGet("publish")]
+    [Obsolete("前端不再调用,择机删除")]
     public async Task<PagedDto<PublishDto>> PublishOrderList([FromQuery] QueryOrderPublishDto dto)
     {
         var (total, items) = await _orderRepository.Queryable()
@@ -314,8 +332,8 @@ public class OrderController : BaseController
             .WhereIF(!string.IsNullOrEmpty(dto.FromPhone), d => d.FromPhone == dto.FromPhone) //来电号码
                                                                                               //.WhereIF(!string.IsNullOrEmpty(dto.PubMan),
                                                                                               //    d => d.AcceptorName.Contains(dto.PubMan!) || d.AcceptorStaffNo.Contains(dto.PubMan!))
-            //.WhereIF(dto.PubRange == EPublicState.Pub, d => d.OrderPublish.PublishState)
-            //.WhereIF(dto.PubRange == EPublicState.NoPub, d => !d.OrderPublish.PublishState)
+                                                                                              //.WhereIF(dto.PubRange == EPublicState.Pub, d => d.OrderPublish.PublishState)
+                                                                                              //.WhereIF(dto.PubRange == EPublicState.NoPub, d => !d.OrderPublish.PublishState)
             .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, d => d.Source == ESource.ProvinceStraight)
             .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, d => d.Source != ESource.ProvinceStraight)
             .WhereIF(dto.FiledType != null && dto.FiledType == FiledType.CenterFiled, d => d.ProcessType == EProcessType.Zhiban)
@@ -592,7 +610,7 @@ public class OrderController : BaseController
                 .Select(x => new Kv { Key = x.DicDataValue, Value = x.DicDataName }).ToList()
         };
         var (idName, idNames) = await _workflowDomainService.GetHandleOrgsAsync(order.WorkflowId, HttpContext.RequestAborted);
-        res.ActualHandleOrgName = new Kv() {  Key=order.ActualHandleOrgCode, Value= order.ActualHandleOrgName };
+        res.ActualHandleOrgName = new Kv() { Key = order.ActualHandleOrgCode, Value = order.ActualHandleOrgName };
         res.idNames = order.CounterSignType == null
             ? null
             : idNames.Where(d => d.Key != idName.Key).ToList();
@@ -605,6 +623,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpGet("published")]
+    [Obsolete("前端不再调用,择机删除")]
     public async Task<PagedDto<PublishedDto>> PublishedOrderList([FromQuery] PublishedPagedRequest dto)
     {
         var (total, items) = await _orderPublishRepository.Queryable()
@@ -637,6 +656,31 @@ public class OrderController : BaseController
         return new PagedDto<PublishedDto>(total, _mapper.Map<IReadOnlyList<PublishedDto>>(items));
     }
 
+    /// <summary>
+    /// 发布列表(集合)
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("published/items")]
+    public async Task<IList<PublishedDto>> GetPublishedOrderListAsync([FromQuery] PublishedPagedRequest dto)
+    {
+        var fixedQueryCount = _systemSettingCacheManager.FixedQueryCount;
+        var query = _orderApplication.GetPublishedOrder(dto);
+        return (await query.ToFixedListAsync(dto.QueryIndex, fixedQueryCount, HttpContext.RequestAborted))
+            .Adapt<List<PublishedDto>>();
+    }
+
+    /// <summary>
+    /// 发布列表(总条数)
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("published/count")]
+    public async Task<int> GetPublishedOrderCountAsync([FromQuery] PublishedPagedRequest dto)
+    {
+        return await _orderApplication.GetPublishedOrder(dto).CountAsync();
+    }
+
     /// <summary>
     /// 发布详情
     /// </summary>
@@ -740,9 +784,9 @@ public class OrderController : BaseController
         var users = await _userRepository.Queryable()
             .Includes(d => d.Organization)
             .Includes(d => d.Roles)
-            .WhereIF(!_appOptions.Value.IsZiGong,d => d.Roles.Any(x => roles.Contains(x.Name)))
+            .WhereIF(!_appOptions.Value.IsZiGong, d => d.Roles.Any(x => roles.Contains(x.Name)))
             .WhereIF(_appOptions.Value.IsZiGong, d => d.OrgId == OrgSeedData.CenterId)
-			.ToListAsync(HttpContext.RequestAborted);
+            .ToListAsync(HttpContext.RequestAborted);
         return users.Select(d => new OrderMigrationHandler
         {
             UserId = d.Id,
@@ -865,8 +909,8 @@ public class OrderController : BaseController
                      (d.Order.ExpiredTime > d.Order.ActualHandleTime && d.Order.Status >= EOrderStatus.Filed)) //否 超期
             .WhereIF(dto.StartTime.HasValue, d => d.VisitTime >= dto.StartTime)
             .WhereIF(dto.EndTime.HasValue, d => d.VisitTime <= dto.EndTime)
-            .WhereIF(dto.StartPublishTime.HasValue && dto.EndPublishTime.HasValue,d=> d.PublishTime>= dto.StartPublishTime && d.PublishTime <= dto.EndPublishTime) // 发布时间
-            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName),d=>d.Order.ActualHandleOrgName == dto.ActualHandleOrgName) //接办部门
+            .WhereIF(dto.StartPublishTime.HasValue && dto.EndPublishTime.HasValue, d => d.PublishTime >= dto.StartPublishTime && d.PublishTime <= dto.EndPublishTime) // 发布时间
+            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), d => d.Order.ActualHandleOrgName == dto.ActualHandleOrgName) //接办部门
             .OrderByDescending(x => x.PublishTime)
             .WhereIF(dto.Channel.NotNullOrEmpty(), d => d.Order.SourceChannelCode == dto.Channel)
             .OrderByDescending(d => d.PublishTime)
@@ -1286,8 +1330,8 @@ public class OrderController : BaseController
         var users = await _userRepository.Queryable()
             .Includes(d => d.Organization)
             .Includes(d => d.Roles)
-            .WhereIF(!_appOptions.Value.IsZiGong,d => d.Roles.Any(x => roles.Contains(x.Name)))
-            .WhereIF(_appOptions.Value.IsZiGong,d=> d.OrgId == OrgSeedData.CenterId)
+            .WhereIF(!_appOptions.Value.IsZiGong, d => d.Roles.Any(x => roles.Contains(x.Name)))
+            .WhereIF(_appOptions.Value.IsZiGong, d => d.OrgId == OrgSeedData.CenterId)
             .ToListAsync(HttpContext.RequestAborted);
         return users.Select(d => new OrderMigrationHandler
         {
@@ -1312,60 +1356,66 @@ public class OrderController : BaseController
             .ExecuteCommandAsync(HttpContext.RequestAborted);
     }
 
-	/// <summary>
-	/// 部门满意度明细
-	/// </summary>
-	/// <param name="dto"></param>
-	/// <returns></returns>
-	[HttpGet("org-visitdetail-list")]
-	public async Task<PagedDto<OrgVisitDetailListResp>> OrgVisitDetailList([FromQuery] OrgVisitDetailListReq dto)
-	{
-		var query = _orderRepository.OrgVisitDetailFiltrationList(dto);
-		var (total, items) = await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
+    /// <summary>
+    /// 部门满意度明细
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("org-visitdetail-list")]
+    public async Task<PagedDto<OrgVisitDetailListResp>> OrgVisitDetailList([FromQuery] OrgVisitDetailListReq dto)
+    {
+        //特殊需求:管理员账号使用该查询条件查询的数据,与富顺的账号查询的数据一致;
+        var isAdmin = _orderDomainService.IsCheckAdmin();
+        var orgId = isAdmin ? "001059" : _sessionContext.RequiredOrgId;
+        var query = _orderRepository.OrgVisitDetailFiltrationList(dto, orgId);
+        var (total, items) = await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
 
-		return new PagedDto<OrgVisitDetailListResp>(total, _mapper.Map<IReadOnlyList<OrgVisitDetailListResp>>(items));
-	}
+        return new PagedDto<OrgVisitDetailListResp>(total, _mapper.Map<IReadOnlyList<OrgVisitDetailListResp>>(items));
+    }
 
-	/// <summary>
-	/// 部门满意度明细导出
-	/// </summary>
-	/// <param name="dto"></param>
-	/// <returns></returns>
-	[HttpPost("org-visitdetail-list-export")]
-	public async Task<FileStreamResult> OrgVisitDetailListExport([FromBody] ExportExcelDto<OrgVisitDetailListReq> dto)
-	{
-		var query = _orderRepository.OrgVisitDetailFiltrationList(dto.QueryDto);
+    /// <summary>
+    /// 部门满意度明细导出
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpPost("org-visitdetail-list-export")]
+    public async Task<FileStreamResult> OrgVisitDetailListExport([FromBody] ExportExcelDto<OrgVisitDetailListReq> dto)
+    {
+        //特殊需求:管理员账号使用该查询条件查询的数据,与富顺的账号查询的数据一致;
+        var isAdmin = _orderDomainService.IsCheckAdmin();
+        var orgId = isAdmin ? "001059" : _sessionContext.RequiredOrgId;
+        var query = _orderRepository.OrgVisitDetailFiltrationList(dto.QueryDto, orgId);
 
-		List<OrgVisitDetailListResp> orders;
-		if (dto.IsExportAll)
-		{
-			orders = await query.ToListAsync(HttpContext.RequestAborted);
-		}
-		else
-		{
-			var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
-			orders = items;
-		}
-		dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
-		var dtos = orders
-			.Select(stu => _mapper.Map(stu, typeof(OrgVisitDetailListResp), dynamicClass))
-			.Cast<object>()
-			.ToList();
-
-		var stream = ExcelHelper.CreateStream(dtos);
-		return ExcelStreamResult(stream, "部门满意度明细");
-	}
+        List<OrgVisitDetailListResp> orders;
+        if (dto.IsExportAll)
+        {
+            orders = await query.ToListAsync(HttpContext.RequestAborted);
+        }
+        else
+        {
+            var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+            orders = items;
+        }
+        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+        var dtos = orders
+            .Select(stu => _mapper.Map(stu, typeof(OrgVisitDetailListResp), dynamicClass))
+            .Cast<object>()
+            .ToList();
 
-	#endregion
+        var stream = ExcelHelper.CreateStream(dtos);
+        return ExcelStreamResult(stream, "部门满意度明细");
+    }
 
-	#region 二次回访申请
+    #endregion
 
-	/// <summary>
-	/// 可二次回访申请列表
-	/// </summary>
-	/// <param name="dto"></param>
-	/// <returns></returns>
-	[HttpGet("visitapply/visitagainlist")]
+    #region 二次回访申请
+
+    /// <summary>
+    /// 可二次回访申请列表
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("visitapply/visitagainlist")]
     public async Task<PagedDto<OrderCanVisitAgainDto>> OrderVisitAgainList([FromQuery] OrderVisitAgainListDto dto)
     {
         var (total, items) = await _orderVisitedDetailRepository.Queryable()
@@ -1778,7 +1828,7 @@ public class OrderController : BaseController
         try
         {
             dto.NextWorkflow.WorkflowId = delay.WorkflowId;
-            await _workflowApplication.NextAsync(dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
+            await _workflowDomainService.NextAsync(_sessionContext, dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
         }
         catch (Exception e)
         {
@@ -1903,10 +1953,10 @@ public class OrderController : BaseController
             .WhereIF(dto.QueryDelayState is EQueryDelayState.Examining, d => d.DelayState == EDelayState.Examining)
             .WhereIF(dto.QueryDelayState is EQueryDelayState.Pass, d => d.DelayState == EDelayState.Pass)
             .WhereIF(dto.QueryDelayState is EQueryDelayState.NoPass, d => d.DelayState == EDelayState.NoPass)
-            .WhereIF(!string.IsNullOrEmpty(dto.CurrentStepName),d => !SqlFunc.IsNullOrEmpty(d.WorkflowId) && d.Workflow.ActualHandleStepName == dto.CurrentStepName) //当前节点
-            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandlerName),d => !SqlFunc.IsNullOrEmpty(d.WorkflowId) && d.Workflow.ActualHandlerName == dto.ActualHandlerName) // 审批人
-            .WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName),d => d.Order.OrgLevelOneName == dto.OrgLevelOneName) //一级部门
-            .WhereIF(dto.StartCreationTime.HasValue && dto.EndCreationTime.HasValue, d=>d.CreationTime >= dto.StartCreationTime && d.CreationTime <= dto.EndCreationTime) // 申请时间
+            .WhereIF(!string.IsNullOrEmpty(dto.CurrentStepName), d => !SqlFunc.IsNullOrEmpty(d.WorkflowId) && d.Workflow.ActualHandleStepName == dto.CurrentStepName) //当前节点
+            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandlerName), d => !SqlFunc.IsNullOrEmpty(d.WorkflowId) && d.Workflow.ActualHandlerName == dto.ActualHandlerName) // 审批人
+            .WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName), d => d.Order.OrgLevelOneName == dto.OrgLevelOneName) //一级部门
+            .WhereIF(dto.StartCreationTime.HasValue && dto.EndCreationTime.HasValue, d => d.CreationTime >= dto.StartCreationTime && d.CreationTime <= dto.EndCreationTime) // 申请时间
             .OrderByDescending(d => d.ApplyDelayTime)
             .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
 
@@ -2281,7 +2331,9 @@ public class OrderController : BaseController
         try
         {
             dto.NextWorkflow.WorkflowId = screen.WorkflowId;
-            await _workflowApplication.NextAsync(dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
+            //await _workflowApplication.NextAsync(dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted);
+            await _workflowDomainService.NextAsync(_sessionContext, dto.NextWorkflow,
+                cancellationToken: HttpContext.RequestAborted);
         }
         catch (Exception e)
         {
@@ -3762,8 +3814,9 @@ public class OrderController : BaseController
                     var flowStepHandler = nextDto.NextHandlers.FirstOrDefault();
                     await _orderRepository.Updateable().SetColumns(o => new Order()
                     {
-	                    CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username
-                    }).Where(o=>o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+                        CenterToOrgHandlerId = flowStepHandler.UserId,
+                        CenterToOrgHandlerName = flowStepHandler.Username
+                    }).Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
                 }
 
                 await _workflowDomainService.NextAsync(_sessionContext, nextDto, order.ExpiredTime, isAutoFillSummaryOpinion, cancellationToken);
@@ -3775,7 +3828,7 @@ public class OrderController : BaseController
                 orderHandleFlowDto.CrossSteps = orderHandleFlowDto.CrossSteps.OrderBy(d => d.Sort).ToList();
                 var stepCount = orderHandleFlowDto.CrossSteps.Count;
                 var unhandleSteps = new List<WorkflowStep> { startStep };
-                for (int i = 0;i < stepCount;i++)
+                for (int i = 0; i < stepCount; i++)
                 {
                     var crossStep = orderHandleFlowDto.CrossSteps[i];
                     var tempSteps = new List<WorkflowStep>();
@@ -3923,13 +3976,6 @@ public class OrderController : BaseController
     [HttpPost("endcs")]
     public async Task EndCountersign([FromBody] EndCountersignDto dto)
     {
-        //var workflow = await _workflowDomainService.TerminalCountersignAsync(dto.CountersignId, HttpContext.RequestAborted);
-        //var order = await _orderRepository.GetAsync(d => d.WorkflowId == workflow.Id, HttpContext.RequestAborted);
-        //if (order is null)
-        //    throw new UserFriendlyException($"工单未开启流程, workflowId: {workflow.Id}");
-        //order.UpdateHandlingStatus(workflow.IsInCountersign);
-        //_mapper.Map(workflow, order);
-        //await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
         await _orderApplication.EndCountersign(dto, HttpContext.RequestAborted);
     }
 
@@ -4147,8 +4193,9 @@ public class OrderController : BaseController
         {
             query.WhereIF(dto.QueryType is 1, d => d.IsForwarded == false)
                 .WhereIF(dto.QueryType is 2, d => d.IsForwarded == true)
-                .Where(d => SqlFunc.Subqueryable<OrderSpecial>().Where(os => os.OrderId == d.Id && os.IsDeleted == false && os.SpecialType == ESpecialType.ReTransact)
-                    .NotAny());
+                //.Where(d => SqlFunc.Subqueryable<OrderSpecial>().Where(os => os.OrderId == d.Id && os.IsDeleted == false && os.SpecialType == ESpecialType.ReTransact)
+                //    .NotAny())
+                ;
         }
 
         var (total, items) = await query
@@ -4161,7 +4208,10 @@ public class OrderController : BaseController
             .Where(d => SqlFunc.Subqueryable<OrderDelay>().Where(od => od.OrderId == d.Id && od.IsDeleted == false && od.DelayState == EDelayState.Examining).NotAny())
             .Where(d => SqlFunc.Subqueryable<OrderSendBackAudit>().Where(osba => osba.OrderId == d.Id && osba.IsDeleted == false && osba.State == ESendBackAuditState.Apply)
                 .NotAny())
-            .Where(d=> SqlFunc.Subqueryable<OrderSpecial>().Where(s=>s.OrderId == d.Id).NotAny() || SqlFunc.Subqueryable<OrderSpecial>().Where(s=> s.OrderId == d.Id && s.State > 0).Any())
+            .Where(d => SqlFunc.Subqueryable<OrderSpecial>().Where(s => s.OrderId == d.Id && s.State == 0 && s.IsDeleted == false )
+	            .WhereIF(dto.QueryType != null && ( dto.QueryType == 1 || dto.QueryType == 2),s =>  s.SpecialType == ESpecialType.ReTransact)
+	            //.WhereIF(dto.QueryType != null && dto.QueryType == 3, s =>  s.SpecialType != ESpecialType.ReTransact)
+				.NotAny())
             .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
             .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword))
             .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No == dto.No)
@@ -4218,50 +4268,14 @@ public class OrderController : BaseController
     [HttpGet("waited/center")]
     public async Task<PagedDto<OrderDto>> QueryWaitedForCenter([FromQuery] QueryOrderWaitedCenterDto dto)
     {
-        //if (dto.EndCreationTime.HasValue)
-        //    dto.EndCreationTime = dto.EndCreationTime.Value.AddDays(1).AddSeconds(-1);
-        //if (dto.StartTimeEnd.HasValue)
-        //    dto.StartTimeEnd = dto.StartTimeEnd.Value.AddDays(1).AddSeconds(-1);
-
-        //var (total, items) = await _orderRepository.Queryable()
-        //    //.LeftJoin<WorkflowStep>((d, step) => d.Id == step.ExternalId)
-        //    //.Where((d, step) =>
-        //    // ((string.IsNullOrEmpty(d.WorkflowId) && (string.IsNullOrEmpty(d.SignerId) || d.SignerId == _sessionContext.RequiredUserId)) ||
-        //    //  (!string.IsNullOrEmpty(d.WorkflowId) &&
-        //    //   ((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))) &&
-        //    //   ( step.Status != EWorkflowStepStatus.Handled )
-        //    //  )))
-        //    //.Where(d => d.Workflow.Steps.Any(s => s.Status < EWorkflowStepStatus.Handled && s.HandlerOrgId == OrgSeedData.CenterId))
-        //    .LeftJoin<WorkflowStep>((d, step) => d.Id == step.ExternalId)
-        //    .Where((d, step) => (step.Id == null || (step.HandlerOrgId == OrgSeedData.CenterId && step.Status < EWorkflowStepStatus.Handled)))
-        //    .Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
-        //    .Where(d => d.Status != EOrderStatus.BackToProvince && d.Status < EOrderStatus.Filed)
-        //    .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No!.Contains(dto.No!))
-        //    .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title!.Contains(dto.Title!))
-        //    .WhereIF(dto is { StCreationTime: not null, EndCreationTime: not null }, d => d.CreationTime >= dto.StCreationTime && d.CreationTime <= dto.EndCreationTime)
-        //    .WhereIF(dto is { StartTimeSt: not null, StartTimeEnd: not null }, d => d.StartTime >= dto.StartTimeSt && d.StartTime <= dto.StartTimeEnd)
-        //    .WhereIF(!string.IsNullOrEmpty(dto.StepName), d => d.ActualHandleStepName == dto.StepName)
-        //    .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), d => d.ActualHandleOrgName!.Contains(dto.ActualHandleOrgName!))
-        //    .WhereIF(dto.Status.HasValue, d => d.Status == dto.Status)
-        //    .WhereIF(!string.IsNullOrEmpty(dto.AcceptorName), d => d.AcceptorName!.Contains(dto.AcceptorName!))
-        //    .WhereIF(dto.ExpiredStatus is EExpiredStatus.Normal, d => DateTime.Now < d.NearlyExpiredTime)
-        //    .WhereIF(dto.ExpiredStatus is EExpiredStatus.GoingToExpired, d => DateTime.Now > d.NearlyExpiredTime && DateTime.Now < d.ExpiredTime)
-        //    .WhereIF(dto.ExpiredStatus is EExpiredStatus.Expired, d => DateTime.Now >= d.ExpiredTime)
-        //    .WhereIF(dto.IsUrgent.HasValue, d => d.IsUrgent == dto.IsUrgent.Value)
-        //    .OrderBy(d => d.Status)
-        //    .OrderBy(d => d.CreationTime, OrderByType.Desc)
-        //    .ToPagedListAsync(dto, HttpContext.RequestAborted);
-
         var (total, items) = await _orderRepository.Queryable()
-	        .Includes(d=>d.Workflow.Steps)
+            .Includes(d => d.Workflow.Steps)
             .Where(d => SqlFunc.Subqueryable<WorkflowTrace>()
+                            .WhereIF(!string.IsNullOrEmpty(dto.CenterToOrgHandlerName), step => step.BusinessType == EBusinessType.Send && step.HandlerName.Contains(dto.CenterToOrgHandlerName))
                             .Where(step => step.ExternalId == d.Id &&
                                            step.HandlerOrgId == OrgSeedData.CenterId &&
-                                           step.Status < EWorkflowStepStatus.Handled)
-                            .WhereIF(!string.IsNullOrEmpty(dto.CenterToOrgHandlerName),step=>step.BusinessType == EBusinessType.Send && step.HandlerName.Contains(dto.CenterToOrgHandlerName)).Any() ||
-                        (string.IsNullOrEmpty(d.WorkflowId) && string.IsNullOrEmpty(dto.CenterToOrgHandlerName))
+                                           step.Status < EWorkflowStepStatus.Handled).Any()
+                        || (string.IsNullOrEmpty(d.WorkflowId) && string.IsNullOrEmpty(dto.CenterToOrgHandlerName))
             )
             .Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
             .Where(d => d.Status != EOrderStatus.BackToProvince && d.Status < EOrderStatus.Filed)
@@ -4279,7 +4293,6 @@ public class OrderController : BaseController
             .WhereIF(dto.ExpiredStatus is EExpiredStatus.Expired, d => DateTime.Now >= d.ExpiredTime)
             //.WhereIF(!string.IsNullOrEmpty(dto.CenterToOrgHandlerName), d => d.CenterToOrgHandlerName.Contains(dto.CenterToOrgHandlerName))
             .WhereIF(dto.IsUrgent.HasValue, d => d.IsUrgent == dto.IsUrgent!.Value)
-            .OrderBy(d => d.Status)
             .OrderByIF(string.IsNullOrEmpty(dto.SortField), d => d.CreationTime, OrderByType.Desc)
             .OrderByIF(dto is { SortField: "startTime", SortRule: 0 }, d => d.StartTime, OrderByType.Asc) //受理时间升序
             .OrderByIF(dto is { SortField: "startTime", SortRule: 1 }, d => d.StartTime, OrderByType.Desc) //受理时间降序
@@ -4474,12 +4487,12 @@ public class OrderController : BaseController
                 audit.State = ESendBackAuditState.End;
                 audit.AuditUser = "默认通过";
                 audit.AuditTime = DateTime.Now;
-                if (prevStep.BusinessType == EBusinessType.Send)
+                if (prevStep.BusinessType == EBusinessType.Send && dto.Handler != null)
                 {
-	                await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = dto.Handler.UserId, CenterToOrgHandlerName = dto.Handler.Username })
-		                .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+                    await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = dto.Handler.UserId, CenterToOrgHandlerName = dto.Handler.Username })
+                        .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
                 }
-				var flowDirection = await _workflowApplication.PreviousAsync(dto, HttpContext.RequestAborted);
+                var flowDirection = await _workflowApplication.PreviousAsync(dto, HttpContext.RequestAborted);
                 var processType = flowDirection == EFlowDirection.OrgToCenter || flowDirection == EFlowDirection.CenterToCenter
                     ? EProcessType.Zhiban
                     : EProcessType.Jiaoban;
@@ -4495,12 +4508,12 @@ public class OrderController : BaseController
             audit.State = ESendBackAuditState.End;
             audit.AuditUser = "默认通过";
             audit.AuditTime = DateTime.Now;
-            if (prevStep.BusinessType == EBusinessType.Send)
+            if (prevStep.BusinessType == EBusinessType.Send && dto.Handler != null)
             {
-	            await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = dto.Handler.UserId, CenterToOrgHandlerName = dto.Handler.Username })
-		            .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+                await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = dto.Handler.UserId, CenterToOrgHandlerName = dto.Handler.Username })
+                    .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
             }
-			var flowDirection = await _workflowApplication.PreviousAsync(dto, HttpContext.RequestAborted);
+            var flowDirection = await _workflowApplication.PreviousAsync(dto, HttpContext.RequestAborted);
             var processType = flowDirection == EFlowDirection.OrgToCenter || flowDirection == EFlowDirection.CenterToCenter
                 ? EProcessType.Zhiban
                 : EProcessType.Jiaoban;
@@ -4509,8 +4522,8 @@ public class OrderController : BaseController
             await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { ProcessType = processType, SendBackNum = order.SendBackNum })
                 .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
 
-			//发送短信TODO
-		}
+            //发送短信TODO
+        }
 
         await _orderSendBackAuditRepository.AddAsync(audit, HttpContext.RequestAborted);
     }
@@ -4557,8 +4570,8 @@ public class OrderController : BaseController
                         sendBack.SendBackData.Handler = handler;
                     }
                     await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = sendBack.SendBackData.Handler.UserId, CenterToOrgHandlerName = sendBack.SendBackData.Handler.Username })
-	                    .Where(o => o.Id == sendBack.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-				}
+                        .Where(o => o.Id == sendBack.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+                }
             }
 
             //string applicantId, string applicantOrgId, string[] applicantRoleIds,
@@ -4576,8 +4589,8 @@ public class OrderController : BaseController
                 order.SendBackNum = order.SendBackNum.HasValue ? order.SendBackNum.Value + 1 : 1;
             await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { ProcessType = processType, SendBackNum = order.SendBackNum })
                 .Where(o => o.Id == sendBack.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
-			//发送短信TODO
-		}
+            //发送短信TODO
+        }
         else
         {
             await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { Status = sendBack.Status.Value })
@@ -4629,8 +4642,8 @@ public class OrderController : BaseController
                             sendBack.SendBackData.Handler = handler;
                         }
                         await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = sendBack.SendBackData.Handler.UserId, CenterToOrgHandlerName = sendBack.SendBackData.Handler.Username })
-	                        .Where(o => o.Id == sendBack.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-					}
+                            .Where(o => o.Id == sendBack.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+                    }
                 }
 
                 sendBack.SendBackData.ExpiredTime = order.ExpiredTime;
@@ -5095,11 +5108,14 @@ public class OrderController : BaseController
             var orderDto = _mapper.Map<OrderDto>(order);
             await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
                 cancellationToken: HttpContext.RequestAborted);
-            var flowStepHandler = recall.NextHandlers.FirstOrDefault();
-			await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username })
-	            .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-			//}
-			await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, order.Status >= EOrderStatus.Filed, EWorkflowTraceType.Recall,
+            if (dto.BusinessType == EBusinessType.Send && recall.NextHandlers.Any())
+            {
+				var flowStepHandler = recall.NextHandlers.FirstOrDefault();
+				await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username })
+					.Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+			}
+            //}
+            await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, order.Status >= EOrderStatus.Filed, EWorkflowTraceType.Recall,
                 HttpContext.RequestAborted);
 
             if (order.Status >= EOrderStatus.Filed)
@@ -5167,25 +5183,23 @@ public class OrderController : BaseController
     [LogFilter("工单重办")]
     public async Task Add([FromBody] OrderReTransactDto dto)
     {
-        var specialAny = await _orderSpecialRepository.Queryable().Where(x => x.OrderId == dto.OrderId && x.State == 0)
+	    var order = await _orderRepository
+		    .Queryable()
+		    .Includes(d => d.Workflow)
+		    .FirstAsync(d => d.Id == dto.OrderId);
+	    if (order.Workflow.IsInCountersign) throw UserFriendlyException.SameMessage("工单会签中,无法进行重办!");
+		var specialAny = await _orderSpecialRepository.Queryable().Where(x => x.OrderId == dto.OrderId && x.State == 0)
             .AnyAsync();
-        if (specialAny) throw UserFriendlyException.SameMessage("工单已存在待审批特提信息!");
+        if (specialAny) throw UserFriendlyException.SameMessage(order.No + " 工单已存在待审批特提信息!");
 
         var screen = await _orderScreenRepository.Queryable().Where(x => x.OrderId == dto.OrderId && (int)x.Status < 2).AnyAsync();
-        if (screen) throw UserFriendlyException.SameMessage("工单存在甄别中的信息!");
+        if (screen) throw UserFriendlyException.SameMessage(order.No + " 工单存在甄别中的信息!");
 
         if (await _orderSendBackAuditRepository.AnyAsync(x => x.OrderId == dto.OrderId && x.State == ESendBackAuditState.Apply,
                 HttpContext.RequestAborted))
         {
-            throw UserFriendlyException.SameMessage("该工单存在正在审核中的退回,不能办理");
+            throw UserFriendlyException.SameMessage(order.No + " 工单存在正在审核中的退回,不能办理");
         }
-
-        var order = await _orderRepository
-            .Queryable()
-            .Includes(d => d.Workflow)
-            .FirstAsync(d => d.Id == dto.OrderId);
-        if (order.Workflow.IsInCountersign) throw UserFriendlyException.SameMessage("工单会签中,无法进行重办!");
-
         var model = _mapper.Map<OrderSpecial>(dto);
 
         var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true,
@@ -5285,10 +5299,15 @@ public class OrderController : BaseController
             var processType = dto.FlowDirection is EFlowDirection.OrgToCenter or EFlowDirection.CenterToCenter or EFlowDirection.FiledToCenter
                 ? EProcessType.Zhiban
                 : EProcessType.Jiaoban;
-			var flowStepHandler = recall.NextHandlers.FirstOrDefault();
-			await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username })
-				.Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-			await _workflowApplication.RecallAsync(recall, endTime, order.Status >= EOrderStatus.Filed, EWorkflowTraceType.Redo,
+
+            if (dto.BusinessType == EBusinessType.Send && recall.NextHandlers.Any())
+            {
+				var flowStepHandler = recall.NextHandlers.FirstOrDefault();
+				await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username })
+					.Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+			}
+
+            await _workflowApplication.RecallAsync(recall, endTime, order.Status >= EOrderStatus.Filed, EWorkflowTraceType.Redo,
                 HttpContext.RequestAborted);
             //var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == dto.OrderId);
             //if (publish != null)
@@ -5430,13 +5449,17 @@ public class OrderController : BaseController
             var orderDto = _mapper.Map<OrderDto>(order);
             await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
                 cancellationToken: HttpContext.RequestAborted);
-			//}
-			var flowStepHandler = recall.NextHandlers.FirstOrDefault();
-			await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username })
-				.Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-			//todo 特提重办,按审批通过时间依据中心派至部门的规则计算期满时间,更新order
+            //}
+            if (special.BusinessType == EBusinessType.Send && recall.NextHandlers.Any())
+            {
+				var flowStepHandler = recall.NextHandlers.FirstOrDefault();
+				await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username })
+					.Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+			}
+          
+            //todo 特提重办,按审批通过时间依据中心派至部门的规则计算期满时间,更新order
 
-			await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, order.Status >= EOrderStatus.Filed, EWorkflowTraceType.Recall,
+            await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, order.Status >= EOrderStatus.Filed, EWorkflowTraceType.Recall,
                 HttpContext.RequestAborted);
             if (order.Status >= EOrderStatus.Filed)
             {
@@ -5581,12 +5604,15 @@ public class OrderController : BaseController
                 await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
                     cancellationToken: HttpContext.RequestAborted);
 				//}
-				var flowStepHandler = recall.NextHandlers.FirstOrDefault();
-				await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username })
-					.Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-				//todo 特提重办,按审批通过时间依据中心派至部门的规则计算期满时间,更新order
+				if (special.BusinessType == EBusinessType.Send && recall.NextHandlers.Any())
+				{
+					var flowStepHandler = recall.NextHandlers.FirstOrDefault();
+					await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username })
+						.Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+				}
+                //todo 特提重办,按审批通过时间依据中心派至部门的规则计算期满时间,更新order
 
-				await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, order.Status >= EOrderStatus.Filed, EWorkflowTraceType.Recall,
+                await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, order.Status >= EOrderStatus.Filed, EWorkflowTraceType.Recall,
                     HttpContext.RequestAborted);
                 if (order.Status >= EOrderStatus.Filed)
                 {
@@ -5831,7 +5857,7 @@ public class OrderController : BaseController
         var order = await _orderRepository.GetAsync(id, HttpContext.RequestAborted);
         var isInstaShot = order.SourceChannel.Contains("随手拍");
         var defaultStepKey = string.Empty;
-		List<Kv> orgs = new();
+        List<Kv> orgs = new();
         if (order == null) throw UserFriendlyException.SameMessage("无效工单信息!");
         //中心会签调取方法
         var org = await _workflowDomainService.GetLevelOneOrgsAsync(order.WorkflowId, HttpContext.RequestAborted);
@@ -5839,14 +5865,14 @@ public class OrderController : BaseController
         var step = await _workflowApplication.GetRecallStepsAsync(order.WorkflowId, HttpContext.RequestAborted);
         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())
-			{
-				var stepdDefault = step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.OrgLevel == 1)
-					.FirstOrDefault();
-				defaultStepKey = stepdDefault.Key;
-			}
-		}
+            step.Steps = step.Steps.Where(x => x.Key.ToLower() != "start").ToList();
+            if (step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.OrgLevel == 1).Any())
+            {
+                var stepdDefault = step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.OrgLevel == 1)
+                    .FirstOrDefault();
+                defaultStepKey = stepdDefault.Key;
+            }
+        }
         //获取部门信息
         var rsp = new
         {
@@ -5860,20 +5886,87 @@ public class OrderController : BaseController
             Step = step,
             Orgs = orgs,
             DefaultStepKey = defaultStepKey
-		};
+        };
         return rsp;
     }
 
+	/// <summary>
+	/// 部门批量重提 该部门及下级部门回访结果 不满意 未评价 视为满意 
+	/// </summary>
+	/// <returns></returns>
+	[HttpPost("org_batch_special")]
+    [AllowAnonymous]
+	public async Task OrgBatchSpecial([FromBody] OrgBatchSpecialDto model)
+	{
+        //部门信息
+		var org = await _organizeRepository.Queryable().Where(o => o.Id == model.OrgId).FirstAsync(HttpContext.RequestAborted);
+		if (org is null)
+			throw UserFriendlyException.SameMessage("部门信息不存在 请检查部门信息是否正确!");
+		//用户信息  && !u.Name.Contains("测试")
+		var user = await _userRepository.Queryable().Where(u => u.OrgId == model.OrgId).FirstAsync(HttpContext.RequestAborted);
+		if (user is null)
+			throw UserFriendlyException.SameMessage("用户信息不存在 请检查部门下用户信息是否正确!");
+		//工单信息 中心会签件不处理
+		var orders = await _orderRepository.Queryable(isAdmin: true)
+			.Includes(o=>o.Workflow)
+	        .Includes(o=>o.OrderVisits)
+	        .Where(o=> (o.CounterSignType == null || o.CounterSignType == ECounterSignType.Department) && o.OrderVisits.Any(ov=> ov.VisitState == EVisitState.Visited && 
+                                             ov.VisitTime >= model.StartTime && ov.VisitTime <= model.EndTime && 
+	                                         ov.OrderVisitDetails.Any(ord=> ord.VisitOrgCode.StartsWith(model.OrgId) &&
+	                                                                        (SqlFunc.JsonField(ord.OrgProcessingResults, "Key") == "2" || 
+	                                                                         SqlFunc.JsonField(ord.OrgProcessingResults, "Key") == "7" ||
+	                                                                         SqlFunc.JsonField(ord.OrgProcessingResults, "Key") == "-1" )
+	                                                                        ))).ToListAsync();
+		if (!orders.Any())
+			throw UserFriendlyException.SameMessage(org.Name + " 部门及下级部门不存在回访结果为不满意、未评价、视为满意的工单!");
+		foreach (var order in orders)
+		{
+			var nextStep = await _workflowStepRepository.Queryable().Where(step =>
+					step.WorkflowId == order.WorkflowId && step.HandlerOrgId == model.OrgId &&
+					step.StepType == EStepType.Normal).OrderByDescending(step => step.CreationTime)
+				.FirstAsync(HttpContext.RequestAborted);
+			if (nextStep is null)
+				continue;
+			var dto = new OrderReTransactDto
+			{
+				AlterTime = true,
+				BusinessType = EBusinessType.Department,
+				FlowDirection = EFlowDirection.FiledToOrg,
+				HandlerType = EHandlerType.OrgLevel,
+				NextHandlers = new List<FlowStepHandler>()
+				{
+					new FlowStepHandler
+					{
+						UserId = user.Id, Username = user.Name, Key = org.Id, Value = org.Name, OrgId = org.Id,
+						OrgName = org.Name
+					}
+				},
+				NextStepCode = nextStep.Code,
+				NextStepName = nextStep.Name,
+				OrderId = order.Id,
+				Cause = "不满意二次办理",
+				Reason = "部门回访不满意  批量特提",
+				SpecialType = ESpecialType.SendBack,
+				StepType = EStepType.Normal,
+                TimeLimit = 5,
+				TimeLimitUnit = ETimeType.WorkDay,
+				WorkflowId = order.WorkflowId
+			};
+			await Add(dto);
+		}
+
+	}
+
     #endregion
 
-    #region 市民信息
+	#region 市民信息
 
-    /// <summary>
-    /// 新增市民信息
-    /// </summary>
-    /// <param name="dtos"></param>
-    /// <returns></returns>
-    [HttpPost("citizen")]
+	/// <summary>
+	/// 新增市民信息
+	/// </summary>
+	/// <param name="dtos"></param>
+	/// <returns></returns>
+	[HttpPost("citizen")]
     [LogFilter("新增市民信息")]
     public async Task Add([FromBody] CitizenAddDto dto)
     {
@@ -6563,7 +6656,7 @@ public class OrderController : BaseController
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
-   [HttpGet("order/about_expire/list_count")]
+    [HttpGet("order/about_expire/list_count")]
     public async Task<int> AboutListCountAsnc([FromQuery] AboutToExpireListDto dto)
     {
         var version = _systemSettingCacheManager.GetAboutToExpireVersion;
@@ -7552,13 +7645,13 @@ public class OrderController : BaseController
                     .SetColumns(o => new Orders.Order() { Status = status, SignerId = dto.Handler.UserId })
                     .Where(o => o.Id == dto.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
             }
-            //else if
-            //{
-            //    await _orderRepository.Updateable()
-            //        .SetColumns(o => new Orders.Order() { Status = status, CenterToOrgHandlerId = dto.Handler.UserId, CenterToOrgHandlerName = dto.Handler.Username })
-            //        .Where(o => o.Id == dto.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
-            //}
-            else 
+            else if (step.BusinessType == EBusinessType.Send)
+            {
+                await _orderRepository.Updateable()
+                    .SetColumns(o => new Orders.Order() { Status = status, CenterToOrgHandlerId = dto.Handler.UserId, CenterToOrgHandlerName = dto.Handler.Username })
+                    .Where(o => o.Id == dto.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
+            }
+            else
             {
                 await _orderRepository.Updateable()
                     .SetColumns(o => new Orders.Order() { Status = status })

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

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

+ 229 - 3
src/Hotline.Api/Controllers/TestController.cs

@@ -1,4 +1,5 @@
 using DocumentFormat.OpenXml.Drawing.Charts;
+using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
 using DotNetCore.CAP;
 using Hotline.Ai.Visit;
 using Hotline.Application.CallCenter;
@@ -39,6 +40,7 @@ using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Realtime;
 using Hotline.Share.Dtos.TrCallCenter;
+using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.JudicialManagement;
 using Hotline.Share.Enums.Order;
@@ -54,6 +56,7 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Options;
 using MiniExcelLibs;
 using Newtonsoft.Json;
+using NPOI.POIFS.Crypt.Dsig;
 using SqlSugar;
 using StackExchange.Redis;
 using System.Threading;
@@ -134,6 +137,7 @@ public class TestController : BaseController
     //private readonly ICacheManager<User> _cache;
     private readonly ICalcExpireTime _expireTime;
     private readonly ICallNativeRepository _callNativeRepository;
+    private readonly IRepository<OldSendProData> _oldSendProDataRepository;
 
 
     public TestController(
@@ -187,7 +191,8 @@ ICallApplication callApplication,
         ISystemSettingCacheManager systemSettingCacheManager,
         ICalcExpireTime expireTime
 ,
-        ICallNativeRepository callNativeRepository)
+        ICallNativeRepository callNativeRepository,
+        IRepository<OldSendProData> oldSendProDataRepository)
     {
         _logger = logger;
         //_authorizeGenerator = authorizeGenerator;
@@ -221,7 +226,6 @@ ICallApplication callApplication,
         _qualityApplication = qualityApplication;
         _enforcementApplication = enforcementApplication;
         _workflowDomainService = workflowDomainService;
-        _orderRepository = orderRepository;
         _mapper = mapper;
         _orderReportApplication = orderReportApplication;
         _enforcementOrdersRepository = enforcementOrdersRepository;
@@ -237,8 +241,230 @@ ICallApplication callApplication,
         _systemSettingCacheManager = systemSettingCacheManager;
         _expireTime = expireTime;
         _callNativeRepository = callNativeRepository;
+        _oldSendProDataRepository = oldSendProDataRepository;
+    }
+
+    /// <summary>
+    /// 修改泸州省工单编码区域
+    /// </summary>
+    /// <returns></returns>
+    [HttpPost("updateoldsendprodata")]
+    [AllowAnonymous]
+    public async Task UpdateOldSendProData()
+    {
+        var list = await _oldSendProDataRepository.Queryable().Where(p => p.ProvinceNo.Contains("99511500")).ToListAsync();
+        if (list != null && list.Any())
+        {
+            foreach (var item in list)
+            {
+                var prono = item.ProvinceNo;
+                prono = prono.Replace("99511500", "99510500");
+                item.NewProvinceNo = prono;
+                await _oldSendProDataRepository.UpdateAsync(item);
+            }
+        }
+    }
+
+    /// <summary>
+    /// 修改工单省编号
+    /// </summary>
+    /// <returns></returns>
+    [HttpPost("updatesendprodata")]
+    [AllowAnonymous]
+    public async Task UpdateSendProData()
+    {
+        var list = await _oldSendProDataRepository.Queryable().Where(p => p.ProvinceNo.Contains("99511500")).ToListAsync();
+        if (list != null && list.Any())
+        {
+            foreach (var item in list)
+            {
+                var data = await _orderRepository.GetAsync(p => p.Id == item.Id, HttpContext.RequestAborted);
+                if (data != null)
+                {
+                    data.ProvinceNo = item.NewProvinceNo;
+                    await _orderRepository.Updateable(data).UpdateColumns(d => d.ProvinceNo).ExecuteCommandAsync(HttpContext.RequestAborted);
+                }
+            }
+        }
     }
 
+    /// <summary>
+    /// 从新推送省上数据
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet("sendpushprodata")]
+    [AllowAnonymous]
+    public async Task SendPushProData(string provinceNo)
+    {
+        //推送 受理信息、结果信息、过程信息、话务信息、回访信息
+        var list = await _oldSendProDataRepository.Queryable()
+            .Where(p => p.CreatorName == null)
+            .WhereIF(!string.IsNullOrEmpty(provinceNo), p => p.ProvinceNo == provinceNo).ToListAsync();
+        if (list != null && list.Any())
+        {
+            foreach (var item in list)
+            {
+                var order = await _orderRepository.GetAsync(p => p.Id == item.Id, HttpContext.RequestAborted);
+                if (order != null)
+                {
+                    item.CreatorName = item.NewProvinceNo;
+                    await _oldSendProDataRepository.Updateable(item).UpdateColumns(d => d.CreatorName).ExecuteCommandAsync(HttpContext.RequestAborted);
+
+                    //受理信息
+                    #region 受理信息
+                    //var publishCallRecordDto = new PublishCallRecrodDto() { };
+                    //if (order.SourceChannelCode == AppDefaults.SourceChannel.DianHua &&
+                    //    !string.IsNullOrEmpty(order.CallId))
+                    //{
+                    //    if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.TianRun)
+                    //    {
+                    //        var callRecord = await _callApplication.GetTianrunCallAsync(order?.CallId, HttpContext.RequestAborted);
+                    //        if (callRecord != null)
+                    //        {
+                    //            publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
+                    //        }
+                    //    }
+                    //    else if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.XingTang)
+                    //    {
+                    //        var call = await _callApplication.GetCallAsync(order?.CallId, HttpContext.RequestAborted);
+                    //        if (call is not null)
+                    //        {
+                    //            publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(call);
+
+                    //            // 工单开始办理如果获取的通话记录是呼出并且录音文件是空就不推送通话记录
+                    //            // 如果 通话记录是呼入, 并且没有录音文件
+                    //            if (_systemSettingCacheManager.OrderStartHandlerPushCallIsNull && call.Direction == ECallDirection.Out && !string.IsNullOrEmpty(call.AudioFile))
+                    //            {
+                    //                publishCallRecordDto.TrCallRecordDto = null;
+                    //            }
+                    //        }
+                    //    }
+                    //}
+                    //publishCallRecordDto.Order = _mapper.Map<OrderDto>(order);
+
+                    //await _capPublisher.PublishAsync(EventNames.HotlineOrderFlowStarted, publishCallRecordDto,
+                    //    cancellationToken: HttpContext.RequestAborted);
+                    #endregion
+
+                    //结果信息
+                    #region 受理信息、话务信息、结果信息
+                    if (order != null)
+                    {
+                        var trace = await _workflowTraceRepository.Queryable()
+                            .FirstAsync(d => d.WorkflowId == order.WorkflowId && d.StepType == EStepType.End, HttpContext.RequestAborted);
+                        var orderFlowDto = new OrderFlowDto
+                        {
+                            Order = _mapper.Map<OrderDto>(order),
+                            WorkflowTrace = _mapper.Map<WorkflowTraceDto>(trace)
+                        };
+                        if (order.SourceChannelCode == AppDefaults.SourceChannel.DianHua &&
+                            !string.IsNullOrEmpty(order.CallId))
+                        {
+                            if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.TianRun)
+                            {
+                                var callRecord = await _callApplication.GetTianrunCallAsync(order?.CallId, HttpContext.RequestAborted);
+                                if (callRecord != null)
+                                {
+                                    orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
+                                }
+                            }
+                            else if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.XingTang)
+                            {
+                                var call = await _callApplication.GetCallAsync(order?.CallId, HttpContext.RequestAborted);
+                                if (call is not null)
+                                {
+                                    orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(call);
+
+                                    // 工单开始办理如果获取的通话记录是呼出并且录音文件是空就不推送通话记录
+                                    // 如果 通话记录是呼入, 并且没有录音文件
+                                    if (_systemSettingCacheManager.OrderStartHandlerPushCallIsNull && call.Direction == ECallDirection.Out && !string.IsNullOrEmpty(call.AudioFile))
+                                    {
+                                        orderFlowDto.TrCallRecordDto = null;
+                                    }
+                                }
+                            }
+                        }
+                        //这里需要判断是否是警情退回
+                        orderFlowDto.IsNonPoliceReturn = false;
+                        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFiled, orderFlowDto, cancellationToken: HttpContext.RequestAborted);
+                        //_logger.LogWarning($"推送完成: {order.ProvinceNo}");
+                    }
+
+                    #endregion
+
+                    //过程信息
+                    #region 过程信息
+                    //查询过程数据
+
+                    if (order != null)
+                    {
+                        var listStep = await _workflowTraceRepository.Queryable()
+                             .Where(p => p.WorkflowId == order.WorkflowId && p.TraceState == EWorkflowTraceState.Normal).ToListAsync();
+                        if (listStep != null && listStep.Any())
+                        {
+                            foreach (var itemStep in listStep)
+                            {
+                                var orderDto = _mapper.Map<OrderDto>(order);
+                                var flowDto = new OrderFlowDto
+                                {
+                                    Order = orderDto,
+                                    WorkflowTrace = _mapper.Map<WorkflowTraceDto>(itemStep),
+                                    ExpiredTimeChanged = false,
+                                    HandlerOrgLevel = itemStep.HandlerOrgId.CalcOrgLevel()
+                                };
+                                await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFlowHandled, flowDto, cancellationToken: HttpContext.RequestAborted);
+                            }
+                        }
+                    }
+
+                    #endregion
+                    //话务信息
+
+                    //回访信息
+                    #region 回访信息
+
+                    if (order != null && order.Status == EOrderStatus.Visited)
+                    {
+                        var listVist = await _orderRepository.Queryable()
+                        .Includes(x => x.OrderVisits.Where(q => q.VisitState == EVisitState.Visited).ToList(), d => d.OrderVisitDetails)
+                        .Where(x => x.Id == item.Id && x.Status == EOrderStatus.Visited).ToListAsync();
+
+                        foreach (var itemVisit in listVist)
+                        {
+                            try
+                            {
+                                var visit = itemVisit.OrderVisits.FirstOrDefault();
+                                if (visit != null)
+                                {
+                                    var visitRemark = visit.OrderVisitDetails.Where(q => q.VisitTarget == EVisitTarget.Org).FirstOrDefault()?.VisitContent;
+                                    //推省上
+                                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisited,
+                                    new PublishVisitDto()
+                                    {
+                                        Order = _mapper.Map<OrderDto>(itemVisit),
+                                        No = visit.No,
+                                        VisitType = visit.VisitType,
+                                        VisitName = visit.CreatorName,
+                                        VisitTime = visit.VisitTime,
+                                        VisitRemark = string.IsNullOrEmpty(visitRemark) == true ? "满意" : visitRemark,
+                                        AreaCode = itemVisit.AreaCode!,
+                                        SubjectResultSatifyCode = visit.NowEvaluate.Key,
+                                        FirstSatisfactionCode = itemVisit.FirstVisitResultCode,
+                                        ClientGuid = ""
+                                    }, cancellationToken: HttpContext.RequestAborted);
+                                }
+                            }
+                            catch { }
+                        }
+                    }
+
+                    #endregion
+                }
+            }
+        }
+    }
+
+
 
     [HttpGet("time")]
     [AllowAnonymous]
@@ -1054,7 +1280,7 @@ ICallApplication callApplication,
     /// <returns></returns>
     [HttpPost("push_order_call")]
     [AllowAnonymous]
-    public async Task PushOrderCallAsync([FromBody]List<string> ProvinceNos)
+    public async Task PushOrderCallAsync([FromBody] List<string> ProvinceNos)
     {
         var orders = await _orderRepository.Queryable()
             .Where(m => ProvinceNos.Contains(m.ProvinceNo))

+ 91 - 1
src/Hotline.Api/Controllers/WebPortalController.cs

@@ -56,6 +56,7 @@ namespace Hotline.Api.Controllers
         private readonly IRepository<Knowledge> _knowledgeRepository;
         private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
         private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
+        private readonly ITypedCache<string> _getVailData;
 
         public WebPortalController(IMapper mapper,
             IMediator mediator,
@@ -78,7 +79,8 @@ namespace Hotline.Api.Controllers
             IRepository<KnowledgeType> knowledgeTypeRepository,
             IRepository<Knowledge> knowledgeRepository,
             ISystemDicDataCacheManager systemDicDataCacheManager,
-            IOptionsSnapshot<AppConfiguration> appOptions
+            IOptionsSnapshot<AppConfiguration> appOptions,
+            ITypedCache<string> getVailData
             )
         {
             _mapper = mapper;
@@ -103,6 +105,7 @@ namespace Hotline.Api.Controllers
             _knowledgeRepository = knowledgeRepository;
             _systemDicDataCacheManager = systemDicDataCacheManager;
             _appOptions = appOptions;
+            _getVailData = getVailData;
         }
 
         #region 通知
@@ -786,6 +789,7 @@ namespace Hotline.Api.Controllers
             int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));
             OrderListReturnDto returnDto = new()
             {
+                Total=total,
                 PageNum = dto.PageIndex,
                 PageCount = nPageCount,
                 Data = _mapper.Map<IReadOnlyList<OrderListDto>>(items)
@@ -794,6 +798,50 @@ namespace Hotline.Api.Controllers
             return OpenResponse.Ok(WebPortalDeResponse<OrderListReturnDto>.Success(returnDto, "成功"));
         }
 
+        /// <summary>
+        /// 查询工单发布后公开的数据
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("get_order_list_all_bynoortitle")]
+        [AllowAnonymous]
+        public async Task<OpenResponse> GetOrderByListAllByNoOrTitle([FromBody] QueryOrderListDto dto)
+        {
+            var (total, items) = await _orderRepository.Queryable(includeDeleted: true)
+                .LeftJoin<OrderPublish>((p, op) => p.Id == op.OrderId)
+                .WhereIF(!string.IsNullOrEmpty(dto.FlowCode), (p, op) => p.No == dto.FlowCode)
+                .WhereIF(!string.IsNullOrEmpty(dto.FlowName), (p, op) => p.Title.Contains(dto.FlowName))
+                .WhereIF(!string.IsNullOrEmpty(dto.FlowSType), (p, op) => p.AcceptTypeCode == dto.FlowSType)
+                .WhereIF(!string.IsNullOrEmpty(dto.FlowRType), (p, op) => p.HotspotId == dto.FlowRType)
+                .WhereIF(!string.IsNullOrEmpty(dto.FlowSDate), (p, op) => p.StartTime >= DateTime.Parse(DateTime.Parse(dto.FlowSDate).ToString("yyyy-MM-dd 00:00:00")))//dto.FlowSDate
+                .WhereIF(!string.IsNullOrEmpty(dto.FlowEDate), (p, op) => p.StartTime <= DateTime.Parse(DateTime.Parse(dto.FlowEDate).ToString("yyyy-MM-dd 00:00:00")))// dto.FlowEDate
+                .WhereIF(!string.IsNullOrEmpty(dto.FlowFrom), (p, op) => p.FromName.Contains(dto.FlowFrom))
+                .WhereIF(dto.IdentityType.HasValue, (p, op) => p.IdentityType == dto.IdentityType)
+                .OrderByDescending((p, op) => p.CreationTime)
+               .Select((p, op) => new OrderListDto
+               {
+                   FlowID = p.Id,
+                   FlowCode = p.No,
+                   FlowPwd = p.Password,
+                   FlowTitle = p.Title,
+                   FlowFromName = p.SourceChannel,
+                   FlowPurTypeName = p.AcceptType,
+                   ConTypeName = p.HotspotName,
+                   FlowAddDate = p.CreationTime,
+                   PubDate = op.CreationTime,
+                   RSFlagName = p.Status >= EOrderStatus.Filed ? "办理完成" : "办理中"
+               })
+               .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
+
+            OrderListReturnAllDto returnDto = new()
+            {
+                Total = total,
+                Data = _mapper.Map<IReadOnlyList<OrderListDto>>(items)
+            };
+
+            return OpenResponse.Ok(WebPortalDeResponse<OrderListReturnAllDto>.Success(returnDto, "成功"));
+        }
+
         /// <summary>
         /// 办件摘编详情
         /// </summary>
@@ -1359,5 +1407,47 @@ namespace Hotline.Api.Controllers
             }
             return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<OrderFormCount>>.Success(formFileCount));
         }
+
+        /// <summary>
+        /// 缓存值
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("setgetvaildata")]
+        [AllowAnonymous]
+        public async Task<OpenResponse> SetGetVailData([FromBody] GetVailDataDto dto)
+        {
+            if (string.IsNullOrEmpty(dto.Key) || string.IsNullOrEmpty(dto.Value))
+                return OpenResponse.Ok(WebPortalDeResponse<string>.Success("-1"));
+
+            string strGuid = Guid.NewGuid().ToString();
+
+            string keyToken = dto.Key + strGuid;
+            await _getVailData.SetAsync(keyToken, dto.Value, TimeSpan.FromHours(1), cancellationToken: HttpContext.RequestAborted);
+            return OpenResponse.Ok(WebPortalDeResponse<string>.Success(strGuid));
+        }
+
+        /// <summary>
+        /// 缓存值
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("getgetvaildata")]
+        [AllowAnonymous]
+        public async Task<OpenResponse> GetGetVailData([FromBody] GetVailDataDto dto)
+        {
+            if (string.IsNullOrEmpty(dto.Key))
+                return OpenResponse.Ok(WebPortalDeResponse<string>.Success("-1"));
+
+            var data = await _getVailData.GetAsync(dto.Key, cancellationToken: HttpContext.RequestAborted);
+            if (!string.IsNullOrEmpty(data) && data == dto.Value)
+            {
+                await _getVailData.RemoveAsync(dto.Key, cancellationToken: HttpContext.RequestAborted);
+                return OpenResponse.Ok(WebPortalDeResponse<string>.Success("1"));
+            }
+
+
+            return OpenResponse.Ok(WebPortalDeResponse<string>.Success("-1"));
+        }
     }
 }

+ 18 - 11
src/Hotline.Api/Controllers/WorkflowController.cs

@@ -347,9 +347,10 @@ public class WorkflowController : BaseController
     /// 办理节点
     /// </summary>
     [HttpPost("next")]
+    [Obsolete("即将弃用")]
     public async Task Next([FromBody] NextWorkflowDto dto)
     {
-        await _workflowApplication.NextAsync(dto, cancellationToken: HttpContext.RequestAborted);
+        await _workflowDomainService.NextAsync(_sessionContext, dto, cancellationToken: HttpContext.RequestAborted);
     }
 
     /// <summary>
@@ -582,24 +583,30 @@ public class WorkflowController : BaseController
     public async Task<FileStreamResult> ScreenListExport([FromBody] ExportExcelDto<QueryOrderCountersignDto> dto)
     {
 	    var query = _workflowApplication.QueryOrderCountersigns(dto.QueryDto, _sessionContext)
-		    .Select((c, w, o) => c);
+			 .Select((c, w, o) => new WorkflowCountersign()
+			 {
+                Id  = c.Id.SelectAll(),
+                Order = o,
+			 });
 	    List<WorkflowCountersign> data;
-	    if (dto.IsExportAll)
+
+		if (dto.IsExportAll)
 	    {
 		    data = await query.ToListAsync(HttpContext.RequestAborted);
-	    }
+		}
 	    else
-	    {
-		    var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
-		    data = items;
-	    }
+		{
+
+			var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+			data = items;
+		}
 
-	    var dataDtos = _mapper.Map<ICollection<WorkflowCountersignDto>>(data);
+        var dataDtos = _mapper.Map<ICollection<WorkflowCountersignDto>>(data);
 
-	    dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
 
 	    var dtos = dataDtos
-		    .Select(stu => _mapper.Map(stu, typeof(WorkflowCountersignDto), dynamicClass))
+			.Select(stu => _mapper.Map(stu, typeof(WorkflowCountersignDto), dynamicClass))
 		    .Cast<object>()
 		    .ToList();
 

+ 3 - 3
src/Hotline.Api/Filter/LogFilterAttribute.cs

@@ -42,7 +42,7 @@ namespace Hotline.Api.Filter
 				{
 					case "GET":
 						Method = "GET";
-						log.ExecuteParam = context.HttpContext.Request.QueryString.Value;
+						log.ExecuteParam = context.HttpContext.Request.QueryString;
 						break;
 
 					case "POST":
@@ -50,11 +50,11 @@ namespace Hotline.Api.Filter
 						if (context.ActionArguments?.Count > 0)
 						{
 							log.ExecuteUrl += context.HttpContext.Request.QueryString.Value;
-							log.ExecuteParam = JsonConvert.SerializeObject(context.ActionArguments);
+							log.ExecuteParam = context.ActionArguments;
 						}
 						else
 						{
-							log.ExecuteParam = context.HttpContext.Request.QueryString.Value;
+							log.ExecuteParam = context.HttpContext.Request.QueryString;
 						}
 						break;
 				}

+ 3 - 3
src/Hotline.Application/CallCenter/DefaultCallApplication.cs

@@ -242,8 +242,8 @@ public abstract class DefaultCallApplication : ICallApplication
             .LeftJoin<OrderVisit>((d, o, v) => d.Id == v.CallId)
             // .WhereIF(string.IsNullOrEmpty(dto.ToNo), (d, o, v) => d.GroupId != "0")
             .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), (d, o, v) => o.No == dto.OrderNo)
-            .WhereIF(!string.IsNullOrEmpty(dto.FromNo), d => d.FromNo == dto.FromNo)
-            .WhereIF(!string.IsNullOrEmpty(dto.ToNo), d => d.ToNo == dto.ToNo)
+            .WhereIF(!string.IsNullOrEmpty(dto.FromNo), d => d.FromNo.Contains(dto.FromNo!))
+            .WhereIF(!string.IsNullOrEmpty(dto.ToNo), d => d.ToNo.Contains(dto.ToNo!))
             .WhereIF(!string.IsNullOrEmpty(dto.UserName), d => d.UserName == dto.UserName)
             .WhereIF(!string.IsNullOrEmpty(dto.TelNo), d => d.TelNo == dto.TelNo)
             .WhereIF(dto.EndBy != null, d => d.EndBy == dto.EndBy)
@@ -506,7 +506,7 @@ public abstract class DefaultCallApplication : ICallApplication
             .FirstAsync(cancellationToken);
         if (orderCall is null || orderCall.CallNo.IsNullOrEmpty())
         {
-            _logger.LogError($"延迟更新工单通话, 工单: {orderId} 根据 order.id left join call_native 信息为空; 消息队列无须重试");
+            _logger.LogInformation($"延迟更新工单通话, 工单: {orderId} 根据 order.id left join call_native 信息为空; 消息队列无须重试");
             return;
         }
 

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

@@ -38,10 +38,10 @@ namespace Hotline.Application.FlowEngine
         Task<FlowAssignInfo> GetNextStepFlowAssignInfoAsync(Workflow workflow, WorkflowStep currentStep,
             BasicWorkflowDto dto, StepDefine nextStepDefine, bool isNextDynamic, CancellationToken cancellationToken);
 
-        /// <summary>
-        /// 流转至下一节点(节点办理)
-        /// </summary>
-        Task<Workflow> NextAsync(NextWorkflowDto dto, DateTime? expiredTime = null, CancellationToken cancellationToken = default);
+        ///// <summary>
+        ///// 流转至下一节点(节点办理)
+        ///// </summary>
+        //Task<Workflow> NextAsync(NextWorkflowDto dto, DateTime? expiredTime = null, CancellationToken cancellationToken = default);
 
         /// <summary>
         /// 退回(返回前一节点)
@@ -62,7 +62,7 @@ namespace Hotline.Application.FlowEngine
         /// <summary>
         /// 办理至结束节点(无视流程模板配置,操作人需是当前节点办理对象)
         /// </summary>
-        Task HandleToEndAsync(string workflowId, string opinion, List<FileDto> files,
+        Task HandleToEndAsync(string workflowId, string opinion, List<FileDto> files, DateTime? expiredTime = null,
             EReviewResult reviewResult = EReviewResult.Unknown, CancellationToken cancellationToken = default);
 
         ////////

+ 182 - 197
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -4,15 +4,11 @@ using Hotline.FlowEngine;
 using Hotline.FlowEngine.Definitions;
 using Hotline.FlowEngine.WorkflowModules;
 using Hotline.FlowEngine.Workflows;
-using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Orders;
 using Hotline.Settings;
-using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.FlowEngine;
-using Hotline.Share.Dtos.FlowEngine.Definition;
-using Hotline.Share.Dtos.Settings;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Identity;
 using Hotline.Users;
@@ -28,15 +24,9 @@ using XF.Domain.Repository;
 using XF.Utility.EnumExtensions;
 using Hotline.Share.Dtos.File;
 using Microsoft.Extensions.Logging;
-using System.Text;
-using System.Diagnostics;
 using Hotline.Configurations;
 using Hotline.Share.Dtos.Order.Handle;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Options;
 using Newtonsoft.Json;
-using NPOI.SS.Formula.Functions;
-using DocumentFormat.OpenXml.Drawing;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
 using SqlSugar;
 using Hotline.SeedData;
@@ -264,76 +254,76 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         return workflow.Id;
     }
 
-    /// <summary>
-    /// 流转至下一节点(节点办理)
-    /// </summary>
-    public async Task<Workflow> NextAsync(NextWorkflowDto dto, DateTime? expiredTime = null, CancellationToken cancellationToken = default)
-    {
-        var validator = new NextWorkflowDtoValidator();
-        var validResult = await validator.ValidateAsync(dto, cancellationToken);
-        if (!validResult.IsValid)
-            throw new UserFriendlyException(
-                $"非法参数, {string.Join(',', validResult.Errors.Select(d => d.ErrorMessage))}");
-        var workflow = await _workflowDomainService.GetWorkflowAsync(dto.WorkflowId, withDefine: true, withSteps: true,
-            withTraces: true, withCountersigns: true, cancellationToken: cancellationToken);
-
-        //var currentStep = _workflowDomainService.FindCurrentStepWaitForHandle(workflow,
-        //    current.RequiredUserId, current.RequiredOrgId, current.Roles);
-        var currentStep = workflow.Steps.FirstOrDefault(d => d.Id == dto.StepId);
-        if (currentStep == null)
-            throw new UserFriendlyException(
-                $"未找到对应节点, workflowId: {dto.WorkflowId}, stepId: {dto.StepId}", "未找到对应节点");
-        if (currentStep.Status is EWorkflowStepStatus.Handled)
-            throw new UserFriendlyException("该状态不支持继续办理");
-
-        var currentStepDefine = _workflowDomainService.GetStepDefine(workflow.WorkflowDefinition, currentStep.Code);
-
-        //下一节点是否为动态节点
-        var isNextDynamic = currentStepDefine.InstanceMode is EInstanceMode.Dynamic &&
-                            !_workflowDomainService.DynamicShouldTerminal(currentStepDefine, _sessionContextProvider.SessionContext.OrgLevel);
-
-        StepDefine nextStepDefine;
-        if (isNextDynamic
-            || (currentStep.IsInCountersign() && !currentStep.IsTopCountersignEndStep(workflow.TopCountersignStepId))
-            || dto.IsStartCountersign)
-        {
-            //下一步配置为当前节点配置
-            nextStepDefine = currentStepDefine;
-        }
-        else
-        {
-            //下一步配置为下一步节点配置
-            nextStepDefine = _workflowDomainService.GetStepDefine(workflow.WorkflowDefinition, dto.NextStepCode);
-        }
-
-        //需求:按角色选择办理人可以不选,表示该角色下所有人都可以办理,同时依据配置:是否本部门人办理显示待选办理人。角色下只要一人办理即可(即:角色下不发起会签)
-        if (nextStepDefine.HandlerType != EHandlerType.Role && !dto.NextHandlers.Any())
-            throw new UserFriendlyException("未指定节点处理者");
-
-        if (dto.IsStartCountersign)
-        {
-            if (!currentStepDefine.CanStartCountersign)
-                throw new UserFriendlyException("当前节点不支持发起会签");
-            //if (currentStepDefine.HandlerType is EHandlerType.Role)
-            //    throw new UserFriendlyException("当前节点不支持发起会签");
-            //即使当前节点支持发起会签,但下一节点为信息汇总节点、结束节点时也不可发起会签
-            if (nextStepDefine.StepType is EStepType.Summary or EStepType.End)
-                throw new UserFriendlyException("下一节点不允许发起会签");
-            //下一节点是会签汇总节点也不允许发起会签
-            if (dto.BackToCountersignEnd)
-                throw new UserFriendlyException("下一节点不允许发起会签");
-        }
-
-        var flowAssignInfo =
-            await GetNextStepFlowAssignInfoAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic, cancellationToken);
-
-        //var nextStepHandlers = await GetNextStepHandlersAsync(workflow, nextStepDefine, dto, cancellationToken);
-
-        await _workflowDomainService.NextAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic,
-            flowAssignInfo, expiredTime, cancellationToken);
-
-        return workflow;
-    }
+    ///// <summary>
+    ///// 流转至下一节点(节点办理)
+    ///// </summary>
+    //public async Task<Workflow> NextAsync(NextWorkflowDto dto, DateTime? expiredTime = null, CancellationToken cancellationToken = default)
+    //{
+    //    var validator = new NextWorkflowDtoValidator();
+    //    var validResult = await validator.ValidateAsync(dto, cancellationToken);
+    //    if (!validResult.IsValid)
+    //        throw new UserFriendlyException(
+    //            $"非法参数, {string.Join(',', validResult.Errors.Select(d => d.ErrorMessage))}");
+    //    var workflow = await _workflowDomainService.GetWorkflowAsync(dto.WorkflowId, withDefine: true, withSteps: true,
+    //        withTraces: true, withCountersigns: true, cancellationToken: cancellationToken);
+
+    //    //var currentStep = _workflowDomainService.FindCurrentStepWaitForHandle(workflow,
+    //    //    current.RequiredUserId, current.RequiredOrgId, current.Roles);
+    //    var currentStep = workflow.Steps.FirstOrDefault(d => d.Id == dto.StepId);
+    //    if (currentStep == null)
+    //        throw new UserFriendlyException(
+    //            $"未找到对应节点, workflowId: {dto.WorkflowId}, stepId: {dto.StepId}", "未找到对应节点");
+    //    if (currentStep.Status is EWorkflowStepStatus.Handled)
+    //        throw new UserFriendlyException("该状态不支持继续办理");
+
+    //    var currentStepDefine = _workflowDomainService.GetStepDefine(workflow.WorkflowDefinition, currentStep.Code);
+
+    //    //下一节点是否为动态节点
+    //    var isNextDynamic = currentStepDefine.InstanceMode is EInstanceMode.Dynamic &&
+    //                        !_workflowDomainService.DynamicShouldTerminal(currentStepDefine, _sessionContextProvider.SessionContext.OrgLevel);
+
+    //    StepDefine nextStepDefine;
+    //    if (isNextDynamic
+    //        || (currentStep.IsInCountersign() && !currentStep.IsTopCountersignEndStep(workflow.TopCountersignStepId))
+    //        || dto.IsStartCountersign)
+    //    {
+    //        //下一步配置为当前节点配置
+    //        nextStepDefine = currentStepDefine;
+    //    }
+    //    else
+    //    {
+    //        //下一步配置为下一步节点配置
+    //        nextStepDefine = _workflowDomainService.GetStepDefine(workflow.WorkflowDefinition, dto.NextStepCode);
+    //    }
+
+    //    //需求:按角色选择办理人可以不选,表示该角色下所有人都可以办理,同时依据配置:是否本部门人办理显示待选办理人。角色下只要一人办理即可(即:角色下不发起会签)
+    //    if (nextStepDefine.HandlerType != EHandlerType.Role && !dto.NextHandlers.Any())
+    //        throw new UserFriendlyException("未指定节点处理者");
+
+    //    if (dto.IsStartCountersign)
+    //    {
+    //        if (!currentStepDefine.CanStartCountersign)
+    //            throw new UserFriendlyException("当前节点不支持发起会签");
+    //        //if (currentStepDefine.HandlerType is EHandlerType.Role)
+    //        //    throw new UserFriendlyException("当前节点不支持发起会签");
+    //        //即使当前节点支持发起会签,但下一节点为信息汇总节点、结束节点时也不可发起会签
+    //        if (nextStepDefine.StepType is EStepType.Summary or EStepType.End)
+    //            throw new UserFriendlyException("下一节点不允许发起会签");
+    //        //下一节点是会签汇总节点也不允许发起会签
+    //        if (dto.BackToCountersignEnd)
+    //            throw new UserFriendlyException("下一节点不允许发起会签");
+    //    }
+
+    //    var flowAssignInfo =
+    //        await GetNextStepFlowAssignInfoAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic, cancellationToken);
+
+    //    //var nextStepHandlers = await GetNextStepHandlersAsync(workflow, nextStepDefine, dto, cancellationToken);
+
+    //    await _workflowDomainService.NextAsync(workflow, currentStep, dto, nextStepDefine, isNextDynamic,
+    //        flowAssignInfo, expiredTime, cancellationToken);
+
+    //    return workflow;
+    //}
 
     /// <summary>
     /// 退回(返回前一节点)
@@ -420,7 +410,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     /// <summary>
     /// 无视流程模板配置直接将当前节点办理至结束节点
     /// </summary>
-    public async Task HandleToEndAsync(string workflowId, string opinion, List<FileDto> files,
+    public async Task HandleToEndAsync(string workflowId, string opinion, List<FileDto> files, DateTime? expiredTime = null,
         EReviewResult reviewResult = EReviewResult.Unknown, CancellationToken cancellationToken = default)
     {
         var workflow = await _workflowDomainService.GetWorkflowAsync(workflowId, withDefine: true, withSteps: true,
@@ -443,7 +433,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
             Files = files,
             StepId = unHandleStep.Id
         };
-        await NextAsync(dto, cancellationToken: cancellationToken);
+        //await NextAsync(dto, cancellationToken: cancellationToken);
+        await _workflowDomainService.NextAsync(_sessionContextProvider.SessionContext, dto, expiredTime: expiredTime, cancellationToken: cancellationToken);
     }
 
     /// <summary>
@@ -562,12 +553,12 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                             dto.OrgIds.Contains(d.ParentId))
                 .ToListAsync(cancellationToken);
             nextStepOption.Items = orgs.Select(d => new FlowStepHandler
-                {
-                    Key = d.Id,
-                    Value = d.Name,
-                    OrgId = d.Id,
-                    OrgName = d.Name
-                })
+            {
+                Key = d.Id,
+                Value = d.Name,
+                OrgId = d.Id,
+                OrgName = d.Name
+            })
                 .ToList();
             nextStepOption.FlowDirection = _workflowDomainService.GetFlowDirection(dto.BusinessType, stepDefine.BusinessType);
             stepOptions.Add(nextStepOption);
@@ -637,7 +628,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 //当前待办节点为会签汇总节点时:检查是否为顶级会签汇总节点,t:按配置往下走,f:继续往上汇总,不需要重复往下指派
                 if (!currentStep.IsTopCountersignEndStep(workflow.TopCountersignStepId))
                 {
-                    var startCountersignStep = GetCsLoopStartStep(workflow, currentStep);
+                    var startCountersignStep = _workflowDomainService.GetCsLoopStartStep(workflow.Steps, currentStep);
 
                     ////查找当前节点对应会签开始节点的上级作为下一个cs汇总节点的汇总对象
                     //var startCountersignStep =
@@ -652,7 +643,9 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     var nextStepOption = await GetDynamicStepAsync(currentStep.CountersignPolicy.Value,
                         EStepType.Normal, currentStep.BusinessType, cancellationToken);
 
-                    dto.Steps = new List<NextStepOption> { nextStepOption, countersignEndOption };
+                    dto.Steps = new List<NextStepOption> { nextStepOption };
+                    if (countersignEndOption != null)
+                        dto.Steps.Add(countersignEndOption);
                     return dto;
                 }
             }
@@ -664,7 +657,9 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 var nextStepOption =
                     await GetDynamicStepAsync(currentStep.CountersignPolicy.Value,
                         EStepType.Normal, currentStep.BusinessType, cancellationToken);
-                dto.Steps = new List<NextStepOption> { nextStepOption, countersignEndOption };
+                dto.Steps = new List<NextStepOption> { nextStepOption };
+                if (countersignEndOption != null)
+                    dto.Steps.Add(countersignEndOption);
                 return dto;
             }
         }
@@ -687,19 +682,6 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         return dto;
     }
 
-    private WorkflowStep GetCsLoopStartStep(Workflow workflow, WorkflowStep currentStep)
-    {
-        var startCountersignStep =
-            workflow.Steps.FirstOrDefault(d => d.Id == currentStep.CountersignStartStepId);
-        if (startCountersignStep is null)
-            throw new UserFriendlyException(
-                $"未查询到会签开始节点,workflowId: {workflow.Id}, startStepId: {currentStep.CountersignStartStepId}",
-                "未查询到会签开始节点,数据异常");
-        if (!startCountersignStep.IsCountersignEndStep)
-            return startCountersignStep;
-        return GetCsLoopStartStep(workflow, startCountersignStep);
-    }
-
     /// <summary>
     /// 查询撤回可选节点及办理对象
     /// </summary>
@@ -803,7 +785,9 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
             ? EFlowDirection.CenterToFile
             : EFlowDirection.OrgToFile;
 
-        await NextAsync(nextDto, cancellationToken: cancellationToken);
+        //await NextAsync(nextDto, cancellationToken: cancellationToken);
+        await _workflowDomainService.NextAsync(_sessionContextProvider.SessionContext, nextDto,
+            cancellationToken: cancellationToken);
     }
 
     //供开启流程调用
@@ -991,17 +975,17 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     var lowLevels = levels.Where(d => d > _sessionContextProvider.SessionContext.OrgLevel).ToList();
                     orgs1 = await query
                         .Where(d => (upLevels.Contains(d.Level) && d.Id.StartsWith(levelOneOrgId)) ||
-                                    (lowLevels.Contains(d.Level) && d.Id.Contains(orgId)))
+                                    (lowLevels.Contains(d.Level) && d.Id.StartsWith(orgId)))
                         .ToListAsync(cancellationToken);
                 }
 
                 handlers = orgs1.Select(d => new FlowStepHandler
-                    {
-                        Key = d.Id,
-                        Value = d.Name,
-                        OrgId = d.Id,
-                        OrgName = d.Name
-                    })
+                {
+                    Key = d.Id,
+                    Value = d.Name,
+                    OrgId = d.Id,
+                    OrgName = d.Name
+                })
                     .ToList();
                 break;
             case EHandlerType.OrgType:
@@ -1013,12 +997,12 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     .ToListAsync(cancellationToken);
 
                 handlers = orgs2.Select(d => new FlowStepHandler
-                    {
-                        Key = d.Id,
-                        Value = d.Name,
-                        OrgId = d.Id,
-                        OrgName = d.Name
-                    })
+                {
+                    Key = d.Id,
+                    Value = d.Name,
+                    OrgId = d.Id,
+                    OrgName = d.Name
+                })
                     .ToList();
                 break;
             default:
@@ -1039,11 +1023,12 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         };
     }
 
-    private NextStepOption GetCsEndStepByTargetPrev(List<WorkflowStep> steps, WorkflowStep step)
+    private NextStepOption? GetCsEndStepByTargetPrev(List<WorkflowStep> steps, WorkflowStep step)
     {
         var prevStep = steps.FirstOrDefault(d => d.Id == step.PrevStepId);
-        if (prevStep is null)
-            throw new UserFriendlyException("未查找到会签上级节点");
+        //归档以后特提发起会签场景
+        if (prevStep is null || !prevStep.IsStartCountersign) return null;
+
         var text = prevStep.HandlerOrgIsCenter.Value
             ? "热线中心会签汇总"
             : $"{prevStep.HandlerOrgId.CalcOrgLevel().ToChinese()}级部门会签汇总";
@@ -1642,7 +1627,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 {
                     if (dto.BackToCountersignEnd)
                     {
-                        var csStartStep = GetCsLoopStartStep(workflow, currentStep);
+                        var csStartStep = _workflowDomainService.GetCsLoopStartStep(workflow.Steps, currentStep);
                         var prevStep = workflow.Steps.FirstOrDefault(d => d.Id == csStartStep.PrevStepId);
                         if (prevStep is null)
                             throw new UserFriendlyException("未查询到目标节点的前一节点");
@@ -1732,87 +1717,87 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         }
     }
 
-    public ISugarQueryable<WorkflowCountersign,Workflow,Order> QueryOrderCountersigns(QueryOrderCountersignDto dto, ISessionContext _sessionContext)
+    public ISugarQueryable<WorkflowCountersign, Workflow, Order> QueryOrderCountersigns(QueryOrderCountersignDto dto, ISessionContext _sessionContext)
     {
-		var Role = _sessionContext.Roles;
-
-		var query = _workflowCountersignRepository.Queryable()
-			.Includes(x => x.Members)
-			.LeftJoin<Workflow>((c, w) => c.WorkflowId == w.Id)
-			.InnerJoin<Order>((c, w, o) => w.ExternalId == o.Id)
-			.WhereIF(!string.IsNullOrEmpty(dto.Title), (c, w, o) => o.Title.Contains(dto.Title))
-			.WhereIF(!string.IsNullOrEmpty(dto.OrderNo), (c, w, o) => o.No == dto.OrderNo)
-			.WhereIF(!string.IsNullOrEmpty(dto.AcceptType), (c, w, o) => o.AcceptTypeCode == dto.AcceptType)//受理类型
-			.WhereIF(!string.IsNullOrEmpty(dto.Channel), (c, w, o) => o.SourceChannelCode == dto.Channel)//受理类型
-			.WhereIF(!string.IsNullOrEmpty(dto.Hotspot), (c, w, o) => o.HotspotSpliceName != null && o.HotspotSpliceName.Contains(dto.Hotspot))//热点类型
-			.WhereIF(!string.IsNullOrEmpty(dto.OrgId), (c, w, o) => c.FinisherOrgId == dto.OrgId) //接办部门
-			.WhereIF(dto.CounterSignType != null, (c, w, o) => c.CounterSignType == dto.CounterSignType) //会签类型
-		;
-
-		var rolePaiDan = _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan)?.SettingValue[0];//派单员角色
-		var seatsMonitor = _systemSettingCacheManager.GetSetting(SettingConstants.SeatsMonitor)?.SettingValue[0];//班长角色
-		var isAdmin = false;
-		var systemAdministrator = _systemSettingCacheManager.GetSetting(SettingConstants.SystemAdministrator)?.SettingValue[0];//管理员角色
-		if (!string.IsNullOrEmpty(systemAdministrator) && (_sessionContext.Roles.Contains(systemAdministrator) || _sessionContext.Roles.Contains(RoleSeedData.AdminRole)))
-			isAdmin = true;
-
-		//发起会签:班长角色能看所有会签信件;新增管理员能看到所有会签
-		//派单员角色只能看到自己发起的会签信件;
-		//承办部门用户能看到自己发起的和同级部门用户发起的会签件
-		if (dto.InitiatedCountersignature.HasValue && dto.InitiatedCountersignature == true)
-		{
-			if (_sessionContext.Roles.Any(p => p == seatsMonitor) || isAdmin)
-			{
-
-			}
-			else
-			if (_sessionContext.Roles.Any(p => p == rolePaiDan))
-			{
-				query = query.Where((c, w, o) => c.StarterId == _sessionContext.UserId);
-			}
-			else
-			{
-				query = query.Where((c, w, o) => c.StarterOrgId == _sessionContext.RequiredOrgId);
-			}
-		}
-
-		//会签已办(会签状态为已结束):
-		//班长角色能看所有已结束的会签信件;新增管理员能看到所有会签
-		//派单员不会办理会签件只会发起会签件所以这一点派单员角色可以忽略;
-		//承办部门用户能看到和同级部门用户已办理过的会签件
-		if (dto.HandleCountersignature.HasValue && dto.HandleCountersignature == true)
-		{
-			if (_sessionContext.Roles.Any(p => p == seatsMonitor) || isAdmin)
-			{
-				query = query.Where((c, w, o) => c.EndTime.HasValue);
-			}
-			else
-		   if (_sessionContext.Roles.Any(p => p == rolePaiDan))
-			{
-				query = query.Where((c, w, o) => c.Members.Any(m => m.Key == _sessionContext.RequiredOrgId) && c.EndTime.HasValue);
-			}
-			else
-			{
-				query = query.Where((c, w, o) => c.Members.Any(m => m.Key == _sessionContext.OrgId || m.Key == _sessionContext.RequiredOrgId) && c.EndTime.HasValue);
-			}
-		}
-
-		var items =  query
-			.OrderByDescending((c, w, o) => o.ExpiredTime);
-		return items;
+        var Role = _sessionContext.Roles;
+
+        var query = _workflowCountersignRepository.Queryable()
+            .Includes(x => x.Members)
+            .LeftJoin<Workflow>((c, w) => c.WorkflowId == w.Id)
+            .InnerJoin<Order>((c, w, o) => w.ExternalId == o.Id)
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), (c, w, o) => o.Title.Contains(dto.Title))
+            .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), (c, w, o) => o.No == dto.OrderNo)
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), (c, w, o) => o.AcceptTypeCode == dto.AcceptType)//受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.Channel), (c, w, o) => o.SourceChannelCode == dto.Channel)//受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), (c, w, o) => o.HotspotSpliceName != null && o.HotspotSpliceName.Contains(dto.Hotspot))//热点类型
+            .WhereIF(!string.IsNullOrEmpty(dto.OrgId), (c, w, o) => c.FinisherOrgId == dto.OrgId) //接办部门
+            .WhereIF(dto.CounterSignType != null, (c, w, o) => c.CounterSignType == dto.CounterSignType) //会签类型
+        ;
+
+        var rolePaiDan = _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan)?.SettingValue[0];//派单员角色
+        var seatsMonitor = _systemSettingCacheManager.GetSetting(SettingConstants.SeatsMonitor)?.SettingValue[0];//班长角色
+        var isAdmin = false;
+        var systemAdministrator = _systemSettingCacheManager.GetSetting(SettingConstants.SystemAdministrator)?.SettingValue[0];//管理员角色
+        if (!string.IsNullOrEmpty(systemAdministrator) && (_sessionContext.Roles.Contains(systemAdministrator) || _sessionContext.Roles.Contains(RoleSeedData.AdminRole)))
+            isAdmin = true;
+
+        //发起会签:班长角色能看所有会签信件;新增管理员能看到所有会签
+        //派单员角色只能看到自己发起的会签信件;
+        //承办部门用户能看到自己发起的和同级部门用户发起的会签件
+        if (dto.InitiatedCountersignature.HasValue && dto.InitiatedCountersignature == true)
+        {
+            if (_sessionContext.Roles.Any(p => p == seatsMonitor) || isAdmin)
+            {
+
+            }
+            else
+            if (_sessionContext.Roles.Any(p => p == rolePaiDan))
+            {
+                query = query.Where((c, w, o) => c.StarterId == _sessionContext.UserId);
+            }
+            else
+            {
+                query = query.Where((c, w, o) => c.StarterOrgId == _sessionContext.RequiredOrgId);
+            }
+        }
+
+        //会签已办(会签状态为已结束):
+        //班长角色能看所有已结束的会签信件;新增管理员能看到所有会签
+        //派单员不会办理会签件只会发起会签件所以这一点派单员角色可以忽略;
+        //承办部门用户能看到和同级部门用户已办理过的会签件
+        if (dto.HandleCountersignature.HasValue && dto.HandleCountersignature == true)
+        {
+            if (_sessionContext.Roles.Any(p => p == seatsMonitor) || isAdmin)
+            {
+                query = query.Where((c, w, o) => c.EndTime.HasValue);
+            }
+            else
+           if (_sessionContext.Roles.Any(p => p == rolePaiDan))
+            {
+                query = query.Where((c, w, o) => c.Members.Any(m => m.Key == _sessionContext.RequiredOrgId) && c.EndTime.HasValue);
+            }
+            else
+            {
+                query = query.Where((c, w, o) => c.Members.Any(m => m.Key == _sessionContext.OrgId || m.Key == _sessionContext.RequiredOrgId) && c.EndTime.HasValue);
+            }
+        }
+
+        var items = query
+            .OrderByDescending((c, w, o) => o.ExpiredTime);
+        return items;
     }
 
 
     #region private
 
-	/// <summary>
-	/// 查询流程业务模块
-	/// </summary>
-	/// <param name="code"></param>
-	/// <param name="cancellationToken"></param>
-	/// <returns></returns>
-	/// <exception cref="UserFriendlyException"></exception>
-	public async Task<WorkflowModule> GetWorkflowModuleAsync(string code, CancellationToken cancellationToken)
+    /// <summary>
+    /// 查询流程业务模块
+    /// </summary>
+    /// <param name="code"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    /// <exception cref="UserFriendlyException"></exception>
+    public async Task<WorkflowModule> GetWorkflowModuleAsync(string code, CancellationToken cancellationToken)
     {
         var wfModule = await _wfModuleCacheManager.GetWorkflowModuleAsync(code, cancellationToken);
         if (wfModule == null)

+ 2 - 2
src/Hotline.Application/Knowledge/KnowApplication.cs

@@ -87,8 +87,8 @@ namespace Hotline.Application.Knowledge
                 .Where(x => (x.Status == EKnowledgeStatus.Drafts && x.CreatorId == _sessionContext.UserId) || (x.Status != EKnowledgeStatus.Drafts))
                 .WhereIF(!string.IsNullOrEmpty(pagedDto.Title), x => x.Title.Contains(pagedDto.Title!))
                 .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), x => x.Title.Contains(pagedDto.Keyword!) || x.CreatorName.Contains(pagedDto.Keyword!) || x.CreatorOrgName.Contains(pagedDto.Keyword!) || x.SourceOrganize.Name.Contains(pagedDto.Keyword!))
-                .WhereIF(pagedDto.Status.HasValue && pagedDto.Status != EKnowledgeStatus.OffShelf && pagedDto.Status != EKnowledgeStatus.NewDrafts, x => x.Status == pagedDto.Status && ((x.ExpiredTime != null && x.ExpiredTime > DateTime.Now) || x.ExpiredTime == null))
-                .WhereIF(pagedDto.Status.HasValue && pagedDto.Status == EKnowledgeStatus.OffShelf, x => x.Status == pagedDto.Status || (x.ExpiredTime != null && x.ExpiredTime < DateTime.Now && x.Status != EKnowledgeStatus.Drafts))
+                .WhereIF(pagedDto.Status.HasValue && pagedDto.Status != EKnowledgeStatus.OffShelf && pagedDto.Status != EKnowledgeStatus.NewDrafts && pagedDto.Status != EKnowledgeStatus.All, x => x.Status == pagedDto.Status && ((x.ExpiredTime != null && x.ExpiredTime > DateTime.Now) || x.ExpiredTime == null))
+                .WhereIF(pagedDto.Status.HasValue && pagedDto.Status == EKnowledgeStatus.OffShelf , x => x.Status == pagedDto.Status || (x.ExpiredTime != null && x.ExpiredTime < DateTime.Now && x.Status != EKnowledgeStatus.Drafts))
                 .WhereIF(pagedDto.IsPublic.HasValue, x => x.IsPublic == pagedDto.IsPublic)
                 .WhereIF(!string.IsNullOrEmpty(pagedDto.Summary), x => x.Summary != null && x.Summary.Contains(pagedDto.Summary!))
                 .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.StartsWith(typeSpliceName)))

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

@@ -14,6 +14,7 @@ using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
 using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Dtos.Order.Publish;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Settings;
 using Hotline.Share.Requests;
@@ -355,5 +356,7 @@ namespace Hotline.Application.Orders
         Task SpecialVerify(OrderSpecialAddDto dto, Order order, CancellationToken cancellationToken);
 
         Task EndCountersign(EndCountersignDto dto, CancellationToken cancellationToken);
-	}
+        ISugarQueryable<OrderPublish> GetPublishedOrder(PublishedPagedRequest dto);
+        ISugarQueryable<Order> GetPublishOrderList(QueryOrderPublishDto dto);
+    }
 }

+ 87 - 1
src/Hotline.Application/Orders/OrderApplication.cs

@@ -73,6 +73,7 @@ using System.Linq.Dynamic.Core;
 using System.Threading;
 using Hotline.Application.CallCenter;
 using Hotline.Repository.SqlSugar.Orders;
+using Hotline.Share.Dtos.Order.Publish;
 
 namespace Hotline.Application.Orders;
 
@@ -239,7 +240,11 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         await _workflowDomainService.UpdateUnhandleExpiredTimeAsync(order.WorkflowId, expiredTimeConfig.ExpiredTime, cancellationToken);
 
         await _orderRepository.UpdateAsync(order, cancellationToken);
-    }
+
+        var orderDto = _mapper.Map<OrderDto>(order);
+        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
+	        cancellationToken: cancellationToken);
+	}
 
     // /// <summary>
     // /// 新增工单办理流程记录
@@ -668,6 +673,85 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         }
     }
 
+    /// <summary>
+    /// 获取待发布列表
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public ISugarQueryable<Order> GetPublishOrderList(QueryOrderPublishDto dto)
+    {
+        return _orderRepository.Queryable()
+            //.Includes(d => d.OrderPublish)
+            .Where(x => x.Status == EOrderStatus.Filed)
+            .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword!))
+            .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No))
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title))
+            //.WhereIF(dto.PubState == EPubState.Pub, d => d.Status >= EOrderStatus.Published)
+            //.WhereIF(dto.PubState == EPubState.NoPub, d => d.Status == EOrderStatus.Filed)
+            .WhereIF(!string.IsNullOrEmpty(dto.Channel), d => d.SourceChannelCode == dto.Channel)
+            .WhereIF(!string.IsNullOrEmpty(dto.OrderTag), d => d.OrderTagCode == dto.OrderTag!) //工单标签
+            .WhereIF(!string.IsNullOrEmpty(dto.CenterToOrgHandlerName), d => d.CenterToOrgHandlerName == dto.CenterToOrgHandlerName!) //派单人
+            .WhereIF(!string.IsNullOrEmpty(dto.NameOrNo), d => d.AcceptorName == dto.NameOrNo! || d.AcceptorStaffNo == dto.NameOrNo!) //受理人/坐席
+            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), d => d.ActualHandleOrgName.Contains(dto.ActualHandleOrgName)) //接办部门(综合查询模糊)
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), d => d.AcceptTypeCode == dto.AcceptType) //受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), d => d.HotspotSpliceName != null && d.HotspotSpliceName.Contains(dto.Hotspot))
+            .WhereIF(!string.IsNullOrEmpty(dto.FromPhone), d => d.FromPhone == dto.FromPhone) //来电号码
+                                                                                              //.WhereIF(!string.IsNullOrEmpty(dto.PubMan),
+                                                                                              //    d => d.AcceptorName.Contains(dto.PubMan!) || d.AcceptorStaffNo.Contains(dto.PubMan!))
+                                                                                              //.WhereIF(dto.PubRange == EPublicState.Pub, d => d.OrderPublish.PublishState)
+                                                                                              //.WhereIF(dto.PubRange == EPublicState.NoPub, d => !d.OrderPublish.PublishState)
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, d => d.Source == ESource.ProvinceStraight)
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, d => d.Source != ESource.ProvinceStraight)
+            .WhereIF(dto.FiledType != null && dto.FiledType == FiledType.CenterFiled, d => d.ProcessType == EProcessType.Zhiban)
+            .WhereIF(dto.FiledType != null && dto.FiledType == FiledType.OrgFiled, d => d.ProcessType == EProcessType.Jiaoban)
+            .WhereIF(dto.IsCountersign != null && dto.IsCountersign == true, d => d.CounterSignType != null)
+            .WhereIF(dto.IsCountersign != null && dto.IsCountersign == false, d => d.CounterSignType == null)
+            .WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptType))
+            .WhereIF(dto.HotspotIds.Any(), d => dto.HotspotIds.Contains(d.HotspotId))
+            //.WhereIF(dto.Resolve.HasValue, d => d.OrderPublish.Resolve == dto.Resolve)
+            .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
+            .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
+            .WhereIF(dto.FiledTimeStart.HasValue, d => d.FiledTime >= dto.FiledTimeStart)
+            .WhereIF(dto.FiledTimeEnd.HasValue, d => d.FiledTime <= dto.FiledTimeEnd)
+            .WhereIF(dto.QuerySelf.HasValue && dto.QuerySelf.Value, d => d.WaitForPublisherId == _sessionContext.RequiredUserId)
+            .WhereIF(dto.IsOverTime == true,
+                d => (d.ExpiredTime < DateTime.Now && d.Status < EOrderStatus.Filed) ||
+                     (d.ExpiredTime < d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //是 超期
+            .WhereIF(dto.IsOverTime == false,
+                d => (d.ExpiredTime > DateTime.Now && d.Status < EOrderStatus.Filed) ||
+                     (d.ExpiredTime > d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //否 超期
+            .OrderByDescending(d => d.FiledTime);
+    }
+
+    public ISugarQueryable<OrderPublish> GetPublishedOrder(PublishedPagedRequest dto)
+    {
+        return _orderPublishRepository.Queryable()
+            .Includes(x => x.Order)
+            .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Order.Title.StartsWith(dto.Keyword!))
+            .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.Order.No.Contains(dto.No!))
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Order.Title.Contains(dto.Title!))
+            .WhereIF(dto.CreationTimeStart.HasValue, d => d.Order.CreationTime >= dto.CreationTimeStart)
+            .WhereIF(dto.CreationTimeEnd.HasValue, d => d.Order.CreationTime <= dto.CreationTimeEnd)
+            .WhereIF(!string.IsNullOrEmpty(dto.FromPhone), d => d.Order.FromPhone == dto.FromPhone) //来电号码
+            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName),
+                d => d.Order.ActualHandleOrgName.Contains(dto.ActualHandleOrgName)) //接办部门(综合查询模糊)
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), d => d.Order.AcceptTypeCode == dto.AcceptType) //受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), d => d.Order.HotspotSpliceName != null && d.Order.HotspotSpliceName.Contains(dto.Hotspot))
+            .WhereIF(!string.IsNullOrEmpty(dto.PublishName), d => d.CreatorName.Contains(dto.PublishName!))
+            .WhereIF(!string.IsNullOrEmpty(dto.NameOrNo),
+                d => d.Order.AcceptorName == dto.NameOrNo! || d.Order.AcceptorStaffNo == dto.NameOrNo!) //受理人/坐席
+            .WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime)
+            .WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime)
+            .WhereIF(dto.Resolve.HasValue, x => x.Resolve == dto.Resolve)
+            .WhereIF(dto.IsOverTime == true,
+                d => (d.Order.ExpiredTime < DateTime.Now && d.Order.Status < EOrderStatus.Filed) ||
+                     (d.Order.ExpiredTime < d.Order.ActualHandleTime && d.Order.Status >= EOrderStatus.Filed)) //是 超期
+            .WhereIF(dto.IsOverTime == false,
+                d => (d.Order.ExpiredTime > DateTime.Now && d.Order.Status < EOrderStatus.Filed) ||
+                     (d.Order.ExpiredTime > d.Order.ActualHandleTime && d.Order.Status >= EOrderStatus.Filed)) //否 超期
+            .OrderByDescending(d => d.CreationTime);
+    }
+
     /// <summary>
     /// 发布量统计(按账号)
     /// </summary>
@@ -2727,10 +2811,12 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         if (order == null)
         {
             order = _mapper.Map<Order>(dto);
+            
             order.InitId();
             if (files != null && files.Any())
                 order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
             await _orderDomainService.AddAsync(order, cancellationToken: cancellationToken);
+          
         }
         else
         {

+ 1 - 0
src/Hotline.Application/Orders/OrderScreenHandler/OrderScreenEndWorkflowHandler.cs

@@ -74,6 +74,7 @@ public class OrderScreenEndWorkflowHandler : INotificationHandler<EndWorkflowNot
 						else {
 							var screenSatisfy = new Kv() { Key = "-1", Value = "视为满意" };
 							visitDetail.OrgProcessingResults = screenSatisfy;
+							visitDetail.OrgNoSatisfiedReason = new List<Kv>();
 							//visitDetail.OrgHandledAttitude = screenSatisfy;
 							await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
 							// 修改主表当前评价结果

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

@@ -227,7 +227,8 @@ namespace Hotline.Application.Orders
                 .Includes(x => x.SecondaryHandling)
                 .Where(x => x.OrderVisit.Order.IsProvince == false)
                 .LeftJoin<OrderScreen>((x, s) => x.Id == s.VisitDetailId && s.Status < EScreenStatus.End && s.IsDeleted == false)
-                .Where((x, s) => s.Id == null && (x.SecondaryHandling.State == ESecondaryHandlingState.NotApply || x.SecondaryHandling.Id == null))
+                //.Where((x, s) => s.Id == null && (x.SecondaryHandling.State == ESecondaryHandlingState.NotApply || x.SecondaryHandling.Id == null))
+                .Where(x=> SqlFunc.Subqueryable<OrderSecondaryHandling>().Where(osh => osh.VisitDetailId == x.Id &&  osh.State == ESecondaryHandlingState.NotApply).NotAny())
                 //.Where(x => x.OrderVisit.VisitTime < dto.CreationTimeEnd && x.OrderVisit.VisitTime > dto.CreationTimeStart)
                 .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.OrderVisit.Order!.No!.Contains(dto.No!))
                 .WhereIF(dto.IsProvince.HasValue, x => x.OrderVisit.Order!.IsProvince == dto.IsProvince)
@@ -245,7 +246,8 @@ namespace Hotline.Application.Orders
                 .WhereIF(!string.IsNullOrEmpty(dto.OrgProcessingResults), x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == dto.OrgProcessingResults)
                 .WhereIF(!string.IsNullOrEmpty(dto.OrgHandledAttitude), x => SqlFunc.JsonListObjectAny(x.OrgHandledAttitude, "Key", dto.OrgHandledAttitude))
                 .WhereIF(!string.IsNullOrEmpty(dto.OrgNoSatisfiedReason), x => SqlFunc.JsonField(x.OrgNoSatisfiedReason, "Key") == dto.OrgNoSatisfiedReason)
-                .Where((x, s) => x.OrderVisit.VisitState == EVisitState.Visited && x.OrderVisit.IsCanHandle)
+                .Where(x => SqlFunc.Subqueryable<OrderVisit>().Where(ov => ov.Id == x.VisitId && ov.VisitState == EVisitState.Visited && ov.IsCanHandle).Any())
+                //.Where((x, s) => x.OrderVisit.VisitState == EVisitState.Visited && x.OrderVisit.IsCanHandle)
                 .WhereIF(!isAdmin, (x, s) => (x.OrderVisit.Order.CounterSignType ==  ECounterSignType.Department || x.OrderVisit.Order.CounterSignType == null) && x.VisitOrgCode.StartsWith(_sessionContext.OrgId))
                 ;
             if (_sessionContext.OrgId != null && !_sessionContext.OrgIsCenter)

+ 5 - 5
src/Hotline.Application/Subscribers/DatasharingSubscriber.cs

@@ -327,7 +327,7 @@ namespace Hotline.Application.Subscribers
                 }
 
                 order.CurrentStepName = workflow.CurrentStepName;
-                order.CurrentStepCode=workflow.CurrentStepCode;
+                order.CurrentStepCode = workflow.CurrentStepCode;
                 order.CurrentStepId = workflow.CurrentStepId;
                 order.CurrentStepCreateTime = workflow.CurrentStepCreateTime;
                 order.CurrentHandleTime = workflow.CurrentHandleTime;
@@ -506,9 +506,9 @@ namespace Hotline.Application.Subscribers
             //CityBaseConfiguration cityBase = JsonConvert.DeserializeObject<CityBaseConfiguration>(setting);
             SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
             await _workflowApplication.HandleToEndAsync(orderScreen.WorkflowId, "省上推送甄别结果", null,
-                dto.ProvinceScreenResult.AuditResult
+                 reviewResult: dto.ProvinceScreenResult.AuditResult
                     ? Share.Enums.FlowEngine.EReviewResult.Approval
-                    : Share.Enums.FlowEngine.EReviewResult.Failed, cancellationToken);
+                    : Share.Enums.FlowEngine.EReviewResult.Failed, cancellationToken: cancellationToken);
             orderScreen.Status = dto.ProvinceScreenResult.AuditResult ? Share.Enums.Order.EScreenStatus.End : Share.Enums.Order.EScreenStatus.Refuse;
             //if (orderScreen.Status == Share.Enums.Order.EScreenStatus.End)
             //{
@@ -783,7 +783,7 @@ namespace Hotline.Application.Subscribers
 
                     SessionContextCreator.CreateSessionContext(_sessionContextProvider, dto.Source);
                     await _workflowApplication.HandleToEndAsync(orderDelay.WorkflowId, dto.Opinion, dto.Files,
-                        dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed, cancellationToken);
+                      reviewResult: dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed, cancellationToken: cancellationToken);
                 }
             }
         }
@@ -844,7 +844,7 @@ namespace Hotline.Application.Subscribers
                     }
                     else
                     {
-                        await _workflowApplication.HandleToEndAsync(order.WorkflowId, dto.Opinion, dto.Files, cancellationToken: cancellationToken);
+                        await _workflowApplication.HandleToEndAsync(order.WorkflowId, dto.Opinion, dto.Files, expiredTime: order.ExpiredTime, cancellationToken: cancellationToken);
                     }
 
                     break;

+ 8 - 1
src/Hotline.Application/Subscribers/InternalCapSubscriber.cs

@@ -15,6 +15,7 @@ using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Push;
 using Hotline.Share.Mq;
 using Hotline.Users;
+using MapsterMapper;
 using MediatR;
 using Microsoft.AspNetCore.Http;
 using NPOI.SS.Formula.Functions;
@@ -37,6 +38,7 @@ namespace Hotline.Application.Subscribers
         private readonly IRepository<OrderDelay> _orderDelayRepository;
         private readonly IWorkflowDomainService _workflowDomainService;
         private readonly ICalcExpireTime _expireTime;
+        private readonly IMapper _mapper;
 
 		public InternalCapSubscriber(
             IOrderRepository orderRepository,
@@ -48,7 +50,8 @@ namespace Hotline.Application.Subscribers
             IOrderApplication orderApplication,
             IRepository<OrderDelay> orderDelayRepository,
             IWorkflowDomainService workflowDomainService,
-            ICalcExpireTime expireTime
+            ICalcExpireTime expireTime,
+            IMapper mapper
 			)
         {
             _orderRepository = orderRepository;
@@ -61,6 +64,7 @@ namespace Hotline.Application.Subscribers
             _orderDelayRepository = orderDelayRepository;
             _workflowDomainService = workflowDomainService;
             _expireTime = expireTime;
+            _mapper = mapper;
 		}
 
         /// <summary>
@@ -330,6 +334,9 @@ namespace Hotline.Application.Subscribers
 					}
 					order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
 					_capPublisher.PublishDelay(order.ExpiredTime.Value - DateTime.Now.AddHours(1), EventNames.HotlineOrderAutomaticDelay, new PublishAutomaticDelayDto() { OrderId = order.Id });
+					var orderDto = _mapper.Map<OrderDto>(order);
+					await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
+						cancellationToken: cancellationToken);
 				}
 			}
 		

+ 17 - 18
src/Hotline.Repository.SqlSugar/CallCenter/CallNativeRepository.cs

@@ -37,24 +37,23 @@ public class CallNativeRepository : BaseRepository<CallNative>, ICallNativeRepos
         }
 
         var list = await Db.Reportable(dts).ToQueryable<DateTime>()
-            .LeftJoin<CallNative>((it, o) => o.BeginIvrTime >= it.ColumnName && o.BeginIvrTime < it.ColumnName.AddHours(1) && o.Direction == ECallDirection.In && o.CallState != ECallState.Invalid)
-             //.Where((it, o) => o.CallDirection == ECallDirection.In)
-             .WhereIF(!string.IsNullOrEmpty(source), (it, o) => o.ToNo == source)
-            .GroupBy((it, o) => it.ColumnName)
-            .Select((it, o) => new TrCallHourDto()
-            {
-                DateTimeTo = it.ColumnName,
-                Hour = it.ColumnName.Hour, //小时段
-                EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.AnsweredTime != null && o.Duration >= effectiveTimes, 1, 0)),//有效接通
-                ConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.AnsweredTime != null && o.Duration <= connectByeTimes, 1, 0)), //接通秒挂
-                NoConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.AnsweredTime == null && o.RingDuration <= noConnectByeTimes && o.RingDuration > 0, 1, 0)), //未接通秒挂
-                QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallState == ECallState.NotAcceptedHang, 1, 0)), //队列挂断
-                IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallState == ECallState.IVRNoAccept, 1, 0)), //IVR挂断
-            })
-            .MergeTable()
-            .OrderBy(x => x.Hour)
-            .ToListAsync();
-
+             .LeftJoin<CallNative>((it, o) => o.BeginIvrTime >= it.ColumnName && o.BeginIvrTime < it.ColumnName.AddHours(1) && o.Direction == ECallDirection.In && o.CallState != ECallState.Invalid)
+              //.Where((it, o) => o.CallDirection == ECallDirection.In)
+              .WhereIF(!string.IsNullOrEmpty(source), (it, o) => o.ToNo == source)
+             .GroupBy((it, o) => it.ColumnName)
+             .Select((it, o) => new TrCallHourDto()
+             {
+                 DateTimeTo = it.ColumnName,
+                 Hour = it.ColumnName.Hour, //小时段
+                 EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.AnsweredTime != null && o.Duration >= effectiveTimes, 1, 0)),//有效接通
+                 ConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.AnsweredTime != null && o.Duration <= connectByeTimes, 1, 0)), //接通秒挂
+                 NoConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.AnsweredTime == null && o.RingDuration <= noConnectByeTimes && o.RingDuration > 0, 1, 0)), //未接通秒挂
+                 QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallState == ECallState.NotAcceptedHang, 1, 0)), //队列挂断
+                 IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallState == ECallState.IVRNoAccept, 1, 0)), //IVR挂断
+             })
+             .MergeTable()
+             .OrderBy(x => x.Hour)
+             .ToListAsync();
         var resultList = list.GroupBy(x => x.Hour)
              .Select(x => new TrCallHourDto()
              {

+ 50 - 35
src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs

@@ -19,9 +19,11 @@ using System.Linq.Dynamic.Core;
 using System.Net;
 using System.Reflection;
 using System.Reflection.Emit;
+using Hotline.Caching.Interfaces;
 using XF.Domain.Authentications;
 using XF.Domain.Dependency;
 using XF.Domain.Repository;
+using System.Collections.Generic;
 
 namespace Hotline.Repository.SqlSugar.Orders
 {
@@ -32,20 +34,23 @@ namespace Hotline.Repository.SqlSugar.Orders
         private readonly IRepository<OrderVisit> _orderVisitRepository;
         private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
         private readonly ISessionContext _sessionContext;
+        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
 
-        public OrderRepository(ISugarUnitOfWork<HotlineDbContext> uow,
+		public OrderRepository(ISugarUnitOfWork<HotlineDbContext> uow,
             IDataPermissionFilterBuilder dataPermissionFilterBuilder,
             IRepository<OrderSendBackAudit> orderSendBackAuditRepository,
             IRepository<OrderVisit> orderVisitRepository,
             ISessionContext sessionContext,
-            IRepository<OrderVisitDetail> orderVisitDetailRepository
-            ) : base(uow, dataPermissionFilterBuilder)
+            IRepository<OrderVisitDetail> orderVisitDetailRepository,
+            ISystemSettingCacheManager systemSettingCacheManager
+			) : base(uow, dataPermissionFilterBuilder)
         {
             _dataPermissionFilterBuilder = dataPermissionFilterBuilder;
             _orderSendBackAuditRepository = orderSendBackAuditRepository;
             _orderVisitRepository = orderVisitRepository;
             _sessionContext = sessionContext;
             _orderVisitDetailRepository = orderVisitDetailRepository;
+            _systemSettingCacheManager = systemSettingCacheManager;
 
         }
 
@@ -1265,16 +1270,11 @@ namespace Hotline.Repository.SqlSugar.Orders
                 .WhereIF(dto.ActualHandleTimeEnd.HasValue, x => x.OrderVisit.Order.ActualHandleTime <= dto.ActualHandleTimeEnd)//办结时间结束
                 .WhereIF(dto.VisitTimeStart.HasValue, x => x.OrderVisit.VisitTime >= dto.VisitTimeStart) //回访时间
                 .WhereIF(dto.VisitTimeEnd.HasValue, x => x.OrderVisit.VisitTime < dto.VisitTimeEnd) //回访时间
-                .OrderByIF(string.IsNullOrEmpty(dto.SortField),x=>x.OrderVisit.VisitTime,OrderByType.Desc)
-                .OrderByIF(dto is { SortField: "creationTime", SortRule:0 },x=>x.OrderVisit.Order.CreationTime,OrderByType.Asc) //受理时间升序
-                .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.OrderVisit.Order.CreationTime, OrderByType.Desc) //受理时间降序
-                .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.OrderVisit.VisitTime, OrderByType.Asc) //回访时间升序
-                .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.OrderVisit.VisitTime, OrderByType.Desc) //回访时间降序
-                .OrderByIF(dto is { SortField: "filedTime", SortRule:0 },x=>x.OrderVisit.Order.FiledTime,OrderByType.Asc) //办结时间升序
-                .OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.OrderVisit.Order.FiledTime, OrderByType.Desc) //办结时间降序
+
                 .Select(x => new OrgVisitDetailListResp()
                 {
-                    Id = x.OrderVisit.Order.Id,
+                    Id =  x.Id,
+                    OrderId = x.OrderVisit.Order.Id,
                     VisitId = x.OrderVisit.Id,
                     No = x.OrderVisit.No,
                     ReTransactNum = x.OrderVisit.Order.ReTransactNum,
@@ -1295,7 +1295,13 @@ namespace Hotline.Repository.SqlSugar.Orders
                     FiledTime = x.OrderVisit.Order.FiledTime,
                     VisitOrgName = x.VisitOrgName,
                     ActualHandleOrgName = x.OrderVisit.Order.ActualHandleOrgName
-                });
+                }).MergeTable().OrderByIF(string.IsNullOrEmpty(dto.SortField), x => x.VisitTime, OrderByType.Desc)
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, x => x.CreationTime, OrderByType.Asc) //受理时间升序
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.CreationTime, OrderByType.Desc) //受理时间降序
+                .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.VisitTime, OrderByType.Asc) //回访时间升序
+                .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.VisitTime, OrderByType.Desc) //回访时间降序
+                .OrderByIF(dto is { SortField: "filedTime", SortRule: 0 }, x => x.FiledTime, OrderByType.Asc) //办结时间升序
+                .OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.FiledTime, OrderByType.Desc); //办结时间降序;
 
         }
 
@@ -1321,16 +1327,11 @@ namespace Hotline.Repository.SqlSugar.Orders
                 .WhereIF(dto.TypeId is 1, x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == dto.DateValue)
                 .WhereIF(dto.TypeId is 2, x => SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == dto.DateValue)
                 .WhereIF(!string.IsNullOrEmpty(dto.LineNum), x => x.OrderVisit.Order.CallRecord.Gateway == dto.LineNum)
-                .OrderByIF(string.IsNullOrEmpty(dto.SortField), x => x.OrderVisit.VisitTime, OrderByType.Desc)
-                .OrderByIF(dto is { SortField: "startTime", SortRule: 0 }, x => x.OrderVisit.Order.StartTime, OrderByType.Asc) //受理时间升序
-                .OrderByIF(dto is { SortField: "startTime", SortRule: 1 }, x => x.OrderVisit.Order.StartTime, OrderByType.Desc) //受理时间降序
-                .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.OrderVisit.VisitTime, OrderByType.Asc) //回访时间升序
-                .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.OrderVisit.VisitTime, OrderByType.Desc) //回访时间降序
-                .OrderByIF(dto is { SortField: "filedTime", SortRule: 0 }, x => x.OrderVisit.Order.FiledTime, OrderByType.Asc) //办结时间升序
-                .OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.OrderVisit.Order.FiledTime, OrderByType.Desc) //办结时间降序
+
                 .Select(x => new OrgVisitDetailListResp
                 {
-                    Id = x.OrderVisit.Order.Id,
+                    Id = x.Id,
+                    OrderId = x.OrderVisit.Order.Id,
                     VisitId = x.OrderVisit.Id,
                     No = x.OrderVisit.No,
                     ReTransactNum = x.OrderVisit.Order.ReTransactNum,
@@ -1339,7 +1340,7 @@ namespace Hotline.Repository.SqlSugar.Orders
                     HotspotSpliceName = x.OrderVisit.Order.HotspotSpliceName,
                     OrgLevelOneName = x.OrderVisit.Order.OrgLevelOneName,
                     CurrentHandleOrgName = x.OrderVisit.Order.CurrentHandleOrgName,
-                    CreationTime = x.CreationTime,
+                    CreationTime = x.OrderVisit.Order.CreationTime,
                     Title = x.OrderVisit.Order.Title,
                     VisitUser = x.OrderVisit.Employee.Name,
                     VisitType = x.OrderVisit.VisitType,
@@ -1349,7 +1350,14 @@ namespace Hotline.Repository.SqlSugar.Orders
                     FileOpinion = x.OrderVisit.Order.FileOpinion,
                     FiledTime = x.OrderVisit.Order.FiledTime,
                     VisitOrgName = x.VisitOrgName
-                });
+                }).MergeTable()
+                .OrderByIF(string.IsNullOrEmpty(dto.SortField), x => x.VisitTime, OrderByType.Desc)
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, x => x.CreationTime, OrderByType.Asc) //受理时间升序
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.CreationTime, OrderByType.Desc) //受理时间降序
+                .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.VisitTime, OrderByType.Asc) //回访时间升序
+                .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.VisitTime, OrderByType.Desc) //回访时间降序
+                .OrderByIF(dto is { SortField: "filedTime", SortRule: 0 }, x => x.FiledTime, OrderByType.Asc) //办结时间升序
+                .OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.FiledTime, OrderByType.Desc); //办结时间降序;
         }
 
 		/// <summary>
@@ -1357,15 +1365,17 @@ namespace Hotline.Repository.SqlSugar.Orders
 		/// </summary>
 		/// <param name="dto"></param>
 		/// <returns></returns>
-		public ISugarQueryable<OrgVisitDetailListResp> OrgVisitDetailFiltrationList(OrgVisitDetailListReq dto)
+		public ISugarQueryable<OrgVisitDetailListResp> OrgVisitDetailFiltrationList(OrgVisitDetailListReq dto, string orgId)
 		{
 			var IsCenter = _sessionContext.OrgIsCenter;
+			var hiddenOrder = _systemSettingCacheManager.GetSetting(SettingConstants.OrgVisitDetailHiddenOrderNo).SettingValue;
 
 			return _orderVisitDetailRepository.Queryable()
 				.Includes(x => x.OrderVisit, x => x.Order)
 				.Includes(x => x.OrderVisit, x => x.Employee)
 				.Where(x => x.OrderVisit.VisitState == EVisitState.Visited && x.VisitTarget == EVisitTarget.Org)
-				.WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContext.RequiredOrgId))
+                .WhereIF(hiddenOrder.Any(), x =>!hiddenOrder.Contains(x.OrderVisit.Order.No))
+                .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(orgId))
 				.WhereIF(dto.OrgVisitStatisticsType.HasValue, x => x.OrderVisit.Order.ProcessType == (EProcessType)((int)dto.OrgVisitStatisticsType))
 				.WhereIF(dto.Keyword.NotNullOrEmpty(), x => x.OrderVisit.Order.Title.Contains(dto.Keyword)) // 根据关键字匹配
 				.WhereIF(dto.TypeCode != 0, x => x.OrderVisit.Order.IdentityType == (EIdentityType)dto.TypeCode)
@@ -1382,18 +1392,15 @@ namespace Hotline.Repository.SqlSugar.Orders
 				.WhereIF(dto.ActualHandleTimeEnd.HasValue, x => x.OrderVisit.Order.ActualHandleTime <= dto.ActualHandleTimeEnd)//办结时间结束
 				.WhereIF(dto.VisitTimeStart.HasValue, x => x.OrderVisit.VisitTime >= dto.VisitTimeStart) //回访时间
 				.WhereIF(dto.VisitTimeEnd.HasValue, x => x.OrderVisit.VisitTime < dto.VisitTimeEnd) //回访时间
-				.OrderByIF(string.IsNullOrEmpty(dto.SortField), x => x.OrderVisit.VisitTime, OrderByType.Desc)
-				.OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, x => x.OrderVisit.Order.CreationTime, OrderByType.Asc) //受理时间升序
-				.OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.OrderVisit.Order.CreationTime, OrderByType.Desc) //受理时间降序
-				.OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.OrderVisit.VisitTime, OrderByType.Asc) //回访时间升序
-				.OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.OrderVisit.VisitTime, OrderByType.Desc) //回访时间降序
-				.OrderByIF(dto is { SortField: "filedTime", SortRule: 0 }, x => x.OrderVisit.Order.FiledTime, OrderByType.Asc) //办结时间升序
-				.OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.OrderVisit.Order.FiledTime, OrderByType.Desc) //办结时间降序
-				.Where(x=> SqlFunc.JsonField(x.OrgProcessingResults, "Value") != "不满意" && SqlFunc.JsonField(x.OrgProcessingResults, "Value") != "非常不满意" && SqlFunc.JsonField(x.OrgProcessingResults, "Value") != "未做评价")
-				.Where(x=>x.VisitOrgCode.StartsWith(_sessionContext.RequiredOrgId))
+                    //特殊需求:要求新增查询条件【一级部门】,如查询【富顺县人民政府】则显示该一级部门以及下级部门的工单数据
+                .WhereIF(!string.IsNullOrEmpty(dto.LevelOneOrg), x=> x.OrderVisit.Order.OrgLevelOneName == dto.LevelOneOrg || x.OrderVisit.Order.OrgLevelOneCode == dto.LevelOneOrg)
+				
+				.Where(x=> SqlFunc.JsonField(x.OrgProcessingResults, "Key") != "2" && SqlFunc.JsonField(x.OrgProcessingResults, "Key") != "-1" && SqlFunc.JsonField(x.OrgProcessingResults, "Key") != "0" && SqlFunc.JsonField(x.OrgProcessingResults, "Key") != "7")
+				.Where(x=>x.VisitOrgCode.StartsWith(orgId))
 				.Select(x => new OrgVisitDetailListResp()
 				{
-					Id = x.OrderVisit.Order.Id,
+					Id = x.Id,
+                    OrderId = x.OrderVisit.Order.Id,
 					VisitId = x.OrderVisit.Id,
 					No = x.OrderVisit.No,
 					ReTransactNum = x.OrderVisit.Order.ReTransactNum,
@@ -1414,7 +1421,15 @@ namespace Hotline.Repository.SqlSugar.Orders
 					FiledTime = x.OrderVisit.Order.FiledTime,
 					VisitOrgName = x.VisitOrgName,
 					ActualHandleOrgName = x.OrderVisit.Order.ActualHandleOrgName
-				});
+				}).MergeTable()
+                .OrderByIF(string.IsNullOrEmpty(dto.SortField), x => x.VisitTime, OrderByType.Desc)
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, x => x.CreationTime, OrderByType.Asc) //受理时间升序
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.CreationTime, OrderByType.Desc) //受理时间降序
+                .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.VisitTime, OrderByType.Asc) //回访时间升序
+                .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.VisitTime, OrderByType.Desc) //回访时间降序
+                .OrderByIF(dto is { SortField: "filedTime", SortRule: 0 }, x => x.FiledTime, OrderByType.Asc) //办结时间升序
+                .OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.FiledTime, OrderByType.Desc) //办结时间降序
+                ;
 
 		}
 	}

+ 50 - 0
src/Hotline.Share/Dtos/JudicialManagement/JudicialManagementAddOrderDto.cs

@@ -1,6 +1,7 @@
 using Hotline.Share.Dtos.File;
 using Hotline.Share.Enums.JudicialManagement;
 using Hotline.Share.Enums.Order;
+using Hotline.Share.Enums.Settings;
 
 namespace Hotline.Share.Dtos.JudicialManagement
 {
@@ -193,6 +194,55 @@ namespace Hotline.Share.Dtos.JudicialManagement
         /// </summary>
         public string IncidentAddressText => IncidentAddress();
 
+        /// <summary>
+        /// 交办时间
+        /// </summary>
+        public DateTime? CenterToOrgTime {  get; set; }
+
+        /// <summary>
+        /// 接办部门
+        /// </summary>
+        public string? ActualHandleOrgName {  get; set; }
+
+        /// <summary>
+        /// 接办时间
+        /// </summary>
+        public DateTime? ActualHandleTime {  get; set; }
+
+        /// <summary>
+        /// 办理时间限制(如:24小时、7个工作日)
+        /// </summary>
+        public string? TimeLimit { get; set; }
+
+        public int? TimeLimitCount { get; set; }
+
+        public ETimeType? TimeLimitUnit { get; set; }
+
+        /// <summary>
+        /// 工单期满时间
+        /// </summary>
+        public DateTime? ExpiredTime {  get; set; }
+
+        /// <summary>
+        /// 部门是否解决
+        /// </summary>
+        public bool IsResolved { get; set; }
+
+        /// <summary>
+        /// 部门处理结果
+        /// </summary>
+        public string IsResolvedText => IsResolved ? "已解决" : "未解决";
+
+        /// <summary>
+        /// 中心意见
+        /// </summary>
+        public string? CenterOpinion { get; set; }
+
+        /// <summary>
+        /// 承办意见
+        /// </summary>
+        public string? FileOpinion { get; set; }
+
         /// <summary>
         /// 组装省市区
         /// </summary>

+ 9 - 4
src/Hotline.Share/Dtos/Knowledge/KnowledgeDto.cs

@@ -33,10 +33,15 @@ namespace Hotline.Share.Dtos.Knowledge
     /// </summary>
     public class AddKnowledgeDto : KnowledgeDto
     {
-        /// <summary>
-        /// 知识Code
-        /// </summary>
-        public string Code { get; set; }
+	    /// <summary>
+	    /// 知识来源
+	    /// </summary>
+	    public string? Source { get; set; }
+
+		/// <summary>
+		/// 知识Code
+		/// </summary>
+		public string Code { get; set; }
 
         /// <summary>
         /// 标签名称

+ 8 - 1
src/Hotline.Share/Dtos/Knowledge/KnowledgeTypeDto.cs

@@ -77,5 +77,12 @@
         /// 树形分类
         /// </summary>
         public List<TreeListDto> TreeLists { get; set; } = new();
-    }
+
+        /// <summary>
+        /// 子级
+        /// </summary>
+        public List<KnowledgeTypeDto> children { get; set; }
+
+        public int KnowledgeNum { get; set; }
+	}
 }

+ 9 - 4
src/Hotline.Share/Dtos/Order/OrderBiDto.cs

@@ -279,10 +279,15 @@ namespace Hotline.Share.Dtos.Order
 
 	public class OrgVisitDetailListResp
 	{
-		/// <summary>
-		/// 工单ID
-		/// </summary>
-		public string Id { get; set; }
+        /// <summary>
+        /// 回访子ID
+        /// </summary>
+        public string Id { get; set; }
+
+        /// <summary>
+        /// 工单ID
+        /// </summary>
+        public string OrderId { get; set; }
 
 		/// <summary>
 		/// 回访ID

+ 9 - 0
src/Hotline.Share/Dtos/Order/OrderSpecialDto.cs

@@ -477,4 +477,13 @@ namespace Hotline.Share.Dtos.Order
 
 		public OrderSpecialDto OrderSpecial { get; set; }
 	}
+
+	public class OrgBatchSpecialDto
+	{
+		public string OrgId { get; set; }
+
+		public DateTime StartTime { get; set; }
+
+		public DateTime EndTime { get; set; }
+	}
 }

+ 4 - 0
src/Hotline.Share/Dtos/Order/Publish/QueryOrderPublishDto.cs

@@ -117,4 +117,8 @@ public record QueryOrderPublishDto : PagedKeywordRequest
 	/// </summary>
 	public bool? IsOverTime { get; set; }
 
+    /// <summary>
+    /// 查询批次
+    /// </summary>
+    public int QueryIndex { get; set; }
 }

+ 39 - 2
src/Hotline.Share/Dtos/WebPortal/GetOrderCodePwd.cs

@@ -1,4 +1,5 @@
-using Hotline.Share.Enums.Order;
+using Hotline.Share.Dtos.File;
+using Hotline.Share.Enums.Order;
 using Hotline.Share.Requests;
 
 namespace Hotline.Share.Dtos.WebPortal
@@ -39,7 +40,7 @@ namespace Hotline.Share.Dtos.WebPortal
         /// <summary>
         /// 来电/信人身份
         /// </summary>
-        public EIdentityType? IdentityType { get; set; } 
+        public EIdentityType? IdentityType { get; set; }
 
         /// <summary>
         /// 信件编号
@@ -139,6 +140,22 @@ namespace Hotline.Share.Dtos.WebPortal
 
     }
 
+    /// <summary>
+    /// 办件摘编列表数据
+    /// </summary>
+    public class OrderListReturnAllDto
+    {
+        /// <summary>
+        /// 总数
+        /// </summary>
+        public int Total { get; set; }
+
+        /// <summary>
+        /// 数据对象
+        /// </summary>
+        public IReadOnlyList<OrderListDto> Data { get; set; }
+    }
+
     /// <summary>
     /// 办件摘编列表数据
     /// </summary>
@@ -154,6 +171,11 @@ namespace Hotline.Share.Dtos.WebPortal
         /// </summary>
         public int PageCount { get; set; }
 
+        /// <summary>
+        /// 总条数
+        /// </summary>
+        public int Total { get; set; }
+
         /// <summary>
         /// 数据对象
         /// </summary>
@@ -269,6 +291,11 @@ namespace Hotline.Share.Dtos.WebPortal
         /// 一级部门名称
         /// </summary>
         public string? OrgLevelOneName { get; set; }
+
+        /// <summary>
+        /// 附件
+        /// </summary>
+        public List<FileJson>? FileJson { get; set; }
     }
 
     /// <summary>
@@ -404,4 +431,14 @@ namespace Hotline.Share.Dtos.WebPortal
         /// </summary>
         public IReadOnlyList<OrderFormCount> formFileCount { get; set; }
     }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class GetVailDataDto()
+    {
+        public string Key { get; set; }
+
+        public string Value { get; set; }
+    }
 }

+ 7 - 1
src/Hotline.Share/Enums/KnowledgeBase/EKnowledgeStatus.cs

@@ -7,9 +7,15 @@ namespace Hotline.Share.Enums.KnowledgeBase;
 /// </summary>
 public enum EKnowledgeStatus
 {
+	/// <summary>
+	/// 全部
+	/// </summary>
+	[Description("全部")]
+	All = -1,
+
 	/// <summary>
 	/// 待提交
-/// </summary>
+	/// </summary>
 	[Description("待提交")]
     Drafts = 0,
 

+ 10 - 0
src/Hotline.Share/Requests/PagedKeywordRequest.cs

@@ -224,6 +224,11 @@ public record PublishedPagedRequest : PagedKeywordRequest
     /// 是否超期
     /// </summary>
     public bool? IsOverTime { get; set; }
+
+    /// <summary>
+    /// 查询批次
+    /// </summary>
+    public int QueryIndex { get; set; }
 }
 
 public record HotspotSubtotalReportPagedRequest : ReportPagedRequest
@@ -432,6 +437,11 @@ public record TimeSharingPagedKeywordRequest : PagedKeywordRequest
 
 public record OrgVisitDetailListReq: PagedKeywordRequest
 {
+    /// <summary>
+    /// 一级部门(id或名称)
+    /// </summary>
+    public string? LevelOneOrg { get; set; }
+
     /// <summary>
     /// 部门分类
     /// </summary>

+ 1 - 1
src/Hotline/Ai/CallOut/CallOutTemplate.cs

@@ -10,7 +10,7 @@ namespace Hotline.Ai.CallOut
 
         public bool IsEnable { get; set; }
 
-        [SugarColumn(ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDataType = "text")]
         public string TemplateContent { get; set; }
 
         [Navigate(NavigateType.OneToMany, nameof(CallOutTask.CallOutTemplateId))]

+ 5 - 0
src/Hotline/Article/Bulletin.cs

@@ -93,6 +93,11 @@ namespace Hotline.Article
         [SugarColumn(ColumnDataType = "json", IsJson = true, IsNullable = true)]
         public List<Kv>? DisplayLocation { get; set; }
 
+        /// <summary>
+        /// 旧数据id
+        /// </summary>
+        public string? OldNoticeId { get; set; }
+
         /// <summary>
         /// 阅读量+1
         /// </summary>

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

@@ -297,5 +297,10 @@ namespace Hotline.FlowEngine.Workflows
 
         Task JumpToEndAsync(ISessionContext current, Workflow workflow, string opinion, List<FileDto> files, DateTime? expiredTime,
             EReviewResult reviewResult = EReviewResult.Unknown, CancellationToken cancellationToken = default);
+
+        /// <summary>
+        /// 查找会签循环的初始会签发起节点
+        /// </summary>
+        WorkflowStep GetCsLoopStartStep(List<WorkflowStep> steps, WorkflowStep currentStep);
     }
 }

+ 11 - 6
src/Hotline/FlowEngine/Workflows/WorkflowCountersign.cs

@@ -1,4 +1,5 @@
-using Hotline.Share.Dtos.FlowEngine.Workflow;
+using Hotline.Orders;
+using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Enums.FlowEngine;
 using SqlSugar;
 using XF.Domain.Entities;
@@ -7,6 +8,7 @@ using XF.Domain.Repository;
 
 namespace Hotline.FlowEngine.Workflows
 {
+    [SugarIndex("index_wfcs_workflowId", nameof(WorkflowStep.WorkflowId), OrderByType.Desc)]
     public class WorkflowCountersign : CreationEntity
     {
         public string WorkflowId { get; set; }
@@ -136,12 +138,15 @@ namespace Hotline.FlowEngine.Workflows
         [SugarColumn(IsIgnore = true)]
         public List<WorkflowCountersign> Children { get; set; }
 
-        #region method
+        [SugarColumn(IsIgnore = true)]
+		public Order Order { get; set; }
 
-        /// <summary>
-        /// 会签是否完成(如有嵌套会签,表示下级所有会签都完成了)
-        /// </summary>
-        public bool IsCompleted() => EndTime.HasValue;
+		#region method
+
+		/// <summary>
+		/// 会签是否完成(如有嵌套会签,表示下级所有会签都完成了)
+		/// </summary>
+		public bool IsCompleted() => EndTime.HasValue;
 
         /// <summary>
         /// 结束会签(需提前确认所有子集都已结束)

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

@@ -1,4 +1,5 @@
-using XF.Domain.Entities;
+using SqlSugar;
+using XF.Domain.Entities;
 using XF.Domain.Repository;
 
 namespace Hotline.FlowEngine.Workflows;
@@ -6,6 +7,7 @@ namespace Hotline.FlowEngine.Workflows;
 /// <summary>
 /// 会签办理对象
 /// </summary>
+[SugarIndex("index_wfcsMember_workflowCountersignId", nameof(WorkflowCountersignMember.WorkflowCountersignId), OrderByType.Desc)]
 public class WorkflowCountersignMember : CreationEntity
 {
     public string WorkflowCountersignId { get; set; }

+ 54 - 38
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -19,12 +19,9 @@ using XF.Domain.Dependency;
 using XF.Domain.Entities;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
-using System.Diagnostics;
 using System.Text;
 using Hotline.Configurations;
-using Hotline.Orders;
 using Hotline.Share.Dtos.File;
-using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.Options;
 
 namespace Hotline.FlowEngine.Workflows
@@ -1275,7 +1272,11 @@ namespace Hotline.FlowEngine.Workflows
             CancellationToken cancellation)
         {
             return await _workflowStepRepository.Queryable()
-                .Where(d => d.WorkflowId == workflowId && d.HandlerOrgId == orgId && d.StepType != EStepType.End && d.StepType != EStepType.Summary)
+                .Where(d => d.WorkflowId == workflowId 
+                            && d.HandlerOrgId == orgId 
+                            && d.StepType != EStepType.End 
+                            && d.StepType != EStepType.Summary
+                            && !d.IsCountersignEndStep)
                 //.Where(d => d.StepHandlers.Any(sh => sh.OrgId == orgId) && d.WorkflowId == workflowId)
                 .OrderByDescending(d => d.HandleTime)
                 .FirstAsync(cancellation);
@@ -2036,6 +2037,24 @@ namespace Hotline.FlowEngine.Workflows
             HandleStep(step, dto.Opinion, dto.NextStepCode);
         }
 
+        /// <summary>
+        /// 查找会签循环的初始会签发起节点
+        /// </summary>
+        /// <param name="steps"></param>
+        /// <param name="currentStep"></param>
+        /// <returns></returns>
+        /// <exception cref="UserFriendlyException"></exception>
+        public WorkflowStep GetCsLoopStartStep(List<WorkflowStep> steps, WorkflowStep currentStep)
+        {
+            var startCountersignStep = steps.FirstOrDefault(d => d.Id == currentStep.CountersignStartStepId);
+            if (startCountersignStep is null)
+                throw new UserFriendlyException(
+                    $"GetCsLoopStartStep: 未查询到会签开始节点,workflowId: {currentStep.WorkflowId}, startStepId: {currentStep.CountersignStartStepId}",
+                    "未查询到会签开始节点,数据异常");
+            if (!startCountersignStep.IsCountersignEndStep)
+                return startCountersignStep;
+            return GetCsLoopStartStep(steps, startCountersignStep);
+        }
 
         #region private method
 
@@ -2308,15 +2327,17 @@ namespace Hotline.FlowEngine.Workflows
         private async Task<List<WorkflowStep>> CreateCsEndStepsByTargetPrevAsync(Workflow workflow, WorkflowStep step,
             BasicWorkflowDto dto, DateTime? expiredTime, bool isAutoFillSummaryOpinion = false, CancellationToken cancellationToken = default)
         {
-            var countersignStartStep = workflow.Steps.FirstOrDefault(d => d.Id == step.PrevStepId);
+            //var countersignStartStep = workflow.Steps.FirstOrDefault(d => d.Id == step.PrevStepId);
+            var countersignStartStep = workflow.Steps.FirstOrDefault(d => d.StartCountersignId == step.CountersignId);
             if (countersignStartStep is null)
-                throw new UserFriendlyException("未查询到当前节点上级节点");
+                throw new UserFriendlyException("未查询到当前节点上级会签开启节点");
             var nextSteps = new List<WorkflowStep>();
             //会签未全部办理则不创建汇总节点
 
-            var csInnerSteps = workflow.Steps.Where(d => d.PrevStepId == countersignStartStep.Id).ToList();
-            if (csInnerSteps.Any(d =>
-                    d.Status != EWorkflowStepStatus.Handled || (d.IsStartCountersign && !d.IsStartedCountersignEnd)))
+            //var csInnerSteps = workflow.Steps.Where(d => d.PrevStepId == countersignStartStep.Id).ToList();
+            //if (csInnerSteps.Any(d =>
+            //        d.Status != EWorkflowStepStatus.Handled || (d.IsStartCountersign && !d.IsStartedCountersignEnd)))
+            if(!HasStepsAllHandledIncludeCountersign(workflow.Steps, countersignStartStep))
                 return nextSteps;
 
             string? opinion = null;
@@ -2352,6 +2373,22 @@ namespace Hotline.FlowEngine.Workflows
             return nextSteps;
         }
 
+        /// <summary>
+        /// 是否会签节点都已经办理完成(包含会签嵌套的判断)
+        /// </summary>
+        private bool HasStepsAllHandledIncludeCountersign(List<WorkflowStep> steps, WorkflowStep countersignStartStep)
+        {
+            var innerSteps = steps.Where(d => d.CountersignId == countersignStartStep.StartCountersignId).ToList();
+            foreach (var step in innerSteps)
+            {
+                if (step.Status != EWorkflowStepStatus.Handled) return false;
+                if (step.IsStartCountersign)
+                    return HasStepsAllHandledIncludeCountersign(steps, step);
+            }
+            return true;
+        }
+
+
         /// <summary>
         /// 以某一节点作为根节点开始查找最底层办理节点(需求:自动填充汇总节点意见)
         /// </summary>
@@ -2469,7 +2506,7 @@ namespace Hotline.FlowEngine.Workflows
             var countersignId = startStep.CountersignId;
             if (startStep.IsCountersignEndStep)
             {
-                var topStartCsStep = GetCsLoopStartStep(workflow, startStep);
+                var topStartCsStep = GetCsLoopStartStep(workflow.Steps, startStep);
                 countersignId = topStartCsStep.CountersignId;
             }
 
@@ -3166,6 +3203,7 @@ namespace Hotline.FlowEngine.Workflows
                 throw new UserFriendlyException("该流程未处于会签中");
             countersign = workflow.Countersigns.First(d => d.Id == countersign.Id);
 
+
             var startCountersignStep = workflow.Steps.Find(d => d.StartCountersignId == countersign.Id);
             if (startCountersignStep is null)
                 throw new UserFriendlyException("未查询到发起会签节点");
@@ -3173,8 +3211,7 @@ namespace Hotline.FlowEngine.Workflows
                 throw new UserFriendlyException("该会签已汇总");
 
             var updateCountersigns = new List<WorkflowCountersign>();
-            EndCountersignWithCascade(countersign, workflow.Countersigns, startCountersignStep.BusinessType,
-                ref updateCountersigns);
+            EndCountersignWithCascade(countersign, workflow.Countersigns, startCountersignStep.BusinessType, ref updateCountersigns);
 
             if (updateCountersigns.Any())
             {
@@ -3195,8 +3232,10 @@ namespace Hotline.FlowEngine.Workflows
 
                 //cp会签发起节点变为待办节点
                 //1. create terminal trace 2. 撤回至startStep
-                var newStep = await DuplicateStepWithTraceAsync(workflow, startCountersignStep, EWorkflowTraceType.Normal, expireTime,
-                    cancellationToken);
+                var stepToDuplicate = startCountersignStep.IsCountersignEndStep
+                    ? GetCsLoopStartStep(workflow.Steps, startCountersignStep)
+                    : startCountersignStep;
+                var newStep = await DuplicateStepWithTraceAsync(workflow, stepToDuplicate, EWorkflowTraceType.Normal, expireTime, cancellationToken);
 
                 //当topcsStep结束cs时,实际办理节点应该更新为newStep
                 if (startCountersignStep.Id == workflow.TopCountersignStepId)
@@ -3231,16 +3270,6 @@ namespace Hotline.FlowEngine.Workflows
                 if (workflow.CheckIfCountersignOver())
                     workflow.EndCountersign();
 
-                // var removeHandlers = updateSteps.SelectMany(d => d.Handlers).Select(d => d.Key).ToList();
-                //
-                // var handlerObjs = newStep.Handlers.Select(d => new HandlerGroupItem
-                // {
-                //     GroupId = Guid.NewGuid().ToString(),
-                //     Key = d.Key,
-                //     Value = d.Value
-                // }).ToList();
-                //workflow.UpdateHandlers(removeHandlers, newStep.FlowAssignType.Value, handlerObjs);
-
                 await _workflowRepository.UpdateAsync(workflow, cancellationToken);
             }
 
@@ -3548,7 +3577,7 @@ namespace Hotline.FlowEngine.Workflows
                     {
                         if (dto.BackToCountersignEnd)
                         {
-                            var csStartStep = GetCsLoopStartStep(workflow, currentStep);
+                            var csStartStep = GetCsLoopStartStep(workflow.Steps, currentStep);
                             var prevStep = workflow.Steps.FirstOrDefault(d => d.Id == csStartStep.PrevStepId);
                             if (prevStep is null)
                                 throw new UserFriendlyException("未查询到目标节点的前一节点");
@@ -3599,19 +3628,6 @@ namespace Hotline.FlowEngine.Workflows
                 cancellationToken);
         }
 
-        private WorkflowStep GetCsLoopStartStep(Workflow workflow, WorkflowStep currentStep)
-        {
-            var startCountersignStep =
-                workflow.Steps.FirstOrDefault(d => d.Id == currentStep.CountersignStartStepId);
-            if (startCountersignStep is null)
-                throw new UserFriendlyException(
-                    $"未查询到会签开始节点,workflowId: {workflow.Id}, startStepId: {currentStep.CountersignStartStepId}",
-                    "未查询到会签开始节点,数据异常");
-            if (!startCountersignStep.IsCountersignEndStep)
-                return startCountersignStep;
-            return GetCsLoopStartStep(workflow, startCountersignStep);
-        }
-
         #endregion
     }
 }

+ 3 - 8
src/Hotline/FlowEngine/Workflows/WorkflowStep.cs

@@ -1,16 +1,11 @@
-using Hotline.File;
-using Hotline.Share.Dtos;
-using Hotline.Share.Dtos.FlowEngine;
-using Hotline.Share.Dtos.FlowEngine.Definition;
-using Hotline.Share.Dtos.FlowEngine.Workflow;
-using Hotline.Share.Enums.FlowEngine;
+using Hotline.Share.Enums.FlowEngine;
 using SqlSugar;
 using XF.Domain.Entities;
-using XF.Domain.Exceptions;
 
 namespace Hotline.FlowEngine.Workflows;
 
-[SugarIndex("index_step_externalId", nameof(WorkflowStep.ExternalId), OrderByType.Asc)]
+[SugarIndex("index_step_workflowId", nameof(WorkflowStep.WorkflowId), OrderByType.Desc)]
+[SugarIndex("index_step_externalId", nameof(WorkflowStep.ExternalId), OrderByType.Desc)]
 public class WorkflowStep : StepBasicEntity
 {
    [Navigate(NavigateType.OneToOne, nameof(Id),

+ 1 - 1
src/Hotline/FlowEngine/Workflows/WorkflowSupplement.cs

@@ -14,7 +14,7 @@ public class WorkflowSupplement : CreationEntity
     /// <summary>
     /// 补充意见
     /// </summary>
-    [SugarColumn(Length = 2000)]
+    [SugarColumn(ColumnDataType = "text")]
     public string Opinion { get; set; }
 
     /// <summary>

+ 2 - 5
src/Hotline/FlowEngine/Workflows/WorkflowTrace.cs

@@ -7,11 +7,8 @@ namespace Hotline.FlowEngine.Workflows;
 /// <summary>
 /// 流转记录
 /// </summary>
-[SugarIndex("index_trace_externalId", nameof(WorkflowTrace.ExternalId), OrderByType.Asc)]
-[SugarIndex("index_trace_flowAssignType", nameof(WorkflowTrace.FlowAssignType), OrderByType.Asc)]
-[SugarIndex("index_trace_handlerId", nameof(WorkflowTrace.HandlerId), OrderByType.Asc)]
-[SugarIndex("index_trace_handlerOrgId", nameof(WorkflowTrace.HandlerOrgId), OrderByType.Asc)]
-[SugarIndex("index_trace_roleId", nameof(WorkflowTrace.RoleId), OrderByType.Asc)]
+[SugarIndex("index_trace_workflowId", nameof(WorkflowTrace.WorkflowId), OrderByType.Desc)]
+[SugarIndex("index_trace_externalId", nameof(WorkflowTrace.ExternalId), OrderByType.Desc)]
 public class WorkflowTrace : StepBasicEntity
 {
     /// <summary>

+ 6 - 0
src/Hotline/KnowledgeBase/Knowledge.cs

@@ -216,4 +216,10 @@ public class Knowledge : WorkflowEntity//   WorkflowEntity  FullStateEntity
 	/// </summary>
 	[SugarColumn(ColumnDescription = "收藏数量")]
 	public int? CollectCount { get; set; } = 0;
+
+	/// <summary>
+	/// 知识来源
+	/// </summary>
+	[SugarColumn(ColumnDescription = "知识来源")]
+	public string? Source { get; set; }
 }

+ 1 - 1
src/Hotline/KnowledgeBase/KnowledgeComment.cs

@@ -27,7 +27,7 @@ namespace Hotline.KnowledgeBase
 		/// <summary>
 		/// 评论内容
 		/// </summary>
-		[SugarColumn(ColumnDescription = "评论内容", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "评论内容", ColumnDataType = "text")]
 		public string? Content { get; set; }
 
 		/// <summary>

+ 2 - 2
src/Hotline/KnowledgeBase/KnowledgeCorrection.cs

@@ -31,7 +31,7 @@ namespace Hotline.KnowledgeBase
 		/// <summary>
 		/// 纠错内容
 		/// </summary>
-		[SugarColumn(ColumnDescription = "纠错内容", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "纠错内容", ColumnDataType = "text")]
 		public string? Content { get; set; }
 
 		/// <summary>
@@ -49,7 +49,7 @@ namespace Hotline.KnowledgeBase
 		/// <summary>
 		/// 答复内容
 		/// </summary>
-		[SugarColumn(ColumnDescription = "纠错内容", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "纠错内容", ColumnDataType = "text")]
 		public string? ReplyContent { get; set; }
 
 		/// <summary>

+ 2 - 2
src/Hotline/KnowledgeBase/KnowledgeQuestions.cs

@@ -29,7 +29,7 @@ namespace Hotline.KnowledgeBase
 		/// <summary>
 		/// 提问内容
 		/// </summary>
-		[SugarColumn(ColumnDescription = "提问内容", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "提问内容", ColumnDataType = "text")]
 		public string? Content { get; set; }
 
 		/// <summary>
@@ -47,7 +47,7 @@ namespace Hotline.KnowledgeBase
 		/// <summary>
 		/// 答复内容
 		/// </summary>
-		[SugarColumn(ColumnDescription = "纠错内容", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "纠错内容", ColumnDataType = "text")]
 		public string? ReplyContent { get; set; }
 
 		/// <summary>

+ 0 - 7
src/Hotline/KnowledgeBase/KnowledgeType.cs

@@ -45,13 +45,6 @@ public class KnowledgeType : FullStateEntity
     /// </summary>
     public int? OldTypeId { get; set; }
 
-	/// <summary>
-	/// 子级
-	/// </summary>
-	[SqlSugar.SugarColumn(IsIgnore = true)]
-    public List<KnowledgeType> children { get; set; }
-
-
     /// <summary>
     /// 类型关联机构
     /// </summary>

+ 2 - 2
src/Hotline/KnowledgeBase/KnowledgeWord.cs

@@ -27,13 +27,13 @@ namespace Hotline.KnowledgeBase
 		/// <summary>
 		/// 近义词
 		/// </summary>
-		[SugarColumn(ColumnDescription = "近义词", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "近义词", ColumnDataType = "text")]
 		public string? Synonym { get; set; }
 
 		/// <summary>
 		/// 备注
 		/// </summary>
-		[SugarColumn(ColumnDescription = "备注", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "备注", ColumnDataType = "text")]
 		public string? Remark { get; set; }
 
 		/// <summary>

+ 1 - 1
src/Hotline/KnowledgeBase/KnowledgeWorkFlow.cs

@@ -37,7 +37,7 @@ namespace Hotline.KnowledgeBase
         /// <summary>
         /// 实际办理意见(办理中...or 最终办理意见)
         /// </summary>
-        [SugarColumn(Length = 2000)]
+        [SugarColumn(ColumnDataType = "text")]
         public string? ActualOpinion { get; set; } 
 
 		/// <summary>

+ 1 - 1
src/Hotline/Orders/Citizen.cs

@@ -69,7 +69,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 市民标签
         /// </summary>
-        [SugarColumn(ColumnDescription = "市民标签", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "市民标签", ColumnDataType = "text")]
         public string? Label { get; set; }
 
 		/// <summary>

+ 1 - 1
src/Hotline/Orders/IOrderRepository.cs

@@ -184,7 +184,7 @@ namespace Hotline.Orders
 		/// </summary>
 		/// <param name="dto"></param>
 		/// <returns></returns>
-		ISugarQueryable<OrgVisitDetailListResp> OrgVisitDetailFiltrationList(OrgVisitDetailListReq dto);
+		ISugarQueryable<OrgVisitDetailListResp> OrgVisitDetailFiltrationList(OrgVisitDetailListReq dto, string orgId);
 
     }
 

+ 13 - 0
src/Hotline/Orders/OldSendProData.cs

@@ -0,0 +1,13 @@
+using XF.Domain.Repository;
+
+namespace Hotline.Orders
+{
+    public class OldSendProData : CreationEntity
+    {
+        public string No { get; set; }
+
+        public string ProvinceNo { get; set; }
+
+        public string? NewProvinceNo { get; set; }
+    }
+}

+ 3 - 4
src/Hotline/Orders/Order.cs

@@ -22,10 +22,9 @@ namespace Hotline.Orders
     /// </summary>
     [Description("工单")]
     [SugarIndex("unique_order_no", nameof(Order.No), OrderByType.Desc, true)]
-    [SugarIndex("index_order_creationtime", nameof(Order.CreationTime), OrderByType.Asc)]
-    [SugarIndex("index_order_startTime", nameof(Order.StartTime), OrderByType.Asc)]
-    [SugarIndex("index_order_status", nameof(Status), OrderByType.Asc)]
-    [SugarIndex("index_order_expiredTime", nameof(Order.ExpiredTime), OrderByType.Asc)]
+    [SugarIndex("index_order_creationtime", nameof(Order.CreationTime), OrderByType.Desc)]
+    [SugarIndex("index_order_startTime", nameof(Order.StartTime), OrderByType.Desc)]
+    [SugarIndex("index_order_expiredTime", nameof(Order.ExpiredTime), OrderByType.Desc)]
 	public partial class Order : PositionWorkflowEntity
     {
         public Order()

+ 1 - 1
src/Hotline/Orders/OrderComplement.cs

@@ -20,7 +20,7 @@ public class OrderComplement : CreationEntity
     /// <summary>
     /// 补充意见
     /// </summary>
-    [SugarColumn(Length = 2000)]
+    [SugarColumn(ColumnDataType = "text")]
     public string Opinion { get; set; }
 
     /// <summary>

+ 4 - 2
src/Hotline/Orders/OrderCopy.cs

@@ -1,4 +1,5 @@
-using System;
+using SqlSugar;
+using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Linq;
@@ -11,7 +12,8 @@ namespace Hotline.Orders
 	/// 副本工单
 	/// </summary>
 	[Description("副本工单")]
-	public partial class OrderCopy : Order
+    [SugarIndex("index_copy_orderId", nameof(OrderCopy.OrderId), OrderByType.Desc)]
+    public partial class OrderCopy : Order
 	{
 		/// <summary>
 		/// 工单ID

+ 7 - 6
src/Hotline/Orders/OrderDelay.cs

@@ -71,12 +71,13 @@ namespace Hotline.Orders
         /// <summary>
         /// 延期申请单位
         /// </summary>
-        public ETimeType DelayUnit { get; set; } 
+        public ETimeType DelayUnit { get; set; }
 
-        /// <summary>
-        /// 延期申请理由
-        /// </summary>
-        public string DelayReason { get; set; }
+		/// <summary>
+		/// 延期申请理由
+		/// </summary>
+		[SugarColumn(ColumnDescription = "延期申请理由", ColumnDataType = "text")]
+		public string DelayReason { get; set; }
 
         /// <summary>
         /// 申请前期满时间
@@ -112,7 +113,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 审核意见
         /// </summary>
-        [SugarColumn(ColumnDescription = "审核意见", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "审核意见", ColumnDataType = "text")]
         public string? AuditOpinion { get; set; } 
         #endregion
 

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

@@ -364,6 +364,10 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         }
         order.Init();
         order.No = GenerateNewOrderNo();
+        if (order.Source == ESource.Police110)
+        {
+            order.Title = @"(非警情工单-"+order.No.Substring(order.No.Length - 6) +")";
+        }
         order.Password = Random.Shared.Next(100000, 1000000).ToString();
         order.ProvinceNo = string.IsNullOrEmpty(order.ProvinceNo) ? GenerateNewProvinceNo(order.No, order.SourceChannelCode) : order.ProvinceNo;
         return await _orderRepository.AddOrderNavAsync(order, cancellationToken);

+ 2 - 2
src/Hotline/Orders/OrderScreen.cs

@@ -77,13 +77,13 @@ namespace Hotline.Orders
         /// <summary>
         /// 甄别申请原因
         /// </summary>
-        [SugarColumn(ColumnDescription = "甄别申请原因", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "甄别申请原因", ColumnDataType = "text")]
         public string? Content { get; set; }
 
         /// <summary>
         /// 甄别申请回复
         /// </summary>
-        [SugarColumn(ColumnDescription = "甄别申请回复", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "甄别申请回复", ColumnDataType = "text")]
         public string? ReplyContent { get; set; }
 
         #region 用于省平台查询

+ 3 - 3
src/Hotline/Orders/OrderSecondaryHandling.cs

@@ -47,19 +47,19 @@ namespace Hotline.Orders
 		/// <summary>
 		/// 申请理由
 		/// </summary>
-		[SugarColumn(ColumnDescription = "申请理由", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "申请理由", ColumnDataType = "text")]
 		public string? Content { get; set; }
 
 		/// <summary>
 		/// 退回意见
 		/// </summary>
-		[SugarColumn(ColumnDescription = "退回意见", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "退回意见", ColumnDataType = "text")]
 		public string? SendBackContent { get; set; }
 
 		/// <summary>
 		/// 审批意见
 		/// </summary>
-		[SugarColumn(ColumnDescription = "审批意见", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "审批意见", ColumnDataType = "text")]
 		public string? AuditContent { get; set; }
 
 		/// <summary>

+ 2 - 2
src/Hotline/Orders/OrderSendBackAudit.cs

@@ -51,13 +51,13 @@ namespace Hotline.Orders
 		/// <summary>
 		/// 退回原因
 		/// </summary>
-		[SugarColumn(ColumnDescription = "退回原因", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "退回原因", ColumnDataType = "text")]
 		public string? Content { get; set; }
 
 		/// <summary>
 		/// 审批意见
 		/// </summary>
-		[SugarColumn(ColumnDescription = "审批意见", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "审批意见", ColumnDataType = "text")]
 		public string? AuditContent { get; set; }
 
 		/// <summary>

+ 3 - 3
src/Hotline/Orders/OrderSendback.cs

@@ -22,7 +22,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 申请原因
         /// </summary>
-        [SugarColumn(ColumnDescription = "申请原因", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "申请原因", ColumnDataType = "text")]
         public string? Content { get; set; }
 
         /// <summary>
@@ -33,7 +33,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 省上退回反馈
         /// </summary>
-        [SugarColumn(ColumnDescription = "退回反馈", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "退回反馈", ColumnDataType = "text")]
         public string? Reason { get; set; }
 
         /// <summary>
@@ -54,7 +54,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 审核意见
         /// </summary>
-        [SugarColumn(ColumnDescription = "审核意见", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "审核意见", ColumnDataType = "text")]
         public string? AuditOpinion { get; set; }
 
         /// <summary>

+ 2 - 2
src/Hotline/Orders/OrderSpecial.cs

@@ -69,7 +69,7 @@ namespace Hotline.Orders
 		/// <summary>
 		/// 特提理由
 		/// </summary>
-		[SugarColumn(ColumnDescription = "特提理由", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "特提理由", ColumnDataType = "text")]
         public string? Reason { get; set; }
 
         /// <summary>
@@ -87,7 +87,7 @@ namespace Hotline.Orders
 		/// <summary>
 		/// 特提意见
 		/// </summary>
-		[SugarColumn(ColumnDescription = "特提意见", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "特提意见", ColumnDataType = "text")]
         public string? Opinion { get; set; }
 
 		/// <summary>

+ 2 - 2
src/Hotline/Orders/OrderSupervise.cs

@@ -59,13 +59,13 @@ namespace Hotline.Orders
         /// <summary>
         /// 督办申请内容
         /// </summary>
-        [SugarColumn(ColumnDescription = "督办申请内容", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "督办申请内容", ColumnDataType = "text")]
         public string? ApplyContent { get; set; }
 
         /// <summary>
         /// 督办回复内容
         /// </summary>
-        [SugarColumn(ColumnDescription = "督办回复内容", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "督办回复内容", ColumnDataType = "text")]
         public string? ReplyContent { get; set; }
 
         /// <summary>

+ 1 - 1
src/Hotline/Orders/OrderTerminate.cs

@@ -42,7 +42,7 @@ namespace Hotline.Orders
 		/// <summary>
 		/// 终止理由
 		/// </summary>
-		[SugarColumn(ColumnDescription = "终止理由", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "终止理由", ColumnDataType = "text")]
 		public string? Content { get; set; }
 
 		/// <summary>

+ 2 - 2
src/Hotline/Orders/OrderUrge.cs

@@ -61,13 +61,13 @@ namespace Hotline.Orders
         /// <summary>
         /// 催办申请内容
         /// </summary>
-        [SugarColumn(ColumnDescription = "催办申请内容", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "催办申请内容", ColumnDataType = "text")]
         public string? ApplyContent { get; set; }
 
         /// <summary>
         /// 催办回复内容
         /// </summary>
-        [SugarColumn(ColumnDescription = "催办回复内容", ColumnDataType = "varchar(2000)")]
+        [SugarColumn(ColumnDescription = "催办回复内容", ColumnDataType = "text")]
         public string? ReplyContent { get; set; }
 
         /// <summary>

+ 2 - 1
src/Hotline/Orders/OrderVisitDetail.cs

@@ -8,7 +8,8 @@ using XF.Utility.EnumExtensions;
 
 namespace Hotline.Orders
 {
-    public class OrderVisitDetail : CreationEntity
+	[SugarIndex("index_visitDetail_creationtime", nameof(OrderVisitDetail.CreationTime), OrderByType.Desc)]
+	public class OrderVisitDetail : CreationEntity
     {
 
         /// <summary>

+ 2 - 2
src/Hotline/Orders/OrderWord.cs

@@ -27,13 +27,13 @@ namespace Hotline.Orders
 		/// <summary>
 		/// 近义词
 		/// </summary>
-		[SugarColumn(ColumnDescription = "近义词", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "近义词", ColumnDataType = "text")]
 		public string? Synonym { get; set; }
 
 		/// <summary>
 		/// 备注
 		/// </summary>
-		[SugarColumn(ColumnDescription = "备注", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "备注", ColumnDataType = "text")]
 		public string? Remark { get; set; }
 
 		/// <summary>

+ 1 - 1
src/Hotline/Orders/RepeatableEvent.cs

@@ -28,7 +28,7 @@ namespace Hotline.Orders
 		/// <summary>
 		/// 关键词
 		/// </summary>
-		[SugarColumn(ColumnDescription = "关键词", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "关键词", ColumnDataType = "text")]
 		public string? KeyWords { get; set; }
 
 		/// <summary>

+ 1 - 1
src/Hotline/Quality/Quality.cs

@@ -41,7 +41,7 @@ namespace Hotline.Quality
 		/// <summary>
 		/// 质检评价
 		/// </summary>
-		[SugarColumn(ColumnDescription = "质检评价", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "质检评价", ColumnDataType = "text")]
 		public string? Content { get; set; }
 
 		/// <summary>

+ 1 - 1
src/Hotline/Quality/QualityDetail.cs

@@ -35,7 +35,7 @@ namespace Hotline.Quality
 		/// <summary>
 		/// 扣分内容
 		/// </summary>
-		[SugarColumn(ColumnDescription = "扣分内容", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "扣分内容", ColumnDataType = "text")]
 		public string? Content { get; set; }
 
 		/// <summary>

+ 1 - 1
src/Hotline/Quality/QualityItem.cs

@@ -17,7 +17,7 @@ namespace Hotline.Quality
 		/// <summary>
 		/// 质检项目描述
 		/// </summary>
-		[SugarColumn(ColumnDescription = "质检项目描述", ColumnDataType = "varchar(2000)")]
+		[SugarColumn(ColumnDescription = "质检项目描述", ColumnDataType = "text")]
 		public string? Describe { get; set; }
 
 		/// <summary>

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

@@ -586,6 +586,11 @@ namespace Hotline.Settings
         /// </summary>
         public const string HandleOpinionWordLimit = "HandleOpinionWordLimit";
 
+        /// <summary>
+        /// 电话呼入弹单方式(兴唐)
+        /// </summary>
+        public const string CallInOpenType = "CallInOpenType";
+
         /// <summary>
         /// 取消发布功能总开关
         /// </summary>
@@ -652,5 +657,15 @@ namespace Hotline.Settings
         /// 小程序Banner集合
         /// </summary>
         public static string AppBanner = "小程序Banner";
+
+		/// <summary>
+		/// 部门满意度明细不显示工单
+		/// </summary>
+		public const string OrgVisitDetailHiddenOrderNo = "OrgVisitDetailHiddenOrderNo";
+
+        /// <summary>
+        /// 交办单是否保密
+        /// </summary>
+        public const string IsTheAssignmentFormConfidential = "IsTheAssignmentFormConfidential";
     }
 }

+ 3 - 2
src/Hotline/Settings/SystemLog.cs

@@ -1,5 +1,6 @@
 using SqlSugar;
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Linq;
@@ -38,11 +39,11 @@ namespace Hotline.Settings
 		/// 请求参数 
 		///</summary>
 		[SugarColumn(ColumnDataType = "json", IsJson = true)]
-		public string? ExecuteParam { get; set; }
+		public object? ExecuteParam { get; set; }
 		/// <summary>
 		/// 请求结果 
 		///</summary>
 		[SugarColumn(ColumnDataType = "json", IsJson = true)]
-		public string? ExecuteResult { get; set; }
+		public object? ExecuteResult { get; set; }
 	}
 }

+ 8 - 1
src/Hotline/WebPortal/WebFlowAccept.cs

@@ -1,4 +1,5 @@
-using Hotline.Share.Enums.Order;
+using Hotline.Share.Dtos.File;
+using Hotline.Share.Enums.Order;
 using SqlSugar;
 using XF.Domain.Repository;
 
@@ -135,5 +136,11 @@ namespace Hotline.WebPortal
         [SugarColumn(ColumnDescription = "微信Id")]
         public string? WXOpenid { get; set; }
 
+        /// <summary>
+        /// 附件
+        /// </summary>
+        [SugarColumn(ColumnDataType = "json", IsJson = true)]
+        public List<FileDto>? Files { get; set; } = new();
+
     }
 }

+ 1 - 1
src/XF.Domain.Repository/XF.Domain.Repository.csproj

@@ -10,7 +10,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="SqlSugarCore" Version="5.1.4.169" />
+    <PackageReference Include="SqlSugarCore" Version="5.1.4.170" />
     <PackageReference Include="XF.Utility.SequentialId" Version="1.0.2" />
   </ItemGroup>