Commit 5e629136e080a69f32ab6118c6535fc3abaec34e
1 parent
45c3414e
feat: 添加开单服务根据健康师和科技部老师ID查询功能,返回健康师和科技部老师业绩数据;添加经理类型枚举;优化经理业绩完成情况查询逻辑
Showing
14 changed files
with
585 additions
and
11 deletions
netcore/src/Modularity/Common/NCC.Common/Extension/Ext.cs
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbListByJksQueryInput.cs
0 → 100644
| 1 | +using NCC.Common.Filter; | |
| 2 | + | |
| 3 | +namespace NCC.Extend.Entitys.Dto.LqKdKdjlb | |
| 4 | +{ | |
| 5 | + /// <summary> | |
| 6 | + /// 根据健康师ID查询开单列表输入 | |
| 7 | + /// </summary> | |
| 8 | + public class LqKdKdjlbListByJksQueryInput : PageInputBase | |
| 9 | + { | |
| 10 | + /// <summary> | |
| 11 | + /// 健康师ID(必填) | |
| 12 | + /// </summary> | |
| 13 | + public string jksId { get; set; } | |
| 14 | + | |
| 15 | + /// <summary> | |
| 16 | + /// 开始时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) | |
| 17 | + /// </summary> | |
| 18 | + public string startTime { get; set; } | |
| 19 | + | |
| 20 | + /// <summary> | |
| 21 | + /// 结束时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) | |
| 22 | + /// </summary> | |
| 23 | + public string endTime { get; set; } | |
| 24 | + | |
| 25 | + /// <summary> | |
| 26 | + /// 门店ID(可选) | |
| 27 | + /// </summary> | |
| 28 | + public string djmd { get; set; } | |
| 29 | + | |
| 30 | + /// <summary> | |
| 31 | + /// 是否有效(可选,0=全部,1=有效,2=无效,默认1) | |
| 32 | + /// </summary> | |
| 33 | + public int isEffective { get; set; } = 1; | |
| 34 | + } | |
| 35 | +} | |
| 36 | + | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbListByKjbQueryInput.cs
0 → 100644
| 1 | +using NCC.Common.Filter; | |
| 2 | + | |
| 3 | +namespace NCC.Extend.Entitys.Dto.LqKdKdjlb | |
| 4 | +{ | |
| 5 | + /// <summary> | |
| 6 | + /// 根据科技部老师ID查询开单列表输入 | |
| 7 | + /// </summary> | |
| 8 | + public class LqKdKdjlbListByKjbQueryInput : PageInputBase | |
| 9 | + { | |
| 10 | + /// <summary> | |
| 11 | + /// 科技部老师ID(必填) | |
| 12 | + /// </summary> | |
| 13 | + public string kjblsId { get; set; } | |
| 14 | + | |
| 15 | + /// <summary> | |
| 16 | + /// 开始时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) | |
| 17 | + /// </summary> | |
| 18 | + public string startTime { get; set; } | |
| 19 | + | |
| 20 | + /// <summary> | |
| 21 | + /// 结束时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) | |
| 22 | + /// </summary> | |
| 23 | + public string endTime { get; set; } | |
| 24 | + | |
| 25 | + /// <summary> | |
| 26 | + /// 门店ID(可选) | |
| 27 | + /// </summary> | |
| 28 | + public string djmd { get; set; } | |
| 29 | + | |
| 30 | + /// <summary> | |
| 31 | + /// 是否有效(可选,0=全部,1=有效,2=无效,默认1) | |
| 32 | + /// </summary> | |
| 33 | + public int isEffective { get; set; } = 1; | |
| 34 | + } | |
| 35 | +} | |
| 36 | + | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbListOutput.cs
| ... | ... | @@ -170,5 +170,15 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb |
| 170 | 170 | /// 开单品项明细列表 |
| 171 | 171 | /// </summary> |
| 172 | 172 | public List<LqKdPxmxInfoOutput> ItemDetails { get; set; } |
| 173 | + | |
| 174 | + /// <summary> | |
| 175 | + /// 健康师业绩列表 | |
| 176 | + /// </summary> | |
| 177 | + public List<LqKdJksyjInfoOutput> lqKdJksyjList { get; set; } | |
| 178 | + | |
| 179 | + /// <summary> | |
| 180 | + /// 科技部老师业绩列表 | |
| 181 | + /// </summary> | |
| 182 | + public List<LqKdKjbsyjInfoOutput> lqKdKjbsyjList { get; set; } | |
| 173 | 183 | } |
| 174 | 184 | } | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbListQueryInput.cs
| ... | ... | @@ -139,5 +139,14 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb |
| 139 | 139 | /// </summary> |
| 140 | 140 | public int isEffective { get; set; } = 0; |
| 141 | 141 | |
| 142 | + /// <summary> | |
| 143 | + /// 健康师ID(可选,传入后只返回该健康师参与的开单记录) | |
| 144 | + /// </summary> | |
| 145 | + public string jksId { get; set; } | |
| 146 | + | |
| 147 | + /// <summary> | |
| 148 | + /// 科技部老师ID(可选,传入后只返回该老师参与的开单记录) | |
| 149 | + /// </summary> | |
| 150 | + public string kjblsId { get; set; } | |
| 142 | 151 | } |
| 143 | 152 | } | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/Dto/LqMdGeneralManagerLifeline/LqMdGeneralManagerLifelineCrInput.cs
| ... | ... | @@ -28,6 +28,12 @@ namespace NCC.Extend.Entitys.Dto.LqMdGeneralManagerLifeline |
| 28 | 28 | public string generalManagerId { get; set; } |
| 29 | 29 | |
| 30 | 30 | /// <summary> |
| 31 | + /// 经理类型(0=经理,1=总经理) | |
| 32 | + /// </summary> | |
| 33 | + [Required(ErrorMessage = "经理类型不能为空")] | |
| 34 | + public int managerType { get; set; } = 1; | |
| 35 | + | |
| 36 | + /// <summary> | |
| 31 | 37 | /// 生命线1 |
| 32 | 38 | /// </summary> |
| 33 | 39 | [Required(ErrorMessage = "生命线1不能为空")] | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/Dto/LqMdGeneralManagerLifeline/LqMdGeneralManagerLifelineInfoOutput.cs
| ... | ... | @@ -28,6 +28,11 @@ namespace NCC.Extend.Entitys.Dto.LqMdGeneralManagerLifeline |
| 28 | 28 | public string generalManagerId { get; set; } |
| 29 | 29 | |
| 30 | 30 | /// <summary> |
| 31 | + /// 经理类型(0=经理,1=总经理) | |
| 32 | + /// </summary> | |
| 33 | + public int managerType { get; set; } | |
| 34 | + | |
| 35 | + /// <summary> | |
| 31 | 36 | /// 生命线1 |
| 32 | 37 | /// </summary> |
| 33 | 38 | public decimal lifeline1 { get; set; } | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/Dto/LqMdGeneralManagerLifeline/LqMdGeneralManagerLifelineListOutput.cs
| ... | ... | @@ -28,6 +28,16 @@ namespace NCC.Extend.Entitys.Dto.LqMdGeneralManagerLifeline |
| 28 | 28 | public string generalManagerId { get; set; } |
| 29 | 29 | |
| 30 | 30 | /// <summary> |
| 31 | + /// 经理类型(0=经理,1=总经理) | |
| 32 | + /// </summary> | |
| 33 | + public int managerType { get; set; } | |
| 34 | + | |
| 35 | + /// <summary> | |
| 36 | + /// 经理类型(0=经理,1=总经理) | |
| 37 | + /// </summary> | |
| 38 | + public string managerTypeName { get; set; } | |
| 39 | + | |
| 40 | + /// <summary> | |
| 31 | 41 | /// 生命线1 |
| 32 | 42 | /// </summary> |
| 33 | 43 | public decimal lifeline1 { get; set; } | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/Dto/LqMdGeneralManagerLifeline/LqMdGeneralManagerLifelineUpInput.cs
| ... | ... | @@ -28,6 +28,12 @@ namespace NCC.Extend.Entitys.Dto.LqMdGeneralManagerLifeline |
| 28 | 28 | public string generalManagerId { get; set; } |
| 29 | 29 | |
| 30 | 30 | /// <summary> |
| 31 | + /// 经理类型(0=经理,1=总经理) | |
| 32 | + /// </summary> | |
| 33 | + [Required(ErrorMessage = "经理类型不能为空")] | |
| 34 | + public int managerType { get; set; } = 1; | |
| 35 | + | |
| 36 | + /// <summary> | |
| 31 | 37 | /// 生命线1 |
| 32 | 38 | /// </summary> |
| 33 | 39 | [Required(ErrorMessage = "生命线1不能为空")] | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_md_general_manager_lifeline/LqMdGeneralManagerLifelineEntity.cs
| ... | ... | @@ -36,6 +36,12 @@ namespace NCC.Extend.Entitys.lq_md_general_manager_lifeline |
| 36 | 36 | public string GeneralManagerId { get; set; } |
| 37 | 37 | |
| 38 | 38 | /// <summary> |
| 39 | + /// 经理类型(0=经理,1=总经理) | |
| 40 | + /// </summary> | |
| 41 | + [SugarColumn(ColumnName = "F_ManagerType")] | |
| 42 | + public int ManagerType { get; set; } = 1; | |
| 43 | + | |
| 44 | + /// <summary> | |
| 39 | 45 | /// 生命线1 |
| 40 | 46 | /// </summary> |
| 41 | 47 | [SugarColumn(ColumnName = "F_Lifeline1")] | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Enum/ManagerTypeEnum.cs
0 → 100644
| 1 | +using System.ComponentModel; | |
| 2 | + | |
| 3 | +namespace NCC.Extend.Entitys.Enum | |
| 4 | +{ | |
| 5 | + /// <summary> | |
| 6 | + /// 经理类型枚举 | |
| 7 | + /// </summary> | |
| 8 | + public enum ManagerTypeEnum | |
| 9 | + { | |
| 10 | + /// <summary> | |
| 11 | + /// 经理 | |
| 12 | + /// </summary> | |
| 13 | + [Description("经理")] | |
| 14 | + 经理 = 0, | |
| 15 | + | |
| 16 | + /// <summary> | |
| 17 | + /// 总经理 | |
| 18 | + /// </summary> | |
| 19 | + [Description("总经理")] | |
| 20 | + 总经理 = 1, | |
| 21 | + } | |
| 22 | +} | |
| 23 | + | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend/LqDailyReportService.cs
| ... | ... | @@ -752,7 +752,7 @@ namespace NCC.Extend |
| 752 | 752 | managerFilter = $"AND target.F_GeneralManagerId = '{input.ManagerId}'"; |
| 753 | 753 | } |
| 754 | 754 | |
| 755 | - // SQL查询:获取经理汇总业绩 | |
| 755 | + // SQL查询:获取经理汇总业绩(基于lq_md_general_manager_lifeline表中的经理和门店关系) | |
| 756 | 756 | var sql = $@" |
| 757 | 757 | SELECT |
| 758 | 758 | target.F_GeneralManagerId as ManagerId, |
| ... | ... | @@ -761,7 +761,7 @@ namespace NCC.Extend |
| 761 | 761 | COALESCE(SUM(target.F_Lifeline2), 0) as TotalTarget2, |
| 762 | 762 | COALESCE(SUM(target.F_Lifeline3), 0) as TotalTarget3, |
| 763 | 763 | COUNT(DISTINCT target.F_StoreId) as StoreCount, |
| 764 | - -- 总完成业绩 | |
| 764 | + -- 总完成业绩(基于lq_md_general_manager_lifeline表中的门店关系计算) | |
| 765 | 765 | SUM(COALESCE(( |
| 766 | 766 | SELECT SUM(billing.sfyj) |
| 767 | 767 | FROM lq_kd_kdjlb billing | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs
| ... | ... | @@ -214,8 +214,49 @@ namespace NCC.Extend.LqKdKdjlb |
| 214 | 214 | List<string> queryKdrq = input.kdrq != null ? input.kdrq.Split(',').ToObeject<List<string>>() : null; |
| 215 | 215 | DateTime? startKdrq = queryKdrq != null ? Ext.GetDateTime(queryKdrq.First()) : null; |
| 216 | 216 | DateTime? endKdrq = queryKdrq != null ? Ext.GetDateTime(queryKdrq.Last()) : null; |
| 217 | - var data = await _db.Queryable<LqKdKdjlbEntity>() | |
| 218 | - .WhereIF(!string.IsNullOrEmpty(input.keyword), p => p.Kdhyc.Contains(input.keyword) || p.Kdhysjh.Contains(input.keyword)) | |
| 217 | + | |
| 218 | + // 根据是否传入健康师ID或科技部老师ID,动态构建查询 | |
| 219 | + ISugarQueryable<LqKdKdjlbEntity> baseQuery = null; | |
| 220 | + | |
| 221 | + if (!string.IsNullOrEmpty(input.jksId) && !string.IsNullOrEmpty(input.kjblsId)) | |
| 222 | + { | |
| 223 | + // 同时传入健康师ID和科技部老师ID,需要同时关联两个业绩表 | |
| 224 | + baseQuery = _db.Queryable<LqKdJksyjEntity, LqKdKjbsyjEntity, LqKdKdjlbEntity>( | |
| 225 | + (jksyj, kjbsyj, kdjlb) => jksyj.Glkdbh == kdjlb.Id && kjbsyj.Glkdbh == kdjlb.Id) | |
| 226 | + .Where((jksyj, kjbsyj, kdjlb) => jksyj.Jkszh == input.jksId && jksyj.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 227 | + .Where((jksyj, kjbsyj, kdjlb) => kjbsyj.Kjbls == input.kjblsId && kjbsyj.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 228 | + .Select((jksyj, kjbsyj, kdjlb) => kdjlb) | |
| 229 | + .Distinct() | |
| 230 | + .MergeTable(); | |
| 231 | + } | |
| 232 | + else if (!string.IsNullOrEmpty(input.jksId)) | |
| 233 | + { | |
| 234 | + // 只传入健康师ID,关联健康师业绩表 | |
| 235 | + baseQuery = _db.Queryable<LqKdJksyjEntity, LqKdKdjlbEntity>( | |
| 236 | + (jksyj, kdjlb) => jksyj.Glkdbh == kdjlb.Id) | |
| 237 | + .Where((jksyj, kdjlb) => jksyj.Jkszh == input.jksId && jksyj.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 238 | + .Select((jksyj, kdjlb) => kdjlb) | |
| 239 | + .Distinct() | |
| 240 | + .MergeTable(); | |
| 241 | + } | |
| 242 | + else if (!string.IsNullOrEmpty(input.kjblsId)) | |
| 243 | + { | |
| 244 | + // 只传入科技部老师ID,关联科技部老师业绩表 | |
| 245 | + baseQuery = _db.Queryable<LqKdKjbsyjEntity, LqKdKdjlbEntity>( | |
| 246 | + (kjbsyj, kdjlb) => kjbsyj.Glkdbh == kdjlb.Id) | |
| 247 | + .Where((kjbsyj, kdjlb) => kjbsyj.Kjbls == input.kjblsId && kjbsyj.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 248 | + .Select((kjbsyj, kdjlb) => kdjlb) | |
| 249 | + .Distinct() | |
| 250 | + .MergeTable(); | |
| 251 | + } | |
| 252 | + else | |
| 253 | + { | |
| 254 | + // 没有传入健康师ID或科技部老师ID,使用原来的查询逻辑 | |
| 255 | + baseQuery = _db.Queryable<LqKdKdjlbEntity>(); | |
| 256 | + } | |
| 257 | + | |
| 258 | + var data = await baseQuery | |
| 259 | + .WhereIF(!string.IsNullOrEmpty(input.keyword), p => p.Kdhyc.Contains(input.keyword) || p.Kdhysjh.Contains(input.keyword)) | |
| 219 | 260 | .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id)) |
| 220 | 261 | .WhereIF(!string.IsNullOrEmpty(input.djmd), p => p.Djmd.Equals(input.djmd)) |
| 221 | 262 | .WhereIF(!string.IsNullOrEmpty(input.jsj), p => p.Jsj.Equals(input.jsj)) |
| ... | ... | @@ -308,18 +349,383 @@ namespace NCC.Extend.LqKdKdjlb |
| 308 | 349 | var itemDetailsGrouped = itemDetails.GroupBy(x => x.glkdbh) |
| 309 | 350 | .ToDictionary(g => g.Key, g => g.ToList()); |
| 310 | 351 | |
| 311 | - // 为每个开单记录分配品项明细 | |
| 352 | + // 批量查询健康师业绩(性能优化:一次性查询所有开单的健康师业绩) | |
| 353 | + var jksyjList = new List<LqKdJksyjInfoOutput>(); | |
| 354 | + if (billingIds.Any()) | |
| 355 | + { | |
| 356 | + jksyjList = await _db.Queryable<LqKdJksyjEntity>() | |
| 357 | + .Where(x => billingIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 358 | + .Select(x => new LqKdJksyjInfoOutput | |
| 359 | + { | |
| 360 | + id = x.Id, | |
| 361 | + glkdbh = x.Glkdbh, | |
| 362 | + kdpxid = x.Kdpxid, | |
| 363 | + jks = x.Jks, | |
| 364 | + jksxm = x.Jksxm, | |
| 365 | + jkszh = x.Jkszh, | |
| 366 | + jksyj = x.Jksyj, | |
| 367 | + yjsj = x.Yjsj, | |
| 368 | + jsj_id = x.Jsj_id, | |
| 369 | + isEffective = x.IsEffective | |
| 370 | + }) | |
| 371 | + .ToListAsync(); | |
| 372 | + } | |
| 373 | + | |
| 374 | + // 批量查询科技部老师业绩(性能优化:一次性查询所有开单的科技部老师业绩) | |
| 375 | + var kjbsyjList = new List<LqKdKjbsyjInfoOutput>(); | |
| 376 | + if (billingIds.Any()) | |
| 377 | + { | |
| 378 | + kjbsyjList = await _db.Queryable<LqKdKjbsyjEntity>() | |
| 379 | + .Where(x => billingIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 380 | + .Select(x => new LqKdKjbsyjInfoOutput | |
| 381 | + { | |
| 382 | + id = x.Id, | |
| 383 | + glkdbh = x.Glkdbh, | |
| 384 | + kdpxid = x.Kdpxid, | |
| 385 | + kjbls = x.Kjbls, | |
| 386 | + kjblsxm = x.Kjblsxm, | |
| 387 | + kjblszh = x.Kjblszh, | |
| 388 | + kjblsyj = x.Kjblsyj, | |
| 389 | + yjsj = x.Yjsj, | |
| 390 | + isEffective = x.IsEffective | |
| 391 | + }) | |
| 392 | + .ToListAsync(); | |
| 393 | + } | |
| 394 | + | |
| 395 | + // 按开单ID分组健康师业绩 | |
| 396 | + var jksyjGrouped = jksyjList.GroupBy(x => x.glkdbh) | |
| 397 | + .ToDictionary(g => g.Key, g => g.ToList()); | |
| 398 | + | |
| 399 | + // 按开单ID分组科技部老师业绩 | |
| 400 | + var kjbsyjGrouped = kjbsyjList.GroupBy(x => x.glkdbh) | |
| 401 | + .ToDictionary(g => g.Key, g => g.ToList()); | |
| 402 | + | |
| 403 | + // 为每个开单记录分配品项明细、健康师业绩和科技部老师业绩 | |
| 312 | 404 | foreach (var item in data.list) |
| 313 | 405 | { |
| 314 | 406 | item.ItemDetails = itemDetailsGrouped.ContainsKey(item.id) |
| 315 | 407 | ? itemDetailsGrouped[item.id] |
| 316 | 408 | : new List<LqKdPxmxInfoOutput>(); |
| 409 | + item.lqKdJksyjList = jksyjGrouped.ContainsKey(item.id) | |
| 410 | + ? jksyjGrouped[item.id] | |
| 411 | + : new List<LqKdJksyjInfoOutput>(); | |
| 412 | + item.lqKdKjbsyjList = kjbsyjGrouped.ContainsKey(item.id) | |
| 413 | + ? kjbsyjGrouped[item.id] | |
| 414 | + : new List<LqKdKjbsyjInfoOutput>(); | |
| 317 | 415 | } |
| 318 | 416 | |
| 319 | 417 | return PageResult<LqKdKdjlbListOutput>.SqlSugarPageResult(data); |
| 320 | 418 | } |
| 321 | 419 | #endregion |
| 322 | 420 | |
| 421 | + #region 根据健康师ID获取开单列表 | |
| 422 | + /// <summary> | |
| 423 | + /// 根据健康师ID获取开单列表 | |
| 424 | + /// </summary> | |
| 425 | + /// <remarks> | |
| 426 | + /// 根据健康师ID查询该健康师参与的所有开单记录,支持时间周期查询和分页 | |
| 427 | + /// | |
| 428 | + /// 示例请求: | |
| 429 | + /// GET /api/Extend/LqKdKdjlb/GetListByJksId?jksId=健康师ID&startTime=2025-01-01&endTime=2025-01-31&currentPage=1&pageSize=10 | |
| 430 | + /// | |
| 431 | + /// 参数说明: | |
| 432 | + /// - jksId: 健康师ID(必填) | |
| 433 | + /// - startTime: 开始时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) | |
| 434 | + /// - endTime: 结束时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) | |
| 435 | + /// - djmd: 门店ID(可选) | |
| 436 | + /// - isEffective: 是否有效(可选,0=全部,1=有效,2=无效,默认1) | |
| 437 | + /// - currentPage: 当前页码(必填) | |
| 438 | + /// - pageSize: 每页数量(必填) | |
| 439 | + /// | |
| 440 | + /// 返回说明: | |
| 441 | + /// - 返回格式与GetList接口相同,包含开单基本信息及品项明细列表 | |
| 442 | + /// </remarks> | |
| 443 | + /// <param name="input">查询参数</param> | |
| 444 | + /// <returns>开单列表(分页)</returns> | |
| 445 | + /// <response code="200">查询成功</response> | |
| 446 | + /// <response code="400">参数错误</response> | |
| 447 | + /// <response code="500">服务器内部错误</response> | |
| 448 | + [HttpGet("GetListByJksId")] | |
| 449 | + public async Task<dynamic> GetListByJksId([FromQuery] LqKdKdjlbListByJksQueryInput input) | |
| 450 | + { | |
| 451 | + try | |
| 452 | + { | |
| 453 | + if (string.IsNullOrEmpty(input.jksId)) | |
| 454 | + { | |
| 455 | + throw NCCException.Oh("健康师ID不能为空"); | |
| 456 | + } | |
| 457 | + | |
| 458 | + var sidx = input.sidx == null ? "kdrq" : input.sidx; | |
| 459 | + var sort = string.IsNullOrEmpty(input.sort) ? "DESC" : input.sort; | |
| 460 | + | |
| 461 | + // 解析时间范围 | |
| 462 | + DateTime? startDate = null; | |
| 463 | + DateTime? endDate = null; | |
| 464 | + if (!string.IsNullOrEmpty(input.startTime)) | |
| 465 | + { | |
| 466 | + startDate = Ext.GetDateTime(input.startTime); | |
| 467 | + } | |
| 468 | + if (!string.IsNullOrEmpty(input.endTime)) | |
| 469 | + { | |
| 470 | + endDate = Ext.GetDateTime(input.endTime); | |
| 471 | + // 如果只传了日期,则设置为当天的23:59:59 | |
| 472 | + if (endDate.HasValue && !input.endTime.Contains(":")) | |
| 473 | + { | |
| 474 | + endDate = new DateTime(endDate.Value.Year, endDate.Value.Month, endDate.Value.Day, 23, 59, 59); | |
| 475 | + } | |
| 476 | + } | |
| 477 | + | |
| 478 | + // 通过健康师业绩表关联查询开单记录 | |
| 479 | + var data = await _db.Queryable<LqKdJksyjEntity, LqKdKdjlbEntity>( | |
| 480 | + (jksyj, kdjlb) => jksyj.Glkdbh == kdjlb.Id) | |
| 481 | + .Where((jksyj, kdjlb) => jksyj.Jkszh == input.jksId) | |
| 482 | + .WhereIF(input.isEffective != 0, (jksyj, kdjlb) => jksyj.IsEffective == input.isEffective && kdjlb.IsEffective == input.isEffective) | |
| 483 | + .WhereIF(input.isEffective == 0, (jksyj, kdjlb) => jksyj.IsEffective == StatusEnum.有效.GetHashCode() && kdjlb.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 484 | + .WhereIF(startDate.HasValue, (jksyj, kdjlb) => kdjlb.Kdrq >= startDate.Value) | |
| 485 | + .WhereIF(endDate.HasValue, (jksyj, kdjlb) => kdjlb.Kdrq <= endDate.Value) | |
| 486 | + .WhereIF(!string.IsNullOrEmpty(input.djmd), (jksyj, kdjlb) => kdjlb.Djmd == input.djmd) | |
| 487 | + .Select((jksyj, kdjlb) => new LqKdKdjlbListOutput | |
| 488 | + { | |
| 489 | + id = kdjlb.Id, | |
| 490 | + djmd = kdjlb.Djmd, | |
| 491 | + jsj = kdjlb.Jsj, | |
| 492 | + kdrq = kdjlb.Kdrq, | |
| 493 | + gjlx = kdjlb.Gjlx, | |
| 494 | + hgjg = kdjlb.Hgjg, | |
| 495 | + zdyj = kdjlb.Zdyj, | |
| 496 | + sfyj = kdjlb.Sfyj, | |
| 497 | + qk = kdjlb.Qk, | |
| 498 | + ckfs = kdjlb.Ckfs, | |
| 499 | + fkfs = kdjlb.Fkfs, | |
| 500 | + fkyy = kdjlb.Fkyy, | |
| 501 | + fkpd = kdjlb.Fkpd, | |
| 502 | + khly = kdjlb.Khly, | |
| 503 | + tjr = kdjlb.Tjr, | |
| 504 | + deductAmount = kdjlb.DeductAmount, | |
| 505 | + paidDebt = kdjlb.PaidDebt, | |
| 506 | + supplementBillingId = kdjlb.SupplementBillingId, | |
| 507 | + sfskdd = kdjlb.Sfskdd, | |
| 508 | + jj = kdjlb.Jj, | |
| 509 | + bz = kdjlb.Bz, | |
| 510 | + kdhy = kdjlb.Kdhy, | |
| 511 | + kdhyc = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == kdjlb.Kdhy).Select(x => x.Khmc), | |
| 512 | + kdhysjh = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == kdjlb.Kdhy).Select(x => x.Sjh), | |
| 513 | + isEffective = kdjlb.IsEffective, | |
| 514 | + createUser = kdjlb.CreateUser, | |
| 515 | + createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == kdjlb.CreateUser).Select(x => x.RealName), | |
| 516 | + activityId = kdjlb.ActivityId, | |
| 517 | + activityName = SqlFunc.Subqueryable<LqPackageInfoEntity>().Where(x => x.Id == kdjlb.ActivityId).Select(x => x.ActivityName), | |
| 518 | + }) | |
| 519 | + .MergeTable() | |
| 520 | + .Distinct() // 去重,因为一个开单可能对应多个健康师业绩记录 | |
| 521 | + .OrderBy($"{sidx} {sort}") | |
| 522 | + .ToPagedListAsync(input.currentPage, input.pageSize); | |
| 523 | + | |
| 524 | + // 获取当前页的开单记录ID列表 | |
| 525 | + var billingIds = data.list.Select(x => x.id).ToList(); | |
| 526 | + | |
| 527 | + // 批量查询品项明细 | |
| 528 | + var itemDetails = new List<LqKdPxmxInfoOutput>(); | |
| 529 | + if (billingIds.Any()) | |
| 530 | + { | |
| 531 | + itemDetails = await _db.Queryable<LqKdPxmxEntity>() | |
| 532 | + .Where(x => billingIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 533 | + .Select(x => new LqKdPxmxInfoOutput | |
| 534 | + { | |
| 535 | + id = x.Id, | |
| 536 | + glkdbh = x.Glkdbh, | |
| 537 | + px = x.Px, | |
| 538 | + pxmc = x.Pxmc, | |
| 539 | + pxjg = x.Pxjg, | |
| 540 | + projectNumber = x.ProjectNumber, | |
| 541 | + isEnabled = x.IsEnabled, | |
| 542 | + sourceType = x.SourceType, | |
| 543 | + memberId = x.MemberId, | |
| 544 | + createTime = x.CreateTIme, | |
| 545 | + totalPrice = x.TotalPrice, | |
| 546 | + actualPrice = x.ActualPrice, | |
| 547 | + remark = x.Remark, | |
| 548 | + isEffective = x.IsEffective | |
| 549 | + }) | |
| 550 | + .ToListAsync(); | |
| 551 | + } | |
| 552 | + | |
| 553 | + // 按开单ID分组品项明细 | |
| 554 | + var itemDetailsGrouped = itemDetails.GroupBy(x => x.glkdbh) | |
| 555 | + .ToDictionary(g => g.Key, g => g.ToList()); | |
| 556 | + | |
| 557 | + // 为每个开单记录分配品项明细 | |
| 558 | + foreach (var item in data.list) | |
| 559 | + { | |
| 560 | + item.ItemDetails = itemDetailsGrouped.ContainsKey(item.id) | |
| 561 | + ? itemDetailsGrouped[item.id] | |
| 562 | + : new List<LqKdPxmxInfoOutput>(); | |
| 563 | + } | |
| 564 | + | |
| 565 | + return PageResult<LqKdKdjlbListOutput>.SqlSugarPageResult(data); | |
| 566 | + } | |
| 567 | + catch (Exception ex) | |
| 568 | + { | |
| 569 | + _logger.LogError(ex, $"根据健康师ID获取开单列表失败 - 健康师ID: {input?.jksId}, 开始时间: {input?.startTime}, 结束时间: {input?.endTime}"); | |
| 570 | + throw NCCException.Oh($"根据健康师ID获取开单列表失败: {ex.Message}"); | |
| 571 | + } | |
| 572 | + } | |
| 573 | + #endregion | |
| 574 | + | |
| 575 | + #region 根据科技部老师ID获取开单列表 | |
| 576 | + /// <summary> | |
| 577 | + /// 根据科技部老师ID获取开单列表 | |
| 578 | + /// </summary> | |
| 579 | + /// <remarks> | |
| 580 | + /// 根据科技部老师ID查询该老师参与的所有开单记录,支持时间周期查询和分页 | |
| 581 | + /// | |
| 582 | + /// 示例请求: | |
| 583 | + /// GET /api/Extend/LqKdKdjlb/GetListByKjbId?kjblsId=科技部老师ID&startTime=2025-01-01&endTime=2025-01-31&currentPage=1&pageSize=10 | |
| 584 | + /// | |
| 585 | + /// 参数说明: | |
| 586 | + /// - kjblsId: 科技部老师ID(必填) | |
| 587 | + /// - startTime: 开始时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) | |
| 588 | + /// - endTime: 结束时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) | |
| 589 | + /// - djmd: 门店ID(可选) | |
| 590 | + /// - isEffective: 是否有效(可选,0=全部,1=有效,2=无效,默认1) | |
| 591 | + /// - currentPage: 当前页码(必填) | |
| 592 | + /// - pageSize: 每页数量(必填) | |
| 593 | + /// | |
| 594 | + /// 返回说明: | |
| 595 | + /// - 返回格式与GetList接口相同,包含开单基本信息及品项明细列表 | |
| 596 | + /// </remarks> | |
| 597 | + /// <param name="input">查询参数</param> | |
| 598 | + /// <returns>开单列表(分页)</returns> | |
| 599 | + /// <response code="200">查询成功</response> | |
| 600 | + /// <response code="400">参数错误</response> | |
| 601 | + /// <response code="500">服务器内部错误</response> | |
| 602 | + [HttpGet("GetListByKjbId")] | |
| 603 | + public async Task<dynamic> GetListByKjbId([FromQuery] LqKdKdjlbListByKjbQueryInput input) | |
| 604 | + { | |
| 605 | + try | |
| 606 | + { | |
| 607 | + if (string.IsNullOrEmpty(input.kjblsId)) | |
| 608 | + { | |
| 609 | + throw NCCException.Oh("科技部老师ID不能为空"); | |
| 610 | + } | |
| 611 | + | |
| 612 | + var sidx = input.sidx == null ? "kdrq" : input.sidx; | |
| 613 | + var sort = string.IsNullOrEmpty(input.sort) ? "DESC" : input.sort; | |
| 614 | + | |
| 615 | + // 解析时间范围 | |
| 616 | + DateTime? startDate = null; | |
| 617 | + DateTime? endDate = null; | |
| 618 | + if (!string.IsNullOrEmpty(input.startTime)) | |
| 619 | + { | |
| 620 | + startDate = Ext.GetDateTime(input.startTime); | |
| 621 | + } | |
| 622 | + if (!string.IsNullOrEmpty(input.endTime)) | |
| 623 | + { | |
| 624 | + endDate = Ext.GetDateTime(input.endTime); | |
| 625 | + // 如果只传了日期,则设置为当天的23:59:59 | |
| 626 | + if (endDate.HasValue && !input.endTime.Contains(":")) | |
| 627 | + { | |
| 628 | + endDate = new DateTime(endDate.Value.Year, endDate.Value.Month, endDate.Value.Day, 23, 59, 59); | |
| 629 | + } | |
| 630 | + } | |
| 631 | + | |
| 632 | + // 通过科技部老师业绩表关联查询开单记录 | |
| 633 | + var data = await _db.Queryable<LqKdKjbsyjEntity, LqKdKdjlbEntity>( | |
| 634 | + (kjbsyj, kdjlb) => kjbsyj.Glkdbh == kdjlb.Id) | |
| 635 | + .Where((kjbsyj, kdjlb) => kjbsyj.Kjbls == input.kjblsId) | |
| 636 | + .WhereIF(input.isEffective != 0, (kjbsyj, kdjlb) => kjbsyj.IsEffective == input.isEffective && kdjlb.IsEffective == input.isEffective) | |
| 637 | + .WhereIF(input.isEffective == 0, (kjbsyj, kdjlb) => kjbsyj.IsEffective == StatusEnum.有效.GetHashCode() && kdjlb.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 638 | + .WhereIF(startDate.HasValue, (kjbsyj, kdjlb) => kdjlb.Kdrq >= startDate.Value) | |
| 639 | + .WhereIF(endDate.HasValue, (kjbsyj, kdjlb) => kdjlb.Kdrq <= endDate.Value) | |
| 640 | + .WhereIF(!string.IsNullOrEmpty(input.djmd), (kjbsyj, kdjlb) => kdjlb.Djmd == input.djmd) | |
| 641 | + .Select((kjbsyj, kdjlb) => new LqKdKdjlbListOutput | |
| 642 | + { | |
| 643 | + id = kdjlb.Id, | |
| 644 | + djmd = kdjlb.Djmd, | |
| 645 | + jsj = kdjlb.Jsj, | |
| 646 | + kdrq = kdjlb.Kdrq, | |
| 647 | + gjlx = kdjlb.Gjlx, | |
| 648 | + hgjg = kdjlb.Hgjg, | |
| 649 | + zdyj = kdjlb.Zdyj, | |
| 650 | + sfyj = kdjlb.Sfyj, | |
| 651 | + qk = kdjlb.Qk, | |
| 652 | + ckfs = kdjlb.Ckfs, | |
| 653 | + fkfs = kdjlb.Fkfs, | |
| 654 | + fkyy = kdjlb.Fkyy, | |
| 655 | + fkpd = kdjlb.Fkpd, | |
| 656 | + khly = kdjlb.Khly, | |
| 657 | + tjr = kdjlb.Tjr, | |
| 658 | + deductAmount = kdjlb.DeductAmount, | |
| 659 | + paidDebt = kdjlb.PaidDebt, | |
| 660 | + supplementBillingId = kdjlb.SupplementBillingId, | |
| 661 | + sfskdd = kdjlb.Sfskdd, | |
| 662 | + jj = kdjlb.Jj, | |
| 663 | + bz = kdjlb.Bz, | |
| 664 | + kdhy = kdjlb.Kdhy, | |
| 665 | + kdhyc = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == kdjlb.Kdhy).Select(x => x.Khmc), | |
| 666 | + kdhysjh = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == kdjlb.Kdhy).Select(x => x.Sjh), | |
| 667 | + isEffective = kdjlb.IsEffective, | |
| 668 | + createUser = kdjlb.CreateUser, | |
| 669 | + createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == kdjlb.CreateUser).Select(x => x.RealName), | |
| 670 | + activityId = kdjlb.ActivityId, | |
| 671 | + activityName = SqlFunc.Subqueryable<LqPackageInfoEntity>().Where(x => x.Id == kdjlb.ActivityId).Select(x => x.ActivityName), | |
| 672 | + }) | |
| 673 | + .MergeTable() | |
| 674 | + .Distinct() // 去重,因为一个开单可能对应多个科技部老师业绩记录 | |
| 675 | + .OrderBy($"{sidx} {sort}") | |
| 676 | + .ToPagedListAsync(input.currentPage, input.pageSize); | |
| 677 | + | |
| 678 | + // 获取当前页的开单记录ID列表 | |
| 679 | + var billingIds = data.list.Select(x => x.id).ToList(); | |
| 680 | + | |
| 681 | + // 批量查询品项明细 | |
| 682 | + var itemDetails = new List<LqKdPxmxInfoOutput>(); | |
| 683 | + if (billingIds.Any()) | |
| 684 | + { | |
| 685 | + itemDetails = await _db.Queryable<LqKdPxmxEntity>() | |
| 686 | + .Where(x => billingIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode()) | |
| 687 | + .Select(x => new LqKdPxmxInfoOutput | |
| 688 | + { | |
| 689 | + id = x.Id, | |
| 690 | + glkdbh = x.Glkdbh, | |
| 691 | + px = x.Px, | |
| 692 | + pxmc = x.Pxmc, | |
| 693 | + pxjg = x.Pxjg, | |
| 694 | + projectNumber = x.ProjectNumber, | |
| 695 | + isEnabled = x.IsEnabled, | |
| 696 | + sourceType = x.SourceType, | |
| 697 | + memberId = x.MemberId, | |
| 698 | + createTime = x.CreateTIme, | |
| 699 | + totalPrice = x.TotalPrice, | |
| 700 | + actualPrice = x.ActualPrice, | |
| 701 | + remark = x.Remark, | |
| 702 | + isEffective = x.IsEffective | |
| 703 | + }) | |
| 704 | + .ToListAsync(); | |
| 705 | + } | |
| 706 | + | |
| 707 | + // 按开单ID分组品项明细 | |
| 708 | + var itemDetailsGrouped = itemDetails.GroupBy(x => x.glkdbh) | |
| 709 | + .ToDictionary(g => g.Key, g => g.ToList()); | |
| 710 | + | |
| 711 | + // 为每个开单记录分配品项明细 | |
| 712 | + foreach (var item in data.list) | |
| 713 | + { | |
| 714 | + item.ItemDetails = itemDetailsGrouped.ContainsKey(item.id) | |
| 715 | + ? itemDetailsGrouped[item.id] | |
| 716 | + : new List<LqKdPxmxInfoOutput>(); | |
| 717 | + } | |
| 718 | + | |
| 719 | + return PageResult<LqKdKdjlbListOutput>.SqlSugarPageResult(data); | |
| 720 | + } | |
| 721 | + catch (Exception ex) | |
| 722 | + { | |
| 723 | + _logger.LogError(ex, $"根据科技部老师ID获取开单列表失败 - 科技部老师ID: {input?.kjblsId}, 开始时间: {input?.startTime}, 结束时间: {input?.endTime}"); | |
| 724 | + throw NCCException.Oh($"根据科技部老师ID获取开单列表失败: {ex.Message}"); | |
| 725 | + } | |
| 726 | + } | |
| 727 | + #endregion | |
| 728 | + | |
| 323 | 729 | #region 新建开单记录表 |
| 324 | 730 | /// <summary> |
| 325 | 731 | /// 新建开单记录表 | ... | ... |
netcore/src/Modularity/Extend/NCC.Extend/LqMdGeneralManagerLifelineService.cs
| ... | ... | @@ -7,10 +7,12 @@ using Mapster; |
| 7 | 7 | using Microsoft.AspNetCore.Mvc; |
| 8 | 8 | using NCC.Common.Core.Manager; |
| 9 | 9 | using NCC.Common.Enum; |
| 10 | +using NCC.Common.Extension; | |
| 10 | 11 | using NCC.Common.Filter; |
| 11 | 12 | using NCC.Dependency; |
| 12 | 13 | using NCC.DynamicApiController; |
| 13 | 14 | using NCC.Extend.Entitys.Dto.LqMdGeneralManagerLifeline; |
| 15 | +using NCC.Extend.Entitys.Enum; | |
| 14 | 16 | using NCC.Extend.Entitys.lq_md_general_manager_lifeline; |
| 15 | 17 | using NCC.Extend.Entitys.lq_md_target; |
| 16 | 18 | using NCC.Extend.Interfaces.LqMdGeneralManagerLifeline; |
| ... | ... | @@ -77,6 +79,7 @@ namespace NCC.Extend.LqMdGeneralManagerLifeline |
| 77 | 79 | storeId = it.StoreId, |
| 78 | 80 | month = it.Month, |
| 79 | 81 | generalManagerId = it.GeneralManagerId, |
| 82 | + managerType = it.ManagerType, | |
| 80 | 83 | lifeline1 = it.Lifeline1, |
| 81 | 84 | commissionRate1 = it.CommissionRate1, |
| 82 | 85 | lifeline2 = it.Lifeline2, |
| ... | ... | @@ -92,6 +95,21 @@ namespace NCC.Extend.LqMdGeneralManagerLifeline |
| 92 | 95 | .MergeTable() |
| 93 | 96 | .OrderBy(sidx + " " + input.sort) |
| 94 | 97 | .ToPagedListAsync(input.currentPage, input.pageSize); |
| 98 | + | |
| 99 | + // 设置经理类型中文名称 | |
| 100 | + foreach (var item in data.list) | |
| 101 | + { | |
| 102 | + if (Enum.IsDefined(typeof(ManagerTypeEnum), item.managerType)) | |
| 103 | + { | |
| 104 | + var enumValue = (ManagerTypeEnum)item.managerType; | |
| 105 | + item.managerTypeName = enumValue.GetDescription(); | |
| 106 | + } | |
| 107 | + else | |
| 108 | + { | |
| 109 | + item.managerTypeName = string.Empty; | |
| 110 | + } | |
| 111 | + } | |
| 112 | + | |
| 95 | 113 | return PageResult<LqMdGeneralManagerLifelineListOutput>.SqlSugarPageResult(data); |
| 96 | 114 | } |
| 97 | 115 | #endregion |
| ... | ... | @@ -273,6 +291,7 @@ namespace NCC.Extend.LqMdGeneralManagerLifeline |
| 273 | 291 | Id = YitIdHelper.NextId().ToString(), |
| 274 | 292 | StoreId = target.StoreId, |
| 275 | 293 | Month = target.Month, |
| 294 | + ManagerType = ManagerTypeEnum.总经理.GetHashCode(), | |
| 276 | 295 | GeneralManagerId = target.BusinessUnitGeneralManager, |
| 277 | 296 | Lifeline1 = 0, |
| 278 | 297 | CommissionRate1 = 0, |
| ... | ... | @@ -299,14 +318,15 @@ namespace NCC.Extend.LqMdGeneralManagerLifeline |
| 299 | 318 | Id = YitIdHelper.NextId().ToString(), |
| 300 | 319 | StoreId = target.StoreId, |
| 301 | 320 | Month = target.Month, |
| 321 | + ManagerType = ManagerTypeEnum.经理.GetHashCode(), | |
| 302 | 322 | GeneralManagerId = target.BusinessUnitManager, |
| 303 | 323 | Lifeline1 = 0, |
| 304 | 324 | CommissionRate1 = 0, |
| 305 | - Lifeline2 = null, | |
| 306 | - CommissionRate2 = null, | |
| 307 | - Lifeline3 = null, | |
| 308 | - CommissionRate3 = null, | |
| 309 | - Remark = null, | |
| 325 | + Lifeline2 = 0, | |
| 326 | + CommissionRate2 = 0, | |
| 327 | + Lifeline3 = 0, | |
| 328 | + CommissionRate3 = 0, | |
| 329 | + Remark = "", | |
| 310 | 330 | CreateTime = DateTime.Now, |
| 311 | 331 | CreateUserId = userInfo.userId, |
| 312 | 332 | }); |
| ... | ... | @@ -405,6 +425,7 @@ namespace NCC.Extend.LqMdGeneralManagerLifeline |
| 405 | 425 | Id = YitIdHelper.NextId().ToString(), |
| 406 | 426 | StoreId = p.StoreId, |
| 407 | 427 | Month = targetMonthStr, |
| 428 | + ManagerType = p.ManagerType, | |
| 408 | 429 | GeneralManagerId = p.GeneralManagerId, |
| 409 | 430 | Lifeline1 = p.Lifeline1, |
| 410 | 431 | CommissionRate1 = p.CommissionRate1, | ... | ... |