Browse Source

新增部门考核统计

qinchaoyue 1 tháng trước cách đây
mục cha
commit
81b736aeb1

+ 10 - 0
src/Hotline.Api/Controllers/Snapshot/BiSnapshotController.cs

@@ -209,4 +209,14 @@ public class BiSnapshotController : BaseController
     [HttpGet("county-redpack-statistics")]
     public async Task<IList<CountyRedPackStatisticsOutDto>> GetCountyRedPackStatisticsAsync([FromQuery] CountyRedPackStatisticsInDto dto)
         => await _biSnapshotApplication.GetCountyRedPackStatistics(dto).ToListAsync();
+
+    /// <summary>
+    /// 部门考核统计-随手拍
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    [HttpGet("department-statistics")]
+    public async Task<IList<SnapshotDepartmentStatisticsOutDto>> GetSnapshotDepartmentStatisticsAsync([FromQuery]SnapshotDepartmentStatisticsInDto dto)
+        => await _biSnapshotApplication.GetSnapshotDepartmentStatistics(dto).ToListAsync();
 }

+ 55 - 0
src/Hotline.Application/Snapshot/BiSnapshotApplication.cs

@@ -596,5 +596,60 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
         return query;
     }
 
+    /// <summary>
+    /// 部门考核统计-随手拍
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public ISugarQueryable<SnapshotDepartmentStatisticsOutDto> GetSnapshotDepartmentStatistics(SnapshotDepartmentStatisticsInDto dto)
+    {
+        bool IsCenter = _sessionContext.OrgIsCenter;
+        var orgLevel = _sessionContext.OrgLevel;
+        string orgLevelStr = (_sessionContext.RequiredOrgId.Length + 3).ToString();
+
+        var query = _orderSnapshotRepository.Queryable(includeDeleted: true)
+            .LeftJoin<Order>((snapshot, order) => snapshot.Id == order.Id)
+            .LeftJoin<OrderSendBackAudit>((snapshot, order, back) => snapshot.Id == back.OrderId && back.State == ESendBackAuditState.End)
+            .LeftJoin<OrderVisit>((snapshot, order, back, visit) => snapshot.Id == visit.OrderId && visit.VisitState == EVisitState.Visited)
+            .LeftJoin<OrderSecondaryHandling>((snapshot, order, back, visit, second) => snapshot.Id == second.OrderId && second.State == ESecondaryHandlingState.End)
+            .Where((snapshot, order) => snapshot.CreationTime >= dto.StartTime && snapshot.CreationTime <= dto.EndTime && order.ActualHandleOrgCode != null)
+            .GroupBy((snapshot, order) => new
+            {
+                OrgCode = order.ActualHandleOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6"))
+            })
+            .Select((snapshot, order, back, visit, second) => new SnapshotDepartmentStatisticsOutDto()
+            {
+                OrgCode = order.ActualHandleOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
+                OrderCountNum = SqlFunc.AggregateCount(snapshot.Id),
+                ReceiveIn4Hour = SqlFunc.AggregateCount(SqlFunc.IIF(order.ActualHandleStepCreateTime != null && order.ActualHandleStepCreateTime.Value.AddHours(-4) <= order.CreationTime, 1, 0)),
+                TimeOutField = SqlFunc.AggregateCount(SqlFunc.IIF(order.Status >= EOrderStatus.Filed && order.FiledTime > order.ExpiredTime, 1, 0)),
+                TimeOutNoField = SqlFunc.AggregateCount(SqlFunc.IIF(order.Status < EOrderStatus.Filed && DateTime.Now > order.ExpiredTime, 1, 0)),
+                OnTimeCount = SqlFunc.AggregateSum(SqlFunc.IIF(order.FiledTime <= order.ExpiredTime, 1, 0)),
+                SatisfiedCount = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(visit.NowEvaluate, "key", "1") || SqlFunc.JsonListObjectAny(visit.NowEvaluate, "key", "2"), 1, 0)),
+                NoSatisfiedCount = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(visit.NowEvaluate, "key", "1") || SqlFunc.JsonListObjectAny(visit.NowEvaluate, "key", "2"), 0, 1)),
+                SecondNum = SqlFunc.AggregateCount(second.Id),
+                FirstFiledOrderCount = SqlFunc.AggregateCount(SqlFunc.IIF(order.Status >= EOrderStatus.Filed && second.Id == null, 1, 0)),
+                SecondSatisfied = SqlFunc.AggregateCount(SqlFunc.IIF(second.State == ESecondaryHandlingState.Handled && (SqlFunc.JsonField(order.OrgProcessingResults, "Key") == "1" || SqlFunc.JsonField(order.OrgProcessingResults, "Key") == "2"), 1, 0)),
+            })
+            .MergeTable()
+            .LeftJoin<SystemOrganize>((it, o) => it.OrgCode == o.Id)
+            .Select((it, o) => new SnapshotDepartmentStatisticsOutDto()
+            {
+                OrgName = o.Name,
+                OrgCode = it.OrgCode,
+                ReceiveIn4Hour = it.ReceiveIn4Hour,
+                TimeOutField = it.TimeOutField,
+                TimeOutNoField = it.TimeOutNoField,
+                OnTimeCount = it.OnTimeCount,
+                SatisfiedCount = it.SatisfiedCount,
+                NoSatisfiedCount = it.NoSatisfiedCount,
+                SecondNum = it.SecondNum,
+                FirstFiledOrderCount = it.FirstFiledOrderCount,
+                SecondSatisfied = it.SecondSatisfied
+            });
+
+        return query;
+    }
 
 }

+ 8 - 0
src/Hotline.Application/Snapshot/IBiSnapshotApplication.cs

@@ -69,4 +69,12 @@ public interface IBiSnapshotApplication
     /// <param name="dto"></param>
     /// <returns></returns>
     ISugarQueryable<CountyRedPackStatisticsOutDto> GetCountyRedPackStatistics(CountyRedPackStatisticsInDto dto);
+
+    /// <summary>
+    /// 部门考核统计-随手拍
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    ISugarQueryable<SnapshotDepartmentStatisticsOutDto> GetSnapshotDepartmentStatistics(SnapshotDepartmentStatisticsInDto dto);
 }

+ 119 - 0
src/Hotline.Share/Dtos/Snapshot/StatisticsDto.cs

@@ -2186,3 +2186,122 @@ public class CountyRedPackStatisticsInDto
     public string? IndustryId { get; set; }
 }
 
+
+public class SnapshotDepartmentStatisticsOutDto
+{
+    /// <summary>
+    /// 部门Code
+    /// </summary>
+    public string OrgCode { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    public string OrgName { get; set; }
+
+    /// <summary>
+    /// 信件总量
+    /// </summary>
+    public int OrderCountNum { get; set; }
+
+    /// <summary>
+    /// 按时办结个数
+    /// </summary>
+    public int OnTimeCount { get; set; }
+
+    /// <summary>
+    /// 工单及时率
+    /// </summary>
+    public string TimelinessRatio { get; set; } = "0.00";
+
+    /// <summary>
+    /// 4小时内
+    /// </summary>
+    public int ReceiveIn4Hour { get; set; }
+
+    /// <summary>
+    /// 超期办结
+    /// </summary>
+    public int TimeOutField { get; set; }
+
+    /// <summary>
+    /// 超期未办结
+    /// </summary>
+    public int TimeOutNoField { get; set; }
+
+    /// <summary>
+    /// 超期率
+    /// </summary>
+    public string TimeOutRate => CalcRate(TimeOutNoField + TimeOutField, OrderCountNum);
+
+    /// <summary>
+    /// 超期量
+    /// </summary>
+    public int TimeOutCount => TimeOutField + TimeOutNoField;
+
+    /// <summary>
+    /// 按时办结率
+    /// </summary>
+    public string CloseOnTimeRate => CalcRate(OnTimeCount, OrderCountNum);
+
+    /// <summary>
+    /// 满意工单
+    /// </summary>
+    public int SatisfiedCount { get; set; }
+
+    /// <summary>
+    /// 回访满意率
+    /// </summary>
+    public string SatisfiedRate => CalcRate(SatisfiedCount, SatisfiedCount + NoSatisfiedCount);
+
+    /// <summary>
+    /// 不满意量
+    /// </summary>
+    public int NoSatisfiedCount { get; set; }
+
+    /// <summary>
+    /// 一次办结工单
+    /// </summary>
+    public int FirstFiledOrderCount { get; set; }
+
+    /// <summary>
+    /// 一次办结率
+    /// </summary>
+    public string FirstFiledOrderRate => CalcRate(FirstFiledOrderCount, OrderCountNum);
+
+    /// <summary>
+    /// 二次办理个数
+    /// </summary>
+    public int SecondNum { get; set; }
+
+    /// <summary>
+    /// 二次办理满意率
+    /// </summary>
+    public int SecondSatisfied { get; set; }
+
+    /// <summary>
+    /// 二次办理率
+    /// </summary>
+    public string SecondRate => CalcRate(SecondNum, OrderCountNum);
+
+    /// <summary>
+    /// 计算率
+    /// </summary>
+    /// <returns></returns>
+    public string CalcRate(int Quantity, int Count)
+    {
+        if (Count != 0 && Quantity != 0)
+        {
+            return Math.Round((Quantity / (double)Count) * 100, 2) + "%";
+        }
+        return "0%";
+    }
+}
+
+public class SnapshotDepartmentStatisticsInDto
+{
+    [Required]
+    public DateTime StartTime { get; set; }
+    [Required]
+    public DateTime EndTime { get; set; }
+}

+ 12 - 0
test/Hotline.Tests/Application/BiSnapshotApplicationTest.cs

@@ -80,4 +80,16 @@ public class BiSnapshotApplicationTest : TestBase
         transposedItems.ShouldNotBeNull();
         transposedItems.Count.ShouldNotBe(0);
     }
+
+    [Fact]
+    public async Task GetSnapshotDepartmentStatistics_Test()
+    {
+        var inDto = new SnapshotDepartmentStatisticsInDto
+        {
+            StartTime = DateTime.Now.AddDays(-30),
+            EndTime = DateTime.Now,
+        };
+        var items = await _biSnapshotApplication.GetSnapshotDepartmentStatistics(inDto).ToListAsync();
+        items.ShouldNotBeNull();
+    }
 }