qinchaoyue 1 месяц назад
Родитель
Сommit
1faf431131

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

@@ -201,4 +201,21 @@ public class BiSnapshotController : BaseController
     public async Task<PagedDto<CommunityStatisticsDetailsOutDto>> GetCommunityStatisticsDetailsAsync([FromQuery] CommunityStatisticsDetailsInDto dto)
         => (await _biSnapshotApplication.GetCommunityStatisticsDetails(dto).ToPagedListAsync(dto)).ToPaged();
 
+    /// <summary>
+    /// 随手拍区域统计
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("county-redpack-statistics")]
+    public async Task<IList<CountyRedPackStatisticsOutDto>> GetCountyRedPackStatisticsAsync([FromQuery] CountyRedPackStatisticsInDto dto)
+        => await _biSnapshotApplication.GetCountyRedPackStatistics(dto);
+
+    /// <summary>
+    /// 随手拍区域统计-导出
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("county-redpack-statistics/export")]
+    public async Task<IList<CountyRedPackStatisticsOutDto>> GetCountyRedPackStatisticsExportAsync([FromQuery] CountyRedPackStatisticsInDto dto)
+        => await _biSnapshotApplication.GetCountyRedPackStatistics(dto);
 }

+ 43 - 3
src/Hotline.Application/Snapshot/BiSnapshotApplication.cs

@@ -46,8 +46,9 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
     private readonly ISessionContext _sessionContext;
     private readonly IOrderRepository _orderRepository;
     private readonly ICommunityInfoRepository _communityInfoRepository;
+    private readonly IRepository<SystemArea> _systemAreaRepository;
 
-    public BiSnapshotApplication(IOrderSnapshotRepository orderSnapshotRepository, IRedPackRecordRepository redPackRecordRepository, IIndustryRepository industryRepository, IIndustryCaseRepository industryCaseRepository, IRedPackAuditRepository redPackAuditRepository, IRepository<Hotspot> hotspotTypeRepository, ISessionContext sessionContext, IOrderRepository orderRepository, ICommunityInfoRepository communityInfoRepository)
+    public BiSnapshotApplication(IOrderSnapshotRepository orderSnapshotRepository, IRedPackRecordRepository redPackRecordRepository, IIndustryRepository industryRepository, IIndustryCaseRepository industryCaseRepository, IRedPackAuditRepository redPackAuditRepository, IRepository<Hotspot> hotspotTypeRepository, ISessionContext sessionContext, IOrderRepository orderRepository, ICommunityInfoRepository communityInfoRepository, IRepository<SystemArea> systemAreaRepository)
     {
         _orderSnapshotRepository = orderSnapshotRepository;
         _redPackRecordRepository = redPackRecordRepository;
@@ -58,6 +59,7 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
         _sessionContext = sessionContext;
         _orderRepository = orderRepository;
         _communityInfoRepository = communityInfoRepository;
+        _systemAreaRepository = systemAreaRepository;
     }
 
     public ISugarQueryable<HotspotStatisticsOutDto> GetHotspotStatistics(HotspotStatisticsInDto dto)
@@ -534,7 +536,7 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
             CommunityCode = it.Id,
             CommunityName = it.Name,
             CommunityFullName = it.FullName,
-            SumCount = SqlFunc.Subqueryable<OrderSnapshot>().Where(snapshot => snapshot.CommunityFullName.Contains(it.FullName)).Count(),
+            SumCount = SqlFunc.Subqueryable<OrderSnapshot>().Where(snapshot => snapshot.CommunityFullName!.Contains(it.FullName)).Count(),
             HasChild = SqlFunc.Subqueryable<CommunityInfo>().Where(c => c.ParentCode == it.Id).Any()
         });
 #if DEBUG
@@ -547,7 +549,7 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
     {
         var query = _orderSnapshotRepository.Queryable(includeDeleted: true)
             .LeftJoin<Order>((snapshot, order) => snapshot.Id == order.Id)
-            .Where((snapshot, order) => snapshot.CreationTime >= dto.StartTime && snapshot.CreationTime <= dto.EndTime && snapshot.CommunityFullName.Contains(dto.CommunityFullName))
+            .Where((snapshot, order) => snapshot.CreationTime >= dto.StartTime && snapshot.CreationTime <= dto.EndTime && snapshot.CommunityFullName!.Contains(dto.CommunityFullName))
             .WhereIF(dto.IndustryId.NotNullOrEmpty(), (snapshot, order) => snapshot.IndustryId == dto.IndustryId)
             .Select((snapshot, order) => new CommunityStatisticsDetailsOutDto(), true);
 #if DEBUG
@@ -555,4 +557,42 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
 #endif
         return query;
     }
+
+    public async Task<IList<CountyRedPackStatisticsOutDto>> GetCountyRedPackStatistics(CountyRedPackStatisticsInDto dto)
+    {
+        var query = _systemAreaRepository.Queryable(includeDeleted: true)
+            .LeftJoin<Order>((area, order) => order.County == area.AreaName && order.CreationTime >= dto.StartTime && order.CreationTime <= dto.EndTime && order.County != null)
+            .LeftJoin<OrderSnapshot>((area, order, snapshot) => snapshot.Id == order.Id && (dto.IndustryId.IsNullOrEmpty() || snapshot.IndustryId == dto.IndustryId))
+            .LeftJoin<RedPackAudit>((area, order, snapshot, audit) => snapshot.Id == audit.OrderId)
+            .LeftJoin<RedPackRecord>((area, order, snapshot, audit, record) => audit.Id == record.RedPackAuditId)
+            .LeftJoin<SupplementRecord>((area, order, snapshot, audit, record, supplement) => supplement.RedPackAuditId == audit.Id)
+            .LeftJoin<RedPackGuiderAudit>((area, order, snapshot, audit, record, supplement, guiderAudit) => guiderAudit.OrderId == snapshot.Id)
+            .LeftJoin<RedPackRecord>((area, order, snapshot, audit, record, supplement, guiderAudit, guiderRecord) => guiderAudit.Id == guiderRecord.RedPackAuditId)
+            .LeftJoin<Industry>((area, order, snapshot, audit, record, supplement, guiderAudit, guiderRecord, industry) => snapshot.IndustryId == industry.Id)
+            .Where((area, order, snapshot, audit, record, supplement, guiderAudit, guiderRecord) => area.ParentId == "510300" || area.AreaName == "外地")
+            .GroupBy((area, order, snapshot, audit, record, supplement, guiderAudit, guiderRecord) => new { area.AreaName, order.County })
+            .Select((area, order, snapshot, audit, record, supplement, guiderAudit, guiderRecord, industry) => new CountyRedPackStatisticsOutDto
+            {
+                County = area.AreaName,
+                JuBaoZongShu = SqlFunc.AggregateSum(SqlFunc.IIF(industry.IndustryType == EIndustryType.Clue, 1, 0)),
+                YiBanJieShu = SqlFunc.AggregateSum(SqlFunc.IIF(order.Status >= EOrderStatus.Filed && industry.IndustryType == EIndustryType.Clue, 1, 0)),
+                ShiMinShenHeTongGuoShu = SqlFunc.AggregateSum(SqlFunc.IIF(record.PeopleType == EReadPackUserType.Citizen && audit.Status == ERedPackAuditStatus.Agree, 1, 0)),
+                ShiMinZongJinE = SqlFunc.AggregateSum(SqlFunc.IIF(record.PeopleType == EReadPackUserType.Citizen && audit.Status == ERedPackAuditStatus.Agree, audit.ApprovedAmount, 0)),
+                ShiMinYiLing = SqlFunc.AggregateSum(SqlFunc.IIF(record.PeopleType == EReadPackUserType.Citizen && record.PickupStatus == ERedPackPickupStatus.Received, record.Amount, 0)),
+                ShiMinDaiLing = SqlFunc.AggregateSum(SqlFunc.IIF(record.PeopleType == EReadPackUserType.Citizen && record.PickupStatus == ERedPackPickupStatus.Unreceived, record.Amount, 0)),
+                ShiMinDaiBuLing = SqlFunc.AggregateSum(SqlFunc.IIF(record.PeopleType == EReadPackUserType.Citizen && supplement.Id != null, supplement.ReplenishAmount, 0)),
+                WangGeYuanZongJianShu = SqlFunc.AggregateSum(SqlFunc.IIF(snapshot.IsDeal == true, 1, 0)),
+                WangGeYuanShenHeTongGuoShu = SqlFunc.AggregateSum(SqlFunc.IIF(guiderAudit.LevelTwoStatus == ERedPackAuditStatus.Agree, 1, 0)),
+                WangGeYuanZongJinE = SqlFunc.AggregateSum(SqlFunc.IIF(guiderAudit.LevelTwoStatus == ERedPackAuditStatus.Agree, guiderAudit.ApprovedAmount, 0)),
+                WangGeYuanYiLing = SqlFunc.AggregateSum(SqlFunc.IIF(guiderRecord.PickupStatus == ERedPackPickupStatus.Received, guiderRecord.Amount, 0)),
+                WangGeYuanDaiLing = SqlFunc.AggregateSum(SqlFunc.IIF(guiderRecord.PickupStatus == ERedPackPickupStatus.Unreceived, guiderRecord.Amount, 0)),
+            });
+
+#if DEBUG
+        var sql = query.ToSqlString();
+#endif
+        var outDto = await query.ToListAsync();
+        outDto.AddSumLine("County");
+        return outDto;
+    }
 }

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

@@ -62,4 +62,11 @@ public interface IBiSnapshotApplication
     /// <param name="dto"></param>
     /// <returns></returns>
     ISugarQueryable<CommunityStatisticsDetailsOutDto> GetCommunityStatisticsDetails(CommunityStatisticsDetailsInDto dto);
+
+    /// <summary>
+    /// 随手拍区域统计
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    Task<IList<CountyRedPackStatisticsOutDto>> GetCountyRedPackStatistics(CountyRedPackStatisticsInDto dto);
 }

+ 1 - 0
src/Hotline.Application/Snapshot/RedPackApplication.cs

@@ -88,6 +88,7 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
         redPackAudit.AuditTime = DateTime.Now;
         redPackAudit.AuditOrgId = _sessionContext.OrgId;
         redPackAudit.AuditOrgName = _sessionContext.OrgName;
+        redPackAudit.ApprovedAmount = redPackAudit.ShouldAmount;
         var order = await _orderRepository.Queryable()
             .Where(m => m.Id == redPackAudit.OrderId)
             .Select(m => new { m.Id, m.No, m.FromName, m.FromPhone })

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

@@ -2071,3 +2071,109 @@ public record CommunityStatisticsDetailsInDto : PagedRequest
     /// </summary>
     public string? IndustryId { get; set; }
 }
+
+public class CountyRedPackStatisticsOutDto
+{
+    /// <summary>
+    /// 区域
+    /// </summary>
+    public string? County { get; set; }
+
+    /// <summary>
+    /// 举报总数
+    /// </summary>
+    public int JuBaoZongShu { get; set; }
+
+    /// <summary>
+    /// 已办结数
+    /// </summary>
+    public int YiBanJieShu { get; set; }
+
+    /// <summary>
+    /// 办结率
+    /// </summary>
+    public string BanJieLv => CalcRate(YiBanJieShu, JuBaoZongShu);
+
+    /// <summary>
+    /// 市民审核通过数
+    /// </summary>
+    public int ShiMinShenHeTongGuoShu { get; set; }
+
+    /// <summary>
+    /// 市民总金额
+    /// </summary>
+    public double? ShiMinZongJinE { get; set; }
+
+    /// <summary>
+    /// 市民已领
+    /// </summary>
+    public double ShiMinYiLing { get; set; }
+
+    /// <summary>
+    /// 市民待领
+    /// </summary>
+    public double ShiMinDaiLing { get; set; }
+
+    /// <summary>
+    /// 市民待补领
+    /// </summary>
+    public double? ShiMinDaiBuLing { get; set; }
+
+    /// <summary>
+    /// 网格员总件数
+    /// </summary>
+    public int WangGeYuanZongJianShu { get; set; }
+
+    /// <summary>
+    /// 网格员审核通过数
+    /// </summary>
+    public int WangGeYuanShenHeTongGuoShu { get; set; }
+
+    /// <summary>
+    /// 网格员总金额
+    /// </summary>
+    public double? WangGeYuanZongJinE { get; set; }
+
+    /// <summary>
+    /// 网格员已领
+    /// </summary>
+    public double WangGeYuanYiLing { get; set; }
+
+    /// <summary>
+    /// 网格员待领
+    /// </summary>
+    public double WangGeYuanDaiLing { get; set; }
+
+    /// <summary>
+    /// 网格员待补领
+    /// </summary>
+    public double WangGeYuianDaiBuLing { get; set; } = 0;
+
+    /// <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 CountyRedPackStatisticsInDto
+{
+    [Required]
+    public DateTime StartTime { get; set; }
+    [Required]
+    public DateTime EndTime { get; set; }
+
+    /// <summary>
+    /// 行业Id
+    /// </summary>
+    public string? IndustryId { get; set; }
+}
+

+ 26 - 0
src/Hotline.Share/Tools/ListExtensions.cs

@@ -32,4 +32,30 @@ public static class ListExtensions
         return value != null && value.Count != 0;
     }
 
+    public static void AddSumLine<T>(this IList<T> list, string fieldName)
+    {
+        var type = typeof(T);
+        var properties = type.GetProperties();
+        var sumLine = Activator.CreateInstance<T>();
+        foreach (var property in properties)
+        {
+            if (property.Name == fieldName)
+            {
+                property.SetValue(sumLine, "合计");
+            }
+            else if (property.PropertyType == typeof(int))
+            {
+                property.SetValue(sumLine, list.Sum(m => (int)property.GetValue(m)));
+            }
+            else if (property.PropertyType == typeof(decimal))
+            {
+                property.SetValue(sumLine, list.Sum(m => (decimal)property.GetValue(m)));
+            }
+            else if (property.PropertyType == typeof(double?))
+            {
+                property.SetValue(sumLine, list.Sum(m => (double)property.GetValue(m)));
+            }
+        }
+        list.Add(sumLine);
+    }
 }

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

@@ -61,4 +61,17 @@ public class BiSnapshotApplicationTest : TestBase
             }
         }
     }
+
+    [Fact]
+    public async Task GetCountyRedPackStatistics_Test()
+    {
+        var inDto = new CountyRedPackStatisticsInDto
+        {
+            StartTime = DateTime.Now.AddDays(-30),
+            EndTime = DateTime.Now,
+            //IndustryId = "08dd5bc7-6d22-478c-8955-aea3b6d59df6"
+        };
+        var items = await _biSnapshotApplication.GetCountyRedPackStatistics(inDto).ToListAsync();
+        items.Count.ShouldNotBe(0);
+    }
 }

+ 1 - 1
test/Hotline.Tests/Application/OrderSnapshotApplicationTest.cs

@@ -124,7 +124,7 @@ public class OrderSnapshotApplicationTest : TestBase
                 orderSnapshot = await _orderSnapshotRepository.GetAsync(order.Id);
                 orderSnapshot.CommunityName.ShouldNotBeNull();
                 var orderReply = await _orderSnapshotRepository.GetByNetworkENumberAsync(replyDto.AppealNumber);
-                orderReply.IsDanger.ShouldBe(true);
+                orderReply.IsDanger.ShouldBe(replyDto.IsHiddenDanger == "1" ? true : false);
                 orderReply.MemberMobile.ShouldBe(replyDto.MemberMobile);
                 orderReply.MemberName.ShouldBe(replyDto.MemberName);
                 orderReply.NetworkRemark.ShouldBe(replyDto.ReplyContent);

+ 1 - 1
test/Hotline.Tests/Mock/OrderServiceMock.cs

@@ -85,7 +85,7 @@ public class OrderServiceMock
         inDto.Street = "单元测试街道" + DateTime.Now.ToLongDateTimeString();
         inDto.IndustryId = industry.Id;
         inDto.Town = "仙市镇";
-        inDto.County = "沿滩区";
+        inDto.County = "大安区";
         inDto.Description = "单元测试添加的时间描述";
         inDto.IsSecret = false;
         inDto.PhoneNumber = _sessionContext.Phone;