qinchaoyue 8 месяцев назад
Родитель
Сommit
c293b7ef33

+ 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
+}

+ 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);
+    }
+}