瀏覽代碼

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

Dun.Jason 1 周之前
父節點
當前提交
d021bfc620
共有 57 個文件被更改,包括 3016 次插入1444 次删除
  1. 158 91
      src/Hotline.Api/Controllers/Bi/BiCallController.cs
  2. 410 107
      src/Hotline.Api/Controllers/Bi/BiOrderController.cs
  3. 1 59
      src/Hotline.Api/Controllers/IPPbxController.cs
  4. 52 53
      src/Hotline.Api/Controllers/JudicialManagementOrdersController.cs
  5. 360 247
      src/Hotline.Api/Controllers/OrderController.cs
  6. 2 0
      src/Hotline.Api/Controllers/PushMessageController.cs
  7. 78 41
      src/Hotline.Api/Controllers/QualityController.cs
  8. 1 1
      src/Hotline.Api/Controllers/Snapshot/SnapshotController.cs
  9. 43 5
      src/Hotline.Api/Controllers/TestController.cs
  10. 1 1
      src/Hotline.Api/StartupExtensions.cs
  11. 14 14
      src/Hotline.Api/StartupHelper.cs
  12. 1 0
      src/Hotline.Api/config/appsettings.Development.json
  13. 8 4
      src/Hotline.Application/CallCenter/DefaultCallApplication.cs
  14. 39 26
      src/Hotline.Application/JudicialManagement/EnforcementApplication.cs
  15. 19 5
      src/Hotline.Application/OrderApp/Handlers/OrderHandler/OrderVisitSmsHandler.cs
  16. 192 148
      src/Hotline.Application/OrderApp/OrderApplication.cs
  17. 14 6
      src/Hotline.Application/OrderApp/OrderSecondaryHandlingApplication.cs
  18. 23 12
      src/Hotline.Application/OrderApp/OrderSendBackAuditApplication.cs
  19. 2 1
      src/Hotline.Application/Snapshot/BiSnapshotApplication.cs
  20. 1 1
      src/Hotline.Application/Snapshot/Contracts/ISnapshotApplication.cs
  21. 63 14
      src/Hotline.Application/Snapshot/SnapshotApplicationBase.cs
  22. 17 8
      src/Hotline.Application/Snapshot/SnapshotOrderApplication.cs
  23. 9 4
      src/Hotline.Application/StatisticalReport/CallReport/CallReportApplicationBase.cs
  24. 23 18
      src/Hotline.Application/StatisticalReport/CallReport/YiBinCallReportApplication.cs
  25. 2 2
      src/Hotline.Application/StatisticalReport/ICallReportApplication.cs
  26. 2 2
      src/Hotline.Repository.SqlSugar/Extensions/SqlSugarStartupExtensions.cs
  27. 16 0
      src/Hotline.Share/Dtos/JudicialManagement/EnforcementOrderListDto.cs
  28. 36 1
      src/Hotline.Share/Dtos/JudicialManagement/JudicialManagementAddOrderDto.cs
  29. 62 44
      src/Hotline.Share/Dtos/Order/OrderBiDto.cs
  30. 155 90
      src/Hotline.Share/Dtos/Order/OrderFinalityDto.cs
  31. 36 1
      src/Hotline.Share/Dtos/Order/OrderSecondaryHandlingDto.cs
  32. 305 25
      src/Hotline.Share/Dtos/Order/QueryOrderDto.cs
  33. 261 200
      src/Hotline.Share/Dtos/Order/SendBackDto.cs
  34. 5 0
      src/Hotline.Share/Dtos/Push/MessagePagedDto.cs
  35. 5 0
      src/Hotline.Share/Dtos/Push/PushReceiveMessageDto.cs
  36. 54 1
      src/Hotline.Share/Dtos/Quality/QualityDto.cs
  37. 167 134
      src/Hotline.Share/Dtos/Quality/QualityItemDto.cs
  38. 23 1
      src/Hotline.Share/Dtos/Quality/QualityTemplateDto.cs
  39. 0 1
      src/Hotline.Share/Dtos/Snapshot/PointsDto.cs
  40. 2 2
      src/Hotline.Share/Enums/Order/ECaseType.cs
  41. 33 0
      src/Hotline.Share/Requests/PagedKeywordRequest.cs
  42. 7 1
      src/Hotline/Caching/Interfaces/ISystemSettingCacheManager.cs
  43. 13 0
      src/Hotline/Caching/Services/SystemSettingCacheManager.cs
  44. 11 3
      src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs
  45. 1 1
      src/Hotline/Hotline.csproj
  46. 3 2
      src/Hotline/Orders/OrderDomainService.cs
  47. 21 9
      src/Hotline/Orders/OrderVisitDomainService.cs
  48. 39 25
      src/Hotline/Push/FWMessage/PushDomainService.cs
  49. 5 0
      src/Hotline/Settings/SettingConstants.cs
  50. 29 0
      src/Hotline/Snapshot/ETianqueRequestMode.cs
  51. 75 0
      src/Hotline/Tools/LocationConverter.cs
  52. 9 8
      src/TianQue.Sdk/TQHttpClient.cs
  53. 42 19
      src/TianQue.Sdk/TiqnQueService.cs
  54. 5 3
      test/Hotline.Tests/Application/DefaultCallApplicationTest.cs
  55. 1 0
      test/Hotline.Tests/Application/PointsRecordApplicationTest.cs
  56. 12 3
      test/Hotline.Tests/Application/SnapshotApplicationTest.cs
  57. 48 0
      test/Hotline.Tests/Domain/PushDomainServiceTest.cs

+ 158 - 91
src/Hotline.Api/Controllers/Bi/BiCallController.cs

@@ -24,6 +24,8 @@ using XF.Utility.EnumExtensions;
 using Hotline.Share.Enums.CallCenter;
 using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Api.Filter;
+using Hotline.Share.Dtos.Order.Publish;
+using Hotline.Application.StatisticalReport.CallReport;
 
 namespace Hotline.Api.Controllers.Bi;
 
@@ -85,8 +87,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("calls_export")]
-	[LogFilterAlpha("导出日志")]
-	[AllowAnonymous]
+    [LogFilterAlpha("导出日志")]
+    [AllowAnonymous]
     public async Task<FileStreamResult> ExportQueryCallsAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
         => ExcelStreamResult(
             _exportApplication.GetExcelStream(
@@ -136,8 +138,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query_calls_statistics_export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> QueryCallsStatisticsExportAsync([FromBody] ExportExcelDto<StartEndTimeDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QueryCallsStatisticsExportAsync([FromBody] ExportExcelDto<StartEndTimeDto> dto)
     {
         var items = (await _callReportApplication.QueryCallsDetailStatisticsAsync(dto.QueryDto, HttpContext.RequestAborted));
         return _exportApplication.GetExcelFile(dto, items, "话务日期统计", "Date");
@@ -159,8 +161,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query_calls_statistics_detail/export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> QueryCallsStatisticsDetailAsync([FromBody] ExportExcelDto<QueryCallsStatisticsDetailInDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QueryCallsStatisticsDetailAsync([FromBody] ExportExcelDto<QueryCallsStatisticsDetailInDto> dto)
     {
         var items = (await _callReportApplication.QueryCallsStatisticsDetailAsync(dto.QueryDto, HttpContext.RequestAborted)).Item2;
         return _exportApplication.GetExcelFile(dto, items, "话务日期统计详情", "OrderNo");
@@ -218,8 +220,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query_calls_detail_export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> QueryCallsDetailExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QueryCallsDetailExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
     {
         return ExcelStreamResult(
             _exportApplication.GetExcelStream(
@@ -267,8 +269,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query_incall_calls_list_export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> GetInCallCallListExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> GetInCallCallListExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
     {
         var (total, data) = await _callReportApplication.QueryCallsDetailInTotalAsync(dto.QueryDto, dto.IsExportAll);
 
@@ -328,8 +330,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query_calls_hour_detail_list_export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> QueryCallsHourDetailListExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QueryCallsHourDetailListExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
         => ExcelStreamResult(
             _exportApplication.GetExcelStream(
                 dto,
@@ -363,8 +365,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("seats/export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> ExportSeatss([FromBody] ExportExcelDto<ReportRequiredPagedRequest> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> ExportSeatss([FromBody] ExportExcelDto<ReportRequiredPagedRequest> dto)
     {
         return ExcelStreamResult(
             _exportApplication.GetExcelStream(
@@ -432,6 +434,46 @@ public class BiCallController : BaseController
             .ToListAsync(HttpContext.RequestAborted);
     }
 
+    /// <summary>
+    /// 小休统计
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpPost("rests/export")]
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QuerySeatRestExport([FromBody] ExportExcelDto<QuerySeatRestRequest> dto)
+    {
+        var query = await _telRestRepository.Queryable()
+            .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.UserName), x => x.UserName.Contains(dto.QueryDto.UserName))
+            .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.StaffNo), x => x.StaffNo.Contains(dto.QueryDto.StaffNo))
+            .Where(x => x.CreationTime >= dto.QueryDto.StartTime)
+            .Where(x => x.CreationTime <= dto.QueryDto.EndTime)
+            .GroupBy(x => new { x.UserId, x.StaffNo, x.UserName })
+            .Select(x => new BiSeatRestDto
+            {
+                UserId = x.UserId,
+                StaffNo = x.StaffNo,
+                UserName = x.UserName,
+                RestCount = SqlFunc.AggregateCount(x.Id),
+                RestDuration = SqlFunc.AggregateSum(x.RestDuration / 60) / SqlFunc.AggregateCount(x.Id),
+                CumulativeDuration = SqlFunc.AggregateSum(x.RestDuration / 60)
+            })
+            .OrderByIF(dto.QueryDto.SortRule is 0, a => a.RestDuration, OrderByType.Asc)
+            .OrderByIF(dto.QueryDto.SortRule is 1, a => a.RestDuration, OrderByType.Desc)
+            .MergeTable()
+            .ToListAsync(HttpContext.RequestAborted);
+
+        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<BiSeatRestDto>(dto.ColumnInfos);
+
+        var dtos = _mapper.Map<ICollection<BiSeatRestDto>>(query)
+                          .Select(stu => _mapper.Map(stu, typeof(BiSeatRestDto), dynamicClass))
+                          .Cast<object>()
+                          .ToList();
+
+        var stream = ExcelHelper.CreateStream(dtos);
+        return ExcelStreamResult(stream, "座席小休统计表");
+    }
+
     /// <summary>
     /// 坐席转接统计
     /// </summary>
@@ -441,10 +483,32 @@ public class BiCallController : BaseController
     [AllowAnonymous]
     public async Task<PagedDto<BiSeatSwitchDto>> QuerySeatSwitch([FromQuery] QuerySeatSwitchRequest dto)
     {
-        var (total, items) = await _callReportApplication.QuerySeatSwitchAsync(dto, HttpContext.RequestAborted);
+        var (total, items) = await _callReportApplication.QuerySeatSwitchAsync(dto, false, HttpContext.RequestAborted);
         return new PagedDto<BiSeatSwitchDto>(total, items);
     }
 
+    /// <summary>
+    /// 坐席转接统计导出
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpPost("seatswitch/export")]
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QuerySeatSwitchExport([FromBody] ExportExcelDto<QuerySeatSwitchRequest> dto)
+    {
+        var (total, items) = await _callReportApplication.QuerySeatSwitchAsync(dto.QueryDto, dto.IsExportAll, HttpContext.RequestAborted);
+
+        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<BiSeatSwitchDto>(dto.ColumnInfos);
+        var dtos = _mapper.Map<ICollection<BiSeatSwitchDto>>(items)
+                          .Select(stu => _mapper.Map(stu, typeof(BiSeatSwitchDto), dynamicClass))
+                          .Cast<object>()
+                          .ToList();
+        var stream = ExcelHelper.CreateStream(dtos);
+        return ExcelStreamResult(stream, "转外线统计分析");
+    }
+
+
+
     /// <summary>
     /// 小时统计
     /// </summary>
@@ -459,8 +523,8 @@ public class BiCallController : BaseController
     /// </summary>
     /// <returns></returns>
     [HttpPost("hourcall/export")]
-	[LogFilterAlpha("导出日志")]
-	[AllowAnonymous]
+    [LogFilterAlpha("导出日志")]
+    [AllowAnonymous]
     public async Task<FileStreamResult> ExportQueryHourCall([FromBody] ExportExcelDto<BiQueryHourCallDto> dto)
         => ExcelStreamResult(
             _exportApplication.GetExcelStream(
@@ -488,7 +552,7 @@ public class BiCallController : BaseController
     [HttpGet("hourcall_list")]
     public async Task<PagedDto<BiSeatSwitchDto>> QueryCallList([FromQuery] QueryCallListDto dto)
     {
-        var res =  await _callReportApplication.GetCallListAsync(dto, HttpContext.RequestAborted);
+        var res = await _callReportApplication.GetCallListAsync(dto, HttpContext.RequestAborted);
         return new PagedDto<BiSeatSwitchDto>(res.Total, res.Data);
     }
 
@@ -498,29 +562,29 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("hourcall_list/export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> ExportQueryCallList([FromBody] ExportExcelDto<QueryCallListDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> ExportQueryCallList([FromBody] ExportExcelDto<QueryCallListDto> dto)
     {
-		foreach (var item in dto.ColumnInfos)
-		{
-            if (item.Prop  == "cpn" || item.Prop == "cdpn")
+        foreach (var item in dto.ColumnInfos)
+        {
+            if (item.Prop == "cpn" || item.Prop == "cdpn")
             {
                 item.Prop = item.Prop.ToUpper();
             }
-		}
-		return ExcelStreamResult(
-		  _exportApplication.GetExcelStream(
-			  dto,
-			  (await _callReportApplication.GetCallListAsync(dto.QueryDto, HttpContext.RequestAborted)).Data)
-		  , "通话时段分析");
-	} 
-
-	/// <summary>
-	/// 通话时段统计明细获取基本信息
-	/// </summary>
-	/// <param name="id"></param>
-	/// <returns></returns>
-	[HttpGet("hourcall_list_base")]
+        }
+        return ExcelStreamResult(
+          _exportApplication.GetExcelStream(
+              dto,
+              (await _callReportApplication.GetCallListAsync(dto.QueryDto, HttpContext.RequestAborted)).Data)
+          , "通话时段分析");
+    }
+
+    /// <summary>
+    /// 通话时段统计明细获取基本信息
+    /// </summary>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    [HttpGet("hourcall_list_base")]
     public async Task<object> ReTransactBaseData()
     {
         var rsp = new
@@ -548,8 +612,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("gateway-query/export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> ExportQueryGatetWay(ExportExcelDto<BiQueryGateWayDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> ExportQueryGatetWay(ExportExcelDto<BiQueryGateWayDto> dto)
         => ExcelStreamResult(
             _exportApplication.GetExcelStream(
                 dto,
@@ -570,21 +634,22 @@ public class BiCallController : BaseController
     {
         var list = await _callReportApplication.QueryCallDateStatisticsDetail(dto);
 
-        var total = new QueryCallDateStatisticsDetailResp() {
+        var total = new QueryCallDateStatisticsDetailResp()
+        {
             Date = "合计",
-            IvrCallInTotal = list.Sum(x=>x.IvrCallInTotal),
-            PersonCallInCount = list.Sum(x=>x.PersonCallInCount),
-            EnterpriseCallInCount = list.Sum(x=>x.EnterpriseCallInCount),
-            GaoXiaoCallInCount = list.Sum(x=>x.GaoXiaoCallInCount), //高效办成一件事
-            AiCallInCount = list.Sum(x=>x.AiCallInCount),
-            PersonCallInPutthroughCount = list.Sum(x=>x.PersonCallInPutthroughCount),
-            EnterpriseCallInPutthroughCount = list.Sum(x=>x.EnterpriseCallInPutthroughCount),
-            GaoXiaoCallInPutthroughCount = list.Sum(x=>x.GaoXiaoCallInPutthroughCount),
-            AiCallInPutthroughCount = list.Sum(x=>x.AiCallInPutthroughCount),
-            PersonRingOffCount = list.Sum(x=>x.PersonRingOffCount),//个人服务挂断
-            EnterpriseRingOffCount = list.Sum(x=>x.EnterpriseRingOffCount), //企业挂断
-            GaoXiaoRingOffCount = list.Sum(x=>x.GaoXiaoRingOffCount), 
-            IvrRingOffCount = list.Sum(x=>x.IvrRingOffCount), //IVR挂断
+            IvrCallInTotal = list.Sum(x => x.IvrCallInTotal),
+            PersonCallInCount = list.Sum(x => x.PersonCallInCount),
+            EnterpriseCallInCount = list.Sum(x => x.EnterpriseCallInCount),
+            GaoXiaoCallInCount = list.Sum(x => x.GaoXiaoCallInCount), //高效办成一件事
+            AiCallInCount = list.Sum(x => x.AiCallInCount),
+            PersonCallInPutthroughCount = list.Sum(x => x.PersonCallInPutthroughCount),
+            EnterpriseCallInPutthroughCount = list.Sum(x => x.EnterpriseCallInPutthroughCount),
+            GaoXiaoCallInPutthroughCount = list.Sum(x => x.GaoXiaoCallInPutthroughCount),
+            AiCallInPutthroughCount = list.Sum(x => x.AiCallInPutthroughCount),
+            PersonRingOffCount = list.Sum(x => x.PersonRingOffCount),//个人服务挂断
+            EnterpriseRingOffCount = list.Sum(x => x.EnterpriseRingOffCount), //企业挂断
+            GaoXiaoRingOffCount = list.Sum(x => x.GaoXiaoRingOffCount),
+            IvrRingOffCount = list.Sum(x => x.IvrRingOffCount), //IVR挂断
         };
 
         return new { List = list, Total = total };
@@ -596,8 +661,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query-calldate-statistics/export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> QueryCallDateStatisticsDetailExport([FromBody]ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QueryCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
          =>
             _exportApplication.GetExcelFile(
                 dto,
@@ -610,16 +675,17 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpGet("query-person-calldate-statistics")]
-    public async Task<object> QueryPersonCallDateStatisticsDetail([FromQuery]QueryCallDateStatisticsDetailDto dto)
+    public async Task<object> QueryPersonCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
     {
         var list = await _callReportApplication.QueryPersonCallDateStatisticsDetail(dto);
-        var total = new QueryPersonCallDateStatisticsDetailResp() {
+        var total = new QueryPersonCallDateStatisticsDetailResp()
+        {
             Date = "合计",
-            PersonCallInCount = list.Sum(x=>x.PersonCallInCount),
-            PersonCallInPutthroughCount = list.Sum(x=>x.PersonCallInPutthroughCount),
+            PersonCallInCount = list.Sum(x => x.PersonCallInCount),
+            PersonCallInPutthroughCount = list.Sum(x => x.PersonCallInPutthroughCount),
             //PersonRingOffCount = list.Sum(x=>x.PersonRingOffCount),//个人服务挂断
-            PersonQueueOffCount = list.Sum(x=>x.PersonQueueOffCount),//个人服务队列挂断
-            PersonWaitOffCount = list.Sum(x=>x.PersonWaitOffCount) //个人服务等待挂断
+            PersonQueueOffCount = list.Sum(x => x.PersonQueueOffCount),//个人服务队列挂断
+            PersonWaitOffCount = list.Sum(x => x.PersonWaitOffCount) //个人服务等待挂断
         };
         return new { List = list, Total = total };
     }
@@ -630,12 +696,12 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query-person-calldate-statistics/export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> QueryPersonCallDateStatisticsDetailExport([FromBody]ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QueryPersonCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
      => _exportApplication.GetExcelFile(
                 dto,
                 await _callReportApplication.QueryPersonCallDateStatisticsDetail(dto.QueryDto)
-            , "个人服务话务明细","Date");
+            , "个人服务话务明细", "Date");
 
 
     /// <summary>
@@ -644,16 +710,17 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpGet("query-enterprise-calldate-statistics")]
-    public async Task<object> QueryEnterpriseCallDateStatisticsDetail([FromQuery]QueryCallDateStatisticsDetailDto dto)
+    public async Task<object> QueryEnterpriseCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
     {
         var list = await _callReportApplication.QueryEnterpriseCallDateStatisticsDetail(dto);
-        var total = new QueryEnterpriseCallDateStatisticsDetailResp() {
+        var total = new QueryEnterpriseCallDateStatisticsDetailResp()
+        {
             Date = "合计",
-            EnterpriseCallInCount = list.Sum(x=>x.EnterpriseCallInCount),
-            EnterpriseCallInPutthroughCount = list.Sum(x=>x.EnterpriseCallInPutthroughCount),
+            EnterpriseCallInCount = list.Sum(x => x.EnterpriseCallInCount),
+            EnterpriseCallInPutthroughCount = list.Sum(x => x.EnterpriseCallInPutthroughCount),
             //EnterpriseRingOffCount = list.Sum(x=>x.EnterpriseRingOffCount), //企业挂断
-            EnterpriseQueueOffCount = list.Sum(x=>x.EnterpriseQueueOffCount),//个人服务队列挂断
-            EnterpriseWaitOffCount = list.Sum(x=>x.EnterpriseWaitOffCount) //个人服务等待挂断
+            EnterpriseQueueOffCount = list.Sum(x => x.EnterpriseQueueOffCount),//个人服务队列挂断
+            EnterpriseWaitOffCount = list.Sum(x => x.EnterpriseWaitOffCount) //个人服务等待挂断
         };
         return new { List = list, Total = total };
     }
@@ -664,12 +731,12 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query-enterprise-calldate-statistics/export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> QueryEnterpriseCallDateStatisticsDetailExport([FromBody]ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QueryEnterpriseCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
     => _exportApplication.GetExcelFile(
                 dto,
                 await _callReportApplication.QueryEnterpriseCallDateStatisticsDetail(dto.QueryDto)
-            , "企业服务话务明细","Date");
+            , "企业服务话务明细", "Date");
 
 
     /// <summary>
@@ -681,7 +748,7 @@ public class BiCallController : BaseController
     public async Task<object> QueryCallOutDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
     {
         List<string> enterpriseTels = _systemSettingCacheManager.GetSetting(SettingConstants.EnterpriseTel)?.SettingValue;
-        var list = await _callReportApplication.QueryCallOutDateStatisticsDetail(dto,enterpriseTels);
+        var list = await _callReportApplication.QueryCallOutDateStatisticsDetail(dto, enterpriseTels);
 
         var total = new QueryCallOutDateStatisticsDetailResp()
         {
@@ -691,9 +758,9 @@ public class BiCallController : BaseController
             AiVisitCallOutCount = list.Sum(x => x.AiVisitCallOutCount),
             AiCallOutCount = list.Sum(x => x.AiCallOutCount),
             PersonCallOutPutthroughCount = list.Sum(x => x.PersonCallOutPutthroughCount),
-            EnterpriseCallOutPutthroughCount = list.Sum(x=>x.EnterpriseCallOutPutthroughCount),
-            AiVisitCallOutPutthroughCount = list.Sum(x=>x.AiVisitCallOutPutthroughCount),
-            AiCallOutPutthroughCount = list.Sum(x=>x.AiCallOutPutthroughCount)
+            EnterpriseCallOutPutthroughCount = list.Sum(x => x.EnterpriseCallOutPutthroughCount),
+            AiVisitCallOutPutthroughCount = list.Sum(x => x.AiVisitCallOutPutthroughCount),
+            AiCallOutPutthroughCount = list.Sum(x => x.AiCallOutPutthroughCount)
         };
 
         return new { List = list, Total = total };
@@ -706,14 +773,14 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query-callout-date-statistics/export")]
-	[LogFilterAlpha("导出日志")]
-	public async  Task<FileStreamResult> QueryCallOutDateStatisticsDetailExport([FromBody]ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QueryCallOutDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
     {
         List<string> enterpriseTels = _systemSettingCacheManager.GetSetting(SettingConstants.EnterpriseTel)?.SettingValue;
 
         return _exportApplication.GetExcelFile(
                 dto,
-                await _callReportApplication.QueryCallOutDateStatisticsDetail(dto.QueryDto,enterpriseTels)
+                await _callReportApplication.QueryCallOutDateStatisticsDetail(dto.QueryDto, enterpriseTels)
             , "呼出话务统计明细", "Date");
     }
 
@@ -723,9 +790,9 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpGet("query-seat-monthcall")]
-    public async Task<object> QuerySeatMonthCall([FromQuery]QuerySeatMonthCallRequest dto)
+    public async Task<object> QuerySeatMonthCall([FromQuery] QuerySeatMonthCallRequest dto)
     {
-        var list =  await _callReportApplication.QuerySeatMonthCall(dto);
+        var list = await _callReportApplication.QuerySeatMonthCall(dto);
         var total = new QuerySeatMonthCallResp()
         {
             Name = "合计",
@@ -750,10 +817,10 @@ public class BiCallController : BaseController
     public async Task<object> QuerySeatMonthCallBaseData()
     {
         var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi).SettingValue;
-       
+
         return new
         {
-            SeatUser =await _userRepository.Queryable().Includes(d => d.Roles).Where(d => d.Roles.Any(x => setting.Contains(x.Name))).ToListAsync()            
+            SeatUser = await _userRepository.Queryable().Includes(d => d.Roles).Where(d => d.Roles.Any(x => setting.Contains(x.Name))).ToListAsync()
         };
     }
 
@@ -763,10 +830,10 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query-seat-monthcall/export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> QuerySeatMonthCallExport([FromBody] ExportExcelDto<QuerySeatMonthCallRequest> dto)
-    =>  _exportApplication.GetExcelFile(
-            dto,              
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QuerySeatMonthCallExport([FromBody] ExportExcelDto<QuerySeatMonthCallRequest> dto)
+    => _exportApplication.GetExcelFile(
+            dto,
             await _callReportApplication.QuerySeatMonthCall(dto.QueryDto)
             , "坐席月接通率统计", "Name");
 
@@ -780,7 +847,7 @@ public class BiCallController : BaseController
     public async Task<PagedDto<QuerySeatMonthCallDetailResp>> QuerySeatMonthCallDetail([FromQuery] QuerySeatMonthCallDetailRequest dto)
     {
         var query = _callReportApplication.QuerySeatMonthCallDetail(dto);
-        var(total, items) =  await query.ToPagedListAsync(dto.PageIndex, dto.PageSize);
+        var (total, items) = await query.ToPagedListAsync(dto.PageIndex, dto.PageSize);
         return new PagedDto<QuerySeatMonthCallDetailResp>(total, items);
     }
 
@@ -790,8 +857,8 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("query-seat-monthcall-detail/export")]
-	[LogFilterAlpha("导出日志")]
-	public async Task<FileStreamResult> QuerySeatMonthCallDetailExport([FromBody] ExportExcelDto<QuerySeatMonthCallDetailRequest> dto)
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QuerySeatMonthCallDetailExport([FromBody] ExportExcelDto<QuerySeatMonthCallDetailRequest> dto)
     {
         var query = _callReportApplication.QuerySeatMonthCallDetail(dto.QueryDto);
         List<QuerySeatMonthCallDetailResp> data;

+ 410 - 107
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -1202,6 +1202,66 @@ namespace Hotline.Api.Controllers.Bi
             return new PagedDto<OrderBiSpecialListVo>(total, items);
         }
 
+        /// <summary>
+        /// 特提统计导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("special_data_list/export")]
+        [LogFilterAlpha("导出日志")]
+        public async Task<FileStreamResult> SpecialDataListExport([FromBody] ExportExcelDto<ReportPagedRequest> dto)
+        {
+            if (!dto.QueryDto.StartTime.HasValue || !dto.QueryDto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
+
+            var IsCenter = _sessionContext.OrgIsCenter;
+
+            var query = _orderSpecialRepository.Queryable()
+                .WhereIF(dto.QueryDto.StartTime.HasValue, x => x.CreationTime >= dto.QueryDto.StartTime)
+                .WhereIF(dto.QueryDto.EndTime.HasValue, x => x.CreationTime <= dto.QueryDto.EndTime)
+                .WhereIF(IsCenter == false, x => x.OrgId.StartsWith(_sessionContext.RequiredOrgId))
+                .GroupBy(x => new { x.Cause })
+                .Select(x => new OrderBiSpecialListVo
+                {
+                    Cause = x.Cause,
+                    OrderNum = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
+                    MaxSpecialTime = SqlFunc.AggregateMax(x.CreationTime),
+                })
+                .MergeTable();
+            switch (dto.QueryDto.SortField)
+            {
+                case "cause":
+                    query = dto.QueryDto.SortRule is 0 ? query.OrderBy(x => x.Cause) : query.OrderByDescending(x => x.Cause);
+                    break;
+                case "orderNum":
+                    query = dto.QueryDto.SortRule is 0 ? query.OrderBy(x => x.OrderNum) : query.OrderByDescending(x => x.OrderNum);
+                    break;
+                case "maxSpecialTime":
+                    query = dto.QueryDto.SortRule is 0 ? query.OrderBy(x => x.MaxSpecialTime) : query.OrderByDescending(x => x.MaxSpecialTime);
+                    break;
+            }
+
+            var total = 0;
+            var items = new List<OrderBiSpecialListVo>();
+            if (dto.IsExportAll)
+            {
+                items = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                (total, items) = await query.ToPagedListAsync(dto.QueryDto.PageIndex, dto.QueryDto.PageSize, HttpContext.RequestAborted);
+            }
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<OrderBiSpecialListVo>(dto.ColumnInfos);
+
+            var dtos = _mapper.Map<ICollection<OrderBiSpecialListVo>>(items)
+                              .Select(stu => _mapper.Map(stu, typeof(OrderBiSpecialListVo), dynamicClass))
+                              .Cast<object>()
+                              .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "特提统计");
+        }
+
         /// <summary>
         /// 获取工单特提信息列表
         /// </summary>
@@ -4349,6 +4409,67 @@ namespace Hotline.Api.Controllers.Bi
             return new PagedDto<HighFrequencyCallStatisticsDto>(total, _mapper.Map<IReadOnlyList<HighFrequencyCallStatisticsDto>>(items));
         }
 
+        /// <summary>
+        /// 高频来电统计导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("high_frequency_call_statistics/export")]
+        [LogFilterAlpha("导出日志")]
+        public async Task<FileStreamResult> HighFrequencyCallStatisticsExport([FromBody] ExportExcelDto<HighFrequencyCallStatisticsRequest> dto)
+        {
+            if (!dto.QueryDto.StartTime.HasValue || !dto.QueryDto.EndTime.HasValue)
+                throw UserFriendlyException.SameMessage("请选择时间!");
+
+            int CallCount = 2;
+            var HighFrequencyCallStatistics = _systemSettingCacheManager.GetSetting(SettingConstants.HighFrequencyCallStatistics)?.SettingValue[0];
+            if (HighFrequencyCallStatistics != null)
+                CallCount = int.Parse(HighFrequencyCallStatistics);
+
+            var query = _trCallRecordRepository.Queryable()
+                     .LeftJoin<Order>((p, o) => p.ExternalId == o.Id)
+                   .Where((p, o) => p.OverTime >= dto.QueryDto.StartTime && p.OverTime <= dto.QueryDto.EndTime)
+                   .Where((p, o) => p.CallOrderType == ECallOrderType.Order)
+                   .Where((p, o) => p.ExternalId != null && o.Id != null)
+                   .Where((p, o) => p.CallDirection == ECallDirection.In)
+                    .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.PhoneNum), (p, o) => p.CPN == dto.QueryDto.PhoneNum)
+                   .Select((p, o) => new
+                   {
+                       p.CPN,
+                       p.ExternalId
+                   })
+                   .MergeTable()
+                   .GroupBy(p => p.CPN)
+                   .Select(p => new HighFrequencyCallStatisticsDto
+                   {
+                       Callnum = p.CPN,
+                       OrderCountNum = SqlFunc.AggregateCount(p.CPN),//总量
+                   })
+                  .MergeTable()
+                 .Where(p => p.OrderCountNum >= CallCount)
+                 .OrderByDescending(p => p.OrderCountNum);
+
+            var total = 0;
+            var items = new List<HighFrequencyCallStatisticsDto>();
+            if (dto.IsExportAll)
+            {
+                items = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                (total, items) = await query.ToPagedListAsync(dto.QueryDto.PageIndex, dto.QueryDto.PageSize, HttpContext.RequestAborted);
+            }
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<HighFrequencyCallStatisticsDto>(dto.ColumnInfos);
+            var dtos = _mapper.Map<ICollection<HighFrequencyCallStatisticsDto>>(items)
+                              .Select(stu => _mapper.Map(stu, typeof(HighFrequencyCallStatisticsDto), dynamicClass))
+                              .Cast<object>()
+                              .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "高频来电统计");
+        }
+
         /// <summary>
         /// 高频来电统计列表详情
         /// </summary>
@@ -4483,6 +4604,83 @@ namespace Hotline.Api.Controllers.Bi
             return new PagedDto<HighMatterWarningDto>(total, _mapper.Map<IReadOnlyList<HighMatterWarningDto>>(items));
         }
 
+        /// <summary>
+        /// 高频事项预警
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("highmatter-warning/export")]
+        [LogFilterAlpha("导出日志")]
+        public async Task<FileStreamResult> HighMatterWarningExport([FromBody] ExportExcelDto<HighMatterWarningRequest> dto)
+        {
+            var filterTitle = _systemSettingCacheManager.GetSetting(SettingConstants.HighMatterWarningFilterTitle).SettingValue;
+
+            var query = _orderRepository.Queryable()
+                .Where(x => x.CreationTime >= dto.QueryDto.StartTime && x.CreationTime <= dto.QueryDto.EndTime)
+                .Where(x => filterTitle.Any(s => x.Title.Contains(s)) == false)
+                .LeftJoin<SystemArea>((it, o) => it.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")) == o.Id)
+                .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.AcceptType), x => x.AcceptTypeCode == dto.QueryDto.AcceptType)//受理类型
+                .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.Hotspot), x => x.HotspotSpliceName != null && x.HotspotSpliceName.Contains(dto.QueryDto.Hotspot))//热点类型
+                .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.AreaCode), x => x.AreaCode == dto.QueryDto.AreaCode)//区域
+                .GroupBy((it, o) => new
+                {
+                    it.AcceptTypeCode,
+                    it.AcceptType,
+                    it.HotspotId,
+                    it.HotspotName,
+                    AreaCode = it.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
+                    o.AreaName,
+                })
+                .Having((it, o) => SqlFunc.AggregateCount(it.HotspotName) >= 5)
+                .Select((it, o) => new HighMatterWarningDto()
+                {
+                    AcceptTypeCode = it.AcceptTypeCode,
+                    AcceptType = it.AcceptType,
+                    AreaName = o.AreaName,
+                    HotspotName = it.HotspotName,
+                    HotspotId = it.HotspotId,
+                    SumCount = SqlFunc.AggregateCount(it.HotspotName),
+                    Id = SqlFunc.AggregateMin(it.Id),
+                    AreaCode = it.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6"))
+                })
+                .MergeTable()
+                .LeftJoin<Order>((x, d) => x.Id == d.Id)
+                .Select((x, d) => new HighMatterWarningDto()
+                {
+                    AreaName = x.AreaName,
+                    HotspotName = x.HotspotName,
+                    HotspotId = x.HotspotId,
+                    Title = d.Title,
+                    SumCount = x.SumCount,
+                    Id = d.Id,
+                    AcceptTypeCode = x.AcceptTypeCode,
+                    AcceptType = x.AcceptType,
+                    AreaCode = x.AreaCode
+                })
+                .MergeTable()
+                .OrderByDescending(d => d.SumCount);
+
+            var total = 0;
+            var items = new List<HighMatterWarningDto>();
+            if (dto.IsExportAll)
+            {
+                items = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                (total, items) = await query.ToPagedListAsync(dto.QueryDto.PageIndex, dto.QueryDto.PageSize, HttpContext.RequestAborted);
+            }
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<HighMatterWarningDto>(dto.ColumnInfos);
+            var dtos = _mapper.Map<ICollection<HighMatterWarningDto>>(items)
+                              .Select(stu => _mapper.Map(stu, typeof(HighMatterWarningDto), dynamicClass))
+                              .Cast<object>()
+                              .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "高频事项预警");
+        }
+
         /// <summary>
         /// 高频事项预警明细
         /// </summary>
@@ -5697,6 +5895,51 @@ namespace Hotline.Api.Controllers.Bi
             }
         }
 
+        /// <summary>
+        /// 下级区域统计导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("area_subordinate/export")]
+        [LogFilterAlpha("导出日志")]
+        public async Task<FileStreamResult> AreaSubordinateExport([FromBody] ExportExcelDto<AreaSubordinateRequest> dto)
+        {
+            var StartTime = dto.QueryDto.StartTime;
+            var EndTime = dto.QueryDto.EndTime;
+            var TypeId = dto.QueryDto.TypeId;
+            var Line = dto.QueryDto.Line;
+            DataTable data = new DataTable();
+
+            var list = await _systemAreaRepository.Queryable()
+                .LeftJoin<Order>((s, o) => o.AreaCode.StartsWith(s.Id))
+                .Where((s, o) => o.CreationTime >= StartTime && o.CreationTime <= EndTime)
+                .WhereIF(TypeId != null && TypeId == 1, (s, o) => o.IdentityType == EIdentityType.Citizen)
+                .WhereIF(TypeId != null && TypeId == 2, (s, o) => o.IdentityType == EIdentityType.Enterprise)
+                .WhereIF(!string.IsNullOrEmpty(Line), (s, o) => o.TransferPhone == Line)
+                .GroupBy((s, o) => s.Id)
+                .OrderBy((s, o) => new { s.Id }, OrderByType.Asc)
+                .Select((s, o) => new AreaSubordinateReportRes
+                {
+                    AreaName = s.AreaName,
+                    SumCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.AreaCode.StartsWith(s.Id), 1, 0))
+                })
+                .ToListAsync();
+            data = list.ToDataTable("areasubordinate");
+            //合计
+            DataRow sumRow = data.NewRow();
+            sumRow["AreaName"] = "合计";
+            decimal totalAmount = 0;
+            foreach (DataRow row in data.Rows)
+            {
+                totalAmount += Convert.ToDecimal(row["SumCount"]);
+            }
+            sumRow["SumCount"] = totalAmount;
+            data.Rows.Add(sumRow);
+
+            var stream = ExcelHelper.CreateStream(data);
+            return ExcelStreamResult(stream, "下级区域统计");
+        }
+
         /// <summary>
         /// 热点满意度统计
         /// </summary>
@@ -6791,6 +7034,66 @@ namespace Hotline.Api.Controllers.Bi
             return returnList;
         }
 
+        /// <summary>
+        /// 网上群众路线通报导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("onlinemassline-report/export")]
+        [LogFilterAlpha("导出日志")]
+        public async Task<FileStreamResult> OnlineMassLineReportExport([FromBody] ExportExcelDto<OnlineMassLineReportRequest> dto)
+        {
+            var nowList = await _orderRepository.Queryable()
+                .Where(x => x.CreationTime >= dto.QueryDto.StartTime && x.CreationTime <= dto.QueryDto.EndTime).ToListAsync();
+
+
+            var oldList = await _orderRepository.Queryable()
+                .Where(x => x.CreationTime >= dto.QueryDto.ChainStartTime && x.CreationTime <= dto.QueryDto.ChainEndTime).ToListAsync();
+
+
+            var returnList = new List<OnlineMassLineReportRes>();
+            //市12345政务服务便民热线
+            var Other = new OnlineMassLineReportRes();
+            Other.SourceChannel = "市12345政务服务便民热线";
+            Other.SumCount = nowList.Where(x => x.IsProvince == false && x.SourceChannelCode != "SZYSM").Count(); //市12345政务服务便民热线
+            Other.PreviousCount = oldList.Where(x => x.IsProvince == false && x.SourceChannelCode != "SZYSM").Count(); //市12345政务服务便民热线
+            returnList.Add(Other);
+            //中国政府网“我向总理说句话”
+            var ZGZFW = new OnlineMassLineReportRes();
+            ZGZFW.SourceChannel = "中国政府网“我向总理说句话”";
+            ZGZFW.SumCount = nowList.Where(x => x.IsProvince == true && x.ReceiveProvinceNo.StartsWith("ZGZFW")).Count(); //中国政府网“我向总理说句话”
+            ZGZFW.PreviousCount = oldList.Where(x => x.IsProvince == true && x.ReceiveProvinceNo.StartsWith("ZGZFW")).Count(); //中国政府网“我向总理说句话”
+            returnList.Add(ZGZFW);
+            //国家政务服务平台“投诉与建议”
+            var GJZWFWPT = new OnlineMassLineReportRes();
+            GJZWFWPT.SourceChannel = "国家政务服务平台“投诉与建议”";
+            GJZWFWPT.SumCount = nowList.Where(x => x.IsProvince == true && x.ReceiveProvinceNo.StartsWith("GJZWFWPT")).Count(); //国家政务服务平台“投诉与建议”
+            GJZWFWPT.PreviousCount = oldList.Where(x => x.IsProvince == true && x.ReceiveProvinceNo.StartsWith("GJZWFWPT")).Count(); //国家政务服务平台“投诉与建议”
+            returnList.Add(GJZWFWPT);
+            //省12345政务服务便民热线
+            var Province12345 = new OnlineMassLineReportRes();
+            Province12345.SourceChannel = "省12345政务服务便民热线";
+            Province12345.SumCount = nowList.Where(x => x.IsProvince == true && x.ReceiveProvinceNo.StartsWith("GJZWFWPT") == false && x.ReceiveProvinceNo.StartsWith("ZGZFW") == false).Count(); //国家政务服务平台“投诉与建议”
+            Province12345.PreviousCount = oldList.Where(x => x.IsProvince == true && x.ReceiveProvinceNo.StartsWith("GJZWFWPT") == false && x.ReceiveProvinceNo.StartsWith("ZGZFW") == false).Count(); //国家政务服务平台“投诉与建议”
+            returnList.Add(Province12345);
+            //市政府网站“市长与网民”
+            var SZYSM = new OnlineMassLineReportRes();
+            SZYSM.SourceChannel = "市政府网站“市长与网民”";
+            SZYSM.SumCount = nowList.Where(x => x.SourceChannelCode == "SZYSM").Count(); //国家政务服务平台“投诉与建议”
+            SZYSM.PreviousCount = oldList.Where(x => x.SourceChannelCode == "SZYSM").Count(); //国家政务服务平台“投诉与建议”
+            returnList.Add(SZYSM);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<OnlineMassLineReportRes>(dto.ColumnInfos);
+
+            var dtos = _mapper.Map<ICollection<OnlineMassLineReportRes>>(returnList)
+                              .Select(stu => _mapper.Map(stu, typeof(OnlineMassLineReportRes), dynamicClass))
+                              .Cast<object>()
+                              .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "网上群众路线统计");
+        }
+
         /// <summary>
         /// 部门退回中心统计
         /// </summary>
@@ -6890,111 +7193,111 @@ namespace Hotline.Api.Controllers.Bi
         }
 
 
-		/// <summary>
-		/// 坐席退回中心统计
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpGet("seat_sendback_statistics")]
-		public async Task<List<SeatSendBackStatisticsVo>> SeatSendBackStatistics([FromQuery] PagedKeywordRequest dto)
-		{
-			var quer = _orderApplication.SeatSendBackStatistics(dto);
-			var list = await quer.ToListAsync(HttpContext.RequestAborted);
-			list.Add(new SeatSendBackStatisticsVo()
-			{
-				UserName = "合计",
-				SendOrderNum = list.Sum(m => m.SendOrderNum),
-				SendOrderBackNum = list.Sum(m => m.SendOrderBackNum),
-				SendOrderBackNumber = list.Sum(m => m.SendOrderBackNumber),
-				CentreFileNum = list.Sum(m => m.CentreFileNum),
-				CentreFileBackNum = list.Sum(m => m.CentreFileBackNum),
-				CentreFileBackNumber = list.Sum(m => m.CentreFileBackNumber),
-			});
-
-			return list;
-		}
-
-		/// <summary>
-		/// 坐席退回中心统计
-		/// </summary>
-		/// <returns></returns>
-		[HttpPost("seat_sendback_statistics/_export")]
-		[LogFilterAlpha("导出日志")]
-		public async Task<FileStreamResult> SeatSendBackStatisticsExport([FromBody] ExportExcelDto<PagedKeywordRequest> dto)
-		{
-			var query = _orderApplication.SeatSendBackStatistics(dto.QueryDto);
-			List<SeatSendBackStatisticsVo> data;
-
-			data = await query.ToListAsync(HttpContext.RequestAborted);
-
-			data.Add(new SeatSendBackStatisticsVo()
-			{
-				UserName = "合计",
-				SendOrderNum = data.Sum(m => m.SendOrderNum),
-				SendOrderBackNum = data.Sum(m => m.SendOrderBackNum),
-				SendOrderBackNumber = data.Sum(m => m.SendOrderBackNumber),
-				CentreFileNum = data.Sum(m => m.CentreFileNum),
-				CentreFileBackNum = data.Sum(m => m.CentreFileBackNum),
-				CentreFileBackNumber = data.Sum(m => m.CentreFileBackNumber),
-			});
-
-			dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<SeatSendBackStatisticsVo>(dto.ColumnInfos);
-
-			var dtos = data
-				.Select(stu => _mapper.Map(stu, typeof(SeatSendBackStatisticsVo), dynamicClass))
-				.Cast<object>()
-				.ToList();
-
-			var stream = ExcelHelper.CreateStream(dtos);
-
-			return ExcelStreamResult(stream, "坐席退回统计");
-		}
-
-		/// <summary>
-		/// 坐席退回统计明细
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpGet("seat_sendback_detail")]
-		public async Task<PagedDto<OrderDto>> SeatSendBackStatisticsDetail([FromQuery] SeatSendBackStatisticsDetail dto)
-		{
-			var quer = _orderApplication.SeatSendBackStatisticsDetail(dto);
-			var (total, items) = await quer.ToPagedListAsync(dto.PageIndex, dto.PageSize);
-
-			return new PagedDto<OrderDto>(total, items);
-		}
-
-		/// <summary>
-		/// 坐席退回统计明细导出
-		/// </summary>
-		/// <returns></returns>
-		[HttpPost("seat_sendback_detail/_export")]
-		[LogFilterAlpha("导出日志")]
-		public async Task<FileStreamResult> SeatSendBackStatisticsDetailExport([FromBody] ExportExcelDto<SeatSendBackStatisticsDetail> dto)
-		{
-			var query = _orderApplication.SeatSendBackStatisticsDetail(dto.QueryDto);
-			List<OrderDto> data;
-			if (dto.IsExportAll)
-			{
-				data = await query.ToListAsync(HttpContext.RequestAborted);
-			}
-			else
-			{
-				var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
-				data = items;
-			}
-
-			dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<OrderDto>(dto.ColumnInfos);
-
-			var dtos = data
-				.Select(stu => _mapper.Map(stu, typeof(OrderDto), dynamicClass))
-				.Cast<object>()
-				.ToList();
-
-			var stream = ExcelHelper.CreateStream(dtos);
-
-			return ExcelStreamResult(stream, "坐席退回统计明细");
-		}
-
-	}
+        /// <summary>
+        /// 坐席退回中心统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("seat_sendback_statistics")]
+        public async Task<List<SeatSendBackStatisticsVo>> SeatSendBackStatistics([FromQuery] PagedKeywordRequest dto)
+        {
+            var quer = _orderApplication.SeatSendBackStatistics(dto);
+            var list = await quer.ToListAsync(HttpContext.RequestAborted);
+            list.Add(new SeatSendBackStatisticsVo()
+            {
+                UserName = "合计",
+                SendOrderNum = list.Sum(m => m.SendOrderNum),
+                SendOrderBackNum = list.Sum(m => m.SendOrderBackNum),
+                SendOrderBackNumber = list.Sum(m => m.SendOrderBackNumber),
+                CentreFileNum = list.Sum(m => m.CentreFileNum),
+                CentreFileBackNum = list.Sum(m => m.CentreFileBackNum),
+                CentreFileBackNumber = list.Sum(m => m.CentreFileBackNumber),
+            });
+
+            return list;
+        }
+
+        /// <summary>
+        /// 坐席退回中心统计
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("seat_sendback_statistics/_export")]
+        [LogFilterAlpha("导出日志")]
+        public async Task<FileStreamResult> SeatSendBackStatisticsExport([FromBody] ExportExcelDto<PagedKeywordRequest> dto)
+        {
+            var query = _orderApplication.SeatSendBackStatistics(dto.QueryDto);
+            List<SeatSendBackStatisticsVo> data;
+
+            data = await query.ToListAsync(HttpContext.RequestAborted);
+
+            data.Add(new SeatSendBackStatisticsVo()
+            {
+                UserName = "合计",
+                SendOrderNum = data.Sum(m => m.SendOrderNum),
+                SendOrderBackNum = data.Sum(m => m.SendOrderBackNum),
+                SendOrderBackNumber = data.Sum(m => m.SendOrderBackNumber),
+                CentreFileNum = data.Sum(m => m.CentreFileNum),
+                CentreFileBackNum = data.Sum(m => m.CentreFileBackNum),
+                CentreFileBackNumber = data.Sum(m => m.CentreFileBackNumber),
+            });
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<SeatSendBackStatisticsVo>(dto.ColumnInfos);
+
+            var dtos = data
+                .Select(stu => _mapper.Map(stu, typeof(SeatSendBackStatisticsVo), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "坐席退回统计");
+        }
+
+        /// <summary>
+        /// 坐席退回统计明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("seat_sendback_detail")]
+        public async Task<PagedDto<OrderDto>> SeatSendBackStatisticsDetail([FromQuery] SeatSendBackStatisticsDetail dto)
+        {
+            var quer = _orderApplication.SeatSendBackStatisticsDetail(dto);
+            var (total, items) = await quer.ToPagedListAsync(dto.PageIndex, dto.PageSize);
+
+            return new PagedDto<OrderDto>(total, items);
+        }
+
+        /// <summary>
+        /// 坐席退回统计明细导出
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("seat_sendback_detail/_export")]
+        [LogFilterAlpha("导出日志")]
+        public async Task<FileStreamResult> SeatSendBackStatisticsDetailExport([FromBody] ExportExcelDto<SeatSendBackStatisticsDetail> dto)
+        {
+            var query = _orderApplication.SeatSendBackStatisticsDetail(dto.QueryDto);
+            List<OrderDto> data;
+            if (dto.IsExportAll)
+            {
+                data = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                data = items;
+            }
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<OrderDto>(dto.ColumnInfos);
+
+            var dtos = data
+                .Select(stu => _mapper.Map(stu, typeof(OrderDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "坐席退回统计明细");
+        }
+
+    }
 }

+ 1 - 59
src/Hotline.Api/Controllers/IPPbxController.cs

@@ -684,66 +684,8 @@ namespace Hotline.Api.Controllers
                 //await _iPPbxApplication.ResetTelStatus(null, dto.TelNo, CancellationToken.None);
             }
             dto.Status = await _callTelClient.GetStatusAsync(dto.Status);
-            //await _callApplication.EndActionAsync(dto.Adapt<EndActionInDto>());
-            TelOperation telOperation = new TelOperation
-            {
-                StaffNo = dto.StaffNo,
-                TelNo = dto.TelNo,
-                OperateState = dto.Status,
-                OperateTime = DateTime.Now,
-            };
+            await _callApplication.EndActionAsync(dto.Adapt<EndActionInDto>());
 
-            switch (dto.Status)
-            {
-                case 0:
-                    telOperation.OperateStateText = "签出";
-                    break;
-                case 100:
-                    telOperation.OperateStateText = "签入";
-                    break;
-                case 200:
-                    telOperation.OperateStateText = "空闲";
-                    break;
-                case 201:
-                    telOperation.OperateStateText = "小休";
-                    break;
-                case 202:
-                    telOperation.OperateStateText = "繁忙";
-                    break;
-                case 300:
-                    telOperation.OperateStateText = "呼入振铃";
-                    break;
-                case 301:
-                    telOperation.OperateStateText = "呼入通话";
-                    break;
-                case 302:
-                    telOperation.OperateStateText = "呼出振铃";
-                    break;
-                case 303:
-                    telOperation.OperateStateText = "呼出通话";
-                    break;
-                case 310:
-                    telOperation.OperateStateText = "通话保持";
-                    break;
-                case 320:
-                    telOperation.OperateStateText = "会议";
-                    break;
-                case 330:
-                    telOperation.OperateStateText = "咨询";
-                    break;
-                case 400:
-                    telOperation.OperateStateText = "整理";
-                    break;
-                case 900:
-                    telOperation.OperateStateText = "注册";
-                    break;
-                case 901:
-                    telOperation.OperateStateText = "注销";
-                    break;
-                default:
-                    break;
-            }
-            await _telOperationRepository.AddAsync(telOperation);
         }
 
         #endregion

+ 52 - 53
src/Hotline.Api/Controllers/JudicialManagementOrdersController.cs

@@ -38,7 +38,6 @@ namespace Hotline.Api.Controllers
         private readonly IRepository<EnforcementOrdersHandler> _enforcementOrdersHandlerRepository;
         private readonly IEnforcementApplication _enforcementApplication;
         private readonly IRepository<Order> _orderRepository;
-        private readonly IRepository<LawEnforcementAgencies> _lawEnforcementAgenciesRepository;
 
         /// <summary>
         /// 
@@ -86,7 +85,6 @@ namespace Hotline.Api.Controllers
             _enforcementOrdersHandlerRepository = enforcementOrdersHandlerRepository;
             _enforcementApplication = enforcementApplication;
             _orderRepository = orderRepository;
-            _lawEnforcementAgenciesRepository = lawEnforcementAgenciesRepository;
         }
 
         /// <summary>
@@ -106,12 +104,12 @@ namespace Hotline.Api.Controllers
             await _judicialManagementOrdersService.AddAsync(order, true, HttpContext.RequestAborted);
 
             //处理执法部门
-            if (dto.LawEnforcementAgencies != null && dto.LawEnforcementAgencies.Any())
+            if (dto.EnforcementOrdersHandler != null && dto.EnforcementOrdersHandler.Any())
             {
-                List<LawEnforcementAgencies> lawEnforcementAgencies = new();
-                foreach (var item in dto.LawEnforcementAgencies)
+                List<EnforcementOrdersHandler> enforcementOrdersHandlers = new();
+                foreach (var item in dto.EnforcementOrdersHandler)
                 {
-                    lawEnforcementAgencies.Add(new LawEnforcementAgencies
+                    enforcementOrdersHandlers.Add(new EnforcementOrdersHandler
                     {
                         OrderId = order.Id,
                         OrderNo = order.No,
@@ -120,8 +118,8 @@ namespace Hotline.Api.Controllers
                         OrgName = item.Key
                     });
                 }
-                if (lawEnforcementAgencies != null && lawEnforcementAgencies.Any())
-                    await _lawEnforcementAgenciesRepository.AddRangeAsync(lawEnforcementAgencies, HttpContext.RequestAborted);
+                if (enforcementOrdersHandlers != null && enforcementOrdersHandlers.Any())
+                    await _enforcementOrdersHandlerRepository.AddRangeAsync(enforcementOrdersHandlers, HttpContext.RequestAborted);
             }
             return order.Id;
         }
@@ -148,12 +146,12 @@ namespace Hotline.Api.Controllers
             await _judicialManagementOrdersRepository.UpdateAsync(order, HttpContext.RequestAborted);
 
             //处理执法部门
-            if (dto.LawEnforcementAgencies != null && dto.LawEnforcementAgencies.Any())
+            if (dto.EnforcementOrdersHandler != null && dto.EnforcementOrdersHandler.Any())
             {
-                List<LawEnforcementAgencies> lawEnforcementAgencies = new();
-                foreach (var item in dto.LawEnforcementAgencies)
+                List<EnforcementOrdersHandler> enforcementOrdersHandlers = new();
+                foreach (var item in dto.EnforcementOrdersHandler)
                 {
-                    lawEnforcementAgencies.Add(new LawEnforcementAgencies
+                    enforcementOrdersHandlers.Add(new EnforcementOrdersHandler
                     {
                         OrderId = order.Id,
                         OrderNo = order.No,
@@ -161,10 +159,10 @@ namespace Hotline.Api.Controllers
                         OrgCode = item.Value,
                         OrgName = item.Key
                     });
-                    if (lawEnforcementAgencies != null && lawEnforcementAgencies.Any())
+                    if (enforcementOrdersHandlers != null && enforcementOrdersHandlers.Any())
                     {
-                        await _lawEnforcementAgenciesRepository.RemoveAsync(p => p.OrderId == order.Id, false, HttpContext.RequestAborted);
-                        await _lawEnforcementAgenciesRepository.AddRangeAsync(lawEnforcementAgencies, HttpContext.RequestAborted);
+                        await _enforcementOrdersHandlerRepository.RemoveAsync(p => p.OrderId == order.Id, false, HttpContext.RequestAborted);
+                        await _enforcementOrdersHandlerRepository.AddRangeAsync(enforcementOrdersHandlers, HttpContext.RequestAborted);
                     }
 
                 }
@@ -190,45 +188,45 @@ namespace Hotline.Api.Controllers
             await _judicialManagementOrdersRepository.UpdateAsync(order, HttpContext.RequestAborted);
         }
 
-        /// <summary>
-        /// 关联执法部门
-        /// </summary>
-        /// <param name="dto"></param>
-        /// <returns></returns>
-        [HttpPut("associated_law_enforcement_gencies")]
-        [LogFilter("关联执法部门")]
-        public async Task AssociatedLawEnforcementAgencies([FromBody] AssociatedLawEnforcementAgenciesDto dto)
-        {
-            if (dto.LawEnforcementAgencies == null || dto.LawEnforcementAgencies.Count == 0)
-                throw UserFriendlyException.SameMessage("请选择执法部门");
-
-            var order = await _judicialManagementOrdersRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
-            if (order == null)
-                throw UserFriendlyException.SameMessage("工单查询失败");
-            //处理执法部门
-            if (dto.LawEnforcementAgencies != null && dto.LawEnforcementAgencies.Any())
-            {
-                List<LawEnforcementAgencies> lawEnforcementAgencies = new();
-                foreach (var item in dto.LawEnforcementAgencies)
-                {
-                    lawEnforcementAgencies.Add(new LawEnforcementAgencies
-                    {
-                        OrderId = order.Id,
-                        OrderNo = order.No,
-                        OrderSoure = EOrderSoure.Enforcement,
-                        OrgCode = item.Value,
-                        OrgName = item.Key
-                    });
-                }
-                if (lawEnforcementAgencies != null && lawEnforcementAgencies.Any())
-                {
-                    await _lawEnforcementAgenciesRepository.AddRangeAsync(lawEnforcementAgencies, HttpContext.RequestAborted);
-                    order.LawEnforcementAgencies = dto.LawEnforcementAgencies;
-                    await _judicialManagementOrdersRepository.UpdateAsync(order, HttpContext.RequestAborted);
-                }
-            }
+        ///// <summary>
+        ///// 关联执法部门
+        ///// </summary>
+        ///// <param name="dto"></param>
+        ///// <returns></returns>
+        //[HttpPut("associated_law_enforcement_gencies")]
+        //[LogFilter("关联执法部门")]
+        //public async Task AssociatedLawEnforcementAgencies([FromBody] AssociatedLawEnforcementAgenciesDto dto)
+        //{
+        //    if (dto.LawEnforcementAgencies == null || dto.LawEnforcementAgencies.Count == 0)
+        //        throw UserFriendlyException.SameMessage("请选择执法部门");
+
+        //    var order = await _judicialManagementOrdersRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
+        //    if (order == null)
+        //        throw UserFriendlyException.SameMessage("工单查询失败");
+        //    //处理执法部门
+        //    if (dto.LawEnforcementAgencies != null && dto.LawEnforcementAgencies.Any())
+        //    {
+        //        List<LawEnforcementAgencies> lawEnforcementAgencies = new();
+        //        foreach (var item in dto.LawEnforcementAgencies)
+        //        {
+        //            lawEnforcementAgencies.Add(new LawEnforcementAgencies
+        //            {
+        //                OrderId = order.Id,
+        //                OrderNo = order.No,
+        //                OrderSoure = EOrderSoure.Enforcement,
+        //                OrgCode = item.Value,
+        //                OrgName = item.Key
+        //            });
+        //        }
+        //        if (lawEnforcementAgencies != null && lawEnforcementAgencies.Any())
+        //        {
+        //            await _enforcementOrdersHandlerRepository.AddRangeAsync(lawEnforcementAgencies, HttpContext.RequestAborted);
+        //            order.LawEnforcementAgencies = dto.LawEnforcementAgencies;
+        //            await _judicialManagementOrdersRepository.UpdateAsync(order, HttpContext.RequestAborted);
+        //        }
+        //    }
 
-        }
+        //}
 
         /// <summary>
         /// 查询工单详情
@@ -259,6 +257,7 @@ namespace Hotline.Api.Controllers
                     dto.IsResolved = data.IsResolved;
                     dto.FileOpinion = data.FileOpinion;
                     dto.CenterOpinion = data.CenterToOrgOpinion;
+                    dto.EnforcementOrdersHandler = order.EnforcementOrdersHandler;
                 }
             }
 

+ 360 - 247
src/Hotline.Api/Controllers/OrderController.cs

@@ -9,7 +9,7 @@ using Hotline.Application.Quality;
 using Hotline.Application.Snapshot.Contracts;
 using Hotline.Application.Systems;
 using Hotline.Article;
-using Hotline.Authentications; 
+using Hotline.Authentications;
 using Hotline.Caching.Interfaces;
 using Hotline.CallCenter.Calls;
 using Hotline.Configurations;
@@ -2358,146 +2358,41 @@ public class OrderController : BaseController
     /// <summary>
     /// 批量审批延期
     /// </summary>
-    //[HttpPost("delay/batch_audit")]
-    //[LogFilter("批量审批延期")]
-    ////[LogFilterAlpha("延期审核")]
-    //public async Task<string> BatchAuditDelay([FromBody] BatchDelayNextFlowDto dto)
-    //{
-    //    var result = new StringBuilder();
-    //    var fail = 0;
-    //    var success = 0;
-    //    var workflow = dto.NextWorkflow;
-    //    foreach (var item in dto.DelayId)
-    //    {
-    //        try
-    //        {
-    //            //if (workflow.NextHandlers.Any() && workflow.NextHandlers.Count() == 1)
-    //            //{
-    //            //    var handler = workflow.NextHandlers.FirstOrDefault();
-    //            //    if (string.IsNullOrEmpty(handler.UserId))
-    //            //    {
-    //            //        workflow.NextHandlers = new List<StepAssignInfo>();
-    //            //    }
-    //            //}
-
-    //            var delay = await _orderDelayRepository.Queryable().Includes(x => x.Order).Where(x => x.Id == item)
-    //                .FirstAsync(HttpContext.RequestAborted);
-    //            workflow.WorkflowId = delay.WorkflowId;
-    //            var workflowEntuty = await _workflowDomainService.GetWorkflowAsync(workflow.WorkflowId, withDefine: true, withSteps: true,
-    //                cancellationToken: HttpContext.RequestAborted);
-    //            var currentStep = workflowEntuty.Steps.FirstOrDefault(d =>
-    //                d.Status == EWorkflowStepStatus.WaitForAccept || d.Status == EWorkflowStepStatus.WaitForHandle);
-
-    //            NextStepsWithOpinionDto<NextStepOption> next = null;
-
-    //            try
-    //            {
-    //                next = await _workflowApplication.GetNextStepsAsync(delay.WorkflowId, HttpContext.RequestAborted);
-    //            }
-    //            catch (UserFriendlyException e)
-    //            {
-    //                if (e.Message.Contains("未找到对应节点"))
-    //                {
-    //                    result.Append("无权审核:" + delay.No);
-    //                    fail++;
-    //                }
-    //                else
-    //                {
-    //                    throw;
-    //                }
-    //            }
-
-    //            if (next == null) continue;
-
-    //            if (!delay.Order.IsProvince)
-    //            {
-    //                if (next.Steps.Any(x => x.Value == "省审批"))
-    //                {
-    //                    next.Steps.Remove(next.Steps.First(x => x.Value == "省审批"));
-    //                }
-    //            }
-
-    //            if (!_sessionContext.OrgIsCenter && currentStep.Name != "中心初审")
-    //            {
-    //                if (next.Steps.Any(x => x.Value == "中心终审"))
-    //                {
-    //                    next.Steps.Remove(next.Steps.First(x => x.Value == "中心终审"));
-    //                }
-    //            }
-
-    //            workflow.StepId = next.StepId;
-    //            workflow.ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed;
-
-    //            if (workflow.ReviewResult == EReviewResult.Approval)
-    //            {
-    //                var isBatch = next.Steps.Where(x => x.Value == workflow.NextStepName).Any();
-    //                if (isBatch)
-    //                {
-    //                    var step = next.Steps.Where(x => x.Value == workflow.NextStepName).FirstOrDefault();
-    //                    workflow.NextStepCode = step.Key;
-    //                    workflow.NextStepName = step.Value;
-    //                }
-    //                else
-    //                {
-    //                    result.Append("无权审核:" + delay.No);
-    //                    fail++;
-    //                    continue;
-    //                }
-
-    //                await _workflowDomainService.NextAsync(workflow, cancellationToken: HttpContext.RequestAborted);
-    //            }
-    //            else
-    //            {
-    //                var reject = workflow.Adapt<RejectDto>();
-    //                await _workflowApplication.RejectAsync(reject, HttpContext.RequestAborted);
-    //            }
-
-    //            success++;
-    //        }
-    //        catch (UserFriendlyException e)
-    //        {
-    //            result.Append(e.Message);
-    //            fail++;
-    //        }
-    //    }
-
-    //    return $"总共: {dto.DelayId.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result.ToString()}";
-    //}
-
     [HttpPost("delay/batch_audit")]
     [LogFilter("批量审批延期")]
+    //[LogFilterAlpha("延期审核")]
     public async Task<string> BatchAuditDelay([FromBody] BatchDelayNextFlowDto dto)
     {
         var result = new StringBuilder();
         var fail = 0;
         var success = 0;
-        var workflowDto = dto.NextWorkflow;
-        var delays = await _orderDelayRepository.Queryable()
-            .Includes(x => x.Order)
-            .Includes(x => x.Workflow, d => d.WorkflowDefinition)
-            .Includes(x => x.Workflow, d => d.Steps)
-            .Includes(x => x.Workflow, d => d.Traces)
-            .Includes(x => x.Workflow, d => d.Countersigns)
-            .Where(x => dto.DelayId.Contains(x.Id))
-            .ToListAsync(HttpContext.RequestAborted);
-
-        if (!delays.Any())
-            return string.Empty;
-
-        var currentStep = delays.First().Workflow.Steps.FirstOrDefault(d =>
-            d.Status == EWorkflowStepStatus.WaitForAccept || d.Status == EWorkflowStepStatus.WaitForHandle);
-
-        var updateDelays = new List<OrderDelay>();
-        var updateOrders = new List<Order>();
-        foreach (var delay in delays)
+        var workflow = dto.NextWorkflow;
+        foreach (var item in dto.DelayId)
         {
             try
             {
+                //if (workflow.NextHandlers.Any() && workflow.NextHandlers.Count() == 1)
+                //{
+                //    var handler = workflow.NextHandlers.FirstOrDefault();
+                //    if (string.IsNullOrEmpty(handler.UserId))
+                //    {
+                //        workflow.NextHandlers = new List<StepAssignInfo>();
+                //    }
+                //}
+
+                var delay = await _orderDelayRepository.Queryable().Includes(x => x.Order).Where(x => x.Id == item)
+                    .FirstAsync(HttpContext.RequestAborted);
+                workflow.WorkflowId = delay.WorkflowId;
+                var workflowEntuty = await _workflowDomainService.GetWorkflowAsync(workflow.WorkflowId, withDefine: true, withSteps: true,
+                    cancellationToken: HttpContext.RequestAborted);
+                var currentStep = workflowEntuty.Steps.FirstOrDefault(d =>
+                    d.Status == EWorkflowStepStatus.WaitForAccept || d.Status == EWorkflowStepStatus.WaitForHandle);
+
                 NextStepsWithOpinionDto<NextStepOption> next = null;
 
                 try
                 {
-                    next = await _workflowApplication.GetNextStepsAsync(delay.Workflow, HttpContext.RequestAborted);
+                    next = await _workflowApplication.GetNextStepsAsync(delay.WorkflowId, HttpContext.RequestAborted);
                 }
                 catch (UserFriendlyException e)
                 {
@@ -2530,70 +2425,33 @@ public class OrderController : BaseController
                     }
                 }
 
-                workflowDto.StepId = next.StepId;
-                workflowDto.ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed;
+                workflow.StepId = next.StepId;
+                workflow.ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed;
 
-                if (dto.IsPass)
+                if (workflow.ReviewResult == EReviewResult.Approval)
                 {
-                    var step = next.Steps.FirstOrDefault(x => x.Value == workflowDto.NextStepName);
-                    if (step is null)
+                    var isBatch = next.Steps.Where(x => x.Value == workflow.NextStepName).Any();
+                    if (isBatch)
+                    {
+                        var step = next.Steps.Where(x => x.Value == workflow.NextStepName).FirstOrDefault();
+                        workflow.NextStepCode = step.Key;
+                        workflow.NextStepName = step.Value;
+                    }
+                    else
                     {
                         result.Append("无权审核:" + delay.No);
                         fail++;
                         continue;
                     }
 
-                    workflowDto.NextStepCode = step.Key;
-                    workflowDto.NextStepName = step.Value;
-
-                    //处理工单延期
-                    var order = delay.Order;
-                    var expiredTimeBase = DateTime.Now;
-                    if (_appOptions.Value.IsZiGong)
-                    {
-                        expiredTimeBase = order.ExpiredTime.Value;
-                    }
-
-                    var startTime = DateTime.Now;
-                    if (order.CenterToOrgTime.HasValue)
-                    {
-                        startTime = order.CenterToOrgTime!.Value;
-                    }
-
-                    var expiredTimeConfig =
-                        await _expireTime.CalcEndTime(expiredTimeBase, startTime, new TimeConfig(delay.DelayNum, delay.DelayUnit),
-                            order.AcceptTypeCode);
-                    order.ExpiredTime = expiredTimeConfig.ExpiredTime;
-                    order.NearlyExpiredTime = expiredTimeConfig.NearlyExpiredTime;
-                    order.NearlyExpiredTimeOne = expiredTimeConfig.NearlyExpiredTimeOne;
-                    //TODO发送短信即将超期
-                    if (delay.IsProDelay)
-                    {
-                        order.ExpiredTimeProvince = expiredTimeConfig.ExpiredTime;
-                    }
-
-                    updateOrders.Add(order);
-
-                    await _workflowDomainService.NextAsync(delay.Workflow, workflowDto,
-                        expiredTime: order.ExpiredTime,
-                        cancellationToken: HttpContext.RequestAborted);
-
-                    await _workflowDomainService.UpdateUnhandleExpiredTimeAsync(order.WorkflowId, order.ExpiredTime, HttpContext.RequestAborted);
-
-                    var orderDto = _mapper.Map<OrderDto>(order);
-                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
-                        cancellationToken: HttpContext.RequestAborted);
+                    await _workflowDomainService.NextAsync(workflow, cancellationToken: HttpContext.RequestAborted);
                 }
                 else
                 {
-                    var reject = workflowDto.Adapt<RejectDto>();
+                    var reject = workflow.Adapt<RejectDto>();
                     await _workflowApplication.RejectAsync(reject, HttpContext.RequestAborted);
                 }
 
-
-                delay.DelayState = dto.IsPass ? EDelayState.Pass : EDelayState.NoPass;
-                updateDelays.Add(delay);
-
                 success++;
             }
             catch (UserFriendlyException e)
@@ -2603,23 +2461,165 @@ public class OrderController : BaseController
             }
         }
 
+        return $"总共: {dto.DelayId.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result.ToString()}";
+    }
 
-        await _orderDelayRepository.Updateable(updateDelays)
-            .UpdateColumns(d => d.DelayState)
-            .ExecuteCommandAsync(HttpContext.RequestAborted);
+    //[HttpPost("delay/batch_audit")]
+    //[LogFilter("批量审批延期")]
+    //public async Task<string> BatchAuditDelay([FromBody] BatchDelayNextFlowDto dto)
+    //{
+    //    var result = new StringBuilder();
+    //    var fail = 0;
+    //    var success = 0;
+    //    var workflowDto = dto.NextWorkflow;
+    //    var delays = await _orderDelayRepository.Queryable()
+    //        .Includes(x => x.Order)
+    //        .Includes(x => x.Workflow, d => d.WorkflowDefinition)
+    //        .Includes(x => x.Workflow, d => d.Steps)
+    //        .Includes(x => x.Workflow, d => d.Traces)
+    //        .Includes(x => x.Workflow, d => d.Countersigns)
+    //        .Where(x => dto.DelayId.Contains(x.Id))
+    //        .ToListAsync(HttpContext.RequestAborted);
+
+    //    if (!delays.Any())
+    //        return string.Empty;
+
+    //    var currentStep = delays.First().Workflow.Steps.FirstOrDefault(d =>
+    //        d.Status == EWorkflowStepStatus.WaitForAccept || d.Status == EWorkflowStepStatus.WaitForHandle);
+
+    //    var updateDelays = new List<OrderDelay>();
+    //    var updateOrders = new List<Order>();
+    //    foreach (var delay in delays)
+    //    {
+    //        try
+    //        {
+    //            NextStepsWithOpinionDto<NextStepOption> next = null;
 
-        await _orderRepository.Updateable(updateOrders)
-            .UpdateColumns(d => new
-            {
-                d.ExpiredTime,
-                d.NearlyExpiredTime,
-                d.NearlyExpiredTimeOne,
-                d.ExpiredTimeProvince
-            })
-            .ExecuteCommandAsync(HttpContext.RequestAborted);
+    //            try
+    //            {
+    //                next = await _workflowApplication.GetNextStepsAsync(delay.Workflow, HttpContext.RequestAborted);
+    //            }
+    //            catch (UserFriendlyException e)
+    //            {
+    //                if (e.Message.Contains("未找到对应节点"))
+    //                {
+    //                    result.Append("无权审核:" + delay.No);
+    //                    fail++;
+    //                }
+    //                else
+    //                {
+    //                    throw;
+    //                }
+    //            }
 
-        return $"总共: {dto.DelayId.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result}";
-    }
+    //            if (next == null) continue;
+
+    //            if (!delay.Order.IsProvince)
+    //            {
+    //                if (next.Steps.Any(x => x.Value == "省审批"))
+    //                {
+    //                    next.Steps.Remove(next.Steps.First(x => x.Value == "省审批"));
+    //                }
+    //            }
+
+    //            if (!_sessionContext.OrgIsCenter && currentStep.Name != "中心初审")
+    //            {
+    //                if (next.Steps.Any(x => x.Value == "中心终审"))
+    //                {
+    //                    next.Steps.Remove(next.Steps.First(x => x.Value == "中心终审"));
+    //                }
+    //            }
+
+    //            workflowDto.StepId = next.StepId;
+    //            workflowDto.ReviewResult = dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed;
+
+    //            if (dto.IsPass)
+    //            {
+    //                var step = next.Steps.FirstOrDefault(x => x.Value == workflowDto.NextStepName);
+    //                if (step is null)
+    //                {
+    //                    result.Append("无权审核:" + delay.No);
+    //                    fail++;
+    //                    continue;
+    //                }
+
+    //                workflowDto.NextStepCode = step.Key;
+    //                workflowDto.NextStepName = step.Value;
+
+    //                //处理工单延期
+    //                var order = delay.Order;
+    //                var expiredTimeBase = DateTime.Now;
+    //                if (_appOptions.Value.IsZiGong)
+    //                {
+    //                    expiredTimeBase = order.ExpiredTime.Value;
+    //                }
+
+    //                var startTime = DateTime.Now;
+    //                if (order.CenterToOrgTime.HasValue)
+    //                {
+    //                    startTime = order.CenterToOrgTime!.Value;
+    //                }
+
+    //                var expiredTimeConfig =
+    //                    await _expireTime.CalcEndTime(expiredTimeBase, startTime, new TimeConfig(delay.DelayNum, delay.DelayUnit),
+    //                        order.AcceptTypeCode);
+    //                order.ExpiredTime = expiredTimeConfig.ExpiredTime;
+    //                order.NearlyExpiredTime = expiredTimeConfig.NearlyExpiredTime;
+    //                order.NearlyExpiredTimeOne = expiredTimeConfig.NearlyExpiredTimeOne;
+    //                //TODO发送短信即将超期
+    //                if (delay.IsProDelay)
+    //                {
+    //                    order.ExpiredTimeProvince = expiredTimeConfig.ExpiredTime;
+    //                }
+
+    //                updateOrders.Add(order);
+
+    //                await _workflowDomainService.NextAsync(delay.Workflow, workflowDto,
+    //                    expiredTime: order.ExpiredTime,
+    //                    cancellationToken: HttpContext.RequestAborted);
+
+    //                await _workflowDomainService.UpdateUnhandleExpiredTimeAsync(order.WorkflowId, order.ExpiredTime, HttpContext.RequestAborted);
+
+    //                var orderDto = _mapper.Map<OrderDto>(order);
+    //                await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
+    //                    cancellationToken: HttpContext.RequestAborted);
+    //            }
+    //            else
+    //            {
+    //                var reject = workflowDto.Adapt<RejectDto>();
+    //                await _workflowApplication.RejectAsync(reject, HttpContext.RequestAborted);
+    //            }
+
+
+    //            delay.DelayState = dto.IsPass ? EDelayState.Pass : EDelayState.NoPass;
+    //            updateDelays.Add(delay);
+
+    //            success++;
+    //        }
+    //        catch (UserFriendlyException e)
+    //        {
+    //            result.Append(e.Message);
+    //            fail++;
+    //        }
+    //    }
+
+
+    //    await _orderDelayRepository.Updateable(updateDelays)
+    //        .UpdateColumns(d => d.DelayState)
+    //        .ExecuteCommandAsync(HttpContext.RequestAborted);
+
+    //    await _orderRepository.Updateable(updateOrders)
+    //        .UpdateColumns(d => new
+    //        {
+    //            d.ExpiredTime,
+    //            d.NearlyExpiredTime,
+    //            d.NearlyExpiredTimeOne,
+    //            d.ExpiredTimeProvince
+    //        })
+    //        .ExecuteCommandAsync(HttpContext.RequestAborted);
+
+    //    return $"总共: {dto.DelayId.Length}, 成功: {success}, 失败: {fail}, 失败原因: {result}";
+    //}
 
 
 
@@ -3507,11 +3507,34 @@ public class OrderController : BaseController
     {
         var (total, items) = await _orderSuperviseRepository.Queryable()
             .Includes(x => x.Order)
-            .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
-                d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
-            .WhereIF(dto.SuperviseState > -1, x => x.State == dto.SuperviseState)
-            .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
-            .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
+            .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Order.Title.Contains(dto.Keyword!) || x.Order.No.Contains(dto.Keyword!))
+            .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No))                                //工单编号
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, x => x.Order.IsProvince == true)   //是否省工单
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.Order.IsProvince == false)
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title))                       //工单标题
+            .WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.Order.SourceChannelCode == dto.Channel)              //来源渠道
+            .WhereIF(dto.Status.HasValue, x => x.Order.Status == dto.Status)                                         //工单状态
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), x => x.Order.AcceptTypeCode == dto.AcceptTypeCode)   //受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), x => x.Order.HotspotSpliceName != null && x.Order.HotspotSpliceName.Contains(dto.Hotspot)) //热点
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptorName), x => x.Order.AcceptorName == dto.AcceptorName!)        //受理人
+            .WhereIF(!string.IsNullOrEmpty(dto.CurrentHandleOrgName), x => x.Order.CurrentHandleOrgName.Contains(dto.CurrentHandleOrgName)) //接办部门
+            .WhereIF(dto.ExpiredTimeStart.HasValue, x => x.Order.ExpiredTime >= dto.ExpiredTimeStart)                //期满时间Start
+            .WhereIF(dto.ExpiredTimeEnd.HasValue, x => x.Order.ExpiredTime <= dto.ExpiredTimeEnd)                    //期满时间End
+            .WhereIF(dto.SuperviseTimeStart.HasValue, x => x.CreationTime >= dto.SuperviseTimeStart)                 //督办时间Start
+            .WhereIF(dto.SuperviseTimeEnd.HasValue, x => x.CreationTime <= dto.SuperviseTimeEnd)                     //督办时间End
+            .WhereIF(dto.ReplyLimitTimeStart.HasValue, x => x.ReplyLimitTime >= dto.ReplyLimitTimeStart)             //督办回复时限Start
+            .WhereIF(dto.ReplyLimitTimeEnd.HasValue, x => x.ReplyLimitTime <= dto.ReplyLimitTimeEnd)                 //督办回复时限End
+            .WhereIF(!string.IsNullOrEmpty(dto.CrUser), x => x.CrUser.Contains(dto.CrUser))                          //督办人
+            .WhereIF(!string.IsNullOrEmpty(dto.LaunchOrgName), x => x.LaunchOrgName.Contains(dto.LaunchOrgName))     //督办部门
+            .WhereIF(!string.IsNullOrEmpty(dto.ApplyContent), x => x.ApplyContent.Contains(dto.ApplyContent))        //督办意见
+            .WhereIF(dto.SuperviseState > -1, x => x.State == dto.SuperviseState)                                    //督办状态
+            .WhereIF(dto.CreationTimeStart.HasValue, x => x.Order.CreationTime >= dto.CreationTimeStart)             //受理时间Start
+            .WhereIF(dto.CreationTimeEnd.HasValue, x => x.Order.CreationTime <= dto.CreationTimeEnd)                 //受理时间End
+            .WhereIF(dto.ReplyTimeStart.HasValue, x => x.ReplyTime >= dto.ReplyTimeStart)                            //督办回复时间Start
+            .WhereIF(dto.ReplyTimeEnd.HasValue, x => x.ReplyTime <= dto.ReplyTimeEnd)                                //督办回复时间End
+            .WhereIF(!string.IsNullOrEmpty(dto.ReplyContent), x => x.ReplyContent.Contains(dto.ReplyContent))        //督办回复内容
+            .WhereIF(dto.SignTimeStart.HasValue, x => x.SignTime >= dto.SignTimeStart)                               //督办签收时间Start
+            .WhereIF(dto.SignTimeEnd.HasValue, x => x.SignTime <= dto.SignTimeEnd)                                   //督办签收时间End
             .Where(x => x.OrgId == _sessionContext.OrgId)
             .OrderByDescending(x => x.CreationTime)
             .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
@@ -3879,22 +3902,38 @@ public class OrderController : BaseController
         //如果角色不为空,则说明催办的是角色,则根据部门和角色一起查
         var (total, items) = await _orderUrgeRepository.Queryable()
             .Includes(x => x.Order)
-            .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
-                d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
-            .WhereIF(dto.UrgeState > -1, d => d.State == dto.UrgeState)
-            .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
-            .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
-            .WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName), d => d.Order.OrgLevelOneName.Contains(dto.OrgLevelOneName)) //一级部门
-            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName),
-                d => d.Order.ActualHandleOrgName.Contains(dto.ActualHandleOrgName)) //接办部门(综合查询模糊)
-            .WhereIF(!string.IsNullOrEmpty(dto.CurrentStepCode), d => d.Order.CurrentStepCode == dto.CurrentStepCode) //当前办理节点
+            .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Order.Title.Contains(dto.Keyword!) || x.Order.No.Contains(dto.Keyword!))
+            .WhereIF(dto.UrgeState > -1, x => x.State == dto.UrgeState)
             .WhereIF(_sessionContext.OrgIsCenter == false, d =>
                 (SqlFunc.IsNullOrEmpty(d.RoleId) == true && d.OrgId.StartsWith(_sessionContext.RequiredOrgId)) ||
                 (SqlFunc.IsNullOrEmpty(d.RoleId) == false && d.OrgId.StartsWith(_sessionContext.RequiredOrgId) &&
                  _sessionContext.Roles.Contains(d.RoleId))
             )
+            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), x => x.Order.ActualHandleOrgName.Contains(dto.ActualHandleOrgName)) //接办部门(综合查询模糊)
+            .WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName), x => x.Order.OrgLevelOneName.Contains(dto.OrgLevelOneName)) //一级部门
+            .WhereIF(!string.IsNullOrEmpty(dto.CurrentStepCode), x => x.Order.CurrentStepCode == dto.CurrentStepCode) //当前办理节点
+            .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No))                                //工单编号
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, x => x.Order.IsProvince == true)   //是否省工单
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.Order.IsProvince == false)
+            .WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.Order.SourceChannelCode == dto.Channel)              //来源渠道
+            .WhereIF(dto.ExpiredTimeStart.HasValue, x => x.Order.ExpiredTime >= dto.ExpiredTimeStart)                //期满时间Start
+            .WhereIF(dto.ExpiredTimeEnd.HasValue, x => x.Order.ExpiredTime <= dto.ExpiredTimeEnd)                    //期满时间End
+            .WhereIF(dto.CreationTimeStart.HasValue, x => x.Order.CreationTime >= dto.CreationTimeStart)             //受理时间Start
+            .WhereIF(dto.CreationTimeEnd.HasValue, x => x.Order.CreationTime <= dto.CreationTimeEnd)                 //受理时间End
+            .WhereIF(dto.Status.HasValue, x => x.Order.Status == dto.Status)                                         //工单状态
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title))                       //工单标题
+            .WhereIF(!string.IsNullOrEmpty(dto.CurrentHandleOrgName), x => x.Order.CurrentHandleOrgName.Contains(dto.CurrentHandleOrgName)) //接办部门
+            .WhereIF(dto.CurrentHandleTimeStart.HasValue, x => x.Order.CurrentHandleTime >= dto.CurrentHandleTimeStart)//接办时间Start
+            .WhereIF(dto.CurrentHandleTimeEnd.HasValue, x => x.Order.CurrentHandleTime <= dto.CurrentHandleTimeEnd)    //接办时间End
+            .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), x => x.Order.HotspotSpliceName != null && x.Order.HotspotSpliceName.Contains(dto.Hotspot)) //热点
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), x => x.Order.AcceptTypeCode == dto.AcceptTypeCode)   //受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.CrUser), x => x.CrUser.Contains(dto.CrUser))                          //催办人
+            .WhereIF(!string.IsNullOrEmpty(dto.CreatorOrgName), x => x.CreatorOrgName.Contains(dto.CreatorOrgName))  //催办部门
+            .WhereIF(dto.CrTimeStart.HasValue, x => x.CreationTime >= dto.CrTimeStart)                               //催办时间Start
+            .WhereIF(dto.CrTimeEnd.HasValue, x => x.CreationTime <= dto.CrTimeEnd)                                   //催办时间End
+            .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.OrgName.Contains(dto.OrgName))                       //催办部门
+            .WhereIF(!string.IsNullOrEmpty(dto.ApplyContent), x => x.ApplyContent.Contains(dto.ApplyContent))        //催办内容
 
-            //   .WhereIF(_sessionContext.RequiredOrgId!="001", x => x.OrgId == _sessionContext.OrgId)
             .OrderByDescending(x => x.CreationTime)
             .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
 
@@ -3911,12 +3950,31 @@ public class OrderController : BaseController
     {
         var (total, items) = await _orderUrgeRepository.Queryable()
             .Includes(x => x.Order)
-            .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
-                d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
+            .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Order.Title.Contains(dto.Keyword!) || x.Order.No.Contains(dto.Keyword!))
             .WhereIF(dto.UrgeState > -1, x => x.State == dto.UrgeState)
-            .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
-            .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
             .WhereIF(_sessionContext.OrgIsCenter == false, x => x.OrgId.StartsWith(_sessionContext.OrgId))
+            .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No))                                //工单编号
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, x => x.Order.IsProvince == true)   //是否省工单
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.Order.IsProvince == false)
+            .WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.Order.SourceChannelCode == dto.Channel)              //来源渠道
+            .WhereIF(dto.ExpiredTimeStart.HasValue, x => x.Order.ExpiredTime >= dto.ExpiredTimeStart)                //期满时间Start
+            .WhereIF(dto.ExpiredTimeEnd.HasValue, x => x.Order.ExpiredTime <= dto.ExpiredTimeEnd)                    //期满时间End
+            .WhereIF(dto.CreationTimeStart.HasValue, x => x.Order.CreationTime >= dto.CreationTimeStart)             //受理时间Start
+            .WhereIF(dto.CreationTimeEnd.HasValue, x => x.Order.CreationTime <= dto.CreationTimeEnd)                 //受理时间End
+            .WhereIF(dto.Status.HasValue, x => x.Order.Status == dto.Status)                                         //工单状态
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title))                       //工单标题
+            .WhereIF(!string.IsNullOrEmpty(dto.CurrentHandleOrgName), x => x.Order.CurrentHandleOrgName.Contains(dto.CurrentHandleOrgName)) //接办部门
+            .WhereIF(dto.CurrentHandleTimeStart.HasValue, x => x.Order.CurrentHandleTime >= dto.CurrentHandleTimeStart)//接办时间Start
+            .WhereIF(dto.CurrentHandleTimeEnd.HasValue, x => x.Order.CurrentHandleTime <= dto.CurrentHandleTimeEnd)    //接办时间End
+            .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), x => x.Order.HotspotSpliceName != null && x.Order.HotspotSpliceName.Contains(dto.Hotspot)) //热点
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), x => x.Order.AcceptTypeCode == dto.AcceptTypeCode)   //受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.CrUser), x => x.CrUser.Contains(dto.CrUser))                          //催办人
+            .WhereIF(!string.IsNullOrEmpty(dto.CreatorOrgName), x => x.CreatorOrgName.Contains(dto.CreatorOrgName))  //催办部门
+            .WhereIF(dto.CrTimeStart.HasValue, x => x.CreationTime >= dto.CrTimeStart)                               //催办时间Start
+            .WhereIF(dto.CrTimeEnd.HasValue, x => x.CreationTime <= dto.CrTimeEnd)                                   //催办时间End
+            .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.OrgName.Contains(dto.OrgName))                       //催办部门
+            .WhereIF(!string.IsNullOrEmpty(dto.CurrentStepCode), x => x.Order.CurrentStepCode == dto.CurrentStepCode) //当前办理节点
+            .WhereIF(dto.CrState.HasValue, x => x.State == dto.CrState)
             .OrderByDescending(x => x.CreationTime)
             .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
 
@@ -4249,6 +4307,44 @@ public class OrderController : BaseController
         return orderUrgeDto;
     }
 
+    /// <summary>
+    /// 列表页面基础数据
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet("basedata")]
+    public async Task<object> BaseDataRange()
+    {
+        // 催办查询 催办状态
+        List<Kv> kvCrState = new()
+        {
+            new Kv { Key = "0", Value = "待办未读" },
+            new Kv { Key = "1", Value = "已回复" },
+            new Kv { Key = "3", Value = "签收已读" }
+        };
+
+        //延期申请单位
+        List<Kv> ETimeType = new()
+        {
+            new Kv { Key = "1", Value = "小时" },
+            new Kv { Key = "2", Value = "工作日" },
+            new Kv { Key = "3", Value = "自然日" }
+        };
+
+        var wfModule = await _workflowApplication.GetWorkflowModuleAsync(WorkflowModuleConsts.OrderHandle, HttpContext.RequestAborted);
+        var definition = wfModule.Definition;
+        var rsp = new
+        {
+            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)),
+            CrState = kvCrState,
+            DelayUnitOptions = ETimeType
+        };
+        return rsp;
+    }
+
+
     #endregion
 
     #region 工单办理
@@ -5620,9 +5716,9 @@ public class OrderController : BaseController
                         var prevSendOrder = sendOrderTrace is not null;
                         if (_appOptions.Value.IsZiGong && prevSendOrder)
                         {
-							prevSendOrder = await _orderDomainService.SchedulingAtWork(sendOrderTrace.HandlerId);
-						}
-						if (prevSendOrder)
+                            prevSendOrder = await _orderDomainService.SchedulingAtWork(sendOrderTrace.HandlerId);
+                        }
+                        if (prevSendOrder)
                         {
                             //todo
                             nextDto.NextHandlers = new List<StepAssignInfo>
@@ -6120,22 +6216,22 @@ public class OrderController : BaseController
     }
 
 
-	/// <summary>
-	/// 提前触发平均派单 
-	/// </summary>
-	/// <returns></returns>
-	[HttpPost("advanced_trigger_average_order")]
-	[AllowAnonymous]
-	public async Task AdvancedTriggerAverageOrder()
-	{
-		await _orderDomainService.AdvancedTriggerAverageOrder(HttpContext.RequestAborted);
-	}
+    /// <summary>
+    /// 提前触发平均派单 
+    /// </summary>
+    /// <returns></returns>
+    [HttpPost("advanced_trigger_average_order")]
+    [AllowAnonymous]
+    public async Task AdvancedTriggerAverageOrder()
+    {
+        await _orderDomainService.AdvancedTriggerAverageOrder(HttpContext.RequestAborted);
+    }
 
-	/// <summary>
-	/// 批量归档(暂时只支持派单组节点操作)
-	/// </summary>
-	/// <returns>成功总量</returns>
-	[HttpPost("batch-file")]
+    /// <summary>
+    /// 批量归档(暂时只支持派单组节点操作)
+    /// </summary>
+    /// <returns>成功总量</returns>
+    [HttpPost("batch-file")]
     public async Task<string> BatchFile([FromBody] OrderBatchFileDto dto)
     {
         var orders = await _orderRepository.Queryable()
@@ -6793,20 +6889,20 @@ public class OrderController : BaseController
             var order = await _orderRepository.Queryable().Includes(d => d.Workflow).FirstAsync(d => d.Id == sendBack.OrderId);
             //if (_appOptions.Value.IsZiGong)
             //{
-                //var (currentStep, prevStep, steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
-                //    order.WorkflowId, sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(), sendBack.AssignStepId,
-                //    HttpContext.RequestAborted);
+            //var (currentStep, prevStep, steps, isOrgToCenter, isSecondToFirstOrgLevel) = await _workflowApplication.GetPreviousInformationAsync(
+            //    order.WorkflowId, sendBack.WorkflowUserId, sendBack.WorkflowOrgId, sendBack.WorkflowRoleIds.ToArray(), sendBack.AssignStepId,
+            //    HttpContext.RequestAborted);
 
-                //if (prevStep.BusinessType == EBusinessType.Send)
-                //{
-                //    // 平均派单
-                //    var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
-                //    if (averageSendOrder)
-                //    {
-                //        var handler = await _orderDomainService.AverageOrder(HttpContext.RequestAborted);
-                //        sendBack.SendBackData.Handler = handler;
-                //    }
-                //}
+            //if (prevStep.BusinessType == EBusinessType.Send)
+            //{
+            //    // 平均派单
+            //    var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
+            //    if (averageSendOrder)
+            //    {
+            //        var handler = await _orderDomainService.AverageOrder(HttpContext.RequestAborted);
+            //        sendBack.SendBackData.Handler = handler;
+            //    }
+            //}
             //}
 
             sendBack.SendBackData.ExpiredTime = order.ExpiredTime;
@@ -7249,7 +7345,7 @@ public class OrderController : BaseController
                 BusinessType = dto.BusinessType
             };
 
-            if (dto.FlowDirection is not EFlowDirection.OrgToOrg)
+            if (dto.FlowDirection is not EFlowDirection.OrgToOrg and not EFlowDirection.Other)
             {
                 //重新计算期满时间
                 ExpiredTimeWithConfig expiredTime;
@@ -8985,11 +9081,28 @@ public class OrderController : BaseController
     {
         var (total, items) = await _orderFinalityRepository.Queryable()
             .Includes(x => x.Order)
-            .WhereIF(dto.IsProvince.HasValue, x => x.Order.IsProvince == dto.IsProvince)
-            .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
-                x => x.Order.No.Contains(dto.Keyword!) || x.Order.Title.Contains(dto.Keyword!))
-            //.WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title!))
-            //.WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No!))
+            .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Order.No.Contains(dto.Keyword!) || x.Order.Title.Contains(dto.Keyword!))
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, x => x.Order.IsProvince == true)   //是否省工单
+            .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.Order.IsProvince == false)
+            .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No))                                //工单编号
+            .WhereIF(dto.Status.HasValue, x => x.Order.Status == dto.Status)                                         //工单状态
+            .WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.Order.SourceChannelCode == dto.Channel)              //来源渠道
+            .WhereIF(!string.IsNullOrEmpty(dto.CurrentStepCode), x => x.Order.CurrentStepCode.Contains(dto.CurrentStepCode)) //当前节点
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title))                       //工单标题
+            .WhereIF(dto.CreationTimeStart.HasValue, x => x.Order.CreationTime >= dto.CreationTimeStart)             //受理时间Start
+            .WhereIF(dto.CreationTimeEnd.HasValue, x => x.Order.CreationTime <= dto.CreationTimeEnd)                 //受理时间End
+            .WhereIF(!string.IsNullOrEmpty(dto.CreatorName), x => x.CreatorName.Contains(dto.CreatorName))           //设置人
+            .WhereIF(dto.SetCreationTimeStart.HasValue, x => x.CreationTime >= dto.SetCreationTimeStart)             //设置时间Start
+            .WhereIF(dto.SetCreationTimeEnd.HasValue, x => x.CreationTime <= dto.SetCreationTimeEnd)                 //设置时间End
+            .WhereIF(dto.ExpiredTimeStart.HasValue, x => x.Order.ExpiredTime >= dto.ExpiredTimeStart)                //期满时间Start
+            .WhereIF(dto.ExpiredTimeEnd.HasValue, x => x.Order.ExpiredTime <= dto.ExpiredTimeEnd)                    //期满时间End
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), x => x.Order.AcceptTypeCode == dto.AcceptTypeCode)   //受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), x => x.Order.HotspotSpliceName != null && x.Order.HotspotSpliceName.Contains(dto.Hotspot)) //热点
+            .WhereIF(!string.IsNullOrEmpty(dto.CurrentHandleOrgName), x => x.Order.CurrentHandleOrgName.Contains(dto.CurrentHandleOrgName)) //接办部门
+            .WhereIF(dto.CurrentHandleTimeStart.HasValue, x => x.Order.CurrentHandleTime >= dto.CurrentHandleTimeStart)//接办时间Start
+            .WhereIF(dto.CurrentHandleTimeEnd.HasValue, x => x.Order.CurrentHandleTime <= dto.CurrentHandleTimeEnd)    //接办时间End
+            .WhereIF(dto.FiledTimeStart.HasValue, x => x.Order.FiledTime >= dto.FiledTimeStart)                        //办结时间Start
+            .WhereIF(dto.FiledTimeEnd.HasValue, x => x.Order.FiledTime <= dto.FiledTimeEnd)                            //办结时间End
             .OrderByDescending(x => x.CreationTime)
             .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
         return new PagedDto<OrderFinalityDto>(total, _mapper.Map<IReadOnlyList<OrderFinalityDto>>(items));

+ 2 - 0
src/Hotline.Api/Controllers/PushMessageController.cs

@@ -220,6 +220,8 @@ namespace Hotline.Api.Controllers
                 .WhereIF(!string.IsNullOrEmpty(pagedDto.SendName), d => d.CreatorName.Contains(pagedDto.SendName))
                 .WhereIF(!string.IsNullOrEmpty(pagedDto.SendOrg), d => d.CreatorOrgName.Contains(pagedDto.SendOrg))
                 .WhereIF(!string.IsNullOrEmpty(pagedDto.SendContent), d => d.Content.Contains(pagedDto.SendContent))
+                .WhereIF(pagedDto.IsSmsReply.HasValue && pagedDto.IsSmsReply == false, d => d.IsSmsReply == false)
+                .WhereIF(pagedDto.IsSmsReply.HasValue && pagedDto.IsSmsReply == true, d => d.IsSmsReply == true)
                 .OrderByDescending(it => it.CreationTime)
                 .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
 

+ 78 - 41
src/Hotline.Api/Controllers/QualityController.cs

@@ -24,6 +24,10 @@ using Hotline.Configurations;
 using Hotline.CallCenter.Calls;
 using System.Linq;
 using Hotline.Repository.SqlSugar.Quality;
+using Hotline.Caching.Services;
+using Hotline.FlowEngine.WorkflowModules;
+using Hotline.Settings.TimeLimits;
+using Hotline.Share.Enums.Order;
 
 namespace Hotline.Api.Controllers
 {
@@ -51,6 +55,7 @@ namespace Hotline.Api.Controllers
         private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
         private readonly IRepository<SystemLog> _logRepository;
         private readonly IRepository<QualityTransferRecords> _qualityTransferRecordsRepository;
+        private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
 
         public QualityController(
             ISessionContext sessionContext,
@@ -72,7 +77,8 @@ namespace Hotline.Api.Controllers
             ICallApplication callApplication,
             IOptionsSnapshot<AppConfiguration> appOptions,
             IRepository<SystemLog> logRepository,
-            IRepository<QualityTransferRecords> qualityTransferRecordsRepository)
+            IRepository<QualityTransferRecords> qualityTransferRecordsRepository,
+            ISystemDicDataCacheManager sysDicDataCacheManager)
         {
             _sessionContext = sessionContext;
             _mapper = mapper;
@@ -94,6 +100,7 @@ namespace Hotline.Api.Controllers
             _appOptions = appOptions;
             _logRepository = logRepository;
             _qualityTransferRecordsRepository = qualityTransferRecordsRepository;
+            _sysDicDataCacheManager = sysDicDataCacheManager;
         }
         #region 质检管理
         /// <summary>
@@ -123,25 +130,25 @@ namespace Hotline.Api.Controllers
             await _qualityApplication.UpdateQualityAsync(dto, HttpContext.RequestAborted);
         }
 
-		/// <summary>
-		/// 更新质检
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpPut("transfer")]
-		public async Task TransferUpdate([FromBody] TransferUpdate dto)
-		{
-			await _qualitey.Updateable().SetColumns(x=> new Hotline.Quality.Quality { Transfer  = dto.Transfer }).Where(x=>x.Id == dto.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
-		}
+        /// <summary>
+        /// 更新质检
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPut("transfer")]
+        public async Task TransferUpdate([FromBody] TransferUpdate dto)
+        {
+            await _qualitey.Updateable().SetColumns(x => new Hotline.Quality.Quality { Transfer = dto.Transfer }).Where(x => x.Id == dto.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
+        }
 
 
 
-		/// <summary>
-		/// 获取质检列表
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpGet("list")]
+        /// <summary>
+        /// 获取质检列表
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("list")]
         public async Task<PagedDto<QualityDto>> List([FromQuery] QualityListDto dto)
         {
             var (total, items) = await _qualitey.Queryable()
@@ -159,6 +166,18 @@ namespace Hotline.Api.Controllers
                 .WhereIF(dto.CreationTimeEnd.HasValue, x => x.CreationTime <= dto.CreationTimeEnd)
                 .WhereIF(dto.MaxGrade.HasValue, x => x.Grade <= dto.MaxGrade)
                 .WhereIF(dto.MinGrade.HasValue, x => x.Grade >= dto.MinGrade)
+                .WhereIF(dto.AiQuality.HasValue, x => x.AiQuality == dto.AiQuality)                           //质检方式
+                .WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.Order.SourceChannelCode == dto.Channel)    //来源渠道
+                .WhereIF(dto.AcceptanceTimeStart.HasValue, x => x.Order.CreationTime >= dto.AcceptanceTimeStart) //受理时间Star
+                .WhereIF(dto.AcceptanceTimeEnd.HasValue, x => x.Order.CreationTime <= dto.AcceptanceTimeEnd)   //受理时间End
+                .WhereIF(dto.Status.HasValue, x => x.Order.Status == dto.Status)                               //工单状态
+                .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), x => x.Order.AcceptTypeCode == dto.AcceptTypeCode) //受理类型
+                .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), x => x.Order.HotspotSpliceName != null && x.Order.HotspotSpliceName.Contains(dto.Hotspot)) //热点
+                .WhereIF(!string.IsNullOrEmpty(dto.NameOrNo), x => x.Order.AcceptorName == dto.NameOrNo! || x.Order.AcceptorStaffNo == dto.NameOrNo!)   //受理人/坐席
+                .WhereIF(!string.IsNullOrEmpty(dto.FromPhone), x => x.Order.FromPhone.Contains(dto.FromPhone)) //来电号码
+                .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))          //质检人
+                .WhereIF(dto.QualityTimeStart.HasValue, x => x.QualityTime >= dto.QualityTimeStart)              //质检时间Star
+                .WhereIF(dto.QualityTimeEnd.HasValue, x => x.QualityTime <= dto.QualityTimeEnd)                //质检时间End
                 .OrderByDescending(x => x.CreationTime)
                 .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
             return new PagedDto<QualityDto>(total, _mapper.Map<IReadOnlyList<QualityDto>>(items));
@@ -333,7 +352,17 @@ namespace Hotline.Api.Controllers
                 .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name!))
                 .WhereIF(!string.IsNullOrEmpty(dto.GroupingName), d => d.GroupingName.Contains(dto.GroupingName!))
                 .WhereIF(dto.IsEnable.HasValue, d => d.IsEnable == dto.IsEnable)
-                .OrderByDescending(x => x.CreationTime)
+
+                .WhereIF(!string.IsNullOrEmpty(dto.Describe), d => d.Describe.Contains(dto.Describe!))
+                .WhereIF(dto.MaxGrade.HasValue, d => d.Grade <= dto.MaxGrade)
+                .WhereIF(dto.MinGrade.HasValue, d => d.Grade >= dto.MinGrade)
+                .WhereIF(!string.IsNullOrEmpty(dto.CreatorName), d => d.CreatorName.Contains(dto.CreatorName!))
+                .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
+                .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
+                .WhereIF(!string.IsNullOrEmpty(dto.LastModificationName), d => d.LastModificationName.Contains(dto.LastModificationName!))
+                .WhereIF(dto.LastModificationTimeStart.HasValue, d => d.LastModificationTime >= dto.LastModificationTimeStart)
+                .WhereIF(dto.LastModificationTimeEnd.HasValue, d => d.LastModificationTime <= dto.LastModificationTimeEnd)
+                .OrderByDescending(d => d.CreationTime)
                 .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
             return new PagedDto<QualityItemDto>(total, _mapper.Map<IReadOnlyList<QualityItemDto>>(items));
         }
@@ -449,9 +478,15 @@ namespace Hotline.Api.Controllers
             var (total, items) = await _qualityTemplate.Queryable()
                 .Includes(x => x.templateDetails)
                 .Includes(x => x.templateDetails, y => y.QualityItem)
-                .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name!))
-                .WhereIF(dto.Grouping.HasValue, d => d.Grouping == dto.Grouping)
-                .WhereIF(dto.IsEnable.HasValue, d => d.IsEnable == dto.IsEnable)
+                .WhereIF(!string.IsNullOrEmpty(dto.Name), x => x.Name.Contains(dto.Name!))
+                .WhereIF(dto.Grouping.HasValue, x => x.Grouping == dto.Grouping)
+                .WhereIF(dto.IsEnable.HasValue, x => x.IsEnable == dto.IsEnable)
+                .WhereIF(!string.IsNullOrEmpty(dto.CreatorName), x => x.CreatorName.Contains(dto.CreatorName!))
+                .WhereIF(dto.CreationTimeStart.HasValue, x => x.CreationTime >= dto.CreationTimeStart)
+                .WhereIF(dto.CreationTimeEnd.HasValue, x => x.CreationTime <= dto.CreationTimeEnd)
+                .WhereIF(!string.IsNullOrEmpty(dto.LastModificationName), x => x.LastModificationName.Contains(dto.LastModificationName!))
+                .WhereIF(dto.LastModificationTimeStart.HasValue, x => x.LastModificationTime >= dto.LastModificationTimeStart)
+                .WhereIF(dto.LastModificationTimeEnd.HasValue, x => x.LastModificationTime <= dto.LastModificationTimeEnd)
                 .OrderByDescending(x => x.CreationTime)
                 .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
             return new PagedDto<QualityTemplateDto>(total, _mapper.Map<IReadOnlyList<QualityTemplateDto>>(items));
@@ -657,16 +692,16 @@ namespace Hotline.Api.Controllers
             await _qualityTransferRecordsRepository.AddRangeAsync(transfers);
         }
 
-		/// <summary>
-		/// 智能质检转写_兴唐_定时调用
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[AllowAnonymous]
-		[HttpPost("transfer")]
-		[LogFilter("智能质检转写_兴唐_定时调用")]
-		public async Task AiTransfer_XT()
-		{
+        /// <summary>
+        /// 智能质检转写_兴唐_定时调用
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [AllowAnonymous]
+        [HttpPost("transfer")]
+        [LogFilter("智能质检转写_兴唐_定时调用")]
+        public async Task AiTransfer_XT()
+        {
             var translatings = await _qualityTransferRecordsRepository.Queryable().Where(x => x.IsFinished == false && x.TransferState == EQualityTransferState.Translating).OrderBy(x => x.TransferTime).ToListAsync();
             if (translatings.Any())
             {
@@ -674,19 +709,21 @@ namespace Hotline.Api.Controllers
                 if ((DateTime.Now - transfer.TransferTime.Value).TotalMinutes >= 30)
                 {
                     await _qualityTransferRecordsRepository.Updateable().SetColumns(x => new QualityTransferRecords { TransferState = EQualityTransferState.Lose }).Where(x => x.Id == transfer.Id).ExecuteCommandAsync();
-					await _qualitey.Updateable().SetColumns(x => new Hotline.Quality.Quality { TransferState = EQualityTransferState.Lose }).Where(x => x.Id == transfer.QualityId).ExecuteCommandAsync();
-				}
+                    await _qualitey.Updateable().SetColumns(x => new Hotline.Quality.Quality { TransferState = EQualityTransferState.Lose }).Where(x => x.Id == transfer.QualityId).ExecuteCommandAsync();
+                }
                 return;
             }
-            else {
+            else
+            {
                 var trany = await _qualityTransferRecordsRepository.Queryable().Where(x => x.IsFinished == false && x.TransferState == EQualityTransferState.NotStarted).AnyAsync();
-                if (trany) {
-					var notStarted = await _qualityTransferRecordsRepository.Queryable().Where(x => x.IsFinished == false && x.TransferState == EQualityTransferState.NotStarted).OrderBy(x => x.TransferTime).FirstAsync();
-					await _qualityTransferRecordsRepository.Updateable().SetColumns(x => new QualityTransferRecords { TransferState = EQualityTransferState.Translating, TransferTime = DateTime.Now }).Where(x => x.Id == notStarted.Id).ExecuteCommandAsync();
-					Task.Run(async () => await _qualityApplication.Transfer_XT(notStarted.QualityId, HttpContext.RequestAborted));
-				}
-			}
-		}
+                if (trany)
+                {
+                    var notStarted = await _qualityTransferRecordsRepository.Queryable().Where(x => x.IsFinished == false && x.TransferState == EQualityTransferState.NotStarted).OrderBy(x => x.TransferTime).FirstAsync();
+                    await _qualityTransferRecordsRepository.Updateable().SetColumns(x => new QualityTransferRecords { TransferState = EQualityTransferState.Translating, TransferTime = DateTime.Now }).Where(x => x.Id == notStarted.Id).ExecuteCommandAsync();
+                    Task.Run(async () => await _qualityApplication.Transfer_XT(notStarted.QualityId, HttpContext.RequestAborted));
+                }
+            }
+        }
 
 
         /// <summary>

+ 1 - 1
src/Hotline.Api/Controllers/Snapshot/SnapshotController.cs

@@ -190,7 +190,7 @@ public class SnapshotController : BaseController
     /// <returns></returns>
     [HttpGet("bulletions")]
     [AllowAnonymous]
-    public async Task<IReadOnlyList<BulletinOutDto>> QueryBulletinsAsync([FromQuery] BulletinInDto dto)
+    public async Task<IReadOnlyList<BulletinListOutDto>> QueryBulletinsAsync([FromQuery] BulletinInDto dto)
         => await _snapshotApplication.GetBulletinsAsync(dto, HttpContext.RequestAborted);
 
     /// <summary>

+ 43 - 5
src/Hotline.Api/Controllers/TestController.cs

@@ -1,5 +1,7 @@
 using System.Text;
 using System.Text.Json;
+using System.Threading;
+using DocumentFormat.OpenXml.Office2010.Excel;
 using DotNetCore.CAP;
 using Hotline.Ai.Quality;
 using Hotline.Application.CallCenter;
@@ -22,6 +24,8 @@ using Hotline.FlowEngine.Workflows;
 using Hotline.Import;
 using Hotline.JudicialManagement;
 using Hotline.Orders;
+using Hotline.Push.FWMessage;
+using Hotline.Push.Notifies;
 using Hotline.Realtimes;
 using Hotline.Repository.SqlSugar;
 using Hotline.Repository.SqlSugar.Ts;
@@ -34,6 +38,7 @@ using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Dtos.Home;
 using Hotline.Share.Dtos.Identity;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Dtos.Push;
 using Hotline.Share.Dtos.Realtime;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Dtos.TrCallCenter;
@@ -41,6 +46,7 @@ using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.JudicialManagement;
 using Hotline.Share.Enums.Order;
+using Hotline.Share.Enums.Push;
 using Hotline.Share.Mq;
 using Hotline.ThirdAccountDomainServices.Interfaces;
 using Hotline.Users;
@@ -125,6 +131,7 @@ public class TestController : BaseController
     private readonly IServiceProvider _serviceProvider;
     private readonly IRepository<OrderDelay> _orderDelayRepository;
     private readonly IRepository<OrderSecondaryHandling> _orderSecondaryHandlingRepository;
+    private readonly IRepository<Message> _messageRepository;
 
 
     public TestController(
@@ -182,7 +189,8 @@ public class TestController : BaseController
         IOrderScreenRepository orderScreenRepository,
         IRepository<OrderVisit> orderVisitRepository,
         IServiceProvider serviceProvider,
-        IRepository<OrderSecondaryHandling> orderSecondaryHandlingRepository
+        IRepository<OrderSecondaryHandling> orderSecondaryHandlingRepository,
+        IRepository<Message> messageRepository
         )
     {
         _logger = logger;
@@ -236,6 +244,7 @@ public class TestController : BaseController
         _serviceProvider = serviceProvider;
         _orderDelayRepository = orderDelayRepository;
         _orderSecondaryHandlingRepository = orderSecondaryHandlingRepository;
+        _messageRepository = messageRepository;
     }
 
     /// <summary>
@@ -1538,9 +1547,38 @@ public class TestController : BaseController
         return ipv4;
     }
 
-    //public string DecryptSign(string sign)
-    //{
-    //    return sign;
-    //}
+    [AllowAnonymous]
+    [HttpGet("sms")]
+    public async Task<string> PushSms(DateTime start, DateTime end, bool rightnow = false)
+    {
+        var smses = await _messageRepository.Queryable()
+            .Where(d=>d.SendState < ESendState.Success)
+            .Where(d => d.CreationTime >= start && d.CreationTime <= end)
+            .ToListAsync(HttpContext.RequestAborted);
+
+        var total = smses.Count;
+        if(!rightnow)
+            return $"共计: {total}";
+
+        var successed = 0;
+        Share.Dtos.Push.MessageDto messageDto;
+        foreach (var message in smses)
+        {
+            PushMessageDto pushMessage = new()
+            {
+                ClientId = "Hotline",
+                ExternalId = message.Id,
+                Content = message.Content,
+                Remark = message.Remark,
+                Name = message.Name,
+                TelNumber = message.TelNumber
+            };
+            //消息队列
+            await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.SendSms, pushMessage, cancellationToken:HttpContext.RequestAborted);
+            successed++;
+        }
+
+        return $"共计: {total}, 成功:{successed}";
+    }
 }
 

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

@@ -200,7 +200,7 @@ internal static class StartupExtensions
             .AddValidatorsFromAssembly(typeof(ValidatorExtensions).Assembly);
 
         //mq
-        services.AddMq(configuration);
+        services.AddMq(()=>configuration.GetSection(nameof(MqConfiguration)).Get<MqConfiguration>());
 
         //job
         services.RegisterJob(appConfiguration);

+ 14 - 14
src/Hotline.Api/StartupHelper.cs

@@ -294,22 +294,22 @@ namespace Hotline.Api
                         .StartNow()
                         .WithCronSchedule("0 0/5 * * * ? *"));
 
-                        d.AddJob<SendOrderJob>(autoSendOrderKey);
-                        d.AddTrigger(t => t
-                            .WithIdentity("task-send-order-trigger")
-                            .ForJob(autoSendOrderKey)
-                            .StartNow()
-                            .WithCronSchedule("0 10 9 * * ?")
-                        );
+                        //d.AddJob<SendOrderJob>(autoSendOrderKey);
+                        //d.AddTrigger(t => t
+                        //    .WithIdentity("task-send-order-trigger")
+                        //    .ForJob(autoSendOrderKey)
+                        //    .StartNow()
+                        //    .WithCronSchedule("0 10 9 * * ?")
+                        //);
                         break;
                     case AppDefaults.AppScope.ZiGong:
-	                    d.AddJob<SendOrderJob>(autoSendOrderKey);
-	                    d.AddTrigger(t => t
-		                    .WithIdentity("task-send-order-trigger")
-		                    .ForJob(autoSendOrderKey)
-		                    .StartNow()
-		                    .WithCronSchedule("0 10 9 * * ?")
-	                    );
+	                    //d.AddJob<SendOrderJob>(autoSendOrderKey);
+	                    //d.AddTrigger(t => t
+		                   // .WithIdentity("task-send-order-trigger")
+		                   // .ForJob(autoSendOrderKey)
+		                   // .StartNow()
+		                   // .WithCronSchedule("0 10 9 * * ?")
+	                    //);
 						break;
 					default:
                         break;

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

@@ -120,6 +120,7 @@
   "MqConfiguration": {
     "DbConnectionString": "PORT=5432;DATABASE=fwmq;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;",
     "UseDashBoard": true,
+    "FailedRetryCount": 5,
     "RabbitMq": {
       "UserName": "dev",
       "Password": "123456",

+ 8 - 4
src/Hotline.Application/CallCenter/DefaultCallApplication.cs

@@ -362,15 +362,19 @@ public abstract class DefaultCallApplication : ICallApplication
 
         if (dto.Type == 2)
         {
-            return query.Select((d, o, v) => new CallNativeDto
+            var d = query.Select((d, o, v) => new CallNativeDto
             {
-                OrderId = v.OrderId,
-                OrderNo = v.Order.No,
-                Title = v.Order.Title,
+                OrderId = SqlFunc.IsNull(v.OrderId, v.OrderId),
+                OrderNo = SqlFunc.IsNull(v.Order.No, o.No),
+                Title = SqlFunc.IsNull(v.Order.Title, o.Title),
                 CallState = d.CallState,
                 IsVisit = !SqlFunc.IsNullOrEmpty(v.Id),
                 IsOrder = !SqlFunc.IsNullOrEmpty(o.Id),
             }, true);
+#if DEBUG
+            var sql = d.ToSqlString();
+#endif
+            return d;
         }
         if (dto.Type == 3)
         {

+ 39 - 26
src/Hotline.Application/JudicialManagement/EnforcementApplication.cs

@@ -1,4 +1,6 @@
-using Hotline.JudicialManagement;
+using Hotline.CaseLibrary;
+using Hotline.IndustryClassification;
+using Hotline.JudicialManagement;
 using Hotline.Orders;
 using Hotline.Settings;
 using Hotline.Share.Dtos;
@@ -211,6 +213,7 @@ namespace Hotline.Application.JudicialManagement
                        AcceptorStaffNo = o.AcceptorStaffNo,
                        AcceptorOrgCode = o.AcceptorOrgCode,
                        AcceptorOrgName = o.AcceptorOrgName,
+                       CaseType = o.CaseType 
                    })
                 .MergeTable();
         }
@@ -361,7 +364,8 @@ namespace Hotline.Application.JudicialManagement
                     AcceptorStaffNo = x.AcceptorStaffNo,
                     AcceptorOrgCode = x.AcceptorOrgCode,
                     AcceptorOrgName = x.AcceptorOrgName,
-                    VisitId = p.VisitId
+                    VisitId = p.VisitId,
+                    CaseType = x.CaseType 
                 })
                .MergeTable();
 
@@ -370,18 +374,17 @@ namespace Hotline.Application.JudicialManagement
 
         public async Task<List<IndustryOrderStaticsDto>> QueryIndustryOrderStatics(QueryIndustryOrderStatisticsRequest queryIndustryOrderStatisticsRequest)
         {
-            var judicialManagementOrderTable = _judicialManagementOrdersRepository.Queryable()
-                .Where(x => x.CreationTime >= queryIndustryOrderStatisticsRequest.StartTime && x.CreationTime <= queryIndustryOrderStatisticsRequest.EndTime);
-            var queryable = judicialManagementOrderTable.InnerJoin<OrderSnapshot>((j, o) => j.Id == o.Id)
-                .GroupBy((j, o) => o.IndustryName)
-                .Select((j, o) => new IndustryOrderStaticsDto
-                {
-                    IndustryName = o.IndustryName,
-                    TotalOrderCount = SqlFunc.AggregateCount(o.Id),
-                    EnforcementOrderCount = SqlFunc.AggregateCount(SqlFunc.IIF(j.IsEnforcementOrder.HasValue && j.IsEnforcementOrder == true, 1, 0)),
-                    NotEnforcementOrderCount = SqlFunc.AggregateCount(SqlFunc.IIF(j.IsEnforcementOrder.HasValue && j.IsEnforcementOrder != true, 1, 0)),
-                    ToBeVerifiedOrderCount = SqlFunc.AggregateCount(SqlFunc.IIF(j.IsEnforcementOrder == null, 1, 0))
-                });
+            var queryIndustryOrderStatisticsRateRequest = _mapper.Map<QueryIndustryOrderStatisticsRateRequest>(queryIndustryOrderStatisticsRequest);
+            ISugarQueryable<JudicialManagementOrders, Order, IndustryAssociations, IndustrialManagement> groupByQueryable = IndustryGroupBy(queryIndustryOrderStatisticsRateRequest);
+
+            var queryable = groupByQueryable.Select((x, o, a, i) => new IndustryOrderStaticsDto
+            {
+                IndustryName = i.IndustrialName,
+                TotalOrderCount = SqlFunc.AggregateCount(x.Id),
+                EnforcementOrderCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsEnforcementOrder.HasValue && x.IsEnforcementOrder == true, 1, 0)),
+                NotEnforcementOrderCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsEnforcementOrder.HasValue && x.IsEnforcementOrder != true, 1, 0)),
+                ToBeVerifiedOrderCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsEnforcementOrder == null, 1, 0))
+            });
 
 
             var result = await queryable.ToListAsync();
@@ -391,25 +394,35 @@ namespace Hotline.Application.JudicialManagement
 
         public async Task<List<IndustryOrderStaticsRateDto>> QueryIndustryOrderStaticsRate(QueryIndustryOrderStatisticsRateRequest queryIndustryOrderStatisticsRateRequest)
         {
-            var judicialManagementOrderTable = _judicialManagementOrdersRepository.Queryable()
-                .LeftJoin<Order>((x, o) => x.Id == o.Id)
-                .Where((x, o) => x.CreationTime >= queryIndustryOrderStatisticsRateRequest.StartTime && x.CreationTime <= queryIndustryOrderStatisticsRateRequest.EndTime)
-                .WhereIF(string.IsNullOrEmpty(queryIndustryOrderStatisticsRateRequest.AreaCode), (x, o) => o.AreaCode != null && o.AreaCode.StartsWith(queryIndustryOrderStatisticsRateRequest.AreaCode));
+            ISugarQueryable<JudicialManagementOrders, Order, IndustryAssociations, IndustrialManagement> groupByQueryable = IndustryGroupBy(queryIndustryOrderStatisticsRateRequest);
 
-            var queryable = judicialManagementOrderTable.InnerJoin<OrderSnapshot>((x, o, s) => x.Id == s.Id)
-               .GroupBy((x, o, s) => s.IndustryName)
-               .Select((x, o, s) => new IndustryOrderStaticsRateDto
-               {
-                   IndustryName = s.IndustryName,
-                   Rate = SqlFunc.AggregateCount(SqlFunc.IIF(o.IsEnforcementOrder.HasValue && o.IsEnforcementOrder == true, 1, 0)) / SqlFunc.AggregateCount(o.Id),
-                   Count = SqlFunc.AggregateCount(SqlFunc.IIF(o.IsEnforcementOrder.HasValue && o.IsEnforcementOrder == true, 1, 0))
-               });
+            var queryable = groupByQueryable.Select((x, o, a, i) => new IndustryOrderStaticsRateDto
+            {
+                IndustryName = i.IndustrialName,
+                Rate = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsEnforcementOrder.HasValue && x.IsEnforcementOrder == true, 1, 0)) / SqlFunc.AggregateCount(x.Id),
+                Count = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsEnforcementOrder.HasValue && x.IsEnforcementOrder == true, 1, 0))
+            });
 
             var result = await queryable.ToListAsync();
 
             return result;
         }
 
+        private ISugarQueryable<JudicialManagementOrders, Order, IndustryAssociations, IndustrialManagement> IndustryGroupBy(QueryIndustryOrderStatisticsRateRequest queryIndustryOrderStatisticsRateRequest)
+        {
+            var judicialManagementOrderTable = _judicialManagementOrdersRepository.Queryable()
+                            .LeftJoin<Order>((x, o) => x.Id == o.Id)
+                            .Where((x, o) => x.CreationTime >= queryIndustryOrderStatisticsRateRequest.StartTime && x.CreationTime <= queryIndustryOrderStatisticsRateRequest.EndTime)
+                            .WhereIF(string.IsNullOrEmpty(queryIndustryOrderStatisticsRateRequest.AreaCode), (x, o) => o.AreaCode != null && o.AreaCode.StartsWith(queryIndustryOrderStatisticsRateRequest.AreaCode));
+
+            var queryable = judicialManagementOrderTable
+                .LeftJoin<IndustryAssociations>((x, o, a) => a.OrganizeId == o.ActualHandleOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("9")))
+                .LeftJoin<IndustrialManagement>((x, o, a, i) => a.IndustrialManagementId == i.Id);
+
+            var groupby = queryable.GroupBy((x, o, a, i) => i.IndustrialName);
+            return groupby;
+        }
+
         public async Task<List<EventTypeOrderStaticsDto>> QueryEventTypeOrderStatics(QueryEventTypeOrderStaticsRequest queryEventTypeOrderStaticsRequest)
         {
             var judicialManagementOrderTable = _judicialManagementOrdersRepository.Queryable()

+ 19 - 5
src/Hotline.Application/OrderApp/Handlers/OrderHandler/OrderVisitSmsHandler.cs

@@ -2,6 +2,7 @@
 using Hotline.Orders;
 using Hotline.Push.FWMessage;
 using Hotline.Push.Notifies;
+using Hotline.Settings;
 using Hotline.Share.Dtos.Push;
 using Hotline.Share.Enums.Push;
 using Hotline.Share.Mq;
@@ -14,16 +15,22 @@ public class OrderVisitSmsHandler : INotificationHandler<ReceiveMessageNotify>
 {
     private readonly IOrderVisitDomainService _orderVisitDomainService;
     private readonly IRepository<Message> _messageRepository;
+    private readonly ISystemLogRepository _logRepository;
 
-    public OrderVisitSmsHandler(IOrderVisitDomainService orderVisitDomainService, IRepository<Message> messageRepository)
+    public OrderVisitSmsHandler(IOrderVisitDomainService orderVisitDomainService, IRepository<Message> messageRepository, ISystemLogRepository logRepository)
     {
         _orderVisitDomainService = orderVisitDomainService;
         _messageRepository = messageRepository;
+        _logRepository = logRepository;
     }
 
     public async Task Handle(ReceiveMessageNotify notification, CancellationToken cancellationToken)
     {
-        if (notification.NotifyDto.Type != "2") return;
+        if (notification.NotifyDto.Type != "2")
+        {
+            _logRepository.Add("短信回访-不处理", notification, "Type=2才处理,现在Type:" + notification.NotifyDto.Type, "OrderVisitSmsHandler", 0);
+            return;
+        }
 
         var msg = await _messageRepository
             .Queryable()
@@ -31,9 +38,16 @@ public class OrderVisitSmsHandler : INotificationHandler<ReceiveMessageNotify>
             .Where(m => m.PushBusiness == EPushBusiness.VisitSms || m.PushBusiness == EPushBusiness.SearchSms)
             .Where(m => m.SendState == ESendState.Success)
             .OrderByDescending(m => m.CreationTime)
-            .FirstAsync();
-        if (msg.SendTime!.Value.AddDays(2) < DateTime.Now) return;
-        await _orderVisitDomainService.UpdateSmsReplyAsync(notification.NotifyDto);
+            .FirstAsync(cancellationToken);
+        if (msg != null)
+        {
+            if (msg.SendTime!.Value.AddDays(2) < DateTime.Now)
+            {
+                _logRepository.Add("短信回访-不处理", notification, "msg.SendTime 已经超过2天, 不处理", "OrderVisitSmsHandler", 0);
+                return;
+            }
+            await _orderVisitDomainService.UpdateSmsReplyAsync(notification.NotifyDto);
+        }
     }
 }
 

+ 192 - 148
src/Hotline.Application/OrderApp/OrderApplication.cs

@@ -1,4 +1,5 @@
-using DocumentFormat.OpenXml.Spreadsheet;
+using DocumentFormat.OpenXml.Drawing.Diagrams;
+using DocumentFormat.OpenXml.Spreadsheet;
 using DotNetCore.CAP;
 using FluentValidation;
 using Hotline.Application.FlowEngine;
@@ -41,6 +42,7 @@ using Hotline.Share.Enums.Quality;
 using Hotline.Share.Enums.Settings;
 using Hotline.Share.Mq;
 using Hotline.Share.Requests;
+using Hotline.Share.Tools;
 using Hotline.Statistics;
 using Hotline.Tools;
 using Hotline.Users;
@@ -4030,24 +4032,44 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// <returns></returns>
     public ISugarQueryable<OrderScreenAuditVo> OrderScreenAudit(OrderScreenAuditPagedRequest dto)
     {
-        var query = _workflowTraceRepository.Queryable()
-            .Where(x => x.ModuleCode == "OrderScreen")
-            .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, x => x.HandleTime >= dto.StartTime && x.HandleTime <= dto.EndTime)
-            .WhereIF(!string.IsNullOrEmpty(dto.AuditUserName), x => x.HandlerName == dto.AuditUserName)
-            .Where(x => x.HandlerName != null && x.HandlerName != "")
-            .WhereIF(dto.AuditType is 1, x => x.Name == "班长审批")
-            .WhereIF(dto.AuditType is 2, x => x.Name == "中心领导")
-             .WhereIF(_appOptions.Value.IsZiGong && dto.AuditType is 3, x => x.Name == "中心初审")
-            .GroupBy(x => new { x.HandlerName })
-            .Select(x => new OrderScreenAuditVo
-            {
-                AuditName = x.HandlerName,
-                AuditNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceType == EWorkflowTraceType.Normal && x.TraceState == EWorkflowTraceState.Normal, 1,
-                    0)),
-                AuditBackNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceState == EWorkflowTraceState.StepRemoveByPrevious ||
-                x.TraceState == EWorkflowTraceState.StepRemoveByRecall, 1, 0)),
-            });
-        return query;
+        if (_appOptions.Value.IsZiGong)
+        {
+            return _workflowTraceRepository.Queryable()
+                .Where(x => x.ModuleCode == "OrderScreen")
+                .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, x => x.HandleTime >= dto.StartTime && x.HandleTime <= dto.EndTime)
+                .WhereIF(!string.IsNullOrEmpty(dto.AuditUserName), x => x.HandlerName == dto.AuditUserName)
+                .Where(x => x.HandlerName != null && x.HandlerName != "")
+                .WhereIF(!string.IsNullOrEmpty(dto.StepName), x => x.Name == dto.StepName)
+                //.WhereIF(dto.AuditType is 1, x => x.Name == "班长审批")
+                //.WhereIF(dto.AuditType is 2, x => x.Name == "中心领导")
+                // .WhereIF(_appOptions.Value.IsZiGong && dto.AuditType is 3, x => x.Name == "中心初审")
+                .GroupBy(x => new { x.HandlerName, x.Name })
+                .Select(x => new OrderScreenAuditVo
+                {
+                    AuditName = x.HandlerName,
+                    StepName = x.Name,
+                    AuditNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceType == EWorkflowTraceType.Normal && x.TraceState == EWorkflowTraceState.Normal, 1, 0)),
+                    AuditBackNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceState == EWorkflowTraceState.StepRemoveByPrevious || x.TraceState == EWorkflowTraceState.StepRemoveByRecall, 1, 0)),
+                });
+        }
+        else
+        {
+            return _workflowTraceRepository.Queryable()
+               .Where(x => x.ModuleCode == "OrderScreen")
+               .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, x => x.HandleTime >= dto.StartTime && x.HandleTime <= dto.EndTime)
+               .WhereIF(!string.IsNullOrEmpty(dto.AuditUserName), x => x.HandlerName == dto.AuditUserName)
+               .Where(x => x.HandlerName != null && x.HandlerName != "")
+               .WhereIF(dto.AuditType is 1, x => x.Name == "班长审批")
+               .WhereIF(dto.AuditType is 2, x => x.Name == "中心领导")
+                .WhereIF(_appOptions.Value.IsZiGong && dto.AuditType is 3, x => x.Name == "中心初审")
+               .GroupBy(x => new { x.HandlerName })
+               .Select(x => new OrderScreenAuditVo
+               {
+                   AuditName = x.HandlerName,
+                   AuditNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceType == EWorkflowTraceType.Normal && x.TraceState == EWorkflowTraceState.Normal, 1, 0)),
+                   AuditBackNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceState == EWorkflowTraceState.StepRemoveByPrevious, 1, 0)),
+               });
+        }
     }
 
     /// <summary>
@@ -4769,15 +4791,16 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                     case EBusinessType.Send:
                         // 平均派单
                         var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
-                        if (averageSendOrder) {
-							var sendOrderTrace = workflow.Traces
-		                    .Where(x => x.BusinessType == EBusinessType.Send && x.HandlerId != AppDefaults.SendPoolId)
-		                    .MaxBy(x => x.CreationTime);
-							var prevSendOrder = sendOrderTrace is not null;
-							if (prevSendOrder)
-							{
-								prevSendOrder = await _orderDomainService.SchedulingAtWork(sendOrderTrace.HandlerId);
-							}
+                        if (averageSendOrder)
+                        {
+                            var sendOrderTrace = workflow.Traces
+                            .Where(x => x.BusinessType == EBusinessType.Send && x.HandlerId != AppDefaults.SendPoolId)
+                            .MaxBy(x => x.CreationTime);
+                            var prevSendOrder = sendOrderTrace is not null;
+                            if (prevSendOrder)
+                            {
+                                prevSendOrder = await _orderDomainService.SchedulingAtWork(sendOrderTrace.HandlerId);
+                            }
                             if (prevSendOrder)
                             {
                                 rsp = new StepAssignInfo()
@@ -4792,10 +4815,11 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 
                                 };
                             }
-                            else {
-								rsp = await _orderDomainService.AverageOrder(cancellationToken);
-							}
-						}
+                            else
+                            {
+                                rsp = await _orderDomainService.AverageOrder(cancellationToken);
+                            }
+                        }
                         break;
                     case EBusinessType.Department:
                         rsp = new StepAssignInfo
@@ -4980,37 +5004,37 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                     case EBusinessType.Send:
                         // 平均派单
                         var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
-						if (averageSendOrder)
-						{
-							var sendOrderTrace = workflow.Traces
-							.Where(x => x.BusinessType == EBusinessType.Send && x.HandlerId != AppDefaults.SendPoolId)
-							.MaxBy(x => x.CreationTime);
-							var prevSendOrder = sendOrderTrace is not null;
-							if (prevSendOrder)
-							{
-								prevSendOrder = await _orderDomainService.SchedulingAtWork(sendOrderTrace.HandlerId);
-							}
-							if (prevSendOrder)
-							{
-								//todo
-								rsp = new StepAssignInfo()
-								{
-									Key = sendOrderTrace.HandlerId,
-									Value = sendOrderTrace.HandlerName,
-									UserId = sendOrderTrace.HandlerId,
-									Username = sendOrderTrace.HandlerName,
-									OrgId = sendOrderTrace.HandlerOrgId,
-									OrgName = sendOrderTrace.HandlerOrgName,
-									FlowAssignType = EFlowAssignType.User
-
-								};
-							}
-							else
-							{
-								rsp = await _orderDomainService.AverageOrder(cancellationToken);
-							}
-						}
-						break;
+                        if (averageSendOrder)
+                        {
+                            var sendOrderTrace = workflow.Traces
+                            .Where(x => x.BusinessType == EBusinessType.Send && x.HandlerId != AppDefaults.SendPoolId)
+                            .MaxBy(x => x.CreationTime);
+                            var prevSendOrder = sendOrderTrace is not null;
+                            if (prevSendOrder)
+                            {
+                                prevSendOrder = await _orderDomainService.SchedulingAtWork(sendOrderTrace.HandlerId);
+                            }
+                            if (prevSendOrder)
+                            {
+                                //todo
+                                rsp = new StepAssignInfo()
+                                {
+                                    Key = sendOrderTrace.HandlerId,
+                                    Value = sendOrderTrace.HandlerName,
+                                    UserId = sendOrderTrace.HandlerId,
+                                    Username = sendOrderTrace.HandlerName,
+                                    OrgId = sendOrderTrace.HandlerOrgId,
+                                    OrgName = sendOrderTrace.HandlerOrgName,
+                                    FlowAssignType = EFlowAssignType.User
+
+                                };
+                            }
+                            else
+                            {
+                                rsp = await _orderDomainService.AverageOrder(cancellationToken);
+                            }
+                        }
+                        break;
                     case EBusinessType.Department:
                         rsp = new StepAssignInfo
                         {
@@ -6258,12 +6282,31 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 .Queryable(hasHandled: isHandled, isAdmin: isAdmin)
                 .Includes(d => d.Order)
                 .Includes(d => d.Workflow)
-                .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
-                    d => d.Order.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
-                //.WhereIF(dto.IsApply == true, d => d.DelayState != EDelayState.Examining)
+                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Order.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
                 .WhereIF(dto.IsApply == false, d => d.DelayState == EDelayState.Examining)
-                //.WhereIF(dto.DelayState != null, x => x.DelayState == dto.DelayState)
-                //.Where(x=>x.DelayState == EDelayState.Examining)
+                .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.Order.No.Contains(dto.No))                                   //工单编号
+                .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, d => d.Order.IsProvince == true)      //是否省工单
+                .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, d => d.Order.IsProvince == false)
+                .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Order.Title.Contains(dto.Title))                          //工单标题
+                .WhereIF(!string.IsNullOrEmpty(dto.Channel), d => d.Order.SourceChannelCode == dto.Channel)                 //来源渠道
+                .WhereIF(dto.CreationTimeStart.HasValue, d => d.Order.CreationTime >= dto.CreationTimeStart)                //受理时间Start
+                .WhereIF(dto.CreationTimeEnd.HasValue, d => d.Order.CreationTime <= dto.CreationTimeEnd)                    //受理时间End
+                .WhereIF(!string.IsNullOrEmpty(dto.AcceptorName), d => d.Order.AcceptorName == dto.AcceptorName!)           //受理人
+                .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), d => d.Order.HotspotSpliceName != null && d.Order.HotspotSpliceName.Contains(dto.Hotspot)) //热点
+                .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), d => d.Order.AcceptTypeCode == dto.AcceptTypeCode)      //受理类型
+                .WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName), d => d.Order.OrgLevelOneName.Contains(dto.OrgLevelOneName)) //一级部门
+                .WhereIF(!string.IsNullOrEmpty(dto.CurrentHandleOrgName), d => d.Order.CurrentHandleOrgName.Contains(dto.CurrentHandleOrgName)) //接办部门
+                .WhereIF(dto.CurrentHandleTimeStart.HasValue, d => d.Order.CurrentHandleTime >= dto.CurrentHandleTimeStart) //接办时间Start
+                .WhereIF(dto.CurrentHandleTimeEnd.HasValue, d => d.Order.CurrentHandleTime <= dto.CurrentHandleTimeEnd)     //接办时间End
+                .WhereIF(dto.ApplyTimeStart.HasValue, d => d.CreationTime >= dto.ApplyTimeStart)                            //延期申请时间Start
+                .WhereIF(dto.ApplyTimeEnd.HasValue, d => d.CreationTime <= dto.ApplyTimeEnd)                                //延期申请时间End
+                .WhereIF(!string.IsNullOrEmpty(dto.ApplyName), d => d.CreatorName.Contains(dto.ApplyName))                  //延期申请人
+                .WhereIF(!string.IsNullOrEmpty(dto.ApplyOrgName), d => d.CreatorOrgName.Contains(dto.ApplyOrgName))         //延期申请部门
+                .WhereIF(dto.DelayNum.HasValue, d => d.DelayNum == dto.DelayNum)                                            //延期申请时限
+                .WhereIF(dto.DelayUnit.HasValue, d => d.DelayUnit == dto.DelayUnit)                                         //延期申请单位
+                .WhereIF(!string.IsNullOrEmpty(dto.DelayReason), d => d.DelayReason.Contains(dto.DelayReason))              //申请理由
+                .WhereIF(dto.BeforeDelayStart.HasValue, d => d.BeforeDelay >= dto.BeforeDelayStart)                         //申请前期满时间Start
+                .WhereIF(dto.BeforeDelayEnd.HasValue, d => d.BeforeDelay <= dto.BeforeDelayEnd)                             //申请前期满时间End
                 .OrderByDescending(d => d.ApplyDelayTime)
             ;
 
@@ -6489,40 +6532,40 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     }
 
 
-	#region 坐席退回统计表
-	/// <summary>
-	/// 坐席退回统计表
-	/// </summary>
-	/// <param name="dto"></param>
-	/// <returns></returns>
-	public ISugarQueryable<SeatSendBackStatisticsVo> SeatSendBackStatistics(PagedKeywordRequest dto) 
+    #region 坐席退回统计表
+    /// <summary>
+    /// 坐席退回统计表
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public ISugarQueryable<SeatSendBackStatisticsVo> SeatSendBackStatistics(PagedKeywordRequest dto)
     {
-		var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi);
-		var roles = setting?.SettingValue.ToList();
-		var seats =  _userRepository.Queryable()
-			.Includes(d => d.Organization)
-			.Includes(d => d.Roles)
-			.Where(d => d.Roles.Any(x => roles.Contains(x.Name)));
+        var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi);
+        var roles = setting?.SettingValue.ToList();
+        var seats = _userRepository.Queryable()
+            .Includes(d => d.Organization)
+            .Includes(d => d.Roles)
+            .Where(d => d.Roles.Any(x => roles.Contains(x.Name)));
         var send = _workflowTraceRepository.Queryable()
             .LeftJoin<Order>((x, o) => x.ExternalId == o.Id)
-            .Where((x, o) => x.HandlerOrgId  != OrgSeedData.CenterId && (x.PrevStepName == "班长审批"|| x.PrevStepName == "派单组") && o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && x.CreationTime >= dto.StartTime)
-            .GroupBy((x, o) => new {o.AcceptorId  })
-            .Select((x, o) => new SeatSendBackStatisticsVo { UserId = o.AcceptorId , SendOrderNum = SqlFunc.AggregateDistinctCount(x.ExternalId) });
-
-      //  var sendBack = _workflowTraceRepository.Queryable()
-			   //.LeftJoin<Order>((x, o) => x.ExternalId == o.Id)
-      //         .Where((x, o) => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && x.CreationTime >= dto.StartTime && x.BusinessType == EBusinessType.Seat && (x.PrevStepName == "班长审批" || x.PrevStepName == "派单组"))
-			   //.GroupBy((x, o) => new { o.AcceptorId})
-			   //.Select((x, o) => new { UserId = o.AcceptorId, SendOrderBackNum = SqlFunc.AggregateDistinctCount(x.ExternalId), SendOrderBackNumber = SqlFunc.AggregateCount(x.ExternalId) });
+            .Where((x, o) => x.HandlerOrgId != OrgSeedData.CenterId && (x.PrevStepName == "班长审批" || x.PrevStepName == "派单组") && o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && x.CreationTime >= dto.StartTime)
+            .GroupBy((x, o) => new { o.AcceptorId })
+            .Select((x, o) => new SeatSendBackStatisticsVo { UserId = o.AcceptorId, SendOrderNum = SqlFunc.AggregateDistinctCount(x.ExternalId) });
+
+        //  var sendBack = _workflowTraceRepository.Queryable()
+        //.LeftJoin<Order>((x, o) => x.ExternalId == o.Id)
+        //         .Where((x, o) => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && x.CreationTime >= dto.StartTime && x.BusinessType == EBusinessType.Seat && (x.PrevStepName == "班长审批" || x.PrevStepName == "派单组"))
+        //.GroupBy((x, o) => new { o.AcceptorId})
+        //.Select((x, o) => new { UserId = o.AcceptorId, SendOrderBackNum = SqlFunc.AggregateDistinctCount(x.ExternalId), SendOrderBackNumber = SqlFunc.AggregateCount(x.ExternalId) });
         var sendBack = _orderSendBackAuditRepository.Queryable()
 			.LeftJoin<Order>((x, o) => x.OrderId == o.Id)
-			.Where((x, o) => x.ApplyOrgId != OrgSeedData.CenterId && (x.SendBackStepName == "班长审批" || x.SendBackStepName == "派单组") && o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime)
+			.Where((x, o) =>  (x.SendBackStepName == "话务部") && o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime)
 			.GroupBy((x, o) => new { o.AcceptorId })
 			.Select((x, o) => new SeatSendBackStatisticsVo { UserId = o.AcceptorId, SendOrderBackNum = SqlFunc.AggregateDistinctCount(x.OrderId), SendOrderBackNumber = SqlFunc.AggregateCount(x.Id) });
 
 
 		var filed = _orderRepository.Queryable()
-            .Where(x=> x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime && x.Status >= EOrderStatus.Filed && x.FileOrgIsCenter == true)
+            .Where(x=> x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime && x.Status >= EOrderStatus.Filed && x.FileOrgIsCenter == true && x.FileUserRole == EFileUserType.Seat)
             .GroupBy(x=>x.AcceptorId)
             .Select(x => new SeatSendBackStatisticsVo { UserId = x.AcceptorId, CentreFileNum = SqlFunc.AggregateDistinctCount(x.Id) });
 
@@ -6530,56 +6573,57 @@ public class OrderApplication : IOrderApplication, IScopeDependency
              .LeftJoin<Order>((x, o) => x.OrderId == o.Id)
              .Where((x, o) => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && x.SpecialType == ESpecialType.SendBack && x.NextStepCode == "start")
              .GroupBy((x, o) => new { o.AcceptorId })
-             .Select((x, o) => new SeatSendBackStatisticsVo { UserId = o.AcceptorId, CentreFileBackNum = SqlFunc.AggregateDistinctCount(x.OrderId), CentreFileBackNumber = SqlFunc.AggregateCount(x.OrderId)});
-
-      var query =   seats.LeftJoin(send, (s, sd) => s.Id == sd.UserId)
-            .LeftJoin(sendBack, (s, sd, sb) => s.Id == sb.UserId)
-            .LeftJoin(filed, (s, sd, sb, f) => s.Id == f.UserId)
-            .LeftJoin(back, (s, sd, sb, f, b) => s.Id == b.UserId)
-            .GroupBy((s, sd, sb, f, b) => new { s.Id, s.Name })
-			.Select((s, sd, sb, f, b) => new SeatSendBackStatisticsVo
-			{
-				UserId = s.Id,
-				UserName = s.Name,
-				SendOrderNum = SqlFunc.AggregateSum(sd.SendOrderNum),
-				SendOrderBackNum = SqlFunc.AggregateSum(sb.SendOrderBackNum),
-				SendOrderBackNumber = SqlFunc.AggregateSum(sb.SendOrderBackNumber),
-				CentreFileNum = SqlFunc.AggregateSum(f.CentreFileNum),
-				CentreFileBackNum = SqlFunc.AggregateSum(b.CentreFileBackNum),
-				CentreFileBackNumber = SqlFunc.AggregateSum(b.CentreFileBackNumber),
-			});
+             .Select((x, o) => new SeatSendBackStatisticsVo { UserId = o.AcceptorId, CentreFileBackNum = SqlFunc.AggregateDistinctCount(x.OrderId), CentreFileBackNumber = SqlFunc.AggregateCount(x.OrderId) });
+
+        var query = seats.LeftJoin(send, (s, sd) => s.Id == sd.UserId)
+              .LeftJoin(sendBack, (s, sd, sb) => s.Id == sb.UserId)
+              .LeftJoin(filed, (s, sd, sb, f) => s.Id == f.UserId)
+              .LeftJoin(back, (s, sd, sb, f, b) => s.Id == b.UserId)
+              .GroupBy((s, sd, sb, f, b) => new { s.Id, s.Name })
+              .Select((s, sd, sb, f, b) => new SeatSendBackStatisticsVo
+              {
+                  UserId = s.Id,
+                  UserName = s.Name,
+                  SendOrderNum = SqlFunc.AggregateSum(sd.SendOrderNum),
+                  SendOrderBackNum = SqlFunc.AggregateSum(sb.SendOrderBackNum),
+                  SendOrderBackNumber = SqlFunc.AggregateSum(sb.SendOrderBackNumber),
+                  CentreFileNum = SqlFunc.AggregateSum(f.CentreFileNum),
+                  CentreFileBackNum = SqlFunc.AggregateSum(b.CentreFileBackNum),
+                  CentreFileBackNumber = SqlFunc.AggregateSum(b.CentreFileBackNumber),
+              });
         return query;
-	}
+    }
 
 
-	/// <summary>
-	/// 坐席退回统计表明细
-	/// </summary>
-	/// <param name="dto"></param>
-	/// <returns></returns>
-	public ISugarQueryable<OrderDto> SeatSendBackStatisticsDetail(SeatSendBackStatisticsDetail dto) {
+    /// <summary>
+    /// 坐席退回统计表明细
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public ISugarQueryable<OrderDto> SeatSendBackStatisticsDetail(SeatSendBackStatisticsDetail dto)
+    {
 
-		if (dto.StatisticsType == "sendOrderNum")
+        if (dto.StatisticsType == "sendOrderNum")
         {
-           var query = _orderRepository.Queryable().Where(x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime)
-                .WhereIF(!string.IsNullOrEmpty(dto.UserId ),x=> x.AcceptorId == dto.UserId)
-				.WhereIF(!string.IsNullOrEmpty(dto.No), x => x.No.Contains(dto.No!))
-				.WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Title.Contains(dto.Title!))
-				.WhereIF(!string.IsNullOrEmpty(dto.AcceptType), x => x.AcceptTypeCode == dto.AcceptType) //受理类型
-				.WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.SourceChannelCode == dto.Channel) //来源渠道
-				 .WhereIF(!string.IsNullOrEmpty(dto.Hotspot),
-					x => x.HotspotSpliceName != null && x.HotspotSpliceName.Contains(dto.Hotspot)) //热点分类
-				.Where(x => SqlFunc.Subqueryable<WorkflowTrace>().Where(wt => wt.ExternalId == x.Id && wt.HandlerOrgId != OrgSeedData.CenterId && (wt.PrevStepName == "班长审批" || wt.PrevStepName == "派单组")).Any())
-                .Select(x=> new OrderDto() { Id = x.Id.SelectAll() })
-				.OrderByIF(dto is { SortField: "startTime", SortRule: 0 }, x => x.StartTime, OrderByType.Asc)
-				.OrderByIF(dto is { SortField: "startTime", SortRule: 1 }, x => x.StartTime, OrderByType.Desc)
-				.OrderByIF(dto is { SortField: "filedTime", SortRule: 0 }, x => x.FiledTime, OrderByType.Asc)
-				.OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.FiledTime, OrderByType.Desc)
-				.OrderByIF(dto is { SortField: "sendBackAuditTime", SortRule: 0 }, x => x.SendBackAuditTime, OrderByType.Asc)
-				.OrderByIF(dto is { SortField: "sendBackAuditTime", SortRule: 1 }, x => x.SendBackAuditTime, OrderByType.Desc);
+            var query = _orderRepository.Queryable().Where(x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime)
+                 .WhereIF(!string.IsNullOrEmpty(dto.UserId), x => x.AcceptorId == dto.UserId)
+                 .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.No.Contains(dto.No!))
+                 .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Title.Contains(dto.Title!))
+                 .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), x => x.AcceptTypeCode == dto.AcceptType) //受理类型
+                 .WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.SourceChannelCode == dto.Channel) //来源渠道
+                  .WhereIF(!string.IsNullOrEmpty(dto.Hotspot),
+                     x => x.HotspotSpliceName != null && x.HotspotSpliceName.Contains(dto.Hotspot)) //热点分类
+                 .Where(x => SqlFunc.Subqueryable<WorkflowTrace>().Where(wt => wt.ExternalId == x.Id && wt.HandlerOrgId != OrgSeedData.CenterId && (wt.PrevStepName == "班长审批" || wt.PrevStepName == "派单组")).Any())
+                 .Select(x => new OrderDto() { Id = x.Id.SelectAll() })
+                 .OrderByIF(dto is { SortField: "startTime", SortRule: 0 }, x => x.StartTime, OrderByType.Asc)
+                 .OrderByIF(dto is { SortField: "startTime", SortRule: 1 }, x => x.StartTime, OrderByType.Desc)
+                 .OrderByIF(dto is { SortField: "filedTime", SortRule: 0 }, x => x.FiledTime, OrderByType.Asc)
+                 .OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.FiledTime, OrderByType.Desc)
+                 .OrderByIF(dto is { SortField: "sendBackAuditTime", SortRule: 0 }, x => x.SendBackAuditTime, OrderByType.Asc)
+                 .OrderByIF(dto is { SortField: "sendBackAuditTime", SortRule: 1 }, x => x.SendBackAuditTime, OrderByType.Desc);
             return query;
         }
-        else if(dto.StatisticsType == "sendOrderBackNum")
+        else if (dto.StatisticsType == "sendOrderBackNum")
         {
 			var query = _orderRepository.Queryable().Where(x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime )
 				.WhereIF(!string.IsNullOrEmpty(dto.UserId), x => x.AcceptorId == dto.UserId)
@@ -6589,7 +6633,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 				.WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.SourceChannelCode == dto.Channel) //来源渠道
 				 .WhereIF(!string.IsNullOrEmpty(dto.Hotspot),
 					x => x.HotspotSpliceName != null && x.HotspotSpliceName.Contains(dto.Hotspot)) //热点分类
-				.Where(x => SqlFunc.Subqueryable<OrderSendBackAudit>().Where(os => os.OrderId == x.Id && os.ApplyOrgId != OrgSeedData.CenterId && (os.SendBackStepName == "班长审批" || os.SendBackStepName == "派单组")).Any())
+				.Where(x => SqlFunc.Subqueryable<OrderSendBackAudit>().Where(os => os.OrderId == x.Id && (os.SendBackStepName == "话务部")).Any())
 				.Select(x => new OrderDto() { Id = x.Id.SelectAll() })
 				.OrderByIF(dto is { SortField: "startTime", SortRule: 0 }, x => x.StartTime, OrderByType.Asc)
 				.OrderByIF(dto is { SortField: "startTime", SortRule: 1 }, x => x.StartTime, OrderByType.Desc)
@@ -6602,7 +6646,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 		else if (dto.StatisticsType == "sendOrderBackNumber")
 		{
 			var query = _orderRepository.Queryable()
-                .LeftJoin<OrderSendBackAudit>((x, os) => x.Id == os.OrderId && os.ApplyOrgId != OrgSeedData.CenterId && (os.SendBackStepName == "班长审批" || os.SendBackStepName == "派单组"))
+                .LeftJoin<OrderSendBackAudit>((x, os) => x.Id == os.OrderId  && (os.SendBackStepName == "话务部"))
 				.WhereIF(!string.IsNullOrEmpty(dto.No), (x, os) => x.No.Contains(dto.No!))
 				.WhereIF(!string.IsNullOrEmpty(dto.Title), (x, os) => x.Title.Contains(dto.Title!))
 				.WhereIF(!string.IsNullOrEmpty(dto.AcceptType), (x, os) => x.AcceptTypeCode == dto.AcceptType) //受理类型
@@ -6623,7 +6667,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 		}
 		else if (dto.StatisticsType == "centreFileNum")
 		{
-			var query = _orderRepository.Queryable().Where(x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime )
+			var query = _orderRepository.Queryable().Where(x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime && x.FileUserRole == EFileUserType.Seat )
 				.WhereIF(!string.IsNullOrEmpty(dto.UserId), x => x.AcceptorId == dto.UserId)
 				.WhereIF(!string.IsNullOrEmpty(dto.No), x => x.No.Contains(dto.No!))
 				.WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Title.Contains(dto.Title!))
@@ -6673,15 +6717,15 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 				.WhereIF(!string.IsNullOrEmpty(dto.UserId), (x, os) => x.AcceptorId == dto.UserId)
 				.Select((x, os) => new OrderDto() { Id = x.Id.SelectAll() , SendBackOpinion = os.Reason , SendBackAuditTime = os.CreationTime })
                 .MergeTable()
-				.OrderByIF(dto is { SortField: "startTime", SortRule: 0 }, x => x.StartTime, OrderByType.Asc)
-				.OrderByIF(dto is { SortField: "startTime", SortRule: 1 }, x => x.StartTime, OrderByType.Desc)
-				.OrderByIF(dto is { SortField: "filedTime", SortRule: 0 }, x => x.FiledTime, OrderByType.Asc)
-				.OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.FiledTime, OrderByType.Desc)
-				.OrderByIF(dto is { SortField: "sendBackAuditTime", SortRule: 0 }, x => x.SendBackAuditTime, OrderByType.Asc)
-				.OrderByIF(dto is { SortField: "sendBackAuditTime", SortRule: 1 }, x => x.SendBackAuditTime, OrderByType.Desc);
-			return query;
-		}
+                .OrderByIF(dto is { SortField: "startTime", SortRule: 0 }, x => x.StartTime, OrderByType.Asc)
+                .OrderByIF(dto is { SortField: "startTime", SortRule: 1 }, x => x.StartTime, OrderByType.Desc)
+                .OrderByIF(dto is { SortField: "filedTime", SortRule: 0 }, x => x.FiledTime, OrderByType.Asc)
+                .OrderByIF(dto is { SortField: "filedTime", SortRule: 1 }, x => x.FiledTime, OrderByType.Desc)
+                .OrderByIF(dto is { SortField: "sendBackAuditTime", SortRule: 0 }, x => x.SendBackAuditTime, OrderByType.Asc)
+                .OrderByIF(dto is { SortField: "sendBackAuditTime", SortRule: 1 }, x => x.SendBackAuditTime, OrderByType.Desc);
+            return query;
+        }
         return null;
-	}
-	#endregion
+    }
+    #endregion
 }

+ 14 - 6
src/Hotline.Application/OrderApp/OrderSecondaryHandlingApplication.cs

@@ -242,13 +242,13 @@ namespace Hotline.Application.OrderApp
                 await _orderRepository.UpdateAsync(order, false, cancellationToken);
 
                 visit.VisitState = EVisitState.None;
-			}
+            }
             else
             {
                 visit.IsCanHandle = true;
             }
-			await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
-			await _orderSecondaryHandlingRepository.UpdateAsync(model, cancellationToken);
+            await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
+            await _orderSecondaryHandlingRepository.UpdateAsync(model, cancellationToken);
         }
 
 
@@ -333,9 +333,17 @@ namespace Hotline.Application.OrderApp
                 .Includes(x => x.VisitDetail)
                 .Includes(x => x.Visit, d => d.Order)
                 .Where(x => x.State > ESecondaryHandlingState.NotApply)
-                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Visit.Order.Title.Contains(dto.Keyword!) || x.Visit.Order.No.Contains(dto.Keyword!))
-                .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Visit.Order.Title.Contains(dto.Title!))
-                .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Visit.Order.No.Contains(dto.No!))
+                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Order.Title.Contains(dto.Keyword!) || x.Order.No.Contains(dto.Keyword!))
+                .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No!))
+                .WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.Order.SourceChannelCode == dto.Channel)              //来源渠道
+                .WhereIF(dto.SendBack.HasValue, x => x.SendBackNum == dto.SendBack!)                                     //重提办理
+                .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title!))                      //工单编号
+                .WhereIF(!string.IsNullOrEmpty(dto.ApplyName), x => x.CreatorName.Contains(dto.ApplyName))               //申请人
+                .WhereIF(!string.IsNullOrEmpty(dto.ApplyOrgName), x => x.ApplyOrgName.Contains(dto.ApplyOrgName))        //申请部门
+                .WhereIF(dto.ApplyTimeStart.HasValue, x => x.CreationTime >= dto.ApplyTimeStart)                         //申请时间Start
+                .WhereIF(dto.ApplyTimeEnd.HasValue, x => x.CreationTime <= dto.ApplyTimeEnd)                             //申请时间End
+                .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), x => x.Order.AcceptTypeCode == dto.AcceptTypeCode)   //受理类型
+                .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), x => x.Order.HotspotSpliceName != null && x.Order.HotspotSpliceName.Contains(dto.Hotspot)) //热点
                 .WhereIF(dto.Status is ESecondaryHandlingState.Apply, x => x.State == ESecondaryHandlingState.Apply)
                 .WhereIF(dto.Status is ESecondaryHandlingState.Handled, x => x.State != ESecondaryHandlingState.Apply)
                 .WhereIF(dto.Status is ESecondaryHandlingState.End || dto.Status is ESecondaryHandlingState.Refuse || dto.Status is ESecondaryHandlingState.NotApply, x => x.State == dto.Status)

+ 23 - 12
src/Hotline.Application/OrderApp/OrderSendBackAuditApplication.cs

@@ -24,22 +24,33 @@ namespace Hotline.Application.OrderApp
             return _orderSendBackAuditRepository.Queryable()
                 .Includes(x => x.Order)
                 .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
-                    d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
-                .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Order.Title.Contains(dto.Title!))
-                .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.Order.No.Contains(dto.No!))
-                .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), d => d.Order.AcceptTypeCode == dto.AcceptTypeCode)
-                .WhereIF(!string.IsNullOrEmpty(dto.OrgName), d => d.ApplyOrgName == dto.OrgName)
-                .WhereIF(dto.DataScope is 1, d => d.CreatorId == _sessionContext.RequiredUserId)
-                .WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime)
-                .WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime)
-                .WhereIF(dto.AuditState == 1, d => d.State == ESendBackAuditState.Apply)
-                .WhereIF(dto is { AuditState: 2, State: null }, d => d.State > ESendBackAuditState.Apply)
-                .WhereIF(dto.AuditState is 2 or 3 && dto.State.HasValue && dto.State != ESendBackAuditState.All, d => d.State == dto.State)
+                    x => x.Order.Title.Contains(dto.Keyword!) || x.Order.No.Contains(dto.Keyword!))
+                .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title!))
+                .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No!))
+                .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, x => x.Order.IsProvince == true)
+                .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.Order.IsProvince == false)
+                .WhereIF(!string.IsNullOrEmpty(dto.Channel), x => x.Order.SourceChannelCode == dto.Channel)    //来源渠道
+                .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), x => x.Order.AcceptTypeCode == dto.AcceptTypeCode)
+                .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), x => x.Order.HotspotSpliceName != null && x.Order.HotspotSpliceName.Contains(dto.Hotspot)) //热点
+                .WhereIF(!string.IsNullOrEmpty(dto.CenterToOrgHandlerName), x => x.Order.CenterToOrgHandlerName.Contains(dto.CenterToOrgHandlerName))   //最近派单员              
+                .WhereIF(!string.IsNullOrEmpty(dto.SendBackStepName), x => x.SendBackStepName.Contains(dto.SendBackStepName))                           //退回节点                   
+                .WhereIF(!string.IsNullOrEmpty(dto.NameOrNo), x => x.Order.AcceptorName == dto.NameOrNo! || x.Order.AcceptorStaffNo == dto.NameOrNo!)   //受理人/坐席
+                .WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName), x => x.Order.OrgLevelOneName.Contains(dto.OrgLevelOneName))                        //一级部门 
+                .WhereIF(!string.IsNullOrEmpty(dto.Content), x => x.Order.Content.Contains(dto.Content))                                                //受理内容 
+                .WhereIF(!string.IsNullOrEmpty(dto.ApplyName), x => x.CreatorName.Contains(dto.ApplyName))                                              //申请人 
+                .WhereIF(!string.IsNullOrEmpty(dto.ApplyOrgName), x => x.ApplyOrgName.Contains(dto.ApplyOrgName))                                       //申请部门 
+                .WhereIF(!string.IsNullOrEmpty(dto.Opinion), x => x.SendBackData.Opinion.Contains(dto.Opinion))
+                .WhereIF(!string.IsNullOrEmpty(dto.ApplyOrgName), x => x.ApplyOrgName == dto.ApplyOrgName)
+                .WhereIF(dto.DataScope is 1, x => x.CreatorId == _sessionContext.RequiredUserId)
+                .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
+                .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
+                .WhereIF(dto.AuditState == 1, x => x.State == ESendBackAuditState.Apply)
+                .WhereIF(dto is { AuditState: 2, State: null }, x => x.State > ESendBackAuditState.Apply)
+                .WhereIF(dto.AuditState is 2 or 3 && dto.State.HasValue && dto.State != ESendBackAuditState.All, x => x.State == dto.State)
                 .WhereIF(dto.AuditState == 3 && _sessionContext.RequiredOrgId != OrgSeedData.CenterId, x => x.ApplyOrgId.StartsWith(_sessionContext.OrgId))
                 .WhereIF(_sessionContext.Roles.Contains("role_sysadmin") == false && dto.AuditState != 3, x => x.SendBackOrgId == _sessionContext.OrgId) // 123 系统管理员;
                 .WhereIF(dto.ExpiredTimeStart.HasValue, x => x.Order.ExpiredTime >= dto.ExpiredTimeStart)
                 .WhereIF(dto.ExpiredTimeEnd.HasValue, x => x.Order.ExpiredTime <= dto.ExpiredTimeEnd)
-
             .OrderByDescending(x => x.CreationTime);
         }
     }

+ 2 - 1
src/Hotline.Application/Snapshot/BiSnapshotApplication.cs

@@ -734,7 +734,8 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
             .LeftJoin<OrderSendBackAudit>((snapshot, order, back) => snapshot.Id == back.OrderId && back.State == ESendBackAuditState.End)
             .LeftJoin<OrderVisit>((snapshot, order, back, visit) => snapshot.Id == visit.OrderId && visit.VisitState == EVisitState.Visited)
             .LeftJoin<OrderSecondaryHandling>((snapshot, order, back, visit, second) => snapshot.Id == second.OrderId && second.State == ESecondaryHandlingState.End)
-            .Where((snapshot, order) => snapshot.CreationTime >= dto.StartTime && snapshot.CreationTime <= dto.EndTime && order.ActualHandleOrgCode != null)
+            .Where((snapshot, order) => snapshot.CreationTime >= dto.StartTime && snapshot.CreationTime <= dto.EndTime 
+            && order.ActualHandleOrgCode != null && order.ActualHandleOrgCode != "001")
             .GroupBy((snapshot, order) => new
             {
                 OrgCode = order.ActualHandleOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6"))

+ 1 - 1
src/Hotline.Application/Snapshot/Contracts/ISnapshotApplication.cs

@@ -29,7 +29,7 @@ public interface ISnapshotApplication
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
-    Task<IReadOnlyList<BulletinOutDto>> GetBulletinsAsync(BulletinInDto dto, CancellationToken cancellationToken);
+    Task<IReadOnlyList<BulletinListOutDto>> GetBulletinsAsync(BulletinInDto dto, CancellationToken cancellationToken);
     
     /// <summary>
     /// 获取工单列表

+ 63 - 14
src/Hotline.Application/Snapshot/SnapshotApplicationBase.cs

@@ -41,6 +41,7 @@ using Hotline.Settings.Hotspots;
 using Microsoft.Extensions.Options;
 using XF.Utility.MQ;
 using System.Threading;
+using NPOI.SS.Formula.Functions;
 
 namespace Hotline.Application.Snapshot;
 
@@ -291,7 +292,7 @@ public abstract class SnapshotApplicationBase
     /// 获取随手拍小程序公告
     /// </summary>
     /// <returns></returns>
-    public async Task<IReadOnlyList<BulletinOutDto>> GetBulletinsAsync(BulletinInDto dto, CancellationToken cancellationToken)
+    public async Task<IReadOnlyList<BulletinListOutDto>> GetBulletinsAsync(BulletinInDto dto, CancellationToken cancellationToken)
     {
         var items = await _bulletinRepository.Queryable()
             .Where(m => m.BulletinState == EBulletinState.ReviewPass && m.IsArrive == true)
@@ -299,7 +300,7 @@ public abstract class SnapshotApplicationBase
             .Where((bulletin, industry) => industry.Id == dto.IndustryId)
             .ToFixedListAsync(dto, cancellationToken);
 
-        return items.Adapt<IReadOnlyList<BulletinOutDto>>();
+        return items.Adapt<IReadOnlyList<BulletinListOutDto>>();
     }
 
     /// <summary>
@@ -488,20 +489,19 @@ public abstract class SnapshotApplicationBase
     public async Task<IList<RedPackOutDto>> GetRedPacksAsync(RedPacksInDto dto, CancellationToken cancellationToken)
     {
         var items = await _redPackRecordRepository.Queryable(includeDeleted: true)
-            .LeftJoin<Order>((m , order) => m.OrderId == order.Id)
+            .LeftJoin<Order>((m, order) => m.OrderId == order.Id)
             .Where(m => m.IsDeleted == false)
             .Where(m => m.WXOpenId == _sessionContext.OpenId)
             .WhereIF(dto.Status == ERedPackPickupStatus.Unreceived, (m, order) => m.PickupStatus == dto.Status && (order.HotspotId == null || order.HotspotId.StartsWith("18") == false))
             .WhereIF(dto.Status != ERedPackPickupStatus.Unreceived, (m, order) => m.PickupStatus == dto.Status)
             .Where(m => m.CreationTime.ToString("yyyy-MM") == dto.Time)
-            .LeftJoin<Order>((red, order) => red.OrderId == order.Id)
-            .Select((red, order) => new RedPackOutDto
+            .Select((m, order) => new RedPackOutDto
             {
                 OrderId = order.Id,
-                Amount = red.Amount,
+                Amount = m.Amount,
                 Title = order.Title,
-                CreationTime = red.CreationTime,
-                RedPackAuditId = red.RedPackAuditId
+                CreationTime = m.CreationTime,
+                RedPackAuditId = m.RedPackAuditId
             })
             .ToFixedListAsync(dto, cancellationToken);
 
@@ -967,17 +967,12 @@ public abstract class SnapshotApplicationBase
             .Select((points, citizen) => new PointsRankUserDto
             {
                 IsSecurityMax = citizen.IsSecurityMax ?? false,
-                Rank = SqlFunc.MappingColumn<int>($@"
-            CASE 
-                WHEN citizen.""Id"" = '{_sessionContext.UserId}' THEN 1 
-                ELSE DENSE_RANK() OVER (ORDER BY SUM(CASE WHEN ""points"".""Direction"" = 1 THEN ""points"".""Points"" ELSE 0 END) DESC)
-            END"),
+                Rank = SqlFunc.MappingColumn<int>($@" DENSE_RANK() OVER (ORDER BY SUM(CASE WHEN ""points"".""Direction"" = 0 THEN ""points"".""Points"" ELSE 0 END) DESC)"),
                 Points = SqlFunc.AggregateSum(points.Points),
                 UserName = citizen.Name!,
                 PhoneNumber = citizen.PhoneNumber,
                 CitizenId = citizen.Id,
             }).MergeTable()
-            .OrderByDescending(points => points.Rank)
             .Take(11);
 
 #if DEBUG
@@ -992,6 +987,60 @@ public abstract class SnapshotApplicationBase
             else
                 m.HeadUrl = _systemDicDataCacheManager.HeaderImages("default");
         });
+        if (item.Any(m => m.CitizenId == _sessionContext.UserId) == false)
+        {
+            var my = (await _pointsRecordRepository.Queryable()
+               .LeftJoin<Citizen>((points, citizen) => points.UserId == citizen.Id)
+               .Where((points, citizen) => points.CreationTime >= startTime && points.CreationTime <= endTime)
+               .GroupBy((points, citizen) => new { citizen.Id, points.UserId, citizen.IsSecurityMax, citizen.Name, citizen.PhoneNumber })
+               .Select((points, citizen) => new PointsRankUserDto
+               {
+                   IsSecurityMax = citizen.IsSecurityMax ?? false,
+                   Rank = SqlFunc.MappingColumn<int>($@" DENSE_RANK() OVER (ORDER BY SUM(CASE WHEN ""points"".""Direction"" = 0 THEN ""points"".""Points"" ELSE 0 END) DESC)"),
+                   Points = SqlFunc.AggregateSum(points.Points),
+                   UserName = citizen.Name!,
+                   PhoneNumber = citizen.PhoneNumber,
+                   CitizenId = citizen.Id,
+               }).MergeTable()
+               .ToListAsync()).FirstOrDefault(m => m.CitizenId == _sessionContext.UserId);
+            if (my != null)
+            {
+                item.Insert(0, new PointsRankUserDto
+                {
+                    UserName = my.UserName,
+                    CitizenId = my.CitizenId,
+                    PhoneNumber = my.PhoneNumber,
+                    Rank = my.Rank,
+                    Points = my.Points,
+                    HeadUrl = _systemDicDataCacheManager.HeaderImages("default"),
+                    IsSecurityMax = false
+                });
+            }
+            else
+            {
+                var citizen = await _citizenRepository.GetAsync(_sessionContext.UserId);
+                var count = await _citizenRepository.CountAsync(m => m.Name != "");
+                if (citizen != null)
+                {
+                    item.Insert(0, new PointsRankUserDto
+                    {
+                        UserName = citizen.Name,
+                        CitizenId = citizen.Id,
+                        PhoneNumber = citizen.PhoneNumber,
+                        Rank = count,
+                        Points = 0,
+                        HeadUrl = _systemDicDataCacheManager.HeaderImages("default"),
+                        IsSecurityMax = false
+                    });
+                }
+            }
+        }
+        else
+        {
+            var my = item.First(m => m.CitizenId == _sessionContext.UserId);
+            item.Remove(my);
+            item.Insert(0, my);
+        }
         outDto.Ranks = item;
         return outDto;
     }

+ 17 - 8
src/Hotline.Application/Snapshot/SnapshotOrderApplication.cs

@@ -693,18 +693,27 @@ public class SnapshotOrderApplication : IOrderSnapshotApplication, IScopeDepende
     {
         if (_systemSettingCacheManager.Snapshot == false) return;
 
-        var sspSourceChannel = new List<string>() { "ZGSSP", "SJP12345"};
+        var sspSourceChannel = new List<string>() { "ZGSSP", "SJP12345" };
         if (sspSourceChannel.Any(m => m == dto.SourceChannelCode) == false)
         {
-            await _orderSnapshotRepository.Removeable()
+            await _orderSnapshotRepository.Updateable()
+                .SetColumns(m => m.IsDeleted, true)
                 .Where(m => m.Id == dto.Id)
                 .ExecuteCommandAsync(token);
-            return;
         }
-        await _orderSnapshotRepository.Updateable()
-            .SetColumns(m => m.IndustryId, dto.IndustryId)
-            .SetColumns(m => m.IndustryName, dto.IndustryName)
-            .Where(m => m.Id == dto.Id)
-            .ExecuteCommandAsync(token);
+        else
+        {
+            await _orderSnapshotRepository.Queryable(includeDeleted: true)
+                .Where(m => m.Id == dto.Id)
+                .FirstAsync(token)
+                .Then(async snapshot =>
+                {
+                    snapshot.IsDeleted = false;
+                    snapshot.IndustryId = dto.IndustryId;
+                    snapshot.IndustryName = dto.IndustryName;
+
+                    await _orderSnapshotRepository.UpdateAsync(snapshot, token);
+                });
+        }
     }
 }

+ 9 - 4
src/Hotline.Application/StatisticalReport/CallReport/CallReportApplicationBase.cs

@@ -322,9 +322,9 @@ public abstract class CallReportApplicationBase : ICallReportApplication
     }
 
 
-    public virtual async Task<(int, List<BiSeatSwitchDto>)> QuerySeatSwitchAsync(QuerySeatSwitchRequest dto, CancellationToken cancellationToken)
+    public virtual async Task<(int, List<BiSeatSwitchDto>)> QuerySeatSwitchAsync(QuerySeatSwitchRequest dto, bool isAll, CancellationToken cancellationToken)
     {
-        return await _callNativeRepository.Queryable()
+        var query = _callNativeRepository.Queryable()
             .Where(x => !string.IsNullOrEmpty(x.AgentTransferNumber) && x.CallState != ECallState.Invalid)
             .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
             .WhereIF(!string.IsNullOrEmpty(dto.CDPN), x => x.ToNo.Contains(dto.CDPN))
@@ -339,8 +339,13 @@ public abstract class CallReportApplicationBase : ICallReportApplication
                 TelNo = x.TelNo,
                 UserName = x.UserName,
             })
-            .OrderByDescending(x => x.CreatedTime)
-            .ToPagedListAsync(dto.PageIndex, dto.PageSize, cancellationToken);
+            .OrderByDescending(x => x.CreatedTime);
+
+        if (isAll)
+        {
+            return (0, await query.ToListAsync(cancellationToken));
+        }
+        return await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, cancellationToken);
     }
 
     public virtual Task<List<QuerySeatMonthCallResp>> QuerySeatMonthCall(QuerySeatMonthCallRequest dto)

+ 23 - 18
src/Hotline.Application/StatisticalReport/CallReport/YiBinCallReportApplication.cs

@@ -207,25 +207,30 @@ public class YiBinCallReportApplication : CallReportApplicationBase, ICallReport
               , connectByeTimes, CallInOverConnRingTime, SeatChaoTime, dto.Keyword);
     }
 
-    public override async Task<(int, List<BiSeatSwitchDto>)> QuerySeatSwitchAsync(QuerySeatSwitchRequest dto, CancellationToken cancellationToken)
+    public override async Task<(int, List<BiSeatSwitchDto>)> QuerySeatSwitchAsync(QuerySeatSwitchRequest dto, bool isAll, CancellationToken cancellationToken)
     {
-        return await _trCallRecordRepository.Queryable()
-            .Where(x => !string.IsNullOrEmpty(x.AgentTransferNumber))
-            .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
-            .WhereIF(!string.IsNullOrEmpty(dto.CDPN), x => x.CDPN.Contains(dto.CDPN))
-            .Where(x => x.CreatedTime >= dto.StartTime)
-            .Where(x => x.CreatedTime <= dto.EndTime)
-            .Select(x => new BiSeatSwitchDto
-            {
-                UserId = x.UserId,
-                CPN = x.CPN,
-                CDPN = x.CDPN,
-                CreatedTime = x.CreatedTime,
-                TelNo = x.AgentTransferNumber,
-                UserName = x.UserName,
-            })
-            .OrderByDescending(x => x.CreatedTime)
-            .ToPagedListAsync(dto.PageIndex, dto.PageSize, cancellationToken);
+        var query = _trCallRecordRepository.Queryable()
+                      .Where(x => !string.IsNullOrEmpty(x.AgentTransferNumber))
+                      .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
+                      .WhereIF(!string.IsNullOrEmpty(dto.CDPN), x => x.CDPN.Contains(dto.CDPN))
+                      .Where(x => x.CreatedTime >= dto.StartTime)
+                      .Where(x => x.CreatedTime <= dto.EndTime)
+                      .Select(x => new BiSeatSwitchDto
+                      {
+                          UserId = x.UserId,
+                          CPN = x.CPN,
+                          CDPN = x.CDPN,
+                          CreatedTime = x.CreatedTime,
+                          TelNo = x.AgentTransferNumber,
+                          UserName = x.UserName,
+                      })
+                      .OrderByDescending(x => x.CreatedTime);
+
+        if (isAll)
+        {
+            return (0, await query.ToListAsync(cancellationToken));
+        }
+        return await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, cancellationToken);
     }
 
     public override async Task<List<TrCallHourDto>> GetCallHourListAsync(BiQueryHourCallDto dto, CancellationToken requestAborted)

+ 2 - 2
src/Hotline.Application/StatisticalReport/ICallReportApplication.cs

@@ -34,7 +34,7 @@ namespace Hotline.Application.StatisticalReport
         Task<List<BiSeatCallsDto>> QuerySeatCallAsync(ReportRequiredPagedRequest dto, CancellationToken cancellationToken);
 
         Task<List<QueryCallsDetailDto>> QueryCallsHourDetailAsync(BiQueryCallsDto dto, CancellationToken cancellationToken);
-        Task<(int, List<BiSeatSwitchDto>)> QuerySeatSwitchAsync(QuerySeatSwitchRequest dto, CancellationToken cancellationToken);
+        Task<(int, List<BiSeatSwitchDto>)> QuerySeatSwitchAsync(QuerySeatSwitchRequest dto, bool isAll, CancellationToken cancellationToken);
         Task<List<TrCallHourDto>> GetCallHourListAsync(BiQueryHourCallDto dto, CancellationToken cancellationToken);
         Task<TotalData<BiSeatSwitchDto>> GetCallListAsync(QueryCallListDto dto, CancellationToken cancellationToken);
         Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, CancellationToken cancellationToken);
@@ -76,7 +76,7 @@ namespace Hotline.Application.StatisticalReport
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        Task<List<QueryCallOutDateStatisticsDetailResp>> QueryCallOutDateStatisticsDetail(QueryCallDateStatisticsDetailDto dto,List<string> enterpriseTels);
+        Task<List<QueryCallOutDateStatisticsDetailResp>> QueryCallOutDateStatisticsDetail(QueryCallDateStatisticsDetailDto dto, List<string> enterpriseTels);
 
         /// <summary>
         /// 坐席月接通率统计

+ 2 - 2
src/Hotline.Repository.SqlSugar/Extensions/SqlSugarStartupExtensions.cs

@@ -230,8 +230,8 @@ namespace Hotline.Repository.SqlSugar.Extensions
                 ////获取原生SQL推荐 5.1.4.63  性能OK
                 //Log.Information(UtilMethods.GetNativeSql(sql, pars));
 
-                Log.Information("Sql: {0}", sql);
-                Log.Information("SqlParameters: {0}", string.Join(',', pars.Select(d => d.Value)));
+                //Log.Information("Sql: {0}", sql);
+                //Log.Information("SqlParameters: {0}", string.Join(',', pars.Select(d => d.Value)));
             };
             db.Aop.OnError = (exp) =>//SQL报错
             {

+ 16 - 0
src/Hotline.Share/Dtos/JudicialManagement/EnforcementOrderListDto.cs

@@ -1,5 +1,6 @@
 using Hotline.Share.Enums.Order;
 using System.Diagnostics.Metrics;
+using XF.Utility.EnumExtensions;
 
 namespace Hotline.Share.Dtos.JudicialManagement
 {
@@ -229,6 +230,21 @@ namespace Hotline.Share.Dtos.JudicialManagement
             return $"{Province}{City}{County}";
         }
 
+        /// <summary>
+        /// 个案类型
+        /// </summary>
+        public ECaseType? CaseType { get; set; }
+
+        /// <summary>
+        /// 个案类型
+        /// </summary>
+        public string CaseTypeDesc
+        {
+            get
+            {
+                return CaseType?.GetDescription()??string.Empty;
+            }
+        }
     }
 
     public class EnforcementOrgSatisfactionOrderListDto : EnforcementOrderListDto

+ 36 - 1
src/Hotline.Share/Dtos/JudicialManagement/JudicialManagementAddOrderDto.cs

@@ -2,6 +2,8 @@
 using Hotline.Share.Enums.JudicialManagement;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Settings;
+using System.ComponentModel;
+using XF.Utility.EnumExtensions;
 
 namespace Hotline.Share.Dtos.JudicialManagement
 {
@@ -95,7 +97,24 @@ namespace Hotline.Share.Dtos.JudicialManagement
         /// <summary>
         /// 执法部门
         /// </summary>
-        public List<Kv> LawEnforcementAgencies { get; set; }
+        public List<Kv> EnforcementOrdersHandler { get; set; }
+
+        public string EnforcementOrdersHandlerText => GetText();
+
+        public string GetText()
+        {
+            string strOrgName = "";
+            if (EnforcementOrdersHandler != null && EnforcementOrdersHandler.Count > 0)
+            {
+                foreach (var item in EnforcementOrdersHandler)
+                {
+                    strOrgName += item.Key + ",";
+                }
+                if (!string.IsNullOrEmpty(strOrgName))
+                    strOrgName = strOrgName.Substring(0, strOrgName.Length - 1);
+            }
+            return strOrgName;
+        }
     }
 
     /// <summary>
@@ -251,6 +270,22 @@ namespace Hotline.Share.Dtos.JudicialManagement
         {
             return $"{Province}{City}{County}{Town}";
         }
+
+        /// <summary>
+        /// 个案类型
+        /// </summary>
+        public ECaseType? CaseType { get; set; }
+
+        /// <summary>
+        /// 个案类型
+        /// </summary>
+        public string CaseTypeDesc
+        {
+            get
+            {
+                return CaseType?.GetDescription() ?? string.Empty;
+            }
+        }
     }
 
     public class AssociatedLawEnforcementAgenciesDto

+ 62 - 44
src/Hotline.Share/Dtos/Order/OrderBiDto.cs

@@ -1570,6 +1570,11 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public string AuditName { get; set; }
 
+        /// <summary>
+        /// 节点名称
+        /// </summary>
+        public string StepName { get; set; }
+
         /// <summary>
         /// 审批数量
         /// </summary>
@@ -1712,6 +1717,19 @@ namespace Hotline.Share.Dtos.Order
         public double Chain => PreviousCount == 0 ? 0 : Math.Round((SumCount / (double)PreviousCount) * 100, 2);
     }
 
+    public class AreaSubordinateReportRes
+    {
+        /// <summary>
+        /// 区域名称
+        /// </summary>
+        public string AreaName { get; set; }
+
+        /// <summary>
+        /// 分类统计
+        /// </summary>
+        public int SumCount { get; set; }
+    }
+
     public class OrgSendBackAuditListVo
     {
         public string OrgId { get; set; }
@@ -1721,64 +1739,64 @@ namespace Hotline.Share.Dtos.Order
         public int Num { get; set; }
     }
 
-    public class SeatSendBackStatisticsVo 
+    public class SeatSendBackStatisticsVo
     {
         /// <summary>
         /// 用户Id
         /// </summary>
         public string UserId { get; set; }
 
-		/// <summary>
-		/// 姓名
-		/// </summary>
-		public string UserName { get; set; }
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        public string UserName { get; set; }
 
-		/// <summary>
-		/// 派单件总量件数
-		/// </summary>
-		public int SendOrderNum { get; set; }
+        /// <summary>
+        /// 派单件总量件数
+        /// </summary>
+        public int SendOrderNum { get; set; }
 
-		/// <summary>
-		/// 派单件退办总量件数
-		/// </summary>
-		public int SendOrderBackNum { get; set; }
+        /// <summary>
+        /// 派单件退办总量件数
+        /// </summary>
+        public int SendOrderBackNum { get; set; }
 
         public string SendOrderBackRate => GetSendOrderBackRate();
-		public string GetSendOrderBackRate()
-		{
-			if (SendOrderNum == 0 || SendOrderBackNum == 0)
-			{
-				return "0.000%";
-			}
-			return Math.Round((SendOrderBackNum / (double)SendOrderNum) * 100, 2) + "%";
-		}
-		/// <summary>
-		/// 派单件退办总量次数
-		/// </summary>
-		public int SendOrderBackNumber { get; set; }
+        public string GetSendOrderBackRate()
+        {
+            if (SendOrderNum == 0 || SendOrderBackNum == 0)
+            {
+                return "0.000%";
+            }
+            return Math.Round((SendOrderBackNum / (double)SendOrderNum) * 100, 2) + "%";
+        }
+        /// <summary>
+        /// 派单件退办总量次数
+        /// </summary>
+        public int SendOrderBackNumber { get; set; }
 
         /// <summary>
         /// 中心归档件总量
         /// </summary>
         public int CentreFileNum { get; set; }
 
-		/// <summary>
-		/// 中心归档件退回件数
-		/// </summary>
-		public int CentreFileBackNum { get; set; }
-
-		public string CentreFileBackRate => GetCentreFileBackRate();
-		public string GetCentreFileBackRate()
-		{
-			if (CentreFileNum == 0 || CentreFileBackNum == 0)
-			{
-				return "0.000%";
-			}
-			return Math.Round((CentreFileBackNum / (double)CentreFileNum) * 100, 2) + "%";
-		}
-		/// <summary>
-		/// 中心归档件退回次数
-		/// </summary>
-		public int CentreFileBackNumber { get; set; }
-	}
+        /// <summary>
+        /// 中心归档件退回件数
+        /// </summary>
+        public int CentreFileBackNum { get; set; }
+
+        public string CentreFileBackRate => GetCentreFileBackRate();
+        public string GetCentreFileBackRate()
+        {
+            if (CentreFileNum == 0 || CentreFileBackNum == 0)
+            {
+                return "0.000%";
+            }
+            return Math.Round((CentreFileBackNum / (double)CentreFileNum) * 100, 2) + "%";
+        }
+        /// <summary>
+        /// 中心归档件退回次数
+        /// </summary>
+        public int CentreFileBackNumber { get; set; }
+    }
 }

+ 155 - 90
src/Hotline.Share/Dtos/Order/OrderFinalityDto.cs

@@ -1,4 +1,5 @@
-using Hotline.Share.Requests;
+using Hotline.Share.Enums.Order;
+using Hotline.Share.Requests;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -7,93 +8,157 @@ using System.Threading.Tasks;
 
 namespace Hotline.Share.Dtos.Order
 {
-	public class OrderFinalityDto : OrderFinalityBaseDto
-	{
-		/// <summary>
-		/// 工单ID
-		/// </summary>
-		public string OrderId { get; set; }
-
-		/// <summary>
-		/// 
-		/// </summary>
-		public OrderDto Order { get; set; }
-	}
-
-	public class OrderFinalityAddDto
-	{
-
-		/// <summary>
-		/// 工单ID
-		/// </summary>
-		public List<OrdersFinalityAddDto> OrderIds { get; set; }
-	}
-	public class OrdersFinalityAddDto
-	{
-
-		public string OrderId { get; set; }
-	}
-
-	public class OrderFinalityDeleteDto
-	{
-		public List<string> Ids { get; set; }
-	}
-
-	public class OrderFinalityUpdateDto : OrderFinalityAddDto
-	{
-		public string Id { get; set; }
-	}
-
-	public record OrderFinalityListDto : PagedKeywordRequest
-	{
-		/// <summary>
-		/// 标题
-		/// </summary>
-		public string? Title { get; set; }
-
-		/// <summary>
-		/// 编号
-		/// </summary>
-		public string? No { get; set; }
-
-		/// <summary>
-		/// 是否为省工单
-		/// </summary>
-		public bool? IsProvince { get; set; }
-
-	}
-	public class OrderFinalityBaseDto
-	{
-		public DateTime? LastModificationTime { get; set; }
-
-		public bool IsDeleted { get; set; }
-
-		/// <summary>
-		/// 删除时间
-		/// </summary>
-		public DateTime? DeletionTime { get; set; }
-
-
-		/// <summary>
-		/// 创建时间
-		/// </summary>
-		public DateTime CreationTime { get; set; }
-
-		public string Id { get; set; }
-
-		/// <summary>
-		/// 组织Id
-		/// </summary>
-		public string? CreatorOrgId { get; set; }
-
-
-		public string? CreatorOrgName { get; set; }
-
-		/// <summary>
-		/// 创建人
-		/// </summary>
-		public string? CreatorId { get; set; }
-
-		public string? CreatorName { get; set; }
-	}
+    public class OrderFinalityDto : OrderFinalityBaseDto
+    {
+        /// <summary>
+        /// 工单ID
+        /// </summary>
+        public string OrderId { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public OrderDto Order { get; set; }
+    }
+
+    public class OrderFinalityAddDto
+    {
+
+        /// <summary>
+        /// 工单ID
+        /// </summary>
+        public List<OrdersFinalityAddDto> OrderIds { get; set; }
+    }
+    public class OrdersFinalityAddDto
+    {
+
+        public string OrderId { get; set; }
+    }
+
+    public class OrderFinalityDeleteDto
+    {
+        public List<string> Ids { get; set; }
+    }
+
+    public class OrderFinalityUpdateDto : OrderFinalityAddDto
+    {
+        public string Id { get; set; }
+    }
+
+    public record OrderFinalityListDto : PagedKeywordRequest
+    {
+        /// <summary>
+        /// 编号
+        /// </summary>
+        public string? No { get; set; }
+
+        /// <summary>
+        /// 工单状态
+        /// </summary>
+        public EOrderStatus? Status { get; set; }
+
+        /// <summary>
+        /// 来源渠道
+        /// </summary>
+        public string? Channel { get; set; }
+
+        /// <summary>
+        /// 当前节点
+        /// </summary>
+        public string? CurrentStepCode { get; set; }
+
+        /// <summary>
+        /// 标题
+        /// </summary>
+        public string? Title { get; set; }
+
+        /// <summary>
+        /// 受理时间(工单创建时间)
+        /// </summary>
+        public DateTime? CreationTimeStart { get; set; }
+        public DateTime? CreationTimeEnd { get; set; }
+
+        /// <summary>
+        /// 设置人
+        /// </summary>
+        public string? CreatorName { get; set; }
+
+        /// <summary>
+        /// 设置时间
+        /// </summary>
+        public DateTime? SetCreationTimeStart { get; set; }
+        public DateTime? SetCreationTimeEnd { get; set; }
+
+        /// <summary>
+        /// 期满时间
+        /// </summary>
+        public DateTime? ExpiredTimeStart { get; set; }
+        public DateTime? ExpiredTimeEnd { get; set; }
+
+        /// <summary>
+        /// 受理类型
+        /// </summary>
+        public string? AcceptTypeCode { get; set; }
+
+        /// <summary>
+        /// 热点分类关键词
+        /// </summary>
+        public string? Hotspot { get; set; }
+
+        /// <summary>
+        /// 接办部门
+        /// </summary>
+        public string? CurrentHandleOrgName { get; set; }
+
+        /// <summary>
+        /// 接办时间
+        /// </summary>
+        public DateTime? CurrentHandleTimeStart { get; set; }
+        public DateTime? CurrentHandleTimeEnd { get; set; }
+
+        /// <summary>
+        /// 办结时间
+        /// </summary>
+        public DateTime? FiledTimeStart { get; set; }
+        public DateTime? FiledTimeEnd { get; set; }
+
+        /// <summary>
+        /// 省工单
+        /// </summary>
+        public bool? IsProvinceOrder { get; set; }
+    }
+    public class OrderFinalityBaseDto
+    {
+        public DateTime? LastModificationTime { get; set; }
+
+        public bool IsDeleted { get; set; }
+
+        /// <summary>
+        /// 删除时间
+        /// </summary>
+        public DateTime? DeletionTime { get; set; }
+
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime CreationTime { get; set; }
+
+        public string Id { get; set; }
+
+        /// <summary>
+        /// 组织Id
+        /// </summary>
+        public string? CreatorOrgId { get; set; }
+
+
+        public string? CreatorOrgName { get; set; }
+
+        /// <summary>
+        /// 创建人
+        /// </summary>
+        public string? CreatorId { get; set; }
+
+        public string? CreatorName { get; set; }
+    }
 }

+ 36 - 1
src/Hotline.Share/Dtos/Order/OrderSecondaryHandlingDto.cs

@@ -207,5 +207,40 @@ namespace Hotline.Share.Dtos.Order
 		/// </summary>
 		public string? Title { get; set;}
 
-	}
+        /// <summary>
+        /// 来源渠道
+        /// </summary>
+        public string? Channel { get; set; }
+
+        /// <summary>
+        /// 重提办理
+        /// </summary>
+        public int? SendBack { get; set; }
+
+        /// <summary>
+        /// 受理类型
+        /// </summary>
+        public string? AcceptTypeCode { get; set; }
+
+        /// <summary>
+        /// 热点分类关键词
+        /// </summary>
+        public string? Hotspot { get; set; }
+
+        /// <summary>
+        /// 申请人
+        /// </summary>
+        public string? ApplyName { get; set; }
+
+        /// <summary>
+        /// 申请部门
+        /// </summary>
+        public string? ApplyOrgName { get; set; }
+
+        /// <summary>
+        /// 申请时间
+        /// </summary>
+        public DateTime? ApplyTimeStart { get; set; }
+        public DateTime? ApplyTimeEnd { get; set; }
+    }
 }

+ 305 - 25
src/Hotline.Share/Dtos/Order/QueryOrderDto.cs

@@ -570,8 +570,6 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public bool? IsApply { get; set; }
 
-        public EDelayState? DelayState { get; set; }
-
         /// <summary>
         /// 延期状态快捷查询
         /// </summary>
@@ -593,11 +591,6 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public string? ActualHandlerName { get; set; }
 
-        /// <summary>
-        /// 一级部门
-        /// </summary>
-		public string? OrgLevelOneName { get; set; }
-
         /// <summary>
         /// 延期申请时间
         /// </summary>
@@ -609,14 +602,54 @@ namespace Hotline.Share.Dtos.Order
         public DateTime? EndCreationTime { get; set; }
 
         /// <summary>
-        /// 受理类型
+        /// 期满时间
         /// </summary>
-        public string? AcceptType { get; set; }
+        public DateTime? ExpiredTimeStart { get; set; }
+        public DateTime? ExpiredTimeEnd { get; set; }
 
         /// <summary>
-        /// 热点分类关键词
+        /// 延期申请人
         /// </summary>
-        public string? Hotspot { get; set; }
+        public string? DelayApplyName { get; set; }
+
+        /// <summary>
+        /// 延期申请部门
+        /// </summary>
+        public string? DelayApplyOrgName { get; set; }
+
+        /// <summary>
+        /// 是否自动延期
+        /// </summary>
+        public bool? IsAutomaticDelay { get; set; }
+
+
+
+
+
+        /// <summary>
+        /// 工单编码
+        /// </summary>
+        public string? No { get; set; }
+
+        /// <summary>
+        /// 省工单
+        /// </summary>
+        public bool? IsProvinceOrder { get; set; }
+
+        /// <summary>
+        /// 工单标题
+        /// </summary>
+        public string? Title { get; set; }
+
+        /// <summary>
+        /// 延期审批状态
+        /// </summary>
+        public EDelayState? DelayState { get; set; }
+
+        /// <summary>
+        /// 来源渠道
+        /// </summary>
+        public string? Channel { get; set; }
 
         /// <summary>
         /// 受理时间(工单创建时间)
@@ -625,30 +658,84 @@ namespace Hotline.Share.Dtos.Order
         public DateTime? CreationTimeEnd { get; set; }
 
         /// <summary>
-        /// 期满时间
+        /// 受理人
         /// </summary>
-        public DateTime? ExpiredTimeStart { get; set; }
-        public DateTime? ExpiredTimeEnd { get; set; }
+        public string? AcceptorName { get; set; }
 
         /// <summary>
-        /// 来源渠道
+        /// 热点分类关键词
         /// </summary>
-        public string? Channel { get; set; }
+        public string? Hotspot { get; set; }
+
+
+        /// <summary>
+        /// 受理类型
+        /// </summary>
+        public string? AcceptType { get; set; }
+
+        /// <summary>
+        /// 受理类型
+        /// </summary>
+        public string? AcceptTypeCode { get; set; }
+
+        /// <summary>
+        /// 一级部门
+        /// </summary>
+        public string? OrgLevelOneName { get; set; }
+
+        /// <summary>
+        /// 接办部门
+        /// </summary>
+        public string? CurrentHandleOrgName { get; set; }
+
+        /// <summary>
+        /// 接办时间
+        /// </summary>
+        public DateTime? CurrentHandleTimeStart { get; set; }
+        public DateTime? CurrentHandleTimeEnd { get; set; }
+
+        /// <summary>
+        /// 延期申请时间
+        /// </summary>
+        public DateTime? ApplyTimeStart { get; set; }
+        public DateTime? ApplyTimeEnd { get; set; }
 
         /// <summary>
         /// 延期申请人
         /// </summary>
-        public string? DelayApplyName { get; set; }
+        public string? ApplyName { get; set; }
 
         /// <summary>
         /// 延期申请部门
         /// </summary>
-        public string? DelayApplyOrgName { get; set; }
+        public string? ApplyOrgName { get; set; }
 
         /// <summary>
-        /// 是否自动延期
+        /// 延期申请时限
         /// </summary>
-        public bool? IsAutomaticDelay { get; set; }
+        public int? DelayNum { get; set; }
+
+        /// <summary>
+        /// 延期申请单位
+        /// </summary>
+        public ETimeType? DelayUnit { get; set; }
+
+        /// <summary>
+        /// 工单状态
+        /// </summary>
+        public EOrderStatus? Status { get; set; }
+
+        /// <summary>
+        /// 申请理由
+        /// </summary>
+        public string? DelayReason { get; set; }
+
+        /// <summary>
+        /// 申请前期满时间
+        /// </summary>
+        public DateTime? BeforeDelayStart { get; set; }
+        public DateTime? BeforeDelayEnd { get; set; }
+
     }
 
     public record ApplySuperviseDto
@@ -663,8 +750,111 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public int? SuperviseState { get; set; }
 
+
+        /// <summary>
+        /// 工单编码
+        /// </summary>
+        public string? No { get; set; }
+
+        /// <summary>
+        /// 省工单
+        /// </summary>
+        public bool? IsProvinceOrder { get; set; }
+
+        /// <summary>
+        /// 工单标题
+        /// </summary>
+        public string? Title { get; set; }
+
+        /// <summary>
+        /// 来源渠道
+        /// </summary>
+        public string? Channel { get; set; }
+
+        /// <summary>
+        /// 工单状态
+        /// </summary>
+        public EOrderStatus? Status { get; set; }
+
+        /// <summary>
+        /// 受理类型
+        /// </summary>
+        public string? AcceptTypeCode { get; set; }
+
+        /// <summary>
+        /// 热点分类关键词
+        /// </summary>
+        public string? Hotspot { get; set; }
+
+        /// <summary>
+        /// 受理人
+        /// </summary>
+        public string? AcceptorName { get; set; }
+
+        /// <summary>
+        /// 接办部门
+        /// </summary>
+        public string? CurrentHandleOrgName { get; set; }
+
+        /// <summary>
+        /// 受理时间(工单创建时间)
+        /// </summary>
         public DateTime? CreationTimeStart { get; set; }
         public DateTime? CreationTimeEnd { get; set; }
+
+        /// <summary>
+        /// 期满时间
+        /// </summary>
+        public DateTime? ExpiredTimeStart { get; set; }
+        public DateTime? ExpiredTimeEnd { get; set; }
+
+        /// <summary>
+        /// 督办时间
+        /// </summary>
+        public DateTime? SuperviseTimeStart { get; set; }
+        public DateTime? SuperviseTimeEnd { get; set; }
+
+        /// <summary>
+        /// 督办回复时限
+        /// </summary>
+        public DateTime? ReplyLimitTimeStart { get; set; }
+        public DateTime? ReplyLimitTimeEnd { get; set; }
+
+        /// <summary>
+        /// 督办回复时间
+        /// </summary>
+        public DateTime? ReplyTimeStart { get; set; }
+        public DateTime? ReplyTimeEnd { get; set; }
+
+        /// <summary>
+        /// 督办回复内容
+        /// </summary>
+        public string? ReplyContent { get; set; }
+
+        /// <summary>
+        /// 督办人
+        /// </summary>
+        public string? CrUser { get; set; }
+
+        /// <summary>
+        /// 督办部门
+        /// </summary>
+        public string? LaunchOrgName { get; set; }
+
+        /// <summary>
+        /// 被督办部门
+        /// </summary>
+        public string? OrgName { get; set; }
+
+        /// <summary>
+        /// 督办意见
+        /// </summary>
+        public string? ApplyContent { get; set; }
+
+        /// 督办签收时间
+        /// </summary>
+        public DateTime? SignTimeStart { get; set; }
+        public DateTime? SignTimeEnd { get; set; }
     }
 
     public record ScreenListDto : PagedKeywordRequest
@@ -973,6 +1163,10 @@ namespace Hotline.Share.Dtos.Order
         /// 回复状态
         /// </summary>
         public int? UrgeState { get; set; }
+
+        /// <summary>
+        /// 受理时间(工单创建时间)
+        /// </summary>
         public DateTime? CreationTimeStart { get; set; }
         public DateTime? CreationTimeEnd { get; set; }
 
@@ -990,6 +1184,91 @@ namespace Hotline.Share.Dtos.Order
         /// 当前办理节点
         /// </summary>
         public string? CurrentStepCode { get; set; }
+
+
+        /// <summary>
+        /// 工单编码
+        /// </summary>
+        public string? No { get; set; }
+
+        /// <summary>
+        /// 省工单
+        /// </summary>
+        public bool? IsProvinceOrder { get; set; }
+
+        /// <summary>
+        /// 来源渠道
+        /// </summary>
+        public string? Channel { get; set; }
+
+        /// <summary>
+        /// 期满时间
+        /// </summary>
+        public DateTime? ExpiredTimeStart { get; set; }
+        public DateTime? ExpiredTimeEnd { get; set; }
+
+        /// <summary>
+        /// 工单状态
+        /// </summary>
+        public EOrderStatus? Status { get; set; }
+
+        /// <summary>
+        /// 工单标题
+        /// </summary>
+        public string? Title { get; set; }
+
+        /// <summary>
+        /// 接办部门
+        /// </summary>
+        public string? CurrentHandleOrgName { get; set; }
+
+        /// <summary>
+        /// 接办时间
+        /// </summary>
+        public DateTime? CurrentHandleTimeStart { get; set; }
+        public DateTime? CurrentHandleTimeEnd { get; set; }
+
+        /// <summary>
+        /// 热点分类关键词
+        /// </summary>
+        public string? Hotspot { get; set; }
+
+        /// <summary>
+        /// 受理类型
+        /// </summary>
+        public string? AcceptTypeCode { get; set; }
+
+        /// <summary>
+        /// 催办人
+        /// </summary>
+        public string? CrUser { get; set; }
+
+        /// <summary>
+        /// 催办部门
+        /// </summary>
+        public string? CreatorOrgName { get; set; }
+
+        /// <summary>
+        /// 催办时间
+        /// </summary>
+        public DateTime? CrTimeStart { get; set; }
+        public DateTime? CrTimeEnd { get; set; }
+
+        /// <summary>
+        /// 被催办部门
+        /// </summary>
+        public string? OrgName { get; set; }
+
+        /// <summary>
+        /// 催办内容
+        /// </summary>
+        public string? ApplyContent { get; set; }
+
+        /// <summary>
+        /// 催办状态
+        /// </summary>
+        public int? CrState { get; set; }
+
     }
 
     public class QueryRepeatableEventDto
@@ -1066,15 +1345,16 @@ namespace Hotline.Share.Dtos.Order
     }
 
 
-    public record SeatSendBackStatisticsDetail : PagedKeywordRequest {
+    public record SeatSendBackStatisticsDetail : PagedKeywordRequest
+    {
 
 
         public string UserId { get; set; }
-		public string StatisticsType { get; set; }
+        public string StatisticsType { get; set; }
 
-		public string? No { get; set; }
+        public string? No { get; set; }
 
-		public string? Title { get; set; }
+        public string? Title { get; set; }
 
 
         /// <summary>
@@ -1096,7 +1376,7 @@ namespace Hotline.Share.Dtos.Order
     }
 
 
-	public enum EPublicState
+    public enum EPublicState
     {
         /// <summary>
         /// 全部

+ 261 - 200
src/Hotline.Share/Dtos/Order/SendBackDto.cs

@@ -12,207 +12,268 @@ using XF.Utility.EnumExtensions;
 
 namespace Hotline.Share.Dtos.Order
 {
-	public class AuditSendBackDto
-	{
-		public string Id { get; set; }
-
-		/// <summary>
-		///  审核结果
-		/// </summary>
-		public ESendBackAuditState State { get; set; }
-
-		/// <summary>
-		/// 审核意见
-		/// </summary>
-		public string? AuditContent { get; set; }
-
-
-			/// <summary>
-		/// 是否允许再次退回
-		/// </summary>
-		public bool? IsReturnAgain { get; set; }
-
-	}
-
-	public class BatchAuditSendBackDto : AuditSendBackDto {
-		public List<string> Ids { get; set; }
-	}
-	public class SendBackDto : SendBackBaseDto
-	{
-		/// <summary>
-		/// 工单ID
-		/// </summary>
-		public string OrderId { get; set; }
-
-
-		/// <summary>
-		/// 退回原因
-		/// </summary>
-		public string? Content { get; set; }
-
-		/// <summary>
-		/// 审批意见
-		/// </summary>
-		public string? AuditContent { get; set; }
-
-		/// <summary>
-		/// 工单
-		/// </summary>
-		public OrderDto Order { get; set; }
-
-		/// <summary>
-		/// 退回数据
-		/// </summary>
-		public PreviousWorkflowDto SendBackData { get; set; }
-
-		/// <summary>
-		/// 审批人ID
-		/// </summary>
-		public string? AuditId { get; set; }
-
-		public string? AuditUser { get; set; }
-
-
-		/// <summary>
-		/// 审批时间
-		/// </summary>
-		public DateTime? AuditTime { get; set; }
-
-		/// <summary>
-		/// 申请部门ID
-		/// </summary>
-		public string ApplyOrgId { get; set; }
-
-		/// <summary>
-		/// 申请部门名称
-		/// </summary>
-		public string ApplyOrgName { get; set; }
-
-		/// <summary>
-		/// 退回部门ID
-		/// </summary>
-		public string SendBackOrgId { get; set; }
-
-		/// <summary>
-		/// 退回部门名称
-		/// </summary>
-		public string SendBackOrgName { get; set; }
-
-		/// <summary>
-		///  审核结果  0  待审核  1 审核通过  2 审核不通过
-		/// </summary>
-		public ESendBackAuditState State { get; set; }
-
-		public string StateText => State.GetDescription();
-		/// <summary>
-		/// 退回节点名称
-		/// </summary>
-		public string? SendBackStepName { get; set; }
-
-		/// <summary>
-		/// 退回节点创建时间
-		/// </summary>
-		public DateTime? WorkflowStepSendBackCrTime { get; set; }
-
-		/// <summary>
-		///  退回时差
-		/// </summary>
-		public double SendBackTimeDifference => GetSendBackTimeDifference();
-
-		public double GetSendBackTimeDifference() {
-			if (WorkflowStepSendBackCrTime.HasValue)
-			{
-				TimeSpan? timeDifference = CreationTime - WorkflowStepSendBackCrTime;
-				return Math.Round(timeDifference.Value.TotalMinutes / 60, 1);
-			}
-			return 0;
-		}
-
-		public bool IsReturnAgainShow => ApplyOrgId != "001" && SendBackOrgId == "001";
-		/// <summary>
-		/// 附件列表
-		/// </summary>
-		public List<FileDto> Files { get; set; } = new();
-	}
-	public class SendBackBaseDto
-	{
-		public DateTime? LastModificationTime { get; set; }
-
-		public bool IsDeleted { get; set; }
-
-		/// <summary>
-		/// 删除时间
-		/// </summary>
-		public DateTime? DeletionTime { get; set; }
-
-
-		/// <summary>
-		/// 创建时间
-		/// </summary>
-		public DateTime CreationTime { get; set; }
-
-		public string Id { get; set; }
-
-		/// <summary>
-		/// 组织Id
-		/// </summary>
-		public string? CreatorOrgId { get; set; }
-
-
-		public string? CreatorOrgName { get; set; }
-
-		/// <summary>
-		/// 创建人
-		/// </summary>
-		public string? CreatorId { get; set; }
-
-		public string? CreatorName { get; set; }
-	}
-	public record SendBackListDto : PagedKeywordRequest
-	{
-		/// <summary>
-		/// </summary>
-		public ESendBackAuditState? State { get; set; }
-
-		/// <summary>
-		/// 1 待办  2 已办 3全部
-		/// </summary>
-		public int AuditState { get; set; }
-
-		/// <summary>
-		/// 0 全部  1 我的
-		/// </summary>
-		public int? DataScope { get; set; }
-
-		/// <summary>
-		/// 工单标题
-		/// </summary>
-		public string Title { get; set; }
-
-		/// <summary>
-		/// 工单编号
-		/// </summary>
-		public string No { get; set; }
-
-		/// <summary>
-		/// 受理类型
-		/// </summary>
-		public string? AcceptTypeCode { get; set; }
-
-		/// <summary>
-		/// 申请部门
-		/// </summary>
-		public string? OrgName { get; set; }
-
-		/// <summary>
-		/// 期满时间开始
-		/// </summary>
-		public DateTime? ExpiredTimeStart { get; set; }
-
-		/// <summary>
-		/// 期满时间结束
-		/// </summary>
+    public class AuditSendBackDto
+    {
+        public string Id { get; set; }
+
+        /// <summary>
+        ///  审核结果
+        /// </summary>
+        public ESendBackAuditState State { get; set; }
+
+        /// <summary>
+        /// 审核意见
+        /// </summary>
+        public string? AuditContent { get; set; }
+
+
+        /// <summary>
+        /// 是否允许再次退回
+        /// </summary>
+        public bool? IsReturnAgain { get; set; }
+
+    }
+
+    public class BatchAuditSendBackDto : AuditSendBackDto
+    {
+        public List<string> Ids { get; set; }
+    }
+    public class SendBackDto : SendBackBaseDto
+    {
+        /// <summary>
+        /// 工单ID
+        /// </summary>
+        public string OrderId { get; set; }
+
+
+        /// <summary>
+        /// 退回原因
+        /// </summary>
+        public string? Content { get; set; }
+
+        /// <summary>
+        /// 审批意见
+        /// </summary>
+        public string? AuditContent { get; set; }
+
+        /// <summary>
+        /// 工单
+        /// </summary>
+        public OrderDto Order { get; set; }
+
+        /// <summary>
+        /// 退回数据
+        /// </summary>
+        public PreviousWorkflowDto SendBackData { get; set; }
+
+        /// <summary>
+        /// 审批人ID
+        /// </summary>
+        public string? AuditId { get; set; }
+
+        public string? AuditUser { get; set; }
+
+
+        /// <summary>
+        /// 审批时间
+        /// </summary>
+        public DateTime? AuditTime { get; set; }
+
+        /// <summary>
+        /// 申请部门ID
+        /// </summary>
+        public string ApplyOrgId { get; set; }
+
+        /// <summary>
+        /// 申请部门名称
+        /// </summary>
+        public string ApplyOrgName { get; set; }
+
+        /// <summary>
+        /// 退回部门ID
+        /// </summary>
+        public string SendBackOrgId { get; set; }
+
+        /// <summary>
+        /// 退回部门名称
+        /// </summary>
+        public string SendBackOrgName { get; set; }
+
+        /// <summary>
+        ///  审核结果  0  待审核  1 审核通过  2 审核不通过
+        /// </summary>
+        public ESendBackAuditState State { get; set; }
+
+        public string StateText => State.GetDescription();
+        /// <summary>
+        /// 退回节点名称
+        /// </summary>
+        public string? SendBackStepName { get; set; }
+
+        /// <summary>
+        /// 退回节点创建时间
+        /// </summary>
+        public DateTime? WorkflowStepSendBackCrTime { get; set; }
+
+        /// <summary>
+        ///  退回时差
+        /// </summary>
+        public double SendBackTimeDifference => GetSendBackTimeDifference();
+
+        public double GetSendBackTimeDifference()
+        {
+            if (WorkflowStepSendBackCrTime.HasValue)
+            {
+                TimeSpan? timeDifference = CreationTime - WorkflowStepSendBackCrTime;
+                return Math.Round(timeDifference.Value.TotalMinutes / 60, 1);
+            }
+            return 0;
+        }
+
+        public bool IsReturnAgainShow => ApplyOrgId != "001" && SendBackOrgId == "001";
+        /// <summary>
+        /// 附件列表
+        /// </summary>
+        public List<FileDto> Files { get; set; } = new();
+    }
+    public class SendBackBaseDto
+    {
+        public DateTime? LastModificationTime { get; set; }
+
+        public bool IsDeleted { get; set; }
+
+        /// <summary>
+        /// 删除时间
+        /// </summary>
+        public DateTime? DeletionTime { get; set; }
+
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime CreationTime { get; set; }
+
+        public string Id { get; set; }
+
+        /// <summary>
+        /// 组织Id
+        /// </summary>
+        public string? CreatorOrgId { get; set; }
+
+
+        public string? CreatorOrgName { get; set; }
+
+        /// <summary>
+        /// 创建人
+        /// </summary>
+        public string? CreatorId { get; set; }
+
+        public string? CreatorName { get; set; }
+    }
+    public record SendBackListDto : PagedKeywordRequest
+    {
+        /// <summary>
+        /// </summary>
+        public ESendBackAuditState? State { get; set; }
+
+        /// <summary>
+        /// 1 待办  2 已办 3全部
+        /// </summary>
+        public int AuditState { get; set; }
+
+        /// <summary>
+        /// 0 全部  1 我的
+        /// </summary>
+        public int? DataScope { get; set; }
+
+        /// <summary>
+        /// 工单标题
+        /// </summary>
+        public string Title { get; set; }
+
+        /// <summary>
+        /// 工单编号
+        /// </summary>
+        public string No { get; set; }
+
+        /// <summary>
+        /// 受理类型
+        /// </summary>
+        public string? AcceptTypeCode { get; set; }
+
+        /// <summary>
+        /// 申请部门
+        /// </summary>
+        public string? ApplyOrgName { get; set; }
+
+        /// <summary>
+        /// 期满时间开始
+        /// </summary>
+        public DateTime? ExpiredTimeStart { get; set; }
+
+        /// <summary>
+        /// 期满时间结束
+        /// </summary>
         public DateTime? ExpiredTimeEnd { get; set; }
 
+        /// <summary>
+        /// 是否省工单
+        /// </summary>
+        public bool? IsProvinceOrder { get; set; }
+
+        /// <summary>
+        /// 来源渠道
+        /// </summary>
+        public string? Channel { get; set; }
+
+        /// <summary>
+        /// 受理类型
+        /// </summary>
+        public string? AcceptType { get; set; }
+
+        /// <summary>
+        /// 热点分类关键词
+        /// </summary>
+        public string? Hotspot { get; set; }
+
+        /// <summary>
+        /// 最近派单员
+        /// </summary>
+        public string? CenterToOrgHandlerName { get; set; }
+
+        /// <summary>
+        /// 退回节点
+        /// </summary>
+        public string? SendBackStepName { get; set; }
+
+        /// <summary>
+        /// 退回时差
+        /// </summary>
+        public int? SendBackTimeDifference { get; set; }
+
+        /// <summary>
+        /// 受理人
+        /// </summary>
+        public string? NameOrNo { get; set; }
+
+        /// <summary>
+        /// 一级部门
+        /// </summary>
+        public string? OrgLevelOneName { get; set; }
+
+        /// <summary>
+        /// 受理内容
+        /// </summary>
+        public string? Content { get; set; }
+
+        /// <summary>
+        /// 申请人
+        /// </summary>
+        public string? ApplyName { get; set; }
+
+        /// <summary>
+        /// 申请理由
+        /// </summary>
+        public string? Opinion { get; set; }
     }
 }

+ 5 - 0
src/Hotline.Share/Dtos/Push/MessagePagedDto.cs

@@ -54,6 +54,11 @@ namespace Hotline.Share.Dtos.Push
         /// 发送内容
         /// </summary>
         public string? SendContent { get; set;}
+
+        /// <summary>
+        /// 是否有回复
+        /// </summary>
+        public bool? IsSmsReply { get; set;}
     }
 
 

+ 5 - 0
src/Hotline.Share/Dtos/Push/PushReceiveMessageDto.cs

@@ -68,5 +68,10 @@ namespace Hotline.Share.Dtos.Push
         /// 发送失败原因等
         /// </summary>
         public string? Reason { get; set; }
+
+        /// <summary>
+        /// 手机号
+        /// </summary>
+        public string? TelNumber { get; set; }
     }
 }

+ 54 - 1
src/Hotline.Share/Dtos/Quality/QualityDto.cs

@@ -1,5 +1,6 @@
 
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Quality;
 using Hotline.Share.Requests;
 using XF.Utility.EnumExtensions;
@@ -239,7 +240,7 @@ namespace Hotline.Share.Dtos.Quality
         public EQualityState? State { get; set; }
 
         /// <summary>
-        /// 质检状态
+        /// 质检来源
         /// </summary>
         public EQualitySource? Source { get; set; }
         public DateTime? CreationTimeStart { get; set; }
@@ -259,6 +260,58 @@ namespace Hotline.Share.Dtos.Quality
         /// 工单编码
         /// </summary>
         public string? No { get; set; }
+
+        /// <summary>
+        /// 质检方式 true 智能质检 false 人工质检
+        /// </summary>
+        public bool? AiQuality { get; set; }
+
+        /// <summary>
+        /// 来源渠道
+        /// </summary>
+        public string? Channel { get; set; }
+
+        /// <summary>
+        /// 受理时间(工单创建时间)
+        /// </summary>
+        public DateTime? AcceptanceTimeStart { get; set; }
+        public DateTime? AcceptanceTimeEnd { get; set; }
+
+        /// <summary>
+        /// 工单状态
+        /// </summary>
+        public EOrderStatus? Status { get; set; }
+
+        /// <summary>
+        /// 受理类型
+        /// </summary>
+        public string? AcceptTypeCode { get; set; }
+
+        /// <summary>
+        /// 热点分类关键词
+        /// </summary>
+        public string? Hotspot { get; set; }
+
+        /// <summary>
+        /// 受理坐席名字或工号
+        /// </summary>
+        public string? NameOrNo { get; set; }
+
+        /// <summary>
+        /// 来电号码
+        /// </summary>
+        public string? FromPhone { get; set; }
+
+        /// <summary>
+        /// 质检人
+        /// </summary>
+        public string? UserName { get; set; }
+
+        /// <summary>
+        /// 质检时间
+        /// </summary>
+        public DateTime? QualityTimeStart { get; set; }
+        public DateTime? QualityTimeEnd { get; set; }
     }
 
     public class AiQualityXTDto

+ 167 - 134
src/Hotline.Share/Dtos/Quality/QualityItemDto.cs

@@ -9,138 +9,171 @@ using XF.Utility.EnumExtensions;
 
 namespace Hotline.Share.Dtos.Quality
 {
-	public class QualityItemAddDto
-	{
-		/// <summary>
-		/// 质检项目名称
-		/// </summary>
-		public string Name { get; set; }
-
-		/// <summary>
-		/// 质检项目描述
-		/// </summary>
-		public string? Describe { get; set; }
-
-		/// <summary>
-		/// 质检项目分组名称
-		/// </summary>
-		public string GroupingName { get; set; }
-
-		/// <summary>
-		/// 是否智能质检项目
-		/// </summary>
-		public int IsIntelligent { get; set; }
-
-		/// <summary>
-		/// 分值
-		/// </summary>
-		public int Grade { get; set; }
-
-		/// <summary>
-		/// 启禁用
-		/// </summary>
-		public int IsEnable { get; set; }
-	}
-	public class QualityItemDeleteDto
-	{
-		public string Id { get; set; }
-	}
-	public class QualityItemBatchDeleteDto
-	{
-		public List<string> Ids { get; set; }
-	}
-	public class QualityItemUpdateDto : QualityItemAddDto
-	{
-		public string Id { get; set; }
-	}
-	public record QualityItemListDto : PagedKeywordRequest
-	{
-		/// <summary>
-		/// 质检项目名称
-		/// </summary>
-		public string? Name { get; set; }
-
-		/// <summary>
-		/// 质检项目分组名称
-		/// </summary>
-		public string? GroupingName { get; set; }
-
-		/// <summary>
-		/// 启禁用
-		/// </summary>
-		public int? IsEnable { get; set; }
-	}
-	public class QualityItemBaseDto
-	{
-		public DateTime? LastModificationTime { get; set; }
-
-		public bool IsDeleted { get; set; }
-
-		/// <summary>
-		/// 删除时间
-		/// </summary>
-		public DateTime? DeletionTime { get; set; }
-
-
-		/// <summary>
-		/// 创建时间
-		/// </summary>
-		public DateTime CreationTime { get; set; }
-
-		public string Id { get; set; }
-
-		/// <summary>
-		/// 组织Id
-		/// </summary>
-		public string? CreatorOrgId { get; set; }
-
-
-		public string? CreatorOrgName { get; set; }
-
-		/// <summary>
-		/// 创建人
-		/// </summary>
-		public string? CreatorId { get; set; }
-
-		public string? CreatorName { get; set; }
-	}
-
-	public class QualityItemDto : QualityItemBaseDto
-	{
-		/// <summary>
-		/// 质检项目名称
-		/// </summary>
-		public string Name { get; set; }
-
-		/// <summary>
-		/// 质检项目描述
-		/// </summary>
-		public string? Describe { get; set; }
-
-		/// <summary>
-		/// 质检项目分组名称
-		/// </summary>
-		public string GroupingName { get; set; }
-
-		/// <summary>
-		/// 是否智能质检项目
-		/// </summary>
-		public int IsIntelligent { get; set; }
-
-		/// <summary>
-		/// 分值
-		/// </summary>
-		public int Grade { get; set; }
-
-		/// <summary>
-		/// 启禁用
-		/// </summary>
-		public int IsEnable { get; set; }
-
-		/// <summary>
-		/// 最近更新人
-		/// </summary>
-		public string? LastModificationName { get; set; }
-
-	}
+    public class QualityItemAddDto
+    {
+        /// <summary>
+        /// 质检项目名称
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 质检项目描述
+        /// </summary>
+        public string? Describe { get; set; }
+
+        /// <summary>
+        /// 质检项目分组名称
+        /// </summary>
+        public string GroupingName { get; set; }
+
+        /// <summary>
+        /// 是否智能质检项目
+        /// </summary>
+        public int IsIntelligent { get; set; }
+
+        /// <summary>
+        /// 分值
+        /// </summary>
+        public int Grade { get; set; }
+
+        /// <summary>
+        /// 启禁用
+        /// </summary>
+        public int IsEnable { get; set; }
+    }
+    public class QualityItemDeleteDto
+    {
+        public string Id { get; set; }
+    }
+    public class QualityItemBatchDeleteDto
+    {
+        public List<string> Ids { get; set; }
+    }
+    public class QualityItemUpdateDto : QualityItemAddDto
+    {
+        public string Id { get; set; }
+    }
+    public record QualityItemListDto : PagedKeywordRequest
+    {
+        /// <summary>
+        /// 质检项目名称
+        /// </summary>
+        public string? Name { get; set; }
+
+        /// <summary>
+        /// 质检项目分组名称
+        /// </summary>
+        public string? GroupingName { get; set; }
+
+        /// <summary>
+        /// 启禁用
+        /// </summary>
+        public int? IsEnable { get; set; }
+
+        /// <summary>
+        /// 质检项目描述
+        /// </summary>
+        public string? Describe { get; set; }
+
+        /// <summary>
+        /// 分值
+        /// </summary>
+        public int? MaxGrade { get; set; }
+        public int? MinGrade { get; set; }
+
+        /// <summary>
+        /// 创建人
+        /// </summary>
+        public string? CreatorName { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime? CreationTimeStart { get; set; }
+        public DateTime? CreationTimeEnd { get; set; }
+
+        /// <summary>
+        /// 更新人
+        /// </summary>
+        public string? LastModificationName { get; set; }
+
+        /// <summary>
+        /// 更新时间
+        /// </summary>
+        public DateTime? LastModificationTimeStart { get; set; }
+        public DateTime? LastModificationTimeEnd { get; set; }
+    }
+    public class QualityItemBaseDto
+    {
+        public DateTime? LastModificationTime { get; set; }
+
+        public bool IsDeleted { get; set; }
+
+        /// <summary>
+        /// 删除时间
+        /// </summary>
+        public DateTime? DeletionTime { get; set; }
+
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime CreationTime { get; set; }
+
+        public string Id { get; set; }
+
+        /// <summary>
+        /// 组织Id
+        /// </summary>
+        public string? CreatorOrgId { get; set; }
+
+
+        public string? CreatorOrgName { get; set; }
+
+        /// <summary>
+        /// 创建人
+        /// </summary>
+        public string? CreatorId { get; set; }
+
+        public string? CreatorName { get; set; }
+    }
+
+    public class QualityItemDto : QualityItemBaseDto
+    {
+        /// <summary>
+        /// 质检项目名称
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 质检项目描述
+        /// </summary>
+        public string? Describe { get; set; }
+
+        /// <summary>
+        /// 质检项目分组名称
+        /// </summary>
+        public string GroupingName { get; set; }
+
+        /// <summary>
+        /// 是否智能质检项目
+        /// </summary>
+        public int IsIntelligent { get; set; }
+
+        /// <summary>
+        /// 分值
+        /// </summary>
+        public int Grade { get; set; }
+
+        /// <summary>
+        /// 启禁用
+        /// </summary>
+        public int IsEnable { get; set; }
+
+        /// <summary>
+        /// 最近更新人
+        /// </summary>
+        public string? LastModificationName { get; set; }
+
+    }
 }

+ 23 - 1
src/Hotline.Share/Dtos/Quality/QualityTemplateDto.cs

@@ -62,7 +62,29 @@ namespace Hotline.Share.Dtos.Quality
 		/// 启禁用
 		/// </summary>
 		public int? IsEnable { get; set; }
-	}
+
+        /// <summary>
+        /// 创建人
+        /// </summary>
+        public string? CreatorName { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime? CreationTimeStart { get; set; }
+        public DateTime? CreationTimeEnd { get; set; }
+
+        /// <summary>
+        /// 更新人
+        /// </summary>
+        public string? LastModificationName { get; set; }
+
+        /// <summary>
+        /// 更新时间
+        /// </summary>
+        public DateTime? LastModificationTimeStart { get; set; }
+        public DateTime? LastModificationTimeEnd { get; set; }
+    }
 	public class TemplateBaseDto
 	{
 		public DateTime? LastModificationTime { get; set; }

+ 0 - 1
src/Hotline.Share/Dtos/Snapshot/PointsDto.cs

@@ -115,7 +115,6 @@ public class PointsRankUserDto
     /// </summary>
     public string UserName { get; set; }
 
-
     private string _phoneNumber;
     /// <summary>
     /// 联系电话

+ 2 - 2
src/Hotline.Share/Enums/Order/ECaseType.cs

@@ -12,9 +12,9 @@ namespace Hotline.Share.Enums.Order
         General=0,
 
         /// <summary>
-        /// 特别关注个案
+        /// 重点关注个案
         /// </summary>
-        [Description("特别关注个案")]
+        [Description("重点关注个案")]
         Special=1
     }
 }

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

@@ -1046,6 +1046,11 @@ public record OrderScreenAuditPagedRequest : PagedKeywordRequest
     /// </summary>
     public int? AuditType { get; set; }
 
+    /// <summary>
+    /// 节点名称
+    /// </summary>
+    public string? StepName { get; set; }
+
 }
 
 public record OrderCenterAcceptPagedRequest : PagedKeywordRequest
@@ -1736,4 +1741,32 @@ public class OnlineMassLineReportRequest
     public DateTime ChainStartTime { get; set; }
 
     public DateTime ChainEndTime { get; set; }
+}
+
+public record AreaSubordinateRequest
+{
+    /// <summary>
+    /// 开始时间
+    /// </summary>
+    public DateTime? StartTime { get; set; }
+
+    /// <summary>
+    /// 结束时间
+    /// </summary>
+    public DateTime? EndTime { get; set; }
+
+    /// <summary>
+    /// 0:全部 ,1:市民,2:企业
+    /// </summary>
+    public int? TypeId { get; set; }
+
+    /// <summary>
+    /// 上级区域Id
+    /// </summary>
+    public string? AreaCode { get; set; }
+
+    /// <summary>
+    /// 线路号
+    /// </summary>
+    public string? Line { get; set; }
 }

+ 7 - 1
src/Hotline/Caching/Interfaces/ISystemSettingCacheManager.cs

@@ -1,4 +1,5 @@
 using Hotline.Settings;
+using Hotline.Snapshot;
 
 namespace Hotline.Caching.Interfaces
 {
@@ -62,7 +63,7 @@ namespace Hotline.Caching.Interfaces
         /// 微信小程序Secret
         /// </summary>
         string WxOpenAppSecret { get; }
-        
+
         /// <summary>
         /// 微信小程序OpenId
         /// </summary>
@@ -104,6 +105,11 @@ namespace Hotline.Caching.Interfaces
         /// </summary>
         string TianQuanPostAcceptInfoApi { get; }
 
+        /// <summary>
+        /// 天阙接口请求方式
+        /// </summary>
+        ETianqueRequestMode TianQueRequestMode { get; }
+
         bool Snapshot { get; }
 
         /// <summary>

+ 13 - 0
src/Hotline/Caching/Services/SystemSettingCacheManager.cs

@@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
 using Newtonsoft.Json.Linq;
 using System.Reflection.Metadata.Ecma335;
+using Hotline.Snapshot;
 using XF.Domain.Cache;
 using XF.Domain.Dependency;
 using XF.Domain.Exceptions;
@@ -79,6 +80,14 @@ namespace Hotline.Caching.Services
 
                 try
                 {
+                    var targetType = typeof(T);
+                    if (targetType.IsEnum)
+                    {
+                        if (value is string strValue)
+                            return (T)Enum.Parse(targetType, strValue, ignoreCase: true);
+                        else
+                            return (T)Enum.ToObject(targetType, value);
+                    }
                     return (T)Convert.ChangeType(value, typeof(T));
                 }
                 catch (InvalidCastException e)
@@ -208,6 +217,10 @@ namespace Hotline.Caching.Services
         public string TianQuanPostAcceptInfoApi =>
             GetOrDefault("08dcd143-5f4b-477f-80e2-c2326d1d82e8", SettingConstants.TianQuanPostAcceptInfoApi, "天阙推送受理信息API接口地址", "http://10.0.188.11:6090/api/v1/test/accept/saveAcceptInfoApi", "测试: http://10.0.188.11:6090/api/v1/test/accept/saveAcceptInfoApi  正式: http://10.0.188.11:6090/api/v1/prod/accept/saveAcceptInfoApi");
 
+        public ETianqueRequestMode TianQueRequestMode =>
+            GetOrDefault("08dc941d-3344-420f-8c3a-fdb7a90d0948", SettingConstants.TianQueRequestMode, "天阙接口请求方式",
+                ETianqueRequestMode.ProEnvProUrl, "天阙接口请求方式");
+
         /// <summary>
         /// 随手拍功能开关
         /// </summary>

+ 11 - 3
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -402,16 +402,24 @@ namespace Hotline.FlowEngine.Workflows
                     }
                     else
                     {
-                        //todo 指派给配置的角色
-                        //dto.FlowAssignType = EFlowAssignType.Role;
-                        dto.NextHandlers.Add(new StepAssignInfo
+                        var orgid = nextStepDefine.BusinessType ==  EBusinessType.Seat ||
+									nextStepDefine.BusinessType == EBusinessType.Send ||
+									nextStepDefine.BusinessType == EBusinessType.CenterMonitor ||
+									nextStepDefine.BusinessType == EBusinessType.CenterLeader
+							? OrgSeedData.CenterId
+							: null;
+						//todo 指派给配置的角色
+						//dto.FlowAssignType = EFlowAssignType.Role;
+						dto.NextHandlers.Add(new StepAssignInfo
                         {
                             Key = handler.Key,
                             Value = handler.Value,
                             RoleId = handler.Key,
                             RoleName = handler.Value,
+                            OrgId = orgid,
                             FlowAssignType = EFlowAssignType.Role
                         });
+                       
                     }
                 }
             }

+ 1 - 1
src/Hotline/Hotline.csproj

@@ -15,7 +15,7 @@
     <PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
     <PackageReference Include="RestSharp" Version="110.2.0" />
     <PackageReference Include="SSH.NET" Version="2024.2.0" />
-    <PackageReference Include="XF.Utility.MQ" Version="1.0.9" />
+    <PackageReference Include="XF.Utility.MQ" Version="1.0.10" />
     <PackageReference Include="FluentValidation" Version="11.10.0" />
   </ItemGroup>
 

+ 3 - 2
src/Hotline/Orders/OrderDomainService.cs

@@ -567,9 +567,10 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
 
     public async Task<bool> SchedulingAtWork(string UserId) 
     {
-        var atWork =  await _schedulingRepository.Queryable()
+		var time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
+		var atWork =  await _schedulingRepository.Queryable()
 			.Includes(x => x.SchedulingUser)
-			.Where(x => x.SchedulingUser.UserId == UserId && x.WorkingTime <= DateTime.Now.TimeOfDay && x.OffDutyTime >= DateTime.Now.TimeOfDay && x.AtWork == true)
+			.Where(x => x.SchedulingUser.UserId == UserId && x.SchedulingTime == time && x.WorkingTime <= DateTime.Now.TimeOfDay && x.OffDutyTime >= DateTime.Now.TimeOfDay && x.AtWork == true)
 			.AnyAsync();
         return atWork;
 	}

+ 21 - 9
src/Hotline/Orders/OrderVisitDomainService.cs

@@ -75,18 +75,30 @@ public class OrderVisitDomainService : IOrderVisitDomainService, IScopeDependenc
     /// <returns></returns>
     public async Task UpdateSmsReplyAsync(MessageDto data)
     {
-        if (data.IsSmsReply == false || data.SmsReplyContent.IsNullOrEmpty()) return;
-
-        var orderVisits = await _orderVisitRepository.Queryable()
-            .Includes(m => m.Order)
-            .Where(m => m.Order.Contact == data.TelNumber)
-            .Where(m => m.VisitState == EVisitState.SMSVisiting)
-            .ToListAsync();
+        if (data.IsSmsReply == false || data.SmsReplyContent.IsNullOrEmpty())
+        {
+            _logRepository.Add("短信回访-不处理", data, "用户回复的内容为空", "UpdateSmsReplyAsync", 0);
+            return;
+        }
 
-        foreach (var orderVisit in orderVisits)
+        var query = _orderVisitRepository.Queryable()
+        .Includes(m => m.Order)
+        .Where(m => m.Order.Contact == data.TelNumber)
+        .Where(m => m.VisitState == EVisitState.SMSVisiting)
+        .OrderBy(m => m.CreationTime);
+
+#if DEBUG
+        var sql = query.ToSqlString();
+#endif
+        var orderVisit = await query.FirstAsync();
+        if (orderVisit == null)
         {
-            await UpdateSmsReplyAsync(orderVisit, data.SmsReplyContent!.Trim());
+            _logRepository.Add("短信回访-不处理", query.ToSqlString(), $"根据电话号码{data.TelNumber} 和回访状态 EVisitState.SMSVisiting, 无法查询出回访信息", "UpdateSmsReplyAsync", 0);
+            return;
         }
+
+        await UpdateSmsReplyAsync(orderVisit, data.SmsReplyContent!.Trim());
+
     }
 
     /// <summary>

+ 39 - 25
src/Hotline/Push/FWMessage/PushDomainService.cs

@@ -130,40 +130,54 @@ public class PushDomainService : IPushDomainService, IScopeDependency
     /// <returns></returns>
     public async Task PushMsgUpdateStateAsync(PushReceiveMessageDto dto, CancellationToken cancellation)
     {
-        var data = await _messageRepository.GetAsync(p => p.Id == dto.ExternalId, cancellation);
-        if (data != null)
+        if (dto.Type != "2")
         {
-            if (dto.Type == "0")
+            var data = await _messageRepository.GetAsync(p => p.Id == dto.ExternalId, cancellation);
+            if (data != null)
             {
-                if (dto.SendState == ESendState.Sending)
+                if (dto.Type == "0")
                 {
-                    data.SmsWaitSendingId = dto.SmsWaitSendingId;
-                    data.SendState = ESendState.Sending;
-                    data.Status = EPushStatus.Success;
+                    if (dto.SendState == ESendState.Sending)
+                    {
+                        data.SmsWaitSendingId = dto.SmsWaitSendingId;
+                        data.SendState = ESendState.Sending;
+                        data.Status = EPushStatus.Success;
+                    }
+                    else
+                        data.Status = EPushStatus.Failed;
+
+                    await _messageRepository.UpdateAsync(data, cancellation);
+                }
+                else if (dto.Type == "1")
+                {
+                    data.SendTime = Convert.ToDateTime(dto.SendTime);
+                    data.SendState = dto.SendState;
+                    data.MsgCount = dto.MsgCount;
+                    data.SmsSendingCompletedId = dto.SmsSendingCompletedId;
+                    await _messageRepository.UpdateAsync(data, cancellation);
                 }
-                else
-                    data.Status = EPushStatus.Failed;
-            }
-            else if (dto.Type == "1")
-            {
-                data.SendTime = Convert.ToDateTime(dto.SendTime);
-                data.SendState = dto.SendState;
-                data.MsgCount = dto.MsgCount;
-                data.SmsSendingCompletedId = dto.SmsSendingCompletedId;
             }
-            else if (dto.Type == "2")
+        }
+        else if (dto.Type == "2")
+        {
+            var messData = await _messageRepository.Queryable()
+                .Where(p => p.TelNumber == dto.TelNumber && (p.PushBusiness == EPushBusiness.VisitSms || p.PushBusiness == EPushBusiness.SearchSms)
+                && p.IsSmsReply == false)
+                .OrderBy(p => p.CreationTime)
+                .FirstAsync();
+            if (messData != null)
             {
-                data.IsSmsReply = dto.IsSmsReply;
-                data.SmsReplyTime = Convert.ToDateTime(dto.SmsReplyTime);
-                data.SmsReplyContent = dto.SmsReplyContent;
+                messData.IsSmsReply = true;
+                messData.SmsReplyTime = Convert.ToDateTime(dto.SmsReplyTime);
+                messData.SmsReplyContent = dto.SmsReplyContent;
+                await _messageRepository.UpdateAsync(messData, cancellation);
             }
-            data.Reason = dto.Reason;
-            await _messageRepository.UpdateAsync(data, cancellation);
 
-            var notify = data.Adapt<ReceiveMessageNotify>();
+            var notify = messData.Adapt<ReceiveMessageNotify>();
             notify.NotifyDto.Type = dto.Type;
-            await _publisher.PublishAsync(notify, PublishStrategy.ParallelNoWait, cancellation);
+            await _publisher.PublishAsync(notify, PublishStrategy.ParallelWhenAll, cancellation);
         }
+
     }
 
     /// <summary>
@@ -190,5 +204,5 @@ public class PushDomainService : IPushDomainService, IScopeDependency
             await _messageRepository.UpdateAsync(data, cancellation);
         }
     }
-    
+
 }

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

@@ -695,6 +695,11 @@ namespace Hotline.Settings
         /// </summary>
         public const string TianQuanPostAcceptInfoApi = "TianQuanPostAcceptInfoApi";
 
+        /// <summary>
+        /// 天阙接口请求方式
+        /// </summary>
+        public const string TianQueRequestMode = "TianQueRequestMode";
+
         /// <summary>
         /// 网格员回复等待时间(单位:小时)
         /// 超过该时间自动退回工单

+ 29 - 0
src/Hotline/Snapshot/ETianqueRequestMode.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Snapshot
+{
+    /// <summary>
+    /// 天阙接口请求方式
+    /// </summary>
+    public enum ETianqueRequestMode
+    {
+        /// <summary>
+        /// 测试环境测试地址
+        /// </summary>
+        TestEnvTestUrl = 0,
+
+        /// <summary>
+        /// 生产环境测试地址
+        /// </summary>
+        ProEnvTestUrl = 1,
+
+        /// <summary>
+        /// 生产环境正式地址
+        /// </summary>
+        ProEnvProUrl = 2,
+    }
+}

+ 75 - 0
src/Hotline/Tools/LocationConverter.cs

@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Tools;
+
+public static class LocationConverter
+{
+    private const double Pi = Math.PI;
+    private const double A = 6378245.0;
+    private const double Ee = 0.006693421622965943;
+
+    public static (double lat, double lon)  Wgs84ToGcj02(double lat, double lon)
+    {
+        double dLat = TransformLat(lon - 105.0, lat - 35.0);
+        double dLon = TransformLon(lon - 105.0, lat - 35.0);
+        double radLat = lat / 180.0 * Pi;
+        double magic = Math.Sin(radLat);
+        magic = 1.0 - Ee * magic * magic;
+        double sqrtMagic = Math.Sqrt(magic);
+        dLat = dLat * 180.0 / A * (1.0 - Ee) / magic * sqrtMagic * Pi;
+        dLon = dLon * 180.0 / A / sqrtMagic * Math.Cos(radLat) * Pi;
+
+        double mgLat = lat + dLat;
+        double mgLon = lon + dLon;
+
+        return (mgLat, mgLon);
+    }
+
+    public static (double lat, double lon) Gcj02ToWgs84(double lat, double lon)
+    {
+        var gps = Transform(lat, lon);
+        double lontitude = lon * 2.0 - gps.lon;
+        double latitude = lat * 2.0 - gps.lat;
+
+        return (latitude, lontitude);
+    }
+
+    private static double TransformLat(double x, double y)
+    {
+        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x));
+        ret += (20.0 * Math.Sin(6.0 * x * Pi) + 20.0 * Math.Sin(2.0 * x * Pi)) * 2.0 / 3.0;
+        ret += (20.0 * Math.Sin(y * Pi) + 40.0 * Math.Sin(y / 3.0 * Pi)) * 2.0 / 3.0;
+        ret += (160.0 * Math.Sin(y / 12.0 * Pi) + 320.0 * Math.Sin(y * Pi / 30.0)) * 2.0 / 3.0;
+        return ret;
+    }
+
+    private static double TransformLon(double x, double y)
+    {
+        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x));
+        ret += (20.0 * Math.Sin(6.0 * x * Pi) + 20.0 * Math.Sin(2.0 * x * Pi)) * 2.0 / 3.0;
+        ret += (20.0 * Math.Sin(x * Pi) + 40.0 * Math.Sin(x / 3.0 * Pi)) * 2.0 / 3.0;
+        ret += (150.0 * Math.Sin(x / 12.0 * Pi) + 300.0 * Math.Sin(x / 30.0 * Pi)) * 2.0 / 3.0;
+        return ret;
+    }
+
+    private static (double lat, double lon) Transform(double lat, double lon)
+    {
+        double dLat = TransformLat(lon - 105.0, lat - 35.0);
+        double dLon = TransformLon(lon - 105.0, lat - 35.0);
+        double radLat = lat / 180.0 * Pi;
+        double magic = Math.Sin(radLat);
+        magic = 1.0 - Ee * magic * magic;
+        double sqrtMagic = Math.Sqrt(magic);
+        dLat = dLat * 180.0 / A * (1.0 - Ee) / magic * sqrtMagic * Pi;
+        dLon = dLon * 180.0 / A / sqrtMagic * Math.Cos(radLat) * Pi;
+
+        double mgLat = lat + dLat;
+        double mgLon = lon + dLon;
+
+        return (mgLat, mgLon);
+    }
+}

+ 9 - 8
src/TianQue.Sdk/TQHttpClient.cs

@@ -16,6 +16,7 @@ public class TQHttpClient
 {
     private readonly string AppSecret;
     private readonly string AppKey;
+    private readonly IHttpClientFactory _httpClientFactory;
 
     /// <summary>
     /// ssh服务器ip
@@ -41,22 +42,21 @@ public class TQHttpClient
 
     private readonly ILogger<TQHttpClient> _logger;
 
-    public TQHttpClient(string appSecret, string appKey, ILogger<TQHttpClient> logger)
+    public TQHttpClient(string appSecret, string appKey, IHttpClientFactory httpClientFactory, ILogger<TQHttpClient> logger)
     {
         AppSecret = appSecret;
         AppKey = appKey;
+        _httpClientFactory = httpClientFactory;
         _logger = logger;
     }
 
-    public TQHttpClient(string appSecret, string appKey, string sshHost, int sshPort, string sshUserName, string sshPassword, ILogger<TQHttpClient> logger)
+    public TQHttpClient(string appSecret, string appKey, string sshHost, int sshPort, string sshUserName, string sshPassword, IHttpClientFactory httpClientFactory, ILogger<TQHttpClient> logger)
+        : this(appSecret, appKey, httpClientFactory, logger)
     {
-        AppSecret = appSecret;
-        AppKey = appKey;
         SSHHost = sshHost;
         SSHPort = sshPort;
         SSHUserName = sshUserName;
         SSHPassword = sshPassword;
-        _logger = logger;
         _sshClient = new SshClient(SSHHost, SSHPort, SSHUserName, SSHPassword);
     }
 
@@ -66,7 +66,8 @@ public class TQHttpClient
         {
             var headers = new Dictionary<string, object> { { "_timeStamp", DateTime.Now.ToUnixTimeMilliseconds() }, { "_nonce", SignUtils.GenerateNonce() } };
             var sortedDic = new SortedDictionary<string, object>(data.ToDictionary());
-            var body = sortedDic.ToJson(new JsonSerializerSettings {
+            var body = sortedDic.ToJson(new JsonSerializerSettings
+            {
                 NullValueHandling = NullValueHandling.Ignore,
                 ContractResolver = new CamelCasePropertyNamesContractResolver(),
                 DateFormatString = "yyyy-MM-dd HH:mm:ss.fff"
@@ -90,7 +91,7 @@ public class TQHttpClient
             {
                 content.Headers.Add(header.Key, header.Value.ToString());
             }
-            var resp = await (new HttpClient()).PostAsync(uri.ToString(), content);
+            var resp = await (_httpClientFactory.CreateClient()).PostAsync(uri.ToString(), content);
             resp.EnsureSuccessStatusCode();
             var result = await resp.Content.ReadAsStringAsync();
             _logger.LogInformation($"天阙交互; url: {uri.ToString()}, headers: {headers.ToJson()} request: {body}, response: {result}");
@@ -103,7 +104,7 @@ public class TQHttpClient
         }
         finally
         {
-            if (_sshClient.IsConnected)
+            if (_sshClient != null && _sshClient.IsConnected)
             {
                 _sshClient.Disconnect();
             }

+ 42 - 19
src/TianQue.Sdk/TiqnQueService.cs

@@ -22,11 +22,13 @@ public class TiqnQueService : IGuiderSystemService, IScopeDependency
 {
     private readonly ILogger<TQHttpClient> _logger;
     private readonly ISystemSettingCacheManager _sysSetting;
+    private readonly IHttpClientFactory _httpClientFactory;
 
-    public TiqnQueService(ILogger<TQHttpClient> logger, ISystemSettingCacheManager sysSetting)
+    public TiqnQueService(ILogger<TQHttpClient> logger, ISystemSettingCacheManager sysSetting, IHttpClientFactory httpClientFactory)
     {
         _logger = logger;
         _sysSetting = sysSetting;
+        _httpClientFactory = httpClientFactory;
     }
 
     /// <summary>
@@ -39,16 +41,16 @@ public class TiqnQueService : IGuiderSystemService, IScopeDependency
     public async Task<ApiResponse<GuiderSystemOutDto>> PostOrder(Order order, OrderSnapshot orderSnapshot, ThirdTokenDto tokenDto)
     {
         var baseUrl = _sysSetting.TianQuanPostAcceptInfoApi;
-        TQHttpClient httpClient;
-        var isDbueg = baseUrl.Contains("test");
-        if (isDbueg)
-        {
-            httpClient = new TQHttpClient(tokenDto.Secret, tokenDto.AppId, "171.94.154.2", 22, "root", "ZGbyy@2024!", _logger);
-        }
-        else
-        {
-            httpClient = new TQHttpClient(tokenDto.Secret, tokenDto.AppId, _logger);
-        }
+
+        //var isDbueg = baseUrl.Contains("test");
+        //if (isDbueg)
+        //{
+        //    httpClient = new TQHttpClient(tokenDto.Secret, tokenDto.AppId, "171.94.154.2", 22, "root", "ZGbyy@2024!", _logger);
+        //}
+        //else
+        //{
+        //    httpClient = new TQHttpClient(tokenDto.Secret, tokenDto.AppId, _logger);
+        //}
         var acceptInfo = order.Adapt<AcceptInfo>();
         acceptInfo.ReplyCode = order.No!; // 唯一标识
         acceptInfo.TypeName = order.AcceptType!; // 诉求类型名称
@@ -61,22 +63,43 @@ public class TiqnQueService : IGuiderSystemService, IScopeDependency
         acceptInfo.RootCategoryInfo = ""; // order.HotspotName!; // 热点分类(大类)
         acceptInfo.CategoryInfo = "";// order.HotspotSpliceName!; // 热点分类(小类)
         acceptInfo.DeadLine = orderSnapshot.DeadLine!.Value; // 截止时间
-        if(isDbueg)
-        {
-            acceptInfo.Prod = false; // 正式/测试
-        }
-        else
+
+        var tianqueRequestMode = _sysSetting.TianQueRequestMode;
+        TQHttpClient httpClient;
+        switch (tianqueRequestMode)
         {
-            acceptInfo.Prod = true; // 正式/测试
+            case ETianqueRequestMode.TestEnvTestUrl:
+                httpClient = new TQHttpClient(tokenDto.Secret, tokenDto.AppId, "171.94.154.2", 22, "root", "ZGbyy@2024!", _httpClientFactory, _logger);
+                acceptInfo.Prod = false;
+                break;
+            case ETianqueRequestMode.ProEnvTestUrl:
+                httpClient = new TQHttpClient(tokenDto.Secret, tokenDto.AppId, _httpClientFactory, _logger);
+                acceptInfo.Prod = false;
+                break;
+            case ETianqueRequestMode.ProEnvProUrl:
+                httpClient = new TQHttpClient(tokenDto.Secret, tokenDto.AppId, _httpClientFactory, _logger);
+                acceptInfo.Prod = true;
+                break;
+            default:
+                throw new ArgumentOutOfRangeException();
         }
 
+        //if (isDbueg)
+        //{
+        //    acceptInfo.Prod = false; // 正式/测试
+        //}
+        //else
+        //{
+        //    acceptInfo.Prod = true; // 正式/测试
+        //}
+
         // 反映人信息
         acceptInfo.PersonList = new List<PersonInfo>
         {
             new() {
                 ReflectPhone = order.Contact!, // 电话
                 ReflectUserName = order.FromName!, // 姓名
-            } 
+            }
         };
         if (order.FileJson != null)
         {
@@ -91,7 +114,7 @@ public class TiqnQueService : IGuiderSystemService, IScopeDependency
             }
         }
         acceptInfo.ValidateObject();
-        var result = await httpClient.PostAsync<ApiReponse<AcceptInfoSuccessDto>>(new Uri(_sysSetting.TianQuanPostAcceptInfoApi), acceptInfo);
+        var result = await httpClient.PostAsync<ApiReponse<AcceptInfoSuccessDto>>(new Uri(baseUrl), acceptInfo);
         return new ApiResponse<GuiderSystemOutDto>
         {
             Code = result.Success ? 0 : 1,

+ 5 - 3
test/Hotline.Tests/Application/DefaultCallApplicationTest.cs

@@ -59,9 +59,11 @@ public class DefaultCallApplicationTest : TestBase
     public async Task QueryCallsFixed_Test()
     {
         var inDto = new QueryCallsFixedDto();
-        inDto.CallStartTimeEnd = DateTime.Now;
-        inDto.CallStartTimeStart = "2024/10/01 00:00:00".ObjToDate();
-        inDto.StaffNo = "8029";
+        //inDto.CallStartTimeEnd = DateTime.Now;
+        //inDto.CallStartTimeStart = "2024/10/01 00:00:00".ObjToDate();
+        //inDto.StaffNo = "8029";
+        inDto.Type = 2;
+        inDto.ToNo = "15892228077";
 
         var items = await _defaultCallApplication.QueryCallsFixedAsync(inDto, new CancellationToken()).ToPageListWithoutTotalAsync(inDto, CancellationToken.None);
         items.ShouldNotBeNull();

+ 1 - 0
test/Hotline.Tests/Application/PointsRecordApplicationTest.cs

@@ -45,6 +45,7 @@ public class PointsRecordApplicationTest : TestBase
     [Fact]
     public async Task GetPointsRank_Test()
     {
+        SetWeiXin();
         var item = await _snapshotApplication.GetPointsRankAsync();
         item.ShouldNotBeNull();
         foreach (var a in item.Ranks)

+ 12 - 3
test/Hotline.Tests/Application/SnapshotApplicationTest.cs

@@ -93,7 +93,7 @@ public class SnapshotApplicationTest : TestBase
             IsPublished = true
         }).ToPageListAsync(0, 10);
         items.NotNullOrEmpty().ShouldBeTrue();
-        var signItems =  await _orderSnapshotApplication.GetSignOrderSnapshotItems(new SignOrderSnapshotItemsInDto()).ToListAsync();
+        var signItems = await _orderSnapshotApplication.GetSignOrderSnapshotItems(new SignOrderSnapshotItemsInDto()).ToListAsync();
     }
 
     [Fact]
@@ -265,7 +265,7 @@ public class SnapshotApplicationTest : TestBase
     [Fact]
     public async Task GetThirdToken_Test()
     {
-        var result = await _identityAppService.GetThredTokenAsync(new ThirdTokenInDto { AppType = EAppType.Snapshot, ThirdType = EThirdType.WeChat,   LoginCode = "0c3Adhll2zDMBe413rnl2KvEym2AdhlH" }, CancellationToken.None);
+        var result = await _identityAppService.GetThredTokenAsync(new ThirdTokenInDto { AppType = EAppType.Snapshot, ThirdType = EThirdType.WeChat, LoginCode = "0c3Adhll2zDMBe413rnl2KvEym2AdhlH" }, CancellationToken.None);
         result["PhoneNumber"].ToString().ShouldNotBeNullOrEmpty();
     }
 
@@ -425,7 +425,16 @@ public class SnapshotApplicationTest : TestBase
     [InlineData(ERedPackPickupStatus.Received)]
     public async Task GetRedPacksAsync(ERedPackPickupStatus status)
     {
-        var page = await _snapshotApplication.GetRedPacksAsync(new RedPacksInDto { Status = status }, CancellationToken.None);
+        try
+        {
+            var page = await _snapshotApplication.GetRedPacksAsync(new RedPacksInDto { Status = status }, CancellationToken.None);
+            page.ShouldNotBeNull();
+        }
+        catch (Exception e)
+        {
+            var msg = e.Message;
+            throw;
+        }        
         //page.Count.ShouldNotBe(0, "数据不应该为空");
     }
 

+ 48 - 0
test/Hotline.Tests/Domain/PushDomainServiceTest.cs

@@ -0,0 +1,48 @@
+using Hotline.Api.Controllers;
+using Hotline.Identity.Accounts;
+using Hotline.Identity.Roles;
+using Hotline.Push.FWMessage;
+using Hotline.Settings;
+using Hotline.Share.Dtos.Push;
+using Hotline.Share.Enums.Push;
+using Hotline.ThirdAccountDomainServices;
+using Hotline.ThirdAccountDomainServices.Interfaces;
+using Hotline.Users;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using SqlSugar.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Cache;
+using XF.Domain.Repository;
+
+namespace Hotline.Tests.Domain;
+
+public class PushDomainServiceTest : TestBase
+{
+    private readonly IPushDomainService _pushDomainService;
+
+    public PushDomainServiceTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, ITypedCache<SystemSetting> cacheSettingData, ThirdAccounSupplierFactory thirdAccountDomainFactory, IServiceProvider serviceProvider, IPushDomainService pushDomainService) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData, thirdAccountDomainFactory, serviceProvider)
+    {
+        _pushDomainService = pushDomainService;
+    }
+
+    [Fact]
+    public async Task PushMsgUpdateState_Test()
+    {
+        var inDto = new PushReceiveMessageDto
+        {
+            Type = "2",
+            Status = EPushStatus.Success,
+            SmsReplyContent = "5",
+            ExternalId = "08dd767e-2866-4f8c-8a27-90f44f8ec44d",
+            IsSmsReply = true,
+            SmsReplyTime = "2025-04-16 17:20:50".ObjToDate()
+        };
+        await _pushDomainService.PushMsgUpdateStateAsync(inDto, CancellationToken.None);
+        Thread.Sleep(60 * 1000);
+    }
+}