Commit 0f0ce0baa720848e67132f7b27ed90c97606cf74

Authored by “wangming”
1 parent 41da4257

Refactor LqStatisticsService to implement gold triangle statistics saving and re…

…trieval endpoints, enhancing performance with database aggregation. Introduce personal performance statistics handling, including saving and querying capabilities. Update LqYcsdJsjService to temporarily disable T area creation logic pending business confirmation.
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 }