Parcourir la source

完成办件统计-随手拍

qinchaoyue il y a 1 mois
Parent
commit
91c9447f11

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

@@ -9,6 +9,7 @@ using Hotline.Settings.Hotspots;
 using Hotline.Share.Requests;
 using SqlSugar;
 using XF.Domain.Authentications;
+using Hotline.Settings;
 
 namespace Hotline.Api.Controllers.Snapshot;
 
@@ -94,4 +95,22 @@ public class BiSnapshotController : BaseController
     public async Task<PagedDto<HotspotStatisticsDetailsOutDto>> GetHotspotStatisticsDetailAsync([FromQuery] HotspotStatisticsDetailsInDto dto)
         => (await _biSnapshotApplication.HotspotStatisticsDetail(dto).ToPagedListAsync(dto)).ToPaged();
 
+    /// <summary>
+    /// 办件统计-随手拍
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("processing-statistics")]
+    public async Task<IList<SnapshotProcessingStatisticsOutDto>> GetSnapshotProcessingStatistics([FromQuery] SnapshotProcessingStatisticsInDto dto)
+        => await _biSnapshotApplication.GetSnapshotProcessingStatistics(dto).ToListAsync();
+
+    /// <summary>
+    /// 办件统计明细-随手拍
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("processing-statistics-detail")]
+    public async Task<PagedDto<SnapshotProcessingStatisticsDetailsOutDto>> GetSnapshotProcessingStatisticsDetails(SnapshotProcessingStatisticsDetailsInDto dto)
+        => (await _biSnapshotApplication.GetSnapshotProcessingStatisticsDetails(dto).ToPagedListAsync(dto)).ToPaged();
+
 }

+ 106 - 2
src/Hotline.Application/Snapshot/BiSnapshotApplication.cs

@@ -2,6 +2,7 @@
 using Hotline.FlowEngine.Workflows;
 using Hotline.Orders;
 using Hotline.Repository.SqlSugar.Orders;
+using Hotline.Settings;
 using Hotline.Settings.Hotspots;
 using Hotline.Share.Attributes;
 using Hotline.Share.Dtos;
@@ -28,6 +29,7 @@ using XF.Domain.Authentications;
 using XF.Domain.Dependency;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
+using static NPOI.HSSF.Util.HSSFColor;
 using static NPOI.SS.Format.CellNumberFormatter;
 
 namespace Hotline.Application.Snapshot;
@@ -100,9 +102,9 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
         var query = _orderRepository.Queryable()
             .Includes(d => d.OrderVisits)
             .Where(d => d.CreationTime >= dto.StartTime && d.CreationTime <= dto.EndTime)
-            .WhereIF(dto.HotspotCode.NotNullOrEmpty(),  d => d.HotspotId.StartsWith(dto.HotspotCode))
+            .WhereIF(dto.HotspotCode.NotNullOrEmpty(), d => d.HotspotId.StartsWith(dto.HotspotCode))
             .WhereIF(IsCenter == false, d => d.ActualHandleOrgCode.StartsWith(_sessionContext.RequiredOrgId))
-            .Select(d => new HotspotStatisticsDetailsOutDto 
+            .Select(d => new HotspotStatisticsDetailsOutDto
             {
                 OrderScreenStatus = SqlFunc.Subqueryable<OrderScreen>().Where(q => q.OrderId == d.Id).OrderByDesc(q => q.CreationTime).Select(q => q.Status), //x.OrderScreens.FirstOrDefault().Status,
             }, true);
@@ -324,4 +326,106 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
             CreationTime = order.CreationTime
         }, true);
     }
+
+    /// <summary>
+    /// 办件统计-随手拍
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public ISugarQueryable<SnapshotProcessingStatisticsOutDto> GetSnapshotProcessingStatistics(SnapshotProcessingStatisticsInDto 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 => snapshot.CreationTime >= dto.StartTime && snapshot.CreationTime <= dto.EndTime)
+            .WhereIF(dto.IndustryId.NotNullOrEmpty(), snapshot => snapshot.IndustryId == dto.IndustryId)
+            .GroupBy((snapshot, order) => new
+            {
+                OrgCode = order.ActualHandleOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6"))
+            })
+            .Select((snapshot, order, back, visit, second) => new SnapshotProcessingStatisticsOutDto()
+            {
+                OrgCode = order.ActualHandleOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
+                YbOrderCountNum = SqlFunc.AggregateCount(SqlFunc.IIF(order.Status >= EOrderStatus.Filed, 1, 0)),
+                ZbOrderCountNum = SqlFunc.AggregateCount(SqlFunc.IIF(order.Status < EOrderStatus.Filed, 1, 0)),
+                ReceiveIn20Minutes = SqlFunc.AggregateCount(SqlFunc.IIF(order.ActualHandleStepCreateTime != null && order.ActualHandleStepCreateTime.Value.AddMinutes(-20) <= order.CreationTime, 1, 0)),
+                ReceiveOut20Minutes = SqlFunc.AggregateCount(SqlFunc.IIF(order.ActualHandleStepCreateTime == null || order.ActualHandleStepCreateTime.Value.AddMinutes(-20) > order.CreationTime, 1, 0)),
+                BackNum = SqlFunc.AggregateCount(SqlFunc.IIF(back.OrderId != null && back.OrderId != "", 1, 0)),
+                TotalHandleDuration = SqlFunc.AggregateSum(order.HandleDuration),
+                End3Day = SqlFunc.AggregateSum(SqlFunc.IIF(order.FiledTime != null && order.FiledTime.Value.AddDays(-3) < order.CreationTime, 1, 0)),
+                End3To5Day = SqlFunc.AggregateSum(SqlFunc.IIF(order.FiledTime != null && order.FiledTime.Value.AddDays(-3) > order.CreationTime && order.FiledTime.Value.AddDays(-5) < order.CreationTime, 1, 0)),
+                End5To7Day = SqlFunc.AggregateSum(SqlFunc.IIF(order.FiledTime != null && order.FiledTime.Value.AddDays(-5) > order.CreationTime && order.FiledTime.Value.AddDays(-7) < order.CreationTime, 1, 0)),
+                End7Day = SqlFunc.AggregateSum(SqlFunc.IIF(order.FiledTime != null && order.FiledTime.Value.AddDays(-7) < order.CreationTime, 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)
+            })
+            .MergeTable()
+            .LeftJoin<SystemOrganize>((it, o) => it.OrgCode == o.Id)
+            .Select((it, o) => new SnapshotProcessingStatisticsOutDto()
+            {
+                OrgName = o.Name,
+                OrgCode = it.OrgCode,
+                YbOrderCountNum = it.YbOrderCountNum,
+                ZbOrderCountNum = it.ZbOrderCountNum,
+                ReceiveIn20Minutes = it.ReceiveIn20Minutes,
+                ReceiveOut20Minutes = it.ReceiveOut20Minutes,
+                BackNum = it.BackNum,
+                TotalHandleDuration = it.TotalHandleDuration,
+                End3Day = it.End3Day,
+                End3To5Day = it.End3To5Day,
+                End5To7Day = it.End5To7Day,
+                End7Day = it.End7Day,
+                OnTimeCount = it.OnTimeCount,
+                SatisfiedCount = it.SatisfiedCount,
+                NoSatisfiedCount = it.NoSatisfiedCount,
+                SecondNum = it.SecondNum
+            });
+
+        return query;
+    }
+
+    public ISugarQueryable<SnapshotProcessingStatisticsDetailsOutDto> GetSnapshotProcessingStatisticsDetails(SnapshotProcessingStatisticsDetailsInDto dto)
+    {
+        dto.FieldName = dto.FieldName.ToLower();
+        var IsCenter = _sessionContext.OrgIsCenter;
+        IsCenter = true;
+        var query = _orderSnapshotRepository.Queryable()
+            .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, back) => order.CreationTime >= dto.StartTime && order.CreationTime <= dto.EndTime && order.ActualHandleOrgCode.StartsWith(dto.OrgId))
+            .WhereIF(IsCenter == false, (snapshot, order, back) => order.ActualHandleOrgCode.StartsWith(_sessionContext.RequiredOrgId))
+            .WhereIF(dto.IndustryId.NotNullOrEmpty(), (snapshot, order, back) => snapshot.IndustryId == dto.IndustryId);
+
+        query = dto.FieldName switch
+        {
+            "ybordercountnum" => query.Where((snapshot, order, back) => order.Status >= EOrderStatus.Filed),
+            "zbordercountnum" => query.Where((snapshot, order, back) => order.Status < EOrderStatus.Filed),
+            "receivein20minutes" => query.Where((snapshot, order, back) => order.ActualHandleStepCreateTime != null && order.ActualHandleStepCreateTime.Value.AddMinutes(-20) <= order.CreationTime),
+            "receiveout20minutes" => query.Where((snapshot, order, back) => order.ActualHandleStepCreateTime == null || order.ActualHandleStepCreateTime.Value.AddMinutes(-20) > order.CreationTime),
+            "backnum" => query.Where((snapshot, order, back) => back.OrderId != null && back.OrderId != ""),
+            "end3day" => query.Where((snapshot, order, back) => order.FiledTime != null && order.FiledTime.Value.AddDays(-3) < order.CreationTime),
+            "end3to5day" => query.Where((snapshot, order, back) => order.FiledTime != null && order.FiledTime.Value.AddDays(-3) > order.CreationTime && order.FiledTime.Value.AddDays(-5) < order.CreationTime),
+            "end5to7day" => query.Where((snapshot, order, back) => order.FiledTime != null && order.FiledTime.Value.AddDays(-5) > order.CreationTime && order.FiledTime.Value.AddDays(-7) < order.CreationTime),
+            "end7day" => query.Where((snapshot, order, back) => order.FiledTime != null && order.FiledTime.Value.AddDays(-7) < order.CreationTime),
+            "satisfiedcount" => query.Where((snapshot, order, back, visit) => SqlFunc.JsonListObjectAny(visit.NowEvaluate, "key", "1") || SqlFunc.JsonListObjectAny(visit.NowEvaluate, "key", "2")),
+            "nosatisfiedcount" => query.Where((snapshot, order, back, visit) => SqlFunc.JsonListObjectAny(visit.NowEvaluate, "key", "1") || SqlFunc.JsonListObjectAny(visit.NowEvaluate, "key", "2")),
+            "secondnum" => query.Where((snapshot, order, back, visit, second) => second.Id != null || second.Id != ""),
+            _ => throw new UserFriendlyException($"入参: {dto.FieldName} 异常")
+        };
+        return query.Select(d => new SnapshotProcessingStatisticsDetailsOutDto
+        {
+            OrderScreenStatus = SqlFunc.Subqueryable<OrderScreen>().Where(q => q.OrderId == d.Id).OrderByDesc(q => q.CreationTime).Select(q => q.Status),
+        }, true);
+    }
 }

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

@@ -22,4 +22,18 @@ public interface IBiSnapshotApplication
     ISugarQueryable<RedPackStatisticsDetailsOutDto> GetRedPackAuditStatisticsDetails(RedPackStatisticsDetailsInDto dto);
     Task<SnapshotStatisticsOutDto> GetSnapshotStatisticsAsync(SnapshotStatisticsInDto dto, CancellationToken token);
     ISugarQueryable<SnapshotStatisticsDetailOutDto> GetSnapshotStatisticsDetail(SnapshotStatisticsDetailInDto dto);
+
+    /// <summary>
+    /// 办件统计-随手拍
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    ISugarQueryable<SnapshotProcessingStatisticsOutDto> GetSnapshotProcessingStatistics(SnapshotProcessingStatisticsInDto dto);
+
+    /// <summary>
+    /// 办件统计明细-随手拍
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    ISugarQueryable<SnapshotProcessingStatisticsDetailsOutDto> GetSnapshotProcessingStatisticsDetails(SnapshotProcessingStatisticsDetailsInDto dto);
 }

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

@@ -1066,3 +1066,273 @@ public class HotspotStatisticsDetailsOutDto
     /// </summary>
     public string FileOpinion { get; set; }
 }
+
+public class SnapshotProcessingStatisticsInDto
+{
+    [Required]
+    public DateTime StartTime { get; set; }
+
+    [Required]
+    public DateTime EndTime { get; set; }
+
+    /// <summary>
+    /// 行业Id
+    /// </summary>
+    public string? IndustryId { get; set; }
+}
+
+public class SnapshotProcessingStatisticsOutDto
+{
+    /// <summary>
+    /// 部门Code
+    /// </summary>
+    public string OrgCode { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    public string OrgName { get; set; }
+
+    /// <summary>
+    /// 信件总量
+    /// </summary>
+    public int OrderCountNum => YbOrderCountNum + ZbOrderCountNum;
+
+    /// <summary>
+    /// 信件已办总量
+    /// </summary>
+    public int YbOrderCountNum { get; set; }
+
+    /// <summary>
+    /// 信件未办总量
+    /// </summary>
+    public int ZbOrderCountNum { get; set; }
+
+    /// <summary>
+    /// 按时办结
+    /// </summary>
+    public int CompleteOnTime { get; set; }
+
+    /// <summary>
+    /// 按时办结率
+    /// </summary>
+    public string CompleteOnTimeRate => CalcRate(YbOrderCountNum, CompleteOnTime);
+
+    /// <summary>
+    /// 办结率
+    /// </summary>
+    public string OrderCompletionRate => CalcRate(YbOrderCountNum, OrderCountNum);
+
+    /// <summary>
+    /// 20分钟内接件
+    /// </summary>
+    public int ReceiveIn20Minutes { get; set; }
+
+    /// <summary>
+    /// 20分钟后接件
+    /// </summary>
+    public int ReceiveOut20Minutes { get; set; }
+
+    /// <summary>
+    /// 工单及时响应率
+    /// </summary>
+    public string PromptResponse => CalcRate(ReceiveIn20Minutes, ReceiveIn20Minutes + ReceiveOut20Minutes);
+
+    /// <summary>
+    /// 退回件
+    /// </summary>
+    public int BackNum { get; set; }
+
+    /// <summary>
+    /// 办件总时长
+    /// </summary>
+    public double? TotalHandleDuration { get; set; }
+
+    /// <summary>
+    /// 3日内办结
+    /// </summary>
+    public int End3Day { get; set; }
+
+    /// <summary>
+    /// 3至5日办结
+    /// </summary>
+    public int End3To5Day { get; set; }
+
+    /// <summary>
+    /// 5至7日办结
+    /// </summary>
+    public int End5To7Day { get; set; }
+
+    /// <summary>
+    /// 7日外办结
+    /// </summary>
+    public int End7Day { get; set; }
+
+    /// <summary>
+    /// 按时办结个数
+    /// </summary>
+    public int OnTimeCount { get; set; }
+
+    /// <summary>
+    /// 按时办结率
+    /// </summary>
+    public string CloseOnTimeRate => CalcRate(OnTimeCount, OrderCountNum);
+
+    /// <summary>
+    /// 满意量
+    /// </summary>
+    public int SatisfiedCount { get; set; }
+
+    /// <summary>
+    /// 不满意量
+    /// </summary>
+    public int NoSatisfiedCount { get; set; }
+
+    /// <summary>
+    /// 满意率
+    /// </summary>
+    public string SatisfiedRate => CalcRate(SatisfiedCount, SatisfiedCount + NoSatisfiedCount);
+
+    /// <summary>
+    /// 二次办理个数
+    /// </summary>
+    public int SecondNum { get; set; }
+
+    /// <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 record SnapshotProcessingStatisticsDetailsInDto : PagedRequest
+{
+    /// <summary>
+    /// 开始时间
+    /// </summary>
+    [Required]
+    public DateTime StartTime { get; set; }
+
+    /// <summary>
+    /// 结束时间
+    /// </summary>
+    [Required]
+    public DateTime EndTime { get; set; }
+
+    /// <summary>
+    /// 字段名称
+    /// </summary>
+    [Required]
+    public string FieldName { get; set; }
+
+    /// <summary>
+    /// 部门Id
+    /// </summary>
+    [Required]
+    public string OrgId { get; set; }
+
+    /// <summary>
+    /// 行业Id
+    /// </summary>
+    public string? IndustryId { get; set; }
+}
+
+public class SnapshotProcessingStatisticsDetailsOutDto
+{
+    /// <summary>
+    /// Id
+    /// </summary>
+    public string Id { get; set; }
+
+    /// <summary>
+    /// 过期状态
+    /// </summary>
+    public EExpiredStatus ExpiredStatus { get; set; }
+
+    /// <summary>
+    /// 过期状态
+    /// </summary>
+    public string ExpiredStatusText => ExpiredStatus.GetDescription();
+
+    /// <summary>
+    /// 受理编号
+    /// </summary>
+    public string No { get; set; }
+
+    /// <summary>
+    /// 信件状态
+    /// </summary>
+    public EOrderStatus Status { get; set; }
+
+    /// <summary>
+    /// 信件状态
+    /// </summary>
+    public string StatusTxt => Status.GetDescription();
+
+    /// <summary>
+    /// 来源
+    /// </summary>
+    public string SourceChannel { get; set; }
+
+    /// <summary>
+    /// 当前节点
+    /// </summary>
+    public string CurrentStepName { get; set; }
+
+    /// <summary>
+    /// 重办次数
+    /// </summary>
+    public int ReTransactNum { get; set; }
+
+    /// <summary>
+    /// 甄别状态
+    /// </summary>
+    public EScreenStatus? OrderScreenStatus { get; set; }
+
+    /// <summary>
+    /// 甄别状态
+    /// </summary>
+    public string? OrderScreenStatusText => OrderScreenStatus.HasValue && OrderScreenStatus != null ? OrderScreenStatus?.GetDescription() : "未甄别";
+
+    /// <summary>
+    /// 受理时间
+    /// </summary>
+    public DateTime CreationTime { get; set; }
+
+    /// <summary>
+    /// 期满时间
+    /// </summary>
+    public DateTime? ExpiredTime { get; set; }
+    
+    /// <summary>
+    /// 接办部门
+    /// </summary>
+    public string ActualHandleOrgName { get; set; }
+
+    /// <summary>
+    /// 接办时间
+    /// </summary>
+    public DateTime? StartTime { get; set; }
+
+    /// <summary>
+    /// 办结时间
+    /// </summary>
+    public DateTime? CenterToOrgTime { get; set; }
+
+    /// <summary>
+    /// 受理类型
+    /// </summary>
+    public string AcceptType { get; set; }
+
+    /// <summary>
+    /// 热点类型
+    /// </summary>
+    public string HotspotName { get; set; }
+}