Эх сурвалжийг харах

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

xf 8 сар өмнө
parent
commit
024a873ae2

+ 110 - 2
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -2660,8 +2660,8 @@ namespace Hotline.Api.Controllers.Bi
             var itemsVo = _mapper.Map<IReadOnlyList<UnsignedOrderDto>>(items);
             var itemsVo = _mapper.Map<IReadOnlyList<UnsignedOrderDto>>(items);
             foreach (var item in itemsVo)
             foreach (var item in itemsVo)
             {
             {
-                item.UnsignedTime = _timeLimitDomainService.CalcWorkTimeToHour(item.WorkflowStep.CreationTime, item.WorkflowStep.Status == EWorkflowStepStatus.WaitForAccept ? DateTime.Now : item.WorkflowStep.AcceptTime!.Value, false);
-            }
+				item.UnsignedTime = _timeLimitDomainService.CalcWorkTimeToHour(item.WorkflowStep.CreationTime, item.WorkflowStep.Status != EWorkflowStepStatus.WaitForAccept && item.WorkflowStep.AcceptTime.HasValue ? item.WorkflowStep.AcceptTime!.Value : DateTime.Now, false);
+			}
             return new PagedDto<UnsignedOrderDto>(total, itemsVo);
             return new PagedDto<UnsignedOrderDto>(total, itemsVo);
         }
         }
 
 
@@ -3689,5 +3689,113 @@ namespace Hotline.Api.Controllers.Bi
 
 
             return ExcelStreamResult(stream, "未签收统计明细数据");
             return ExcelStreamResult(stream, "未签收统计明细数据");
         }
         }
+
+        /// <summary>
+        /// 企业专席信件统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("get_enterprise_seats_report")]
+        public async Task<object> GetEnterpriseSeatsReport([FromQuery] EnterpriseSeatsReportRequestDto dto)
+        {
+            var items = await _orderReportApplication.GetEnterpriseSeatsReport(dto);
+
+            var total = new EnterpriseSeatsReportDto
+            {
+                UserName = "合计",
+                UserId = "",
+                UserNo = "",
+                TelCallNum = items.Sum(p => p.TelCallNum),
+                OrderNum = items.Sum(p => p.OrderNum),
+            };
+
+            return new { List = items, Total = total };
+        }
+
+        /// <summary>
+        /// 企业专席信件统计--导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("get_enterprise_seats_report_export")]
+        public async Task<FileStreamResult> ExportGetEnterpriseSeatsReport([FromBody] ExportExcelDto<EnterpriseSeatsReportRequestDto> dto)
+        {
+            var list = await _orderReportApplication.GetEnterpriseSeatsReport(dto.QueryDto);
+
+            //增加合计
+            list.Add(new EnterpriseSeatsReportDto
+            {
+                UserName = "合计",
+                UserId = "",
+                UserNo = "",
+                TelCallNum = list.Sum(p => p.TelCallNum),
+                OrderNum = list.Sum(p => p.OrderNum),
+            });
+
+            var orderDtos = _mapper.Map<ICollection<EnterpriseSeatsReportDto>>(list);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = orderDtos
+                .Select(stu => _mapper.Map(stu, typeof(EnterpriseSeatsReportDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "企业专席信件统计");
+        }
+
+        /// <summary>
+        /// 企业专席信件统计--明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("get_enterprise_seats_report_detail")]
+        public async Task<PagedDto<OrderDto>> GetEnterpriseSeatsReportDetail([FromQuery] EnterpriseSeatsReportRequestDto dto)
+        {
+            RefAsync<int> total = 0;
+            var queryData = await _orderReportApplication.GetEnterpriseSeatsReportDetail(dto)
+                        .ToPageListAsync(dto.PageIndex, dto.PageSize, total, HttpContext.RequestAborted);
+
+            return new PagedDto<OrderDto>(total, _mapper.Map<List<OrderDto>>(queryData));
+        }
+
+        /// <summary>
+        /// 企业专席信件统计--明细--导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("get_enterprise_seats_report_detail_export")]
+        public async Task<FileStreamResult> ExportGetEnterpriseSeatsReportDetail([FromBody] ExportExcelDto<EnterpriseSeatsReportRequestDto> dto)
+        {
+            var query = _orderReportApplication.GetEnterpriseSeatsReportDetail(dto.QueryDto);
+
+            List<OrderDto> list = new();
+            if (dto.IsExportAll)
+            {
+                var listData = await query.ToListAsync(HttpContext.RequestAborted);
+                list = _mapper.Map<List<OrderDto>>(listData);
+            }
+            else
+            {
+                RefAsync<int> total = 0;
+                var listData = await query.ToPageListAsync(dto.QueryDto.PageIndex, dto.QueryDto.PageSize, total, HttpContext.RequestAborted);
+                list = _mapper.Map<List<OrderDto>>(listData);
+            }
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = list
+                .Select(stu => _mapper.Map(stu, typeof(OrderDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "企业专席信件统计");
+        }
+
+
     }
     }
 }
 }

+ 388 - 51
src/Hotline.Api/Controllers/CommonPController.cs

@@ -21,63 +21,75 @@ using XF.Domain.Authentications;
 using XF.Domain.Exceptions;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 using Hotline.Configurations;
 using Hotline.Configurations;
+using Hotline.Share.Dtos.Order;
+using System.Runtime.InteropServices;
+using Lucene.Net.Util;
 
 
 namespace Hotline.Api.Controllers
 namespace Hotline.Api.Controllers
 {
 {
-    /// <summary>
-    /// 常用意见接口
-    /// </summary>
-    public class CommonPController : BaseController
-    {
-        private readonly ISystemCommonOpinionDomainService _commonOpinionDomainService;
-        private readonly ISystemAreaDomainService _systemAreaDomainService;
-        private readonly IMapper _mapper;
-        private readonly ISessionContext _sessionContext;
-        // private readonly IRepository<TrCallRecord> _trCallRecordRepository;
-        private readonly IOrderRepository _orderRepository;
-        private readonly IOrderDelayRepository _orderDelayRepository;
-        private readonly ITimeLimitDomainService _timeLimitDomainService;
-        private readonly IOrderScreenRepository _orderScreenRepository;
-        private readonly IRepository<OrderVisitDetail> _orderVisitedDetailRepository;
-        private readonly ICallApplication _callApplication;
-        private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
+	/// <summary>
+	/// 常用意见接口
+	/// </summary>
+	public class CommonPController : BaseController
+	{
+		private readonly ISystemCommonOpinionDomainService _commonOpinionDomainService;
+		private readonly ISystemAreaDomainService _systemAreaDomainService;
+		private readonly IMapper _mapper;
+		private readonly ISessionContext _sessionContext;
+		// private readonly IRepository<TrCallRecord> _trCallRecordRepository;
+		private readonly IOrderRepository _orderRepository;
+		private readonly IOrderDelayRepository _orderDelayRepository;
+		private readonly ITimeLimitDomainService _timeLimitDomainService;
+		private readonly IOrderScreenRepository _orderScreenRepository;
+		private readonly IRepository<OrderVisitDetail> _orderVisitedDetailRepository;
+		private readonly ICallApplication _callApplication;
+		private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
+		private readonly IOrderDomainService _orderDomainService;
+		private readonly IRepository<OrderVisit> _orderVisitRepository;
+		private readonly IRepository<OrderSendBackAudit> _orderSendBackAuditRepository;
 
 
-        public CommonPController(
-            ISystemCommonOpinionDomainService commonOpinionDomainService,
-            ISystemAreaDomainService systemAreaDomainService,
-            ISessionContext sessionContext,
-            // IRepository<TrCallRecord> trCallRecordRepository,
-            IOrderRepository orderRepository,
-            IMapper mapper,
-            IOrderDelayRepository orderDelayRepository,
-            ITimeLimitDomainService timeLimitDomainService,
-            IOrderScreenRepository orderScreenRepository,
-            IRepository<OrderVisitDetail> orderVisitedDetailRepository,
-            ICallApplication callApplication,
-            IOptionsSnapshot<AppConfiguration> appOptions)
-        {
-            _commonOpinionDomainService = commonOpinionDomainService;
-            _systemAreaDomainService = systemAreaDomainService;
-            _mapper = mapper;
-            _sessionContext = sessionContext;
-            // _trCallRecordRepository = trCallRecordRepository;
-            _orderRepository = orderRepository;
-            _orderDelayRepository = orderDelayRepository;
-            _timeLimitDomainService = timeLimitDomainService;
-            _orderScreenRepository = orderScreenRepository;
-            _orderVisitedDetailRepository = orderVisitedDetailRepository;
-            _callApplication = callApplication;
-            _appOptions = appOptions;
-        }
+		public CommonPController(
+			ISystemCommonOpinionDomainService commonOpinionDomainService,
+			ISystemAreaDomainService systemAreaDomainService,
+			ISessionContext sessionContext,
+			// IRepository<TrCallRecord> trCallRecordRepository,
+			IOrderRepository orderRepository,
+			IMapper mapper,
+			IOrderDelayRepository orderDelayRepository,
+			ITimeLimitDomainService timeLimitDomainService,
+			IOrderScreenRepository orderScreenRepository,
+			IRepository<OrderVisitDetail> orderVisitedDetailRepository,
+			ICallApplication callApplication,
+			IOptionsSnapshot<AppConfiguration> appOptions,
+			IOrderDomainService orderDomainService,
+			IRepository<OrderVisit> orderVisitRepository,
+			IRepository<OrderSendBackAudit> orderSendBackAuditRepository)
+		{
+			_commonOpinionDomainService = commonOpinionDomainService;
+			_systemAreaDomainService = systemAreaDomainService;
+			_mapper = mapper;
+			_sessionContext = sessionContext;
+			// _trCallRecordRepository = trCallRecordRepository;
+			_orderRepository = orderRepository;
+			_orderDelayRepository = orderDelayRepository;
+			_timeLimitDomainService = timeLimitDomainService;
+			_orderScreenRepository = orderScreenRepository;
+			_orderVisitedDetailRepository = orderVisitedDetailRepository;
+			_callApplication = callApplication;
+			_appOptions = appOptions;
+			_orderDomainService = orderDomainService;
+			_orderVisitRepository = orderVisitRepository;
+			_orderSendBackAuditRepository = orderSendBackAuditRepository;
+		}
 
 
 
 
-        #region 省市区
+		#region 省市区
 
 
-        /// <summary>
-        /// 获取省市区树形
-        /// </summary>
-        /// <returns></returns>
-        [HttpGet("tree-area")]
+		/// <summary>
+		/// 获取省市区树形
+		/// </summary>
+		/// <returns></returns>
+		[HttpGet("tree-area")]
         [Obsolete("请调用sys/area/tree")]
         [Obsolete("请调用sys/area/tree")]
         public async Task<List<SystemArea>> GetAearTree()
         public async Task<List<SystemArea>> GetAearTree()
         {
         {
@@ -198,5 +210,330 @@ namespace Hotline.Api.Controllers
                 ScreenHandle = screenHandle
                 ScreenHandle = screenHandle
             };
             };
         }
         }
-    }
+
+		/// <summary>
+		/// 首页基础数据
+		/// </summary>
+		/// <returns></returns>
+		[HttpGet("home_data_new")]
+		public async Task<Object> GetHomeDataNew()
+		{
+			var allList = new List<HomeOrderDto>();
+			var allNum = 0;
+			var isAdmin = _orderDomainService.IsCheckAdmin();
+			var IsCenter = _sessionContext.OrgIsCenter;
+			if (_sessionContext.OrgIsCenter)
+			{
+				//待办
+				var waitedList = await _orderRepository
+					.Queryable(hasHandled: false, isAdmin: isAdmin)
+					.Includes(d => d.OrderSpecials)
+					.Where(d => d.Status != EOrderStatus.WaitForAccept && d.Status != EOrderStatus.BackToUnAccept && d.Status != EOrderStatus.SpecialToUnAccept && d.Status != EOrderStatus.HandOverToUnAccept)
+					.Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
+					.Where(d => d.Status != EOrderStatus.BackToProvince && d.Status < EOrderStatus.Filed)
+					.Where(d => d.OrderSpecials.Any() == false || d.OrderSpecials.Any(s => s.State > 0))
+					.OrderByDescending(d => new { d.IsUrgent, d.StartTime })
+					.Select(d => new HomeOrderDto
+					{
+						No = d.No,
+						OrderId = d.Id,
+						Title = d.Title,
+						AcceptType = d.AcceptType,
+						HotspotName = d.HotspotName,
+						Type = "Waited",
+						Time = d.ExpiredTime,
+						Status = d.Status,
+						ActualHandleTime = d.ActualHandleTime,
+						CounterSignType = d.CounterSignType
+					})
+					.ToListAsync();
+				allNum += waitedList.Count > 40 ? 40 : waitedList.Count;
+				allList.AddRange(waitedList);
+				// 已超期
+				var waitedExpiredDataList = waitedList.Where(x => (x.Time < DateTime.Now && x.Status < EOrderStatus.Filed) ||
+																  (x.Time < x.ActualHandleTime && x.Status >= EOrderStatus.Filed)).Take(40).ToList();
+				waitedExpiredDataList.ForEach(x => x.Type = "WaitedExpired");
+				allNum += waitedExpiredDataList.Count;
+				allList.AddRange(waitedExpiredDataList);
+				//回访待办
+				var visitDataList = await _orderVisitRepository.Queryable()
+					.Includes(d => d.Order)
+					.Where(d => d.VisitState == EVisitState.WaitForVisit || d.VisitState == EVisitState.NoSatisfiedWaitForVisit)
+					.Where(d => d.EmployeeId == _sessionContext.RequiredUserId)
+					.OrderByDescending(x => x.PublishTime)
+					.Select(d => new HomeOrderDto
+					{
+						No = d.Order.No,
+						OrderId = d.Order.Id,
+						Title = d.Order.Title,
+						AcceptType = d.Order.AcceptType,
+						HotspotName = d.Order.HotspotName,
+						Type = "Visit",
+						Time = d.Order.ExpiredTime,
+						Status = d.Order.Status,
+						CounterSignType = d.Order.CounterSignType
+					})
+					.Take(40)
+					.ToListAsync();
+				allNum += visitDataList.Count;
+				allList.AddRange(visitDataList);
+				//会签待办
+				var signDataList = waitedList.Where(x => x.CounterSignType == ECounterSignType.Center || x.CounterSignType == ECounterSignType.Department).Take(40).ToList();
+				signDataList.ForEach(x => x.Type = "Sign");
+				allNum += signDataList.Count;
+				allList.AddRange(signDataList);
+				//延期待审批
+				var delayDataList = await _orderDelayRepository.Queryable(canView: true, isAdmin: isAdmin)
+					.Includes(d => d.Order)
+					.Where(d => d.DelayState == EDelayState.Examining)
+					.OrderByDescending(d => d.ApplyDelayTime)
+					.Select(d => new HomeOrderDto
+					{
+						No = d.Order.No,
+						OrderId = d.Order.Id,
+						Title = d.Order.Title,
+						AcceptType = d.Order.AcceptType,
+						HotspotName = d.Order.HotspotName,
+						Type = "Delay",
+						Time = d.Order.ExpiredTime,
+						Status = d.Order.Status,
+						CounterSignType = d.Order.CounterSignType
+					}).Take(40)
+					.ToListAsync();
+				allNum += delayDataList.Count;
+				allList.AddRange(delayDataList);
+				//部门即将超期
+				var nearlyExpiredDataList = await _orderRepository.Queryable(canView: !IsCenter)
+					.Includes(d => d.OrderDelays)
+					.Where(d => d.Status < EOrderStatus.Filed && DateTime.Now > d.NearlyExpiredTime && DateTime.Now < d.ExpiredTime)
+					.OrderByDescending(d => d.CreationTime)
+					.Select(d => new HomeOrderDto
+					{
+						No = d.No,
+						OrderId = d.Id,
+						Title = d.Title,
+						AcceptType = d.AcceptType,
+						HotspotName = d.HotspotName,
+						Type = "NearlyExpired",
+						Time = d.ExpiredTime,
+						Status = d.Status,
+						CounterSignType = d.CounterSignType
+					}).Take(40)
+					.ToListAsync();
+				allNum += nearlyExpiredDataList.Count;
+				allList.AddRange(nearlyExpiredDataList);
+				//甄别待审批
+				var screenDataList = await _orderScreenRepository.Queryable(hasHandled: !true, isAdmin: isAdmin)
+					.Includes(d => d.Order)
+					.Includes(d => d.ScreenDetails.Where(sd => sd.AuditUserId == _sessionContext.UserId).OrderByDescending(sd => sd.AuditTime).Take(1).ToList())
+					.Where(d => (d.Status == EScreenStatus.Apply || d.Status == EScreenStatus.Approval || (d.Status == EScreenStatus.SendBack && d.SendBackApply == false)))
+					.Select(d => new HomeOrderDto
+					{
+						No = d.Order.No,
+						OrderId = d.Order.Id,
+						Title = d.Order.Title,
+						AcceptType = d.Order.AcceptType,
+						HotspotName = d.Order.HotspotName,
+						Type = "Screen",
+						Time = d.Order.ExpiredTime,
+						Status = d.Order.Status,
+						CounterSignType = d.Order.CounterSignType
+					}).Take(40)
+					.ToListAsync();
+				allNum += screenDataList.Count;
+				allList.AddRange(screenDataList);
+				//退回待审批
+				var sendBackAuditDataList = await _orderSendBackAuditRepository.Queryable()
+					.Includes(d => d.Order)
+					.Where(d => d.State == ESendBackAuditState.Apply)
+					.WhereIF(_sessionContext.Roles.Contains("role_sysadmin") == false, x => x.SendBackOrgId == _sessionContext.OrgId) // 123 系统管理员;
+					.OrderByDescending(d => d.CreationTime)
+					.Select(d => new HomeOrderDto
+					{
+						No = d.Order.No,
+						OrderId = d.Order.Id,
+						Title = d.Order.Title,
+						AcceptType = d.Order.AcceptType,
+						HotspotName = d.Order.HotspotName,
+						Type = "SendBackAudit",
+						Time = d.Order.ExpiredTime,
+						Status = d.Order.Status,
+						CounterSignType = d.Order.CounterSignType
+					}).Take(40)
+					.ToListAsync();
+				allNum += sendBackAuditDataList.Count;
+				allList.AddRange(sendBackAuditDataList);
+				return new
+				{
+					AllNum = allNum,
+					AllList = allList,
+					WaitedNum = waitedList.Count > 40 ? 40 : waitedList.Count,
+					WaitedList = waitedList.Take(40).ToList(),
+					WaitedExpiredNum = waitedExpiredDataList.Count,
+					WaitedExpiredList = waitedExpiredDataList,
+					VisitListNum = visitDataList.Count,
+					VisitList = visitDataList,
+					SignDataNum = signDataList.Count,
+					SignDataList = signDataList,
+					DelayNum = delayDataList.Count,
+					DelayDataList = delayDataList,
+					NearlyExpiredNum = nearlyExpiredDataList.Count,
+					NearlyExpiredList = nearlyExpiredDataList,
+					ScreenNum = screenDataList.Count,
+					ScreenList = screenDataList,
+					SendBackAuditNum = sendBackAuditDataList.Count,
+					SendBackAuditList = sendBackAuditDataList
+				};
+			}
+			else
+			{
+				//待办
+				var waitedList = await _orderRepository
+					.Queryable(hasHandled: false, isAdmin: isAdmin)
+					.Includes(d => d.OrderSpecials)
+					.Where(d => d.Status != EOrderStatus.WaitForAccept && d.Status != EOrderStatus.BackToUnAccept && d.Status != EOrderStatus.SpecialToUnAccept && d.Status != EOrderStatus.HandOverToUnAccept)
+					.Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
+					.Where(d => d.Status != EOrderStatus.BackToProvince && d.Status < EOrderStatus.Filed)
+					.Where(d => d.OrderSpecials.Any() == false || d.OrderSpecials.Any(s => s.State > 0))
+					.OrderByDescending(d => new { d.IsUrgent, d.StartTime })
+					.Select(d => new HomeOrderDto
+					{
+						No = d.No,
+						OrderId = d.Id,
+						Title = d.Title,
+						AcceptType = d.AcceptType,
+						HotspotName = d.HotspotName,
+						Type = "Waited",
+						Time = d.ExpiredTime,
+						Status = d.Status,
+						ActualHandleTime = d.ActualHandleTime,
+						CounterSignType = d.CounterSignType
+					})
+					.ToListAsync();
+				allNum += waitedList.Count > 40 ? 40 : waitedList.Count;
+				allList.AddRange(waitedList);
+				//已超期
+				var waitedExpiredDataList = waitedList.Where(x => (x.Time < DateTime.Now && x.Status < EOrderStatus.Filed) ||
+																  (x.Time < x.ActualHandleTime && x.Status >= EOrderStatus.Filed)).Take(40).ToList();
+				waitedExpiredDataList.ForEach(x => x.Type = "WaitedExpired");
+				allNum += waitedExpiredDataList.Count;
+				allList.AddRange(waitedExpiredDataList);
+				//会签待办
+				var signDataList = waitedList.Where(x => x.CounterSignType == ECounterSignType.Center || x.CounterSignType == ECounterSignType.Department).Take(40).ToList();
+				signDataList.ForEach(x => x.Type = "Sign");
+				allNum += signDataList.Count;
+				allList.AddRange(signDataList);
+				//甄别待审批
+				var screenDataList = await _orderScreenRepository.Queryable(hasHandled: !true, isAdmin: isAdmin)
+					.Includes(d => d.Order)
+					.Includes(d => d.ScreenDetails.Where(sd => sd.AuditUserId == _sessionContext.UserId).OrderByDescending(sd => sd.AuditTime).Take(1).ToList())
+					.Where(d => (d.Status == EScreenStatus.Apply || d.Status == EScreenStatus.Approval || (d.Status == EScreenStatus.SendBack && d.SendBackApply == false)))
+					.Select(d => new HomeOrderDto
+					{
+						No = d.Order.No,
+						OrderId = d.Order.Id,
+						Title = d.Order.Title,
+						AcceptType = d.Order.AcceptType,
+						HotspotName = d.Order.HotspotName,
+						Type = "Screen",
+						Time = d.Order.ExpiredTime,
+						Status = d.Order.Status,
+						CounterSignType = d.Order.CounterSignType
+					}).Take(40)
+					.ToListAsync();
+				allNum += screenDataList.Count;
+				allList.AddRange(screenDataList);
+				//延期待审批
+				var delayDataList = await _orderDelayRepository.Queryable(canView: true, isAdmin: isAdmin)
+					.Includes(d => d.Order)
+					.Where(d => d.DelayState == EDelayState.Examining)
+					.OrderByDescending(d => d.ApplyDelayTime)
+					.Select(d => new HomeOrderDto
+					{
+						No = d.Order.No,
+						OrderId = d.Order.Id,
+						Title = d.Order.Title,
+						AcceptType = d.Order.AcceptType,
+						HotspotName = d.Order.HotspotName,
+						Type = "Delay",
+						Time = d.Order.ExpiredTime,
+						Status = d.Order.Status,
+						CounterSignType = d.Order.CounterSignType
+					}).Take(40)
+					.ToListAsync();
+				allNum += delayDataList.Count;
+				allList.AddRange(delayDataList);
+				//甄别待申请
+				var screenApplyDataList = await _orderVisitedDetailRepository.Queryable(false, true)
+				.Includes(x => x.OrderVisit)
+				.Includes(x => x.OrderVisit, y => y.Order)
+				.Includes(x => x.OrderVisit, y => y.Employee)
+				.Includes(x => x.OrderScreens)
+				.Where(x => x.OrderScreens.Any(s => s.Status == EScreenStatus.SendBack && s.SendBackApply == true) || x.OrderScreens.Any(s => (s.Status != EScreenStatus.SendBack && s.SendBackApply != true)) == false)
+				.Where(x => x.OrderVisit.VisitState == EVisitState.Visited && x.OrderVisit.IsCanHandle)
+				.Where(x => x.VisitTarget == EVisitTarget.Org && x.VisitOrgCode == _sessionContext.OrgId && (
+					SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1" ||
+					SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "2" ||
+					SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "1" ||
+					SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2"
+				))
+				.OrderByDescending(x => x.CreationTime)
+				.Select(x => new HomeOrderDto
+				{
+					No = x.OrderVisit.Order.No,
+					OrderId = x.OrderVisit.Order.Id,
+					Title = x.OrderVisit.Order.Title,
+					AcceptType = x.OrderVisit.Order.AcceptType,
+					HotspotName = x.OrderVisit.Order.HotspotName,
+					Type = "ScreenApply",
+					Time = x.OrderVisit.Order.ExpiredTime,
+					Status = x.OrderVisit.Order.Status,
+					CounterSignType = x.OrderVisit.Order.CounterSignType
+				}).Take(40).ToListAsync();
+				allNum += screenApplyDataList.Count;
+				allList.AddRange(screenApplyDataList);
+				//退回待审批
+				var sendBackAuditDataList = await _orderSendBackAuditRepository.Queryable()
+					.Includes(d => d.Order)
+					.Where(d => d.State == ESendBackAuditState.Apply)
+					.WhereIF(_sessionContext.Roles.Contains("role_sysadmin") == false, x => x.SendBackOrgId == _sessionContext.OrgId) // 123 系统管理员;
+					.OrderByDescending(d => d.CreationTime)
+					.Select(d => new HomeOrderDto
+					{
+						No = d.Order.No,
+						OrderId = d.Order.Id,
+						Title = d.Order.Title,
+						AcceptType = d.Order.AcceptType,
+						HotspotName = d.Order.HotspotName,
+						Type = "SendBackAudit",
+						Time = d.Order.ExpiredTime,
+						Status = d.Order.Status,
+						CounterSignType = d.Order.CounterSignType
+					}).Take(40)
+					.ToListAsync();
+				allNum += sendBackAuditDataList.Count;
+				allList.AddRange(sendBackAuditDataList);
+				return new
+				{
+					AllNum = allNum,
+					AllList = allList,
+					WaitedNum = waitedList.Count > 40 ? 40 : waitedList.Count,
+					WaitedList = waitedList.Take(40).ToList(),
+					WaitedExpiredNum = waitedExpiredDataList.Count,
+					WaitedExpiredList = waitedExpiredDataList,
+					SignDataNum = signDataList.Count,
+					SignDataList = signDataList,
+					ScreenNum = screenDataList.Count,
+					ScreenList = screenDataList,
+					DelayNum = delayDataList.Count,
+					DelayDataList = delayDataList,
+					ScreenApplyNum = screenApplyDataList.Count,
+					ScreenApplyList = screenApplyDataList,
+					SendBackAuditNum = sendBackAuditDataList.Count,
+					SendBackAuditList = sendBackAuditDataList
+				};
+			}
+		}
+
+	}
 }
 }

+ 3 - 3
src/Hotline.Application/Orders/OrderApplication.cs

@@ -1647,15 +1647,15 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 	    var query = _workflowTraceRepository.Queryable()
 	    var query = _workflowTraceRepository.Queryable()
 		    .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, x => x.HandleTime >= dto.StartTime && x.HandleTime <= dto.EndTime)
 		    .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)
 		    .WhereIF(!string.IsNullOrEmpty(dto.AuditUserName), x => x.HandlerName == dto.AuditUserName)
-            .Where(x=> x.HandlerName != null && x.HandlerName != "" && x.Status == EWorkflowStepStatus.Handled)
+            .Where(x=> x.HandlerName != null && x.HandlerName != "")
             .WhereIF(dto.AuditType is 1,x=>x.Name == "班长审批")
             .WhereIF(dto.AuditType is 1,x=>x.Name == "班长审批")
 		    .WhereIF(dto.AuditType is 2, x => x.Name == "中心领导")
 		    .WhereIF(dto.AuditType is 2, x => x.Name == "中心领导")
 			.GroupBy(x => new { x.HandlerName })
 			.GroupBy(x => new { x.HandlerName })
 		    .Select(x => new OrderScreenAuditVo
 		    .Select(x => new OrderScreenAuditVo
 			{
 			{
 			  AuditName = x.HandlerName,
 			  AuditName = x.HandlerName,
-              AuditNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceState  == EWorkflowTraceState.Normal, 1, 0)),
-              AuditBackNum = SqlFunc.AggregateSum(SqlFunc.IIF( x.TraceState != EWorkflowTraceState.Normal, 1, 0)),
+			  AuditNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceType == EWorkflowTraceType.Normal, 1, 0)),
+			  AuditBackNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceType == EWorkflowTraceType.Previous, 1, 0)),
 			});
 			});
 	    return query;
 	    return query;
     }
     }

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

@@ -152,7 +152,8 @@ namespace Hotline.Application.Orders
                 var order = await _orderRepository.GetAsync(x => x.Id == model.OrderId, cancellationToken);
                 var order = await _orderRepository.GetAsync(x => x.Id == model.OrderId, cancellationToken);
                 if (string.IsNullOrEmpty(order.WorkflowId))
                 if (string.IsNullOrEmpty(order.WorkflowId))
                     throw UserFriendlyException.SameMessage("无效二次办理审批信息,没有找到对应流程信息!");
                     throw UserFriendlyException.SameMessage("无效二次办理审批信息,没有找到对应流程信息!");
-                var step = await _workflowDomainService.FindLastHandleStepAsync(order.WorkflowId, model.ApplyOrgId, cancellationToken);
+                var step = order.CounterSignType == ECounterSignType.Department ?
+                    await _workflowDomainService.FindTopHandleStepAsync(order.WorkflowId, cancellationToken) : await _workflowDomainService.FindLastHandleStepAsync(order.WorkflowId, model.ApplyOrgId, cancellationToken);
                 if (step == null)
                 if (step == null)
                     throw UserFriendlyException.SameMessage("无效二次办理审批信息,没有找到对应流程节点!");
                     throw UserFriendlyException.SameMessage("无效二次办理审批信息,没有找到对应流程节点!");
                 var recall = new RecallDto
                 var recall = new RecallDto

+ 3 - 3
src/Hotline.Application/StatisticalReport/CallReportApplication.cs

@@ -58,7 +58,7 @@ namespace Hotline.Application.StatisticalReport
 
 
             var callData = await _trCallRecordRepository.Queryable()
             var callData = await _trCallRecordRepository.Queryable()
                     .Where(p => p.CreatedTime >= dto.StartTime && p.CreatedTime <= dto.EndTime)
                     .Where(p => p.CreatedTime >= dto.StartTime && p.CreatedTime <= dto.EndTime)
-                   // .Where(p => p.Gateway != "82826886" && SqlFunc.Length(p.Gateway) != 4)
+                     // .Where(p => p.Gateway != "82826886" && SqlFunc.Length(p.Gateway) != 4)
                      .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Gateway == dto.Keyword)
                      .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Gateway == dto.Keyword)
                      .GroupBy(p => p.CreatedTime.ToString("yyyy-MM-dd"))
                      .GroupBy(p => p.CreatedTime.ToString("yyyy-MM-dd"))
                     .Select(p => new QueryCallsDetailDto
                     .Select(p => new QueryCallsDetailDto
@@ -66,7 +66,7 @@ namespace Hotline.Application.StatisticalReport
                         Date = p.CreatedTime.ToString("yyyy-MM-dd"),
                         Date = p.CreatedTime.ToString("yyyy-MM-dd"),
                         InTotal = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In, 1, 0)),//呼入总量
                         InTotal = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In, 1, 0)),//呼入总量
                         InConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.In && p.AnsweredTime != null, 1, 0)),//呼入接通量
                         InConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.In && p.AnsweredTime != null, 1, 0)),//呼入接通量
-                        NotAcceptedHang = SqlFunc.AggregateSum(SqlFunc.IIF(p.Duration == 0 && p.RingTimes <= noConnectByeTimes && p.RingTimes > 0, 1, 0)), //未接通秒挂
+                        NotAcceptedHang = SqlFunc.AggregateSum(SqlFunc.IIF(p.Duration == 0 && p.RingTimes <= noConnectByeTimes && p.RingTimes > 0 && p.CallDirection == ECallDirection.In, 1, 0)), //未接通秒挂
                         TotalDurationIncomingCalls = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.OnState == EOnState.On, p.Duration, 0)), //呼入总时长
                         TotalDurationIncomingCalls = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.OnState == EOnState.On, p.Duration, 0)), //呼入总时长
                         InAvailableAnswer = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration >= effectiveTimes, 1, 0)),//有效接通量
                         InAvailableAnswer = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration >= effectiveTimes, 1, 0)),//有效接通量
                         InHangupImmediateWhenAnswered = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.Duration > 0 && p.Duration <= connectByeTimes, 1, 0)), //呼入接通秒挂
                         InHangupImmediateWhenAnswered = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.Duration > 0 && p.Duration <= connectByeTimes, 1, 0)), //呼入接通秒挂
@@ -98,7 +98,7 @@ namespace Hotline.Application.StatisticalReport
                      .Includes(p => p.Order)
                      .Includes(p => p.Order)
                     .Where(p => p.CreatedTime >= dto.StartTime && p.CreatedTime <= dto.EndTime && p.CallDirection == ECallDirection.In)
                     .Where(p => p.CreatedTime >= dto.StartTime && p.CreatedTime <= dto.EndTime && p.CallDirection == ECallDirection.In)
                     .WhereIF(dto.TypeCode == "2", p => p.OnState == EOnState.On && p.AnsweredTime != null)
                     .WhereIF(dto.TypeCode == "2", p => p.OnState == EOnState.On && p.AnsweredTime != null)
-                   // .Where(p => p.Gateway != "82826886" && SqlFunc.Length(p.Gateway) != 4)
+                     // .Where(p => p.Gateway != "82826886" && SqlFunc.Length(p.Gateway) != 4)
                      .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Gateway == dto.Keyword)
                      .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Gateway == dto.Keyword)
                      .OrderByDescending(p => p.CreatedTime)
                      .OrderByDescending(p => p.CreatedTime)
                     .MergeTable();
                     .MergeTable();

+ 14 - 0
src/Hotline.Application/StatisticalReport/IOrderReportApplication.cs

@@ -133,5 +133,19 @@ namespace Hotline.Application.StatisticalReport
         /// <param name="dto"></param>
         /// <param name="dto"></param>
         /// <returns></returns>
         /// <returns></returns>
         ISugarQueryable<Order> GetOrderNoSigenDetail(OrderNoSigenRequestDto dto);
         ISugarQueryable<Order> GetOrderNoSigenDetail(OrderNoSigenRequestDto dto);
+
+        /// <summary>
+        /// 企业专席信件统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        Task<List<EnterpriseSeatsReportDto>> GetEnterpriseSeatsReport(EnterpriseSeatsReportRequestDto dto);
+
+        /// <summary>
+        /// 企业专席信件统计--明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<Order> GetEnterpriseSeatsReportDetail(EnterpriseSeatsReportRequestDto dto);
     }
     }
 }
 }

+ 91 - 3
src/Hotline.Application/StatisticalReport/OrderReportApplication.cs

@@ -1,17 +1,21 @@
 using Hotline.Application.Orders;
 using Hotline.Application.Orders;
 using Hotline.Caching.Interfaces;
 using Hotline.Caching.Interfaces;
 using Hotline.Caching.Services;
 using Hotline.Caching.Services;
+using Hotline.CallCenter.Calls;
 using Hotline.FlowEngine.WorkflowModules;
 using Hotline.FlowEngine.WorkflowModules;
 using Hotline.FlowEngine.Workflows;
 using Hotline.FlowEngine.Workflows;
+using Hotline.Identity.Accounts;
 using Hotline.Orders;
 using Hotline.Orders;
 using Hotline.Settings;
 using Hotline.Settings;
 using Hotline.Settings.TimeLimits;
 using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Requests;
 using Hotline.Share.Requests;
+using Hotline.Users;
 using JiebaNet.Segmenter.Common;
 using JiebaNet.Segmenter.Common;
 using MapsterMapper;
 using MapsterMapper;
 using MediatR;
 using MediatR;
@@ -40,6 +44,10 @@ namespace Hotline.Application.StatisticalReport
         private readonly IOrderSecondaryHandlingApplication _orderSecondaryHandlingApplication;
         private readonly IOrderSecondaryHandlingApplication _orderSecondaryHandlingApplication;
         private readonly ITimeLimitDomainService _timeLimitDomainService;
         private readonly ITimeLimitDomainService _timeLimitDomainService;
         private readonly IRepository<SystemDicData> _systemDicDataRepository;
         private readonly IRepository<SystemDicData> _systemDicDataRepository;
+        private readonly IRepository<TrCallRecord> _trCallRecordRepository;
+        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
+        private readonly IRepository<User> _userRepository;
+        private readonly IRepository<Account> _accountRepository;
 
 
         /// <summary>
         /// <summary>
         /// 
         /// 
@@ -65,9 +73,12 @@ namespace Hotline.Application.StatisticalReport
             IRepository<OrderScreen> orderScreenRepository,
             IRepository<OrderScreen> orderScreenRepository,
             IOrderSecondaryHandlingApplication orderSecondaryHandlingApplication,
             IOrderSecondaryHandlingApplication orderSecondaryHandlingApplication,
             ITimeLimitDomainService timeLimitDomainService,
             ITimeLimitDomainService timeLimitDomainService,
-            IRepository<SystemDicData> systemDicDataRepository
-,
-            ISystemDicDataCacheManager sysDicDataCacheManager
+            IRepository<SystemDicData> systemDicDataRepository,
+            ISystemDicDataCacheManager sysDicDataCacheManager,
+            IRepository<TrCallRecord> trCallRecordRepository,
+            ISystemSettingCacheManager systemSettingCacheManager,
+            IRepository<User> userRepository,
+            IRepository<Account> accountRepository
             )
             )
         {
         {
             _orderRepository = orderRepository;
             _orderRepository = orderRepository;
@@ -82,6 +93,10 @@ namespace Hotline.Application.StatisticalReport
             _timeLimitDomainService = timeLimitDomainService;
             _timeLimitDomainService = timeLimitDomainService;
             _systemDicDataRepository = systemDicDataRepository;
             _systemDicDataRepository = systemDicDataRepository;
             _sysDicDataCacheManager = sysDicDataCacheManager;
             _sysDicDataCacheManager = sysDicDataCacheManager;
+            _trCallRecordRepository = trCallRecordRepository;
+            _systemSettingCacheManager = systemSettingCacheManager;
+            _userRepository = userRepository;
+            _accountRepository = accountRepository;
         }
         }
         /// <summary>
         /// <summary>
         /// 部门办件统计表---新
         /// 部门办件统计表---新
@@ -1862,5 +1877,78 @@ namespace Hotline.Application.StatisticalReport
                   .MergeTable();
                   .MergeTable();
             }
             }
         }
         }
+
+        /// <summary>
+        /// 企业专席信件统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public async Task<List<EnterpriseSeatsReportDto>> GetEnterpriseSeatsReport(EnterpriseSeatsReportRequestDto dto)
+        {
+            dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);
+
+            //查询坐席信息
+            var enterpriseSeats = _systemSettingCacheManager.GetSetting(SettingConstants.EnterpriseSeats)?.SettingValue;
+            var userData = await _accountRepository.Queryable()
+                  .Where(p => enterpriseSeats.Contains(p.UserName)).Select(p => p.Id).ToListAsync();
+
+            //查询工单
+            var queryOrderData = _orderRepository.Queryable()
+                .Where(p => p.CreationTime >= dto.StartTime && p.CreationTime <= dto.EndTime)
+                .Where(p => userData.Contains(p.SignerId))
+                .WhereIF(!string.IsNullOrEmpty(dto.UserName), p => p.SignerName.Contains(dto.UserName))
+                .GroupBy(p => new { p.SignerId })
+                .Select(p => new EnterpriseSeatsReportDto
+                {
+                    UserId = p.SignerId,
+                    OrderNum = SqlFunc.AggregateSum(SqlFunc.IIF(p.AcceptType != "无效", 1, 0)),
+                })
+                .MergeTable();
+
+            //查询通话
+            var queryCall = _trCallRecordRepository.Queryable()
+                .Where(t => t.CreatedTime >= dto.StartTime && t.CreatedTime <= dto.EndTime && t.OnState == EOnState.On)
+                .Where(t => userData.Contains(t.UserId))
+                .WhereIF(!string.IsNullOrEmpty(dto.UserName), t => t.UserName.Contains(dto.UserName))
+                .GroupBy(t => new { t.UserId })
+                .Select(t => new EnterpriseSeatsReportDto
+                {
+                    UserId = t.UserId,
+                    TelCallNum = SqlFunc.AggregateSum(SqlFunc.IIF(t.CallDirection == ECallDirection.In || t.CallDirection == ECallDirection.Out, 1, 0)),
+                })
+                .MergeTable();
+
+            return await _userRepository.Queryable()
+                .Where(u => userData.Contains(u.Id))
+                .WhereIF(!string.IsNullOrEmpty(dto.UserName), u => u.Name.Contains(dto.UserName))
+                .LeftJoin(queryOrderData, (u, qo) => u.Id == qo.UserId)
+                .LeftJoin(queryCall, (u, qo, qc) => u.Id == qc.UserId)
+                .Select((u, qo, qc) => new EnterpriseSeatsReportDto
+                {
+                    UserName = u.Name,
+                    UserId = u.Id,
+                    UserNo = u.StaffNo,
+                    TelCallNum = qc.TelCallNum,
+                    OrderNum = qo.OrderNum,
+                })
+                .ToListAsync();
+
+        }
+
+        /// <summary>
+        /// 企业专席信件统计--明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public ISugarQueryable<Order> GetEnterpriseSeatsReportDetail(EnterpriseSeatsReportRequestDto dto)
+        {
+            dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);
+
+            return _orderRepository.Queryable()
+                  .Where(o => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && o.SignerId == dto.UserId)
+                  .WhereIF(!string.IsNullOrEmpty(dto.UserName), o => o.SignerName.Contains(dto.UserName))
+               .OrderByDescending(o => o.CreationTime);
+
+        }
     }
     }
 }
 }

+ 27 - 0
src/Hotline.Share/Dtos/Bi/EnterpriseSeatsReportDto.cs

@@ -0,0 +1,27 @@
+namespace Hotline.Share.Dtos.Bi
+{
+    public class EnterpriseSeatsReportDto
+    {
+        /// <summary>
+        /// 坐席名称
+        /// </summary>
+        public string UserName { get; set; }
+
+        public string UserId { get; set; }
+
+        /// <summary>
+        /// 坐席工号
+        /// </summary>
+        public string UserNo { get; set; }
+
+        /// <summary>
+        /// 话务量
+        /// </summary>
+        public int TelCallNum { get; set; }
+
+        /// <summary>
+        /// 工单量
+        /// </summary>
+        public int OrderNum { get; set; }
+    }
+}

+ 64 - 0
src/Hotline.Share/Dtos/Order/HomeOrderDto.cs

@@ -0,0 +1,64 @@
+using Hotline.Share.Enums.FlowEngine;
+using Hotline.Share.Enums.Order;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Share.Dtos.Order
+{
+	public class HomeOrderDto
+	{
+		/// <summary>
+		/// 工单编号
+		/// </summary>
+		public string No { get; set; }
+
+		/// <summary>
+		/// 工单Id
+		/// </summary>
+		public string OrderId { get; set; }
+
+		/// <summary>
+		/// 工单标题
+		/// </summary>
+		public string Title { get; set; }
+
+		/// <summary>
+		/// 受理类型
+		/// </summary>
+		public string? AcceptType { get; set; }
+
+		/// <summary>
+		/// 热点类型
+		/// </summary>
+		public string? HotspotName { get; set; }
+
+		/// <summary>
+		/// 时间
+		/// </summary>
+		public DateTime? Time { get; set; }
+
+		/// <summary>
+		/// 类型
+		/// </summary>
+		public string Type { get; set; }
+
+		/// <summary>
+		/// 会签类型
+		/// </summary>
+		public ECounterSignType? CounterSignType { get; set; }
+
+		/// <summary>
+		/// 工单状态
+		/// </summary>
+		public EOrderStatus Status { get; set; }
+
+		/// <summary>
+		/// 实际办理时间
+		/// </summary>
+		public DateTime? ActualHandleTime { get; set; }
+
+	}
+}

+ 23 - 0
src/Hotline.Share/Requests/OrderNoSigenRequestDto.cs

@@ -37,4 +37,27 @@
         /// </summary>
         /// </summary>
         public int? DataSoure { get; set; }
         public int? DataSoure { get; set; }
     }
     }
+
+    public record EnterpriseSeatsReportRequestDto : PagedRequest
+    {
+        /// <summary>
+        /// 开始时间
+        /// </summary>
+        public DateTime StartTime { get; set; }
+
+        /// <summary>
+        /// 结束时间
+        /// </summary>
+        public DateTime EndTime { get; set; }
+
+        /// <summary>
+        /// 坐席名称
+        /// </summary>
+        public string? UserName { get; set; }
+
+        /// <summary>
+        /// 坐席Id
+        /// </summary>
+        public string? UserId { get; set; }
+    }
 }
 }

+ 10 - 4
src/Hotline/FlowEngine/Workflows/IWorkflowDomainService.cs

@@ -250,10 +250,16 @@ namespace Hotline.FlowEngine.Workflows
         /// <returns></returns>
         /// <returns></returns>
         Task<WorkflowStep> FindLastHandleStepAsync(string workflowId, string orgId, CancellationToken cancellation);
         Task<WorkflowStep> FindLastHandleStepAsync(string workflowId, string orgId, CancellationToken cancellation);
 
 
-        /// <summary>
-        /// 查询流转方向
-        /// </summary>
-        EFlowDirection GetFlowDirection(EBusinessType sourceStepBusinessType, EBusinessType directionStepBusinessType);
+		/// <summary>
+		/// 部门会签工单获取流程最顶级办理节点
+		/// </summary>
+		/// <returns></returns>
+		Task<WorkflowStep> FindTopHandleStepAsync(string workflowId, CancellationToken cancellation);
+
+		/// <summary>
+		/// 查询流转方向
+		/// </summary>
+		EFlowDirection GetFlowDirection(EBusinessType sourceStepBusinessType, EBusinessType directionStepBusinessType);
 
 
         /// <summary>
         /// <summary>
         /// 流程被签收至某个用户(更新流转对象,办理对象,节点办理对象以及stepHandlers)
         /// 流程被签收至某个用户(更新流转对象,办理对象,节点办理对象以及stepHandlers)

+ 13 - 2
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -926,9 +926,20 @@ namespace Hotline.FlowEngine.Workflows
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// 查询流转方向
+        /// 部门会签工单获取流程最顶级办理节点
         /// </summary>
         /// </summary>
-        public EFlowDirection GetFlowDirection(EBusinessType sourceStepBusinessType,
+        /// <returns></returns>
+        public async Task<WorkflowStep> FindTopHandleStepAsync(string workflowId, CancellationToken cancellation)
+        {
+            var workflow = await GetWorkflowAsync(workflowId, withSteps: true, cancellationToken: cancellation);
+
+            return workflow.Steps.First(x => x.Id == x.Workflow.TopCountersignStepId);
+        }
+
+		/// <summary>
+		/// 查询流转方向
+		/// </summary>
+		public EFlowDirection GetFlowDirection(EBusinessType sourceStepBusinessType,
             EBusinessType directionStepBusinessType)
             EBusinessType directionStepBusinessType)
         {
         {
             switch (sourceStepBusinessType)
             switch (sourceStepBusinessType)

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

@@ -464,5 +464,10 @@ namespace Hotline.Settings
         /// 接受短信的角色ID
         /// 接受短信的角色ID
         /// </summary>
         /// </summary>
         public const string AcceptSmsRoleIds = "AcceptSmsRoleIds";
         public const string AcceptSmsRoleIds = "AcceptSmsRoleIds";
+
+        /// <summary>
+        /// 企业专席配置	
+        /// </summary>
+        public const string EnterpriseSeats = "EnterpriseSeats";
     }
     }
 }
 }