Browse Source

动态导出

qinchaoyue 1 month ago
parent
commit
f11c05db76

+ 3 - 2
src/Hotline.Api/Controllers/ExportData/ExportDataController.cs

@@ -99,6 +99,7 @@ public class ExportDataController : BaseController
 
         var returnType = method.ReturnType.GetGenericArguments()[0];
         var fileName = method.GetFileName() + "_";
+        var totalName = method.GetTotalName();
         if (pageIndex == null || pageSize == null)
         {
             pageSize = param.ParameterType.GetProperty("QueryCount")?.GetValue(queryDto);
@@ -109,13 +110,13 @@ public class ExportDataController : BaseController
                 pageIndex = 1;
                 pageSize = 20;
             }
-            else 
+            else
             {
                 pageIndex += 1;
             }
         }
 
-        return _exportApplication.GetExcelFile(returnType, genericType, exportData, ConvertToList(result, (bool)isExportAll, (int)pageIndex, (int)pageSize), fileName);
+        return _exportApplication.GetExcelFile(returnType, genericType, exportData, ConvertToList(result, (bool)isExportAll, (int)pageIndex, (int)pageSize), fileName, totalName);
     }
 
     public static List<object>? ConvertToList(object? result, bool isExportAll, int pageIndex, int pageSize)

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

@@ -208,14 +208,5 @@ public class BiSnapshotController : BaseController
     /// <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);
+        => await _biSnapshotApplication.GetCountyRedPackStatistics(dto).ToListAsync();
 }

+ 38 - 1
src/Hotline.Application/ExportExcel/ExportApplication.cs

@@ -1,4 +1,5 @@
 
+using DocumentFormat.OpenXml.ExtendedProperties;
 using Hotline.Application.Tools;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.Order;
@@ -12,6 +13,7 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.DependencyInjection;
 using MiniExcelLibs;
 using NPOI.HPSF;
+using NPOI.SS.Formula.Functions;
 using SqlSugar;
 using System.Net.Http;
 using System.Reflection;
@@ -69,6 +71,41 @@ namespace Hotline.Application.ExportExcel
             return GetExcelStream(dto, items, func).GetExcelFile(fileName);
         }
 
+        public FileStreamResult GetExcelFile(Type typeT, Type typeD, object dto, IList<object> items, string fileName, string? totalFiledName)
+        {
+            var fieldsAll = typeT.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+            var fields = fieldsAll.Where(f => IsNumericType(f.FieldType)); // 只选择数值类型字段
+            var totalField = fieldsAll.Where(m => m.Name.Contains(totalFiledName)).First();
+
+            var sumDict = new Dictionary<FieldInfo, dynamic>();
+
+            foreach (var field in fields)
+            {
+                sumDict[field] = 0;
+            }
+
+            foreach (var item in items)
+            {
+                foreach (var field in fields)
+                {
+                    var value = field.GetValue(item);
+                    if (value != null)
+                    {
+                        sumDict[field] += (dynamic)value; // 使用 dynamic 累加
+                    }
+                }
+            }
+
+            var resultItem = Activator.CreateInstance(typeT);
+            totalField.SetValue(resultItem, "合计");
+            foreach (var field in fields)
+            {
+                field.SetValue(resultItem, sumDict[field]);
+            }
+            items.Add(resultItem);
+            return GetExcelFile(typeT, typeD, dto, items, fileName);
+        }
+
         public FileStreamResult GetExcelFile(Type typeT, Type typeD, object dto, IList<object> items, string fileName)
         {
             var columnInfos = typeD.GetProperty("ColumnInfos")?.GetValue(dto) as List<ColumnInfo>;
@@ -142,7 +179,7 @@ namespace Hotline.Application.ExportExcel
             return type == typeof(int) || type == typeof(float) || type == typeof(double) ||
                    type == typeof(decimal) || type == typeof(long) || type == typeof(short) ||
                    type == typeof(byte) || type == typeof(uint) || type == typeof(ulong) ||
-                   type == typeof(ushort) || type == typeof(sbyte);
+                   type == typeof(ushort) || type == typeof(sbyte) || type == typeof(double?);
         }
     }
 }

+ 1 - 0
src/Hotline.Application/ExportExcel/IExportApplication.cs

@@ -27,6 +27,7 @@ namespace Hotline.Application.ExportExcel
         FileStreamResult GetExcelFile<T, D>(ExportExcelDto<D> dto, IList<T> items,string fileName, Func<IList<T>, T>? func = null);
 
         FileStreamResult GetExcelFile(Type typeT, Type typeD, object dto, IList<object> items, string fileName);
+        FileStreamResult GetExcelFile(Type typeT, Type typeD, object dto, IList<object> items, string fileName, string? totalFiledName);
 
         /// <summary>
         /// 导入数据

+ 5 - 5
src/Hotline.Application/Snapshot/BiSnapshotApplication.cs

@@ -547,9 +547,10 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
 
     public ISugarQueryable<CommunityStatisticsDetailsOutDto> GetCommunityStatisticsDetails(CommunityStatisticsDetailsInDto dto)
     {
+        var communityFullName = _communityInfoRepository.Queryable().Where(c => c.Id == dto.CommunityCode).Select(c => c.FullName).First();
         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(communityFullName))
             .WhereIF(dto.IndustryId.NotNullOrEmpty(), (snapshot, order) => snapshot.IndustryId == dto.IndustryId)
             .Select((snapshot, order) => new CommunityStatisticsDetailsOutDto(), true);
 #if DEBUG
@@ -558,7 +559,8 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
         return query;
     }
 
-    public async Task<IList<CountyRedPackStatisticsOutDto>> GetCountyRedPackStatistics(CountyRedPackStatisticsInDto dto)
+    [ExportExcel("随手拍区域统计", "County")]
+    public ISugarQueryable<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)
@@ -591,8 +593,6 @@ public class BiSnapshotApplication : IBiSnapshotApplication, IScopeDependency
 #if DEBUG
         var sql = query.ToSqlString();
 #endif
-        var outDto = await query.ToListAsync();
-        outDto.AddSumLine("County");
-        return outDto;
+        return query;
     }
 }

+ 1 - 1
src/Hotline.Application/Snapshot/IBiSnapshotApplication.cs

@@ -68,5 +68,5 @@ public interface IBiSnapshotApplication
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
-    Task<IList<CountyRedPackStatisticsOutDto>> GetCountyRedPackStatistics(CountyRedPackStatisticsInDto dto);
+    ISugarQueryable<CountyRedPackStatisticsOutDto> GetCountyRedPackStatistics(CountyRedPackStatisticsInDto dto);
 }

+ 7 - 0
src/Hotline.Share/Attributes/ExportExcelAttribute.cs

@@ -12,8 +12,15 @@ public class ExportExcelAttribute : Attribute
     /// </summary>
     public string FileName { get; }
 
+    public string? TotalName { get; }
+
     public ExportExcelAttribute(string fileName)
     {
         FileName = fileName;
     }
+    public ExportExcelAttribute(string fileName, string? totalName)
+    {
+        FileName = fileName;
+        TotalName = totalName;
+    }
 }

+ 1 - 1
src/Hotline.Share/Dtos/Snapshot/StatisticsDto.cs

@@ -2073,7 +2073,7 @@ public record CommunityStatisticsDetailsInDto : PagedRequest
     /// 社区全称
     /// </summary>
     [Required]
-    public string CommunityFullName { get; set; }
+    public string CommunityCode { get; set; }
 
     /// <summary>
     /// 行业Id

+ 8 - 0
src/Hotline.Share/Tools/MethodInfoExtensions.cs

@@ -17,4 +17,12 @@ public static class MethodInfoExtensions
         if (att == null) return string.Empty;
         return att.FileName;
     }
+
+    public static string? GetTotalName(this MethodInfo? value)
+    {
+        if (value == null) return string.Empty;
+        var att = value.GetCustomAttribute<ExportExcelAttribute>();
+        if (att == null) return string.Empty;
+        return att.TotalName;
+    }
 }