Browse Source

Merge branch 'test' into lib/test

libin 4 months ago
parent
commit
d4e535cbff
29 changed files with 1354 additions and 726 deletions
  1. 281 498
      src/Hotline.Api/Controllers/Bi/BiOrderController.cs
  2. 134 6
      src/Hotline.Api/Controllers/FileController.cs
  3. 56 27
      src/Hotline.Api/Controllers/OrderController.cs
  4. 1 0
      src/Hotline.Api/Controllers/OrderTerminateController.cs
  5. 1 1
      src/Hotline.Api/Controllers/WebPortalController.cs
  6. 5 1
      src/Hotline.Api/StartupExtensions.cs
  7. 45 21
      src/Hotline.Application/Handlers/FlowEngine/WorkflowPreviousHandler.cs
  8. 34 10
      src/Hotline.Application/Orders/IOrderApplication.cs
  9. 185 28
      src/Hotline.Application/Orders/OrderApplication.cs
  10. 4 2
      src/Hotline.Application/Orders/OrderSecondaryHandlingApplication.cs
  11. 53 5
      src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs
  12. 51 15
      src/Hotline.Share/Dtos/CallCenter/CenterReportStatisticsDto.cs
  13. 42 0
      src/Hotline.Share/Dtos/File/UploadAudioFilesRequestDto.cs
  14. 10 0
      src/Hotline.Share/Dtos/Knowledge/KnowledgeDto.cs
  15. 93 1
      src/Hotline.Share/Dtos/Order/OrderBiDto.cs
  16. 63 6
      src/Hotline.Share/Dtos/Order/OrderDto.cs
  17. 10 0
      src/Hotline.Share/Dtos/Order/OrderTsDetailsDto.cs
  18. 29 25
      src/Hotline.Share/Enums/Order/ESeatEvaluate.cs
  19. 16 21
      src/Hotline.Share/Enums/Order/EVoiceEvaluate.cs
  20. 1 1
      src/Hotline.Share/Hotline.Share.csproj
  21. 2 3
      src/Hotline.Share/Requests/PagedKeywordRequest.cs
  22. 46 0
      src/Hotline/File/UploadAudioFiles.cs
  23. 4 0
      src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs
  24. 41 26
      src/Hotline/KnowledgeBase/KnowledgeDomainService.cs
  25. 15 1
      src/Hotline/KnowledgeBase/KnowledgePV.cs
  26. 43 0
      src/Hotline/KnowledgeBase/KnowledgeQuote.cs
  27. 47 28
      src/Hotline/Orders/Order.cs
  28. 37 0
      src/Hotline/Orders/OrderTsDetails.cs
  29. 5 0
      src/Hotline/Settings/SettingConstants.cs

+ 281 - 498
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -43,6 +43,10 @@ using XF.Utility.EnumExtensions;
 using Hotline.Statistics;
 using DocumentFormat.OpenXml.Drawing;
 using DocumentFormat.OpenXml.Bibliography;
+using NPOI.SS.Formula.Functions;
+using Hotline.Share.Dtos.File;
+using Hotline.File;
+using Hotline.KnowledgeBase;
 using DocumentFormat.OpenXml.Vml.Spreadsheet;
 
 namespace Hotline.Api.Controllers.Bi
@@ -84,6 +88,8 @@ namespace Hotline.Api.Controllers.Bi
         private readonly ISystemOrganizeRepository _organizeRepository;
         private readonly IRepository<CallNative> _callNativeRepository;
         private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
+        private readonly IRepository<OrderTsDetails> _orderTsDetailsRepository;
+        private readonly IRepository<KnowledgeQuote> _knowledgeQuoteRepository;
 
         public BiOrderController(
             IOrderRepository orderRepository,
@@ -120,7 +126,9 @@ namespace Hotline.Api.Controllers.Bi
             IExportApplication exportApplication,
             IOrderVisitApplication orderVisitApplication,
             IRepository<CallNative> callNativeRepository,
-            IOptionsSnapshot<AppConfiguration> appOptions)
+            IOptionsSnapshot<AppConfiguration> appOptions,
+            IRepository<OrderTsDetails> orderTsDetailsRepository,
+            IRepository<KnowledgeQuote> knowledgeQuoteRepository)
         {
             _orderRepository = orderRepository;
             _hotspotTypeRepository = hotspotTypeRepository;
@@ -157,6 +165,8 @@ namespace Hotline.Api.Controllers.Bi
             _orderVisitApplication = orderVisitApplication;
             _callNativeRepository = callNativeRepository;
             _appOptions = appOptions;
+            _orderTsDetailsRepository = orderTsDetailsRepository;
+            _knowledgeQuoteRepository = knowledgeQuoteRepository;
         }
 
         /// <summary>
@@ -1583,6 +1593,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoPutThroughCount),
+                NormalCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.VeryNoSatisfiedCount),
             };
 
             var citySumModel = new VisitAndOrgSatisfactionStatisticsDto()
@@ -1596,6 +1608,8 @@ namespace Hotline.Api.Controllers.Bi
                 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),
+                NormalCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.VeryNoSatisfiedCount),
             };
 
             var sumModel = new VisitAndOrgSatisfactionStatisticsDto()
@@ -1609,6 +1623,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = data.Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = data.Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = data.Sum(x => x.NoPutThroughCount),
+                NormalCount = data.Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = data.Sum(x => x.VeryNoSatisfiedCount),
             };
 
 
@@ -1635,6 +1651,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoPutThroughCount),
+                NormalCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = data.Where(x => x.OrgType == EOrgType.County).Sum(x => x.VeryNoSatisfiedCount),
             };
             var citySumModel = new VisitAndOrgSatisfactionStatisticsDto()
             {
@@ -1647,6 +1665,8 @@ namespace Hotline.Api.Controllers.Bi
                 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),
+                NormalCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = data.Where(x => x.OrgType == EOrgType.City && x.OrgCode != "001").Sum(x => x.VeryNoSatisfiedCount),
             };
             var sumModel = new VisitAndOrgSatisfactionStatisticsDto()
             {
@@ -1659,6 +1679,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = data.Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = data.Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = data.Sum(x => x.NoPutThroughCount),
+                NormalCount = data.Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = data.Sum(x => x.VeryNoSatisfiedCount),
             };
             data.Add(countySumModel);
             data.Add(citySumModel);
@@ -1694,6 +1716,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoPutThroughCount),
+                NormalCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.VeryNoSatisfiedCount),
             };
 
             var citySumModel = new VisitAndOrgSatisfactionStatisticsDto()
@@ -1707,6 +1731,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoPutThroughCount),
+                NormalCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.VeryNoSatisfiedCount),
             };
 
             var sumModel = new VisitAndOrgSatisfactionStatisticsDto()
@@ -1720,6 +1746,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = list.Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = list.Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = list.Sum(x => x.NoPutThroughCount),
+                NormalCount = list.Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = list.Sum(x => x.VeryNoSatisfiedCount),
             };
 
             return new VisitAndOrgSatisfactionStatisticsResultDto { DataList = list, CountySumModel = countySumModel, CitySumModel = citySumModel, SumModel = sumModel };
@@ -1745,6 +1773,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoPutThroughCount),
+                NormalCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.VeryNoSatisfiedCount),
             };
             var citySumModel = new VisitAndOrgSatisfactionStatisticsDto()
             {
@@ -1757,6 +1787,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoPutThroughCount),
+                NormalCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.VeryNoSatisfiedCount),
             };
             var sumModel = new VisitAndOrgSatisfactionStatisticsDto()
             {
@@ -1769,6 +1801,8 @@ namespace Hotline.Api.Controllers.Bi
                 NoSatisfiedCount = list.Sum(x => x.NoSatisfiedCount),
                 NoEvaluateCount = list.Sum(x => x.NoEvaluateCount),
                 NoPutThroughCount = list.Sum(x => x.NoPutThroughCount),
+                NormalCount = list.Sum(x => x.NormalCount),
+                VeryNoSatisfiedCount = list.Sum(x => x.VeryNoSatisfiedCount),
             };
             list.Add(countySumModel);
             list.Add(citySumModel);
@@ -1877,7 +1911,11 @@ namespace Hotline.Api.Controllers.Bi
                 .Select(o => new CenterReportCallDto
                 {
                     EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.On, 1, 0)),//有效
-                    InvalidCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.NoOn /*&& o.BeginIvrTime.HasValue && o.BeginQueueTime.HasValue && o.BeginRingTime.HasValue*/, 1, 0)), //无效(排除队列挂断和IVR挂断)
+					InTotal = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In, 1, 0)),//呼入总量
+					OutTotal = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.Out, 1, 0)),//呼出总量
+					InConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.AnsweredTime != null, 1, 0)),//呼入接通量
+					OutConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(o.TelNo != "0" && o.CallDirection == ECallDirection.Out && o.AnsweredTime != null, 1, 0)),//呼出接通量
+					InvalidCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.NoOn /*&& o.BeginIvrTime.HasValue && o.BeginQueueTime.HasValue && o.BeginRingTime.HasValue*/, 1, 0)), //无效(排除队列挂断和IVR挂断)
                     QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.QueueTims > 0 && o.RingTimes == 0 && o.OnState == EOnState.NoOn, 1, 0)), //队列挂断
                     IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.BeginIvrTime.HasValue && !o.BeginQueueTime.HasValue && !o.BeginRingTime.HasValue && o.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
                 })
@@ -1885,7 +1923,7 @@ namespace Hotline.Api.Controllers.Bi
             if (callData != null)
                 callData.InvalidCount = callData.InvalidCount - callData.QueueByeCount - callData.IvrByeCount;
 
-            if (listOld != null && callData != null)
+            if (listOld != null && listOld.Rows.Count > 0 && callData != null)
             {
                 callData.EffectiveCount = callData.EffectiveCount + Convert.ToInt32(listOld.Rows[0]["CallInConn"]);   // 有效
                 callData.InvalidCount = callData.InvalidCount + Convert.ToInt32(listOld.Rows[0]["CallInNotConn"]);    // 无效
@@ -1926,14 +1964,14 @@ namespace Hotline.Api.Controllers.Bi
                 })
                 .FirstAsync();
 
-            if (listOld != null && orderData != null)
+            if (listOld != null && listOld.Rows.Count > 0 && orderData != null)
             {
                 orderData.EffectiveCount = orderData.EffectiveCount + Convert.ToInt32(listOld.Rows[0]["OrderNormalNum"]);   // 有效
                 orderData.InvalidCount = orderData.InvalidCount + Convert.ToInt32(listOld.Rows[0]["OrderInvalidNum"]);      // 无效
                 orderData.CompletedCount = orderData.CompletedCount + Convert.ToInt32(listOld.Rows[0]["OrderEndNum"]);      // 已办
                 orderData.InProgressCount = orderData.InProgressCount + Convert.ToInt32(listOld.Rows[0]["OrderWaitNum"]);   // 在办
             }
-            if (listInfo != null && orderData != null)
+            if (listInfo != null && listOld.Rows.Count > 0 && orderData != null)
             {
                 orderData.CityAccept = orderData.CityAccept + Convert.ToInt32(listInfo.Rows[0]["OrderCityCount"]);           // 市级部门受理
                 orderData.CountyAccept = orderData.CountyAccept + Convert.ToInt32(listInfo.Rows[0]["OrderCountyCount"]);     // 县(区)受理
@@ -1960,7 +1998,7 @@ namespace Hotline.Api.Controllers.Bi
                 })
                 .FirstAsync();
 
-            if (listInfo != null && orderCompletedData != null)
+            if (listInfo != null && listInfo.Rows.Count > 0 && orderCompletedData != null)
             {
                 orderCompletedData.ExpiredTimeCompletedCount = orderCompletedData.ExpiredTimeCompletedCount + Convert.ToInt32(listInfo.Rows[0]["OrderAlready"]) - Convert.ToInt32(listInfo.Rows[0]["CompleteOnTime"]);
                 orderCompletedData.CityExpiredTimeCompletedCount = orderCompletedData.CityExpiredTimeCompletedCount + Convert.ToInt32(listInfo.Rows[0]["CityAlready"]) - Convert.ToInt32(listInfo.Rows[0]["CityCompleteOnTime"]);
@@ -1971,7 +2009,7 @@ namespace Hotline.Api.Controllers.Bi
                 orderCompletedData.CenterCompletedCount = orderCompletedData.CenterCompletedCount + Convert.ToInt32(listInfo.Rows[0]["CenterAlready"]);
             }
 
-            centerReportStatisticsDto.orderCompletedDto = orderCompletedData;
+            centerReportStatisticsDto.OrderCompletedDto = orderCompletedData;
 
             //工单办理时效
             var orderAgingData = await _orderRepository.Queryable()
@@ -1998,7 +2036,7 @@ namespace Hotline.Api.Controllers.Bi
                 })
                 .FirstAsync();
 
-            if (listInfo != null && orderAgingData != null)
+            if (listInfo != null && listInfo.Rows.Count > 0 && orderAgingData != null)
             {
                 orderAgingData.OrderCount = orderAgingData.OrderCount + Convert.ToInt32(listInfo.Rows[0]["AllCount"]);
                 orderAgingData.CompletedAging = orderAgingData.CompletedAging + Convert.ToInt32(listInfo.Rows[0]["OrderWorkTime"]);
@@ -2010,7 +2048,7 @@ namespace Hotline.Api.Controllers.Bi
                 orderAgingData.CenterCompletedAging = orderAgingData.CenterCompletedAging + Convert.ToInt32(listInfo.Rows[0]["CenterWorkTime"]);
             }
 
-            centerReportStatisticsDto.orderAgingDto = orderAgingData;
+            centerReportStatisticsDto.OrderAgingDto = orderAgingData;
             #endregion
 
             #region 信件来源
@@ -2049,7 +2087,7 @@ namespace Hotline.Api.Controllers.Bi
                 });
             }
 
-            if (listOld != null && sourceChannel != null)
+            if (listOld != null && listOld.Rows.Count > 0 && sourceChannel != null)
             {
                 foreach (var item in sourceChannel)
                 {
@@ -2133,7 +2171,7 @@ namespace Hotline.Api.Controllers.Bi
                 });
             }
 
-            if (listPurOld != null && acceptType != null)
+            if (listPurOld != null && listPurOld.Rows.Count > 0 && acceptType != null)
             {
                 foreach (var item in acceptType)
                 {
@@ -2215,7 +2253,7 @@ namespace Hotline.Api.Controllers.Bi
             centerReportVisitd.CityDissatisfied = data.CityDissatisfied;
             centerReportVisitd.CountyDissatisfied = data.CountyDissatisfied;
 
-            if (listOld != null && centerReportVisitd != null)
+            if (listOld != null && listOld.Rows.Count > 0 && centerReportVisitd != null)
             {
                 centerReportVisitd.Visitd = centerReportVisitd.Visitd + Convert.ToInt32(listOld.Rows[0]["VisitAlreadyNum"]);                    // 已回访
                 centerReportVisitd.WaitVisitd = centerReportVisitd.WaitVisitd + Convert.ToInt32(listOld.Rows[0]["VisitWaitNum"]);               // 待回访
@@ -2223,7 +2261,7 @@ namespace Hotline.Api.Controllers.Bi
                 centerReportVisitd.OrgRate = Math.Round((centerReportVisitd.OrgRate + Convert.ToDouble(listOld.Rows[0]["SatisfactionDepartment"])) / 2, 2);   // 部门满意度
             }
 
-            if (listInfo != null && centerReportVisitd != null)
+            if (listInfo != null && listInfo.Rows.Count > 0 && centerReportVisitd != null)
             {
                 //总体满意率
                 centerReportVisitd.AllRate = Math.Round(centerReportVisitd.AllRate + Convert.ToDouble(listInfo.Rows[0]["SatisfactionRate"]) / 2, 2);
@@ -2431,7 +2469,7 @@ namespace Hotline.Api.Controllers.Bi
                 })
                 .FirstAsync();
 
-            centerReportStatisticsDto.enterpriseOrderDto = enterpriseOrderDto;
+            centerReportStatisticsDto.EnterpriseOrderDto = enterpriseOrderDto;
             var enterpriseOrderDto2 = await _orderVisitDetailRepository.Queryable()
                 .Includes(it => it.OrderVisit, ov => ov.Order)
                 .LeftJoin<SystemOrganize>((it, so) => it.VisitOrgCode == so.Id)
@@ -2449,492 +2487,99 @@ namespace Hotline.Api.Controllers.Bi
                  })
                 .FirstAsync();
 
-            centerReportStatisticsDto.enterpriseOrderDto.VisitdCount = enterpriseOrderDto2.VisitdCount;
-            centerReportStatisticsDto.enterpriseOrderDto.Dissatisfied = enterpriseOrderDto2.Dissatisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.CityDissatisfied = enterpriseOrderDto2.CityDissatisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.CountyDissatisfied = enterpriseOrderDto2.CountyDissatisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.Satisfied = enterpriseOrderDto2.Satisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.CitySatisfied = enterpriseOrderDto2.CitySatisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.CountySatisfied = enterpriseOrderDto2.CountySatisfied;
+            if (enterpriseOrderDto2 != null)
+            {
+				centerReportStatisticsDto.EnterpriseOrderDto.VisitdCount = enterpriseOrderDto2.VisitdCount;
+				centerReportStatisticsDto.EnterpriseOrderDto.Dissatisfied = enterpriseOrderDto2.Dissatisfied;
+				centerReportStatisticsDto.EnterpriseOrderDto.CityDissatisfied = enterpriseOrderDto2.CityDissatisfied;
+				centerReportStatisticsDto.EnterpriseOrderDto.CountyDissatisfied = enterpriseOrderDto2.CountyDissatisfied;
+				centerReportStatisticsDto.EnterpriseOrderDto.Satisfied = enterpriseOrderDto2.Satisfied;
+				centerReportStatisticsDto.EnterpriseOrderDto.CitySatisfied = enterpriseOrderDto2.CitySatisfied;
+				centerReportStatisticsDto.EnterpriseOrderDto.CountySatisfied = enterpriseOrderDto2.CountySatisfied;
+			}
 
-            if (listInfo != null && centerReportStatisticsDto.enterpriseOrderDto != null)
+            if (listInfo != null && listInfo.Rows.Count > 0 && centerReportStatisticsDto.EnterpriseOrderDto != null)
             {
                 // 企业办件
-                centerReportStatisticsDto.enterpriseOrderDto.OrderCount = centerReportStatisticsDto.enterpriseOrderDto.OrderCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseAllCount"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CompletedAging = centerReportStatisticsDto.enterpriseOrderDto.CompletedAging + Convert.ToInt32(listInfo.Rows[0]["EnterpriseWorkTime"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CityOrderCount = centerReportStatisticsDto.enterpriseOrderDto.CityOrderCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCity"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CityCompletedAging = centerReportStatisticsDto.enterpriseOrderDto.CityCompletedAging + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCityWorkTime"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CountyOrderCount = centerReportStatisticsDto.enterpriseOrderDto.CountyOrderCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCounty"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CountyCompletedAging = centerReportStatisticsDto.enterpriseOrderDto.CountyCompletedAging + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCountyWorkTime"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CenterOrderCount = centerReportStatisticsDto.enterpriseOrderDto.CenterOrderCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCenter"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CenterCompletedAging = centerReportStatisticsDto.enterpriseOrderDto.CenterCompletedAging + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCenterWorkTime"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.OrderCount = centerReportStatisticsDto.EnterpriseOrderDto.OrderCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseAllCount"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CompletedAging = centerReportStatisticsDto.EnterpriseOrderDto.CompletedAging + Convert.ToInt32(listInfo.Rows[0]["EnterpriseWorkTime"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CityOrderCount = centerReportStatisticsDto.EnterpriseOrderDto.CityOrderCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCity"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CityCompletedAging = centerReportStatisticsDto.EnterpriseOrderDto.CityCompletedAging + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCityWorkTime"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CountyOrderCount = centerReportStatisticsDto.EnterpriseOrderDto.CountyOrderCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCounty"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CountyCompletedAging = centerReportStatisticsDto.EnterpriseOrderDto.CountyCompletedAging + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCountyWorkTime"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CenterOrderCount = centerReportStatisticsDto.EnterpriseOrderDto.CenterOrderCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCenter"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CenterCompletedAging = centerReportStatisticsDto.EnterpriseOrderDto.CenterCompletedAging + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCenterWorkTime"]);
                 // 企业满意度
-                centerReportStatisticsDto.enterpriseOrderDto.VisitdCount = centerReportStatisticsDto.enterpriseOrderDto.VisitdCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseVisit"]);
-                centerReportStatisticsDto.enterpriseOrderDto.Dissatisfied = centerReportStatisticsDto.enterpriseOrderDto.Dissatisfied + Convert.ToInt32(listInfo.Rows[0]["EnterpriseDisSatisfaction"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CityDissatisfied = centerReportStatisticsDto.enterpriseOrderDto.CityDissatisfied + Convert.ToInt32(listInfo.Rows[0]["CityCount"]) - Convert.ToInt32(listInfo.Rows[0]["CitySatisfactionCount"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CountyDissatisfied = centerReportStatisticsDto.enterpriseOrderDto.CountyDissatisfied + Convert.ToInt32(listInfo.Rows[0]["CountyCount"]) - Convert.ToInt32(listInfo.Rows[0]["CountySatisfactionCount"]);
-                centerReportStatisticsDto.enterpriseOrderDto.Satisfied = centerReportStatisticsDto.enterpriseOrderDto.Satisfied + Convert.ToInt32(listInfo.Rows[0]["AllCount"]) - Convert.ToInt32(listInfo.Rows[0]["SatisfactionCount"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CitySatisfied = centerReportStatisticsDto.enterpriseOrderDto.CitySatisfied + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCitySatisfaction"]);
-                centerReportStatisticsDto.enterpriseOrderDto.CountySatisfied = centerReportStatisticsDto.enterpriseOrderDto.CountySatisfied + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCountySatisfaction"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.VisitdCount = centerReportStatisticsDto.EnterpriseOrderDto.VisitdCount + Convert.ToInt32(listInfo.Rows[0]["EnterpriseVisit"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.Dissatisfied = centerReportStatisticsDto.EnterpriseOrderDto.Dissatisfied + Convert.ToInt32(listInfo.Rows[0]["EnterpriseDisSatisfaction"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CityDissatisfied = centerReportStatisticsDto.EnterpriseOrderDto.CityDissatisfied + Convert.ToInt32(listInfo.Rows[0]["CityCount"]) - Convert.ToInt32(listInfo.Rows[0]["CitySatisfactionCount"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CountyDissatisfied = centerReportStatisticsDto.EnterpriseOrderDto.CountyDissatisfied + Convert.ToInt32(listInfo.Rows[0]["CountyCount"]) - Convert.ToInt32(listInfo.Rows[0]["CountySatisfactionCount"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.Satisfied = centerReportStatisticsDto.EnterpriseOrderDto.Satisfied + Convert.ToInt32(listInfo.Rows[0]["AllCount"]) - Convert.ToInt32(listInfo.Rows[0]["SatisfactionCount"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CitySatisfied = centerReportStatisticsDto.EnterpriseOrderDto.CitySatisfied + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCitySatisfaction"]);
+                centerReportStatisticsDto.EnterpriseOrderDto.CountySatisfied = centerReportStatisticsDto.EnterpriseOrderDto.CountySatisfied + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCountySatisfaction"]);
             }
 
-            #endregion
-
-            return centerReportStatisticsDto;
+			#endregion
+
+			#region 企业信件分类
+			//信件来源
+			var enterpriseAcceptTypeData = await _orderRepository.Queryable(false, false, false)
+				.Where(p => p.CreationTime >= StartTime && p.CreationTime <= EndTime && p.IdentityType == EIdentityType.Enterprise)
+				.Select(it => new
+				{
+					AcceptTypeCode = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(it.AcceptTypeCode), "40", it.AcceptTypeCode),
+					FileOrgIsCenter = it.FileOrgIsCenter.HasValue ? it.FileOrgIsCenter : true,
+					CreationTimeHandleDurationWorkday = it.CreationTimeHandleDurationWorkday.HasValue ? it.CenterToOrgHandleDurationWorkday : 0,
+					CenterToOrgHandleDurationWorkday = it.CenterToOrgHandleDurationWorkday.HasValue ? it.CenterToOrgHandleDurationWorkday : 0,
+				})
+				.MergeTable()//将查询出来的结果合并成一个新表
+				 .GroupBy(temp => new { temp.AcceptTypeCode })//对新表进行分组
+				 .Select(temp => new CenterReportOrderSourceChannelDto
+				 {
+					 Code = temp.AcceptTypeCode,
+					 CountNum = SqlFunc.AggregateCount(temp.AcceptTypeCode),
+					 CompletedAging = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter == true, temp.CreationTimeHandleDurationWorkday, temp.CenterToOrgHandleDurationWorkday))
+				 })
+				 .ToListAsync();
+			List<CenterReportOrderSourceChannelDto> enterpriseAcceptType = new();
+			var enterpriseAcceptTypeDic = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType);
+			foreach (var item in enterpriseAcceptTypeDic)
+			{
+				enterpriseAcceptType.Add(new CenterReportOrderSourceChannelDto
+				{
+					AllCountNum = sourceChannelCount,
+					Name = item.DicDataName,
+					Code = item.DicTypeCode,
+					CountNum = enterpriseAcceptTypeData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0,
+					CompletedAging = enterpriseAcceptTypeData.Find(p => p.Code == item.DicDataValue)?.CompletedAging ?? 0
+				});
+			}
+
+			if (listPurOld != null && listPurOld.Rows.Count > 0 && enterpriseAcceptType != null)
+			{
+				foreach (var item in enterpriseAcceptType)
+				{
+					if (item.Code == "10")
+						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Consult"]);            // 咨询
+					else if (item.Code == "15")
+						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Suggest"]);            // 建议
+					else if (item.Code == "20")
+						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["SeekHelp"]);           // 求助
+					else if (item.Code == "25")
+						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Praise"]);             // 表扬
+					else if (item.Code == "30")
+						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Report"]);             // 举报
+					else if (item.Code == "35")
+						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Complaint"]);          // 投诉
+				}
+			}
+
+			centerReportStatisticsDto.EnterpriseCenterReportOrderAcceptTypes = enterpriseAcceptType;
+			#endregion
+
+			return centerReportStatisticsDto;
         }
 
-        /// <summary>
-        /// 中心报表统计--宜宾
-        /// </summary>
-        /// <param name="StartTime"></param>
-        /// <param name="EndTime"></param>
-        /// <returns></returns>
-        [HttpGet("center_report_forms_statistics_v1")]
-        public async Task<CenterReportStatisticsDto> CenterReportFormsStatisticsV1(DateTime StartTime, DateTime EndTime)
-        {
-            CenterReportStatisticsDto centerReportStatisticsDto = new();
-
-            // 查询工单老数据
-            var listOld = await _orderRepository.CenterReportFormsStatistics(StartTime, EndTime);
-            // 查询类型老数据
-            var listPurOld = await _orderRepository.CenterReportPurTypeStatistics(StartTime, EndTime);
-            // 查询部门老数据
-            var listCity = await _orderRepository.CenterReportDepartStatistics(StartTime, EndTime, "市直部门");
-            var listCounty = await _orderRepository.CenterReportDepartStatistics(StartTime, EndTime, "区县部门");
-
-            // 查询老数据详情
-            //var listTest = await _orderRepository.CenterReportNewStatistics(StartTime, EndTime);
-
-            //信件总量
-            int sourceChannelCount = await _orderRepository.Queryable().Where(p => p.CreationTime >= StartTime && p.CreationTime <= EndTime).CountAsync();
-
-            #region 通话记录
-            //通话记录
-            var callData = await _trCallRecordRepository.Queryable()
-                .Where(p => p.CreatedTime >= StartTime && p.CreatedTime <= EndTime && p.Gateway != "82826886" && SqlFunc.Length(p.Gateway) != 4)
-                .Select(o => new CenterReportCallDto
-                {
-                    EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.On, 1, 0)),//有效
-                    InvalidCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.NoOn /*&& o.BeginIvrTime.HasValue && o.BeginQueueTime.HasValue && o.BeginRingTime.HasValue*/, 1, 0)), //无效(排除队列挂断和IVR挂断)
-                    QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.QueueTims > 0 && o.RingTimes == 0 && o.OnState == EOnState.NoOn, 1, 0)), //队列挂断
-                    IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.BeginIvrTime.HasValue && !o.BeginQueueTime.HasValue && !o.BeginRingTime.HasValue && o.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
-                })
-                .FirstAsync();
-            if (callData != null)
-                callData.InvalidCount = callData.InvalidCount - callData.QueueByeCount - callData.IvrByeCount;
-
-            if (listOld != null && callData != null)
-            {
-                callData.EffectiveCount = callData.EffectiveCount + Convert.ToInt32(listOld.Rows[0]["CallInConn"]);   // 有效
-                callData.InvalidCount = callData.InvalidCount + Convert.ToInt32(listOld.Rows[0]["CallInNotConn"]);    // 无效
-                callData.QueueByeCount = callData.QueueByeCount + Convert.ToInt32(listOld.Rows[0]["CallInQueue"]);    // 队列挂断
-                callData.IvrByeCount = callData.IvrByeCount + Convert.ToInt32(listOld.Rows[0]["CallInIVR"]);          // IVR挂断
-            }
-
-            centerReportStatisticsDto.CenterReportCall = callData;
-
-            #endregion
-
-            #region 工单
-            //工单
-            var orderData = await _orderRepository.Queryable()
-                .Where(p => p.CreationTime >= StartTime && p.CreationTime <= EndTime)
-                .Select(x => new CenterReportOrderDto
-                {
-                    EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
-                    InvalidCount = 0,
-                    CompletedCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Status >= EOrderStatus.Filed, 1, 0)),
-                    InProgressCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Status < EOrderStatus.Filed, 1, 0))
-                })
-                .FirstAsync();
-
-            if (listOld != null && orderData != null)
-            {
-                orderData.EffectiveCount = orderData.EffectiveCount + Convert.ToInt32(listOld.Rows[0]["OrderNormalNum"]);   // 有效
-                orderData.InvalidCount = orderData.InvalidCount + Convert.ToInt32(listOld.Rows[0]["OrderInvalidNum"]);      // 无效
-                orderData.CompletedCount = orderData.CompletedCount + Convert.ToInt32(listOld.Rows[0]["OrderEndNum"]);      // 已办
-                orderData.InProgressCount = orderData.InProgressCount + Convert.ToInt32(listOld.Rows[0]["OrderWaitNum"]);   // 在办
-            }
-
-            centerReportStatisticsDto.CenterReportOrder = orderData;
-            #endregion
-
-            #region 信件来源
-            //信件来源
-            var sourceChannelData = await _orderRepository.Queryable()
-                .Where(p => p.CreationTime >= StartTime && p.CreationTime <= EndTime)
-                .Select(it => new
-                {
-                    SourceChannelCode = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(it.SourceChannelCode), "QT", it.SourceChannelCode)
-                })
-                .MergeTable()//将查询出来的结果合并成一个新表
-                 .GroupBy(it => new { it.SourceChannelCode })//对新表进行分组
-                 .Select(it => new CenterReportOrderSourceChannelDto
-                 {
-                     Code = it.SourceChannelCode,
-                     CountNum = SqlFunc.AggregateCount(it.SourceChannelCode)
-                 })
-                 .ToListAsync();
-            List<CenterReportOrderSourceChannelDto> sourceChannel = new()
-            {
-                new CenterReportOrderSourceChannelDto
-                {
-                    Name = "来源总量",
-                    Code = "All",
-                    CountNum = sourceChannelCount
-                }
-            };
-            var sourceChannelDic = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.SourceChannel);
-            foreach (var item in sourceChannelDic)
-            {
-                sourceChannel.Add(new CenterReportOrderSourceChannelDto
-                {
-                    Name = item.DicDataName,
-                    Code = item.DicDataValue,
-                    CountNum = sourceChannelData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0
-                });
-            }
-
-            if (listOld != null && sourceChannel != null)
-            {
-                foreach (var item in sourceChannel)
-                {
-                    if (item.Code == "All")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromAllNum"]);            //总量
-                    else if (item.Code == "YTW")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromInternet"]);          // 英特网
-                    else if (item.Code == "RGDH")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPhone"]);             // 电话
-                    else if (item.Code == "YBS")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatformYBS"]);       // 宜办事
-                    else if (item.Code == "QT")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromOther"]);             // 其他
-                    else if (item.Code == "ZJ")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromSelfBuild"]);         // 自建
-                    else if (item.Code == "WX")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromWeChat"]);            // 微信
-                    else if (item.Code == "WB")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromWeibo"]);             // 微博
-                    else if (item.Code == "AP")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromApp"]);               // APP
-                    else if (item.Code == "ZHYB")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromSmartYibin"]);        // 智慧宜宾
-                    else if (item.Code == "ZZPT")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatformZZ"]);        // 综治平台
-                    else if (item.Code == "S12328")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatform12328"]);     // 省12328平台
-                    else if (item.Code == "SZYSM")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromMayorNetizen"]);      // 市长与市民
-                    else if (item.Code == "YBRMT")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatformRMT"]);       // 宜宾融媒体
-                    else if (item.Code == "S12345")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatformProvince"]);  // 省12345平台
-                    else if (item.Code == "SZMHD")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatformZMHD"]);      // 省政民互动
-                    else if (item.Code == "SZHZ")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatformSZHZ"]);      // 市州互转
-                    else if (item.Code == "YB110")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatform110"]);       // 宜宾110平台
-                    else if (item.Code == "SMZXBNCS")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatformBBCS"]);      // 市民中心办不成事窗口
-                    else if (item.Code == "IYB")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listOld.Rows[0]["FromPlatformIYB"]);       // i宜宾
-                }
-            }
-
-            centerReportStatisticsDto.CenterReportOrderSourceChannels = sourceChannel;
-
-            #endregion
-
-            #region 信件分类
-            //信件来源
-            var acceptTypeData = await _orderRepository.Queryable(false, false, false)
-                .Where(p => p.CreationTime >= StartTime && p.CreationTime <= EndTime)
-                .Select(it => new
-                {
-                    AcceptTypeCode = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(it.AcceptTypeCode), "40", it.AcceptTypeCode)
-                })
-                .MergeTable()//将查询出来的结果合并成一个新表
-                 .GroupBy(it => new { it.AcceptTypeCode })//对新表进行分组
-                 .Select(it => new CenterReportOrderSourceChannelDto
-                 {
-                     Code = it.AcceptTypeCode,
-                     CountNum = SqlFunc.AggregateCount(it.AcceptTypeCode)
-                 })
-                 .ToListAsync();
-            List<CenterReportOrderSourceChannelDto> acceptType = new();
-            var acceptTypeDic = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType);
-            foreach (var item in acceptTypeDic)
-            {
-                acceptType.Add(new CenterReportOrderSourceChannelDto
-                {
-                    AllCountNum = sourceChannelCount,
-                    Name = item.DicDataName,
-                    Code = item.DicDataValue,
-                    CountNum = acceptTypeData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0
-                });
-            }
-
-            if (listPurOld != null && acceptType != null)
-            {
-                foreach (var item in acceptType)
-                {
-                    if (item.Code == "10")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Consult"]);            // 咨询
-                    else if (item.Code == "15")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Suggest"]);            // 建议
-                    else if (item.Code == "20")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["SeekHelp"]);           // 求助
-                    else if (item.Code == "25")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Praise"]);             // 表扬
-                    else if (item.Code == "30")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Report"]);             // 举报
-                    else if (item.Code == "35")
-                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Complaint"]);          // 投诉
-                }
-            }
-
-            centerReportStatisticsDto.CenterReportOrderAcceptTypes = acceptType;
-            #endregion
-
-            #region 信件回访量
-            //信件回访量
-            CenterReportVisitdDto centerReportVisitd = new()
-            {
-                Visitd = await _orderVisitRepository.Queryable()
-              .Where(x => x.VisitTime >= StartTime && x.VisitTime <= EndTime && x.VisitState == EVisitState.Visited).CountAsync(),
-                WaitVisitd = await _orderVisitRepository.Queryable()
-             .Where(x => x.VisitTime >= StartTime && x.VisitTime <= EndTime && x.VisitState != EVisitState.None && x.VisitState != EVisitState.Visited).CountAsync()
-            };
-
-            //部门
-            var listOrg = await _orderVisitDetailRepository.Queryable()
-                .LeftJoin<OrderVisit>((it, o) => it.VisitId == o.Id)
-                .Where((it, o) => it.VisitTarget == EVisitTarget.Org && o.VisitTime >= StartTime && o.VisitTime <= EndTime && o.VisitState == EVisitState.Visited)
-                 .Select((it, o) => new Satisfaction
-                 {
-                     Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 1, 0)),
-                     Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 0, 1)),
-                 })
-                .ToListAsync();
-
-            if (listOrg != null && listOrg.Count > 0)
-            {
-                var SatisfiedCount = listOrg[0].Satisfied + listOrg[0].Satisfied;
-                if (SatisfiedCount > 0 && listOrg[0].Satisfied > 0)
-                    centerReportVisitd.OrgRate = Math.Round((listOrg[0].Satisfied / (double)SatisfiedCount) * 100, 2);
-            }
-
-            //if (centerReportVisitd.Visitd > 0 && listOrg != null && listOrg.Count > 0 && listOrg[0].Satisfied > 0)
-            //centerReportVisitd.OrgRate = Math.Round((listOrg[0].Satisfied / (double)centerReportVisitd.Visitd) * 100, 2);
-
-            //坐席
-            var listSet = await _orderVisitDetailRepository.Queryable()
-                .LeftJoin<OrderVisit>((it, o) => it.VisitId == o.Id)
-                .Where((it, o) => it.VisitTarget == EVisitTarget.Seat && o.VisitTime >= StartTime && o.VisitTime <= EndTime && o.VisitState == EVisitState.Visited)
-                .Select((it, o) => new Satisfaction
-                {
-                    Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(it.SeatEvaluate == ESeatEvaluate.NoSatisfied, 1, 0)),
-                    Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(it.SeatEvaluate != ESeatEvaluate.NoSatisfied, 1, 0)),
-                }).ToListAsync();
-
-            if (listSet != null && listSet.Count > 0)
-            {
-                var SatisfiedCount = listSet[0].Satisfied + listSet[0].Satisfied;
-                if (SatisfiedCount > 0 && listSet[0].Satisfied > 0)
-                    centerReportVisitd.OrgRate = Math.Round((listSet[0].Satisfied / (double)SatisfiedCount) * 100, 2);
-            }
-
-            //if (centerReportVisitd.Visitd > 0 && listSet != null && listSet.Count > 0 && listSet[0].Satisfied > 0)
-            //    centerReportVisitd.SeatsRate = Math.Round((listSet[0].Satisfied / (double)centerReportVisitd.Visitd) * 100, 2);
-
-            if (listOld != null && centerReportVisitd != null)
-            {
-                centerReportVisitd.Visitd = centerReportVisitd.Visitd + Convert.ToInt32(listOld.Rows[0]["VisitAlreadyNum"]);                    // 已回访
-                centerReportVisitd.WaitVisitd = centerReportVisitd.WaitVisitd + Convert.ToInt32(listOld.Rows[0]["VisitWaitNum"]);               // 待回访
-                centerReportVisitd.SeatsRate = Math.Round((centerReportVisitd.SeatsRate + Convert.ToDouble(listOld.Rows[0]["SatisfactionSeat"])) / 2, 2);      // 坐席满意度
-                centerReportVisitd.OrgRate = Math.Round((centerReportVisitd.OrgRate + Convert.ToDouble(listOld.Rows[0]["SatisfactionDepartment"])) / 2, 2);   // 部门满意度
-            }
-
-            centerReportStatisticsDto.CenterReportVisitd = centerReportVisitd;
-            #endregion
-
-            #region 信件分布情况
-            //市直部门
-
-            var listOrgStatisticsCityAll = await _orderRepository.Queryable()
-                .Where(o => o.CreationTime >= StartTime && o.CreationTime <= EndTime)
-                .Select(o => new
-                {
-                    OrgCode = o.ActualHandleOrgCode == null || o.ActualHandleOrgCode == "" ? "001" : o.ActualHandleOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
-                })
-                .MergeTable()
-                .LeftJoin<SystemOrganize>((o, s) => o.OrgCode == s.Id)
-                 .Where((o, s) => s.OrgType == EOrgType.City || s.OrgType == EOrgType.Province)
-                .GroupBy((o, s) => new
-                {
-                    o.OrgCode,
-                    s.Name
-                })
-                .Select((o, s) => new OrgStatistics
-                {
-                    CountNum = SqlFunc.AggregateCount(o.OrgCode),
-                    OrgCode = o.OrgCode,
-                    OrgName = s.Name
-                }).ToListAsync();
-
-            if (listCity != null && listOrgStatisticsCityAll != null)
-            {
-                var arrOrgCode = "";
-                foreach (var item in listOrgStatisticsCityAll)
-                {
-                    for (int i = 0; i < listCity.Rows.Count; i++)
-                    {
-                        var orgCode1 = item.OrgCode;
-                        var orgCode2 = listCity.Rows[i]["OrgCode"].ToString();
-                        if (orgCode1 == orgCode2)
-                        {
-                            arrOrgCode += "'" + orgCode1 + "',";
-                            item.CountNum = item.CountNum + Convert.ToInt32(listCity.Rows[i]["OrderAllNum"]);
-                        }
-                    }
-                }
-                for (int i = 0; i < listCity.Rows.Count; i++)
-                {
-                    var orgCode = listCity.Rows[i]["OrgCode"].ToString();
-                    if (arrOrgCode.IndexOf("'" + orgCode + "'") == -1)
-                    {
-                        listOrgStatisticsCityAll.Add(
-                        new OrgStatistics
-                        {
-                            OrgCode = listCity.Rows[i]["OrgCode"].ToString(),
-                            OrgName = listCity.Rows[i]["Name"].ToString(),
-                            CountNum = Convert.ToInt32(listCity.Rows[i]["OrderAllNum"])
-                        });
-                    }
-                }
-            }
-
-            centerReportStatisticsDto.OrgStatisticsCityAll = new OrgStatisticsAll
-            {
-                OrgStatistics = listOrgStatisticsCityAll
-            };
-
-            //区县部门
-            var listOrgStatisticsAreaAll = await _orderRepository.Queryable()
-                .Where(o => o.CreationTime >= StartTime && o.CreationTime <= EndTime)
-                .Select(o => new
-                {
-                    OrgCode = o.ActualHandleOrgCode == null || o.ActualHandleOrgCode == "" ? "001" : o.ActualHandleOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
-                })
-                .MergeTable()
-                .LeftJoin<SystemOrganize>((o, s) => o.OrgCode == s.Id)
-                 .Where((o, s) => s.OrgType == EOrgType.County)
-                .GroupBy((o, s) => new
-                {
-                    o.OrgCode,
-                    s.Name
-                })
-                .Select((o, s) => new OrgStatistics
-                {
-                    CountNum = SqlFunc.AggregateCount(o.OrgCode),
-                    OrgCode = o.OrgCode,
-                    OrgName = s.Name
-                }).ToListAsync();
-
-            if (listCounty != null && listOrgStatisticsAreaAll != null)
-            {
-                var arrOrgCode = "";
-                foreach (var item in listOrgStatisticsAreaAll)
-                {
-                    for (int i = 0; i < listCounty.Rows.Count; i++)
-                    {
-                        var orgCode1 = item.OrgCode;
-                        var orgCode2 = listCounty.Rows[i]["OrgCode"].ToString();
-                        if (orgCode1 == orgCode2)
-                        {
-                            arrOrgCode += "'" + orgCode1 + "',";
-                            item.CountNum = item.CountNum + Convert.ToInt32(listCounty.Rows[i]["OrderAllNum"]);
-                        }
-                    }
-                }
-                for (int i = 0; i < listCounty.Rows.Count; i++)
-                {
-                    var orgCode = listCounty.Rows[i]["OrgCode"].ToString();
-                    if (arrOrgCode.IndexOf("'" + orgCode + "'") == -1)
-                    {
-                        listOrgStatisticsAreaAll.Add(
-                        new OrgStatistics
-                        {
-                            OrgCode = listCounty.Rows[i]["OrgCode"].ToString(),
-                            OrgName = listCounty.Rows[i]["Name"].ToString(),
-                            CountNum = Convert.ToInt32(listCounty.Rows[i]["OrderAllNum"])
-                        });
-                    }
-                }
-            }
-
-            centerReportStatisticsDto.OrgStatisticsAreaAll = new OrgStatisticsAll
-            {
-                OrgStatistics = listOrgStatisticsAreaAll
-            };
-            #endregion
-
-            #region 企业服务办件情况
-            var enterpriseOrderDto = await _orderRepository.Queryable()
-                .LeftJoin<SystemOrganize>((x, so) => x.ActualHandleOrgCode == so.Id)
-                .Where((x, so) => x.CreationTime >= StartTime && x.CreationTime <= EndTime && x.IdentityType == EIdentityType.Enterprise)
-                .Select((x, so) => new
-                {
-                    FileOrgIsCenter = x.FileOrgIsCenter.Value,
-                    CreationTimeHandleDurationWorkday = x.CreationTimeHandleDurationWorkday.HasValue ? x.CreationTimeHandleDurationWorkday : 0,
-                    CenterToOrgHandleDurationWorkday = x.CenterToOrgHandleDurationWorkday.HasValue ? x.CenterToOrgHandleDurationWorkday : 0,
-                    OrgType = so.OrgType
-                })
-                .MergeTable()
-                .Select(temp => new EnterpriseOrderDto
-                {
-                    OrderCount = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
-                    CompletedAging = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter, temp.CreationTimeHandleDurationWorkday, temp.CenterToOrgHandleDurationWorkday)),
-                    CityOrderCount = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter == false && temp.OrgType == EOrgType.City, 1, 0)),//市级
-                    CityCompletedAging = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter == false && temp.OrgType == EOrgType.City, temp.CenterToOrgHandleDurationWorkday, 0)),
-                    CountyOrderCount = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter == false && temp.OrgType == EOrgType.County, 1, 0)),//区县
-                    CountyCompletedAging = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter == false && temp.OrgType == EOrgType.County, temp.CenterToOrgHandleDurationWorkday, 0)),
-                    CenterOrderCount = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter, 1, 0)),//中心
-                    CenterCompletedAging = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter, temp.CreationTimeHandleDurationWorkday, 0)),
-                })
-                .FirstAsync();
-
-            centerReportStatisticsDto.enterpriseOrderDto = enterpriseOrderDto;
-            var enterpriseOrderDto2 = await _orderVisitDetailRepository.Queryable()
-                .Includes(it => it.OrderVisit, ov => ov.Order)
-                .LeftJoin<SystemOrganize>((it, so) => it.VisitOrgCode == so.Id)
-                .Where((it, so) => it.VisitTarget == EVisitTarget.Org && it.OrderVisit.VisitTime >= StartTime && it.OrderVisit.VisitTime <= EndTime && it.OrderVisit.VisitState == EVisitState.Visited)
-                .GroupBy((it, so) => it.Id)
-                 .Select((it, so) => new EnterpriseOrderDto
-                 {
-                     VisitdCount = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
-                     Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 1, 0)),
-                     Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 1, 0)),
-                     CityDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2")) && so.OrgType == EOrgType.City, 1, 0)),
-                     CitySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2") && so.OrgType == EOrgType.City, 1, 0)),
-                     CountyDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2")) && so.OrgType == EOrgType.County, 1, 0)),
-                     CountySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2") && so.OrgType == EOrgType.County, 1, 0)),
-                 })
-                .FirstAsync();
-
-            centerReportStatisticsDto.enterpriseOrderDto.VisitdCount = enterpriseOrderDto2.VisitdCount;
-            centerReportStatisticsDto.enterpriseOrderDto.Dissatisfied = enterpriseOrderDto2.Dissatisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.CityDissatisfied = enterpriseOrderDto2.CityDissatisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.CountyDissatisfied = enterpriseOrderDto2.CountyDissatisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.Satisfied = enterpriseOrderDto2.Satisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.CitySatisfied = enterpriseOrderDto2.CitySatisfied;
-            centerReportStatisticsDto.enterpriseOrderDto.CountySatisfied = enterpriseOrderDto2.CountySatisfied;
-
-            #endregion
-
-            return centerReportStatisticsDto;
-        }
 
         /// <summary>
         /// 中心报表统计--自贡
@@ -4243,7 +3888,9 @@ namespace Hotline.Api.Controllers.Bi
                 DefaultSatisfiedCount = list.Select(x => x.DefaultSatisfiedCount).Sum(),
                 NoSatisfiedCount = list.Select(x => x.NoSatisfiedCount).Sum(),
                 NoEvaluateCount = list.Select(x => x.NoEvaluateCount).Sum(),
-                NoPutThroughCount = list.Select(x => x.NoPutThroughCount).Sum()
+                NoPutThroughCount = list.Select(x => x.NoPutThroughCount).Sum(),
+                NormalCount = list.Select(x => x.NormalCount).Sum(),//未接通
+                VeryNoSatisfiedCount = list.Select(x => x.NormalCount).Sum(),//非常不满意
             };
             list.Add(total);
             //区县合计
@@ -4259,7 +3906,10 @@ namespace Hotline.Api.Controllers.Bi
                 DefaultSatisfiedCount = countyList.Select(x => x.DefaultSatisfiedCount).Sum(),
                 NoSatisfiedCount = countyList.Select(x => x.NoSatisfiedCount).Sum(),
                 NoEvaluateCount = countyList.Select(x => x.NoEvaluateCount).Sum(),
-                NoPutThroughCount = countyList.Select(x => x.NoPutThroughCount).Sum()
+                NoPutThroughCount = countyList.Select(x => x.NoPutThroughCount).Sum(),
+                NormalCount = countyList.Select(x => x.NormalCount).Sum(),//未接通
+                VeryNoSatisfiedCount = countyList.Select(x => x.NormalCount).Sum(),//非常不满意
+
             };
             list.Add(countyTotal);
             //市直合计
@@ -4275,7 +3925,9 @@ namespace Hotline.Api.Controllers.Bi
                 DefaultSatisfiedCount = cityList.Select(x => x.DefaultSatisfiedCount).Sum(),
                 NoSatisfiedCount = cityList.Select(x => x.NoSatisfiedCount).Sum(),
                 NoEvaluateCount = cityList.Select(x => x.NoEvaluateCount).Sum(),
-                NoPutThroughCount = cityList.Select(x => x.NoPutThroughCount).Sum()
+                NoPutThroughCount = cityList.Select(x => x.NoPutThroughCount).Sum(),
+                NormalCount = cityList.Select(x => x.NormalCount).Sum(),//未接通
+                VeryNoSatisfiedCount = cityList.Select(x => x.NormalCount).Sum(),//非常不满意
             };
             list.Add(cityTotal);
             return list;
@@ -4751,17 +4403,23 @@ namespace Hotline.Api.Controllers.Bi
 
             var wfModule = await _workflowApplication.GetWorkflowModuleAsync(WorkflowModuleConsts.OrderHandle, HttpContext.RequestAborted);
             var definition = wfModule.Definition;
+            var attitudeType = EnumExts.GetDescriptions<EAttitudeType>();
+            if (_appOptions.Value.IsZiGong == false)
+            {
+                attitudeType = attitudeType.Where(m => new int[] { 2 }.Contains(m.Key) == false).ToList();
+            }
             return new Dictionary<string, dynamic>
             {
                 { "visitSatisfaction", _systemDicDataCacheManager.GetVisitSatisfaction() },
                 { "orgsOptions", items },
-                { "attitudeType", EnumExts.GetDescriptions<EAttitudeType>() },
+                { "attitudeType", attitudeType},
                 { "visitType",EnumExts.GetDescriptions<EVisitType>() },
                 { "channelOptions",_sysDicDataCacheManager.GetSysDicDataCache(TimeLimitBaseDataConsts.SourceChannel) },
                 { "acceptTypeOptions",_sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType)},
                 { "orderStatusOptions", EnumExts.GetDescriptions<EOrderStatus>()},
-                { "currentStepOptions",definition?.Steps.Select(x => new Kv(x.Code, x.Name))}
-            };
+                { "currentStepOptions",definition?.Steps.Select(x => new Kv(x.Code, x.Name))},
+                 { "visitMananer", _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitManner) },
+        };
         }
 
         /// <summary>
@@ -5227,6 +4885,7 @@ namespace Hotline.Api.Controllers.Bi
             var (total, items) = await _orderApplication.HotspotAndAcceptTypeStatisticsDetail(dto).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
             return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
         }
+
         /// <summary>
         /// 热点受理类型明细导出
         /// </summary>
@@ -5590,6 +5249,7 @@ namespace Hotline.Api.Controllers.Bi
             });
             return items;
         }
+
         /// <summary>
         /// 中心受理统计导出
         /// </summary>
@@ -5643,6 +5303,7 @@ namespace Hotline.Api.Controllers.Bi
             var (total, items) = await _orderApplication.OrderCenterAcceptUser(dto).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
             return new PagedDto<OrderCenterAcceptUserVo>(total, items);
         }
+
         /// <summary>
         /// 中心受理值班坐席统计导出
         /// </summary>
@@ -5684,6 +5345,7 @@ namespace Hotline.Api.Controllers.Bi
             var items = await _orderRepository.OrderCenterAcceptHour(dto).ToListAsync(HttpContext.RequestAborted);
             return items;
         }
+
         /// <summary>
         /// 中心受理时间段统计导出
         /// </summary>
@@ -5871,7 +5533,128 @@ namespace Hotline.Api.Controllers.Bi
             return new PagedDto<OrderDelayDto>(total, _mapper.Map<IReadOnlyList<OrderDelayDto>>(items));
         }
 
+        /// <summary>
+        /// 工单热词分析
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("query_order_ts_details_list")]
+        public async Task<PagedDto<OrderTsDetailsDto>> QueryOrderTsDetailsList([FromQuery] PagedKeywordRequest dto)
+        {
+            var (total, items) = await _orderApplication.QueryOrderTsDetailsList(dto).ToPagedListAsync(dto, HttpContext.RequestAborted);
+
+            return new PagedDto<OrderTsDetailsDto>(total, _mapper.Map<IReadOnlyList<OrderTsDetailsDto>>(items));
+        }
+
+        /// <summary>
+        /// 工单热词分析导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("query_order_ts_details_list/export")]
+        public async Task<FileStreamResult> ExportQueryOrderTsDetailsList([FromBody] ExportExcelDto<PagedKeywordRequest> dto)
+        {
+            var query = _orderApplication.QueryOrderTsDetailsList(dto.QueryDto);
+
+            List<OrderTsDetailsDto> lists;
+            if (dto.IsExportAll)
+            {
+                lists = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                lists = items;
+            }
+
+            var listDtos = _mapper.Map<ICollection<OrderTsDetailsDto>>(lists);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = listDtos
+                .Select(stu => _mapper.Map(stu, typeof(OrderTsDetailsDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "工单热词分析数据");
+
+        }
+
+        /// <summary>
+        /// 根据热词查询工单
+        /// </summary>
+        /// <param name="KeyWord"></param>
+        /// <returns></returns>
+        [HttpGet("get_query_order_ts_details_order_list")]
+        public async Task<List<OrderTsDetails>> GetQueryOrderTsDetailslOrderList(string KeyWord)
+        {
+            return await _orderTsDetailsRepository.Queryable()
+                   .Where(p => p.Terms == KeyWord)
+                   .ToListAsync(HttpContext.RequestAborted);
+        }
 
+        /// <summary>
+        /// 知识库引用
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("query_knowledge_quote_list")]
+        public async Task<PagedDto<OrderTsDetailsDto>> QueryKnowledgeQuoteList([FromQuery] PagedKeywordRequest dto)
+        {
+            var (total, items) = await _orderApplication.QueryKnowledgeQuoteList(dto).ToPagedListAsync(dto, HttpContext.RequestAborted);
 
+            return new PagedDto<OrderTsDetailsDto>(total, _mapper.Map<IReadOnlyList<OrderTsDetailsDto>>(items));
+        }
+
+        /// <summary>
+        /// 知识库引用导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("query_knowledge_quote_list/export")]
+        public async Task<FileStreamResult> ExportQueryKnowledgeQuoteList([FromBody] ExportExcelDto<PagedKeywordRequest> dto)
+        {
+            var query = _orderApplication.QueryKnowledgeQuoteList(dto.QueryDto);
+
+            List<OrderTsDetailsDto> lists;
+            if (dto.IsExportAll)
+            {
+                lists = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                lists = items;
+            }
+
+            var listDtos = _mapper.Map<ICollection<OrderTsDetailsDto>>(lists);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = listDtos
+                .Select(stu => _mapper.Map(stu, typeof(OrderTsDetailsDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "知识库引用数据");
+
+        }
+
+        /// <summary>
+        /// 根据知识库引用查询工单
+        /// </summary>
+        /// <param name="KeyWord"></param>
+        /// <returns></returns>
+        [HttpGet("get_query_knowledge_quote_order_list")]
+        public async Task<List<KnowledgeQuote>> GetQueryKnowledgeQuoteOrderList(string KeyWord)
+        {
+            return await _knowledgeQuoteRepository.Queryable()
+                   .Where(p => p.KnowledgeId == KeyWord)
+                   .ToListAsync(HttpContext.RequestAborted);
+        }
     }
 }

+ 134 - 6
src/Hotline.Api/Controllers/FileController.cs

@@ -9,6 +9,13 @@ using XF.Domain.Exceptions;
 using XF.Domain.Repository;
 using Hotline.Caching.Interfaces;
 using Microsoft.AspNetCore.Authorization;
+using DocumentFormat.OpenXml.Presentation;
+using Hotline.File;
+using NPOI.HPSF;
+using Hotline.Share.Requests;
+using SqlSugar;
+using Hotline.Tools;
+using Hotline.Share.Dtos.Order;
 
 namespace Hotline.Api.Controllers
 {
@@ -19,20 +26,24 @@ namespace Hotline.Api.Controllers
         private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
         private readonly IRepository<File.File> _fileRepository;
         private readonly ILogger<FileController> _logger;
+        private readonly IRepository<UploadAudioFiles> _uploadAudioFilesRepository;
 
         public FileController(
             ISessionContext sessionContext,
             IMapper mapper,
             ISystemDicDataCacheManager sysDicDataCacheManager,
             IRepository<File.File> fileRepository,
-            ILogger<FileController> logger)
+            ILogger<FileController> logger,
+            IRepository<UploadAudioFiles> uploadAudioFilesRepository)
         {
             _sessionContext = sessionContext;
             _mapper = mapper;
             _sysDicDataCacheManager = sysDicDataCacheManager;
             _fileRepository = fileRepository;
             _logger = logger;
+            _uploadAudioFilesRepository = uploadAudioFilesRepository;
         }
+
         #region 附件管理
         /// <summary>
         /// 新增附件
@@ -148,11 +159,128 @@ namespace Hotline.Api.Controllers
         [HttpGet("download-proxy")]
         public async Task<IActionResult> DownloadProxy([FromServices] IHttpClientFactory clientFactory, string path)
         {
-                using var client = clientFactory.CreateClient();
-                var responseMessage = await client.GetAsync(path, HttpContext.RequestAborted);
-                responseMessage.EnsureSuccessStatusCode();
-                var stream = await responseMessage.Content.ReadAsStreamAsync(HttpContext.RequestAborted);
-                return File(stream, responseMessage?.Content?.Headers?.ContentType?.MediaType);
+            using var client = clientFactory.CreateClient();
+            var responseMessage = await client.GetAsync(path, HttpContext.RequestAborted);
+            responseMessage.EnsureSuccessStatusCode();
+            var stream = await responseMessage.Content.ReadAsStreamAsync(HttpContext.RequestAborted);
+            return File(stream, responseMessage?.Content?.Headers?.ContentType?.MediaType);
+        }
+
+        #region 录音上传
+        /// <summary>
+        /// 上传录音保存
+        /// </summary>
+        /// <param name="dtos"></param>
+        /// <returns></returns>
+        [HttpPost("adduploadaudiofiles")]
+        public async Task<object> AddUploadAudioFiles([FromBody] List<FileDto> dtos)
+        {
+            if (dtos == null || dtos.Count == 0)
+                throw UserFriendlyException.SameMessage("请上传附件");
+            var successNum = 0;
+            var errorNum = 0;
+            foreach (var item in dtos)
+            {
+                var fileName = item.FileName;
+                string strSuffix = fileName.LastIndexOf(".") > 0 ? fileName.Substring(fileName.LastIndexOf(".") + 1) : "";
+                string strSubFileName = fileName.LastIndexOf(".") > 0 ? fileName.Substring(0, fileName.LastIndexOf(".")) : fileName;
+                UploadAudioFiles audioFiles = new UploadAudioFiles()
+                {
+                    FileId = item.Additions,
+                    FileName = item.FileName,
+                    Name = strSubFileName,
+                    Type = strSuffix,
+                    Path = item.Path,
+                    AllPath = item.AllPath
+                };
+                var id = await _uploadAudioFilesRepository.AddAsync(audioFiles, HttpContext.RequestAborted);
+                if (!string.IsNullOrEmpty(id))
+                    successNum++;
+                else
+                    errorNum++;
+
+            }
+            return new
+            {
+                successNum = successNum,
+                errorNum = errorNum
+            };
         }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="Ids"></param>
+        /// <returns></returns>
+        [HttpGet("deleteuploadaudiofiles")]
+        public async Task DeleteUploadAudioFiles([FromQuery] List<string> Ids)
+        {
+            if (Ids == null || Ids.Count == 0)
+                throw UserFriendlyException.SameMessage("请选择需要删除的数据");
+            foreach (var item in Ids)
+            {
+                await _uploadAudioFilesRepository.RemoveAsync(p => p.Id == item, false, HttpContext.RequestAborted);
+            }
+        }
+
+        /// <summary>
+        /// 查询列表
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("getaudiofileslist")]
+        public async Task<PagedDto<UploadAudioFilesRequestDto>> GetAudioFilesList([FromQuery] PagedKeywordRequest dto)
+        {
+            var (total, items) = await _uploadAudioFilesRepository.Queryable()
+                .Where(p => p.CreationTime >= dto.StartTime && p.CreationTime <= dto.EndTime)
+                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Name.Contains(dto.Keyword))
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, d => d.CreationTime, OrderByType.Asc) //创建时间升序
+                .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, d => d.CreationTime, OrderByType.Desc) //创建时间降序
+                 .ToPagedListAsync(dto, HttpContext.RequestAborted);
+
+            return new PagedDto<UploadAudioFilesRequestDto>(total, _mapper.Map<IReadOnlyList<UploadAudioFilesRequestDto>>(items));
+        }
+
+        /// <summary>
+        /// 查询列表导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("getaudiofileslist/export")]
+        public async Task<FileStreamResult> ExportGetAudioFilesList([FromBody] ExportExcelDto<PagedKeywordRequest> dto)
+        {
+            var query = _uploadAudioFilesRepository.Queryable()
+                .Where(p => p.CreationTime >= dto.QueryDto.StartTime && p.CreationTime <= dto.QueryDto.EndTime)
+                .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.Keyword), p => p.Name.Contains(dto.QueryDto.Keyword))
+                .OrderByIF(dto.QueryDto is { SortField: "creationTime", SortRule: 0 }, d => d.CreationTime, OrderByType.Asc) //创建时间升序
+                .OrderByIF(dto.QueryDto is { SortField: "creationTime", SortRule: 1 }, d => d.CreationTime, OrderByType.Desc);//创建时间降序
+
+            List<UploadAudioFiles> lists;
+            if (dto.IsExportAll)
+            {
+                lists = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                lists = items;
+            }
+
+            var listDtos = _mapper.Map<ICollection<UploadAudioFilesRequestDto>>(lists);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = listDtos
+                .Select(stu => _mapper.Map(stu, typeof(UploadAudioFilesRequestDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "录音上传数据导出");
+
+        }
+
+        #endregion
     }
 }

+ 56 - 27
src/Hotline.Api/Controllers/OrderController.cs

@@ -1,12 +1,15 @@
 using DotNetCore.CAP;
 using Hotline.Api.Filter;
 using Hotline.Application.CallCenter;
+using Hotline.Application.Contracts.Validators.FlowEngine;
 using Hotline.Application.ExportExcel;
 using Hotline.Application.FlowEngine;
 using Hotline.Application.Orders;
 using Hotline.Application.Quality;
 using Hotline.Application.Systems;
+using Hotline.Authentications;
 using Hotline.Caching.Interfaces;
+using Hotline.CallCenter.Calls;
 using Hotline.Configurations;
 using Hotline.ContingencyManagement.Notifies;
 using Hotline.EventBus;
@@ -18,7 +21,6 @@ using Hotline.Import;
 using Hotline.Orders;
 using Hotline.Orders.Notifications;
 using Hotline.OrderTranspond;
-using Hotline.Permissions;
 using Hotline.Push.FWMessage;
 using Hotline.Push.Notifies;
 using Hotline.Repository.SqlSugar.CallCenter;
@@ -30,9 +32,12 @@ using Hotline.Settings.Hotspots;
 using Hotline.Settings.TimeLimitDomain;
 using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Dtos.Order.Detail;
+using Hotline.Share.Dtos.Order.Handle;
 using Hotline.Share.Dtos.Order.Migration;
 using Hotline.Share.Dtos.Order.Publish;
 using Hotline.Share.Dtos.Settings;
@@ -41,6 +46,7 @@ using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Push;
 using Hotline.Share.Enums.Settings;
+using Hotline.Share.Mq;
 using Hotline.Share.Requests;
 using Hotline.Share.Tools;
 using Hotline.Tools;
@@ -56,22 +62,12 @@ using MiniExcelLibs;
 using SqlSugar;
 using System.Text;
 using System.Text.Json;
-using Hotline.Share.Dtos.Order.Handle;
 using XF.Domain.Authentications;
 using XF.Domain.Cache;
 using XF.Domain.Entities;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
 using XF.Utility.EnumExtensions;
-using Hotline.Application.Contracts.Validators.FlowEngine;
-using Hotline.Authentications;
-using Hotline.Share.Dtos.CallCenter;
-using NPOI.SS.Formula.Functions;
-using System.Threading;
-using Hotline.Share.Mq;
-using Hotline.CallCenter.Calls;
-using Hotline.Share.Dtos.Order.Detail;
-using Hotline.Share.Dtos.File;
 
 namespace Hotline.Api.Controllers;
 
@@ -412,14 +408,17 @@ public class OrderController : BaseController
     [HttpPost("batch-publish")]
     public async Task BatchPublishOrder([FromBody] BatchPublishOrderDto dto)
     {
-        var hasHuiQian = await _orderRepository.Queryable().AnyAsync(x => dto.Ids.Contains(x.Id) && x.CounterSignType != null);
+        //任务 127  市州通用-会签件需支持批量发布
+        //会签件也需支持批量发布;若会签件要批量发布,就默认不公开,只对实际办理部门进行回访即可
+        //var hasHuiQian = await _orderRepository.Queryable().AnyAsync(x => dto.Ids.Contains(x.Id) && x.CounterSignType != null);
+        var hasHuiQian = await _orderRepository.Queryable().AnyAsync(x => dto.Ids.Contains(x.Id));
         if (hasHuiQian)
             throw UserFriendlyException.SameMessage("选择的工单中含有会签工单, 不能批量发布. 请排除会签工单.");
 
         var hasProvince = await _orderRepository.Queryable().AnyAsync(x => dto.Ids.Contains(x.Id) && x.Source == ESource.ProvinceStraight);
         //if (hasProvince)
         //    throw UserFriendlyException.SameMessage("选择的工单中含有省工单, 不能批量发布. 请排除省工单.");
-        if (_appOptions.Value.IsYiBin)
+        if (_appOptions.Value.IsYiBin || _appOptions.Value.IsZiGong)
         {
             hasProvince = await _orderRepository.Queryable().AnyAsync(x => dto.Ids.Contains(x.Id) && x.IsProvince);
         }
@@ -543,7 +542,7 @@ public class OrderController : BaseController
             orderVisit.EmployeeId = string.Empty;
         }
 
-        if (order is { FileOrgIsCenter:true, CounterSignType: null } && !order.IsProvince)
+        if (order is { FileOrgIsCenter: true, CounterSignType: null } && !order.IsProvince)
         {
             orderVisit.VisitState = EVisitState.Visited;
             orderVisit.VisitTime = DateTime.Now;
@@ -1074,17 +1073,31 @@ public class OrderController : BaseController
     /// </summary>
     /// <returns></returns>
     [HttpGet("visit/basedata")]
-    public Dictionary<string, dynamic> VisitBaseData() => new Dictionary<string, dynamic>
+    public Dictionary<string, dynamic> VisitBaseData()
+    {
+        var voiceEvaluate = EnumExts.GetDescriptions<EVoiceEvaluate>();
+        var seatEvaluate = EnumExts.GetDescriptions<ESeatEvaluate>();
+        var visitSatisfaction = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction);
+        var visitManner = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitManner);
+        if (_appOptions.Value.IsZiGong == false)
         {
-            { "seatEvaluate", EnumExts.GetDescriptions<ESeatEvaluate>() },
+            seatEvaluate = seatEvaluate.Where(m => new int[] { -1, 1, 3 }.Contains(m.Key) == false).ToList();
+            visitSatisfaction = visitSatisfaction.Where(x => x.DicDataValue != "-1").ToList();
+            visitManner = visitManner.Where(x => x.DicDataValue != "-1").ToList();
+        }
+
+        return new Dictionary<string, dynamic>
+        {
+            { "seatEvaluate", seatEvaluate },
             { "visitType", EnumExts.GetDescriptions<EVisitType>() },
-            { "voiceEvaluate", EnumExts.GetDescriptions<EVoiceEvaluate>() },
-            { "visitSatisfaction", _sysDicDataCacheManager.GetVisitSatisfaction().Where(m => m.DicDataValue != "-1").ToList() },
-            { "visitMananer", _sysDicDataCacheManager.VisitMananer.Where(x => x.DicDataValue != "-1").ToList() },
+            { "voiceEvaluate", voiceEvaluate},
+            { "visitSatisfaction", visitSatisfaction },
+            { "visitMananer", visitManner},
             { "visitStateQuery", EnumExts.GetDescriptions<EVisitStateQuery>() },
             { "sourceChannel", _sysDicDataCacheManager.SourceChannel },
             { "aiVisitResult", EnumExts.GetDescriptions<EAiVisitResult>() }
         };
+    }
 
     /// <summary>
     /// 回访详情
@@ -1112,14 +1125,15 @@ public class OrderController : BaseController
         //    x => x.OrderId == orderVisit.OrderId && x.AgainState == EAgainState.DoAgain, HttpContext.RequestAborted);
         var voiceEvaluate = EnumExts.GetDescriptions<EVoiceEvaluate>();
         var seatEvaluate = EnumExts.GetDescriptions<ESeatEvaluate>();
+        var visitSatisfaction = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction);
+        var visitManner = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitManner);
         if (_appOptions.Value.IsZiGong == false)
         {
-            seatEvaluate = seatEvaluate.Where(m => new int[] { 1, 3 }.Contains(m.Key) == false).ToList();
+            seatEvaluate = seatEvaluate.Where(m => new int[] { -1, 1, 3 }.Contains(m.Key) == false).ToList();
+            visitSatisfaction = visitSatisfaction.Where(x => x.DicDataValue != "-1").ToList();
+            visitManner = visitManner.Where(x => x.DicDataValue != "-1").ToList();
         }
-
-        var visitSatisfaction = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction).Where(x => x.DicDataValue != "-1");
         var dissatisfiedReason = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.DissatisfiedReason);
-        var visitManner = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitManner).Where(x => x.DicDataValue != "-1");
         //var callRecord = await _trCallRecordRepository.GetAsync(x => x.CallAccept == orderVisit.CallId); //由CallAccept改为OtherAccept
         //var callRecord = await _trCallRecordRepository.GetAsync(x => x.OtherAccept == orderVisit.CallId && string.IsNullOrEmpty(x.OtherAccept) == false, HttpContext.RequestAborted);
         var recordingFileUrl = "";
@@ -3343,6 +3357,10 @@ public class OrderController : BaseController
         var delayModel = order.OrderDelays.MaxBy(x => x.CreationTime);
         if (delayModel != null)
         {
+            if (delayModel.IsProDelay)
+            {
+                dto.ProvinceDelayString = "该工单已向省平台发送延期申请!延期状态:" + delayModel.DelayState.GetDescription();
+            }
             var workFlow = await _workflowRepository.GetAsync(delayModel.WorkflowId);
             switch (delayModel.DelayState)
             {
@@ -3365,6 +3383,7 @@ public class OrderController : BaseController
         else
         {
             dto.DelayString = "";
+            dto.ProvinceDelayString = "";
         }
 
         //dto.CanPrevious = canPrevious;
@@ -3473,6 +3492,14 @@ public class OrderController : BaseController
             dto.ProvinceRevokeString = "该工单已由省平台发送撤单!请直接归档办理!";
         }
 
+        //省甄别
+        var orderScreen = await _orderScreenRepository.Queryable().Where(x => x.OrderId == order.Id && x.IsProScreen == true).OrderByDescending(x => x.CreationTime)
+                 .FirstAsync();
+        if (orderScreen != null)
+        {
+            dto.ProvinceScreenString = "该工单已向省平台发送甄别申请!甄别状态:" + orderScreen.Status.GetDescription();
+        }
+
         //终止
         var orderTerminateList = await _orderTerminateRepository.Queryable().Where(x => x.OrderId == order.Id).ToListAsync();
         dto.OrderTerminateStatus = orderTerminateList.Any(x => x.Status == ETerminateStatus.End) ? "同意" :
@@ -3567,11 +3594,11 @@ public class OrderController : BaseController
             await _callApplication.RelateTianrunCallWithOrderAsync(order.CallId, order.Id, HttpContext.RequestAborted);
 
         //内容分词
-        await _orderApplication.OrderParticiple(dto.Content, order.Id, order.CreationTime, HttpContext.RequestAborted);
+        await _orderApplication.OrderParticiple(dto.Content, order.Id, order.No, order.Title, order.CreationTime, HttpContext.RequestAborted);
         //敏感分词
         await _orderApplication.OrderSensitiveParticiple(dto.Content, order.Id, HttpContext.RequestAborted);
-
-
+        //知识库引用
+        await _orderApplication.AddKnowledgeQuote(order.Id, order.Title, order.No, order.KnowledgeQuote, HttpContext.RequestAborted);
         ////sms
         //try
         //{
@@ -3708,7 +3735,7 @@ public class OrderController : BaseController
         await _orderCopyRepository.AddAsync(copy, HttpContext.RequestAborted);
 
         if (order.Content != dto.Content)
-            await _orderApplication.OrderParticiple(dto.Content, dto.Id, order.CreationTime, HttpContext.RequestAborted);
+            await _orderApplication.OrderParticiple(dto.Content, dto.Id, order.No, order.Title, order.CreationTime, HttpContext.RequestAborted);
         if (dto.RepeatableEventDetails?.Any() ?? false)
         {
             var reAdds = dto.RepeatableEventDetails.Where(x => string.IsNullOrEmpty(x.OrderId) && !x.IsDeleted)
@@ -3794,6 +3821,8 @@ public class OrderController : BaseController
 
         //敏感分词
         await _orderApplication.OrderSensitiveParticiple(dto.Content, order.Id, HttpContext.RequestAborted);
+        //知识库引用
+        await _orderApplication.AddKnowledgeQuote(order.Id, order.Title, order.No, order.KnowledgeQuote, HttpContext.RequestAborted);
 
         return new { Id = order.Id, No = order.No, Password = order.Password, CallId = order.CallId };
     }

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

@@ -199,6 +199,7 @@ namespace Hotline.Api.Controllers
 			else
 				model.FileJson = new List<Share.Dtos.File.FileJson>();
 
+			model.Status = ETerminateStatus.Approval;
 			model.Content = dto.Data.Content;
 			model.IsRecommit = true;
 			await _orderTerminateRepository.UpdateAsync(model, HttpContext.RequestAborted);

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

@@ -841,7 +841,7 @@ namespace Hotline.Api.Controllers
                             FlowPurTypeName = p.AcceptTypeCode,
                             ConTypeName = p.HotspotName,
                             FlowAddDate = p.CreationTime,
-                            PubDate = p.CreationTime,
+                            PubDate = p.PubDate,
                             RSFlagName = p.State == "1" ? "办理完成" : "办理中"
                         });
 

+ 5 - 1
src/Hotline.Api/StartupExtensions.cs

@@ -234,7 +234,11 @@ internal static class StartupExtensions
         if (swaggerEnable)
         {
             app.UseSwagger();
-            app.UseSwaggerUI();
+            app.UseSwaggerUI(options =>
+            {
+                options.DefaultModelsExpandDepth(1);
+                options.DefaultModelExpandDepth(5);
+            });
             //app.UseSwaggerUI(c =>
             //{
             //    //c.DocExpansion(DocExpansion.None);

+ 45 - 21
src/Hotline.Application/Handlers/FlowEngine/WorkflowPreviousHandler.cs

@@ -1,20 +1,24 @@
 using DotNetCore.CAP;
+using Hotline.Configurations;
 using Hotline.FlowEngine.Notifications;
 using Hotline.FlowEngine.WorkflowModules;
 using Hotline.FlowEngine.Workflows;
 using Hotline.Orders;
 using Hotline.Push.Notifies;
+using Hotline.Repository.SqlSugar.Orders;
+using Hotline.Settings.TimeLimitDomain;
 using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Push;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Push;
+using Hotline.Share.Enums.Settings;
 using Hotline.Users;
 using MapsterMapper;
 using MediatR;
-using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
 using XF.Domain.Authentications;
 using XF.Domain.Repository;
 
@@ -36,8 +40,11 @@ namespace Hotline.Application.Handlers.FlowEngine
         private readonly ISessionContext _sessionContext;
         private readonly IRepository<OrderScreenDetail> _orderScreenDetailRepository;
         private readonly IRepository<OrderTerminate> _orderTerminateRepository;
+        private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
+        private readonly ICalcExpireTime _expireTime;
+        private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
 
-		public WorkflowPreviousHandler(
+        public WorkflowPreviousHandler(
             IOrderDomainService orderDomainService,
             IOrderRepository orderRepository,
             IOrderScreenRepository orderScreenRepository,
@@ -51,8 +58,11 @@ namespace Hotline.Application.Handlers.FlowEngine
             IMediator mediator,
             ISessionContext sessionContext,
             IRepository<OrderScreenDetail> orderScreenDetailRepository,
-            IRepository<OrderTerminate> orderTerminateRepository
-			)
+            IRepository<OrderTerminate> orderTerminateRepository,
+            IOptionsSnapshot<AppConfiguration> appOptions,
+            ICalcExpireTime expireTime,
+             IRepository<OrderVisitDetail> orderVisitDetailRepository
+            )
         {
             _orderDomainService = orderDomainService;
             _orderRepository = orderRepository;
@@ -68,6 +78,9 @@ namespace Hotline.Application.Handlers.FlowEngine
             _sessionContext = sessionContext;
             _orderScreenDetailRepository = orderScreenDetailRepository;
             _orderTerminateRepository = orderTerminateRepository;
+            _appOptions = appOptions;
+            _expireTime = expireTime;
+            _orderVisitDetailRepository = orderVisitDetailRepository;
         }
 
         /// <summary>Handles a notification</summary>
@@ -170,16 +183,27 @@ namespace Hotline.Application.Handlers.FlowEngine
                         }
                         break;
                     case WorkflowModuleConsts.OrderScreen:
-	                    var workflowSteps = await _workflowDomainService.GetWorkflowAsync(workflow.Id,withSteps: true,cancellationToken:cancellationToken);
-						var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
+                        var workflowSteps = await _workflowDomainService.GetWorkflowAsync(workflow.Id, withSteps: true, cancellationToken: cancellationToken);
+                        var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
                         if (screen != null)
                         {
                             screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
                             screen.SendBackTime = DateTime.Now;
-                            screen.SendBackApply = workflowSteps.Steps.Any(x=>x is { Status: EWorkflowStepStatus.WaitForHandle or EWorkflowStepStatus.WaitForAccept, StepType: EStepType.Start,IsOrigin : true } );
+                            screen.SendBackApply = workflowSteps.Steps.Any(x => x is { Status: EWorkflowStepStatus.WaitForHandle or EWorkflowStepStatus.WaitForAccept, StepType: EStepType.Start, IsOrigin: true });
                             screen.Status = EScreenStatus.SendBack;
                             screen.SendBackNum++;
-							await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
+                            await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
+                            //自贡任务 220 修改甄别截止申请日期的计算方式
+                            //甄别截止申请日期=回访时间+2个工作日  ,若退回到申请人节点,甄别截止申请日期=退回时间+2个工作日
+                            if (screen.SendBackApply == true && _appOptions.Value.IsZiGong)
+                            {
+                                var orderVisitDetail = await _orderVisitDetailRepository.GetAsync(p => p.Id == screen.VisitDetailId, cancellationToken);
+                                if (orderVisitDetail != null)
+                                {
+                                    orderVisitDetail.ScreenByEndTime = (await _expireTime.CalcEndTime(DateTime.Now, DateTime.Now, ETimeType.WorkDay, 2, 0, 0)).EndTime;
+                                    await _orderVisitDetailRepository.UpdateAsync(orderVisitDetail, cancellationToken);
+                                }
+                            }
                         }
                         OrderScreenDetail detail = new OrderScreenDetail
                         {
@@ -192,22 +216,22 @@ namespace Hotline.Application.Handlers.FlowEngine
                     case WorkflowModuleConsts.KnowledgeUpdate:
                     case WorkflowModuleConsts.KnowledgeDelete:
                     case WorkflowModuleConsts.KnowledgeOffshelf:
-					case WorkflowModuleConsts.TelRestApply:
+                    case WorkflowModuleConsts.TelRestApply:
                         break;
                     case WorkflowModuleConsts.OrderTerminate:
-	                    var orderTerminate = await _orderTerminateRepository.Queryable()
-		                    .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
-	                    if (orderTerminate != null)
-	                    {
-		                    orderTerminate.Status = ETerminateStatus.SendBack;
-							if (notification.TargetStep.StepType is EStepType.Start)
-		                    {
+                        var orderTerminate = await _orderTerminateRepository.Queryable()
+                            .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
+                        if (orderTerminate != null)
+                        {
+                            orderTerminate.Status = ETerminateStatus.SendBack;
+                            if (notification.TargetStep.StepType is EStepType.Start)
+                            {
                                 orderTerminate.Status = ETerminateStatus.SendBackStart;
-							}
-		                    await _orderTerminateRepository.UpdateAsync(orderTerminate, cancellationToken);
-	                    }
-	                    break;
-				}
+                            }
+                            await _orderTerminateRepository.UpdateAsync(orderTerminate, cancellationToken);
+                        }
+                        break;
+                }
 
             }
             catch (Exception e)

+ 34 - 10
src/Hotline.Application/Orders/IOrderApplication.cs

@@ -2,6 +2,7 @@
 using Hotline.FlowEngine.Workflows;
 using Hotline.Orders;
 using Hotline.Settings;
+using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
 using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.Order;
@@ -57,7 +58,7 @@ namespace Hotline.Application.Orders
         ISugarQueryable<Order> GetAboutToExpireAsync(AboutToExpireListDto dto);
 
         //Task<PagedDto<WorkflowOrderDto>> GetAboutToExpireNodeAsync(AboutToExpireListDto dto, CancellationToken cancellationToken);
-        Task OrderParticiple(string inputStr, string orderId, DateTime time, CancellationToken cancellationToken);
+        Task OrderParticiple(string inputStr, string orderId, string no, string title, DateTime time, CancellationToken cancellationToken);
         Task OrderSensitiveParticiple(string inputStr, string orderId, CancellationToken cancellationToken);
         /// <summary>
         /// 接收外部平台工单
@@ -330,11 +331,11 @@ namespace Hotline.Application.Orders
         ISugarQueryable<OrderVisitDetail> MayScreenList(MayScreenListDto dto);
 
 
-		ISugarQueryable<Order> QueryWaitedForSeat(QueryOrderWaitedDto dto);
+        ISugarQueryable<Order> QueryWaitedForSeat(QueryOrderWaitedDto dto);
 
 
-		ISugarQueryable<Order> QueryWaited(QueryOrderWaitedDto dto);
-        
+        ISugarQueryable<Order> QueryWaited(QueryOrderWaitedDto dto);
+
 
         /// <summary>
         /// 受理类型前10
@@ -356,12 +357,12 @@ namespace Hotline.Application.Orders
         /// <returns></returns>
         ISugarQueryable<OrderVisit> QueryOrderVisitList(QueryOrderVisitDto dto);
 
-		/// <summary>
-		/// 热点类型小类统计明细
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		ISugarQueryable<Order> HotspotStatisticsDetail(HotspotStatisticsRep dto);
+        /// <summary>
+        /// 热点类型小类统计明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<Order> HotspotStatisticsDetail(HotspotStatisticsRep dto);
 
         /// <summary>
         /// 坐席总体满意度分析
@@ -384,5 +385,28 @@ namespace Hotline.Application.Orders
         /// <returns></returns>
         ISugarQueryable<OrderVisitDetail> QuerySeatSatisfactionOrderVisitList(SeatSatisfactionOrderVisitRequest dto);
 
+        /// <summary>
+        /// 工单热词分析
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<OrderTsDetailsDto> QueryOrderTsDetailsList(PagedKeywordRequest dto);
+
+        /// <summary>
+        /// 知识库引用
+        /// </summary>
+        /// <param name="orderId"></param>
+        /// <param name="title"></param>
+        /// <param name="no"></param>
+        /// <param name="knowledgeQuote"></param>
+        /// <returns></returns>
+        Task AddKnowledgeQuote(string orderId, string title, string no, List<Kv> knowledgeQuote, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// 知识库引用
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<OrderTsDetailsDto> QueryKnowledgeQuoteList(PagedKeywordRequest dto);
     }
 }

+ 185 - 28
src/Hotline.Application/Orders/OrderApplication.cs

@@ -1,15 +1,13 @@
-using DocumentFormat.OpenXml.Drawing;
-using DotNetCore.CAP;
+using DotNetCore.CAP;
 using Hotline.Application.Quality;
 using Hotline.Authentications;
 using Hotline.Caching.Interfaces;
 using Hotline.Configurations;
-using Hotline.EventBus;
 using Hotline.File;
 using Hotline.FlowEngine.WorkflowModules;
 using Hotline.FlowEngine.Workflows;
+using Hotline.KnowledgeBase;
 using Hotline.Orders;
-using Hotline.Orders.Notifications;
 using Hotline.OrderTranspond;
 using Hotline.Push.Notifies;
 using Hotline.Repository.SqlSugar.Extensions;
@@ -19,6 +17,7 @@ using Hotline.SeedData;
 using Hotline.Settings;
 using Hotline.Settings.Hotspots;
 using Hotline.Settings.TimeLimitDomain;
+using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
 using Hotline.Share.Dtos.File;
 using Hotline.Share.Dtos.FlowEngine;
@@ -39,6 +38,8 @@ using Hotline.Users;
 using Mapster;
 using MapsterMapper;
 using MediatR;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Options;
 using PanGu;
 using SqlSugar;
@@ -49,7 +50,6 @@ using XF.Domain.Dependency;
 using XF.Domain.Entities;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
-using XF.Utility.EnumExtensions;
 using WordInfo = PanGu.WordInfo;
 
 namespace Hotline.Application.Orders;
@@ -58,7 +58,6 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 {
     private readonly IMediator _mediator;
     private readonly IRepository<TranspondCityRawData> _transpondCityRawDataRepository;
-    private readonly Publisher _publisher;
     private readonly ISessionContextProvider _sessionContextProvider;
     private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
     private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
@@ -98,6 +97,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly IRepository<SchedulingUser> _schedulingUserRepository;
     private readonly IRepository<StatisticsHotspotSatisfied> _statisticsHotspotSatisfiedRepository;
     private readonly IRepository<StatisticsDepartSatisfied> _statisticsDepartSatisfiedRepository;
+    private readonly IRepository<OrderTsDetails> _orderTsDetailsRepository;
+    private readonly IRepository<KnowledgeQuote> _knowledgeQuoteRepository;
 
     public OrderApplication(
         IOrderDomainService orderDomainService,
@@ -130,7 +131,6 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         IRepository<OrderVisitDetail> orderVisitedDetailRepository,
         IOptionsSnapshot<AppConfiguration> appOptions,
         ISystemDicDataCacheManager sysDicDataCacheManager,
-        Publisher publisher,
         ISessionContextProvider sessionContextProvider,
         IRepository<TranspondCityRawData> transpondCityRawDataRepository,
         IRepository<OrderObserve> orderObserveRepository,
@@ -140,7 +140,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         IRepository<SchedulingUser> schedulingUserRepository,
         IRepository<StatisticsHotspotSatisfied> statisticsHotspotSatisfiedRepository,
         IRepository<StatisticsDepartSatisfied> statisticsDepartSatisfiedRepository,
-        IOrderDelayRepository orderDelayRepository)
+        IOrderDelayRepository orderDelayRepository,
+        IRepository<OrderTsDetails> orderTsDetailsRepository,
+        IRepository<KnowledgeQuote> knowledgeQuoteRepository)
     {
         _orderDomainService = orderDomainService;
         _workflowDomainService = workflowDomainService;
@@ -171,7 +173,6 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _orderVisitedDetailRepository = orderVisitedDetailRepository;
         _appOptions = appOptions;
         _sysDicDataCacheManager = sysDicDataCacheManager;
-        _publisher = publisher;
         _sessionContextProvider = sessionContextProvider;
         _transpondCityRawDataRepository = transpondCityRawDataRepository;
         _orderObserveRepository = orderObserveRepository;
@@ -183,7 +184,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _schedulingUserRepository = schedulingUserRepository;
         _statisticsHotspotSatisfiedRepository = statisticsHotspotSatisfiedRepository;
         _statisticsDepartSatisfiedRepository = statisticsDepartSatisfiedRepository;
-
+        _orderTsDetailsRepository = orderTsDetailsRepository;
+        _knowledgeQuoteRepository = knowledgeQuoteRepository;
     }
 
     /// <summary>
@@ -583,8 +585,13 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// 工单关键字分词
     /// </summary>
     /// <param name="inputStr"></param>
+    /// <param name="orderId"></param>
+    /// <param name="no"></param>
+    /// <param name="title"></param>
+    /// <param name="time"></param>
+    /// <param name="cancellationToken"></param>
     /// <returns></returns>
-    public async Task OrderParticiple(string inputStr, string orderId, DateTime time, CancellationToken cancellationToken)
+    public async Task OrderParticiple(string inputStr, string orderId, string no, string title, DateTime time, CancellationToken cancellationToken)
     {
         var seg = new Segment();
         ICollection<WordInfo> splitWords = seg.DoSegment(inputStr);
@@ -601,6 +608,27 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             var vector = await _repositoryts.SearchAsync(orderId, cancellationToken);
             if (vector != null && vector.Any()) await _repositoryts.UpdateVectorAsync(orderId, words, cancellationToken);
             else await _repositoryts.AddVectorAsync(orderId, time, words, cancellationToken);
+
+            //是否开启分词
+            var isOpenWordSegmentation = _systemSettingCacheManager.GetSetting(SettingConstants.IsOpenWordSegmentation)?.SettingValue[0];
+            if (!string.IsNullOrEmpty(isOpenWordSegmentation) && isOpenWordSegmentation == "true")
+            {
+                //先删除历史数据,在添加新数据
+                await _orderTsDetailsRepository.RemoveAsync(p => p.OrderId == orderId, false, cancellationToken);
+                List<OrderTsDetails> orderTsDetails = new();
+                foreach (var item in words)
+                {
+                    orderTsDetails.Add(new OrderTsDetails
+                    {
+                        Terms = item,
+                        OrderId = orderId,
+                        Title = title,
+                        No = no
+                    });
+                }
+                if (orderTsDetails != null && orderTsDetails.Count > 0)
+                    await _orderTsDetailsRepository.AddRangeAsync(orderTsDetails, cancellationToken);
+            }
         }
         // 结巴分词
         //var segmenter = new JiebaSegmenter();
@@ -1822,10 +1850,16 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                         SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2", 1, 0))), //不满意
                     NoEvaluateCount = SqlFunc.IIF(dto.TypeId == 1,
                         SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "7", 1, 0)),
-                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "7", 1, 0))), //未做评价
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "6", 1, 0))), //未做评价
                     NoPutThroughCount = SqlFunc.IIF(dto.TypeId == 1,
                         SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "6", 1, 0)),
-                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "6", 1, 0))), //未接通
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "8", 1, 0))), //未接通
+                    NormalCount = SqlFunc.IIF(dto.TypeId == 1,
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "3", 1, 0)),
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "3", 1, 0))),//一般
+                    VeryNoSatisfiedCount = SqlFunc.IIF(dto.TypeId == 1,
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1", 1, 0)),
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "1", 1, 0))),//非常不满意
                 })
                 .MergeTable()
                 .LeftJoin<SystemOrganize>((it, o) => it.OrgCode == o.Id)
@@ -1842,6 +1876,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                     NoSatisfiedCount = it.NoSatisfiedCount, //不满意
                     NoEvaluateCount = it.NoEvaluateCount, //未做评价
                     NoPutThroughCount = it.NoPutThroughCount, //未接通
+                    NormalCount=it.NormalCount,
+                    VeryNoSatisfiedCount=it.VeryNoSatisfiedCount
                 })
                 .ToListAsync();
         }
@@ -1873,10 +1909,16 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                         SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2", 1, 0))), //不满意
                     NoEvaluateCount = SqlFunc.IIF(dto.TypeId == 1,
                         SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "7", 1, 0)),
-                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "7", 1, 0))), //未做评价
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "6", 1, 0))), //未做评价
                     NoPutThroughCount = SqlFunc.IIF(dto.TypeId == 1,
                         SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "6", 1, 0)),
-                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "6", 1, 0))), //未接通
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "8", 1, 0))), //未接通
+                    NormalCount = SqlFunc.IIF(dto.TypeId == 1,
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "3", 1, 0)),
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "3", 1, 0))),//一般
+                    VeryNoSatisfiedCount = SqlFunc.IIF(dto.TypeId == 1,
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1", 1, 0)),
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "1", 1, 0))),//非常不满意
                 })
                 .MergeTable()
                 .LeftJoin<SystemOrganize>((it, o) => it.OrgCode == o.Id && (o.Level == orgLevel || o.Level == (orgLevel + 1)))
@@ -1893,6 +1935,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                     NoSatisfiedCount = it.NoSatisfiedCount, //不满意
                     NoEvaluateCount = it.NoEvaluateCount, //未做评价
                     NoPutThroughCount = it.NoPutThroughCount, //未接通
+                    NormalCount = it.NormalCount,//一般
+                    VeryNoSatisfiedCount = it.VeryNoSatisfiedCount//非常不满意
                 })
                 .ToListAsync();
         }
@@ -2055,12 +2099,18 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                        0))), //不满意
                NoEvaluateCount = SqlFunc.IIF(dto.TypeId == 1,
                    SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "7", 1, 0)),
-                   SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "7", 1,
+                   SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "6", 1,
                        0))), //未做评价
                NoPutThroughCount = SqlFunc.IIF(dto.TypeId == 1,
                    SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "6", 1, 0)),
-                   SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "6", 1,
-                       0))) //未接通
+                   SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "8", 1,
+                       0))), //未接通
+               NormalCount = SqlFunc.IIF(dto.TypeId == 1,
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "3", 1, 0)),
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "3", 1, 0))),//一般
+               VeryNoSatisfiedCount = SqlFunc.IIF(dto.TypeId == 1,
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "1", 1, 0)),
+                        SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "1", 1, 0))),//非常不满意
            })
            .MergeTable()
            .LeftJoin<SystemOrganize>((x, it) =>
@@ -2078,6 +2128,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                NoSatisfiedCount = x.NoSatisfiedCount, //不满意
                NoEvaluateCount = x.NoEvaluateCount, //未做评价
                NoPutThroughCount = x.NoPutThroughCount, //未接通
+               NormalCount = x.NormalCount,//一般
+               VeryNoSatisfiedCount = x.VeryNoSatisfiedCount//非常不满意
            }).ToListAsync();
 
 
@@ -2650,10 +2702,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 //Subtotal = SqlFunc.AggregateCount(x.AcceptorId),
                 CentreArchive =
                     SqlFunc.AggregateSum(
-                        SqlFunc.IIF(it.Status >= EOrderStatus.Filed && it.FileOrgIsCenter==true && it.AcceptType != "无效", 1, 0)), //中心归档件
+                        SqlFunc.IIF(it.Status >= EOrderStatus.Filed && it.FileOrgIsCenter == true && it.AcceptType != "无效", 1, 0)), //中心归档件
                 //CentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF(it.Status >= EOrderStatus.Filed && (it.FileUserRole == EFileUserType.Org || it.FileUserRole == EFileUserType.Dispatch), 1, 0)), //转办信件
                 CentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF(
-                    it.AcceptType != "无效" && (it.FileOrgIsCenter ==false ||
+                    it.AcceptType != "无效" && (it.FileOrgIsCenter == false ||
                                               (it.ActualHandleStepName == "派单组" && it.Status < EOrderStatus.Filed) ||
                                               (it.ActualHandleStepName == "班长审批" && it.Status < EOrderStatus.Filed)), 1, 0)),
                 NoCentreCareOf =
@@ -2664,8 +2716,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 Invalid = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptType == "无效", 1, 0)),
                 Repeat = SqlFunc.AggregateSum(SqlFunc.IIF(it.DuplicateIds != null && SqlFunc.JsonArrayLength(it.DuplicateIds) > 0, 1, 0)),
                 Subtotal = SqlFunc.AggregateSum(SqlFunc.IIF(
-                    (it.Status >= EOrderStatus.Filed && it.FileOrgIsCenter==true && it.AcceptType != "无效") ||
-                    (it.AcceptType != "无效" && (it.FileOrgIsCenter ==false ||
+                    (it.Status >= EOrderStatus.Filed && it.FileOrgIsCenter == true && it.AcceptType != "无效") ||
+                    (it.AcceptType != "无效" && (it.FileOrgIsCenter == false ||
                                                (it.ActualHandleStepName == "派单组" && it.Status < EOrderStatus.Filed) ||
                                                (it.ActualHandleStepName == "班长审批" && it.Status < EOrderStatus.Filed))) ||
                     (it.Status <= EOrderStatus.HandOverToUnAccept) || it.AcceptType == "无效" ||
@@ -3017,7 +3069,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                          x.OrderScreens.Any() == false
              //|| x.OrderScreens.Any(s => (s.Status != EScreenStatus.SendBack && s.SendBackApply != true)) == false
              )
-             .Where(x=> x.OrderVisit.Order.ReceiveProvinceNo.StartsWith("ZGZFW")==false || string.IsNullOrEmpty(x.OrderVisit.Order.ReceiveProvinceNo))
+             .Where(x => x.OrderVisit.Order.ReceiveProvinceNo.StartsWith("ZGZFW") == false || string.IsNullOrEmpty(x.OrderVisit.Order.ReceiveProvinceNo))
              .WhereIF(dto.ScreenType == EOrderScreenType.Seat, x => x.OrderVisit.Order.IsProvince == false)
              .WhereIF(dto.ScreenSendBack is 1,
                  x => x.OrderScreens.Any(s => s.Status == EScreenStatus.SendBack && s.ScreenType == dto.ScreenType && s.SendBackApply == true))
@@ -3183,11 +3235,18 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         var query = _orderVisitRepository.Queryable()
             .Includes(d => d.Order)
             .Includes(d => d.Employee)
-            .Includes(d => d.OrderVisitDetails)
-            .WhereIF(dto.VisitStateQuery == EVisitStateQuery.NoVisit,
-                d => d.VisitState == EVisitState.WaitForVisit ||
-                     d.VisitState == EVisitState.NoSatisfiedWaitForVisit)
-            .WhereIF(dto.VisitStateQuery == EVisitStateQuery.Visited, d => d.VisitState == EVisitState.Visited)
+            .Includes(d => d.OrderVisitDetails);
+
+        if (_appOptions.Value.IsZiGong || _appOptions.Value.IsLuZhou)
+        {
+            //任务217  待回访工单显示优化(自贡+泸州通用)回访状态选择“待回访”,在该状态下不查“设为未接通”工单
+            query = query.WhereIF(dto.VisitStateQuery == EVisitStateQuery.NoVisit,
+                d => d.VisitState == EVisitState.WaitForVisit || d.VisitState == EVisitState.NoSatisfiedWaitForVisit && d.IsPutThrough == false);
+        }
+        else
+            query = query.WhereIF(dto.VisitStateQuery == EVisitStateQuery.NoVisit, d => d.VisitState == EVisitState.WaitForVisit || d.VisitState == EVisitState.NoSatisfiedWaitForVisit);
+
+        query = query.WhereIF(dto.VisitStateQuery == EVisitStateQuery.Visited, d => d.VisitState == EVisitState.Visited)
             .WhereIF(dto.VisitStateQuery == EVisitStateQuery.SMSUnsatisfied, d => d.VisitState == EVisitState.SMSUnsatisfied)
             .WhereIF(dto.VisitStateQuery == EVisitStateQuery.SMSVisiting, d => d.VisitState == EVisitState.SMSVisiting)
             .WhereIF(dto.VisitStateQuery == EVisitStateQuery.NoPutThrough, d => d.IsPutThrough == false && d.VisitState != EVisitState.Visited)
@@ -3397,6 +3456,21 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         {
             order = _mapper.Map<Order>(dto);
             order.InitId();
+            if (!string.IsNullOrEmpty(order.AcceptTypeCode))
+            { 
+                var acceptModel = _sysDicDataCacheManager.AcceptType.Where(x => x.DicDataValue == order.AcceptTypeCode).FirstOrDefault();
+                if (acceptModel != null)
+                {
+                    order.AcceptType = acceptModel.DicDataName;
+                }
+            }
+            if (order.IsSecret == true)
+            {
+                order.FocusOnEventsName = "保密";
+                order.FocusOnEvents = "99";
+            }
+
+
             if (files != null && files.Any())
                 order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
             await _orderDomainService.AddAsync(order, cancellationToken: cancellationToken);
@@ -3417,6 +3491,13 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             else
                 order.FileJson = new List<Share.Dtos.File.FileJson>();
             order.ReTransactNum++;
+            order.ProvinceReTransactNum++;
+
+            if (order.IsSecret == true)
+            {
+                order.FocusOnEventsName = "保密";
+                order.FocusOnEvents = "99";
+            }
             //await _orderRepository.UpdateAsync(order, cancellationToken);
 
             if (orderExtension is not null)
@@ -4040,4 +4121,80 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         return list;
     }
     #endregion
+
+    /// <summary>
+    /// 工单热词分析
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public ISugarQueryable<OrderTsDetailsDto> QueryOrderTsDetailsList(PagedKeywordRequest dto)
+    {
+        var query = _orderTsDetailsRepository.Queryable()
+           .GroupBy(p => p.Terms)
+           .Select(p => new OrderTsDetailsDto
+           {
+               Name = p.Terms,
+               CountNum = SqlFunc.AggregateCount(p.Terms),
+           })
+           .MergeTable()
+           .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Name.Contains(dto.Keyword))
+           .OrderByIF(dto is { SortField: "countNum", SortRule: 0 }, p => p.CountNum, OrderByType.Asc)
+           .OrderByIF(dto is { SortField: "countNum", SortRule: 1 }, p => p.CountNum, OrderByType.Desc);
+
+        return query;
+    }
+
+    /// <summary>
+    /// 知识库引用
+    /// </summary>
+    /// <param name="orderId"></param>
+    /// <param name="title"></param>
+    /// <param name="no"></param>
+    /// <param name="knowledgeQuote"></param>
+    /// <returns></returns>
+    public async Task AddKnowledgeQuote(string orderId, string title, string no, List<Kv> knowledgeQuote, CancellationToken cancellationToken)
+    {
+        await _knowledgeQuoteRepository.RemoveAsync(p => p.OrderId == orderId, false, cancellationToken);
+        if (knowledgeQuote != null && knowledgeQuote.Count > 0)
+        {
+            List<KnowledgeQuote> list = [];
+            foreach (var item in knowledgeQuote)
+            {
+                list.Add(new KnowledgeQuote
+                {
+                    KnowledgeId = item.Key,
+                    KnowledgeTitle = item.Value,
+                    OrderId = orderId,
+                    Title = title,
+                    No = no
+                });
+            }
+            if (list != null && list.Count > 0)
+                await _knowledgeQuoteRepository.AddRangeAsync(list, cancellationToken);
+        }
+    }
+
+    /// <summary>
+    /// 知识库引用
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public ISugarQueryable<OrderTsDetailsDto> QueryKnowledgeQuoteList(PagedKeywordRequest dto)
+    {
+        var query = _knowledgeQuoteRepository.Queryable()
+            .Where(p => p.CreationTime >= dto.StartTime && p.CreationTime <= dto.EndTime)
+             .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Title.Contains(dto.Keyword))
+             .MergeTable()
+           .GroupBy(p => new { p.KnowledgeId, p.KnowledgeTitle })
+           .Select(p => new OrderTsDetailsDto
+           {
+               Name = p.KnowledgeTitle,
+               CountNum = SqlFunc.AggregateCount(p.KnowledgeId),
+           })
+           .OrderByIF(dto is { SortField: "countNum", SortRule: 0 }, p => p.CountNum, OrderByType.Asc)
+           .OrderByIF(dto is { SortField: "countNum", SortRule: 1 }, p => p.CountNum, OrderByType.Desc);
+
+        return query;
+    }
+
 }

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

@@ -410,8 +410,10 @@ namespace Hotline.Application.Orders
                     RegardedAsSatisfiedCount = SqlFunc.IIF(dto.VisitTypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgProcessingResults, "Key") == "-1", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgHandledAttitude, "Key") == "-1", 1, 0))),//视为满意
                     DefaultSatisfiedCount = SqlFunc.IIF(dto.VisitTypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgProcessingResults, "Key") == "0", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgHandledAttitude, "Key") == "0", 1, 0))),//默认满意
                     NoSatisfiedCount = SqlFunc.IIF(dto.VisitTypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgProcessingResults, "Key") == "2", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgHandledAttitude, "Key") == "2", 1, 0))),//不满意
-                    NoEvaluateCount = SqlFunc.IIF(dto.VisitTypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgProcessingResults, "Key") == "7", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgHandledAttitude, "Key") == "7", 1, 0))),//未做评价
-                    NoPutThroughCount = SqlFunc.IIF(dto.VisitTypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgProcessingResults, "Key") == "6", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgHandledAttitude, "Key") == "6", 1, 0))),//未接通
+                    NoEvaluateCount = SqlFunc.IIF(dto.VisitTypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgProcessingResults, "Key") == "7", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgHandledAttitude, "Key") == "6", 1, 0))),//未做评价
+                    NoPutThroughCount = SqlFunc.IIF(dto.VisitTypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgProcessingResults, "Key") == "6", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgHandledAttitude, "Key") == "8", 1, 0))),//未接通
+                    NormalCount = SqlFunc.IIF(dto.VisitTypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgProcessingResults, "Key") == "3", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgHandledAttitude, "Key") == "3", 1, 0))),//未接通
+                    VeryNoSatisfiedCount = SqlFunc.IIF(dto.VisitTypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgProcessingResults, "Key") == "1", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.VisitDetail.OrgHandledAttitude, "Key") == "1", 1, 0))),//未接通
                 });
         }
 

+ 53 - 5
src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs

@@ -552,7 +552,13 @@ namespace Hotline.Repository.SqlSugar.Orders
         /// <returns></returns>
         public async Task<DataTable> CenterReportFormsStatistics(DateTime StartTime, DateTime EndTime)
         {
-            var list = await Db.Queryable<StatisticsCenter>()
+            var listAny = await Db.Queryable<StatisticsCenter>()
+                .Where(x => x.Time >= StartTime && x.Time <= EndTime).AnyAsync();
+            if (!listAny)
+            {
+                return null;
+            }
+			var list = await Db.Queryable<StatisticsCenter>()
                 .Where(x => x.Time >= StartTime && x.Time <= EndTime)
                 .Select(x => new StatisticsCenter
                 {
@@ -605,7 +611,14 @@ namespace Hotline.Repository.SqlSugar.Orders
         /// <returns></returns>
         public async Task<DataTable> CenterReportPurTypeStatistics(DateTime StartTime, DateTime EndTime)
         {
-            var list = await Db.Queryable<StatisticsPurTypeSatisfied>()
+            var any = await Db.Queryable<StatisticsPurTypeSatisfied>()
+                .Where(x => x.Time >= StartTime && x.Time <= EndTime).AnyAsync();
+            if (!any)
+            {
+                return null;
+            }
+
+			var list = await Db.Queryable<StatisticsPurTypeSatisfied>()
                 .Where(x => x.Time >= StartTime && x.Time <= EndTime)
                 .Select(x => new StatisticsPurTypeSatisfied
                 {
@@ -637,7 +650,16 @@ namespace Hotline.Repository.SqlSugar.Orders
         /// <returns></returns>
         public async Task<DataTable> CenterReportDepartStatistics(DateTime StartTime, DateTime EndTime, string Type)
         {
-            var list = await Db.Queryable<StatisticsDepart>()
+            var any = await Db.Queryable<StatisticsDepart>()
+                .LeftJoin<SystemOrganize>((x, so) => x.DepartmentId == so.oldBmid)
+                .Where(x => x.Time >= StartTime && x.Time <= EndTime && x.Type == Type).AnyAsync();
+            if (!any)
+            {
+                return null;
+            }
+
+
+			var list = await Db.Queryable<StatisticsDepart>()
                 .LeftJoin<SystemOrganize>((x, so) => x.DepartmentId == so.oldBmid)
                 .Where(x => x.Time >= StartTime && x.Time <= EndTime && x.Type == Type)
                 .GroupBy((x, so) => new
@@ -669,6 +691,13 @@ namespace Hotline.Repository.SqlSugar.Orders
         /// <returns></returns>
         public async Task<DataTable> CenterReportNewStatistics(DateTime StartTime, DateTime EndTime)
         {
+            var any = await Db.Queryable<StatisticsBaseInfo>()
+                .Where(x => x.AddDate >= StartTime && x.AddDate <= EndTime).AnyAsync();
+
+			if (!any)
+            {
+                return null;
+            }
             var list = await Db.Queryable<StatisticsBaseInfo>()
                 .Where(x => x.AddDate >= StartTime && x.AddDate <= EndTime)
                 .Select(x => new
@@ -1748,6 +1777,8 @@ namespace Hotline.Repository.SqlSugar.Orders
         public ISugarQueryable<OrgVisitDetailListResp> OrgVisitDetailList(OrgVisitDetailListReq dto)
         {
             var IsCenter = _sessionContext.OrgIsCenter;
+            if (dto.OrgProcessingResults == null || !dto.OrgProcessingResults.Any() || dto.OrgProcessingResults.First() == null)
+                dto.OrgProcessingResults = null;
 
             return _orderVisitDetailRepository.Queryable()
                 .Includes(x => x.OrderVisit, x => x.Order)
@@ -1761,7 +1792,15 @@ namespace Hotline.Repository.SqlSugar.Orders
                     x => x.OrderVisit.Order.ActualHandleOrgCode != OrgSeedData.CenterId)
                 .WhereIF(dto.Keyword.NotNullOrEmpty(), x => x.OrderVisit.Order.Title.Contains(dto.Keyword)) // 根据关键字匹配
                 .WhereIF(dto.TypeCode != 0, x => x.OrderVisit.Order.IdentityType == (EIdentityType)dto.TypeCode)
-                .WhereIF(!string.IsNullOrEmpty(dto.OrgProcessingResults), dto.AttitudeType == EAttitudeType.ProcessingResult ? x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == dto.OrgProcessingResults : x => SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == dto.OrgProcessingResults)
+                //任务 218 市州通用-部门满意度明细:办件结果查询优化为多选
+                //.WhereIF(dto.OrgProcessingResults != null && dto.OrgProcessingResults.Any(),
+                //      x => dto.OrgProcessingResults.Contains(SqlFunc.JsonField(x.OrgProcessingResults, "Key")))
+                //.WhereIF(dto.OrgHandledAttitude != null && dto.OrgHandledAttitude.Any(),
+                //     x => dto.OrgHandledAttitude.Contains(SqlFunc.JsonField(x.OrgHandledAttitude, "Key")))
+                .WhereIF(dto.OrgProcessingResults != null && dto.OrgProcessingResults.Count > 0,
+                    dto.AttitudeType == EAttitudeType.ProcessingResult ?
+                    x => dto.OrgProcessingResults.Contains(SqlFunc.JsonField(x.OrgProcessingResults, "Key")) :
+                    x => dto.OrgProcessingResults.Contains(SqlFunc.JsonField(x.OrgHandledAttitude, "Key")))
                 .WhereIF(!string.IsNullOrEmpty(dto.VisitUser), x => x.OrderVisit.Employee.Name.Contains(dto.VisitUser))
                 .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.OrderVisit.Order.No == dto.No)
                 .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.OrderVisit.Order.Title.Contains(dto.Title))
@@ -1889,7 +1928,16 @@ namespace Hotline.Repository.SqlSugar.Orders
                 .WhereIF(dto.OrgVisitStatisticsType.HasValue, x => x.OrderVisit.Order.FileOrgIsCenter == (dto.OrgVisitStatisticsType == EOrgVisitStatisticsType.CallCenter))
                 .WhereIF(dto.Keyword.NotNullOrEmpty(), x => x.OrderVisit.Order.Title.Contains(dto.Keyword)) // 根据关键字匹配
                 .WhereIF(dto.TypeCode != 0, x => x.OrderVisit.Order.IdentityType == (EIdentityType)dto.TypeCode)
-                .WhereIF(!string.IsNullOrEmpty(dto.OrgProcessingResults), dto.AttitudeType == EAttitudeType.ProcessingResult ? x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == dto.OrgProcessingResults : x => SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == dto.OrgProcessingResults)
+                  //任务 218 市州通用-部门满意度明细:办件结果查询优化为多选
+                  //.WhereIF(dto.OrgProcessingResults != null && dto.OrgProcessingResults.Any(),
+                  //      x => dto.OrgProcessingResults.Contains(SqlFunc.JsonField(x.OrgProcessingResults, "Key")))
+                  //.WhereIF(dto.OrgHandledAttitude != null && dto.OrgHandledAttitude.Any(),
+                  //     x => dto.OrgHandledAttitude.Contains(SqlFunc.JsonField(x.OrgHandledAttitude, "Key")))
+                  .WhereIF(dto.OrgProcessingResults != null && dto.OrgProcessingResults.Any(),
+                    dto.AttitudeType == EAttitudeType.ProcessingResult ?
+                    x => dto.OrgProcessingResults.Contains(SqlFunc.JsonField(x.OrgProcessingResults, "Key")) :
+                    x => dto.OrgProcessingResults.Contains(SqlFunc.JsonField(x.OrgHandledAttitude, "Key")))
+
                 .WhereIF(!string.IsNullOrEmpty(dto.VisitUser), x => x.OrderVisit.Employee.Name.Contains(dto.VisitUser))
                 .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.OrderVisit.Order.No == dto.No)
                 .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.OrderVisit.Order.Title.Contains(dto.Title))

+ 51 - 15
src/Hotline.Share/Dtos/CallCenter/CenterReportStatisticsDto.cs

@@ -9,12 +9,12 @@ namespace Hotline.Share.Dtos.CallCenter
     public class CenterReportStatisticsDto
     {
         /// <summary>
-        /// 电话
+        /// 电话--自贡
         /// </summary>
         public CenterReportCallInfoDto CenterReportCallInfoDto { get; set; }
 
         /// <summary>
-        /// 电话
+        /// 电话--宜宾
         /// </summary>
         public CenterReportCallDto CenterReportCall { get; set; }
 
@@ -31,17 +31,17 @@ namespace Hotline.Share.Dtos.CallCenter
         /// <summary>
         /// 按时办结情况
         /// </summary>
-        public OrderCompletedDto orderCompletedDto { get; set; }
+        public OrderCompletedDto OrderCompletedDto { get; set; }
 
         /// <summary>
         /// 办理时效
         /// </summary>
-        public OrderAgingDto orderAgingDto { get; set; }
+        public OrderAgingDto OrderAgingDto { get; set; }
 
 		/// <summary>
 		/// 企业办件情况
 		/// </summary>
-		public EnterpriseOrderDto enterpriseOrderDto { get; set; }
+		public EnterpriseOrderDto EnterpriseOrderDto { get; set; }
 
 		/// <summary>
 		/// 信件回访量
@@ -58,10 +58,15 @@ namespace Hotline.Share.Dtos.CallCenter
         /// </summary>
         public List<CenterReportOrderSourceChannelDto> CenterReportOrderAcceptTypes { get; set; }
 
-        /// <summary>
-        /// 专线统计
-        /// </summary>
-        public List<CenterReportOrderSourceChannelDto>  CenterReportOrderDedicatedLine{get;set ;}
+		/// <summary>
+		/// 信件分类
+		/// </summary>
+		public List<CenterReportOrderSourceChannelDto> EnterpriseCenterReportOrderAcceptTypes { get; set; }
+
+		/// <summary>
+		/// 专线统计
+		/// </summary>
+		public List<CenterReportOrderSourceChannelDto>  CenterReportOrderDedicatedLine{get;set ;}
 
         /// <summary>
         /// 市直部门
@@ -136,14 +141,39 @@ namespace Hotline.Share.Dtos.CallCenter
     public class CenterReportCallDto
     {
         /// <summary>
-        /// 话总量
+        /// 话总量
         /// </summary>
-        public int AllCallCount => EffectiveCount + InvalidCount + QueueByeCount + IvrByeCount;
+        public int AllCallCount => InTotal + OutTotal;
 
-        /// <summary>
-        /// 有效
-        /// </summary>
-        public int EffectiveCount { get; set; }
+		/// <summary>
+		/// 接通总量
+		/// </summary>
+		public int AllConnectionCount => InConnectionQuantity + OutConnectionQuantity;
+
+		/// <summary>
+		/// 呼入总量
+		/// </summary>
+		public int InTotal { get; set; }
+
+		/// <summary>
+		/// 呼出总量
+		/// </summary>
+		public int OutTotal { get; set; }
+
+		/// <summary>
+		/// 呼入接通量
+		/// </summary>
+		public int InConnectionQuantity { get; set; }
+
+		/// <summary>
+		/// 呼出接通量
+		/// </summary>
+		public int OutConnectionQuantity { get; set; }
+
+		/// <summary>
+		/// 有效
+		/// </summary>
+		public int EffectiveCount { get; set; }
 
         /// <summary>
         /// 无效
@@ -161,6 +191,12 @@ namespace Hotline.Share.Dtos.CallCenter
         public int IvrByeCount { get; set; }
 
 
+		/// <summary>
+		/// 挂断总量
+		/// </summary>
+		public int AllByeCount => QueueByeCount + IvrByeCount;
+
+
 		/// <summary>
 		/// 总体接通率
 		/// </summary>

+ 42 - 0
src/Hotline.Share/Dtos/File/UploadAudioFilesRequestDto.cs

@@ -0,0 +1,42 @@
+namespace Hotline.Share.Dtos.File
+{
+    public class UploadAudioFilesRequestDto
+    {
+        public string Id { get; set; }
+
+        /// <summary>
+        /// 附件Id
+        /// </summary>
+        public string FileId { get; set; }
+
+        /// <summary>
+		/// 附件全称
+		/// </summary>
+        public string FileName { get; set; }
+
+        /// <summary>
+        /// 附件名称
+        /// </summary>
+        public string? Name { get; set; }
+
+        /// <summary>
+		/// 附件类型
+		/// </summary>
+        public string? Type { get; set; }
+
+        /// <summary>
+        /// 附件路径
+        /// </summary>
+        public string Path { get; set; }
+
+        /// <summary>
+        /// 完整附件路径
+        /// </summary>
+        public string? AllPath { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime CreationTime { get; set; }
+    }
+}

+ 10 - 0
src/Hotline.Share/Dtos/Knowledge/KnowledgeDto.cs

@@ -466,6 +466,16 @@ namespace Hotline.Share.Dtos.Knowledge
         /// 浏览时间
         /// </summary>
         public DateTime CreationTime { get; set; }
+
+        /// <summary>
+        /// 浏览完成时间
+        /// </summary>
+        public DateTime? PvEndTime { get; set; }
+
+        /// <summary>
+        /// 浏览时长
+        /// </summary>
+        public int? BrowseTime { get; set; } = 0;
     }
 
     public class KnowledgeWordOutDto

+ 93 - 1
src/Hotline.Share/Dtos/Order/OrderBiDto.cs

@@ -743,6 +743,58 @@ namespace Hotline.Share.Dtos.Order
             return Math.Round((NoPutThroughCount / (double)TotalSumCount) * 100, 2);
         }
         public string NoPutThroughRateText => NoPutThroughRate + "%";
+
+        /// <summary>
+        /// 一般数
+        /// </summary>
+        public int NormalCount { get; set; }
+
+        /// <summary>
+        /// 一般Key
+        /// </summary>
+        public string NormalKey => "3";
+
+        /// <summary>
+        /// 一般率
+        /// </summary>
+        public double NormalRate => CalcNormalRate();
+
+        public double CalcNormalRate()
+        {
+            if (NormalCount == 0 || TotalSumCount == 0)
+            {
+                return 0.000;
+            }
+            return Math.Round((NormalCount / (double)TotalSumCount) * 100, 3);
+        }
+
+        public string NormalRateText => NormalRate + "%";
+
+        /// <summary>
+        /// 非常不满意数
+        /// </summary>
+        public int VeryNoSatisfiedCount { get; set; }
+
+        /// <summary>
+        /// 非常不满意数Key
+        /// </summary>
+        public string VeryNoSatisfiedKey => "1";
+
+        /// <summary>
+        /// 非常不满意率
+        /// </summary>
+        public double VeryNoSatisfiedRate => CalcVeryNoSatisfiedRate();
+
+        public double CalcVeryNoSatisfiedRate()
+        {
+            if (VeryNoSatisfiedCount == 0 || TotalSumCount == 0)
+            {
+                return 0.000;
+            }
+            return Math.Round((VeryNoSatisfiedCount / (double)TotalSumCount) * 100, 3);
+        }
+
+        public string VeryNoSatisfiedRateText => VeryNoSatisfiedRate + "%";
     }
 
     public class BiOrderSendVo
@@ -981,7 +1033,6 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public double NoPutThroughRate => CalcNoPutThroughRate();
 
-
         public double CalcNoPutThroughRate()
         {
             if (NoPutThroughCount == 0 || TotalSumCount == 0)
@@ -993,6 +1044,47 @@ namespace Hotline.Share.Dtos.Order
 
         public string NoPutThroughRateText => NoPutThroughRate + "%";
 
+        /// <summary>
+        /// 一般数
+        /// </summary>
+        public int NormalCount { get; set; }
+
+        /// <summary>
+        /// 一般率
+        /// </summary>
+        public double NormalRate => CalcNormalRate();
+
+        public double CalcNormalRate()
+        {
+            if (NormalCount == 0 || TotalSumCount == 0)
+            {
+                return 0.000;
+            }
+            return Math.Round((NormalCount / (double)TotalSumCount) * 100, 3);
+        }
+
+        public string NormalRateText => NormalRate + "%";
+
+        /// <summary>
+        /// 非常不满意数
+        /// </summary>
+        public int VeryNoSatisfiedCount { get; set; }
+
+        /// <summary>
+        /// 非常不满意率
+        /// </summary>
+        public double VeryNoSatisfiedRate => CalcVeryNoSatisfiedRate();
+
+        public double CalcVeryNoSatisfiedRate()
+        {
+            if (VeryNoSatisfiedCount == 0 || TotalSumCount == 0)
+            {
+                return 0.000;
+            }
+            return Math.Round((VeryNoSatisfiedCount / (double)TotalSumCount) * 100, 3);
+        }
+
+        public string VeryNoSatisfiedRateText => VeryNoSatisfiedRate + "%";
     }
 
     public class OrderSourceVo

+ 63 - 6
src/Hotline.Share/Dtos/Order/OrderDto.cs

@@ -656,13 +656,13 @@ namespace Hotline.Share.Dtos.Order
 
         public string RemainingTimeTextVoid()
         {
-            if (Status >= EOrderStatus.Filed && FiledTime !=null)
+            if (Status >= EOrderStatus.Filed && FiledTime != null)
             {
-                return Math.Round((ExpiredTime.Value - FiledTime.Value).TotalDays,1) + "天";
+                return Math.Round((ExpiredTime.Value - FiledTime.Value).TotalDays, 1) + "天";
             }
-            else if(Status < EOrderStatus.Filed && ExpiredTime!=null)
+            else if (Status < EOrderStatus.Filed && ExpiredTime != null)
             {
-                return Math.Round((ExpiredTime.Value - DateTime.Now).TotalDays,1) + "天";
+                return Math.Round((ExpiredTime.Value - DateTime.Now).TotalDays, 1) + "天";
             }
             else
             {
@@ -743,6 +743,41 @@ namespace Hotline.Share.Dtos.Order
 
         public int ReTransactNum { get; set; }
 
+        /// <summary>
+        /// 省重办次数
+        /// </summary>
+        public int? ProvinceReTransactNum { get; set; }
+
+        /// <summary>
+        /// 工单交办处理方式 10:直接办结,20:交办,30:派单员重派,40:结果审核重派,50:回访不满意重派
+        /// </summary>
+        public string? CaseProcessTypeText => GetCaseProcessTypeText();
+        public string GetCaseProcessTypeText()
+        {
+            var text = "";
+            if (!string.IsNullOrEmpty(CaseProcessType))
+            {
+                switch (CaseProcessType)
+                {
+                    case "10":
+                    case "20":
+                        break;
+                    case "30":
+                        text = "派单员重派";
+                        break;
+                    case "40":
+                        text = "结果审核重派";
+                        break;
+                    case "50":
+                        text = "回访不满意重派";
+                        break;
+                    default:
+                        break;
+                }
+            }
+            return text;
+        }
+
         /// <summary>
         /// 敏感标签
         /// </summary>
@@ -792,7 +827,7 @@ namespace Hotline.Share.Dtos.Order
                 {
                     overDays = (FiledTime - ExpiredTime).Value.Days + "天";
                 }
-				else if (FiledTime.HasValue == false && ExpiredTime < DateTime.Now)
+                else if (FiledTime.HasValue == false && ExpiredTime < DateTime.Now)
                 {
                     overDays = (DateTime.Now - ExpiredTime).Value.Days + "天";
                 }
@@ -872,6 +907,16 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public string ProvinceRevokeString { get; set; }
 
+        /// <summary>
+        /// 省甄别
+        /// </summary>
+        public string ProvinceScreenString { get; set; }
+
+        /// <summary>
+        /// 省延期
+        /// </summary>
+        public string? ProvinceDelayString { get; set; }
+
         /// <summary>
         /// 省工单退回
         /// </summary>
@@ -955,7 +1000,7 @@ namespace Hotline.Share.Dtos.Order
         public List<OrderComplementDto> OrderComplements { get; set; }
 
         public bool? IsReTransact { get; set; }
-	}
+    }
 
     public class UpdateOrderDto : AddOrderDto
     {
@@ -1216,6 +1261,13 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public DateTime? ExpiredTimeProvince { get; set; }
 
+        /// <summary>
+        /// 工单交办处理方式 10:直接办结,20:交办,30:派单员重派,40:结果审核重派,50:回访不满意重派
+        /// 处理方式为结果审核重派时禁止退单
+        /// 处理方式为回访不满意重派时禁止退单
+        /// </summary>
+        public string? CaseProcessType { get; set; }
+
         /// <summary>
         /// 外部工单唯一标识
         /// </summary>
@@ -1337,6 +1389,11 @@ namespace Hotline.Share.Dtos.Order
         /// 工单推送分类
         /// </summary>
         public List<OrderPushTypeDto>? OrderPushTypes { get; set; }
+
+        /// <summary>
+        ///知识库引用
+        /// </summary>
+        public List<Kv>? KnowledgeQuote { get; set; }
     }
 
     public record CanLinkCallRecordOrderDto : PagedKeywordRequest

+ 10 - 0
src/Hotline.Share/Dtos/Order/OrderTsDetailsDto.cs

@@ -0,0 +1,10 @@
+namespace Hotline.Share.Dtos.Order
+{
+    public class OrderTsDetailsDto
+    {
+        public string Name { get; set; }
+
+        public int CountNum { get; set; }
+    }
+
+}

+ 29 - 25
src/Hotline.Share/Enums/Order/ESeatEvaluate.cs

@@ -1,30 +1,26 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.ComponentModel;
 
 namespace Hotline.Share.Enums.Order
 {
     public enum ESeatEvaluate
     {
         /// <summary>
-        /// 默认满意
+        /// 非常满意
         /// </summary>
-        [Description("默认满意")]
-        DefaultSatisfied = 0,
+        [Description("非常满意")]
+        VerySatisfied = 5,
+
         /// <summary>
-        /// 非常不满意
+        /// 满意
         /// </summary>
-        [Description("非常不满意")]
-        VeryNoSatisfied = 1,
+        [Description("满意")]
+        Satisfied = 4,
 
         /// <summary>
-        /// 满意
+        /// 甄别为满意
         /// </summary>
-        [Description("满意")]
-        NoSatisfied = 2,
+        [Description("甄别为满意")]
+        ScreenSatisfied = -1,
 
         /// <summary>
         /// 一般
@@ -33,27 +29,35 @@ namespace Hotline.Share.Enums.Order
         Normal = 3,
 
         /// <summary>
-        /// 满意
+        /// 满意
         /// </summary>
-        [Description("满意")]
-        Satisfied = 4,
+        [Description("满意")]
+        NoSatisfied = 2,
 
         /// <summary>
-        /// 非常满意
+        /// 非常满意
         /// </summary>
-        [Description("非常满意")]
-        VerySatisfied = 5,
+        [Description("非常不满意")]
+        VeryNoSatisfied = 1,
+
+        /// <summary>
+        /// 未做评价
+        /// </summary>
+        [Description("未做评价")]
+        NoEvaluate = 7,
 
         /// <summary>
         /// 未接通
         /// </summary>
         [Description("未接通")]
-        NoConnect= 6,
+        NoConnect = 6,
 
         /// <summary>
-        /// 未做评价
+        /// 默认满意
         /// </summary>
-        [Description("未做评价")]
-        NoEvaluate = 7,
+        [Description("默认满意")]
+        DefaultSatisfied = 0,
+
+
     }
 }

+ 16 - 21
src/Hotline.Share/Enums/Order/EVoiceEvaluate.cs

@@ -1,31 +1,26 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.ComponentModel;
 
 namespace Hotline.Share.Enums.Order
 {
     public enum EVoiceEvaluate
     {
         /// <summary>
-        /// 甄别为满意
+        /// 非常满意
         /// </summary>
-        [Description("甄别为满意")]
-        ScreenSatisfied = -1,
+        [Description("非常满意")]
+        VerySatisfied = 5,
 
         /// <summary>
-        /// 非常不满意
+        /// 满意
         /// </summary>
-        [Description("非常不满意")]
-        VeryNoSatisfied = 1,
+        [Description("满意")]
+        Satisfied = 4,
 
         /// <summary>
-        /// 满意
+        /// 甄别为满意
         /// </summary>
-        [Description("满意")]
-        NoSatisfied = 2,
+        [Description("甄别为满意")]
+        ScreenSatisfied = -1,
 
         /// <summary>
         /// 一般
@@ -34,16 +29,16 @@ namespace Hotline.Share.Enums.Order
         Normal = 3,
 
         /// <summary>
-        /// 满意
+        /// 满意
         /// </summary>
-        [Description("满意")]
-        Satisfied = 4,
+        [Description("满意")]
+        NoSatisfied = 2,
 
         /// <summary>
-        /// 非常满意
+        /// 非常满意
         /// </summary>
-        [Description("非常满意")]
-        VerySatisfied = 5,
+        [Description("非常满意")]
+        VeryNoSatisfied = 1,
 
         /// <summary>
         /// 未做评价

+ 1 - 1
src/Hotline.Share/Hotline.Share.csproj

@@ -7,7 +7,7 @@
     <GenerateDocumentationFile>True</GenerateDocumentationFile>
     <NoWarn>$(NoWarn);1591;8618;</NoWarn>
     <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-    <Version>1.0.113</Version>
+    <Version>1.0.114</Version>
   </PropertyGroup>
 
   <ItemGroup>

+ 2 - 3
src/Hotline.Share/Requests/PagedKeywordRequest.cs

@@ -483,10 +483,9 @@ public record OrgVisitDetailListReq : PagedKeywordRequest
     public EOrgVisitStatisticsType? OrgVisitStatisticsType { get; set; }
 
     /// <summary>
-    /// AttitudeType = 1 是 办件结果
-    /// AttitudeType = 2 是 办事态度
+    /// 部门办件结果
     /// </summary>
-    public string? OrgProcessingResults { get; set; }
+    public List<string>? OrgProcessingResults { get; set; } 
 
     /// <summary>
     /// 回访人

+ 46 - 0
src/Hotline/File/UploadAudioFiles.cs

@@ -0,0 +1,46 @@
+using SqlSugar;
+using System.ComponentModel;
+using XF.Domain.Repository;
+
+namespace Hotline.File
+{
+    [Description("录音上传")]
+    public class UploadAudioFiles : FullStateEntity
+    {
+        /// <summary>
+        /// 附件Id
+        /// </summary>
+        [SugarColumn(ColumnDescription = "附件Id")]
+        public string FileId { get; set; }
+
+        /// <summary>
+		/// 附件全称
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件全称")]
+        public string FileName { get; set; }
+
+        /// <summary>
+        /// 附件名称
+        /// </summary>
+        [SugarColumn(ColumnDescription = "附件名称")]
+        public string? Name { get; set; }
+
+        /// <summary>
+		/// 附件类型
+		/// </summary>
+		[SugarColumn(ColumnDescription = "附件类型")]
+        public string? Type { get; set; }
+
+        /// <summary>
+        /// 附件路径
+        /// </summary>
+        [SugarColumn(ColumnDescription = "附件路径", ColumnDataType = "varchar(500)")]
+        public string Path { get; set; }
+
+        /// <summary>
+        /// 完整附件路径
+        /// </summary>
+		[SugarColumn(ColumnDescription = "完整附件路径")]
+        public string? AllPath { get; set; }
+    }
+}

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

@@ -998,6 +998,10 @@ namespace Hotline.FlowEngine.Workflows
                 prevStep.FlowAssignType = prevStep.BusinessType is EBusinessType.Seat ? EFlowAssignType.Role :
                     prevStep.BusinessType is EBusinessType.Send ? EFlowAssignType.User : EFlowAssignType.Org;
             }
+            if (workflow.FlowType == EFlowType.Review &&  workflow.ModuleCode == WorkflowModuleConsts.OrderScreen)
+            {
+                prevStep.FlowAssignType = EFlowAssignType.Org;
+			}
 
             //复制上一个节点为待接办
             // var newPrevStep =

+ 41 - 26
src/Hotline/KnowledgeBase/KnowledgeDomainService.cs

@@ -9,6 +9,7 @@ using Hotline.Share.Enums.KnowledgeBase;
 using Hotline.Share.Mq;
 using MapsterMapper;
 using SqlSugar;
+using System;
 using XF.Domain.Dependency;
 using XF.Domain.Entities;
 using XF.Domain.Exceptions;
@@ -81,11 +82,24 @@ namespace Hotline.KnowledgeBase
         /// <returns></returns>
         public async Task KnowledgePvIncreaseAsync(Knowledge know, CancellationToken cancellationToken)
         {
+            var content = know.Content;
+            var length = content.Length;
+            double randomInRange = 0;
+            Random random = new Random();
+            double min = 0.10;
+            double max = 0.29;
+            randomInRange = min + (max - min) * random.NextDouble();
+            var browseTime = Convert.ToInt32((randomInRange * length)/60);
+            if (browseTime<=1)
+            {
+                browseTime = random.Next(2, 6);
+            }
             //写入浏览记录
             KnowledgePv knowledgePv = new()
             {
                 CreationTime = DateTime.Now,
-                KnowledgeCode = know.Code
+                KnowledgeCode = know.Code,
+                BrowseTime = browseTime
             };
             //浏览记录写入
             await _knowledgePVRepository.AddAsync(knowledgePv, cancellationToken);
@@ -240,23 +254,24 @@ namespace Hotline.KnowledgeBase
                 knowledge.Status = EKnowledgeStatus.OnShelf;
                 await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
             }
-            else {
-				//现有知识状态更改为已撤回
-				knowledge.Status = EKnowledgeStatus.Revert;
-				await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
-			}
-			//switch (workFlow.WorkflowModuleStatus)
-   //         {
-   //             case EKnowledgeApplyType.Add:
-   //                 //将知识保存为草稿
-   //                 knowledge.Status = EKnowledgeStatus.Drafts;
-   //                 await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
-   //                 break;
-   //             default:
-   //                 //现有知识状态更改为已撤回
-   //                 knowledge.Status = EKnowledgeStatus.Revert;
-   //                 await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
-   //                 break;
+            else
+            {
+                //现有知识状态更改为已撤回
+                knowledge.Status = EKnowledgeStatus.Revert;
+                await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
+            }
+            //switch (workFlow.WorkflowModuleStatus)
+            //         {
+            //             case EKnowledgeApplyType.Add:
+            //                 //将知识保存为草稿
+            //                 knowledge.Status = EKnowledgeStatus.Drafts;
+            //                 await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
+            //                 break;
+            //             default:
+            //                 //现有知识状态更改为已撤回
+            //                 knowledge.Status = EKnowledgeStatus.Revert;
+            //                 await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
+            //                 break;
 
 
             //}
@@ -338,14 +353,14 @@ namespace Hotline.KnowledgeBase
                     isSendType = "2";
                     break;
                 case WorkflowModuleConsts.KnowledgeOffshelf://下架
-	                //知识先下架                          
-	                knowledge.Status = EKnowledgeStatus.OffShelf;
-	                knowledge.OffShelfTime = System.DateTime.Now;
-	                knowledge.WorkflowId = workflow.Id;
-	                await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
-	                isSendType = "2";
-	                break;
-			}
+                                                            //知识先下架                          
+                    knowledge.Status = EKnowledgeStatus.OffShelf;
+                    knowledge.OffShelfTime = System.DateTime.Now;
+                    knowledge.WorkflowId = workflow.Id;
+                    await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
+                    isSendType = "2";
+                    break;
+            }
 
             #region 数据推送
             var pushKnowledge = _mapper.Map<KnowledgeSendDto>(knowledge);

+ 15 - 1
src/Hotline/KnowledgeBase/KnowledgePV.cs

@@ -1,4 +1,5 @@
-using XF.Domain.Repository;
+using SqlSugar;
+using XF.Domain.Repository;
 
 namespace Hotline.KnowledgeBase;
 
@@ -10,5 +11,18 @@ public class KnowledgePv : CreationEntity
     /// <summary>
     /// 知识Code
     /// </summary>
+    [SugarColumn(ColumnDescription = "知识Code")]
     public string KnowledgeCode { get; set; }
+
+    /// <summary>
+    /// 浏览完成时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "浏览完成时间")]
+    public DateTime? PvEndTime { get; set; }
+
+    /// <summary>
+    /// 浏览时长
+    /// </summary>
+    [SugarColumn(ColumnDescription = "浏览时长")]
+    public int? BrowseTime { get; set; }
 }

+ 43 - 0
src/Hotline/KnowledgeBase/KnowledgeQuote.cs

@@ -0,0 +1,43 @@
+using SqlSugar;
+using System.ComponentModel;
+using XF.Domain.Repository;
+
+namespace Hotline.KnowledgeBase
+{
+    /// <summary>
+	/// 知识库引用
+	/// </summary>
+	[Description("知识库引用")]
+    public class KnowledgeQuote : CreationEntity
+    {
+        /// <summary>
+        /// 知识库Id
+        /// </summary>
+        [SugarColumn(ColumnDescription = "知识库Id")]
+        public string KnowledgeId { get; set; }
+
+        /// <summary>
+        /// 知识标题
+        /// </summary>
+        [SugarColumn(ColumnDescription = "知识标题")]
+        public string KnowledgeTitle { get; set; }
+
+        /// <summary>
+        /// 工单ID
+        /// </summary>
+        [SugarColumn(ColumnDescription = "工单ID")]
+        public string OrderId { get; set; }
+
+        /// <summary>
+        /// 工单标题
+        /// </summary>
+        [SugarColumn(ColumnDescription = "工单标题")]
+        public string Title { get; set; }
+
+        /// <summary>
+        /// 工单编号
+        /// </summary>
+        [SugarColumn(ColumnDescription = "工单编号")]
+        public string No { get; set; }
+    }
+}

+ 47 - 28
src/Hotline/Orders/Order.cs

@@ -25,7 +25,7 @@ namespace Hotline.Orders
     [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 partial class Order : PositionWorkflowEntity
     {
         public Order()
         {
@@ -458,8 +458,8 @@ namespace Hotline.Orders
 
         [SugarColumn(ColumnDescription = "全流程工作日时长")]
         public double? AllDurationWorkday { get; set; }
-        
-        
+
+
         public string? AllDurationHour { get; set; }
 
         /// <summary>
@@ -877,7 +877,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 省退回结果
         /// </summary>
-        [SugarColumn(ColumnDescription ="省退回结果")]
+        [SugarColumn(ColumnDescription = "省退回结果")]
         public bool? ProvinceSendBack { get; set; }
 
         #endregion
@@ -931,6 +931,19 @@ namespace Hotline.Orders
         [SugarColumn(ColumnDescription = "派单退回次数")]
         public int? SendBackNum { get; set; }
 
+        /// <summary>
+        /// 省重办次数
+        /// </summary>
+        [SugarColumn(ColumnDescription = "省重办次数")]
+        public int? ProvinceReTransactNum { get; set; }
+
+        /// <summary>
+        /// 工单交办处理方式 10:直接办结,20:交办,30:派单员重派,40:结果审核重派,50:回访不满意重派
+        /// 处理方式为结果审核重派时禁止退单
+        /// 处理方式为回访不满意重派时禁止退单
+        /// </summary>
+        [SugarColumn(ColumnDescription = " 工单交办处理方式 10:直接办结,20:交办,30:派单员重派,40:结果审核重派,50:回访不满意重派")]
+        public string? CaseProcessType { get; set; }
         #endregion
 
         /// <summary>
@@ -1010,7 +1023,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 重点关注事件名称,保存前端选择,用于返回前端数据
         /// </summary>
-        [SugarColumn(ColumnDescription ="重点关注事件名称")]
+        [SugarColumn(ColumnDescription = "重点关注事件名称")]
         public string? FocusOnEventsName { get; set; }
 
         /// <summary>
@@ -1049,17 +1062,17 @@ namespace Hotline.Orders
         [SugarColumn(IsIgnore = true, ColumnDescription = "超期部门名称")]
         public string? DaysOverdueOrgName { get; set; }
 
-		/// <summary>
-		/// 退回截至时间
-		/// </summary>
-		[SugarColumn(ColumnDescription = "退回截至时间")]
-		public DateTime? SendBackAuditEndTime { get; set; }
+        /// <summary>
+        /// 退回截至时间
+        /// </summary>
+        [SugarColumn(ColumnDescription = "退回截至时间")]
+        public DateTime? SendBackAuditEndTime { get; set; }
 
-		/// <summary>
-		/// 话务提醒是否转办
-		/// </summary>
-		[SugarColumn(ColumnDescription = "话务提醒是否转办")]
-		public bool? IsForwarded { get; set; }
+        /// <summary>
+        /// 话务提醒是否转办
+        /// </summary>
+        [SugarColumn(ColumnDescription = "话务提醒是否转办")]
+        public bool? IsForwarded { get; set; }
 
         #region 回访信息
         /// <summary>
@@ -1073,14 +1086,20 @@ namespace Hotline.Orders
         /// </summary>
         [SugarColumn(ColumnDataType = "json", ColumnDescription = "部门办件结果", IsJson = true, IsNullable = true)]
         public Kv? OrgProcessingResults { get; set; }
-		#endregion
+        #endregion
 
         /// <summary>
         /// 老系统工单Id
         /// </summary>
-		[SugarColumn(ColumnDescription = "老系统工单Id")]
-		public string? OldOrderId { get; set; }
-	}
+        [SugarColumn(ColumnDescription = "老系统工单Id")]
+        public string? OldOrderId { get; set; }
+
+        /// <summary>
+        ///知识库引用
+        /// </summary>
+        [SugarColumn(ColumnDataType = "json", IsJson = true, IsNullable = true, ColumnDescription = "知识库引用")]
+        public List<Kv>? KnowledgeQuote { get; set; }
+    }
 
     public partial class Order
     {
@@ -1132,10 +1151,10 @@ namespace Hotline.Orders
         [Navigate(NavigateType.OneToMany, nameof(OrderTerminate.OrderId))]
         public List<OrderTerminate> OrderTerminates { get; set; }
 
-		/// <summary>
-		/// 
-		/// </summary>
-		[Navigate(NavigateType.OneToMany, nameof(OrderSpecial.OrderId))]
+        /// <summary>
+        /// 
+        /// </summary>
+        [Navigate(NavigateType.OneToMany, nameof(OrderSpecial.OrderId))]
         public List<OrderSpecial> OrderSpecials { get; set; }
 
         /// <summary>
@@ -1250,8 +1269,8 @@ namespace Hotline.Orders
         public void FileEmpty()
         {
             FiledTime = null;
-            FileOpinion = string.Empty; 
-			HandleDurationWorkday = 0;
+            FileOpinion = string.Empty;
+            HandleDurationWorkday = 0;
             HandleDuration = 0;
             FileDurationWorkday = 0;
             FileDuration = 0;
@@ -1421,10 +1440,10 @@ namespace Hotline.Orders
                 return "工单状态非 已归档, " + Status.GetDescription();
             return "";
         }
-    #endregion
-}
+        #endregion
+    }
 
-public class UnsignedOrder
+    public class UnsignedOrder
     {
         public Order Order { get; set; }
 

+ 37 - 0
src/Hotline/Orders/OrderTsDetails.cs

@@ -0,0 +1,37 @@
+using SqlSugar;
+using System.ComponentModel;
+using XF.Domain.Repository;
+
+namespace Hotline.Orders
+{
+    /// <summary>
+	/// 工单热词
+	/// </summary>
+	[Description("工单热词")]
+    public class OrderTsDetails : CreationEntity
+    {
+        /// <summary>
+        /// 分词词语
+        /// </summary>
+        [SugarColumn(ColumnDescription = "分词词语")]
+        public string Terms { get; set; }
+
+        /// <summary>
+        /// 工单ID
+        /// </summary>
+        [SugarColumn(ColumnDescription = "工单ID")]
+        public string OrderId { get; set; }
+
+        /// <summary>
+        /// 工单标题
+        /// </summary>
+        [SugarColumn(ColumnDescription = "工单标题")]
+        public string Title { get; set; }
+
+        /// <summary>
+        /// 工单编号
+        /// </summary>
+        [SugarColumn(ColumnDescription = "工单编号")]
+        public string No {  get; set; }
+    }
+}

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

@@ -683,6 +683,11 @@ namespace Hotline.Settings
         /// </summary>
         public const string Snapshot = "Snapshot";
 
+        /// <summary>
+        /// 是否开启分词
+        /// </summary>
+        public const string IsOpenWordSegmentation = "IsOpenWordSegmentation";
+
         /// <summary>
         /// 是否查询老数据
         /// </summary>