Commit 910e21a04974e54a6f54c777b4957f6db31e1bf3
1 parent
96e0ccc7
修复开单记录汇总筛选逻辑:当传入筛选条件但无匹配数据时返回空结果,而不是所有记录
Showing
6 changed files
with
164 additions
and
614 deletions
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdDeductinfo/LqKdDeductinfoListOutput.cs
| @@ -95,5 +95,20 @@ namespace NCC.Extend.Entitys.Dto.LqKdDeductinfo | @@ -95,5 +95,20 @@ namespace NCC.Extend.Entitys.Dto.LqKdDeductinfo | ||
| 95 | /// 门店名称 | 95 | /// 门店名称 |
| 96 | /// </summary> | 96 | /// </summary> |
| 97 | public string StoreName { get; set; } | 97 | public string StoreName { get; set; } |
| 98 | + | ||
| 99 | + /// <summary> | ||
| 100 | + /// 时间期间(开单日期,用于时间范围筛选) | ||
| 101 | + /// </summary> | ||
| 102 | + public DateTime? TimePeriod { get; set; } | ||
| 103 | + | ||
| 104 | + /// <summary> | ||
| 105 | + /// 开单类型(购买、赠送、体验等) | ||
| 106 | + /// </summary> | ||
| 107 | + public string BillingType { get; set; } | ||
| 108 | + | ||
| 109 | + /// <summary> | ||
| 110 | + /// 合作机构 | ||
| 111 | + /// </summary> | ||
| 112 | + public string CooperationInstitution { get; set; } | ||
| 98 | } | 113 | } |
| 99 | } | 114 | } |
netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs
| @@ -47,6 +47,7 @@ using NCC.Extend.Entitys.lq_mdxx; | @@ -47,6 +47,7 @@ using NCC.Extend.Entitys.lq_mdxx; | ||
| 47 | using NCC.Extend.Entitys.lq_card_transfer_log; | 47 | using NCC.Extend.Entitys.lq_card_transfer_log; |
| 48 | using NCC.Extend.Entitys.Dto.LqDailyReport; | 48 | using NCC.Extend.Entitys.Dto.LqDailyReport; |
| 49 | using NCC.Extend.Entitys.lq_yyjl; | 49 | using NCC.Extend.Entitys.lq_yyjl; |
| 50 | +using NCC.Extend.Entitys.lq_hzf; | ||
| 50 | 51 | ||
| 51 | namespace NCC.Extend.LqKdKdjlb | 52 | namespace NCC.Extend.LqKdKdjlb |
| 52 | { | 53 | { |
| @@ -2322,9 +2323,9 @@ namespace NCC.Extend.LqKdKdjlb | @@ -2322,9 +2323,9 @@ namespace NCC.Extend.LqKdKdjlb | ||
| 2322 | } | 2323 | } |
| 2323 | #endregion | 2324 | #endregion |
| 2324 | 2325 | ||
| 2325 | - #region 获取门店某个时间段的开单记录汇总信息 | 2326 | + #region 获取门店某个时间段的开单记录汇总信息(台账) |
| 2326 | /// <summary> | 2327 | /// <summary> |
| 2327 | - /// 获取门店某个时间段的开单记录汇总信息 | 2328 | + /// 获取门店某个时间段的开单记录汇总信息(台账) |
| 2328 | /// </summary> | 2329 | /// </summary> |
| 2329 | /// <param name="input">查询参数</param> | 2330 | /// <param name="input">查询参数</param> |
| 2330 | /// <returns>开单记录汇总信息</returns> | 2331 | /// <returns>开单记录汇总信息</returns> |
| @@ -2368,12 +2369,15 @@ namespace NCC.Extend.LqKdKdjlb | @@ -2368,12 +2369,15 @@ namespace NCC.Extend.LqKdKdjlb | ||
| 2368 | zdyj = it.Zdyj, | 2369 | zdyj = it.Zdyj, |
| 2369 | sfyj = it.Sfyj, | 2370 | sfyj = it.Sfyj, |
| 2370 | qk = it.Qk, | 2371 | qk = it.Qk, |
| 2372 | + hgjg = it.Hgjg, | ||
| 2373 | + hgjgName = SqlFunc.Subqueryable<LqHzfEntity>().Where(x => x.Id == it.Hgjg).Select(x => x.Hzmc), | ||
| 2371 | kdhyc = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == it.Kdhy).Select(x => x.Khmc), | 2374 | kdhyc = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == it.Kdhy).Select(x => x.Khmc), |
| 2372 | kdhysjh = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == it.Kdhy).Select(x => x.Sjh), | 2375 | kdhysjh = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == it.Kdhy).Select(x => x.Sjh), |
| 2373 | fkfs = it.Fkfs, // 付款方式 | 2376 | fkfs = it.Fkfs, // 付款方式 |
| 2374 | khly = it.Khly, // 客户来源 | 2377 | khly = it.Khly, // 客户来源 |
| 2375 | bz = it.Bz, // 备注 | 2378 | bz = it.Bz, // 备注 |
| 2376 | createTime = it.CreateTime | 2379 | createTime = it.CreateTime |
| 2380 | + | ||
| 2377 | }) | 2381 | }) |
| 2378 | .ToListAsync(); | 2382 | .ToListAsync(); |
| 2379 | 2383 | ||
| @@ -2491,240 +2495,55 @@ namespace NCC.Extend.LqKdKdjlb | @@ -2491,240 +2495,55 @@ namespace NCC.Extend.LqKdKdjlb | ||
| 2491 | }) | 2495 | }) |
| 2492 | .ToListAsync(); | 2496 | .ToListAsync(); |
| 2493 | 2497 | ||
| 2494 | - // 构建按开单记录分组的详细数据 | ||
| 2495 | - var detailedRecords = billingRecords.Select(billing => new | ||
| 2496 | - { | ||
| 2497 | - // 基本信息 | ||
| 2498 | - date = billing.kdrq?.ToString("yyyy-MM-dd"), | ||
| 2499 | - customerName = billing.kdhyc, | ||
| 2500 | - customerPhone = billing.kdhysjh, | ||
| 2501 | - storeId = billing.djmd, | ||
| 2502 | - goldTriangle = billing.jsj, | ||
| 2503 | - customerType = billing.gjlx, | ||
| 2504 | - | ||
| 2505 | - // 品项分类 | ||
| 2506 | - purchasedItems = itemDetails.Where(x => x.glkdbh == billing.id && x.sourceType == "购买").Select(x => new | ||
| 2507 | - { | ||
| 2508 | - id = x.id, | ||
| 2509 | - itemName = x.pxmc, | ||
| 2510 | - itemCode = x.px, | ||
| 2511 | - price = x.pxjg, | ||
| 2512 | - totalPrice = x.totalPrice, | ||
| 2513 | - actualPrice = x.actualPrice, | ||
| 2514 | - projectNumber = x.projectNumber, | ||
| 2515 | - remark = x.remark, | ||
| 2516 | - itemCategory = x.itemCategory, | ||
| 2517 | - }).ToList(), | ||
| 2518 | - | ||
| 2519 | - giftedItems = itemDetails.Where(x => x.glkdbh == billing.id && x.sourceType == "赠送").Select(x => new | ||
| 2520 | - { | ||
| 2521 | - id = x.id, | ||
| 2522 | - itemName = x.pxmc, | ||
| 2523 | - itemCode = x.px, | ||
| 2524 | - price = x.pxjg, | ||
| 2525 | - totalPrice = x.totalPrice, | ||
| 2526 | - actualPrice = x.actualPrice, | ||
| 2527 | - projectNumber = x.projectNumber, | ||
| 2528 | - remark = x.remark, | ||
| 2529 | - itemCategory = x.itemCategory, | ||
| 2530 | - }).ToList(), | ||
| 2531 | - | ||
| 2532 | - experienceItems = itemDetails.Where(x => x.glkdbh == billing.id && x.sourceType == "体验").Select(x => new | ||
| 2533 | - { | ||
| 2534 | - id = x.id, | ||
| 2535 | - itemName = x.pxmc, | ||
| 2536 | - itemCode = x.px, | ||
| 2537 | - price = x.pxjg, | ||
| 2538 | - totalPrice = x.totalPrice, | ||
| 2539 | - actualPrice = x.actualPrice, | ||
| 2540 | - projectNumber = x.projectNumber, | ||
| 2541 | - remark = x.remark, | ||
| 2542 | - itemCategory = x.itemCategory, | ||
| 2543 | - }).ToList(), | ||
| 2544 | - | ||
| 2545 | - // 金额信息 | ||
| 2546 | - paidAmount = billing.sfyj, | ||
| 2547 | - debtAmount = billing.qk, | ||
| 2548 | - totalAmount = billing.zdyj, | ||
| 2549 | - | ||
| 2550 | - // 健康师信息 | ||
| 2551 | - healthTeachers = healthTeacherData.Where(x => x.glkdbh == billing.id).Select(x => new | ||
| 2552 | - { | ||
| 2553 | - teacherId = x.jks, | ||
| 2554 | - teacherName = x.jksxm, | ||
| 2555 | - teacherAccount = x.jkszh, | ||
| 2556 | - performance = x.jksyj, | ||
| 2557 | - performanceTime = x.yjsj, | ||
| 2558 | - itemDetailId = x.kdpxid, | ||
| 2559 | - goldTriangleId = x.jsj_id, | ||
| 2560 | - itemCategory = x.itemCategory, | ||
| 2561 | - itemId = x.itemId, | ||
| 2562 | - storeId = x.storeId, | ||
| 2563 | - itemName = x.itemName | ||
| 2564 | - }).ToList(), | ||
| 2565 | - | ||
| 2566 | - // 其他信息 | ||
| 2567 | - source = billing.khly, // 客户来源 | ||
| 2568 | - paymentMethod = billing.fkfs, // 支付方式 | ||
| 2569 | - remark = billing.bz, // 备注 | ||
| 2570 | - createTime = billing.createTime | ||
| 2571 | - }).OrderByDescending(x => x.date).ToList(); | 2498 | + // 根据筛选条件过滤开单记录 |
| 2499 | + // 收集所有需要匹配的开单ID(取交集) | ||
| 2500 | + var matchedBillingIds = new List<string>(); | ||
| 2501 | + var hasFilterCondition = false; // 标记是否传入了筛选条件 | ||
| 2572 | 2502 | ||
| 2573 | - // 构建返回结果 | ||
| 2574 | - var result = new | 2503 | + // 如果传入了品项分类或品项筛选条件,收集匹配的开单ID |
| 2504 | + if (!string.IsNullOrEmpty(input.ItemCategory) || !string.IsNullOrEmpty(input.ItemId)) | ||
| 2575 | { | 2505 | { |
| 2576 | - success = true, | ||
| 2577 | - data = new | 2506 | + hasFilterCondition = true; |
| 2507 | + var itemMatchedIds = itemDetails.Select(x => x.glkdbh).Distinct().ToList(); | ||
| 2508 | + if (matchedBillingIds.Any()) | ||
| 2578 | { | 2509 | { |
| 2579 | - // 汇总统计 | ||
| 2580 | - summary = new | ||
| 2581 | - { | ||
| 2582 | - totalCount = billingRecords.Count, | ||
| 2583 | - totalAmount = billingRecords.Sum(x => x.zdyj), | ||
| 2584 | - totalPaidAmount = billingRecords.Sum(x => x.sfyj), | ||
| 2585 | - totalDebt = billingRecords.Sum(x => x.qk), | ||
| 2586 | - totalPurchasedItems = purchasedItems.Count, | ||
| 2587 | - totalGiftedItems = giftedItems.Count, | ||
| 2588 | - totalExperienceItems = experienceItems.Count, | ||
| 2589 | - totalHealthTeachers = healthTeacherData.GroupBy(x => x.jks).Count() | ||
| 2590 | - }, | ||
| 2591 | - // 详细记录列表 | ||
| 2592 | - records = detailedRecords | ||
| 2593 | - }, | ||
| 2594 | - message = "获取开单记录汇总信息成功" | ||
| 2595 | - }; | ||
| 2596 | - return result; | ||
| 2597 | - } | ||
| 2598 | - catch (Exception ex) | ||
| 2599 | - { | ||
| 2600 | - throw NCCException.Oh($"获取开单记录汇总信息失败:{ex.Message}"); | ||
| 2601 | - } | ||
| 2602 | - } | ||
| 2603 | - #endregion | ||
| 2604 | - | ||
| 2605 | - #region 获取门店某个时间段的开单记录汇总信息(备份) | ||
| 2606 | - /// <summary> | ||
| 2607 | - /// 获取门店某个时间段的开单记录汇总信息(备份) | ||
| 2608 | - /// </summary> | ||
| 2609 | - /// <param name="input">查询参数</param> | ||
| 2610 | - /// <returns>开单记录汇总信息</returns> | ||
| 2611 | - [HttpGet("GetBillingRecordSummaryByStoreId_bak")] | ||
| 2612 | - public async Task<dynamic> GetBillingRecordSummaryByStoreId_bak([FromQuery] BillingRecordSummaryQueryInput input) | ||
| 2613 | - { | ||
| 2614 | - try | ||
| 2615 | - { | ||
| 2616 | - // 验证参数 | ||
| 2617 | - if (string.IsNullOrEmpty(input.StoreId)) | ||
| 2618 | - { | ||
| 2619 | - throw NCCException.Oh("门店ID不能为空"); | 2510 | + matchedBillingIds = matchedBillingIds.Intersect(itemMatchedIds).ToList(); |
| 2511 | + } | ||
| 2512 | + else | ||
| 2513 | + { | ||
| 2514 | + matchedBillingIds = itemMatchedIds; | ||
| 2515 | + } | ||
| 2620 | } | 2516 | } |
| 2621 | 2517 | ||
| 2622 | - // 如果开始时间和结束时间为空,就默认是当月 | ||
| 2623 | - if (input.StartTime == null || input.EndTime == null) | 2518 | + // 如果传入了健康师筛选条件,收集匹配的开单ID |
| 2519 | + if (!string.IsNullOrEmpty(input.HealthCoachId)) | ||
| 2624 | { | 2520 | { |
| 2625 | - input.StartTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); | ||
| 2626 | - input.EndTime = DateTime.Now.AddDays(DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month)); | ||
| 2627 | - } | ||
| 2628 | - | ||
| 2629 | - // 查询开单记录 | ||
| 2630 | - var billingRecords = await _db.Queryable<LqKdKdjlbEntity>() | ||
| 2631 | - .Where(w => w.Djmd == input.StoreId && w.Kdrq >= input.StartTime && w.Kdrq <= input.EndTime && w.IsEffective == StatusEnum.有效.GetHashCode()) | ||
| 2632 | - .Select(it => new | 2521 | + hasFilterCondition = true; |
| 2522 | + var healthTeacherMatchedIds = healthTeacherData.Select(x => x.glkdbh).Distinct().ToList(); | ||
| 2523 | + if (matchedBillingIds.Any()) | ||
| 2633 | { | 2524 | { |
| 2634 | - id = it.Id, | ||
| 2635 | - djmd = it.Djmd, | ||
| 2636 | - jsj = it.Jsj, | ||
| 2637 | - kdrq = it.Kdrq, | ||
| 2638 | - gjlx = it.Gjlx, | ||
| 2639 | - zdyj = it.Zdyj, | ||
| 2640 | - sfyj = it.Sfyj, | ||
| 2641 | - qk = it.Qk, | ||
| 2642 | - kdhyc = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == it.Kdhy).Select(x => x.Khmc), | ||
| 2643 | - kdhysjh = SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == it.Kdhy).Select(x => x.Sjh), | ||
| 2644 | - fkfs = it.Fkfs, // 付款方式 | ||
| 2645 | - khly = it.Khly, // 客户来源 | ||
| 2646 | - bz = it.Bz, // 备注 | ||
| 2647 | - createTime = it.CreateTime | ||
| 2648 | - }) | ||
| 2649 | - .ToListAsync(); | ||
| 2650 | - | ||
| 2651 | - if (!billingRecords.Any()) | ||
| 2652 | - { | ||
| 2653 | - return new | 2525 | + matchedBillingIds = matchedBillingIds.Intersect(healthTeacherMatchedIds).ToList(); |
| 2526 | + } | ||
| 2527 | + else | ||
| 2654 | { | 2528 | { |
| 2655 | - success = true, | ||
| 2656 | - data = new | ||
| 2657 | - { | ||
| 2658 | - billingSummary = new | ||
| 2659 | - { | ||
| 2660 | - totalCount = 0, | ||
| 2661 | - totalAmount = 0, | ||
| 2662 | - totalPaidAmount = 0, | ||
| 2663 | - totalDebt = 0, | ||
| 2664 | - billingRecords = new List<object>() | ||
| 2665 | - }, | ||
| 2666 | - itemSummary = new | ||
| 2667 | - { | ||
| 2668 | - purchased = new { count = 0, totalAmount = 0, items = new List<object>() }, | ||
| 2669 | - gifted = new { count = 0, totalAmount = 0, items = new List<object>() }, | ||
| 2670 | - experience = new { count = 0, totalAmount = 0, items = new List<object>() } | ||
| 2671 | - }, | ||
| 2672 | - healthTeacherSummary = new | ||
| 2673 | - { | ||
| 2674 | - totalCount = 0, | ||
| 2675 | - teachers = new List<object>() | ||
| 2676 | - } | ||
| 2677 | - }, | ||
| 2678 | - message = "该时间段内无开单记录" | ||
| 2679 | - }; | 2529 | + matchedBillingIds = healthTeacherMatchedIds; |
| 2530 | + } | ||
| 2680 | } | 2531 | } |
| 2681 | 2532 | ||
| 2682 | - var billingIds = billingRecords.Select(x => x.id).ToList(); | ||
| 2683 | - | ||
| 2684 | - // 查询品项明细,按F_SourceType分类 | ||
| 2685 | - var itemDetails = await _db.Queryable<LqKdPxmxEntity>() | ||
| 2686 | - .Where(w => billingIds.Contains(w.Glkdbh) && w.IsEffective == StatusEnum.有效.GetHashCode()) | ||
| 2687 | - .Select(it => new | 2533 | + // 如果传入了筛选条件,必须过滤开单记录(即使没有匹配数据也要过滤,返回空结果) |
| 2534 | + if (hasFilterCondition) | ||
| 2535 | + { | ||
| 2536 | + if (matchedBillingIds.Any()) | ||
| 2688 | { | 2537 | { |
| 2689 | - id = it.Id, | ||
| 2690 | - glkdbh = it.Glkdbh, | ||
| 2691 | - px = it.Px, | ||
| 2692 | - pxmc = it.Pxmc, | ||
| 2693 | - pxjg = it.Pxjg, | ||
| 2694 | - sourceType = it.SourceType, | ||
| 2695 | - totalPrice = it.TotalPrice, | ||
| 2696 | - actualPrice = it.ActualPrice, | ||
| 2697 | - projectNumber = it.ProjectNumber, | ||
| 2698 | - remark = it.Remark, | ||
| 2699 | - itemCategory = it.ItemCategory, | ||
| 2700 | - }) | ||
| 2701 | - .ToListAsync(); | ||
| 2702 | - | ||
| 2703 | - // 按来源类型分类品项 | ||
| 2704 | - var purchasedItems = itemDetails.Where(x => x.sourceType == "购买").ToList(); | ||
| 2705 | - var giftedItems = itemDetails.Where(x => x.sourceType == "赠送").ToList(); | ||
| 2706 | - var experienceItems = itemDetails.Where(x => x.sourceType == "体验").ToList(); | ||
| 2707 | - | ||
| 2708 | - // 查询健康师业绩数据 | ||
| 2709 | - var healthTeacherData = await _db.Queryable<LqKdJksyjEntity>() | ||
| 2710 | - .Where(w => billingIds.Contains(w.Glkdbh) && w.IsEffective == StatusEnum.有效.GetHashCode()) | ||
| 2711 | - .Select(it => new | 2538 | + billingRecords = billingRecords.Where(x => matchedBillingIds.Contains(x.id)).ToList(); |
| 2539 | + } | ||
| 2540 | + else | ||
| 2712 | { | 2541 | { |
| 2713 | - id = it.Id, | ||
| 2714 | - glkdbh = it.Glkdbh, | ||
| 2715 | - jks = it.Jks, | ||
| 2716 | - jksxm = it.Jksxm, | ||
| 2717 | - jkszh = it.Jkszh, | ||
| 2718 | - jksyj = it.Jksyj, | ||
| 2719 | - kdpxid = it.Kdpxid, | ||
| 2720 | - yjsj = it.Yjsj, | ||
| 2721 | - jsj_id = it.Jsj_id, | ||
| 2722 | - itemCategory = it.ItemCategory, | ||
| 2723 | - storeId = it.StoreId, | ||
| 2724 | - itemId = it.ItemId, | ||
| 2725 | - itemName = it.ItemName, | ||
| 2726 | - }) | ||
| 2727 | - .ToListAsync(); | 2542 | + // 传入了筛选条件但没有匹配数据,返回空结果 |
| 2543 | + billingRecords = billingRecords.Where(x => false).ToList(); | ||
| 2544 | + } | ||
| 2545 | + billingIds = billingRecords.Select(x => x.id).ToList(); | ||
| 2546 | + } | ||
| 2728 | 2547 | ||
| 2729 | // 构建按开单记录分组的详细数据 | 2548 | // 构建按开单记录分组的详细数据 |
| 2730 | var detailedRecords = billingRecords.Select(billing => new | 2549 | var detailedRecords = billingRecords.Select(billing => new |
| @@ -2736,7 +2555,8 @@ namespace NCC.Extend.LqKdKdjlb | @@ -2736,7 +2555,8 @@ namespace NCC.Extend.LqKdKdjlb | ||
| 2736 | storeId = billing.djmd, | 2555 | storeId = billing.djmd, |
| 2737 | goldTriangle = billing.jsj, | 2556 | goldTriangle = billing.jsj, |
| 2738 | customerType = billing.gjlx, | 2557 | customerType = billing.gjlx, |
| 2739 | - | 2558 | + cooperationInstitution = billing.hgjg, |
| 2559 | + cooperationInstitutionName = billing.hgjgName, | ||
| 2740 | // 品项分类 | 2560 | // 品项分类 |
| 2741 | purchasedItems = itemDetails.Where(x => x.glkdbh == billing.id && x.sourceType == "购买").Select(x => new | 2561 | purchasedItems = itemDetails.Where(x => x.glkdbh == billing.id && x.sourceType == "购买").Select(x => new |
| 2742 | { | 2562 | { |
| @@ -3647,351 +3467,6 @@ namespace NCC.Extend.LqKdKdjlb | @@ -3647,351 +3467,6 @@ namespace NCC.Extend.LqKdKdjlb | ||
| 3647 | } | 3467 | } |
| 3648 | #endregion | 3468 | #endregion |
| 3649 | 3469 | ||
| 3650 | - #region 门店整体统计表(备份) | ||
| 3651 | - /// <summary> | ||
| 3652 | - /// 门店整体统计表 | ||
| 3653 | - /// </summary> | ||
| 3654 | - /// <remarks> | ||
| 3655 | - /// 统计每个健康师在指定时间周期内的各项数据指标 | ||
| 3656 | - /// 包括:邀约人数、预约人数、到店人数、开单人数、开单金额、消耗金额、人头、人次、消耗项目数 | ||
| 3657 | - /// | ||
| 3658 | - /// 示例请求: | ||
| 3659 | - /// ```json | ||
| 3660 | - /// { | ||
| 3661 | - /// "startTime": "2025-10-01", | ||
| 3662 | - /// "endTime": "2025-10-31", | ||
| 3663 | - /// "departmentId": "部门ID", | ||
| 3664 | - /// "storeId": "门店ID", | ||
| 3665 | - /// "employeeName": "健康师姓名" | ||
| 3666 | - /// } | ||
| 3667 | - /// ``` | ||
| 3668 | - /// | ||
| 3669 | - /// 参数说明: | ||
| 3670 | - /// - startTime: 开始时间(可选,默认为当月1号) | ||
| 3671 | - /// - endTime: 结束时间(可选,默认为当前时间) | ||
| 3672 | - /// - departmentId: 事业部ID(可选) | ||
| 3673 | - /// - storeId: 门店ID(可选) | ||
| 3674 | - /// - employeeName: 健康师姓名(可选) | ||
| 3675 | - /// | ||
| 3676 | - /// 返回字段说明: | ||
| 3677 | - /// - EmployeeId: 健康师ID | ||
| 3678 | - /// - EmployeeName: 健康师姓名 | ||
| 3679 | - /// - StoreId: 门店ID | ||
| 3680 | - /// - StoreName: 门店名称 | ||
| 3681 | - /// - DepartmentId: 事业部ID | ||
| 3682 | - /// - DepartmentName: 事业部名称 | ||
| 3683 | - /// - InviteCount: 邀约人数(按客户去重) | ||
| 3684 | - /// - AppointmentCount: 预约人数(按客户去重,无论预约状态) | ||
| 3685 | - /// - VisitCount: 到店人数(按客户去重,仅统计状态为'已确认'的预约) | ||
| 3686 | - /// - BillingCount: 开单人数(按开单记录去重) | ||
| 3687 | - /// - BillingAmount: 开单金额(开单业绩总金额) | ||
| 3688 | - /// - ConsumeAmount: 消耗金额(消耗业绩总金额) | ||
| 3689 | - /// - HeadCount: 人头(按客户去重) | ||
| 3690 | - /// - PersonCount: 人次(按客户+日期去重,同一客户不同天算多次) | ||
| 3691 | - /// - ProjectCount: 消耗项目数(项目总次数) | ||
| 3692 | - /// - RefundAmount: 退卡金额(健康师退卡业绩总金额) | ||
| 3693 | - /// - LaborCost: 手工费(消耗时的手工费总金额) | ||
| 3694 | - /// - OriginalLaborCost: 原始手工费(消耗时的原始手工费总金额) | ||
| 3695 | - /// - OvertimeLaborCost: 加班手工费(消耗时的加班手工费总金额) | ||
| 3696 | - /// </remarks> | ||
| 3697 | - /// <param name="input">查询参数</param> | ||
| 3698 | - /// <returns>健康师统计数据列表</returns> | ||
| 3699 | - /// <response code="200">成功返回统计数据</response> | ||
| 3700 | - /// <response code="400">参数错误</response> | ||
| 3701 | - /// <response code="500">服务器错误</response> | ||
| 3702 | - [HttpGet("get-health-coach-statistics_bak")] | ||
| 3703 | - public async Task<dynamic> GetHealthCoachStatistics_bak([FromQuery] HealthCoachStatisticsQueryInput input) | ||
| 3704 | - { | ||
| 3705 | - try | ||
| 3706 | - { | ||
| 3707 | - // 设置默认时间范围(如果未提供,默认为当月) | ||
| 3708 | - var startTime = input.StartTime ?? new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); | ||
| 3709 | - var endTime = input.EndTime ?? DateTime.Now; | ||
| 3710 | - | ||
| 3711 | - // 构建SQL查询 | ||
| 3712 | - var sql = $@" | ||
| 3713 | - SELECT | ||
| 3714 | - u.F_Id as EmployeeId, | ||
| 3715 | - u.F_REALNAME as EmployeeName, | ||
| 3716 | - u.F_MDID as StoreId, | ||
| 3717 | - md.dm as StoreName, | ||
| 3718 | - md.syb as DepartmentId, | ||
| 3719 | - dept.F_FullName as DepartmentName, | ||
| 3720 | - | ||
| 3721 | - -- 邀约人数 | ||
| 3722 | - COALESCE(invite_stats.InviteCount, 0) as InviteCount, | ||
| 3723 | - | ||
| 3724 | - -- 预约人数(无论状态) | ||
| 3725 | - COALESCE(appointment_stats.AppointmentCount, 0) as AppointmentCount, | ||
| 3726 | - | ||
| 3727 | - -- 到店人数(已确认状态) | ||
| 3728 | - COALESCE(visit_stats.VisitCount, 0) as VisitCount, | ||
| 3729 | - | ||
| 3730 | - -- 开单人数和金额 | ||
| 3731 | - COALESCE(billing_stats.BillingCount, 0) as BillingCount, | ||
| 3732 | - COALESCE(billing_stats.BillingAmount, 0) as BillingAmount, | ||
| 3733 | - | ||
| 3734 | - -- 消耗相关统计 | ||
| 3735 | - COALESCE(consume_stats.ConsumeAmount, 0) as ConsumeAmount, | ||
| 3736 | - CAST(COALESCE(headcount_stats.HeadCount, 0) AS DECIMAL(18,2)) as HeadCount, | ||
| 3737 | - CAST(COALESCE(personcount_stats.PersonCount, 0) AS DECIMAL(18,2)) as PersonCount, | ||
| 3738 | - CAST(COALESCE(invalid_headcount_stats.HeadCount, 0) AS DECIMAL(18,2)) as InvalidHeadCount, | ||
| 3739 | - CAST(COALESCE(invalid_personcount_stats.PersonCount, 0) AS DECIMAL(18,2)) as InvalidPersonCount, | ||
| 3740 | - CAST(COALESCE(consume_stats.ProjectCount, 0) AS DECIMAL(18,2)) as ProjectCount, | ||
| 3741 | - | ||
| 3742 | - -- 退卡金额 | ||
| 3743 | - COALESCE(refund_stats.RefundAmount, 0) as RefundAmount, | ||
| 3744 | - | ||
| 3745 | - -- 手工费相关统计 | ||
| 3746 | - COALESCE(consume_stats.LaborCost, 0) as LaborCost, | ||
| 3747 | - COALESCE(consume_stats.OriginalLaborCost, 0) as OriginalLaborCost, | ||
| 3748 | - COALESCE(consume_stats.OvertimeLaborCost, 0) as OvertimeLaborCost | ||
| 3749 | - | ||
| 3750 | - FROM BASE_USER u | ||
| 3751 | - LEFT JOIN lq_mdxx md ON u.F_MDID = md.F_Id | ||
| 3752 | - LEFT JOIN base_organize dept ON md.syb = dept.F_Id | ||
| 3753 | - | ||
| 3754 | - -- 邀约统计子查询 | ||
| 3755 | - LEFT JOIN ( | ||
| 3756 | - SELECT | ||
| 3757 | - yyr as EmployeeId, | ||
| 3758 | - COUNT(DISTINCT yykh) as InviteCount | ||
| 3759 | - FROM lq_yaoyjl | ||
| 3760 | - WHERE yyr IS NOT NULL | ||
| 3761 | - AND F_CreateTime >= @startTime | ||
| 3762 | - AND F_CreateTime <= @endTime | ||
| 3763 | - GROUP BY yyr | ||
| 3764 | - ) invite_stats ON u.F_Id = invite_stats.EmployeeId | ||
| 3765 | - | ||
| 3766 | - -- 预约统计子查询 | ||
| 3767 | - LEFT JOIN ( | ||
| 3768 | - SELECT | ||
| 3769 | - yyr as EmployeeId, | ||
| 3770 | - COUNT(DISTINCT gk) as AppointmentCount | ||
| 3771 | - FROM lq_yyjl | ||
| 3772 | - WHERE yyr IS NOT NULL | ||
| 3773 | - AND F_CreateTime >= @startTime | ||
| 3774 | - AND F_CreateTime <= @endTime | ||
| 3775 | - GROUP BY yyr | ||
| 3776 | - ) appointment_stats ON u.F_Id = appointment_stats.EmployeeId | ||
| 3777 | - | ||
| 3778 | - -- 到店统计子查询 | ||
| 3779 | - LEFT JOIN ( | ||
| 3780 | - SELECT | ||
| 3781 | - yyr as EmployeeId, | ||
| 3782 | - COUNT(DISTINCT gk) as VisitCount | ||
| 3783 | - FROM lq_yyjl | ||
| 3784 | - WHERE yyr IS NOT NULL | ||
| 3785 | - AND F_Status = '已确认' | ||
| 3786 | - AND F_CreateTime >= @startTime | ||
| 3787 | - AND F_CreateTime <= @endTime | ||
| 3788 | - GROUP BY yyr | ||
| 3789 | - ) visit_stats ON u.F_Id = visit_stats.EmployeeId | ||
| 3790 | - | ||
| 3791 | - -- 开单统计子查询 | ||
| 3792 | - LEFT JOIN ( | ||
| 3793 | - SELECT | ||
| 3794 | - jkszh as EmployeeId, | ||
| 3795 | - COUNT(DISTINCT glkdbh) as BillingCount, | ||
| 3796 | - SUM(CAST(jksyj AS DECIMAL(18,2))) as BillingAmount | ||
| 3797 | - FROM lq_kd_jksyj | ||
| 3798 | - WHERE jkszh IS NOT NULL | ||
| 3799 | - AND F_IsEffective = 1 | ||
| 3800 | - AND yjsj >= @startTime | ||
| 3801 | - AND yjsj <= @endTime | ||
| 3802 | - GROUP BY jkszh | ||
| 3803 | - ) billing_stats ON u.F_Id = billing_stats.EmployeeId | ||
| 3804 | - | ||
| 3805 | - -- 消耗统计子查询 | ||
| 3806 | - LEFT JOIN ( | ||
| 3807 | - SELECT | ||
| 3808 | - jksyj.jks as EmployeeId, | ||
| 3809 | - SUM(jksyj.jksyj) as ConsumeAmount, | ||
| 3810 | - CAST(SUM(jksyj.F_kdpxNumber) AS DECIMAL(18,2)) as ProjectCount, | ||
| 3811 | - COALESCE(SUM(jksyj.F_LaborCost), 0) as LaborCost, | ||
| 3812 | - COALESCE(SUM(jksyj.F_OriginalLaborCost), 0) as OriginalLaborCost, | ||
| 3813 | - COALESCE(SUM(jksyj.F_OvertimeLaborCost), 0) as OvertimeLaborCost | ||
| 3814 | - FROM lq_xh_jksyj jksyj | ||
| 3815 | - INNER JOIN lq_xh_hyhk hyhk ON jksyj.glkdbh = hyhk.F_Id | ||
| 3816 | - WHERE jksyj.jks IS NOT NULL | ||
| 3817 | - AND jksyj.F_IsEffective = 1 | ||
| 3818 | - AND hyhk.F_IsEffective = 1 | ||
| 3819 | - AND hyhk.hksj >= @startTime | ||
| 3820 | - AND hyhk.hksj <= @endTime | ||
| 3821 | - GROUP BY jksyj.jks | ||
| 3822 | - ) consume_stats ON u.F_Id = consume_stats.EmployeeId | ||
| 3823 | - | ||
| 3824 | - -- 有效人头统计子查询(从人次记录表获取,按月份+客户+数量去重后累加数量,F_HasBilling=1) | ||
| 3825 | - LEFT JOIN ( | ||
| 3826 | - SELECT | ||
| 3827 | - F_PersonId as EmployeeId, | ||
| 3828 | - CAST(COALESCE(SUM(F_Quantity), 0) AS DECIMAL(18,2)) as HeadCount | ||
| 3829 | - FROM ( | ||
| 3830 | - SELECT | ||
| 3831 | - F_PersonId, | ||
| 3832 | - F_WorkMonth, | ||
| 3833 | - F_MemberId, | ||
| 3834 | - F_Quantity | ||
| 3835 | - FROM lq_person_times_record | ||
| 3836 | - WHERE F_PersonId IS NOT NULL | ||
| 3837 | - AND F_IsEffective = 1 | ||
| 3838 | - AND F_PersonType = '健康师' | ||
| 3839 | - AND F_HasBilling = 1 | ||
| 3840 | - AND F_WorkDate >= DATE(@startTime) | ||
| 3841 | - AND F_WorkDate <= DATE(@endTime) | ||
| 3842 | - GROUP BY F_PersonId, F_WorkMonth, F_MemberId, F_Quantity | ||
| 3843 | - ) as distinct_headcount | ||
| 3844 | - GROUP BY F_PersonId | ||
| 3845 | - ) headcount_stats ON u.F_Id = headcount_stats.EmployeeId | ||
| 3846 | - | ||
| 3847 | - -- 有效人次统计子查询(从人次记录表获取,按日期+客户+数量去重后累加数量,F_HasBilling=1) | ||
| 3848 | - LEFT JOIN ( | ||
| 3849 | - SELECT | ||
| 3850 | - F_PersonId as EmployeeId, | ||
| 3851 | - CAST(COALESCE(SUM(F_Quantity), 0) AS DECIMAL(18,2)) as PersonCount | ||
| 3852 | - FROM ( | ||
| 3853 | - SELECT | ||
| 3854 | - F_PersonId, | ||
| 3855 | - F_WorkDate, | ||
| 3856 | - F_MemberId, | ||
| 3857 | - F_Quantity | ||
| 3858 | - FROM lq_person_times_record | ||
| 3859 | - WHERE F_PersonId IS NOT NULL | ||
| 3860 | - AND F_IsEffective = 1 | ||
| 3861 | - AND F_PersonType = '健康师' | ||
| 3862 | - AND F_HasBilling = 1 | ||
| 3863 | - AND F_WorkDate >= DATE(@startTime) | ||
| 3864 | - AND F_WorkDate <= DATE(@endTime) | ||
| 3865 | - GROUP BY F_PersonId, F_WorkDate, F_MemberId, F_Quantity | ||
| 3866 | - ) as distinct_personcount | ||
| 3867 | - GROUP BY F_PersonId | ||
| 3868 | - ) personcount_stats ON u.F_Id = personcount_stats.EmployeeId | ||
| 3869 | - | ||
| 3870 | - -- 无效人头统计子查询(从人次记录表获取,按月份+客户+数量去重后累加数量,F_HasBilling=0) | ||
| 3871 | - LEFT JOIN ( | ||
| 3872 | - SELECT | ||
| 3873 | - F_PersonId as EmployeeId, | ||
| 3874 | - CAST(COALESCE(SUM(F_Quantity), 0) AS DECIMAL(18,2)) as HeadCount | ||
| 3875 | - FROM ( | ||
| 3876 | - SELECT | ||
| 3877 | - F_PersonId, | ||
| 3878 | - F_WorkMonth, | ||
| 3879 | - F_MemberId, | ||
| 3880 | - F_Quantity | ||
| 3881 | - FROM lq_person_times_record | ||
| 3882 | - WHERE F_PersonId IS NOT NULL | ||
| 3883 | - AND F_IsEffective = 1 | ||
| 3884 | - AND F_PersonType = '健康师' | ||
| 3885 | - AND F_HasBilling = 0 | ||
| 3886 | - AND F_WorkDate >= DATE(@startTime) | ||
| 3887 | - AND F_WorkDate <= DATE(@endTime) | ||
| 3888 | - GROUP BY F_PersonId, F_WorkMonth, F_MemberId, F_Quantity | ||
| 3889 | - ) as distinct_headcount | ||
| 3890 | - GROUP BY F_PersonId | ||
| 3891 | - ) invalid_headcount_stats ON u.F_Id = invalid_headcount_stats.EmployeeId | ||
| 3892 | - | ||
| 3893 | - -- 无效人次统计子查询(从人次记录表获取,按日期+客户+数量去重后累加数量,F_HasBilling=0) | ||
| 3894 | - LEFT JOIN ( | ||
| 3895 | - SELECT | ||
| 3896 | - F_PersonId as EmployeeId, | ||
| 3897 | - CAST(COALESCE(SUM(F_Quantity), 0) AS DECIMAL(18,2)) as PersonCount | ||
| 3898 | - FROM ( | ||
| 3899 | - SELECT | ||
| 3900 | - F_PersonId, | ||
| 3901 | - F_WorkDate, | ||
| 3902 | - F_MemberId, | ||
| 3903 | - F_Quantity | ||
| 3904 | - FROM lq_person_times_record | ||
| 3905 | - WHERE F_PersonId IS NOT NULL | ||
| 3906 | - AND F_IsEffective = 1 | ||
| 3907 | - AND F_PersonType = '健康师' | ||
| 3908 | - AND F_HasBilling = 0 | ||
| 3909 | - AND F_WorkDate >= DATE(@startTime) | ||
| 3910 | - AND F_WorkDate <= DATE(@endTime) | ||
| 3911 | - GROUP BY F_PersonId, F_WorkDate, F_MemberId, F_Quantity | ||
| 3912 | - ) as distinct_personcount | ||
| 3913 | - GROUP BY F_PersonId | ||
| 3914 | - ) invalid_personcount_stats ON u.F_Id = invalid_personcount_stats.EmployeeId | ||
| 3915 | - | ||
| 3916 | - -- 退卡统计子查询 | ||
| 3917 | - LEFT JOIN ( | ||
| 3918 | - SELECT | ||
| 3919 | - jkszh as EmployeeId, | ||
| 3920 | - SUM(CAST(jksyj AS DECIMAL(18,2))) as RefundAmount | ||
| 3921 | - FROM lq_hytk_jksyj | ||
| 3922 | - WHERE jkszh IS NOT NULL | ||
| 3923 | - AND F_IsEffective = 1 | ||
| 3924 | - AND tksj >= @startTime | ||
| 3925 | - AND tksj <= @endTime | ||
| 3926 | - GROUP BY jkszh | ||
| 3927 | - ) refund_stats ON u.F_Id = refund_stats.EmployeeId | ||
| 3928 | - | ||
| 3929 | - WHERE u.F_GW = '健康师' | ||
| 3930 | - "; | ||
| 3931 | - | ||
| 3932 | - // 添加条件过滤 | ||
| 3933 | - var conditions = new List<string>(); | ||
| 3934 | - var parameters = new List<SugarParameter> | ||
| 3935 | - { | ||
| 3936 | - new SugarParameter("@startTime", startTime), | ||
| 3937 | - new SugarParameter("@endTime", endTime) | ||
| 3938 | - }; | ||
| 3939 | - | ||
| 3940 | - if (!string.IsNullOrEmpty(input.DepartmentId)) | ||
| 3941 | - { | ||
| 3942 | - conditions.Add("md.syb = @departmentId"); | ||
| 3943 | - parameters.Add(new SugarParameter("@departmentId", input.DepartmentId)); | ||
| 3944 | - } | ||
| 3945 | - | ||
| 3946 | - if (!string.IsNullOrEmpty(input.StoreId)) | ||
| 3947 | - { | ||
| 3948 | - conditions.Add("u.F_MDID = @storeId"); | ||
| 3949 | - parameters.Add(new SugarParameter("@storeId", input.StoreId)); | ||
| 3950 | - } | ||
| 3951 | - | ||
| 3952 | - if (!string.IsNullOrEmpty(input.EmployeeName)) | ||
| 3953 | - { | ||
| 3954 | - conditions.Add("u.F_REALNAME LIKE @employeeName"); | ||
| 3955 | - parameters.Add(new SugarParameter("@employeeName", $"%{input.EmployeeName}%")); | ||
| 3956 | - } | ||
| 3957 | - | ||
| 3958 | - if (conditions.Any()) | ||
| 3959 | - { | ||
| 3960 | - sql += " AND " + string.Join(" AND ", conditions); | ||
| 3961 | - } | ||
| 3962 | - | ||
| 3963 | - sql += " ORDER BY u.F_REALNAME"; | ||
| 3964 | - | ||
| 3965 | - // 执行查询 | ||
| 3966 | - var allData = await _db.Ado.SqlQueryAsync<HealthCoachStatisticsOutput>(sql, parameters); | ||
| 3967 | - | ||
| 3968 | - // 手动分页 | ||
| 3969 | - var totalCount = allData.Count; | ||
| 3970 | - var pagedData = allData | ||
| 3971 | - .Skip((input.currentPage - 1) * input.pageSize) | ||
| 3972 | - .Take(input.pageSize) | ||
| 3973 | - .ToList(); | ||
| 3974 | - | ||
| 3975 | - // 直接返回分页结果 | ||
| 3976 | - return new | ||
| 3977 | - { | ||
| 3978 | - list = pagedData, | ||
| 3979 | - pagination = new | ||
| 3980 | - { | ||
| 3981 | - pageIndex = input.currentPage, | ||
| 3982 | - pageSize = input.pageSize, | ||
| 3983 | - totalCount = totalCount | ||
| 3984 | - } | ||
| 3985 | - }; | ||
| 3986 | - } | ||
| 3987 | - catch (Exception ex) | ||
| 3988 | - { | ||
| 3989 | - _logger.LogError(ex, "获取健康师统计数据失败"); | ||
| 3990 | - throw NCCException.Oh($"获取健康师统计数据失败:{ex.Message}"); | ||
| 3991 | - } | ||
| 3992 | - } | ||
| 3993 | - #endregion | ||
| 3994 | - | ||
| 3995 | #region 获取开单品项明细记录列表 | 3470 | #region 获取开单品项明细记录列表 |
| 3996 | /// <summary> | 3471 | /// <summary> |
| 3997 | /// 获取开单品项明细记录列表(分页) | 3472 | /// 获取开单品项明细记录列表(分页) |
| @@ -4274,7 +3749,11 @@ namespace NCC.Extend.LqKdKdjlb | @@ -4274,7 +3749,11 @@ namespace NCC.Extend.LqKdKdjlb | ||
| 4274 | var sidx = string.IsNullOrEmpty(input.sidx) ? "CreateTime" : input.sidx; | 3749 | var sidx = string.IsNullOrEmpty(input.sidx) ? "CreateTime" : input.sidx; |
| 4275 | 3750 | ||
| 4276 | // 构建基础查询:储扣信息 JOIN 开单记录 JOIN 客户信息 JOIN 门店信息 | 3751 | // 构建基础查询:储扣信息 JOIN 开单记录 JOIN 客户信息 JOIN 门店信息 |
| 4277 | - var baseQuery = _db.Queryable<LqKdDeductinfoEntity, LqKdKdjlbEntity, LqKhxxEntity, LqMdxxEntity>((deduct, billing, member, store) => deduct.BillingId == billing.Id && billing.Kdhy == member.Id && billing.Djmd == store.Id) | 3752 | + var baseQuery = _db.Queryable<LqKdDeductinfoEntity, LqKdKdjlbEntity, LqKhxxEntity, LqMdxxEntity>( |
| 3753 | + (deduct, billing, member, store) => | ||
| 3754 | + deduct.BillingId == billing.Id && | ||
| 3755 | + billing.Kdhy == member.Id && | ||
| 3756 | + billing.Djmd == store.Id) | ||
| 4278 | .WhereIF(!string.IsNullOrEmpty(input.DeductType), (deduct, billing, member, store) => deduct.DeductType == input.DeductType) | 3757 | .WhereIF(!string.IsNullOrEmpty(input.DeductType), (deduct, billing, member, store) => deduct.DeductType == input.DeductType) |
| 4279 | .WhereIF(!string.IsNullOrEmpty(input.DeductId), (deduct, billing, member, store) => deduct.DeductId == input.DeductId) | 3758 | .WhereIF(!string.IsNullOrEmpty(input.DeductId), (deduct, billing, member, store) => deduct.DeductId == input.DeductId) |
| 4280 | .WhereIF(!string.IsNullOrEmpty(input.BillingId), (deduct, billing, member, store) => deduct.BillingId == input.BillingId) | 3759 | .WhereIF(!string.IsNullOrEmpty(input.BillingId), (deduct, billing, member, store) => deduct.BillingId == input.BillingId) |
| @@ -4294,7 +3773,7 @@ namespace NCC.Extend.LqKdKdjlb | @@ -4294,7 +3773,7 @@ namespace NCC.Extend.LqKdKdjlb | ||
| 4294 | (billing.Id != null && billing.Id.Contains(input.keyword))); | 3773 | (billing.Id != null && billing.Id.Contains(input.keyword))); |
| 4295 | 3774 | ||
| 4296 | 3775 | ||
| 4297 | - // 查询并分页 | 3776 | + // 查询并分页,使用子查询获取开单类型 |
| 4298 | var data = await baseQuery.Select((deduct, billing, member, store) => new LqKdDeductinfoListOutput | 3777 | var data = await baseQuery.Select((deduct, billing, member, store) => new LqKdDeductinfoListOutput |
| 4299 | { | 3778 | { |
| 4300 | Id = deduct.Id ?? "", | 3779 | Id = deduct.Id ?? "", |
| @@ -4314,7 +3793,12 @@ namespace NCC.Extend.LqKdKdjlb | @@ -4314,7 +3793,12 @@ namespace NCC.Extend.LqKdKdjlb | ||
| 4314 | MemberName = member.Khmc ?? "", | 3793 | MemberName = member.Khmc ?? "", |
| 4315 | MemberPhone = member.Sjh ?? "", | 3794 | MemberPhone = member.Sjh ?? "", |
| 4316 | StoreId = billing.Djmd ?? "", | 3795 | StoreId = billing.Djmd ?? "", |
| 4317 | - StoreName = store.Dm ?? "" | 3796 | + StoreName = store.Dm ?? "", |
| 3797 | + TimePeriod = billing.Kdrq, | ||
| 3798 | + BillingType = SqlFunc.Subqueryable<LqKdPxmxEntity>() | ||
| 3799 | + .Where(pxmx => pxmx.Id == deduct.DeductId && pxmx.Px == deduct.ItemId) | ||
| 3800 | + .Select(pxmx => pxmx.SourceType), | ||
| 3801 | + CooperationInstitution = billing.Hgjg ?? "" | ||
| 4318 | }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize); | 3802 | }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize); |
| 4319 | 3803 | ||
| 4320 | return PageResult<LqKdDeductinfoListOutput>.SqlSugarPageResult(data); | 3804 | return PageResult<LqKdDeductinfoListOutput>.SqlSugarPageResult(data); |
netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs
| @@ -2133,7 +2133,7 @@ namespace NCC.Extend.LqStatistics | @@ -2133,7 +2133,7 @@ namespace NCC.Extend.LqStatistics | ||
| 2133 | ) personcount_stats ON jksyj.jkszh = personcount_stats.jkszh AND hyhk.md = personcount_stats.md | 2133 | ) personcount_stats ON jksyj.jkszh = personcount_stats.jkszh AND hyhk.md = personcount_stats.md |
| 2134 | WHERE jksyj.F_IsEffective = 1 | 2134 | WHERE jksyj.F_IsEffective = 1 |
| 2135 | AND DATE_FORMAT(hyhk.hksj, '%Y%m') = @statisticsMonth | 2135 | AND DATE_FORMAT(hyhk.hksj, '%Y%m') = @statisticsMonth |
| 2136 | - GROUP BY jksyj.jkszh, jksyj.jksxm, hyhk.md, md.mdbm, md.dm, headcount_stats.F_HeadCount, personcount_stats.F_PersonCount"; | 2136 | + GROUP BY jksyj.jks, jksyj.jksxm, hyhk.md, md.mdbm, md.dm, headcount_stats.F_HeadCount, personcount_stats.F_PersonCount"; |
| 2137 | 2137 | ||
| 2138 | var healthCoachData = await _db.Ado.SqlQueryAsync<dynamic>(healthCoachSql, new { statisticsMonth }); | 2138 | var healthCoachData = await _db.Ado.SqlQueryAsync<dynamic>(healthCoachSql, new { statisticsMonth }); |
| 2139 | foreach (var item in healthCoachData) | 2139 | foreach (var item in healthCoachData) |
netcore/src/Modularity/Extend/NCC.Extend/LqXhHyhkService.cs
| @@ -777,48 +777,48 @@ namespace NCC.Extend.LqXhHyhk | @@ -777,48 +777,48 @@ namespace NCC.Extend.LqXhHyhk | ||
| 777 | .OrderBy($"{sidx} {sort}") | 777 | .OrderBy($"{sidx} {sort}") |
| 778 | .ToPagedListAsync(input.currentPage, input.pageSize); | 778 | .ToPagedListAsync(input.currentPage, input.pageSize); |
| 779 | 779 | ||
| 780 | - // 获取当前页的耗卡记录ID列表 | ||
| 781 | - var consumeIds = data.list.Select(x => x.id).ToList(); | 780 | + // 获取当前页的耗卡记录ID列表 |
| 781 | + var consumeIds = data.list.Select(x => x.id).ToList(); | ||
| 782 | 782 | ||
| 783 | - // 批量查询耗卡明细 | ||
| 784 | - var consumeDetails = new List<LqXhPxmxInfoOutput>(); | ||
| 785 | - if (consumeIds.Any()) | ||
| 786 | - { | ||
| 787 | - consumeDetails = await _db.Queryable<LqXhPxmxEntity>() | ||
| 788 | - .Where(x => consumeIds.Contains(x.ConsumeInfoId) && x.IsEffective == StatusEnum.有效.GetHashCode()) | ||
| 789 | - .Select(x => new LqXhPxmxInfoOutput | ||
| 790 | - { | ||
| 791 | - id = x.Id, | ||
| 792 | - consumeInfoId = x.ConsumeInfoId, | ||
| 793 | - billingItemId = x.BillingItemId, | ||
| 794 | - px = x.Px, | ||
| 795 | - pxmc = x.Pxmc, | ||
| 796 | - pxjg = x.Pxjg, | ||
| 797 | - memberId = x.MemberId, | ||
| 798 | - createTime = x.CreateTIme, | ||
| 799 | - projectNumber = x.ProjectNumber, | ||
| 800 | - originalProjectNumber = x.OriginalProjectNumber, | ||
| 801 | - overtimeProjectNumber = x.OvertimeProjectNumber, | ||
| 802 | - sourceType = x.SourceType, | ||
| 803 | - totalPrice = x.TotalPrice, | ||
| 804 | - isEffective = x.IsEffective, | ||
| 805 | - }) | ||
| 806 | - .ToListAsync(); | ||
| 807 | - } | 783 | + // 批量查询耗卡明细 |
| 784 | + var consumeDetails = new List<LqXhPxmxInfoOutput>(); | ||
| 785 | + if (consumeIds.Any()) | ||
| 786 | + { | ||
| 787 | + consumeDetails = await _db.Queryable<LqXhPxmxEntity>() | ||
| 788 | + .Where(x => consumeIds.Contains(x.ConsumeInfoId) && x.IsEffective == StatusEnum.有效.GetHashCode()) | ||
| 789 | + .Select(x => new LqXhPxmxInfoOutput | ||
| 790 | + { | ||
| 791 | + id = x.Id, | ||
| 792 | + consumeInfoId = x.ConsumeInfoId, | ||
| 793 | + billingItemId = x.BillingItemId, | ||
| 794 | + px = x.Px, | ||
| 795 | + pxmc = x.Pxmc, | ||
| 796 | + pxjg = x.Pxjg, | ||
| 797 | + memberId = x.MemberId, | ||
| 798 | + createTime = x.CreateTIme, | ||
| 799 | + projectNumber = x.ProjectNumber, | ||
| 800 | + originalProjectNumber = x.OriginalProjectNumber, | ||
| 801 | + overtimeProjectNumber = x.OvertimeProjectNumber, | ||
| 802 | + sourceType = x.SourceType, | ||
| 803 | + totalPrice = x.TotalPrice, | ||
| 804 | + isEffective = x.IsEffective, | ||
| 805 | + }) | ||
| 806 | + .ToListAsync(); | ||
| 807 | + } | ||
| 808 | 808 | ||
| 809 | - // 按耗卡记录ID分组耗卡明细 | ||
| 810 | - var consumeDetailsGrouped = consumeDetails.GroupBy(x => x.consumeInfoId) | ||
| 811 | - .ToDictionary(g => g.Key, g => g.ToList()); | 809 | + // 按耗卡记录ID分组耗卡明细 |
| 810 | + var consumeDetailsGrouped = consumeDetails.GroupBy(x => x.consumeInfoId) | ||
| 811 | + .ToDictionary(g => g.Key, g => g.ToList()); | ||
| 812 | 812 | ||
| 813 | - // 为每个耗卡记录分配耗卡明细 | ||
| 814 | - foreach (var item in data.list) | ||
| 815 | - { | ||
| 816 | - item.ConsumeDetails = consumeDetailsGrouped.ContainsKey(item.id) | ||
| 817 | - ? consumeDetailsGrouped[item.id] | ||
| 818 | - : new List<LqXhPxmxInfoOutput>(); | ||
| 819 | - } | 813 | + // 为每个耗卡记录分配耗卡明细 |
| 814 | + foreach (var item in data.list) | ||
| 815 | + { | ||
| 816 | + item.ConsumeDetails = consumeDetailsGrouped.ContainsKey(item.id) | ||
| 817 | + ? consumeDetailsGrouped[item.id] | ||
| 818 | + : new List<LqXhPxmxInfoOutput>(); | ||
| 819 | + } | ||
| 820 | 820 | ||
| 821 | - return PageResult<LqXhHyhkListOutput>.SqlSugarPageResult(data); | 821 | + return PageResult<LqXhHyhkListOutput>.SqlSugarPageResult(data); |
| 822 | } | 822 | } |
| 823 | catch (Exception ex) | 823 | catch (Exception ex) |
| 824 | { | 824 | { |
| @@ -1390,6 +1390,8 @@ namespace NCC.Extend.LqXhHyhk | @@ -1390,6 +1390,8 @@ namespace NCC.Extend.LqXhHyhk | ||
| 1390 | } | 1390 | } |
| 1391 | } | 1391 | } |
| 1392 | } | 1392 | } |
| 1393 | + //查询开单记录 | ||
| 1394 | + var billingRecord = await _db.Queryable<LqKdKdjlbEntity>().Where(x => x.Kdhy == entity.Hy && x.IsEffective == StatusEnum.有效.GetHashCode() && x.Sfyj > 0).AnyAsync(); | ||
| 1393 | //剔除所有T区健康师(姓名中包含"T区"的健康师) | 1395 | //剔除所有T区健康师(姓名中包含"T区"的健康师) |
| 1394 | var NoTallJksyjEntities = allJksyjEntities.Where(x => x.Jks != null && x.Jks != "" && (x.Jksxm == null || !x.Jksxm.Contains("T区"))).ToList(); | 1396 | var NoTallJksyjEntities = allJksyjEntities.Where(x => x.Jks != null && x.Jks != "" && (x.Jksxm == null || !x.Jksxm.Contains("T区"))).ToList(); |
| 1395 | //获取这次耗卡有多少个健康师 | 1397 | //获取这次耗卡有多少个健康师 |
| @@ -1412,6 +1414,7 @@ namespace NCC.Extend.LqXhHyhk | @@ -1412,6 +1414,7 @@ namespace NCC.Extend.LqXhHyhk | ||
| 1412 | Quantity = 1 / (decimal)jksCount, | 1414 | Quantity = 1 / (decimal)jksCount, |
| 1413 | CreateTime = DateTime.Now, | 1415 | CreateTime = DateTime.Now, |
| 1414 | IsEffective = StatusEnum.有效.GetHashCode(), | 1416 | IsEffective = StatusEnum.有效.GetHashCode(), |
| 1417 | + HasBilling = billingRecord ? 1 : 0, | ||
| 1415 | }; | 1418 | }; |
| 1416 | allPersonTimesRecordEntities.Add(personTimesRecordEntity); | 1419 | allPersonTimesRecordEntities.Add(personTimesRecordEntity); |
| 1417 | } | 1420 | } |
| @@ -1437,6 +1440,7 @@ namespace NCC.Extend.LqXhHyhk | @@ -1437,6 +1440,7 @@ namespace NCC.Extend.LqXhHyhk | ||
| 1437 | Quantity = 1 / (decimal)kjbCount, | 1440 | Quantity = 1 / (decimal)kjbCount, |
| 1438 | CreateTime = DateTime.Now, | 1441 | CreateTime = DateTime.Now, |
| 1439 | IsEffective = StatusEnum.有效.GetHashCode(), | 1442 | IsEffective = StatusEnum.有效.GetHashCode(), |
| 1443 | + HasBilling = billingRecord ? 1 : 0, | ||
| 1440 | }; | 1444 | }; |
| 1441 | allPersonTimesRecordEntities.Add(personTimesRecordEntity); | 1445 | allPersonTimesRecordEntities.Add(personTimesRecordEntity); |
| 1442 | } | 1446 | } |
sql/修复人次记录HasBilling字段.sql
0 → 100644
| 1 | +-- 修复人次记录表中F_HasBilling字段 | ||
| 2 | +-- 对于耗卡类型的人次记录,如果会员有开单记录(F_IsEffective=1且Sfyj>0),则设置F_HasBilling=1 | ||
| 3 | + | ||
| 4 | +-- 1. 先查看需要修复的记录数量 | ||
| 5 | +SELECT COUNT(*) as need_fix_count | ||
| 6 | +FROM lq_person_times_record ptr | ||
| 7 | +WHERE ptr.F_BusinessType = '耗卡' | ||
| 8 | + AND ptr.F_HasBilling = 0 | ||
| 9 | + AND ptr.F_MemberId IS NOT NULL | ||
| 10 | + AND ptr.F_MemberId != '' | ||
| 11 | + AND EXISTS ( | ||
| 12 | + SELECT 1 | ||
| 13 | + FROM lq_kd_kdjlb kd | ||
| 14 | + WHERE kd.Kdhy = ptr.F_MemberId | ||
| 15 | + AND kd.F_IsEffective = 1 | ||
| 16 | + AND kd.Sfyj > 0 | ||
| 17 | + ); | ||
| 18 | + | ||
| 19 | +-- 2. 修复耗卡类型的人次记录 | ||
| 20 | +UPDATE lq_person_times_record ptr | ||
| 21 | +INNER JOIN ( | ||
| 22 | + SELECT DISTINCT Kdhy | ||
| 23 | + FROM lq_kd_kdjlb | ||
| 24 | + WHERE F_IsEffective = 1 | ||
| 25 | + AND Sfyj > 0 | ||
| 26 | +) kd ON ptr.F_MemberId = kd.Kdhy | ||
| 27 | +SET ptr.F_HasBilling = 1 | ||
| 28 | +WHERE ptr.F_BusinessType = '耗卡' | ||
| 29 | + AND ptr.F_HasBilling = 0 | ||
| 30 | + AND ptr.F_MemberId IS NOT NULL | ||
| 31 | + AND ptr.F_MemberId != ''; | ||
| 32 | + | ||
| 33 | +-- 3. 验证修复结果(可选) | ||
| 34 | +SELECT COUNT(*) as fixed_count | ||
| 35 | +FROM lq_person_times_record ptr | ||
| 36 | +WHERE ptr.F_BusinessType = '耗卡' | ||
| 37 | + AND ptr.F_HasBilling = 1 | ||
| 38 | + AND ptr.F_MemberId IS NOT NULL | ||
| 39 | + AND ptr.F_MemberId != '' | ||
| 40 | + AND EXISTS ( | ||
| 41 | + SELECT 1 | ||
| 42 | + FROM lq_kd_kdjlb kd | ||
| 43 | + WHERE kd.Kdhy = ptr.F_MemberId | ||
| 44 | + AND kd.F_IsEffective = 1 | ||
| 45 | + AND kd.Sfyj > 0 | ||
| 46 | + ); | ||
| 47 | + |
项目信息-薪酬规则与名词解释.md
| @@ -124,8 +124,8 @@ | @@ -124,8 +124,8 @@ | ||
| 124 | 124 | ||
| 125 | ### 顾问提成规则 | 125 | ### 顾问提成规则 |
| 126 | 126 | ||
| 127 | -- **高级顾问**:战队总业绩 ≥ 6万元 且 组员业绩达到40%以上 且 消耗达到6万元 → 团队总业绩0.8% | ||
| 128 | -- **普通顾问**:战队总业绩 ≥ 4万元 且 组员业绩达到30%以上 且 消耗达到4万元 → 团队总业绩0.3% | 127 | +- 战队总业绩 ≥ 6万元 且 组员业绩达到40%以上 且 消耗达到6万元 → 团队总业绩0.8% |
| 128 | +- 战队总业绩 ≥ 4万元 且 组员业绩达到30%以上 且 消耗达到4万元 → 团队总业绩0.3% | ||
| 129 | 129 | ||
| 130 | ### 店助考核规则 | 130 | ### 店助考核规则 |
| 131 | 131 |