Browse Source

泸州任务:307 新增【坐席退件明细】
309 新增【中心退件明细】

tangjiang 2 months ago
parent
commit
1aece73e69

+ 126 - 0
src/Hotline.Api/Controllers/StatisticalReportController.cs

@@ -0,0 +1,126 @@
+using Hotline.Application.StatisticalReport;
+using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Order;
+using Hotline.Share.Dtos.StatisticalReport;
+using Hotline.Tools;
+using MapsterMapper;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
+using XF.Domain.Authentications;
+
+namespace Hotline.Api.Controllers
+{
+    public class StatisticalReportController : BaseController
+    {
+        private readonly IMapper _mapper;
+        private readonly ISessionContext _sessionContext;
+        private readonly IOrderReportApplication _orderReportApplication;
+
+        public StatisticalReportController(
+            IMapper mapper,
+            ISessionContext sessionContext,
+            IOrderReportApplication orderReportApplication)
+        {
+            _mapper = mapper;
+            _sessionContext = sessionContext;
+            _orderReportApplication = orderReportApplication;
+        }
+        /// <summary>
+        /// 坐席退件明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("getseatreturnorderlist")]
+        [AllowAnonymous]
+        public async Task<PagedDto<SeatReturnOrderListDto>> GetSeatReturnOrderList([FromQuery] SeatReturnOrderListRequestDto dto)
+        {
+            RefAsync<int> total = 0;
+            var dataList = await _orderReportApplication.GetSeatReturnOrderList(dto)
+            //转分页数据
+            .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
+            return new PagedDto<SeatReturnOrderListDto>(total.Value, _mapper.Map<IReadOnlyList<SeatReturnOrderListDto>>(dataList));
+        }
+
+        /// <summary>
+        /// 坐席退件明细--导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("getseatreturnorderlist_export")]
+        public async Task<FileStreamResult> GetSeatReturnOrderListExport([FromBody] ExportExcelDto<SeatReturnOrderListRequestDto> dto)
+        {
+            var query = _orderReportApplication.GetSeatReturnOrderList(dto.QueryDto);
+
+            List<SeatReturnOrderListDto> data;
+            if (dto.IsExportAll)
+            {
+                data = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                RefAsync<int> total = 0;
+                data = await query.ToPageListAsync(dto.QueryDto.PageIndex, dto.QueryDto.PageSize, total);
+            }
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = data
+                .Select(stu => _mapper.Map(stu, typeof(SeatReturnOrderListDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "坐席退件明细数据");
+        }
+
+        /// <summary>
+        /// 中心退件明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("getcenterreturnorderlist")]
+        [AllowAnonymous]
+        public async Task<PagedDto<SeatReturnOrderListDto>> GetCenterReturnOrderList([FromQuery] SeatReturnOrderListRequestDto dto)
+        {
+            RefAsync<int> total = 0;
+            var dataList = await _orderReportApplication.GetCenterReturnOrderList(dto)
+            //转分页数据
+            .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
+            return new PagedDto<SeatReturnOrderListDto>(total.Value, _mapper.Map<IReadOnlyList<SeatReturnOrderListDto>>(dataList));
+        }
+
+        /// <summary>
+        /// 中心退件明细--导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("getcenterreturnorderlist_export")]
+        public async Task<FileStreamResult> GetCenterReturnOrderListExport([FromBody] ExportExcelDto<SeatReturnOrderListRequestDto> dto)
+        {
+            var query = _orderReportApplication.GetCenterReturnOrderList(dto.QueryDto);
+
+            List<SeatReturnOrderListDto> data;
+            if (dto.IsExportAll)
+            {
+                data = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                RefAsync<int> total = 0;
+                data = await query.ToPageListAsync(dto.QueryDto.PageIndex, dto.QueryDto.PageSize, total);
+            }
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = data
+                .Select(stu => _mapper.Map(stu, typeof(SeatReturnOrderListDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "中心退件明细数据");
+        }
+
+    }
+}

+ 21 - 7
src/Hotline.Application/StatisticalReport/IOrderReportApplication.cs

@@ -3,8 +3,8 @@ using Hotline.Settings;
 using Hotline.Settings.Hotspots;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Dtos.StatisticalReport;
 using Hotline.Share.Requests;
-using Microsoft.AspNetCore.Mvc;
 using SqlSugar;
 using System.Data;
 
@@ -152,12 +152,12 @@ namespace Hotline.Application.StatisticalReport
 
         Task<DataTable> ExportHotPortJoinOrgStatisticsAsync(IReadOnlyList<Hotspot> dissatisfiedReason, List<dynamic>? list, List<string> addColumnName);
 
-		/// <summary>
-		/// 部门不满意统计明细
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		ISugarQueryable<OrderVisitDetail> BiQueryVisitNoSatisfiedDetail(BiQueryVisitNoSatisfiedDetailDto dto);
+        /// <summary>
+        /// 部门不满意统计明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<OrderVisitDetail> BiQueryVisitNoSatisfiedDetail(BiQueryVisitNoSatisfiedDetailDto dto);
 
         /// <summary>
         /// 未签收统计
@@ -186,5 +186,19 @@ namespace Hotline.Application.StatisticalReport
         /// <param name="dto"></param>
         /// <returns></returns>
         ISugarQueryable<Order> GetEnterpriseSeatsReportDetail(EnterpriseSeatsReportRequestDto dto);
+
+        /// <summary>
+        /// 坐席退件明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<SeatReturnOrderListDto> GetSeatReturnOrderList(SeatReturnOrderListRequestDto dto);
+
+        /// <summary>
+        /// 中心退件明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<SeatReturnOrderListDto> GetCenterReturnOrderList(SeatReturnOrderListRequestDto dto);
     }
 }

+ 195 - 108
src/Hotline.Application/StatisticalReport/OrderReportApplication.cs

@@ -9,9 +9,11 @@ using Hotline.SeedData;
 using Hotline.Settings;
 using Hotline.Settings.Hotspots;
 using Hotline.Settings.TimeLimits;
+using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Dtos.StatisticalReport;
 using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
@@ -46,22 +48,29 @@ namespace Hotline.Application.StatisticalReport
         private readonly IRepository<User> _userRepository;
         private readonly IRepository<Account> _accountRepository;
         private readonly IRepository<StatisticsDepart> _statisticsDepartRepository;
-		private readonly IRepository<SystemOrganize> _systemOrganizerepository;
-
-		/// <summary>
-		/// 
-		/// </summary>
-		/// <param name="orderRepository"></param>
-		/// <param name="orderVisitDetailRepository"></param>
-		/// <param name="orderDelayRepository"></param>
-		/// <param name="mapper"></param>
-		/// <param name="orderPublishRepository"></param>
-		/// <param name="sessionContext"></param>
-		/// <param name="workflowTraceRepository"></param>
-		/// <param name="orderScreenRepository"></param>
-		/// <param name="orderSecondaryHandlingApplication"></param>
-		/// <param name="timeLimitDomainService"></param>
-		public OrderReportApplication(
+        private readonly IRepository<SystemOrganize> _systemOrganizerepository;
+        private readonly IRepository<OrderSpecial> _orderSpecialRepository;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="orderRepository"></param>
+        /// <param name="orderVisitDetailRepository"></param>
+        /// <param name="orderDelayRepository"></param>
+        /// <param name="mapper"></param>
+        /// <param name="orderPublishRepository"></param>
+        /// <param name="sessionContext"></param>
+        /// <param name="workflowTraceRepository"></param>
+        /// <param name="orderScreenRepository"></param>
+        /// <param name="sysDicDataCacheManager"></param>
+        /// <param name="trCallRecordRepository"></param>
+        /// <param name="systemSettingCacheManager"></param>
+        /// <param name="userRepository"></param>
+        /// <param name="accountRepository"></param>
+        /// <param name="statisticsDepartRepository"></param>
+        /// <param name="systemOrganizerepository"></param>
+        /// <param name="orderSpecialRepository"></param>
+        public OrderReportApplication(
             IOrderRepository orderRepository,
             IRepository<OrderVisitDetail> orderVisitDetailRepository,
             IRepository<OrderDelay> orderDelayRepository,
@@ -76,8 +85,9 @@ namespace Hotline.Application.StatisticalReport
             IRepository<User> userRepository,
             IRepository<Account> accountRepository,
             IRepository<StatisticsDepart> statisticsDepartRepository,
-			IRepository<SystemOrganize> systemOrganizerepository
-			)
+            IRepository<SystemOrganize> systemOrganizerepository,
+             IRepository<OrderSpecial> orderSpecialRepository
+            )
         {
             _orderRepository = orderRepository;
             _orderVisitDetailRepository = orderVisitDetailRepository;
@@ -93,7 +103,8 @@ namespace Hotline.Application.StatisticalReport
             _userRepository = userRepository;
             _accountRepository = accountRepository;
             _statisticsDepartRepository = statisticsDepartRepository;
-			_systemOrganizerepository = systemOrganizerepository;
+            _systemOrganizerepository = systemOrganizerepository;
+            _orderSpecialRepository = orderSpecialRepository;
         }
 
         #region 宜宾、自贡
@@ -132,8 +143,8 @@ namespace Hotline.Application.StatisticalReport
             {
                 var len = orgLength.ToString();
 
-				var oldList = await _systemOrganizerepository.Queryable()
-                    .LeftJoin<StatisticsDepart>((o,x) => x.DepartmentId == o.oldBmid)
+                var oldList = await _systemOrganizerepository.Queryable()
+                    .LeftJoin<StatisticsDepart>((o, x) => x.DepartmentId == o.oldBmid)
                     .Where((o, x) => x.Time >= dto.StartTime && x.Time <= dto.EndTime)
                     .WhereIF(IsCenter == false, (o, x) => o.Id.StartsWith(_sessionContext.RequiredOrgId))
                     //.MergeTable()
@@ -238,13 +249,13 @@ namespace Hotline.Application.StatisticalReport
 
             if (await _statisticsDepartRepository.Queryable().Where(x => x.Time >= dto.StartTime && x.Time <= dto.EndTime).AnyAsync())
             {
-				var len = orgLength.ToString();
-				var oldList = await _statisticsDepartRepository.Queryable()
+                var len = orgLength.ToString();
+                var oldList = await _statisticsDepartRepository.Queryable()
                     .LeftJoin<SystemOrganize>((x, o) => x.DepartmentId == o.oldBmid)
                     .Where((x, o) => x.Time >= dto.StartTime && x.Time <= dto.EndTime)
                     .Where((x, o) => o.Id.StartsWith(_sessionContext.RequiredOrgId))
-					.Where((x, o) => string.IsNullOrEmpty(o.Id) == false)
-					.GroupBy((x, o) => o.Id.Substring(SqlFunc.MappingColumn<int>("0"),
+                    .Where((x, o) => string.IsNullOrEmpty(o.Id) == false)
+                    .GroupBy((x, o) => o.Id.Substring(SqlFunc.MappingColumn<int>("0"),
                         SqlFunc.MappingColumn<int>(len)))
                     .Select((x, o) => new DepartmentalProcessingStatisticsDataDto
                     {
@@ -2155,7 +2166,7 @@ namespace Hotline.Application.StatisticalReport
                     PassTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Pass, 1, 0)),
                     NoPassTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.NoPass, 1, 0)),
                     ExaminingTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Examining, 1, 0)),
-                    WithdrawTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Withdraw,1,0)),
+                    WithdrawTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Withdraw, 1, 0)),
                     //AllTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Pass, 1, 0)) + SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.NoPass, 1, 0)) + SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Examining, 1, 0))
 
                 }).MergeTable();
@@ -2183,7 +2194,7 @@ namespace Hotline.Application.StatisticalReport
                  .WhereIF(dto.Type is 2, x => x.DelayState == EDelayState.NoPass)
                  .WhereIF(dto.Type is 3, x => x.DelayState == EDelayState.Examining)
                  //.WhereIF(dto.Type is 4, x => x.DelayState < EDelayState.Withdraw)
-                 .WhereIF(dto.Type is 5,x=>x.DelayState == EDelayState.Withdraw)
+                 .WhereIF(dto.Type is 5, x => x.DelayState == EDelayState.Withdraw)
              .MergeTable();
 
         }
@@ -2200,7 +2211,7 @@ namespace Hotline.Application.StatisticalReport
             var centerOrgName = _systemSettingCacheManager.GetSetting(SettingConstants.CenterOrgName)?.SettingValue[0];
             var orderData = _orderRepository.Queryable()
               .Where(it => it.Status >= EOrderStatus.Filed)
-              .WhereIF(dto.TimeType == 1,it=> it.StartTime >= dto.StartTime && it.StartTime<= dto.EndTime)
+              .WhereIF(dto.TimeType == 1, it => it.StartTime >= dto.StartTime && it.StartTime <= dto.EndTime)
               .WhereIF(dto.TimeType == 2, it => it.FiledTime >= dto.StartTime && it.FiledTime <= dto.EndTime)
               .WhereIF(dto.TypeId != null && dto.TypeId == 1, it => it.IdentityType == EIdentityType.Citizen)
               .WhereIF(dto.TypeId != null && dto.TypeId == 2, it => it.IdentityType == EIdentityType.Enterprise)
@@ -2291,8 +2302,6 @@ namespace Hotline.Application.StatisticalReport
                  .MergeTable();
         }
 
-
-
         /// <summary>
         /// 受理类型统计
         /// </summary>
@@ -2437,92 +2446,91 @@ namespace Hotline.Application.StatisticalReport
             return dataTable;
         }
 
+        public async Task<DataTable> ExportHotPortJoinOrgStatisticsAsync(IReadOnlyList<Hotspot> dissatisfiedReason, List<dynamic>? list, List<string> addColumnName)
+        {
+            var dataTable = new DataTable();
+            foreach (var item in addColumnName)
+            {
+                dataTable.Columns.Add(item);
+            }
+
+            Dictionary<string, DataRow> dicRow = new();
+
+            // 先拿部门名称
+            // bug 部门名称重复时有问题
+            // 循环填充 首列 数据
+            foreach (var item in list)
+            {
+                foreach (var property in (IDictionary<string, object>)item)
+                {
+                    if (property.Key == "OrgName")
+                    {
+                        var name = property.Value.ToString();
+                        if (string.IsNullOrEmpty(name)) continue;
+                        if (dicRow.Any(m => m.Key == name)) continue;
+                        var dr = dataTable.NewRow();
+                        dr[0] = name;
+                        dicRow.Add(name, dr);
+                    }
+                }
+            }
+
+            var drCount = dataTable.NewRow();
+            drCount[0] = "合计";
+            dicRow.Add("合计", drCount);
+
+            for (int i = 0; i < dissatisfiedReason.Count; i++)
+            { // 循环填充列数据
+
+                var total = 0;
+                for (int l = 0; l < list.Count; l++)
+                {
+                    var columnIndex = i + 2;
+                    var value = string.Empty;
+                    var orgName = string.Empty;
+                    foreach (var property in (IDictionary<string, object>)list[l])
+                    {
+                        if (property.Key.ToLower().Equals("orgname")) orgName = property.Value.ToString();
+                        if (property.Key.ToLower().Equals(dissatisfiedReason[i].Id))
+                        {
+                            value = property.Value.ToString();
+                            total += int.Parse(value!);
+                        }
+                    }
+                    if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(orgName))
+                    {
+                        dicRow[orgName!][columnIndex] = value;
+                    }
+                    if (l + 1 == list.Count)
+                        dicRow["合计"][columnIndex] = total;
+                }
+            }
 
-		public async Task<DataTable> ExportHotPortJoinOrgStatisticsAsync(IReadOnlyList<Hotspot> dissatisfiedReason, List<dynamic>? list, List<string> addColumnName)
-		{
-			var dataTable = new DataTable();
-			foreach (var item in addColumnName)
-			{
-				dataTable.Columns.Add(item);
-			}
-
-			Dictionary<string, DataRow> dicRow = new();
-
-			// 先拿部门名称
-			// bug 部门名称重复时有问题
-			// 循环填充 首列 数据
-			foreach (var item in list)
-			{
-				foreach (var property in (IDictionary<string, object>)item)
-				{
-					if (property.Key == "OrgName")
-					{
-						var name = property.Value.ToString();
-						if (string.IsNullOrEmpty(name)) continue;
-						if (dicRow.Any(m => m.Key == name)) continue;
-						var dr = dataTable.NewRow();
-						dr[0] = name;
-						dicRow.Add(name, dr);
-					}
-				}
-			}
-
-			var drCount = dataTable.NewRow();
-			drCount[0] = "合计";
-			dicRow.Add("合计", drCount);
-
-			for (int i = 0; i < dissatisfiedReason.Count; i++)
-			{ // 循环填充列数据
-
-				var total = 0;
-				for (int l = 0; l < list.Count; l++)
-				{
-					var columnIndex = i + 2;
-					var value = string.Empty;
-					var orgName = string.Empty;
-					foreach (var property in (IDictionary<string, object>)list[l])
-					{
-						if (property.Key.ToLower().Equals("orgname")) orgName = property.Value.ToString();
-						if (property.Key.ToLower().Equals(dissatisfiedReason[i].Id))
-						{
-							value = property.Value.ToString();
-							total += int.Parse(value!);
-						}
-					}
-					if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(orgName))
-					{
-						dicRow[orgName!][columnIndex] = value;
-					}
-					if (l + 1 == list.Count)
-						dicRow["合计"][columnIndex] = total;
-				}
-			}
-
-			foreach (var item in dicRow)
-			{
+            foreach (var item in dicRow)
+            {
                 //小计
                 var index = 0;
                 var subtotal = 0;
-				foreach (var item2 in item.Value.ItemArray)
-				{
-                    if (index >1)
+                foreach (var item2 in item.Value.ItemArray)
+                {
+                    if (index > 1)
                     {
                         subtotal += int.Parse(item2.ToString());
-					}
+                    }
                     index++;
-				}
+                }
                 item.Value[1] = subtotal.ToString();
-				dataTable.Rows.Add(item.Value);
-			}
-			return dataTable;
-		}
-
-		/// <summary>
-		/// 部门不满意统计明细
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpGet("visit-nosatisfied-detail")]
+                dataTable.Rows.Add(item.Value);
+            }
+            return dataTable;
+        }
+
+        /// <summary>
+        /// 部门不满意统计明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("visit-nosatisfied-detail")]
         public ISugarQueryable<OrderVisitDetail> BiQueryVisitNoSatisfiedDetail(BiQueryVisitNoSatisfiedDetailDto dto)
         {
             var IsCenter = _sessionContext.OrgIsCenter;
@@ -2739,5 +2747,84 @@ namespace Hotline.Application.StatisticalReport
                .OrderByDescending(o => o.CreationTime);
 
         }
+
+        /// <summary>
+        /// 坐席退件明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public ISugarQueryable<SeatReturnOrderListDto> GetSeatReturnOrderList(SeatReturnOrderListRequestDto dto)
+        {
+            var dataList = _orderSpecialRepository.Queryable()
+                .Includes(p => p.Order)
+                .Where(p => p.SpecialType == ESpecialType.SendBack && p.BusinessType == EBusinessType.Seat
+                && p.StepType == EStepType.Start && p.NewCurrentStepId != null)
+                .Select(p => new SeatReturnOrderListDto
+                {
+                    Index = SqlFunc.RowNumber($"{p.CreationTime} desc ", $"{p.OrderId}"),
+                    OrderId = p.OrderId,
+                    Title = p.Order.Title,
+                    No = p.Order.No,
+                    OrderCreationTime = p.Order.CreationTime,
+                    AcceptType = p.Order.AcceptType,
+                    AcceptTypeCode = p.Order.AcceptTypeCode,
+                    SourceChannel = p.Order.SourceChannel,
+                    SourceChannelCode = p.Order.SourceChannelCode,
+                    SpecialCreationTime = p.CreationTime,
+                    Name = SqlFunc.Subqueryable<WorkflowStep>().Where(s => s.Id == p.NewCurrentStepId).Select(s => s.HandlerName)
+                })
+            //将结果合并成一个表
+            .MergeTable()
+            .Where(d => d.SpecialCreationTime >= dto.StartTime && d.SpecialCreationTime <= dto.EndTime)
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title))
+            .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No))
+            .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name))
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), d => d.AcceptTypeCode == dto.AcceptTypeCode)
+            .WhereIF(!string.IsNullOrEmpty(dto.SourceChannelCode), d => d.SourceChannelCode == dto.SourceChannelCode)
+            //取第一条数据
+            .Where(d => d.Index == 1)
+            .OrderByDescending(d => d.SpecialCreationTime);
+            return dataList;
+        }
+
+        /// <summary>
+        /// 中心退件明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public ISugarQueryable<SeatReturnOrderListDto> GetCenterReturnOrderList(SeatReturnOrderListRequestDto dto)
+        {
+            var dataList = _orderSpecialRepository.Queryable()
+                .Includes(p => p.Order)
+                .Where(p => p.SpecialType == ESpecialType.SendBack && p.FlowDirection == EFlowDirection.FiledToCenter && p.NewCurrentStepId != null)
+                .Where(p => p.BusinessType == EBusinessType.Seat || p.BusinessType == EBusinessType.Send
+                || p.BusinessType == EBusinessType.CenterMonitor || p.BusinessType == EBusinessType.CenterLeader)
+                .Select(p => new SeatReturnOrderListDto
+                {
+                    Index = SqlFunc.RowNumber($"{p.CreationTime} desc ", $"{p.OrderId}"),
+                    OrderId = p.OrderId,
+                    Title = p.Order.Title,
+                    No = p.Order.No,
+                    OrderCreationTime = p.Order.CreationTime,
+                    AcceptType = p.Order.AcceptType,
+                    AcceptTypeCode = p.Order.AcceptTypeCode,
+                    SourceChannel = p.Order.SourceChannel,
+                    SourceChannelCode = p.Order.SourceChannelCode,
+                    SpecialCreationTime = p.CreationTime,
+                    Name = SqlFunc.Subqueryable<WorkflowStep>().Where(s => s.Id == p.NewCurrentStepId).Select(s => s.HandlerName)
+                })
+            //将结果合并成一个表
+            .MergeTable()
+            .Where(d => d.SpecialCreationTime >= dto.StartTime && d.SpecialCreationTime <= dto.EndTime)
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title))
+            .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No))
+            .WhereIF(!string.IsNullOrEmpty(dto.Name), d => d.Name.Contains(dto.Name))
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), d => d.AcceptTypeCode == dto.AcceptTypeCode)
+            .WhereIF(!string.IsNullOrEmpty(dto.SourceChannelCode), d => d.SourceChannelCode == dto.SourceChannelCode)
+            //取第一条数据
+            .Where(d => d.Index == 1)
+            .OrderByDescending(d => d.SpecialCreationTime);
+            return dataList;
+        }
     }
 }

+ 95 - 0
src/Hotline.Share/Dtos/StatisticalReport/SeatReturnOrderListDto.cs

@@ -0,0 +1,95 @@
+using Hotline.Share.Requests;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Share.Dtos.StatisticalReport
+{
+    public record SeatReturnOrderListRequestDto: PagedKeywordRequest
+    {
+        /// <summary>
+        /// 工单标题
+        /// </summary>
+        public string Title { get; set; }
+
+        /// <summary>
+        /// 工单编号
+        /// </summary>
+        public string No { get; set; }
+
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 受理类型编号
+        /// </summary>
+        public string AcceptTypeCode { get; set; }
+
+        /// <summary>
+        /// 来源渠道编号
+        /// </summary>
+        public string? SourceChannelCode { get; set; }
+    }
+
+    /// <summary>
+    /// 退件明细
+    /// </summary>
+    public class SeatReturnOrderListDto
+    {
+        public int Index {  get; set; }
+
+        /// <summary>
+        /// 工单id
+        /// </summary>
+        public string OrderId { get; set; }
+
+        /// <summary>
+        /// 工单标题
+        /// </summary>
+        public string Title { get; set; }
+
+        /// <summary>
+        /// 工单编号
+        /// </summary>
+        public string No { get; set; }
+
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 受理时间
+        /// </summary>
+        public DateTime OrderCreationTime { get; set; }
+
+        /// <summary>
+        /// 退回时间
+        /// </summary>
+        public DateTime SpecialCreationTime {  get; set; }
+
+        /// <summary>
+        /// 受理类型名称
+        /// </summary>
+        public string AcceptType { get; set; }
+
+        /// <summary>
+        /// 受理类型编号
+        /// </summary>
+        public string AcceptTypeCode { get; set; }
+
+        /// <summary>
+        /// 来源渠道(电话、网站、APP等)
+        /// </summary>
+        public string? SourceChannel { get; set; }
+
+        /// <summary>
+        /// 来源渠道编号
+        /// </summary>
+        public string? SourceChannelCode { get; set; }
+    }
+}