Browse Source

完成 task278
Merge branch 'feature/task278a274' into dev

qinchaoyue 8 months ago
parent
commit
16152dab7b

+ 44 - 0
src/Hotline.Api/Controllers/OrderController.cs

@@ -747,6 +747,50 @@ public class OrderController : BaseController
 
     #region 工单回访
 
+    /// <summary>
+    /// 回访来源统计
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet("visit/source")]
+    [AllowAnonymous]
+    public async Task<IList<OrderVisitSourceChannelDto>> QueryOrderVisitSourceChannelAsync([FromQuery] QueryOrderVisitSourceChannelDto dto)
+    {
+        var startDate = new DateTime();
+        var endDate = new DateTime();
+        switch (dto.DateType)
+        {
+            case Share.Enums.Order.EDateType.Day:
+                (startDate, endDate) = dto.StartTime.GetDayStartAndEnd();
+                break;
+            case Share.Enums.Order.EDateType.Week:
+                (startDate, endDate) = dto.StartTime.GetWeekStartAndEnd();
+                break;
+            case Share.Enums.Order.EDateType.Month:
+                (startDate, endDate) = dto.StartTime.GetMonthStartAndEnd();
+                break;
+            case Share.Enums.Order.EDateType.TimeLimit:
+                if (dto.EndTime is null) throw new UserFriendlyException("结束时间错误");
+                startDate = dto.StartTime;
+                endDate = dto.EndTime.Value;
+                break;
+            default:
+                break;
+        }
+
+        var result = await _orderVisitRepository.Queryable()
+            .LeftJoin<Order>((visit, order) => order.Id == visit.OrderId)
+            .Where((visit, order) => visit.VisitTime >= startDate && visit.VisitTime <= endDate)
+            .GroupBy((visit, order) => new { order.SourceChannel })
+            .Select((visit, order) => new OrderVisitSourceChannelDto
+            {
+                Count = SqlFunc.AggregateCount(visit.OrderId),
+                SourceChannel = order.SourceChannel
+            })
+            .ToListAsync();
+
+        return result;
+    }
+
     /// <summary>
     /// 回访列表
     /// </summary>

+ 32 - 3
src/Hotline.Share/Dtos/Order/OrderVisitDto.cs

@@ -4,6 +4,7 @@ using Hotline.Share.Requests;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -60,6 +61,26 @@ namespace Hotline.Share.Dtos.Order
         public bool? IsEffectiveAiVisit { get; set; }
     }
 
+    public class QueryOrderVisitSourceChannelDto
+    { 
+        /// <summary>
+        /// 开始时间
+        /// </summary>
+        [Required]
+        public DateTime StartTime { get; set; }
+
+        /// <summary>
+        /// 结束时间
+        /// </summary>
+        public DateTime? EndTime { get; set; }
+
+        /// <summary>
+        /// 非时间段统计 EndTime 可以不传;0=按日统计, 1=按周统计, 2=按月统计, 3=按时间段统计;
+        /// </summary>
+        [Required]
+        public EDateType DateType { get; set; }
+    }
+
     public record VisitJudgeQueryReq : PagedKeywordRequest
     {
         /// <summary>
@@ -418,6 +439,13 @@ namespace Hotline.Share.Dtos.Order
         NoVisit = 2,
     }
 
+    public class OrderVisitSourceChannelDto
+    {
+        public int Count { get; set; }
+
+        public string SourceChannel { get; set; }
+    }
+
     public class OrderVisitDto
     {
         public string Id { get; set; }
@@ -550,7 +578,7 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public List<OrderScreenDto> OrderScreens { get; set; }
 
-		public OrderDto Order => OrderVisit != null ? OrderVisit.Order : null;
+        public OrderDto Order => OrderVisit != null ? OrderVisit.Order : null;
 
         /// <summary>
         /// 语音评价(话务评价)
@@ -629,7 +657,8 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public string ScreenSendBackText => GetScreenSendBack() ? "是" : "否";
 
-        public bool GetScreenSendBack() {
+        public bool GetScreenSendBack()
+        {
             if (OrderScreens != null && OrderScreens.Any())
             {
                 if (OrderScreens.First().Status == EScreenStatus.SendBack && OrderScreens.First().SendBackApply)
@@ -641,7 +670,7 @@ namespace Hotline.Share.Dtos.Order
         }
         public bool ScreenSendBack => GetScreenSendBack();
 
-	}
+    }
 
     public class DistributionVisitRspDto
     {

+ 33 - 0
src/Hotline.Share/Enums/Order/EDateType.cs

@@ -0,0 +1,33 @@
+using System.ComponentModel;
+
+namespace Hotline.Share.Enums.Order;
+
+/// <summary>
+/// 时间类型
+/// </summary>
+public enum EDateType
+{
+    /// <summary>
+    /// 按日统计
+    /// </summary>
+    [Description("按日统计")]
+    Day = 0,
+
+    /// <summary>
+    /// 按周统计
+    /// </summary>
+    [Description("按周统计")]
+    Week = 1,
+
+    /// <summary>
+    /// 按月统计
+    /// </summary>
+    [Description("按月统计")]
+    Month = 2,
+
+    /// <summary>
+    /// 按时间段统计
+    /// </summary>
+    [Description("按时间段统计")]
+    TimeLimit = 3
+}

+ 0 - 2
src/Hotline/Orders/OrderVisit.cs

@@ -41,7 +41,6 @@ public class OrderVisit : CreationEntity
     [SugarColumn(IsNullable = true)]
     public EVisitType? VisitType { get; set; }
 
-
     /// <summary>
     /// 发布时间
     /// </summary>
@@ -77,7 +76,6 @@ public class OrderVisit : CreationEntity
     [SugarColumn(IsNullable = true)]
     public DateTime? VisitTime { get; set; }
 
-
     /// <summary>
     /// 回访明细
     /// </summary>

+ 8 - 10
src/Hotline/Orders/OrderVisitDetail.cs

@@ -7,7 +7,7 @@ using XF.Domain.Repository;
 
 namespace Hotline.Orders
 {
-    public class OrderVisitDetail: CreationEntity
+    public class OrderVisitDetail : CreationEntity
     {
 
         /// <summary>
@@ -15,25 +15,25 @@ namespace Hotline.Orders
         /// </summary>
         public string VisitId { get; set; }
 
-
         [Navigate(NavigateType.OneToOne, nameof(VisitId))]
         public OrderVisit OrderVisit { get; set; }
 
         /// <summary>
         /// 二次办理申请
         /// </summary>
-        [Navigate(NavigateType.OneToOne, nameof(Id),nameof(OrderSecondaryHandling.VisitDetailId))]
+        [Navigate(NavigateType.OneToOne, nameof(Id), nameof(OrderSecondaryHandling.VisitDetailId))]
         public OrderSecondaryHandling SecondaryHandling { get; set; }
 
         /// <summary>
         /// 甄别记录
         /// </summary>
-        [Navigate(NavigateType.OneToMany,  nameof(OrderScreen.VisitDetailId), nameof(Id))]
+        [Navigate(NavigateType.OneToMany, nameof(OrderScreen.VisitDetailId), nameof(Id))]
         public List<OrderScreen> OrderScreens { get; set; }
-		/// <summary>
-		/// 语音评价(话务评价)
-		/// </summary>
-		public EVoiceEvaluate? VoiceEvaluate { get; set; }
+
+        /// <summary>
+        /// 语音评价(话务评价)
+        /// </summary>
+        public EVoiceEvaluate? VoiceEvaluate { get; set; }
 
         /// <summary>
         /// 话务员评价(话务评价)
@@ -55,7 +55,6 @@ namespace Hotline.Orders
         /// </summary>
         public string? VolveConent { get; set; }
 
-
         /// <summary>
         /// 部门办件结果
         /// </summary>
@@ -95,6 +94,5 @@ namespace Hotline.Orders
         /// 回访对象类型 10:话务员 20:部门
         /// </summary>
         public EVisitTarget VisitTarget { get; set; }
-
     }
 }

+ 47 - 0
src/Hotline/Tools/DateTimeExtensions.cs

@@ -0,0 +1,47 @@
+
+namespace Hotline.Tools;
+public static class DateTimeExtensions
+{
+    /// <summary>
+    /// 获取指定日期所在周的开始时间和结束时间
+    /// </summary>
+    /// <param name="date"></param>
+    /// <returns></returns>
+    public static (DateTime, DateTime) GetWeekStartAndEnd(this DateTime date)
+    {
+        int diff = date.DayOfWeek - DayOfWeek.Monday;
+        if (diff < 0)
+        {
+            diff += 7;
+        }
+
+        var weekStart = date.AddDays(-1 * diff).Date;
+        var weekEnd = weekStart.AddDays(7).AddTicks(-1);
+
+        return (weekStart, weekEnd);
+    }
+
+    /// <summary>
+    /// 获取指定日期所在天的开始时间和结束时间
+    /// </summary>
+    /// <param name="date"></param>
+    /// <returns></returns>
+    public static (DateTime, DateTime) GetDayStartAndEnd(this DateTime date)
+    {
+        var dayStart = date.Date; 
+        var dayEnd = dayStart.AddDays(1).AddTicks(-1); 
+        return (dayStart, dayEnd);
+    }
+
+    /// <summary>
+    /// 获取指定日期所在月的开始时间和结束时间
+    /// </summary>
+    /// <param name="date"></param>
+    /// <returns></returns>
+    public static (DateTime, DateTime) GetMonthStartAndEnd(this DateTime date)
+    {
+        var monthStart = new DateTime(date.Year, date.Month, 1);
+        var monthEnd = monthStart.AddMonths(1).AddTicks(-1);
+        return (monthStart, monthEnd);
+    }
+}