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 | 270 | </el-tag> |
| 271 | 271 | </template> |
| 272 | 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 | 274 | <template slot-scope="scope"> |
| 275 | 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 | 277 | </template> |
| 278 | 278 | </el-table-column> |
| 279 | 279 | <el-table-column prop="healthCoachPerformance" label="健康师业绩" min-width="130" sortable="custom"> |
| ... | ... | @@ -281,6 +281,12 @@ |
| 281 | 281 | <span class="amount-value">¥{{ formatMoney(scope.row.healthCoachPerformance) }}</span> |
| 282 | 282 | </template> |
| 283 | 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 | 290 | </NCC-table> |
| 285 | 291 | <pagination |
| 286 | 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 | 83 | public string itemCategory { get; set; } |
| 84 | 84 | |
| 85 | 85 | /// <summary> |
| 86 | - /// 健康师账号 | |
| 86 | + /// 健康师账号(保留字段,兼容旧版本,显示第一个健康师) | |
| 87 | 87 | /// </summary> |
| 88 | 88 | public string healthCoachId { get; set; } |
| 89 | 89 | |
| 90 | 90 | /// <summary> |
| 91 | - /// 健康师姓名 | |
| 91 | + /// 健康师姓名(多个健康师用顿号分隔) | |
| 92 | 92 | /// </summary> |
| 93 | 93 | public string healthCoachName { get; set; } |
| 94 | 94 | |
| 95 | 95 | /// <summary> |
| 96 | - /// 健康师业绩 | |
| 96 | + /// 健康师业绩(保留字段,兼容旧版本,显示第一个健康师业绩) | |
| 97 | 97 | /// </summary> |
| 98 | 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 | 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 | 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 | 954 | foreach (var mx in mxList) |
| 958 | 955 | { |
| 959 | 956 | var refundInfo = refundInfoDict.ContainsKey(mx.RefundInfoId) ? refundInfoDict[mx.RefundInfoId] : null; |
| 960 | - | |
| 957 | + | |
| 961 | 958 | // 应用筛选条件 |
| 962 | 959 | if (input.storeIds != null && input.storeIds.Any()) |
| 963 | 960 | { |
| ... | ... | @@ -973,10 +970,29 @@ namespace NCC.Extend.LqHytkHytk |
| 973 | 970 | var memberId = mx.MemberId ?? (refundInfo?.Hy); |
| 974 | 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 | 997 | resultList.Add(new RefundDetailListOutput |
| 982 | 998 | { |
| ... | ... | @@ -995,16 +1011,17 @@ namespace NCC.Extend.LqHytkHytk |
| 995 | 1011 | beautyType = mx.BeautyType, |
| 996 | 1012 | sourceType = mx.SourceType, |
| 997 | 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 | 1021 | // 7. 排序 |
| 1005 | 1022 | var sidx = string.IsNullOrEmpty(input.sidx) ? "refundTime" : input.sidx; |
| 1006 | 1023 | var sort = string.IsNullOrEmpty(input.sort) ? "desc" : input.sort; |
| 1007 | - | |
| 1024 | + | |
| 1008 | 1025 | if (sort.ToLower() == "desc") |
| 1009 | 1026 | { |
| 1010 | 1027 | resultList = resultList.OrderByDescending(x => GetPropertyValue(x, sidx)).ToList(); |
| ... | ... | @@ -1114,39 +1131,36 @@ namespace NCC.Extend.LqHytkHytk |
| 1114 | 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 | 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 | 1169 | foreach (var mx in mxList) |
| 1156 | 1170 | { |
| 1157 | 1171 | var refundInfo = refundInfoDict.ContainsKey(mx.RefundInfoId) ? refundInfoDict[mx.RefundInfoId] : null; |
| 1158 | - | |
| 1172 | + | |
| 1159 | 1173 | // 应用筛选条件 |
| 1160 | 1174 | if (input.storeIds != null && input.storeIds.Any()) |
| 1161 | 1175 | { |
| ... | ... | @@ -1171,10 +1185,29 @@ namespace NCC.Extend.LqHytkHytk |
| 1171 | 1185 | var memberId = mx.MemberId ?? (refundInfo?.Hy); |
| 1172 | 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 | 1212 | resultList.Add(new RefundDetailListOutput |
| 1180 | 1213 | { |
| ... | ... | @@ -1193,16 +1226,17 @@ namespace NCC.Extend.LqHytkHytk |
| 1193 | 1226 | beautyType = mx.BeautyType, |
| 1194 | 1227 | sourceType = mx.SourceType, |
| 1195 | 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 | 1236 | // 7. 排序 |
| 1203 | 1237 | var sidx = string.IsNullOrEmpty(input.sidx) ? "refundTime" : input.sidx; |
| 1204 | 1238 | var sort = string.IsNullOrEmpty(input.sort) ? "desc" : input.sort; |
| 1205 | - | |
| 1239 | + | |
| 1206 | 1240 | if (sort.ToLower() == "desc") |
| 1207 | 1241 | { |
| 1208 | 1242 | resultList = resultList.OrderByDescending(x => GetPropertyValue(x, sidx)).ToList(); |
| ... | ... | @@ -1264,7 +1298,7 @@ namespace NCC.Extend.LqHytkHytk |
| 1264 | 1298 | |
| 1265 | 1299 | // 定义导出字段 |
| 1266 | 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 | 1303 | ExcelConfig excelconfig = new ExcelConfig(); |
| 1270 | 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 | + | ... | ... |