Commit 66be4819fbc7723ba6e265754c0c52efea8a700b

Authored by 李宇
2 parents 4f068096 e63e9808

Merge branch 'master' of http://39.98.150.180/antissoft/lvqianmeiye_ERP

netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatisticsPersonalPerformance/LqStatisticsPersonalPerformanceListOutput.cs 0 → 100644
  1 +using System;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatisticsPersonalPerformance
  4 +{
  5 + /// <summary>
  6 + /// 个人开单业绩统计列表输出
  7 + /// </summary>
  8 + public class LqStatisticsPersonalPerformanceListOutput
  9 + {
  10 + /// <summary>
  11 + /// 主键ID
  12 + /// </summary>
  13 + public string Id { get; set; }
  14 +
  15 + /// <summary>
  16 + /// 统计月份(YYYYMM)
  17 + /// </summary>
  18 + public string StatisticsMonth { get; set; }
  19 +
  20 + /// <summary>
  21 + /// 门店ID
  22 + /// </summary>
  23 + public string StoreId { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 门店名称
  27 + /// </summary>
  28 + public string StoreName { get; set; }
  29 +
  30 + /// <summary>
  31 + /// 金三角ID
  32 + /// </summary>
  33 + public string GoldTriangleId { get; set; }
  34 +
  35 + /// <summary>
  36 + /// 金三角名称
  37 + /// </summary>
  38 + public string GoldTriangleName { get; set; }
  39 +
  40 + /// <summary>
  41 + /// 岗位
  42 + /// </summary>
  43 + public string Position { get; set; }
  44 +
  45 + /// <summary>
  46 + /// 员工ID
  47 + /// </summary>
  48 + public string EmployeeId { get; set; }
  49 +
  50 + /// <summary>
  51 + /// 员工姓名
  52 + /// </summary>
  53 + public string EmployeeName { get; set; }
  54 +
  55 + /// <summary>
  56 + /// 总业绩
  57 + /// </summary>
  58 + public decimal TotalPerformance { get; set; }
  59 +
  60 + /// <summary>
  61 + /// 基础业绩
  62 + /// </summary>
  63 + public decimal BasePerformance { get; set; }
  64 +
  65 + /// <summary>
  66 + /// 合作业绩
  67 + /// </summary>
  68 + public decimal CooperationPerformance { get; set; }
  69 +
  70 + /// <summary>
  71 + /// 订单数量
  72 + /// </summary>
  73 + public int OrderCount { get; set; }
  74 +
  75 + /// <summary>
  76 + /// 最后订单日期
  77 + /// </summary>
  78 + public DateTime? LastOrderDate { get; set; }
  79 +
  80 + /// <summary>
  81 + /// 首次订单日期
  82 + /// </summary>
  83 + public DateTime? FirstOrderDate { get; set; }
  84 +
  85 + /// <summary>
  86 + /// 创建时间
  87 + /// </summary>
  88 + public DateTime CreateTime { get; set; }
  89 + }
  90 +}
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatisticsPersonalPerformance/LqStatisticsPersonalPerformanceListQueryInput.cs 0 → 100644
  1 +using System;
  2 +using NCC.Common.Filter;
  3 +
  4 +namespace NCC.Extend.Entitys.Dto.LqStatisticsPersonalPerformance
  5 +{
  6 + /// <summary>
  7 + /// 个人开单业绩统计列表查询输入
  8 + /// </summary>
  9 + public class LqStatisticsPersonalPerformanceListQueryInput : PageInputBase
  10 + {
  11 + /// <summary>
  12 + /// 统计月份(YYYYMM)
  13 + /// </summary>
  14 + public string StatisticsMonth { get; set; }
  15 +
  16 + /// <summary>
  17 + /// 门店ID
  18 + /// </summary>
  19 + public string StoreId { get; set; }
  20 +
  21 + /// <summary>
  22 + /// 员工ID
  23 + /// </summary>
  24 + public string EmployeeId { get; set; }
  25 +
  26 + /// <summary>
  27 + /// 员工姓名
  28 + /// </summary>
  29 + public string EmployeeName { get; set; }
  30 +
  31 + /// <summary>
  32 + /// 金三角ID
  33 + /// </summary>
  34 + public string GoldTriangleId { get; set; }
  35 +
  36 + /// <summary>
  37 + /// 岗位
  38 + /// </summary>
  39 + public string Position { get; set; }
  40 + }
  41 +}
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_statistics_personal_performance/LqStatisticsPersonalPerformanceEntity.cs 0 → 100644
  1 +using NCC.Common.Const;
  2 +using SqlSugar;
  3 +using System;
  4 +
  5 +namespace NCC.Extend.Entitys.lq_statistics_personal_performance
  6 +{
  7 + /// <summary>
  8 + /// 个人开单业绩统计表
  9 + /// </summary>
  10 + [SugarTable("lq_statistics_personal_performance")]
  11 + [Tenant(ClaimConst.TENANT_ID)]
  12 + public class LqStatisticsPersonalPerformanceEntity
  13 + {
  14 + /// <summary>
  15 + /// 主键ID
  16 + /// </summary>
  17 + [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)]
  18 + public string Id { get; set; }
  19 +
  20 + /// <summary>
  21 + /// 统计月份(YYYYMM)
  22 + /// </summary>
  23 + [SugarColumn(ColumnName = "F_StatisticsMonth")]
  24 + public string StatisticsMonth { get; set; }
  25 +
  26 + /// <summary>
  27 + /// 门店ID
  28 + /// </summary>
  29 + [SugarColumn(ColumnName = "F_StoreId")]
  30 + public string StoreId { get; set; }
  31 +
  32 + /// <summary>
  33 + /// 门店名称
  34 + /// </summary>
  35 + [SugarColumn(ColumnName = "F_StoreName")]
  36 + public string StoreName { get; set; }
  37 +
  38 + /// <summary>
  39 + /// 金三角ID
  40 + /// </summary>
  41 + [SugarColumn(ColumnName = "F_GoldTriangleId")]
  42 + public string GoldTriangleId { get; set; }
  43 +
  44 + /// <summary>
  45 + /// 金三角名称
  46 + /// </summary>
  47 + [SugarColumn(ColumnName = "F_GoldTriangleName")]
  48 + public string GoldTriangleName { get; set; }
  49 +
  50 + /// <summary>
  51 + /// 岗位
  52 + /// </summary>
  53 + [SugarColumn(ColumnName = "F_Position")]
  54 + public string Position { get; set; }
  55 +
  56 + /// <summary>
  57 + /// 员工ID
  58 + /// </summary>
  59 + [SugarColumn(ColumnName = "F_EmployeeId")]
  60 + public string EmployeeId { get; set; }
  61 +
  62 + /// <summary>
  63 + /// 员工姓名
  64 + /// </summary>
  65 + [SugarColumn(ColumnName = "F_EmployeeName")]
  66 + public string EmployeeName { get; set; }
  67 +
  68 + /// <summary>
  69 + /// 总业绩
  70 + /// </summary>
  71 + [SugarColumn(ColumnName = "F_TotalPerformance")]
  72 + public decimal TotalPerformance { get; set; }
  73 +
  74 + /// <summary>
  75 + /// 基础业绩
  76 + /// </summary>
  77 + [SugarColumn(ColumnName = "F_BasePerformance")]
  78 + public decimal BasePerformance { get; set; }
  79 +
  80 + /// <summary>
  81 + /// 合作业绩
  82 + /// </summary>
  83 + [SugarColumn(ColumnName = "F_CooperationPerformance")]
  84 + public decimal CooperationPerformance { get; set; }
  85 +
  86 + /// <summary>
  87 + /// 订单数量
  88 + /// </summary>
  89 + [SugarColumn(ColumnName = "F_OrderCount")]
  90 + public int OrderCount { get; set; }
  91 +
  92 + /// <summary>
  93 + /// 最后订单日期
  94 + /// </summary>
  95 + [SugarColumn(ColumnName = "F_LastOrderDate")]
  96 + public DateTime? LastOrderDate { get; set; }
  97 +
  98 + /// <summary>
  99 + /// 首次订单日期
  100 + /// </summary>
  101 + [SugarColumn(ColumnName = "F_FirstOrderDate")]
  102 + public DateTime? FirstOrderDate { get; set; }
  103 +
  104 + /// <summary>
  105 + /// 创建时间
  106 + /// </summary>
  107 + [SugarColumn(ColumnName = "F_CreateTime")]
  108 + public DateTime CreateTime { get; set; }
  109 + }
  110 +}
netcore/src/Modularity/Extend/NCC.Extend/LqGzService.cs
@@ -26,7 +26,6 @@ using NCC.Extend.Entitys.lq_kd_pxmx; @@ -26,7 +26,6 @@ using NCC.Extend.Entitys.lq_kd_pxmx;
26 using NCC.Extend.Entitys.lq_mdxx; 26 using NCC.Extend.Entitys.lq_mdxx;
27 using NCC.Extend.Entitys.lq_xmzl; 27 using NCC.Extend.Entitys.lq_xmzl;
28 using NCC.Extend.Entitys.lq_ycsd_jsj; 28 using NCC.Extend.Entitys.lq_ycsd_jsj;
29 -using NCC.Extend.Entitys.lq_statistics_gold_triangle;  
30 using NCC.Extend.Interfaces.LqGz; 29 using NCC.Extend.Interfaces.LqGz;
31 using NCC.FriendlyException; 30 using NCC.FriendlyException;
32 using NCC.JsonSerialization; 31 using NCC.JsonSerialization;
@@ -915,233 +914,6 @@ namespace NCC.Extend.LqGz @@ -915,233 +914,6 @@ namespace NCC.Extend.LqGz
915 914
916 #endregion 915 #endregion
917 916
918 - #region 金三角统计数据保存  
919 -  
920 - /// <summary>  
921 - /// 保存金三角开卡业绩统计数据  
922 - /// </summary>  
923 - /// <remarks>  
924 - /// 根据金三角设定和开单记录统计金三角的业绩数据  
925 - /// 使用直接SQL查询提高效率,完全按照原始SQL逻辑实现  
926 - ///  
927 - /// 示例请求:  
928 - /// ```json  
929 - /// POST /api/Extend/LqGz/save-gold-triangle-statistics  
930 - /// {  
931 - /// "statisticsMonth": "202401"  
932 - /// }  
933 - /// ```  
934 - /// </remarks>  
935 - /// <param name="statisticsMonth">统计月份(YYYYMM格式)</param>  
936 - /// <returns>保存结果</returns>  
937 - /// <response code="200">成功保存统计数据</response>  
938 - /// <response code="400">参数错误</response>  
939 - /// <response code="500">服务器内部错误</response>  
940 - [HttpPost("save-gold-triangle-statistics")]  
941 - public async Task<dynamic> SaveGoldTriangleStatistics(string statisticsMonth)  
942 - {  
943 - if (string.IsNullOrEmpty(statisticsMonth) || statisticsMonth.Length != 6)  
944 - {  
945 - throw NCCException.Oh("统计月份格式错误,请使用YYYYMM格式");  
946 - }  
947 -  
948 - try  
949 - {  
950 - // 使用直接SQL查询,完全按照原始SQL逻辑  
951 - var sql = @"  
952 - SELECT  
953 - jsj.F_Id AS JsjId,  
954 - jsj.jsj AS JsjName,  
955 - jsj.yf AS Month,  
956 - jsj.md AS StoreId,  
957 - md.dm AS StoreName,  
958 - COUNT(DISTINCT jksyj.glkdbh) AS OrderCount,  
959 - SUM(CAST(jksyj.jksyj AS DECIMAL(18,2))) AS TotalPerformance,  
960 - MAX(jksyj.yjsj) AS LastOrderDate,  
961 - MIN(jksyj.yjsj) AS FirstOrderDate  
962 - FROM lq_ycsd_jsj jsj  
963 - LEFT JOIN lq_kd_jksyj jksyj ON (  
964 - jsj.F_Id = jksyj.jsj_id  
965 - AND YEAR(jksyj.yjsj) = SUBSTRING(jsj.yf, 1, 4)  
966 - AND MONTH(jksyj.yjsj) = SUBSTRING(jsj.yf, 5, 2)  
967 - )  
968 - LEFT JOIN lq_mdxx md ON jsj.md = md.F_Id  
969 - WHERE jsj.yf = @statisticsMonth  
970 - AND jksyj.yjsj IS NOT NULL  
971 - AND jksyj.jksyj IS NOT NULL  
972 - AND jksyj.jksyj <> ''  
973 - AND jksyj.jksyj <> '0'  
974 - GROUP BY jsj.F_Id, jsj.jsj, jsj.yf, jsj.md, md.dm  
975 - ORDER BY jsj.yf DESC, TotalPerformance DESC";  
976 -  
977 - var statisticsData = await _db.Ado.SqlQueryAsync<dynamic>(sql, new { statisticsMonth });  
978 -  
979 - if (!statisticsData.Any())  
980 - {  
981 - return new  
982 - {  
983 - Success = true,  
984 - Message = $"未找到 {statisticsMonth} 月份的金三角统计数据",  
985 - SavedCount = 0  
986 - };  
987 - }  
988 -  
989 - // 转换为实体对象并保存  
990 - var entities = statisticsData.Select(data => new LqStatisticsGoldTriangleEntity  
991 - {  
992 - Id = YitIdHelper.NextId().ToString(),  
993 - GoldTriangleId = data.JsjId?.ToString(),  
994 - GoldTriangleName = data.JsjName?.ToString(),  
995 - StatisticsMonth = data.Month?.ToString(),  
996 - StoreId = data.StoreId?.ToString(),  
997 - StoreName = data.StoreName?.ToString(),  
998 - OrderCount = Convert.ToInt32(data.OrderCount),  
999 - TotalPerformance = Convert.ToDecimal(data.TotalPerformance),  
1000 - LastOrderDate = data.LastOrderDate as DateTime?,  
1001 - FirstOrderDate = data.FirstOrderDate as DateTime?,  
1002 - CreateTime = DateTime.Now  
1003 - }).ToList();  
1004 -  
1005 - // 先删除该月份的历史数据  
1006 - await _db.Deleteable<LqStatisticsGoldTriangleEntity>()  
1007 - .Where(x => x.StatisticsMonth == statisticsMonth)  
1008 - .ExecuteCommandAsync();  
1009 -  
1010 - // 批量插入新数据  
1011 - var savedCount = await _db.Insertable(entities).ExecuteCommandAsync();  
1012 -  
1013 - _logger.LogInformation($"成功保存金三角统计数据 - 月份: {statisticsMonth}, 记录数: {savedCount}");  
1014 -  
1015 - return new  
1016 - {  
1017 - Success = true,  
1018 - Message = $"成功保存 {savedCount} 条金三角统计数据",  
1019 - SavedCount = savedCount,  
1020 - StatisticsMonth = statisticsMonth  
1021 - };  
1022 - }  
1023 - catch (Exception ex)  
1024 - {  
1025 - _logger.LogError(ex, $"保存金三角统计数据失败 - 月份: {statisticsMonth}");  
1026 - throw NCCException.Oh($"保存金三角统计数据失败: {ex.Message}");  
1027 - }  
1028 - }  
1029 -  
1030 - /// <summary>  
1031 - /// 测试金三角统计SQL查询  
1032 - /// </summary>  
1033 - /// <remarks>  
1034 - /// 直接执行SQL查询,验证统计逻辑是否正确  
1035 - ///  
1036 - /// 示例请求:  
1037 - /// ```json  
1038 - /// GET /api/Extend/LqGz/test-gold-triangle-sql?statisticsMonth=202401  
1039 - /// ```  
1040 - /// </remarks>  
1041 - /// <param name="statisticsMonth">统计月份(YYYYMM格式)</param>  
1042 - /// <returns>原始SQL查询结果</returns>  
1043 - /// <response code="200">成功返回查询结果</response>  
1044 - /// <response code="400">参数错误</response>  
1045 - [HttpGet("test-gold-triangle-sql")]  
1046 - public async Task<dynamic> TestGoldTriangleSql(string statisticsMonth)  
1047 - {  
1048 - if (string.IsNullOrEmpty(statisticsMonth) || statisticsMonth.Length != 6)  
1049 - {  
1050 - throw NCCException.Oh("统计月份格式错误,请使用YYYYMM格式");  
1051 - }  
1052 -  
1053 - try  
1054 - {  
1055 - var sql = @"  
1056 - SELECT  
1057 - jsj.F_Id AS JsjId,  
1058 - jsj.jsj AS JsjName,  
1059 - jsj.yf AS Month,  
1060 - jsj.md AS StoreId,  
1061 - md.dm AS StoreName,  
1062 - COUNT(DISTINCT jksyj.glkdbh) AS OrderCount,  
1063 - SUM(CAST(jksyj.jksyj AS DECIMAL(18,2))) AS TotalPerformance,  
1064 - MAX(jksyj.yjsj) AS LastOrderDate,  
1065 - MIN(jksyj.yjsj) AS FirstOrderDate  
1066 - FROM lq_ycsd_jsj jsj  
1067 - LEFT JOIN lq_kd_jksyj jksyj ON (  
1068 - jsj.F_Id = jksyj.jsj_id  
1069 - AND YEAR(jksyj.yjsj) = SUBSTRING(jsj.yf, 1, 4)  
1070 - AND MONTH(jksyj.yjsj) = SUBSTRING(jsj.yf, 5, 2)  
1071 - )  
1072 - LEFT JOIN lq_mdxx md ON jsj.md = md.F_Id  
1073 - WHERE jsj.yf = @statisticsMonth  
1074 - AND jksyj.yjsj IS NOT NULL  
1075 - AND jksyj.jksyj IS NOT NULL  
1076 - AND jksyj.jksyj <> ''  
1077 - AND jksyj.jksyj <> '0'  
1078 - GROUP BY jsj.F_Id, jsj.jsj, jsj.yf, jsj.md, md.dm  
1079 - ORDER BY jsj.yf DESC, TotalPerformance DESC";  
1080 -  
1081 - var result = await _db.Ado.SqlQueryAsync<dynamic>(sql, new { statisticsMonth });  
1082 -  
1083 - return new  
1084 - {  
1085 - Success = true,  
1086 - Data = result,  
1087 - Count = result.Count,  
1088 - StatisticsMonth = statisticsMonth,  
1089 - Sql = sql  
1090 - };  
1091 - }  
1092 - catch (Exception ex)  
1093 - {  
1094 - _logger.LogError(ex, $"测试金三角统计SQL失败 - 月份: {statisticsMonth}");  
1095 - throw NCCException.Oh($"测试金三角统计SQL失败: {ex.Message}");  
1096 - }  
1097 - }  
1098 -  
1099 - /// <summary>  
1100 - /// 获取金三角统计数据  
1101 - /// </summary>  
1102 - /// <remarks>  
1103 - /// 查询指定月份的金三角统计数据  
1104 - ///  
1105 - /// 示例请求:  
1106 - /// ```json  
1107 - /// GET /api/Extend/LqGz/get-gold-triangle-statistics?statisticsMonth=202401  
1108 - /// ```  
1109 - /// </remarks>  
1110 - /// <param name="statisticsMonth">统计月份(YYYYMM格式)</param>  
1111 - /// <returns>统计数据列表</returns>  
1112 - /// <response code="200">成功返回统计数据</response>  
1113 - /// <response code="400">参数错误</response>  
1114 - [HttpGet("get-gold-triangle-statistics")]  
1115 - public async Task<dynamic> GetGoldTriangleStatistics(string statisticsMonth)  
1116 - {  
1117 - if (string.IsNullOrEmpty(statisticsMonth))  
1118 - {  
1119 - throw NCCException.Oh("统计月份不能为空");  
1120 - }  
1121 -  
1122 - try  
1123 - {  
1124 - var statistics = await _db.Queryable<LqStatisticsGoldTriangleEntity>()  
1125 - .Where(x => x.StatisticsMonth == statisticsMonth)  
1126 - .OrderBy(x => x.TotalPerformance, OrderByType.Desc)  
1127 - .ToListAsync();  
1128 -  
1129 - return new  
1130 - {  
1131 - Success = true,  
1132 - Data = statistics,  
1133 - Count = statistics.Count,  
1134 - StatisticsMonth = statisticsMonth  
1135 - };  
1136 - }  
1137 - catch (Exception ex)  
1138 - {  
1139 - _logger.LogError(ex, $"查询金三角统计数据失败 - 月份: {statisticsMonth}");  
1140 - throw NCCException.Oh($"查询金三角统计数据失败: {ex.Message}");  
1141 - }  
1142 - }  
1143 -  
1144 - #endregion  
1145 917
1146 918
1147 919
netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs
@@ -23,12 +23,18 @@ using NCC.Extend.Entitys.lq_mdxx; @@ -23,12 +23,18 @@ using NCC.Extend.Entitys.lq_mdxx;
23 using NCC.Extend.Entitys.lq_xh_kjbsyj; 23 using NCC.Extend.Entitys.lq_xh_kjbsyj;
24 using NCC.Extend.Entitys.lq_ycsd_jsj; 24 using NCC.Extend.Entitys.lq_ycsd_jsj;
25 using NCC.Extend.Entitys.lq_yjmxb; 25 using NCC.Extend.Entitys.lq_yjmxb;
  26 +using NCC.Extend.Entitys.lq_statistics_gold_triangle;
  27 +using NCC.Extend.Entitys.lq_statistics_personal_performance;
  28 +using NCC.Extend.Entitys.lq_xmzl;
  29 +using NCC.Extend.Entitys.Dto.LqStatisticsPersonalPerformance;
26 using NCC.Extend.Entitys.v_tech_teacher_flow; 30 using NCC.Extend.Entitys.v_tech_teacher_flow;
27 using NCC.Extend.Interfaces.LqStatistics; 31 using NCC.Extend.Interfaces.LqStatistics;
28 using NCC.Extend.Utils; 32 using NCC.Extend.Utils;
29 using NCC.FriendlyException; 33 using NCC.FriendlyException;
30 using NCC.System.Entitys.Permission; 34 using NCC.System.Entitys.Permission;
31 using SqlSugar; 35 using SqlSugar;
  36 +using Yitter.IdGenerator;
  37 +using NCC.Extend.Entitys.lq_kd_pxmx;
32 38
33 namespace NCC.Extend.LqStatistics 39 namespace NCC.Extend.LqStatistics
34 { 40 {
@@ -1178,27 +1184,475 @@ namespace NCC.Extend.LqStatistics @@ -1178,27 +1184,475 @@ namespace NCC.Extend.LqStatistics
1178 throw NCCException.Oh(ErrorCode.COM1001, "查询金三角业绩统计失败"); 1184 throw NCCException.Oh(ErrorCode.COM1001, "查询金三角业绩统计失败");
1179 } 1185 }
1180 } 1186 }
  1187 +
1181 #endregion 1188 #endregion
1182 - }  
1183 1189
1184 - /// <summary>  
1185 - /// 部门信息  
1186 - /// </summary>  
1187 - public class DepartmentInfo  
1188 - { 1190 + #region 金三角统计数据保存
  1191 +
  1192 + /// <summary>
  1193 + /// 1、保存金三角开卡业绩统计数据
  1194 + /// </summary>
  1195 + /// <remarks>
  1196 + /// 根据金三角设定和开单记录统计金三角的业绩数据
  1197 + /// 使用SqlSugar框架实现,优化查询性能
  1198 + ///
  1199 + /// 示例请求:
  1200 + /// ```json
  1201 + /// POST /api/Extend/LqStatistics/save-gold-triangle-statistics
  1202 + /// {
  1203 + /// "statisticsMonth": "202401"
  1204 + /// }
  1205 + /// ```
  1206 + /// </remarks>
  1207 + /// <param name="statisticsMonth">统计月份(YYYYMM格式)</param>
  1208 + /// <returns>保存结果</returns>
  1209 + /// <response code="200">成功保存统计数据</response>
  1210 + /// <response code="400">参数错误</response>
  1211 + /// <response code="500">服务器内部错误</response>
  1212 + [HttpPost("save-gold-triangle-statistics")]
  1213 + public async Task<dynamic> SaveGoldTriangleStatistics(string statisticsMonth)
  1214 + {
  1215 + if (string.IsNullOrEmpty(statisticsMonth) || statisticsMonth.Length != 6)
  1216 + {
  1217 + throw NCCException.Oh("统计月份格式错误,请使用YYYYMM格式");
  1218 + }
  1219 +
  1220 + try
  1221 + {
  1222 + // 使用数据库聚合方式,直接在数据库中完成所有统计计算
  1223 + var sql = @"
  1224 + SELECT
  1225 + jsj.F_Id AS GoldTriangleId,
  1226 + jsj.jsj AS GoldTriangleName,
  1227 + jsj.yf AS StatisticsMonth,
  1228 + jsj.md AS StoreId,
  1229 + COALESCE(md.dm, '') AS StoreName,
  1230 + COUNT(DISTINCT jksyj.glkdbh) AS OrderCount,
  1231 + SUM(CAST(jksyj.jksyj AS DECIMAL(18,2))) AS TotalPerformance,
  1232 + MAX(jksyj.yjsj) AS LastOrderDate,
  1233 + MIN(jksyj.yjsj) AS FirstOrderDate
  1234 + FROM lq_ycsd_jsj jsj
  1235 + LEFT JOIN lq_kd_jksyj jksyj ON (
  1236 + jsj.F_Id = jksyj.jsj_id
  1237 + AND YEAR(jksyj.yjsj) = SUBSTRING(jsj.yf, 1, 4)
  1238 + AND MONTH(jksyj.yjsj) = SUBSTRING(jsj.yf, 5, 2)
  1239 + )
  1240 + LEFT JOIN lq_mdxx md ON jsj.md = md.F_Id
  1241 + WHERE jsj.yf = @statisticsMonth
  1242 + AND (jksyj.yjsj IS NULL OR (
  1243 + jksyj.yjsj IS NOT NULL
  1244 + AND jksyj.jksyj IS NOT NULL
  1245 + AND jksyj.jksyj != ''
  1246 + AND jksyj.jksyj != '0'
  1247 + ))
  1248 + GROUP BY
  1249 + jsj.F_Id,
  1250 + jsj.jsj,
  1251 + jsj.yf,
  1252 + jsj.md,
  1253 + md.dm
  1254 + ORDER BY TotalPerformance DESC";
  1255 +
  1256 + // 解析统计月份
  1257 + var year = int.Parse(statisticsMonth.Substring(0, 4));
  1258 + var month = int.Parse(statisticsMonth.Substring(4, 2));
  1259 +
  1260 + // 执行SQL查询
  1261 + var statisticsData = await _db.Ado.SqlQueryAsync<dynamic>(sql, new { statisticsMonth });
  1262 +
  1263 + if (!statisticsData.Any())
  1264 + {
  1265 + return new
  1266 + {
  1267 + Success = true,
  1268 + Message = $"未找到 {statisticsMonth} 月份的金三角统计数据",
  1269 + SavedCount = 0
  1270 + };
  1271 + }
  1272 +
  1273 + // 转换为实体对象
  1274 + var entities = statisticsData.Select(data => new LqStatisticsGoldTriangleEntity
  1275 + {
  1276 + Id = YitIdHelper.NextId().ToString(),
  1277 + GoldTriangleId = data.GoldTriangleId?.ToString() ?? "",
  1278 + GoldTriangleName = data.GoldTriangleName?.ToString() ?? "",
  1279 + StatisticsMonth = data.StatisticsMonth?.ToString() ?? statisticsMonth,
  1280 + StoreId = data.StoreId?.ToString() ?? "",
  1281 + StoreName = data.StoreName?.ToString() ?? "",
  1282 + OrderCount = Convert.ToInt32(data.OrderCount ?? 0),
  1283 + TotalPerformance = Convert.ToDecimal(data.TotalPerformance ?? 0),
  1284 + LastOrderDate = data.LastOrderDate as DateTime?,
  1285 + FirstOrderDate = data.FirstOrderDate as DateTime?,
  1286 + CreateTime = DateTime.Now
  1287 + }).ToList();
  1288 +
  1289 + // 使用事务确保数据一致性
  1290 + var result = await _db.Ado.UseTranAsync(async () =>
  1291 + {
  1292 + // 先删除该月份的历史数据
  1293 + await _db.Deleteable<LqStatisticsGoldTriangleEntity>()
  1294 + .Where(x => x.StatisticsMonth == statisticsMonth)
  1295 + .ExecuteCommandAsync();
  1296 +
  1297 + // 批量插入新数据
  1298 + return await _db.Insertable(entities).ExecuteCommandAsync();
  1299 + });
  1300 +
  1301 + var savedCount = result.IsSuccess ? result.Data : 0;
  1302 + _logger.LogInformation($"成功保存金三角统计数据 - 月份: {statisticsMonth}, 记录数: {savedCount}");
  1303 +
  1304 + return new
  1305 + {
  1306 + Success = true,
  1307 + Message = $"成功保存 {savedCount} 条金三角统计数据",
  1308 + SavedCount = savedCount,
  1309 + StatisticsMonth = statisticsMonth
  1310 + };
  1311 + }
  1312 + catch (Exception ex)
  1313 + {
  1314 + _logger.LogError(ex, $"保存金三角统计数据失败 - 月份: {statisticsMonth}");
  1315 + throw NCCException.Oh($"保存金三角统计数据失败: {ex.Message}");
  1316 + }
  1317 + }
  1318 +
  1319 + /// <summary>
  1320 + /// 获取金三角统计数据
  1321 + /// </summary>
  1322 + /// <remarks>
  1323 + /// 查询指定月份的金三角统计数据
  1324 + ///
  1325 + /// 示例请求:
  1326 + /// ```json
  1327 + /// GET /api/Extend/LqStatistics/get-gold-triangle-statistics?statisticsMonth=202401
  1328 + /// ```
  1329 + /// </remarks>
  1330 + /// <param name="statisticsMonth">统计月份(YYYYMM格式)</param>
  1331 + /// <returns>统计数据列表</returns>
  1332 + /// <response code="200">成功返回统计数据</response>
  1333 + /// <response code="400">参数错误</response>
  1334 + [HttpGet("get-gold-triangle-statistics")]
  1335 + public async Task<dynamic> GetGoldTriangleStatistics(string statisticsMonth)
  1336 + {
  1337 + if (string.IsNullOrEmpty(statisticsMonth))
  1338 + {
  1339 + throw NCCException.Oh("统计月份不能为空");
  1340 + }
  1341 +
  1342 + try
  1343 + {
  1344 + var statistics = await _db.Queryable<LqStatisticsGoldTriangleEntity>()
  1345 + .Where(x => x.StatisticsMonth == statisticsMonth)
  1346 + .OrderBy(x => x.TotalPerformance, OrderByType.Desc)
  1347 + .ToListAsync();
  1348 +
  1349 + return new
  1350 + {
  1351 + Success = true,
  1352 + Data = statistics,
  1353 + Count = statistics.Count,
  1354 + StatisticsMonth = statisticsMonth
  1355 + };
  1356 + }
  1357 + catch (Exception ex)
  1358 + {
  1359 + _logger.LogError(ex, $"查询金三角统计数据失败 - 月份: {statisticsMonth}");
  1360 + throw NCCException.Oh($"查询金三角统计数据失败: {ex.Message}");
  1361 + }
  1362 + }
  1363 +
  1364 + #endregion
  1365 +
  1366 + #region 个人开单业绩统计
  1367 +
  1368 + /// <summary>
  1369 + /// 保存个人开单业绩统计数据
  1370 + /// </summary>
  1371 + /// <remarks>
  1372 + /// 根据开单记录统计个人的业绩数据,包括基础业绩和合作业绩
  1373 + /// 基础业绩和合作业绩的划分根据品项ID查询lq_xmzl表的fl3字段
  1374 + /// 使用数据库聚合方式优化性能,避免大量数据加载到内存
  1375 + ///
  1376 + /// 示例请求:
  1377 + /// ```json
  1378 + /// POST /api/Extend/LqStatistics/save-personal-performance-statistics
  1379 + /// {
  1380 + /// "statisticsMonth": "202401"
  1381 + /// }
  1382 + /// ```
  1383 + /// </remarks>
  1384 + /// <param name="statisticsMonth">统计月份(YYYYMM格式)</param>
  1385 + /// <returns>保存结果</returns>
  1386 + /// <response code="200">成功保存统计数据</response>
  1387 + /// <response code="400">参数错误</response>
  1388 + /// <response code="500">服务器内部错误</response>
  1389 + [HttpPost("save-personal-performance-statistics")]
  1390 + public async Task<dynamic> SavePersonalPerformanceStatistics(string statisticsMonth)
  1391 + {
  1392 + if (string.IsNullOrEmpty(statisticsMonth) || statisticsMonth.Length != 6)
  1393 + {
  1394 + throw NCCException.Oh("统计月份格式错误,请使用YYYYMM格式");
  1395 + }
  1396 +
  1397 + try
  1398 + {
  1399 + // 使用数据库聚合方式,直接在数据库中完成所有统计计算
  1400 + // 按照开单记录统计,避免重复计算
  1401 + var sql = @"
  1402 + SELECT
  1403 + jksyj.jkszh AS EmployeeId,
  1404 + u.F_REALNAME AS EmployeeName,
  1405 + u.F_MDID AS StoreId,
  1406 + COALESCE(md.dm, '') AS StoreName,
  1407 + COALESCE(jsj.F_Id, '') AS GoldTriangleId,
  1408 + COALESCE(jsj.jsj, '') AS GoldTriangleName,
  1409 + CASE
  1410 + WHEN jsjUser.is_leader = 1 THEN '顾问'
  1411 + ELSE COALESCE(u.F_GW, '')
  1412 + END AS Position,
  1413 + COUNT(DISTINCT jksyj.glkdbh) AS OrderCount,
  1414 + MAX(jksyj.yjsj) AS LastOrderDate,
  1415 + MIN(jksyj.yjsj) AS FirstOrderDate,
  1416 + SUM(
  1417 + CASE
  1418 + WHEN xmzl.fl3 = '合作业绩' THEN CAST(jksyj.jksyj AS DECIMAL(18,2))
  1419 + ELSE 0
  1420 + END
  1421 + ) AS CooperationPerformance,
  1422 + SUM(
  1423 + CASE
  1424 + WHEN xmzl.fl3 IS NULL OR xmzl.fl3 != '合作业绩' THEN CAST(jksyj.jksyj AS DECIMAL(18,2))
  1425 + ELSE 0
  1426 + END
  1427 + ) AS BasePerformance,
  1428 + SUM(CAST(jksyj.jksyj AS DECIMAL(18,2))) AS TotalPerformance
  1429 + FROM lq_kd_jksyj jksyj
  1430 + INNER JOIN lq_kd_pxmx pxmx ON jksyj.F_kdpxid = pxmx.F_Id
  1431 + INNER JOIN lq_xmzl xmzl ON pxmx.px = xmzl.F_Id
  1432 + INNER JOIN BASE_USER u ON jksyj.jkszh = u.F_Id
  1433 + LEFT JOIN lq_mdxx md ON u.F_MDID = md.F_Id
  1434 + LEFT JOIN lq_ycsd_jsj jsj ON jksyj.jsj_id = jsj.F_Id AND jsj.yf = @statisticsMonth
  1435 + LEFT JOIN (
  1436 + SELECT DISTINCT user_id, F_Month, MAX(is_leader) as is_leader
  1437 + FROM lq_jinsanjiao_user
  1438 + WHERE F_Month = @statisticsMonth
  1439 + GROUP BY user_id, F_Month
  1440 + ) jsjUser ON jksyj.jkszh = jsjUser.user_id
  1441 + WHERE jksyj.yjsj IS NOT NULL
  1442 + AND jksyj.jksyj IS NOT NULL
  1443 + AND jksyj.jksyj != ''
  1444 + AND jksyj.jksyj != '0'
  1445 + AND jksyj.F_kdpxid IS NOT NULL
  1446 + AND jksyj.F_kdpxid != ''
  1447 + AND YEAR(jksyj.yjsj) = @year
  1448 + AND MONTH(jksyj.yjsj) = @month
  1449 + GROUP BY
  1450 + jksyj.jkszh,
  1451 + u.F_REALNAME,
  1452 + u.F_MDID,
  1453 + md.dm,
  1454 + jsj.F_Id,
  1455 + jsj.jsj,
  1456 + jsjUser.is_leader,
  1457 + u.F_GW
  1458 + ORDER BY TotalPerformance DESC";
  1459 +
  1460 + // 解析统计月份
  1461 + var year = int.Parse(statisticsMonth.Substring(0, 4));
  1462 + var month = int.Parse(statisticsMonth.Substring(4, 2));
  1463 +
  1464 + var parameters = new Dictionary<string, object>
  1465 + {
  1466 + { "@statisticsMonth", statisticsMonth },
  1467 + { "@year", year },
  1468 + { "@month", month }
  1469 + };
  1470 +
  1471 + _logger.LogInformation($"执行个人业绩统计SQL - 月份: {statisticsMonth}");
  1472 +
  1473 + var statisticsData = await _db.Ado.SqlQueryAsync<dynamic>(sql, parameters);
  1474 +
  1475 + if (!statisticsData.Any())
  1476 + {
  1477 + return new
  1478 + {
  1479 + Success = true,
  1480 + Message = $"未找到 {statisticsMonth} 月份的开单记录数据",
  1481 + SavedCount = 0
  1482 + };
  1483 + }
  1484 +
  1485 + _logger.LogInformation($"查询到个人业绩统计数据: {statisticsData.Count} 条");
  1486 +
  1487 + // 创建实体列表
  1488 + var entities = statisticsData.Select(stats => new LqStatisticsPersonalPerformanceEntity
  1489 + {
  1490 + Id = YitIdHelper.NextId().ToString(),
  1491 + StatisticsMonth = statisticsMonth,
  1492 + StoreId = stats.StoreId?.ToString() ?? "",
  1493 + StoreName = stats.StoreName?.ToString() ?? "",
  1494 + GoldTriangleId = stats.GoldTriangleId?.ToString() ?? "",
  1495 + GoldTriangleName = stats.GoldTriangleName?.ToString() ?? "",
  1496 + Position = stats.Position?.ToString() ?? "",
  1497 + EmployeeId = stats.EmployeeId?.ToString() ?? "",
  1498 + EmployeeName = stats.EmployeeName?.ToString() ?? "",
  1499 + TotalPerformance = Convert.ToDecimal(stats.TotalPerformance ?? 0),
  1500 + BasePerformance = Convert.ToDecimal(stats.BasePerformance ?? 0),
  1501 + CooperationPerformance = Convert.ToDecimal(stats.CooperationPerformance ?? 0),
  1502 + OrderCount = Convert.ToInt32(stats.OrderCount ?? 0),
  1503 + LastOrderDate = stats.LastOrderDate as DateTime?,
  1504 + FirstOrderDate = stats.FirstOrderDate as DateTime?,
  1505 + CreateTime = DateTime.Now
  1506 + }).ToList();
  1507 +
  1508 + // 使用事务确保数据一致性
  1509 + var result = await _db.Ado.UseTranAsync(async () =>
  1510 + {
  1511 + // 先删除该月份的历史数据
  1512 + await _db.Deleteable<LqStatisticsPersonalPerformanceEntity>()
  1513 + .Where(x => x.StatisticsMonth == statisticsMonth)
  1514 + .ExecuteCommandAsync();
  1515 +
  1516 + // 批量插入新数据
  1517 + return await _db.Insertable(entities).ExecuteCommandAsync();
  1518 + });
  1519 +
  1520 + var savedCount = result.IsSuccess ? result.Data : 0;
  1521 + _logger.LogInformation($"成功保存个人业绩统计数据 - 月份: {statisticsMonth}, 记录数: {savedCount}");
  1522 +
  1523 + return new
  1524 + {
  1525 + Success = true,
  1526 + Message = $"成功保存 {savedCount} 条个人业绩统计数据",
  1527 + SavedCount = savedCount,
  1528 + StatisticsMonth = statisticsMonth
  1529 + };
  1530 + }
  1531 + catch (Exception ex)
  1532 + {
  1533 + _logger.LogError(ex, $"保存个人业绩统计数据失败 - 月份: {statisticsMonth}");
  1534 + throw NCCException.Oh($"保存个人业绩统计数据失败: {ex.Message}");
  1535 + }
  1536 + }
  1537 +
1189 /// <summary> 1538 /// <summary>
1190 - /// 部门ID 1539 + /// 获取个人开单业绩统计数据
1191 /// </summary> 1540 /// </summary>
1192 - public string DepartmentId { get; set; } 1541 + /// <remarks>
  1542 + /// 查询指定月份的个人业绩统计数据
  1543 + ///
  1544 + /// 示例请求:
  1545 + /// ```json
  1546 + /// GET /api/Extend/LqStatistics/get-personal-performance-statistics?statisticsMonth=202401
  1547 + /// ```
  1548 + /// </remarks>
  1549 + /// <param name="statisticsMonth">统计月份(YYYYMM格式)</param>
  1550 + /// <returns>统计数据列表</returns>
  1551 + /// <response code="200">成功返回统计数据</response>
  1552 + /// <response code="400">参数错误</response>
  1553 + [HttpGet("get-personal-performance-statistics")]
  1554 + public async Task<dynamic> GetPersonalPerformanceStatistics(string statisticsMonth)
  1555 + {
  1556 + if (string.IsNullOrEmpty(statisticsMonth))
  1557 + {
  1558 + throw NCCException.Oh("统计月份不能为空");
  1559 + }
  1560 +
  1561 + try
  1562 + {
  1563 + var statistics = await _db.Queryable<LqStatisticsPersonalPerformanceEntity>()
  1564 + .Where(x => x.StatisticsMonth == statisticsMonth)
  1565 + .OrderBy(x => x.TotalPerformance, OrderByType.Desc)
  1566 + .ToListAsync();
  1567 +
  1568 + return statistics;
  1569 + }
  1570 + catch (Exception ex)
  1571 + {
  1572 + _logger.LogError(ex, $"查询个人业绩统计数据失败 - 月份: {statisticsMonth}");
  1573 + throw NCCException.Oh($"查询个人业绩统计数据失败: {ex.Message}");
  1574 + }
  1575 + }
1193 1576
1194 /// <summary> 1577 /// <summary>
1195 - /// 部门名称 1578 + /// 分页查询个人开单业绩统计数据
1196 /// </summary> 1579 /// </summary>
1197 - public string DepartmentName { get; set; } 1580 + /// <remarks>
  1581 + /// 分页查询个人业绩统计数据,支持多条件筛选
  1582 + ///
  1583 + /// 示例请求:
  1584 + /// ```json
  1585 + /// POST /api/Extend/LqStatistics/get-personal-performance-statistics-list
  1586 + /// {
  1587 + /// "statisticsMonth": "202401",
  1588 + /// "storeId": "store123",
  1589 + /// "employeeName": "张三",
  1590 + /// "pageIndex": 1,
  1591 + /// "pageSize": 20
  1592 + /// }
  1593 + /// ```
  1594 + /// </remarks>
  1595 + /// <param name="input">查询条件</param>
  1596 + /// <returns>分页统计数据</returns>
  1597 + /// <response code="200">成功返回分页数据</response>
  1598 + /// <response code="400">参数错误</response>
  1599 + [HttpPost("get-personal-performance-statistics-list")]
  1600 + public async Task<dynamic> GetPersonalPerformanceStatisticsList(LqStatisticsPersonalPerformanceListQueryInput input)
  1601 + {
  1602 + try
  1603 + {
  1604 + var query = _db.Queryable<LqStatisticsPersonalPerformanceEntity>();
  1605 +
  1606 + // 添加查询条件
  1607 + query = query.WhereIF(!string.IsNullOrEmpty(input.StatisticsMonth), x => x.StatisticsMonth == input.StatisticsMonth);
  1608 + query = query.WhereIF(!string.IsNullOrEmpty(input.StoreId), x => x.StoreId == input.StoreId);
  1609 + query = query.WhereIF(!string.IsNullOrEmpty(input.EmployeeId), x => x.EmployeeId == input.EmployeeId);
  1610 + query = query.WhereIF(!string.IsNullOrEmpty(input.EmployeeName), x => x.EmployeeName.Contains(input.EmployeeName));
  1611 + query = query.WhereIF(!string.IsNullOrEmpty(input.GoldTriangleId), x => x.GoldTriangleId == input.GoldTriangleId);
  1612 + query = query.WhereIF(!string.IsNullOrEmpty(input.Position), x => x.Position == input.Position);
  1613 +
  1614 + // 按总业绩降序排序
  1615 + query = query.OrderBy(x => x.TotalPerformance, OrderByType.Desc);
  1616 +
  1617 + // 分页查询
  1618 + var result = await query.ToPagedListAsync(input.currentPage, input.pageSize);
  1619 +
  1620 + return new
  1621 + {
  1622 + Records = result.list,
  1623 + Total = result.pagination.Total,
  1624 + PageIndex = input.currentPage,
  1625 + PageSize = input.pageSize
  1626 + };
  1627 + }
  1628 + catch (Exception ex)
  1629 + {
  1630 + _logger.LogError(ex, "查询个人业绩统计数据列表失败");
  1631 + throw NCCException.Oh($"查询个人业绩统计数据列表失败: {ex.Message}");
  1632 + }
  1633 + }
  1634 +
  1635 + #endregion
1198 1636
1199 /// <summary> 1637 /// <summary>
1200 - /// 父部门ID 1638 + /// 部门信息
1201 /// </summary> 1639 /// </summary>
1202 - public string ParentId { get; set; } 1640 + public class DepartmentInfo
  1641 + {
  1642 + /// <summary>
  1643 + /// 部门ID
  1644 + /// </summary>
  1645 + public string DepartmentId { get; set; }
  1646 +
  1647 + /// <summary>
  1648 + /// 部门名称
  1649 + /// </summary>
  1650 + public string DepartmentName { get; set; }
  1651 +
  1652 + /// <summary>
  1653 + /// 父部门ID
  1654 + /// </summary>
  1655 + public string ParentId { get; set; }
  1656 + }
1203 } 1657 }
1204 } 1658 }
netcore/src/Modularity/Extend/NCC.Extend/LqYcsdJsjService.cs
@@ -327,11 +327,11 @@ namespace NCC.Extend.LqYcsdJsj @@ -327,11 +327,11 @@ namespace NCC.Extend.LqYcsdJsj
327 { 327 {
328 await CreateJsjMembers(entity.Id, input.members, userInfo.userId); 328 await CreateJsjMembers(entity.Id, input.members, userInfo.userId);
329 } 329 }
330 - // 3. 创建站点战队T区(如果金三角不是T区且不是单人)  
331 - if (!input.jsj.EndsWith("T区") && input.members != null && input.members.Count > 1)  
332 - {  
333 - await CreateOrUpdateTeamTArea(input.yf, input.jsj, input.md, userInfo.userId);  
334 - } 330 + // 3. 创建站点战队T区(如果金三角不是T区且不是单人),暂时不用创建金三角的T区,等待业务部门确认逻辑后进行
  331 + // if (!input.jsj.EndsWith("T区") && input.members != null && input.members.Count > 1)
  332 + // {
  333 + // await CreateOrUpdateTeamTArea(input.yf, input.jsj, input.md, userInfo.userId);
  334 + // }
335 // 提交事务 335 // 提交事务
336 _db.CommitTran(); 336 _db.CommitTran();
337 } 337 }