xf vor 1 Jahr
Ursprung
Commit
b366f2a075

+ 85 - 2
src/Hotline.Api/Controllers/Bi/BiCallController.cs

@@ -1,8 +1,91 @@
-namespace Hotline.Api.Controllers.Bi;
+using Hotline.CallCenter.Calls;
+using Hotline.Share.Dtos.CallCenter;
+using Hotline.Share.Enums.CallCenter;
+using Hotline.Share.Requests;
+using Hotline.Users;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
+using XF.Domain.Repository;
+
+namespace Hotline.Api.Controllers.Bi;
 
 /// <summary>
 /// 话务报表
 /// </summary>
 public class BiCallController : BaseController
 {
-}
+    private readonly IRepository<TrCallRecord> _trCallRecordRepository;
+    private readonly IRepository<User> _userRepository;
+
+    public BiCallController(
+        IRepository<TrCallRecord> trCallRecordRepository,
+        IRepository<User> userRepository)
+    {
+        _trCallRecordRepository = trCallRecordRepository;
+        _userRepository = userRepository;
+    }
+
+    [HttpGet("calls")]
+    [AllowAnonymous]
+    public async Task<IReadOnlyList<BiCallDto>> QueryCallsAsync([FromQuery] BiQueryCallsDto dto)
+    {
+        dto.StartTime ??= DateTime.Today;
+        dto.EndTime ??= DateTime.Today.AddDays(1).AddSeconds(-1);
+
+        var items = await _trCallRecordRepository.Queryable()
+            .Where(d => d.CreatedTime >= dto.StartTime && d.CreatedTime <= dto.EndTime)
+            .Where(d => d.CallDirection == ECallDirection.In)
+            .WhereIF(!string.IsNullOrEmpty(dto.Line), d => d.Gateway == dto.Line)
+            .Select(d => new
+            {
+                d.CreatedTime.Year,
+                d.CreatedTime.Month,
+                d.CreatedTime.Day,
+                d.CreatedTime.Hour,
+                d.AnsweredTime,
+                d.EndBy
+            })
+            .MergeTable()
+            .GroupBy(d => new
+            {
+                d.Year,
+                d.Month,
+                d.Day,
+                d.Hour
+            })
+            .Select(d => new BiCallDto
+            {
+                Hour = d.Hour,
+                Total = SqlFunc.AggregateCount(d.Hour),
+                Answered = SqlFunc.AggregateSum(SqlFunc.IIF(d.AnsweredTime != null, 1, 0)),
+                Hanguped = SqlFunc.AggregateSum(SqlFunc.IIF(d.AnsweredTime == null && d.EndBy != null && d.EndBy.Value == EEndBy.To, 1, 0))
+            })
+            .OrderBy(d => d.Hour)
+            .ToListAsync(HttpContext.RequestAborted);
+        
+        if (items.Count < 24)
+        {
+            for (var i = 0; i < 24; i++)
+            {
+                var item = items.FirstOrDefault(d => d.Hour == i);
+                if (item is null)
+                    items.Add(new BiCallDto { Hour = i });
+            }
+
+            items = items.OrderBy(d => d.Hour).ToList();
+        }
+
+        return items;
+    }
+
+    [HttpGet("seats")]
+    [AllowAnonymous]
+    public async Task<IReadOnlyList<BiSeatCallsDto>> QuerySeatCallsAsync([FromQuery] ReportPagedRequest dto)
+    {
+        //_userRepository.Queryable()
+        //    .LeftJoin<TrCallRecord>()
+
+        throw new NotImplementedException();
+    }
+}

+ 3 - 3
src/Hotline.Api/Controllers/Bi/BiKnowledgeController.cs

@@ -5,6 +5,7 @@ using Hotline.Share.Enums.KnowledgeBase;
 using Microsoft.AspNetCore.Mvc;
 using SqlSugar;
 using Hotline.Settings;
+using Hotline.Repository.SqlSugar.Extensions;
 
 namespace Hotline.Api.Controllers.Bi
 {
@@ -24,7 +25,6 @@ namespace Hotline.Api.Controllers.Bi
 		[HttpGet("data_list")]
 		public async Task<PagedDto<KnowledgeBiDataListVo>> DataList([FromQuery] KnowledgeBiDataListDto dto)
 		{
-			var total = 0;
 			var query = _knowledgeRepository.Queryable(false,true,false)
 				.LeftJoin<SystemOrganize>((x,o)=>x.SourceOrganizeId == o.Id)
 				.WhereIF(dto.CreationTimeStart.HasValue, (x,o) => x.CreationTime >= dto.CreationTimeStart)
@@ -56,8 +56,8 @@ namespace Hotline.Api.Controllers.Bi
 					query = dto.SortRule == 0 ? query.OrderBy(x => x.PassNum) : query.OrderByDescending(x => x.PassNum);
 					break;
 			}
-            var  items = query.ToPageList(dto.PageIndex, dto.PageSize,ref total);
-			return new PagedDto<KnowledgeBiDataListVo>(total, items);
+            var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
+            return new PagedDto<KnowledgeBiDataListVo>(total, items);
 		}
 	}
 }

+ 96 - 96
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -1,4 +1,5 @@
 using Hotline.Orders;
+using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Settings;
 using Hotline.Share.Dtos.Knowledge;
 using Hotline.Share.Dtos;
@@ -12,102 +13,101 @@ using Hotline.Users;
 
 namespace Hotline.Api.Controllers.Bi
 {
-	public class BiOrderController : BaseController
-	{
-		private readonly IOrderRepository _orderRepository;
-		public BiOrderController(IOrderRepository orderRepository)
-		{
-			_orderRepository = orderRepository;
-		}
+    public class BiOrderController : BaseController
+    {
+        private readonly IOrderRepository _orderRepository;
+        public BiOrderController(IOrderRepository orderRepository)
+        {
+            _orderRepository = orderRepository;
+        }
 
-		/// <summary>
-		/// 部门数据统计
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpGet("org_data_list")]
-		public async Task<PagedDto<OrderBiOrgDataListVo>> OrgDataList([FromQuery] ReportPagedRequest dto)
-		{
-			//TODO 会签统计待处理 目前缺少关联关系
-			var total = 0;
-			var query = _orderRepository.Queryable(false, false, false)
-				.LeftJoin<SystemOrganize>((x, o) => x.ActualHandleOrgCode == o.Id)
-				.WhereIF(dto.CreationTimeStart.HasValue, (x, o) => x.CreationTime >= dto.CreationTimeStart)
-				.WhereIF(dto.CreationTimeEnd.HasValue, (x, o) => x.CreationTime <= dto.CreationTimeEnd)
-				.WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => o.Name.Contains(dto.Keyword!))
-				.GroupBy((x, o) => new { x.ActualHandleOrgCode, o.Name })
-				.Select((x, o) => new OrderBiOrgDataListVo
-				{
-					OrgName = o.Name,
-					OrgId = x.ActualHandleOrgCode,
-					HandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
-					//CounterHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsDeleted, 1, 0)),
-					NoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
-					//CounterNoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.Status == EKnowledgeStatus.OnShelf, 1, 0))
-				}).MergeTable();
-			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;
-			}
-			var items = query.ToPageList(dto.PageIndex, dto.PageSize, ref total);
-			return new PagedDto<OrderBiOrgDataListVo>(total, items);
-		}
+        /// <summary>
+        /// 部门数据统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("org_data_list")]
+        public async Task<PagedDto<OrderBiOrgDataListVo>> OrgDataList([FromQuery] ReportPagedRequest dto)
+        {
+            //TODO 会签统计待处理 目前缺少关联关系
+            var query = _orderRepository.Queryable(false, false, false)
+                .LeftJoin<SystemOrganize>((x, o) => x.ActualHandleOrgCode == o.Id)
+                .WhereIF(dto.StartTime.HasValue, (x, o) => x.CreationTime >= dto.StartTime)
+                .WhereIF(dto.EndTime.HasValue, (x, o) => x.CreationTime <= dto.EndTime)
+                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => o.Name.Contains(dto.Keyword!))
+                .GroupBy((x, o) => new { x.ActualHandleOrgCode, o.Name })
+                .Select((x, o) => new OrderBiOrgDataListVo
+                {
+                    OrgName = o.Name,
+                    OrgId = x.ActualHandleOrgCode,
+                    HandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
+                    //CounterHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsDeleted, 1, 0)),
+                    NoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
+                    //CounterNoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.Status == EKnowledgeStatus.OnShelf, 1, 0))
+                }).MergeTable();
+            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("centre_data_list")]
-		public async Task<PagedDto<OrderBiCentreDataListVo>> CentreDataList([FromQuery] ReportPagedRequest dto) 
-		{
-			var total = 0;
-			var query = _orderRepository.Queryable(false, false, false)
-				.WhereIF(dto.CreationTimeStart.HasValue, x=> x.CreationTime >= dto.CreationTimeStart)
-				.WhereIF(dto.CreationTimeEnd.HasValue, x => x.CreationTime <= dto.CreationTimeEnd)
-				//.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => o.Name.Contains(dto.Keyword!))
-				.GroupBy(x => new { x.AcceptorId,x.AcceptorName })
-				.Select(x => new OrderBiCentreDataListVo
-				{
-					UserName = x.AcceptorName,
-					UserId = x.AcceptorId,
-					CentreArchive = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Zhiban, 1, 0)),
-					CentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Jiaoban, 1, 0)),
-					//NoCentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
-					Invalid = SqlFunc.AggregateSum(SqlFunc.IIF(x.AcceptType == "无效", 1, 0)),
-					Repeat = SqlFunc.AggregateSum(SqlFunc.IIF(x.DuplicateIds != null && x.DuplicateIds.Any(), 1, 0))
-				}).MergeTable();
-			switch (dto.SortField)
-			{
-				case "centreArchive":
-					query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreArchive) : query.OrderByDescending(x => x.CentreArchive);
-					break;
-				case "centreCareOf":
-					query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreCareOf) : query.OrderByDescending(x => x.CentreCareOf);
-					break;
-				case "noCentreCareOf":
-					query = dto.SortRule == 0 ? query.OrderBy(x => x.NoCentreCareOf) : query.OrderByDescending(x => x.NoCentreCareOf);
-					break;
-				case "invalid":
-					query = dto.SortRule == 0 ? query.OrderBy(x => x.Invalid) : query.OrderByDescending(x => x.Invalid);
-					break;
-				case "repeat":
-					query = dto.SortRule == 0 ? query.OrderBy(x => x.Repeat) : query.OrderByDescending(x => x.Repeat);
-					break;
-			}
-			var items = query.ToPageList(dto.PageIndex, dto.PageSize, ref total);
-			return new PagedDto<OrderBiCentreDataListVo>(total, items);
-		}
-	}
+            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")]
+        public async Task<PagedDto<OrderBiCentreDataListVo>> CentreDataList([FromQuery] ReportPagedRequest dto)
+        {
+            var query = _orderRepository.Queryable(false, false, false)
+                .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
+                .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
+                //.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => o.Name.Contains(dto.Keyword!))
+                .GroupBy(x => new { x.AcceptorId, x.AcceptorName })
+                .Select(x => new OrderBiCentreDataListVo
+                {
+                    UserName = x.AcceptorName,
+                    UserId = x.AcceptorId,
+                    CentreArchive = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Zhiban, 1, 0)),
+                    CentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Jiaoban, 1, 0)),
+                    //NoCentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
+                    Invalid = SqlFunc.AggregateSum(SqlFunc.IIF(x.AcceptType == "无效", 1, 0)),
+                    Repeat = SqlFunc.AggregateSum(SqlFunc.IIF(x.DuplicateIds != null && SqlFunc.JsonArrayLength(x.DuplicateIds) > 0, 1, 0))
+                }).MergeTable();
+            switch (dto.SortField)
+            {
+                case "centreArchive":
+                    query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreArchive) : query.OrderByDescending(x => x.CentreArchive);
+                    break;
+                case "centreCareOf":
+                    query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreCareOf) : query.OrderByDescending(x => x.CentreCareOf);
+                    break;
+                case "noCentreCareOf":
+                    query = dto.SortRule == 0 ? query.OrderBy(x => x.NoCentreCareOf) : query.OrderByDescending(x => x.NoCentreCareOf);
+                    break;
+                case "invalid":
+                    query = dto.SortRule == 0 ? query.OrderBy(x => x.Invalid) : query.OrderByDescending(x => x.Invalid);
+                    break;
+                case "repeat":
+                    query = dto.SortRule == 0 ? query.OrderBy(x => x.Repeat) : query.OrderByDescending(x => x.Repeat);
+                    break;
+            }
+            var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
+            return new PagedDto<OrderBiCentreDataListVo>(total, items);
+        }
+    }
 }

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

@@ -13,7 +13,7 @@ namespace Hotline.Repository.SqlSugar.Extensions
     public static class SqlSugarRepositoryExtensions
     {
         public static async Task<(int Total, List<TEntity> Items)> ToPagedListAsync<TEntity>(this ISugarQueryable<TEntity> query, int pageIndex, int pageSize, CancellationToken cancellationToken = default)
-            where TEntity : class, IEntity<string>, new()
+            where TEntity : class, new()
         {
             RefAsync<int> total = 0;
             var items = await query.ToPageListAsync(pageIndex, pageSize, total);
@@ -21,7 +21,7 @@ namespace Hotline.Repository.SqlSugar.Extensions
         }
 
         public static async Task<(int Total, List<TEntity> Items)> ToPagedListAsync<TEntity>(this ISugarQueryable<TEntity> query, PagedRequest dto, CancellationToken cancellationToken = default)
-            where TEntity : class, IEntity<string>, new()
+            where TEntity : class, new()
         {
             RefAsync<int> total = 0;
             var items = await query.ToPageListAsync(dto.PageIndex, dto.PageSize, total);

+ 31 - 0
src/Hotline.Share/Dtos/CallCenter/BiCallDto.cs

@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Share.Dtos.CallCenter
+{
+    public class BiCallDto
+    {
+        /// <summary>
+        /// 小时跨度
+        /// </summary>
+        public string HourRange => Hour == 23 ? "23~24" : $"{Hour:00}~{(Hour + 1):00}";
+
+        public int Hour { get; set; }
+
+        public int Total { get; set; }
+
+        /// <summary>
+        /// 应答量
+        /// </summary>
+        public int Answered { get; set; }
+
+        /// <summary>
+        /// 挂断量
+        /// </summary>
+        public int Hanguped { get; set; }
+
+    }
+}

+ 8 - 3
src/Hotline.Share/Dtos/CallCenter/BiQueryCallsDto.cs

@@ -1,6 +1,11 @@
-namespace Hotline.Share.Dtos.CallCenter;
+using Hotline.Share.Requests;
 
-public class BiQueryCallsDto
+namespace Hotline.Share.Dtos.CallCenter;
+
+public record BiQueryCallsDto: ReportPagedRequest
 {
-    
+    /// <summary>
+    /// 线路
+    /// </summary>
+    public string? Line { get; set; }
 }

+ 97 - 0
src/Hotline.Share/Dtos/CallCenter/BiSeatCallsDto.cs

@@ -0,0 +1,97 @@
+namespace Hotline.Share.Dtos.CallCenter;
+
+/// <summary>
+/// 坐席话务量统计
+/// </summary>
+public class BiSeatCallsDto
+{
+    /// <summary>
+    /// 坐席姓名
+    /// </summary>
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 工号
+    /// </summary>
+    public string StaffNo { get; set; }
+
+    /// <summary>
+    /// 呼入总量
+    /// </summary>
+    public int InTotal { get; set; }
+
+    /// <summary>
+    /// 呼出总量
+    /// </summary>
+    public int OutTotal { get; set; }
+
+    /// <summary>
+    /// 呼入接通量
+    /// </summary>
+    public int InAnswered { get; set; }
+
+    /// <summary>
+    /// 呼出接通量
+    /// </summary>
+    public int OutAnswered { get; set; }
+
+    /// <summary>
+    /// 呼入秒挂
+    /// </summary>
+    public int InHangupImmediate { get; set; }
+
+    /// <summary>
+    /// 呼入未接
+    /// </summary>
+    public int InHanguped { get; set; }
+
+    /// <summary>
+    /// 呼入平均时长
+    /// </summary>
+    public double InDurationAvg { get; set; }
+
+    /// <summary>
+    /// 呼出平均时长
+    /// </summary>
+    public double OutDurationAvg { get; set; }
+
+    /// <summary>
+    /// 有效接通量
+    /// </summary>
+    public int InAvailableAnswer { get; set; }
+
+    /// <summary>
+    /// 呼入接通秒挂
+    /// </summary>
+    public int InHangupImmediateWhenAnswered { get; set; }
+
+    /// <summary>
+    /// 登录时长(分钟)
+    /// </summary>
+    public int LoginDuration { get; set; }
+
+    /// <summary>
+    /// 小修+摘机时长
+    /// </summary>
+    public int RestDuration { get; set; }
+
+    /// <summary>
+    /// 呼入接通率
+    /// </summary>
+    public double InAnsweredRate => InTotal > 0 ? Math.Round(InAnswered / InTotal, digits: 4) : 0;
+
+    /// <summary>
+    /// 呼出接通率
+    /// </summary>
+    public double OutAnsweredRate => OutTotal > 0 ? Math.Round(OutAnswered / OutTotal, digits: 4) : 0;
+
+    /// <summary>
+    /// 呼入有效接通率
+    /// </summary>
+    public double AvailableAnswerRate => InTotal > 0 ? Math.Round(InAvailableAnswer / InTotal, digits: 4) : 0;
+
+    /// <summary>
+    /// 工作效率
+    /// </summary>
+    public double WorkRate => LoginDuration > 0 ? Math.Round(1 - RestDuration / LoginDuration, digits: 4) : 0;
+}

+ 30 - 0
src/Hotline.Share/Dtos/Users/RestDto.cs

@@ -0,0 +1,30 @@
+using Hotline.Share.Enums.CallCenter;
+
+namespace Hotline.Share.Dtos.Users;
+
+public record RestDto
+{
+    public string Id { get; set; }
+
+    public string TelId { get; set; }
+
+    public string TelNo { get; set; }
+
+    public string UserId { get; set; }
+
+    public string UserName { get; set; }
+
+    public DateTime CreationTime { get; set; }
+
+    public DateTime? StartTime { get; set; }
+
+    public DateTime? EndTime { get; set; }
+
+    public double RestDuration { get; set; }
+
+    public string Reason { get; set; }
+
+    public ETelRestApplyStatus ApplyStatus { get; set; }
+
+    public string? WorkflowId { get; set; }
+}

+ 5 - 31
src/Hotline.Share/Dtos/Users/UserDto.cs

@@ -1,40 +1,12 @@
 using Hotline.Share.Dtos.Org;
 using Hotline.Share.Dtos.Roles;
-using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.Identity;
 using Hotline.Share.Enums.Order;
+using Hotline.Share.Enums.User;
 using XF.Utility.EnumExtensions;
 
 namespace Hotline.Share.Dtos.Users;
 
-
-public record RestDto
-{
-    public string Id { get; set; }
-
-    public string TelId { get; set; }
-
-    public string TelNo { get; set; }
-
-    public string UserId { get; set; }
-
-    public string UserName { get; set; }
-
-    public DateTime CreationTime { get; set; }
-
-    public DateTime? StartTime { get; set; }
-
-    public DateTime? EndTime { get; set; }
-
-    public double RestDuration { get; set; }
-
-    public string Reason { get; set; }
-
-    public ETelRestApplyStatus ApplyStatus { get; set; }
-
-    public string? WorkflowId { get; set; }
-}
-
 public record UserDto : AddUserDto
 {
     public string Id { get; set; }
@@ -43,6 +15,8 @@ public record UserDto : AddUserDto
 
     public DateTime CreationTime { get; set; }
 
+    public string UserTypeText => UserType.GetDescription();
+
     public string RoleNames { get; set; }
 
     public string State { get; set; }
@@ -84,9 +58,9 @@ public record AddUserDto
     public string? OrgId { get; set; }
 
     /// <summary>
-    /// 部门编码(冗余)
+    /// 用户类型
     /// </summary>
-    public string? OrgCode { get; set; }
+    public EUserType UserType { get; set; }
 
     /// <summary>
     /// 默认分机号

+ 15 - 0
src/Hotline.Share/Enums/User/EUserType.cs

@@ -0,0 +1,15 @@
+using System.ComponentModel;
+
+namespace Hotline.Share.Enums.User;
+
+public enum EUserType
+{
+    [Description("普通")]
+    Normal = 0,
+
+    /// <summary>
+    /// 坐席(统计需要)
+    /// </summary>
+    [Description("坐席")]
+    Seat = 1,
+}

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

@@ -11,12 +11,12 @@ public record ReportPagedRequest : PagedKeywordRequest
 	/// <summary>
 	/// 开始时间
 	/// </summary>
-	public DateTime? CreationTimeStart { get; set; }
+	public DateTime? StartTime { get; set; }
 
 	/// <summary>
 	/// 结束时间
 	/// </summary>
-	public DateTime? CreationTimeEnd { get; set; }
+	public DateTime? EndTime { get; set; }
 
 	/// <summary>
 	/// 排序字段 

+ 1 - 1
src/Hotline/Orders/Order.cs

@@ -170,7 +170,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 重复工单Id
         /// </summary>
-        [SugarColumn(ColumnDescription = "重复工单Id", ColumnDataType = "json", IsJson = true, IsNullable = true)]
+        [SugarColumn(ColumnDescription = "重复工单Id", ColumnDataType = "json", IsJson = true)]
         public List<string>? DuplicateIds { get; set; }
 
         /// <summary>

+ 6 - 9
src/Hotline/Users/User.cs

@@ -3,6 +3,7 @@ using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Settings;
 using Hotline.Share.Enums.Order;
+using Hotline.Share.Enums.User;
 using SqlSugar;
 using XF.Domain.Entities;
 using XF.Domain.Repository;
@@ -18,7 +19,6 @@ namespace Hotline.Users
         /// <summary>
         /// 手机号(冗余)
         /// </summary>
-        [SugarColumn(IsNullable = true)]
         public string? PhoneNo { get; set; }
 
         /// <summary>
@@ -31,27 +31,24 @@ namespace Hotline.Users
         /// <summary>
         /// 工号
         /// </summary>
-        [SugarColumn(IsNullable = true)]
         public string? StaffNo { get; set; }
 
         /// <summary>
         /// 部门Id
         /// </summary>
-        [SugarColumn(IsNullable = true)]
         public string? OrgId { get; set; }
 
-        ///// <summary>
-        ///// 部门编码(冗余)
-        ///// </summary>
-        //[SugarColumn(IsNullable = true)]
-        //public string? OrgCode { get; set; }
 
         /// <summary>
         /// 默认分机号
         /// </summary>
-        [SugarColumn(IsNullable = true)]
         public string? DefaultTelNo { get; set; }
 
+        /// <summary>
+        /// 用户类型
+        /// </summary>
+        public EUserType UserType { get; set; }
+
         /// <summary>
         /// 所属部门
         /// </summary>