Commit 7d89becc85df33f45b7d8a245c2c9f82dec97ece
1 parent
297c68d7
feat: 退款明细列表优化 - 支持显示多个健康师及业绩
- 修改退款明细列表查询逻辑,从退款健康师业绩表查询(而非开单健康师业绩表) - 支持一个退款明细显示多个健康师,格式:姓名(业绩)、姓名(业绩) - 新增实际退款金额字段,显示所有健康师业绩之和 - 优化前端显示,健康师列显示每个健康师及其业绩 - 添加测试脚本test_refund_detail.sh
Showing
4 changed files
with
183 additions
and
74 deletions
antis-ncc-admin/src/views/statisticsList/form21.vue
| @@ -270,10 +270,10 @@ | @@ -270,10 +270,10 @@ | ||
| 270 | </el-tag> | 270 | </el-tag> |
| 271 | </template> | 271 | </template> |
| 272 | </el-table-column> | 272 | </el-table-column> |
| 273 | - <el-table-column prop="healthCoachName" label="健康师" min-width="120" sortable="custom"> | 273 | + <el-table-column prop="healthCoachName" label="健康师及业绩" min-width="200" sortable="custom"> |
| 274 | <template slot-scope="scope"> | 274 | <template slot-scope="scope"> |
| 275 | <i class="el-icon-user-solid" style="margin-right: 4px; color: #F56C6C;"></i> | 275 | <i class="el-icon-user-solid" style="margin-right: 4px; color: #F56C6C;"></i> |
| 276 | - <span>{{ scope.row.healthCoachName || '无' }}</span> | 276 | + <span :title="scope.row.healthCoachName || '无'" style="white-space: normal; word-break: break-all;">{{ scope.row.healthCoachName || '无' }}</span> |
| 277 | </template> | 277 | </template> |
| 278 | </el-table-column> | 278 | </el-table-column> |
| 279 | <el-table-column prop="healthCoachPerformance" label="健康师业绩" min-width="130" sortable="custom"> | 279 | <el-table-column prop="healthCoachPerformance" label="健康师业绩" min-width="130" sortable="custom"> |
| @@ -281,6 +281,12 @@ | @@ -281,6 +281,12 @@ | ||
| 281 | <span class="amount-value">¥{{ formatMoney(scope.row.healthCoachPerformance) }}</span> | 281 | <span class="amount-value">¥{{ formatMoney(scope.row.healthCoachPerformance) }}</span> |
| 282 | </template> | 282 | </template> |
| 283 | </el-table-column> | 283 | </el-table-column> |
| 284 | + <el-table-column prop="actualRefundAmount" label="实际退款金额" min-width="140" sortable="custom"> | ||
| 285 | + <template slot-scope="scope"> | ||
| 286 | + <i class="el-icon-money" style="margin-right: 4px; color: #67C23A;"></i> | ||
| 287 | + <span class="amount-value">¥{{ formatMoney(scope.row.actualRefundAmount) }}</span> | ||
| 288 | + </template> | ||
| 289 | + </el-table-column> | ||
| 284 | </NCC-table> | 290 | </NCC-table> |
| 285 | <pagination | 291 | <pagination |
| 286 | v-show="total > 0" | 292 | v-show="total > 0" |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqHytkHytk/RefundDetailListOutput.cs
| @@ -83,19 +83,24 @@ namespace NCC.Extend.Entitys.Dto.LqHytkHytk | @@ -83,19 +83,24 @@ namespace NCC.Extend.Entitys.Dto.LqHytkHytk | ||
| 83 | public string itemCategory { get; set; } | 83 | public string itemCategory { get; set; } |
| 84 | 84 | ||
| 85 | /// <summary> | 85 | /// <summary> |
| 86 | - /// 健康师账号 | 86 | + /// 健康师账号(保留字段,兼容旧版本,显示第一个健康师) |
| 87 | /// </summary> | 87 | /// </summary> |
| 88 | public string healthCoachId { get; set; } | 88 | public string healthCoachId { get; set; } |
| 89 | 89 | ||
| 90 | /// <summary> | 90 | /// <summary> |
| 91 | - /// 健康师姓名 | 91 | + /// 健康师姓名(多个健康师用顿号分隔) |
| 92 | /// </summary> | 92 | /// </summary> |
| 93 | public string healthCoachName { get; set; } | 93 | public string healthCoachName { get; set; } |
| 94 | 94 | ||
| 95 | /// <summary> | 95 | /// <summary> |
| 96 | - /// 健康师业绩 | 96 | + /// 健康师业绩(保留字段,兼容旧版本,显示第一个健康师业绩) |
| 97 | /// </summary> | 97 | /// </summary> |
| 98 | public decimal healthCoachPerformance { get; set; } | 98 | public decimal healthCoachPerformance { get; set; } |
| 99 | + | ||
| 100 | + /// <summary> | ||
| 101 | + /// 实际退款金额(所有健康师业绩之和) | ||
| 102 | + /// </summary> | ||
| 103 | + public decimal actualRefundAmount { get; set; } | ||
| 99 | } | 104 | } |
| 100 | } | 105 | } |
| 101 | 106 |
netcore/src/Modularity/Extend/NCC.Extend/LqHytkHytkService.cs
| @@ -916,39 +916,36 @@ namespace NCC.Extend.LqHytkHytk | @@ -916,39 +916,36 @@ namespace NCC.Extend.LqHytkHytk | ||
| 916 | memberDict = members.ToDictionary(x => x.Id, x => x.Sjh ?? ""); | 916 | memberDict = members.ToDictionary(x => x.Id, x => x.Sjh ?? ""); |
| 917 | } | 917 | } |
| 918 | 918 | ||
| 919 | - // 5. 批量查询健康师业绩信息 | ||
| 920 | - var billingItemIds = mxList.Select(x => x.BillingItemId).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); | ||
| 921 | - var healthCoachDict = new Dictionary<string, (string Id, string Name, decimal Performance)>(); | ||
| 922 | - if (billingItemIds.Any()) | 919 | + // 5. 批量查询退款健康师业绩信息(从退款健康师业绩表查询,而不是开单健康师业绩表) |
| 920 | + var mxIds = mxList.Select(x => x.Id).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); | ||
| 921 | + // 使用字典存储每个退款明细对应的多个健康师信息 | ||
| 922 | + var healthCoachDict = new Dictionary<string, List<(string Id, string Name, decimal Performance)>>(); | ||
| 923 | + var actualRefundAmountDict = new Dictionary<string, decimal>(); | ||
| 924 | + | ||
| 925 | + if (mxIds.Any()) | ||
| 923 | { | 926 | { |
| 924 | - // 通过开单品项明细ID查询开单品项明细,获取开单编号和品项明细ID | ||
| 925 | - var pxmxList = await _db.Queryable<LqKdPxmxEntity>() | ||
| 926 | - .Where(x => billingItemIds.Contains(x.Id)) | ||
| 927 | - .Select(x => new { x.Id, x.Glkdbh }) | 927 | + // 通过退卡品相表ID(F_CardReturn)查询退款健康师业绩 |
| 928 | + var jksyjList = await _db.Queryable<LqHytkJksyjEntity>() | ||
| 929 | + .Where(x => mxIds.Contains(x.CardReturn) && x.IsEffective == StatusEnum.有效.GetHashCode()) | ||
| 930 | + .Select(x => new { x.CardReturn, x.Jkszh, x.Jksxm, x.Jksyj }) | ||
| 928 | .ToListAsync(); | 931 | .ToListAsync(); |
| 929 | 932 | ||
| 930 | - if (pxmxList.Any()) | 933 | + // 按退款明细ID分组,建立映射 |
| 934 | + foreach (var jksyj in jksyjList) | ||
| 931 | { | 935 | { |
| 932 | - var glkdbhList = pxmxList.Select(x => x.Glkdbh).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); | ||
| 933 | - var pxmxIdList = pxmxList.Select(x => x.Id).Distinct().ToList(); | 936 | + if (string.IsNullOrEmpty(jksyj.CardReturn)) |
| 937 | + continue; | ||
| 934 | 938 | ||
| 935 | - // 通过开单编号和品项明细ID查询健康师业绩 | ||
| 936 | - var jksyjList = await _db.Queryable<LqKdJksyjEntity>() | ||
| 937 | - .Where(x => glkdbhList.Contains(x.Glkdbh) && pxmxIdList.Contains(x.Kdpxid) && x.IsEffective == 1) | ||
| 938 | - .Select(x => new { x.Glkdbh, x.Kdpxid, x.Jkszh, x.Jksxm, x.Jksyj }) | ||
| 939 | - .ToListAsync(); | 939 | + var jksyjValue = jksyj.Jksyj ?? 0m; |
| 940 | 940 | ||
| 941 | - // 建立开单品项明细ID到健康师信息的映射 | ||
| 942 | - foreach (var jksyj in jksyjList) | 941 | + if (!healthCoachDict.ContainsKey(jksyj.CardReturn)) |
| 943 | { | 942 | { |
| 944 | - // 找到对应的开单品项明细ID | ||
| 945 | - var pxmxId = pxmxList.FirstOrDefault(x => x.Glkdbh == jksyj.Glkdbh && x.Id == jksyj.Kdpxid)?.Id; | ||
| 946 | - if (!string.IsNullOrEmpty(pxmxId)) | ||
| 947 | - { | ||
| 948 | - var jksyjValue = decimal.TryParse(jksyj.Jksyj, out var perf) ? perf : 0; | ||
| 949 | - healthCoachDict[pxmxId] = (jksyj.Jkszh ?? "", jksyj.Jksxm ?? "", jksyjValue); | ||
| 950 | - } | 943 | + healthCoachDict[jksyj.CardReturn] = new List<(string Id, string Name, decimal Performance)>(); |
| 944 | + actualRefundAmountDict[jksyj.CardReturn] = 0m; | ||
| 951 | } | 945 | } |
| 946 | + | ||
| 947 | + healthCoachDict[jksyj.CardReturn].Add((jksyj.Jkszh ?? "", jksyj.Jksxm ?? "", jksyjValue)); | ||
| 948 | + actualRefundAmountDict[jksyj.CardReturn] += jksyjValue; | ||
| 952 | } | 949 | } |
| 953 | } | 950 | } |
| 954 | 951 | ||
| @@ -957,7 +954,7 @@ namespace NCC.Extend.LqHytkHytk | @@ -957,7 +954,7 @@ namespace NCC.Extend.LqHytkHytk | ||
| 957 | foreach (var mx in mxList) | 954 | foreach (var mx in mxList) |
| 958 | { | 955 | { |
| 959 | var refundInfo = refundInfoDict.ContainsKey(mx.RefundInfoId) ? refundInfoDict[mx.RefundInfoId] : null; | 956 | var refundInfo = refundInfoDict.ContainsKey(mx.RefundInfoId) ? refundInfoDict[mx.RefundInfoId] : null; |
| 960 | - | 957 | + |
| 961 | // 应用筛选条件 | 958 | // 应用筛选条件 |
| 962 | if (input.storeIds != null && input.storeIds.Any()) | 959 | if (input.storeIds != null && input.storeIds.Any()) |
| 963 | { | 960 | { |
| @@ -973,10 +970,29 @@ namespace NCC.Extend.LqHytkHytk | @@ -973,10 +970,29 @@ namespace NCC.Extend.LqHytkHytk | ||
| 973 | var memberId = mx.MemberId ?? (refundInfo?.Hy); | 970 | var memberId = mx.MemberId ?? (refundInfo?.Hy); |
| 974 | var refundTime = mx.Tksj ?? refundInfo?.Tksj; | 971 | var refundTime = mx.Tksj ?? refundInfo?.Tksj; |
| 975 | 972 | ||
| 976 | - // 获取健康师信息 | ||
| 977 | - var healthCoachInfo = !string.IsNullOrEmpty(mx.BillingItemId) && healthCoachDict.ContainsKey(mx.BillingItemId) | ||
| 978 | - ? healthCoachDict[mx.BillingItemId] | ||
| 979 | - : (Id: "", Name: "", Performance: 0m); | 973 | + // 获取健康师信息(支持多个健康师) |
| 974 | + var healthCoachList = healthCoachDict.ContainsKey(mx.Id) | ||
| 975 | + ? healthCoachDict[mx.Id] | ||
| 976 | + : new List<(string Id, string Name, decimal Performance)>(); | ||
| 977 | + | ||
| 978 | + // 合并多个健康师姓名和业绩(格式:姓名(业绩),用顿号分隔) | ||
| 979 | + var healthCoachNames = ""; | ||
| 980 | + if (healthCoachList.Any()) | ||
| 981 | + { | ||
| 982 | + var healthCoachItems = healthCoachList | ||
| 983 | + .Where(h => !string.IsNullOrEmpty(h.Name)) | ||
| 984 | + .Select(h => $"{h.Name}({h.Performance:F2})") | ||
| 985 | + .ToList(); | ||
| 986 | + healthCoachNames = string.Join("、", healthCoachItems); | ||
| 987 | + } | ||
| 988 | + | ||
| 989 | + // 获取第一个健康师信息(兼容旧版本) | ||
| 990 | + var firstHealthCoach = healthCoachList.FirstOrDefault(); | ||
| 991 | + | ||
| 992 | + // 获取实际退款金额(所有健康师业绩之和) | ||
| 993 | + var actualRefundAmount = actualRefundAmountDict.ContainsKey(mx.Id) | ||
| 994 | + ? actualRefundAmountDict[mx.Id] | ||
| 995 | + : 0m; | ||
| 980 | 996 | ||
| 981 | resultList.Add(new RefundDetailListOutput | 997 | resultList.Add(new RefundDetailListOutput |
| 982 | { | 998 | { |
| @@ -995,16 +1011,17 @@ namespace NCC.Extend.LqHytkHytk | @@ -995,16 +1011,17 @@ namespace NCC.Extend.LqHytkHytk | ||
| 995 | beautyType = mx.BeautyType, | 1011 | beautyType = mx.BeautyType, |
| 996 | sourceType = mx.SourceType, | 1012 | sourceType = mx.SourceType, |
| 997 | itemCategory = mx.ItemCategory, | 1013 | itemCategory = mx.ItemCategory, |
| 998 | - healthCoachId = healthCoachInfo.Id, | ||
| 999 | - healthCoachName = healthCoachInfo.Name, | ||
| 1000 | - healthCoachPerformance = healthCoachInfo.Performance | 1014 | + healthCoachId = firstHealthCoach.Id, |
| 1015 | + healthCoachName = healthCoachNames, | ||
| 1016 | + healthCoachPerformance = firstHealthCoach.Performance, | ||
| 1017 | + actualRefundAmount = actualRefundAmount | ||
| 1001 | }); | 1018 | }); |
| 1002 | } | 1019 | } |
| 1003 | 1020 | ||
| 1004 | // 7. 排序 | 1021 | // 7. 排序 |
| 1005 | var sidx = string.IsNullOrEmpty(input.sidx) ? "refundTime" : input.sidx; | 1022 | var sidx = string.IsNullOrEmpty(input.sidx) ? "refundTime" : input.sidx; |
| 1006 | var sort = string.IsNullOrEmpty(input.sort) ? "desc" : input.sort; | 1023 | var sort = string.IsNullOrEmpty(input.sort) ? "desc" : input.sort; |
| 1007 | - | 1024 | + |
| 1008 | if (sort.ToLower() == "desc") | 1025 | if (sort.ToLower() == "desc") |
| 1009 | { | 1026 | { |
| 1010 | resultList = resultList.OrderByDescending(x => GetPropertyValue(x, sidx)).ToList(); | 1027 | resultList = resultList.OrderByDescending(x => GetPropertyValue(x, sidx)).ToList(); |
| @@ -1114,39 +1131,36 @@ namespace NCC.Extend.LqHytkHytk | @@ -1114,39 +1131,36 @@ namespace NCC.Extend.LqHytkHytk | ||
| 1114 | memberDict = members.ToDictionary(x => x.Id, x => x.Sjh ?? ""); | 1131 | memberDict = members.ToDictionary(x => x.Id, x => x.Sjh ?? ""); |
| 1115 | } | 1132 | } |
| 1116 | 1133 | ||
| 1117 | - // 5. 批量查询健康师业绩信息 | ||
| 1118 | - var billingItemIds = mxList.Select(x => x.BillingItemId).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); | ||
| 1119 | - var healthCoachDict = new Dictionary<string, (string Id, string Name, decimal Performance)>(); | ||
| 1120 | - if (billingItemIds.Any()) | 1134 | + // 5. 批量查询退款健康师业绩信息(从退款健康师业绩表查询,而不是开单健康师业绩表) |
| 1135 | + var mxIds = mxList.Select(x => x.Id).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); | ||
| 1136 | + // 使用字典存储每个退款明细对应的多个健康师信息 | ||
| 1137 | + var healthCoachDict = new Dictionary<string, List<(string Id, string Name, decimal Performance)>>(); | ||
| 1138 | + var actualRefundAmountDict = new Dictionary<string, decimal>(); | ||
| 1139 | + | ||
| 1140 | + if (mxIds.Any()) | ||
| 1121 | { | 1141 | { |
| 1122 | - // 通过开单品项明细ID查询开单品项明细,获取开单编号和品项明细ID | ||
| 1123 | - var pxmxList = await _db.Queryable<LqKdPxmxEntity>() | ||
| 1124 | - .Where(x => billingItemIds.Contains(x.Id)) | ||
| 1125 | - .Select(x => new { x.Id, x.Glkdbh }) | 1142 | + // 通过退卡品相表ID(F_CardReturn)查询退款健康师业绩 |
| 1143 | + var jksyjList = await _db.Queryable<LqHytkJksyjEntity>() | ||
| 1144 | + .Where(x => mxIds.Contains(x.CardReturn) && x.IsEffective == StatusEnum.有效.GetHashCode()) | ||
| 1145 | + .Select(x => new { x.CardReturn, x.Jkszh, x.Jksxm, x.Jksyj }) | ||
| 1126 | .ToListAsync(); | 1146 | .ToListAsync(); |
| 1127 | 1147 | ||
| 1128 | - if (pxmxList.Any()) | 1148 | + // 按退款明细ID分组,建立映射 |
| 1149 | + foreach (var jksyj in jksyjList) | ||
| 1129 | { | 1150 | { |
| 1130 | - var glkdbhList = pxmxList.Select(x => x.Glkdbh).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); | ||
| 1131 | - var pxmxIdList = pxmxList.Select(x => x.Id).Distinct().ToList(); | 1151 | + if (string.IsNullOrEmpty(jksyj.CardReturn)) |
| 1152 | + continue; | ||
| 1132 | 1153 | ||
| 1133 | - // 通过开单编号和品项明细ID查询健康师业绩 | ||
| 1134 | - var jksyjList = await _db.Queryable<LqKdJksyjEntity>() | ||
| 1135 | - .Where(x => glkdbhList.Contains(x.Glkdbh) && pxmxIdList.Contains(x.Kdpxid) && x.IsEffective == 1) | ||
| 1136 | - .Select(x => new { x.Glkdbh, x.Kdpxid, x.Jkszh, x.Jksxm, x.Jksyj }) | ||
| 1137 | - .ToListAsync(); | 1154 | + var jksyjValue = jksyj.Jksyj ?? 0m; |
| 1138 | 1155 | ||
| 1139 | - // 建立开单品项明细ID到健康师信息的映射 | ||
| 1140 | - foreach (var jksyj in jksyjList) | 1156 | + if (!healthCoachDict.ContainsKey(jksyj.CardReturn)) |
| 1141 | { | 1157 | { |
| 1142 | - // 找到对应的开单品项明细ID | ||
| 1143 | - var pxmxId = pxmxList.FirstOrDefault(x => x.Glkdbh == jksyj.Glkdbh && x.Id == jksyj.Kdpxid)?.Id; | ||
| 1144 | - if (!string.IsNullOrEmpty(pxmxId)) | ||
| 1145 | - { | ||
| 1146 | - var jksyjValue = decimal.TryParse(jksyj.Jksyj, out var perf) ? perf : 0; | ||
| 1147 | - healthCoachDict[pxmxId] = (jksyj.Jkszh ?? "", jksyj.Jksxm ?? "", jksyjValue); | ||
| 1148 | - } | 1158 | + healthCoachDict[jksyj.CardReturn] = new List<(string Id, string Name, decimal Performance)>(); |
| 1159 | + actualRefundAmountDict[jksyj.CardReturn] = 0m; | ||
| 1149 | } | 1160 | } |
| 1161 | + | ||
| 1162 | + healthCoachDict[jksyj.CardReturn].Add((jksyj.Jkszh ?? "", jksyj.Jksxm ?? "", jksyjValue)); | ||
| 1163 | + actualRefundAmountDict[jksyj.CardReturn] += jksyjValue; | ||
| 1150 | } | 1164 | } |
| 1151 | } | 1165 | } |
| 1152 | 1166 | ||
| @@ -1155,7 +1169,7 @@ namespace NCC.Extend.LqHytkHytk | @@ -1155,7 +1169,7 @@ namespace NCC.Extend.LqHytkHytk | ||
| 1155 | foreach (var mx in mxList) | 1169 | foreach (var mx in mxList) |
| 1156 | { | 1170 | { |
| 1157 | var refundInfo = refundInfoDict.ContainsKey(mx.RefundInfoId) ? refundInfoDict[mx.RefundInfoId] : null; | 1171 | var refundInfo = refundInfoDict.ContainsKey(mx.RefundInfoId) ? refundInfoDict[mx.RefundInfoId] : null; |
| 1158 | - | 1172 | + |
| 1159 | // 应用筛选条件 | 1173 | // 应用筛选条件 |
| 1160 | if (input.storeIds != null && input.storeIds.Any()) | 1174 | if (input.storeIds != null && input.storeIds.Any()) |
| 1161 | { | 1175 | { |
| @@ -1171,10 +1185,29 @@ namespace NCC.Extend.LqHytkHytk | @@ -1171,10 +1185,29 @@ namespace NCC.Extend.LqHytkHytk | ||
| 1171 | var memberId = mx.MemberId ?? (refundInfo?.Hy); | 1185 | var memberId = mx.MemberId ?? (refundInfo?.Hy); |
| 1172 | var refundTime = mx.Tksj ?? refundInfo?.Tksj; | 1186 | var refundTime = mx.Tksj ?? refundInfo?.Tksj; |
| 1173 | 1187 | ||
| 1174 | - // 获取健康师信息 | ||
| 1175 | - var healthCoachInfo = !string.IsNullOrEmpty(mx.BillingItemId) && healthCoachDict.ContainsKey(mx.BillingItemId) | ||
| 1176 | - ? healthCoachDict[mx.BillingItemId] | ||
| 1177 | - : (Id: "", Name: "", Performance: 0m); | 1188 | + // 获取健康师信息(支持多个健康师) |
| 1189 | + var healthCoachList = healthCoachDict.ContainsKey(mx.Id) | ||
| 1190 | + ? healthCoachDict[mx.Id] | ||
| 1191 | + : new List<(string Id, string Name, decimal Performance)>(); | ||
| 1192 | + | ||
| 1193 | + // 合并多个健康师姓名和业绩(格式:姓名(业绩),用顿号分隔) | ||
| 1194 | + var healthCoachNames = ""; | ||
| 1195 | + if (healthCoachList.Any()) | ||
| 1196 | + { | ||
| 1197 | + var healthCoachItems = healthCoachList | ||
| 1198 | + .Where(h => !string.IsNullOrEmpty(h.Name)) | ||
| 1199 | + .Select(h => $"{h.Name}({h.Performance:F2})") | ||
| 1200 | + .ToList(); | ||
| 1201 | + healthCoachNames = string.Join("、", healthCoachItems); | ||
| 1202 | + } | ||
| 1203 | + | ||
| 1204 | + // 获取第一个健康师信息(兼容旧版本) | ||
| 1205 | + var firstHealthCoach = healthCoachList.FirstOrDefault(); | ||
| 1206 | + | ||
| 1207 | + // 获取实际退款金额(所有健康师业绩之和) | ||
| 1208 | + var actualRefundAmount = actualRefundAmountDict.ContainsKey(mx.Id) | ||
| 1209 | + ? actualRefundAmountDict[mx.Id] | ||
| 1210 | + : 0m; | ||
| 1178 | 1211 | ||
| 1179 | resultList.Add(new RefundDetailListOutput | 1212 | resultList.Add(new RefundDetailListOutput |
| 1180 | { | 1213 | { |
| @@ -1193,16 +1226,17 @@ namespace NCC.Extend.LqHytkHytk | @@ -1193,16 +1226,17 @@ namespace NCC.Extend.LqHytkHytk | ||
| 1193 | beautyType = mx.BeautyType, | 1226 | beautyType = mx.BeautyType, |
| 1194 | sourceType = mx.SourceType, | 1227 | sourceType = mx.SourceType, |
| 1195 | itemCategory = mx.ItemCategory, | 1228 | itemCategory = mx.ItemCategory, |
| 1196 | - healthCoachId = healthCoachInfo.Id, | ||
| 1197 | - healthCoachName = healthCoachInfo.Name, | ||
| 1198 | - healthCoachPerformance = healthCoachInfo.Performance | 1229 | + healthCoachId = firstHealthCoach.Id, |
| 1230 | + healthCoachName = healthCoachNames, | ||
| 1231 | + healthCoachPerformance = firstHealthCoach.Performance, | ||
| 1232 | + actualRefundAmount = actualRefundAmount | ||
| 1199 | }); | 1233 | }); |
| 1200 | } | 1234 | } |
| 1201 | 1235 | ||
| 1202 | // 7. 排序 | 1236 | // 7. 排序 |
| 1203 | var sidx = string.IsNullOrEmpty(input.sidx) ? "refundTime" : input.sidx; | 1237 | var sidx = string.IsNullOrEmpty(input.sidx) ? "refundTime" : input.sidx; |
| 1204 | var sort = string.IsNullOrEmpty(input.sort) ? "desc" : input.sort; | 1238 | var sort = string.IsNullOrEmpty(input.sort) ? "desc" : input.sort; |
| 1205 | - | 1239 | + |
| 1206 | if (sort.ToLower() == "desc") | 1240 | if (sort.ToLower() == "desc") |
| 1207 | { | 1241 | { |
| 1208 | resultList = resultList.OrderByDescending(x => GetPropertyValue(x, sidx)).ToList(); | 1242 | resultList = resultList.OrderByDescending(x => GetPropertyValue(x, sidx)).ToList(); |
| @@ -1264,7 +1298,7 @@ namespace NCC.Extend.LqHytkHytk | @@ -1264,7 +1298,7 @@ namespace NCC.Extend.LqHytkHytk | ||
| 1264 | 1298 | ||
| 1265 | // 定义导出字段 | 1299 | // 定义导出字段 |
| 1266 | List<ParamsModel> paramList = | 1300 | List<ParamsModel> paramList = |
| 1267 | - "[{\"value\":\"门店\",\"field\":\"storeName\"},{\"value\":\"会员ID\",\"field\":\"memberId\"},{\"value\":\"会员名称\",\"field\":\"memberName\"},{\"value\":\"会员电话\",\"field\":\"memberPhone\"},{\"value\":\"退卡时间\",\"field\":\"refundTime\"},{\"value\":\"退卡品项ID\",\"field\":\"itemId\"},{\"value\":\"退卡品项名称\",\"field\":\"itemName\"},{\"value\":\"退卡数量\",\"field\":\"refundQuantity\"},{\"value\":\"单价\",\"field\":\"unitPrice\"},{\"value\":\"总价\",\"field\":\"totalPrice\"},{\"value\":\"业绩类型\",\"field\":\"performanceType\"},{\"value\":\"科美类型\",\"field\":\"beautyType\"},{\"value\":\"来源类型\",\"field\":\"sourceType\"},{\"value\":\"品项分类\",\"field\":\"itemCategory\"},]".ToList<ParamsModel>(); | 1301 | + "[{\"value\":\"门店\",\"field\":\"storeName\"},{\"value\":\"会员ID\",\"field\":\"memberId\"},{\"value\":\"会员名称\",\"field\":\"memberName\"},{\"value\":\"会员电话\",\"field\":\"memberPhone\"},{\"value\":\"退卡时间\",\"field\":\"refundTime\"},{\"value\":\"退卡品项ID\",\"field\":\"itemId\"},{\"value\":\"退卡品项名称\",\"field\":\"itemName\"},{\"value\":\"退卡数量\",\"field\":\"refundQuantity\"},{\"value\":\"单价\",\"field\":\"unitPrice\"},{\"value\":\"总价\",\"field\":\"totalPrice\"},{\"value\":\"业绩类型\",\"field\":\"performanceType\"},{\"value\":\"科美类型\",\"field\":\"beautyType\"},{\"value\":\"来源类型\",\"field\":\"sourceType\"},{\"value\":\"品项分类\",\"field\":\"itemCategory\"},{\"value\":\"健康师\",\"field\":\"healthCoachName\"},{\"value\":\"健康师业绩\",\"field\":\"healthCoachPerformance\"},]".ToList<ParamsModel>(); |
| 1268 | 1302 | ||
| 1269 | ExcelConfig excelconfig = new ExcelConfig(); | 1303 | ExcelConfig excelconfig = new ExcelConfig(); |
| 1270 | excelconfig.FileName = "退卡明细_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls"; | 1304 | excelconfig.FileName = "退卡明细_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls"; |
test_refund_detail.sh
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | + | ||
| 3 | +# 测试退款明细列表接口 | ||
| 4 | + | ||
| 5 | +echo "=== 测试退款明细列表接口 ===" | ||
| 6 | +echo "" | ||
| 7 | + | ||
| 8 | +# 步骤1: 获取Token | ||
| 9 | +echo "步骤1: 获取Token..." | ||
| 10 | +TOKEN_RESPONSE=$(curl -s -X POST "http://localhost:2011/api/oauth/Login" \ | ||
| 11 | + -H "Content-Type: application/x-www-form-urlencoded" \ | ||
| 12 | + -d "account=admin&password=e10adc3949ba59abbe56e057f20f883e") | ||
| 13 | + | ||
| 14 | +TOKEN=$(echo "$TOKEN_RESPONSE" | python3 -c "import sys, json; data=json.load(sys.stdin); print(data['data']['token'])" 2>/dev/null) | ||
| 15 | + | ||
| 16 | +if [ -z "$TOKEN" ]; then | ||
| 17 | + echo "❌ Token获取失败" | ||
| 18 | + exit 1 | ||
| 19 | +fi | ||
| 20 | + | ||
| 21 | +echo "✅ Token获取成功" | ||
| 22 | +echo "" | ||
| 23 | + | ||
| 24 | +# 步骤2: 调用退款明细列表接口(2025年11月数据) | ||
| 25 | +echo "步骤2: 调用退款明细列表接口(2025年11月数据)..." | ||
| 26 | +echo "接口: POST /api/Extend/LqHytkHytk/refund-detail-list" | ||
| 27 | + | ||
| 28 | +RESPONSE=$(curl -s -X POST "http://localhost:2011/api/Extend/LqHytkHytk/refund-detail-list" \ | ||
| 29 | + -H "Authorization: Bearer $TOKEN" \ | ||
| 30 | + -H "Content-Type: application/json" \ | ||
| 31 | + -d '{ | ||
| 32 | + "currentPage": 1, | ||
| 33 | + "pageSize": 5, | ||
| 34 | + "startTime": "2025-11-01T00:00:00", | ||
| 35 | + "endTime": "2025-11-30T23:59:59" | ||
| 36 | + }') | ||
| 37 | + | ||
| 38 | +echo "$RESPONSE" | python3 -c " | ||
| 39 | +import sys, json | ||
| 40 | +try: | ||
| 41 | + data = json.load(sys.stdin) | ||
| 42 | + print('状态码:', data.get('code')) | ||
| 43 | + print('消息:', data.get('msg')) | ||
| 44 | + items = data.get('data', {}).get('list', []) | ||
| 45 | + print('返回数据条数:', len(items)) | ||
| 46 | + if items: | ||
| 47 | + print('\\n前3条数据详情:') | ||
| 48 | + for i, item in enumerate(items[:3], 1): | ||
| 49 | + print(f'\\n第{i}条:') | ||
| 50 | + print(f' 门店名称: {item.get(\"storeName\", \"N/A\")}') | ||
| 51 | + print(f' 会员名称: {item.get(\"memberName\", \"N/A\")}') | ||
| 52 | + print(f' 品项名称: {item.get(\"itemName\", \"N/A\")}') | ||
| 53 | + print(f' 健康师姓名: {item.get(\"healthCoachName\", \"N/A\")}') | ||
| 54 | + print(f' 健康师业绩: {item.get(\"healthCoachPerformance\", \"N/A\")}') | ||
| 55 | + print(f' 实际退款金额: {item.get(\"actualRefundAmount\", \"N/A\")}') | ||
| 56 | +except Exception as e: | ||
| 57 | + print('解析错误:', str(e)) | ||
| 58 | + print('原始响应:') | ||
| 59 | + print(sys.stdin.read()) | ||
| 60 | +" 2>/dev/null | ||
| 61 | + | ||
| 62 | +echo "" | ||
| 63 | +echo "=== 测试完成 ===" | ||
| 64 | + |