Ver código fonte

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

xf 10 meses atrás
pai
commit
e81a39c9dd

+ 123 - 120
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -116,121 +116,88 @@ namespace Hotline.Api.Controllers.Bi
         [HttpGet("org_data_list_detail")]
         public async Task<PagedDto<OrderDto>> OrgDataListDetail([FromQuery] OrgDataListDetailRequest dto)
         {
-            dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);
-
-            var quer = _orderRepository.Queryable()
-                    .InnerJoin<SystemOrganize>((x, so) => x.ActualHandleOrgCode == so.Id)
-                    .Where(x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime)
-                    .WhereIF(dto.QueryType == 1, x => x.Status >= EOrderStatus.Filed && x.ExpiredTime < x.FiledTime) //业务已办超期
-                    .WhereIF(dto.QueryType == 3, x => x.Status < EOrderStatus.Filed && x.ExpiredTime < SqlFunc.GetDate()) //业务待办超期
-                    .WhereIF(dto.QueryType == 5, x =>
-                        (x.Status >= EOrderStatus.Filed && x.ExpiredTime < x.FiledTime) || (x.Status < EOrderStatus.Filed && x.ExpiredTime < SqlFunc.GetDate()))
-                    .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.QueryType is 1 or 3 && dto.OrgCode == "001", x => x.ActualHandleOrgCode == dto.OrgCode)
-                    .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.QueryType is 1 or 3 && dto.OrgCode != "001", x => x.ActualHandleOrgCode.StartsWith(dto.OrgCode))
-                    .MergeTable();
-
-            if (dto.QueryType is 2 or 4 or 5)
-            {
-                var queryCountersign = _workflowCountersignRepository.Queryable()
-                    .LeftJoin<WorkflowCountersignMember>((x, o) => x.Id == o.WorkflowCountersignId)
-                    .Where((x, o) => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime && x.IsExpired.HasValue && x.IsExpired.Value == true)
-                    .WhereIF(dto.QueryType == 2, (x, o) => o.IsHandled == true) //会签已办超期
-                    .WhereIF(dto.QueryType == 4, (x, o) => o.IsHandled == false) //会签待办超期
-                    .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.QueryType is 2 or 4 or 5, (x, o) => o.Key.StartsWith(dto.OrgCode))
-                    //.GroupBy((x,o)=>x.WorkflowId)
-                    .Select((x, o) => new { Id = x.WorkflowId })
-                    .MergeTable();
-
-                quer = quer.InnerJoin(queryCountersign, (x, c) => x.WorkflowId == c.Id);
-
-            }
-            var (total, items) = await quer.ToPagedListAsync(dto.PageIndex, dto.PageSize);
+			var quer = _orderApplication.QueryOrgDataListDetail(dto);
+			var (total, items) = await quer.ToPagedListAsync(dto.PageIndex, dto.PageSize);
 
             return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
         }
 
-
         /// <summary>
-        /// 部门超期统计
+        /// 部门超期统计明细导出
         /// </summary>
-        /// <param name="dto"></param>
         /// <returns></returns>
-        [HttpGet("org_data_list")]
-        public async Task<PagedDto<OrderBiOrgDataListVo>> OrgDataList([FromQuery] ReportPagedRequest dto)
+        [HttpPost("org_data_list_detail/_export")]
+        public async Task<FileStreamResult> OrgDataListDetailExport([FromBody] ExportExcelDto<OrgDataListDetailRequest> dto)
         {
-            if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
+            var query = _orderApplication.QueryOrgDataListDetail(dto.QueryDto);
+            List<Order> secondaryHandling;
+            if (dto.IsExportAll)
+            {
+                secondaryHandling = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                secondaryHandling = items;
+            }
 
-            dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
+            var secondaryHandlingDtos = _mapper.Map<ICollection<OrderDto>>(secondaryHandling);
 
-            var IsCenter = _sessionContext.OrgIsCenter;
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
 
+            var dtos = secondaryHandlingDtos
+                .Select(stu => _mapper.Map(stu, typeof(OrderDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
 
-            var queryOrder = _systemOrganizeRepository.Queryable()
-                .LeftJoin<Order>((x, o) => x.Id == o.ActualHandleOrgCode)
-                .WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= dto.StartTime)
-                .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= dto.EndTime)
-                .WhereIF(IsCenter == false, (x, o) => o.ActualHandleOrgCode == _sessionContext.RequiredOrgId)
-                .GroupBy((x, o) => new { x.Id, x.Name })
-                .Select((x, o) => new OrderBiOrgDataListVo
-                {
-                    OrgName = x.Name,
-                    OrgId = x.Id,
-                    HandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.Status >= EOrderStatus.Filed && o.ExpiredTime < o.FiledTime, 1, 0)),
-                    NoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.Status < EOrderStatus.Filed && o.ExpiredTime < SqlFunc.GetDate(), 1, 0)),
-                }).MergeTable();
+            var stream = ExcelHelper.CreateStream(dtos);
 
-            var queryCountersign = _workflowCountersignRepository.Queryable()
-                .LeftJoin<WorkflowCountersignMember>((x, o) => x.Id == o.WorkflowCountersignId)
-                .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
-                .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
-                .GroupBy((x, o) => o.Key)
-                .Select((x, o) => new OrderBiOrgDataListVo
-                {
-                    OrgId = o.Key,
-                    CounterHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.IsHandled && x.IsExpired.HasValue && x.IsExpired.Value == true, 1, 0)),
-                    CounterNoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.IsHandled == false && x.IsExpired.HasValue && x.IsExpired.Value == true, 1, 0)),
-                }).MergeTable();
+            return ExcelStreamResult(stream, "部门超期统计明细数据");
+        }
 
-            var query = queryOrder.LeftJoin(queryCountersign, (or, co) => or.OrgId == co.OrgId)
-                .LeftJoin<SystemOrganize>((or, co, so) => or.OrgId.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")) == so.Id)
-                .GroupBy((or, co, so) => new { so.Id, so.Name })
-                .Select((or, co, so) => new OrderBiOrgDataListVo
-                {
-                    OrgName = so.Name,
-                    OrgId = so.Id,
-                    HandlerExtendedNum = SqlFunc.AggregateSum(or.HandlerExtendedNum),
-                    NoHandlerExtendedNum = SqlFunc.AggregateSum(or.NoHandlerExtendedNum),
-                    CounterHandlerExtendedNum = SqlFunc.AggregateSum(co.CounterHandlerExtendedNum),
-                    CounterNoHandlerExtendedNum = SqlFunc.AggregateSum(co.CounterNoHandlerExtendedNum)
-                }).MergeTable();
 
-            query = query.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrgName.Contains(dto.Keyword!)).Where(x => x.HandlerExtendedNum > 0 || x.NoHandlerExtendedNum > 0 || x.CounterHandlerExtendedNum > 0 || x.CounterNoHandlerExtendedNum > 0);
-            switch (dto.SortField)
-            {
-                case "handlerExtendedNum":
-                    query = dto.SortRule == 0 ? query.OrderBy(x => x.HandlerExtendedNum) : query.OrderByDescending(x => x.HandlerExtendedNum);
-                    break;
-                case "counterHandlerExtendedNum":
-                    query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterHandlerExtendedNum) : query.OrderByDescending(x => x.CounterHandlerExtendedNum);
-                    break;
-                case "noHandlerExtendedNum":
-                    query = dto.SortRule == 0 ? query.OrderBy(x => x.NoHandlerExtendedNum) : query.OrderByDescending(x => x.NoHandlerExtendedNum);
-                    break;
-                case "counterNoHandlerExtendedNum":
-                    query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterNoHandlerExtendedNum) : query.OrderByDescending(x => x.CounterNoHandlerExtendedNum);
-                    break;
-            }
+        /// <summary>
+        /// 部门超期统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("org_data_list")]
+        public async Task<PagedDto<OrderBiOrgDataListVo>> OrgDataList([FromQuery] ReportPagedRequest dto)
+        {
 
-            var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
+            var query = _orderApplication.QueryOrgDataList(dto);
+			var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
             return new PagedDto<OrderBiOrgDataListVo>(total, items);
         }
 
         /// <summary>
-        /// 话务员办件统计
+        /// 部门超期统计导出
         /// </summary>
-        /// <param name="dto"></param>
         /// <returns></returns>
-        [HttpGet("centre_data_list")]
+        [HttpPost("org_data_list/_export")]
+        public async Task<FileStreamResult> OrgDataListExport([FromBody] ExportExcelDto<ReportPagedRequest> dto)
+        {
+            var query = _orderApplication.QueryOrgDataList(dto.QueryDto);
+            List<OrderBiOrgDataListVo> secondaryHandling;
+            secondaryHandling = await query.ToListAsync(HttpContext.RequestAborted);
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+            var dtos = secondaryHandling
+             .Select(stu => _mapper.Map(stu, typeof(OrderBiOrgDataListVo), dynamicClass))
+             .Cast<object>()
+             .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "部门超期统计数据");
+        }
+
+
+		/// <summary>
+		/// 话务员办件统计
+		/// </summary>
+		/// <param name="dto"></param>
+		/// <returns></returns>
+		[HttpGet("centre_data_list")]
         public async Task<List<OrderBiCentreDataListVo>> CentreDataList([FromQuery] ReportPagedRequest dto)
         {
             if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
@@ -2758,26 +2725,34 @@ namespace Hotline.Api.Controllers.Bi
             if (!dto.StartTime.HasValue || !dto.EndTime.HasValue)
                 throw UserFriendlyException.SameMessage("请选择时间!");
             dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
-            var (total, items) = await _orderSpecialDetailRepository.Queryable()
-                .Includes(x => x.OrderSpecial)
-                .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.OrgName.Contains(dto.OrgName!))
-                .Where(x => x.OrderSpecial.ESpecialType == ESpecialType.ReTransact)
-                .Where(x => x.OrderSpecial.CreationTime >= dto.StartTime)
-                .Where(x => x.OrderSpecial.CreationTime <= dto.EndTime)
-                .GroupBy(x => new { Time = x.OrderSpecial.CreationTime.ToString("yyyy-MM-dd"), x.OrgId, x.OrgName })
-                .Select(x => new OrderReTransactVo
-                {
-                    Time = x.OrderSpecial.CreationTime.ToString("yyyy-MM-dd"),
-                    OrgId = x.OrgId,
-                    OrgName = x.OrgName,
-                    Num = SqlFunc.AggregateCount(1)
-                }).MergeTable()
-                .OrderByIF(dto.SortRule == 0, x => x.Num, OrderByType.Asc)
-                .OrderByIF(dto.SortRule == 1, x => x.Num, OrderByType.Desc)
-                .ToPagedListAsync(dto, HttpContext.RequestAborted);
+            var query = _orderApplication.OrderReTransact(dto);
+			var (total, items) =  await query
+				.ToPagedListAsync(dto, HttpContext.RequestAborted);
             return new PagedDto<OrderReTransactVo>(total, _mapper.Map<IReadOnlyList<OrderReTransactVo>>(items));
         }
 
+        /// <summary>
+        /// 回退错件导出
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("reTransact/_export")]
+        public async Task<FileStreamResult> OrderReTransactExport([FromBody] ExportExcelDto<QueryOrderReTransactRequest> dto)
+        {
+            var query = _orderApplication.OrderReTransact(dto.QueryDto);
+            List<OrderReTransactVo> secondaryHandling;
+            secondaryHandling = await query.ToListAsync(HttpContext.RequestAborted);
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+            var dtos = secondaryHandling
+             .Select(stu => _mapper.Map(stu, typeof(OrderReTransactVo), dynamicClass))
+             .Cast<object>()
+             .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "回退错件统计数据");
+        }
+
+
         /// <summary>
         /// 回退错件明细
         /// </summary>
@@ -2789,24 +2764,52 @@ namespace Hotline.Api.Controllers.Bi
             if (!dto.StartTime.HasValue || !dto.EndTime.HasValue)
                 throw UserFriendlyException.SameMessage("请选择时间!");
             dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
-            var (total, items) = await _orderSpecialDetailRepository.Queryable()
-                .Includes(x => x.OrderSpecial, s => s.Order)
-                .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.OrgName.Contains(dto.OrgName!))
-                .WhereIF(!string.IsNullOrEmpty(dto.ErrorName), x => x.ErrorName.Contains(dto.ErrorName!))
-                .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.OrderSpecial!.Order!.No!.Contains(dto.No!))
-                .Where(x => x.OrderSpecial.ESpecialType == ESpecialType.ReTransact)
-                .Where(x => x.OrderSpecial.CreationTime >= dto.StartTime)
-                .Where(x => x.OrderSpecial.CreationTime <= dto.EndTime)
-                .ToPagedListAsync(dto, HttpContext.RequestAborted);
+
+            var query = _orderApplication.QueryOrderSourceDetail(dto);
+			var (total, items) = await
+				query.ToPagedListAsync(dto, HttpContext.RequestAborted);
             return new PagedDto<OrderSpecialDetailDto>(total, _mapper.Map<IReadOnlyList<OrderSpecialDetailDto>>(items));
         }
 
+        /// <summary>
+        /// 回退错件明细导出
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("reTransact_detail/_export")]
+        public async Task<FileStreamResult> OrderReTransactDetailExport([FromBody] ExportExcelDto<QueryOrderReTransactDetailRequest> dto)
+        {
+            var query = _orderApplication.QueryOrderSourceDetail(dto.QueryDto);
+            List<OrderSpecialDetail> secondaryHandling;
+            if (dto.IsExportAll)
+            {
+                secondaryHandling = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                secondaryHandling = items;
+            }
+
+            var secondaryHandlingDtos = _mapper.Map<ICollection<OrderSpecialDetailDto>>(secondaryHandling);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = secondaryHandlingDtos
+                .Select(stu => _mapper.Map(stu, typeof(OrderSpecialDetailDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "回退错件明细列表数据");
+        }
+
         /// <summary>
         /// 获取基本信息
         /// </summary>
         /// <param name="id"></param>
         /// <returns></returns>
-		[HttpGet("reTransact_base")]
+        [HttpGet("reTransact_base")]
         public async Task<object> ReTransactBaseData()
         {
             var rsp = new

+ 103 - 71
src/Hotline.Api/Controllers/OrderController.cs

@@ -1349,7 +1349,7 @@ public class OrderController : BaseController
             startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderDelay;
             startDto.Opinion = model.DelayReason;
             startDto.Title = "申请延期流程";
-			string workFlowId = await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, model.Id,
+            string workFlowId = await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, model.Id,
                     cancellationToken: HttpContext.RequestAborted);
             //model.WorkflowId = workFlowId;
             //await _orderDelayRepository.UpdateAsync(model, HttpContext.RequestAborted);
@@ -1719,8 +1719,8 @@ public class OrderController : BaseController
             startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderScreen;
             startDto.Opinion = dto.Data.Content;
             startDto.Title = "申请甄别流程";
-		   workflowId = await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, model.Id,
-                    cancellationToken: HttpContext.RequestAborted);
+            workflowId = await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, model.Id,
+                     cancellationToken: HttpContext.RequestAborted);
             //var screen = await _orderScreenRepository.GetAsync(model.Id, HttpContext.RequestAborted);
             //if (screen != null)
             //{
@@ -2423,18 +2423,19 @@ public class OrderController : BaseController
                 _sessionContext.RequiredOrgId, _sessionContext.OrgName,
                 _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName));
         }
-		var setting = _systemSettingCacheManager.GetSetting(SettingConstants.SeatsMonitor);
-		var settingStr = setting?.SettingValue;
-		var roles = _sessionContext.Roles;
-		foreach (var item in settingStr)
-		{
-			if (roles != null && roles.Contains(item)) dto.CanHandle = true;
-		}
-
-		//var dto = _mapper.Map<OrderDto>(order!);
-		//dto.CountersignId = countersignId;
-		//dto.CanHandle = order.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
-		dto.IsCanDelay = !order.OrderDelays.Any(x => x.DelayState == EDelayState.Examining);
+        //班长代办
+		//var setting = _systemSettingCacheManager.GetSetting(SettingConstants.SeatsMonitor);
+		//var settingStr = setting?.SettingValue;
+		//var roles = _sessionContext.Roles;
+		//foreach (var item in settingStr)
+		//{
+		//	if (roles != null && roles.Contains(item)) dto.CanHandle = true;
+		//}
+
+        //var dto = _mapper.Map<OrderDto>(order!);
+        //dto.CountersignId = countersignId;
+        //dto.CanHandle = order.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
+        dto.IsCanDelay = !order.OrderDelays.Any(x => x.DelayState == EDelayState.Examining);
         if (order.OrderDelays.Any(x => x.DelayState == EDelayState.Examining && x.ApplyOrgCode == _sessionContext.RequiredOrgId))
         {
             dto.CanHandle = false;
@@ -2778,25 +2779,25 @@ public class OrderController : BaseController
                 await Remove(id);
             throw new UserFriendlyException($"工单开启流程失败!, {e.Message}, {e.StackTrace}", "工单开启流程失败");
         }
-		//是否市州互转
-		if (dto.Data.Transpond.HasValue && dto.Data.Transpond.Value)
-		{
-			var order = await _orderRepository.GetAsync(id, HttpContext.RequestAborted);
-			var orderDto = _mapper.Map<OrderDto>(order);
-			await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderTranspondCity, orderDto);
-			//保存本地数据
-			TranspondCityRawData cityRawData = new TranspondCityRawData
-			{
-				OrderCode = order.No,
-				TransferOutTime = DateTime.Now,
-				CityName = order.TranspondCityName,
-				Direction = ETranspondDirection.Out
-			};
-
-			await _transpondCityRawDataRepository.AddAsync(cityRawData, HttpContext.RequestAborted);
-
-		}
-	}
+        //是否市州互转
+        if (dto.Data.Transpond.HasValue && dto.Data.Transpond.Value)
+        {
+            var order = await _orderRepository.GetAsync(id, HttpContext.RequestAborted);
+            var orderDto = _mapper.Map<OrderDto>(order);
+            await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderTranspondCity, orderDto);
+            //保存本地数据
+            TranspondCityRawData cityRawData = new TranspondCityRawData
+            {
+                OrderCode = order.No,
+                TransferOutTime = DateTime.Now,
+                CityName = order.TranspondCityName,
+                Direction = ETranspondDirection.Out
+            };
+
+            await _transpondCityRawDataRepository.AddAsync(cityRawData, HttpContext.RequestAborted);
+
+        }
+    }
 
     /// <summary>
     /// 查询工单办理流程开启参数
@@ -3169,7 +3170,7 @@ public class OrderController : BaseController
                 ((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) && step.HandlerId == _sessionContext.RequiredUserId) ||
                  (step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) && step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
                  (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) && _sessionContext.Roles.Contains(step.RoleId))) &&
-                 (((dto.IsHandled.HasValue && dto.IsHandled == false) && step.Status != EWorkflowStepStatus.Handled)||
+                 (((dto.IsHandled.HasValue && dto.IsHandled == false) && step.Status != EWorkflowStepStatus.Handled) ||
                 ((dto.IsHandled.HasValue && dto.IsHandled == true) && step.Status == EWorkflowStepStatus.Handled)))))
             .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
             .WhereIF(dto.IsHandled.HasValue, d => handleStatuses.Contains(d.Status))
@@ -3216,7 +3217,7 @@ public class OrderController : BaseController
             //  )))
             //.Where(d => d.Workflow.Steps.Any(s => s.Status < EWorkflowStepStatus.Handled && s.HandlerOrgId == OrgSeedData.CenterId))
             .LeftJoin<WorkflowStep>((d, step) => d.Id == step.ExternalId)
-            .Where((d,step)=> (step.Id  == null || step.HandlerOrgId == OrgSeedData.CenterId))
+            .Where((d, step) => (step.Id == null || (step.HandlerOrgId == OrgSeedData.CenterId && step.Status < EWorkflowStepStatus.Handled)))
             .Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
             .Where(d => d.Status != EOrderStatus.BackToProvince && d.Status < EOrderStatus.Filed)
             .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No!.Contains(dto.No!))
@@ -3294,35 +3295,35 @@ public class OrderController : BaseController
                     : d is EOrderStatus.WaitForAccept or EOrderStatus.BackToUnAccept or EOrderStatus.SpecialToUnAccept)
             .ToArray();
 
-		var (total2, items2) = await _orderRepository.Queryable()
-		.LeftJoin<WorkflowStep>((d, step) => d.Id == step.ExternalId)
-		.Where((d, step) =>
-			((string.IsNullOrEmpty(d.WorkflowId) && (string.IsNullOrEmpty(d.SignerId) || d.SignerId == _sessionContext.RequiredUserId)) ||
-			(!string.IsNullOrEmpty(d.WorkflowId) &&
-			((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) && step.HandlerId == _sessionContext.RequiredUserId) ||
-			 (step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) && step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
-			 (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) && _sessionContext.Roles.Contains(step.RoleId))) &&
-			 (((dto.IsHandled.HasValue && dto.IsHandled == false) && step.Status != EWorkflowStepStatus.Handled) ||
-			((dto.IsHandled.HasValue && dto.IsHandled == true) && step.Status == EWorkflowStepStatus.Handled)))))
-		.WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
-		.WhereIF(dto.IsHandled.HasValue, d => handleStatuses.Contains(d.Status))
-		.WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword!))
-		.WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No == dto.No)
-		.WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == true, d => d.CounterSignType.HasValue)
-		.WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == false, d => !d.CounterSignType.HasValue)
-		.WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == true, d => (d.ExpiredTime < DateTime.Now && d.Status < EOrderStatus.Filed) || (d.ExpiredTime < d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //超期 未办
-		.WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == false, d => d.NearlyExpiredTime < DateTime.Now && d.ExpiredTime > DateTime.Now)//即将超期 未办
-		.WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime)
-		.WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime)
-		.Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
-		.Where(d => d.Status != EOrderStatus.BackToProvince && d.Status < EOrderStatus.Filed)
-		.OrderBy(d => d.Status)
-		.OrderByIF(dto.IsHandled == true, d => d.StartTime, OrderByType.Desc)
-		.OrderByIF(dto.IsHandled == false, d => d.CreationTime, OrderByType.Desc)
-		.Select((d, step) => d)
-		.ToPagedListAsync(dto, HttpContext.RequestAborted);
-
-		var page2 = new PagedDto<OrderDto>(total2, _mapper.Map<IReadOnlyList<OrderDto>>(items2));
+        var (total2, items2) = await _orderRepository.Queryable()
+        .LeftJoin<WorkflowStep>((d, step) => d.Id == step.ExternalId)
+        .Where((d, step) =>
+            ((string.IsNullOrEmpty(d.WorkflowId) && (string.IsNullOrEmpty(d.SignerId) || d.SignerId == _sessionContext.RequiredUserId)) ||
+            (!string.IsNullOrEmpty(d.WorkflowId) &&
+            ((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) && step.HandlerId == _sessionContext.RequiredUserId) ||
+             (step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) && step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
+             (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) && _sessionContext.Roles.Contains(step.RoleId))) &&
+             (((dto.IsHandled.HasValue && dto.IsHandled == false) && step.Status != EWorkflowStepStatus.Handled) ||
+            ((dto.IsHandled.HasValue && dto.IsHandled == true) && step.Status == EWorkflowStepStatus.Handled)))))
+        .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
+        .WhereIF(dto.IsHandled.HasValue, d => handleStatuses.Contains(d.Status))
+        .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword!))
+        .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No == dto.No)
+        .WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == true, d => d.CounterSignType.HasValue)
+        .WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == false, d => !d.CounterSignType.HasValue)
+        .WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == true, d => (d.ExpiredTime < DateTime.Now && d.Status < EOrderStatus.Filed) || (d.ExpiredTime < d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //超期 未办
+        .WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == false, d => d.NearlyExpiredTime < DateTime.Now && d.ExpiredTime > DateTime.Now)//即将超期 未办
+        .WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime)
+        .WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime)
+        .Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
+        .Where(d => d.Status != EOrderStatus.BackToProvince && d.Status < EOrderStatus.Filed)
+        .OrderBy(d => d.Status)
+        .OrderByIF(dto.IsHandled == true, d => d.StartTime, OrderByType.Desc)
+        .OrderByIF(dto.IsHandled == false, d => d.CreationTime, OrderByType.Desc)
+        .Select((d, step) => d)
+        .ToPagedListAsync(dto, HttpContext.RequestAborted);
+
+        var page2 = new PagedDto<OrderDto>(total2, _mapper.Map<IReadOnlyList<OrderDto>>(items2));
 
         return new { Waited = page1, Sign = page2 };
     }
@@ -3761,8 +3762,8 @@ public class OrderController : BaseController
             //if (dto.AlterTime)
             //{
             var expiredTime = _timeLimitDomainService.CalcEndTime(DateTime.Now, order.AcceptTypeCode);
-            var processType = dto.FlowDirection is EFlowDirection.OrgToCenter or EFlowDirection.CenterToCenter or EFlowDirection.FiledToCenter 
-                ? EProcessType.Zhiban 
+            var processType = dto.FlowDirection is EFlowDirection.OrgToCenter or EFlowDirection.CenterToCenter or EFlowDirection.FiledToCenter
+                ? EProcessType.Zhiban
                 : EProcessType.Jiaoban;
             //var expiredTime = _timeLimitDomainService.CalcEndTime(DateTime.Now,
             //	ETimeType.WorkDay,
@@ -5019,7 +5020,7 @@ public class OrderController : BaseController
         order.Sign(_sessionContext.RequiredUserId, _sessionContext.UserName);
         order.AutoAccept(_sessionContext.RequiredUserId, _sessionContext.UserName, _sessionContext.StaffNo);
 
-		if (!string.IsNullOrEmpty(order.WorkflowId))
+        if (!string.IsNullOrEmpty(order.WorkflowId))
         {
             var workflow = await _workflowDomainService.SignToSomebodyAsync(
                 order.WorkflowId,
@@ -5614,7 +5615,7 @@ public class OrderController : BaseController
 
                 orderData.SourceChannel = "其他";
                 orderData.SourceChannelCode = "QT";
-                await _orderRepository.UpdateAsync(orderData, HttpContext.RequestAborted);
+                // await _orderRepository.UpdateAsync(orderData, HttpContext.RequestAborted);
 
                 //向省上推送数据
                 if (dto.IsPush)
@@ -5648,12 +5649,11 @@ public class OrderController : BaseController
     [HttpGet("migration/{orderId}")]
     public async Task<GetOrderMigrationDto> Migration(string orderId)
     {
+        var order = await _orderRepository.GetAsync(orderId, HttpContext.RequestAborted);
         var steps = await _workflowStepRepository.Queryable()
             .Where(d => d.ExternalId == orderId && d.Status != EWorkflowStepStatus.Handled)
             .ToListAsync(HttpContext.RequestAborted);
 
-        if (!steps.Any())
-            throw new UserFriendlyException("未查询到待办理节点");
         if (steps.Count > 1)
             throw new UserFriendlyException("多个待办理节点暂不支持平移");
         var step = steps.First();
@@ -5663,6 +5663,12 @@ public class OrderController : BaseController
         var setting = step.BusinessType is EBusinessType.Center
             ? _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi)
             : _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan);
+        //未受理 已签到工单处理
+        if (string.IsNullOrEmpty(order.WorkflowId))
+        {
+            step = new WorkflowStep();
+            setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi);
+        }
         var roles = setting?.SettingValue.ToList();
         var users = await _userRepository.Queryable()
             .Includes(d => d.Organization)
@@ -5672,6 +5678,7 @@ public class OrderController : BaseController
         return new GetOrderMigrationDto
         {
             StepId = step.Id,
+            OrderId = orderId,
             Handlers = users.Select(d => new OrderMigrationHandler
             {
                 UserId = d.Id,
@@ -5683,5 +5690,30 @@ public class OrderController : BaseController
         };
     }
 
+
+    /// <summary>
+    /// 工单平移
+    /// </summary>
+    [HttpPost("change-handler")]
+    public async Task ChangeHandler([FromBody] ChangeHandlerDto dto)
+    {
+        if (string.IsNullOrEmpty(dto.StepId))
+        {
+            await _orderRepository.Updateable().SetColumns(o => new Orders.Order() { SignerId = dto.Handler.UserId, SignerName = dto.Handler.Username })
+                .Where(o => o.Id == dto.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
+        }
+        else
+        {
+            var step = await _workflowStepRepository.Queryable()
+                .Includes(d => d.WorkflowTrace)
+                .FirstAsync(d => d.Id == dto.StepId, HttpContext.RequestAborted);
+            if (step is null)
+                throw new UserFriendlyException("无效节点编号");
+            await _workflowDomainService.ChangeHandlerBatchAsync(new List<(string userId, string username, string orgId, string orgName, ICollection<WorkflowStep> steps)>
+            {
+                new(dto.Handler.UserId,dto.Handler.Username,dto.Handler.OrgId,dto.Handler.OrgName, new List<WorkflowStep>{step})
+            }, HttpContext.RequestAborted);
+        }
+    }
     #endregion
 }

+ 4 - 0
src/Hotline.Application/Mappers/MapperConfigs.cs

@@ -3,6 +3,7 @@ using Hotline.JudicialManagement;
 using Hotline.Orders;
 using Hotline.Push.FWMessage;
 using Hotline.Settings;
+using Hotline.Share.Dtos.Ai;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.JudicialManagement;
 using Hotline.Share.Dtos.OrderExportWord;
@@ -37,6 +38,8 @@ namespace Hotline.Application.Mappers
 
             #endregion
 
+            
+
             config.ForType<EnforcementOrders, EnforcementOrderListDto>()
                 .Map(d => d.Id, x => x.Id)
                 .Map(d => d.WorkflowId, x => x.Order.WorkflowId)
@@ -84,6 +87,7 @@ namespace Hotline.Application.Mappers
              .Map(d => d.ExpiredTime, x => x.ExpiredTime == null ? "" : x.ExpiredTime.Value.ToString("yyyy-MM-dd HH:mm:ss"))
              ;
 
+           
         }
     }
 }

+ 33 - 0
src/Hotline.Application/Mappers/OrderMapperConfigs.cs

@@ -1,7 +1,9 @@
 using Hotline.FlowEngine.Workflows;
 using Hotline.Orders;
+using Hotline.Share.Dtos.Ai;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Settings;
+using Hotline.Share.Enums.Order;
 using Mapster;
 
 namespace Hotline.Application.Mappers;
@@ -14,6 +16,37 @@ public class OrderMapperConfigs : IRegister
             .IgnoreIf((s, d) => s.OrderExtension == null, d => d.OrderExtension)
             .IgnoreIf((s, d) => s.Hotspot == null, d => d.Hotspot)
             ;
+        //TODO 等待测试
+        config.ForType<AiOrderVisitDetail, AiOrderVisitDetailDto>()
+            .IgnoreIf((s, d) => s.Order == null, d => d.No)
+            .IgnoreIf((s, d) => s.Order == null, d => d.Title)
+            .IgnoreIf((s, d) => s.Order == null, d => d.FromName)
+            .IgnoreIf((s, d) => s.Order == null, d => d.FromGender)
+            .IgnoreIf((s, d) => s.Order == null, d => d.StartTime)
+            .IgnoreIf((s, d) => s.Order == null, d => d.FiledTime)
+            .Map(d => d.No, s => s.Order.No)
+            .Map(d => d.Title, s => s.Order.Title)
+            .Map(d => d.FromName, s => s.Order.FromName)
+            .Map(d => d.FromGender, s => s.Order.FromGender)
+            .Map(d => d.StartTime, s => s.Order.StartTime)
+            .Map(d => d.FiledTime, s => s.Order.FiledTime)
+            //.IgnoreIf((s, d) => s.OrderVisit.OrderVisitDetails == null || !s.OrderVisit.OrderVisitDetails.Any() || s.OrderVisit.OrderVisitDetails.All(x=>x.VisitTarget != Share.Enums.Order.EVisitTarget.Seat), d => d.SeatEvaluate)
+            // .IgnoreIf((s, d) => s.OrderVisit.OrderVisitDetails == null && s.OrderVisit.OrderVisitDetails.Count > 0, d => d.OrgProcessingResults)
+            //.IgnoreIf((s, d) => s.OrderVisit.OrderVisitDetails == null && s.OrderVisit.OrderVisitDetails.Count > 0, d => d.IsContact)
+            //.IgnoreIf((s, d) => s.OrderVisit.OrderVisitDetails == null && s.OrderVisit.OrderVisitDetails.Count > 0, d => d.Volved)
+            //.Ignore(d=>d.SeatEvaluate)
+            //.Map(d=>d.SeatEvaluate, s=>s.OrderVisit.OrderVisitDetails.First(x=> x.VisitTarget == EVisitTarget.Seat))
+            .AfterMapping((s, d) =>
+            {
+                d.SeatEvaluate = s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Seat)?.SeatEvaluate;
+                d.OrgProcessingResults = s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org)?.OrgProcessingResults?.Value;
+                d.IsContact = s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org)?.IsContact == true ? "是" : "否";
+                d.Volved = s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org)?.Volved == true ? "是" : "否";
+                d.IsSuccess = s.IsSuccess == true ? "是" : "否";
+            })
+            ;
+
+
 
         config.ForType<AddOrderDto, Order>()
             .IgnoreIf((s, d) => s.OrderExtension == null, d => d.OrderExtension)

+ 28 - 0
src/Hotline.Application/Orders/IOrderApplication.cs

@@ -96,5 +96,33 @@ namespace Hotline.Application.Orders
         /// <param name="dto"></param>
         /// <returns></returns>
         ISugarQueryable<Order> QueryOrderSourceDetail(QueryOrderSourceDetailRequest dto);
+
+		/// <summary>
+		/// 部门超期统计
+		/// </summary>
+		/// <param name="dto"></param>
+		/// <returns></returns>
+		ISugarQueryable<OrderBiOrgDataListVo> QueryOrgDataList(ReportPagedRequest dto);
+
+        /// <summary>
+        /// 部门超期统计明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+		ISugarQueryable<Order> QueryOrgDataListDetail(OrgDataListDetailRequest dto);
+
+		/// <summary>
+		/// 回退错件统计
+		/// </summary>
+		/// <param name="dto"></param>
+		/// <returns></returns>
+		ISugarQueryable<OrderReTransactVo> OrderReTransact(QueryOrderReTransactRequest dto);
+
+		/// <summary>
+		/// 回退错件明细统计
+        /// </summary>
+		/// <param name="dto"></param>
+		/// <returns></returns>
+		ISugarQueryable<OrderSpecialDetail> QueryOrderSourceDetail(QueryOrderReTransactDetailRequest dto);
 	}
 }

+ 171 - 8
src/Hotline.Application/Orders/OrderApplication.cs

@@ -32,6 +32,7 @@ using XF.Domain.Constants;
 using XF.Domain.Dependency;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
+using Hotline.Repository.SqlSugar.System;
 
 namespace Hotline.Application.Orders;
 
@@ -51,8 +52,11 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
     private readonly IQualityApplication _qualityApplication;
     private readonly ICapPublisher _capPublisher;
+    private readonly IRepository<SystemOrganize> _systemOrganizeRepository;
+    private readonly IRepository<WorkflowCountersign> _workflowCountersignRepository;
+    private readonly IRepository<OrderSpecialDetail> _orderSpecialDetailRepository;
 
-    public OrderApplication(
+	public OrderApplication(
         IOrderDomainService orderDomainService,
         IOrderRepository orderRepository,
         IWorkflowDomainService workflowDomainService,
@@ -66,8 +70,11 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         IRepository<OrderVisit> orderVisitRepository,
         IRepository<OrderVisitDetail> orderVisitDetailRepository,
         IQualityApplication qualityApplication,
-        ICapPublisher capPublisher
-        )
+        ICapPublisher capPublisher,
+        IRepository<SystemOrganize> systemOrganizeRepository,
+        IRepository<WorkflowCountersign> workflowCountersignRepository,
+        IRepository<OrderSpecialDetail> orderSpecialDetailRepository
+		)
     {
         _orderDomainService = orderDomainService;
         _workflowDomainService = workflowDomainService;
@@ -83,7 +90,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _orderVisitDetailRepository = orderVisitDetailRepository;
         _qualityApplication = qualityApplication;
         _capPublisher = capPublisher;
-    }
+		_systemOrganizeRepository = systemOrganizeRepository;
+		_workflowCountersignRepository = workflowCountersignRepository;
+        _orderSpecialDetailRepository = orderSpecialDetailRepository;
+	}
 
     /// <summary>
     /// 更新工单办理期满时间(延期调用,其他不调用)
@@ -568,15 +578,168 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .Where(d => d.SourceChannel != null && d.SourceChannel != "");
     }
 
-    #region private
+    /// <summary>
+    /// 部门超期统计
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public ISugarQueryable<OrderBiOrgDataListVo> QueryOrgDataList(ReportPagedRequest dto)
+    {
+		if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
+
+		dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
+
+		var IsCenter = _sessionContext.OrgIsCenter;
+
+
+		var queryOrder = _systemOrganizeRepository.Queryable()
+			.LeftJoin<Order>((x, o) => x.Id == o.ActualHandleOrgCode)
+			.WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= dto.StartTime)
+			.WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= dto.EndTime)
+			.WhereIF(IsCenter == false, (x, o) => o.ActualHandleOrgCode == _sessionContext.RequiredOrgId)
+			.GroupBy((x, o) => new { x.Id, x.Name })
+			.Select((x, o) => new OrderBiOrgDataListVo
+			{
+				OrgName = x.Name,
+				OrgId = x.Id,
+				HandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.Status >= EOrderStatus.Filed && o.ExpiredTime < o.FiledTime, 1, 0)),
+				NoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.Status < EOrderStatus.Filed && o.ExpiredTime < SqlFunc.GetDate(), 1, 0)),
+			}).MergeTable();
+
+		var queryCountersign = _workflowCountersignRepository.Queryable()
+			.LeftJoin<WorkflowCountersignMember>((x, o) => x.Id == o.WorkflowCountersignId)
+			.WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
+			.WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
+			.GroupBy((x, o) => o.Key)
+			.Select((x, o) => new OrderBiOrgDataListVo
+			{
+				OrgId = o.Key,
+				CounterHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.IsHandled && x.IsExpired.HasValue && x.IsExpired.Value == true, 1, 0)),
+				CounterNoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.IsHandled == false && x.IsExpired.HasValue && x.IsExpired.Value == true, 1, 0)),
+			}).MergeTable();
+
+		var query = queryOrder.LeftJoin(queryCountersign, (or, co) => or.OrgId == co.OrgId)
+			.LeftJoin<SystemOrganize>((or, co, so) => or.OrgId.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")) == so.Id)
+			.GroupBy((or, co, so) => new { so.Id, so.Name })
+			.Select((or, co, so) => new OrderBiOrgDataListVo
+			{
+				OrgName = so.Name,
+				OrgId = so.Id,
+				HandlerExtendedNum = SqlFunc.AggregateSum(or.HandlerExtendedNum),
+				NoHandlerExtendedNum = SqlFunc.AggregateSum(or.NoHandlerExtendedNum),
+				CounterHandlerExtendedNum = SqlFunc.AggregateSum(co.CounterHandlerExtendedNum),
+				CounterNoHandlerExtendedNum = SqlFunc.AggregateSum(co.CounterNoHandlerExtendedNum)
+			}).MergeTable();
+
+		query = query.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrgName.Contains(dto.Keyword!)).Where(x => x.HandlerExtendedNum > 0 || x.NoHandlerExtendedNum > 0 || x.CounterHandlerExtendedNum > 0 || x.CounterNoHandlerExtendedNum > 0);
+		switch (dto.SortField)
+		{
+			case "handlerExtendedNum":
+				query = dto.SortRule == 0 ? query.OrderBy(x => x.HandlerExtendedNum) : query.OrderByDescending(x => x.HandlerExtendedNum);
+				break;
+			case "counterHandlerExtendedNum":
+				query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterHandlerExtendedNum) : query.OrderByDescending(x => x.CounterHandlerExtendedNum);
+				break;
+			case "noHandlerExtendedNum":
+				query = dto.SortRule == 0 ? query.OrderBy(x => x.NoHandlerExtendedNum) : query.OrderByDescending(x => x.NoHandlerExtendedNum);
+				break;
+			case "counterNoHandlerExtendedNum":
+				query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterNoHandlerExtendedNum) : query.OrderByDescending(x => x.CounterNoHandlerExtendedNum);
+				break;
+		}
+        return query;
+	}
 
     /// <summary>
-    /// 接受外部工单(除省平台)
+    /// 部门超期统计明细
     /// </summary>
     /// <param name="dto"></param>
-    /// <param name="cancellationToken"></param>
     /// <returns></returns>
-    private async Task<AddOrderResponse> ReceiveOrderFromOtherPlatformAsync(AddOrderDto dto, List<FileDto> files,
+	public ISugarQueryable<Order> QueryOrgDataListDetail(OrgDataListDetailRequest dto)
+	{
+		dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);
+
+		var quer = _orderRepository.Queryable()
+			.InnerJoin<SystemOrganize>((x, so) => x.ActualHandleOrgCode == so.Id)
+			.Where(x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime)
+			.WhereIF(dto.QueryType == 1, x => x.Status >= EOrderStatus.Filed && x.ExpiredTime < x.FiledTime) //业务已办超期
+			.WhereIF(dto.QueryType == 3, x => x.Status < EOrderStatus.Filed && x.ExpiredTime < SqlFunc.GetDate()) //业务待办超期
+			.WhereIF(dto.QueryType == 5, x =>
+				(x.Status >= EOrderStatus.Filed && x.ExpiredTime < x.FiledTime) || (x.Status < EOrderStatus.Filed && x.ExpiredTime < SqlFunc.GetDate()))
+			.WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.QueryType is 1 or 3 && dto.OrgCode == "001", x => x.ActualHandleOrgCode == dto.OrgCode)
+			.WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.QueryType is 1 or 3 && dto.OrgCode != "001", x => x.ActualHandleOrgCode.StartsWith(dto.OrgCode))
+			.MergeTable();
+
+		if (dto.QueryType is 2 or 4 or 5)
+		{
+			var queryCountersign = _workflowCountersignRepository.Queryable()
+				.LeftJoin<WorkflowCountersignMember>((x, o) => x.Id == o.WorkflowCountersignId)
+				.Where((x, o) => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime && x.IsExpired.HasValue && x.IsExpired.Value == true)
+				.WhereIF(dto.QueryType == 2, (x, o) => o.IsHandled == true) //会签已办超期
+				.WhereIF(dto.QueryType == 4, (x, o) => o.IsHandled == false) //会签待办超期
+				.WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.QueryType is 2 or 4 or 5, (x, o) => o.Key.StartsWith(dto.OrgCode))
+				//.GroupBy((x,o)=>x.WorkflowId)
+				.Select((x, o) => new { Id = x.WorkflowId })
+				.MergeTable();
+
+			quer = quer.InnerJoin(queryCountersign, (x, c) => x.WorkflowId == c.Id);
+
+		}
+        return quer;
+	}
+
+    /// <summary>
+    /// 回退错件统计
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public ISugarQueryable<OrderReTransactVo> OrderReTransact(QueryOrderReTransactRequest dto)
+    {
+
+		return _orderSpecialDetailRepository.Queryable()
+			.Includes(x => x.OrderSpecial)
+			.WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.OrgName.Contains(dto.OrgName!))
+			.Where(x => x.OrderSpecial.ESpecialType == ESpecialType.ReTransact)
+			.Where(x => x.OrderSpecial.CreationTime >= dto.StartTime)
+			.Where(x => x.OrderSpecial.CreationTime <= dto.EndTime)
+			.GroupBy(x => new { Time = x.OrderSpecial.CreationTime.ToString("yyyy-MM-dd"), x.OrgId, x.OrgName })
+			.Select(x => new OrderReTransactVo
+			{
+				Time = x.OrderSpecial.CreationTime.ToString("yyyy-MM-dd"),
+				OrgId = x.OrgId,
+				OrgName = x.OrgName,
+				Num = SqlFunc.AggregateCount(1)
+			}).MergeTable()
+			.OrderByIF(dto.SortRule == 0, x => x.Num, OrderByType.Asc)
+			.OrderByIF(dto.SortRule == 1, x => x.Num, OrderByType.Desc); ;
+    }
+    /// <summary>
+    /// 回退错件明细统计
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public ISugarQueryable<OrderSpecialDetail> QueryOrderSourceDetail(QueryOrderReTransactDetailRequest dto)
+    {
+
+	    return  _orderSpecialDetailRepository.Queryable()
+		    .Includes(x => x.OrderSpecial, s => s.Order)
+		    .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.OrgName.Contains(dto.OrgName!))
+		    .WhereIF(!string.IsNullOrEmpty(dto.ErrorName), x => x.ErrorName.Contains(dto.ErrorName!))
+		    .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.OrderSpecial!.Order!.No!.Contains(dto.No!))
+		    .Where(x => x.OrderSpecial.ESpecialType == ESpecialType.ReTransact)
+		    .Where(x => x.OrderSpecial.CreationTime >= dto.StartTime)
+		    .Where(x => x.OrderSpecial.CreationTime <= dto.EndTime);
+	}
+
+	#region private
+
+	/// <summary>
+	/// 接受外部工单(除省平台)
+	/// </summary>
+	/// <param name="dto"></param>
+	/// <param name="cancellationToken"></param>
+	/// <returns></returns>
+	private async Task<AddOrderResponse> ReceiveOrderFromOtherPlatformAsync(AddOrderDto dto, List<FileDto> files,
         ISessionContext current, CancellationToken cancellationToken)
     {
         if (string.IsNullOrEmpty(dto.ExternalId))

+ 58 - 1
src/Hotline.Share/Dtos/Ai/AiDto.cs

@@ -1,5 +1,6 @@
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.Ai;
+using Hotline.Share.Enums.Order;
 using Hotline.Share.Requests;
 using System;
 using System.Collections.Generic;
@@ -310,6 +311,62 @@ namespace Hotline.Share.Dtos.Ai
         /// </summary>
         public string OrderId { get; set; }
 
+        /// <summary>
+        /// 工单号
+        /// </summary>
+        public string No { get; set; }
+        /// <summary>
+        /// 工单标题
+        /// </summary>
+        public string Title { get; set; }
+
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        public string FromName { get; set; }
+
+        /// <summary>
+        /// 来电/信人性别
+        /// </summary>
+        public EGender FromGender { get; set; }
+
+        /// <summary>
+        /// 来电/信人性别
+        /// </summary>
+        public string FromGenderText => FromGender.GetDescription();
+
+        /// <summary>
+        /// 工单开始时间(受理/接办时间=流程开启时间)
+        /// </summary>
+        public DateTime? StartTime { get; set; }
+
+        /// <summary>
+        /// 归档时间(暂为流程结束时间,因流程结束自动归档)
+        /// </summary>
+        public DateTime? FiledTime { get; set; }
+
+        /// <summary>
+        /// 话务员评价
+        /// </summary>
+        public ESeatEvaluate? SeatEvaluate { get; set; }
+
+        public string SeatEvaluateText => SeatEvaluate.GetDescription();
+
+        /// <summary>
+        /// 部门办件结果
+        /// </summary>
+        public string? OrgProcessingResults { get; set; }
+
+        /// <summary>
+        /// 是否联系
+        /// </summary>
+        public string? IsContact { get; set; }
+
+        /// <summary>
+        /// 处理结果
+        /// </summary>
+        public string? Volved { get; set; }
+
         /// <summary>
         /// 工单
         /// </summary>
@@ -339,7 +396,7 @@ namespace Hotline.Share.Dtos.Ai
         /// <summary>
         /// 是否成功
         /// </summary>
-        public bool? IsSuccess { get; set; }
+        public string? IsSuccess { get; set; }
     }
 
     public class CanAiVisitListDto

+ 2 - 1
src/Hotline.Share/Dtos/FlowEngine/Workflow/ChangeHandlerDto.cs

@@ -5,5 +5,6 @@ namespace Hotline.Share.Dtos.FlowEngine.Workflow;
 public class ChangeHandlerDto
 {
     public string StepId { get; set; }
-    public FlowStepHandler Handler { get; set; }
+    public string OrderId { get; set; }
+	public FlowStepHandler Handler { get; set; }
 }

+ 3 - 1
src/Hotline.Share/Dtos/Order/Migration/GetOrderMigrationDto.cs

@@ -10,7 +10,9 @@ namespace Hotline.Share.Dtos.Order.Migration
     public class GetOrderMigrationDto
     {
         public string StepId { get; set; }
-        public IReadOnlyList<OrderMigrationHandler> Handlers { get; set; }
+        public string OrderId { get; set; }
+		
+		public IReadOnlyList<OrderMigrationHandler> Handlers { get; set; }
     }
 
     public class OrderMigrationHandler : FlowStepHandler