Commit 45c3414ed3a65eeff55b140382de163ebe54fb40

Authored by 李宇
2 parents 5762c633 6b449d65

Merge branch 'master' of http://39.98.150.180/antissoft/lvqianmeiye_ERP

antis-ncc-admin/.env.development
... ... @@ -2,6 +2,6 @@
2 2  
3 3 VUE_CLI_BABEL_TRANSPILE_MODULES = true
4 4 # VUE_APP_BASE_API = 'https://erp.lvqianmeiye.com'
5   -VUE_APP_BASE_API = 'http://erp_test.lvqianmeiye.com'
6   -# VUE_APP_BASE_API = 'http://localhost:2011'
  5 +# VUE_APP_BASE_API = 'http://erp_test.lvqianmeiye.com'
  6 +VUE_APP_BASE_API = 'http://localhost:2011'
7 7 VUE_APP_BASE_WSS = 'ws://192.168.110.45:2011/websocket'
... ...
netcore/src/Modularity/Common/NCC.Common/Filter/PageInputBase.cs
... ... @@ -21,7 +21,7 @@ namespace NCC.Common.Filter
21 21 /// <summary>
22 22 /// 每页行数
23 23 /// </summary>
24   - public virtual int pageSize { get; set; } = 50;
  24 + public virtual int pageSize { get; set; } = 20;
25 25  
26 26 /// <summary>
27 27 /// 排序字段:sortField
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXhHyhk/LqXhHyhkListByJksQueryInput.cs 0 → 100644
  1 +using NCC.Common.Filter;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqXhHyhk
  4 +{
  5 + /// <summary>
  6 + /// 根据健康师ID查询耗卡列表输入
  7 + /// </summary>
  8 + public class LqXhHyhkListByJksQueryInput : 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 md { get; set; }
  29 +
  30 + /// <summary>
  31 + /// 是否有效(可选,0=全部,1=有效,2=无效)
  32 + /// </summary>
  33 + public int isEffective { get; set; } = 1;
  34 + }
  35 +}
  36 +
  37 +
  38 +
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXhHyhk/LqXhHyhkListByKjbQueryInput.cs 0 → 100644
  1 +using NCC.Common.Filter;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqXhHyhk
  4 +{
  5 + /// <summary>
  6 + /// 根据科技部老师ID查询耗卡列表输入
  7 + /// </summary>
  8 + public class LqXhHyhkListByKjbQueryInput : 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 md { get; set; }
  29 +
  30 + /// <summary>
  31 + /// 是否有效(可选,0=全部,1=有效,2=无效)
  32 + /// </summary>
  33 + public int isEffective { get; set; } = 1;
  34 + }
  35 +}
  36 +
  37 +
  38 +
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXhHyhk/LqXhHyhkListOutput.cs
1 1 using System;
2 2 using System.Collections.Generic;
  3 +using NCC.Extend.Entitys.Dto.LqXhJksyj;
  4 +using NCC.Extend.Entitys.Dto.LqXhKjbsyj;
3 5 using NCC.Extend.Entitys.Dto.LqXhPxmx;
4 6  
5 7 namespace NCC.Extend.Entitys.Dto.LqXhHyhk
... ... @@ -110,5 +112,15 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk
110 112 /// </summary>
111 113 public decimal? overtimeSgfy { get; set; }
112 114  
  115 + /// <summary>
  116 + /// 健康师业绩列表
  117 + /// </summary>
  118 + public List<LqXhJksyjInfoOutput> lqXhJksyjList { get; set; }
  119 +
  120 + /// <summary>
  121 + /// 科技部老师业绩列表
  122 + /// </summary>
  123 + public List<LqXhKjbsyjInfoOutput> lqXhKjbsyjList { get; set; }
  124 +
113 125 }
114 126 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXhHyhk/LqXhHyhkListQueryInput.cs
... ... @@ -79,5 +79,15 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk
79 79 /// </summary>
80 80 public int isEffective { get; set; } = 0;
81 81  
  82 + /// <summary>
  83 + /// 健康师ID(可选,用于过滤该健康师参与的耗卡)
  84 + /// </summary>
  85 + public string jksId { get; set; }
  86 +
  87 + /// <summary>
  88 + /// 科技部老师ID(可选,用于过滤该老师参与的耗卡)
  89 + /// </summary>
  90 + public string kjblsId { get; set; }
  91 +
82 92 }
83 93 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/Dto/LqMdTarget/LqMdTargetCrInput.cs
... ... @@ -57,6 +57,11 @@ namespace NCC.Extend.Entitys.Dto.LqMdTarget
57 57 public decimal educationDepartmentTarget { get; set; } = 0;
58 58  
59 59 /// <summary>
  60 + /// 大项目部业绩目标
  61 + /// </summary>
  62 + public decimal majorProjectDepartmentTarget { get; set; } = 0;
  63 +
  64 + /// <summary>
60 65 /// 事业部总经理
61 66 /// </summary>
62 67 public string businessUnitGeneralManager { get; set; }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/Dto/LqMdTarget/LqMdTargetInfoOutput.cs
... ... @@ -58,6 +58,11 @@ namespace NCC.Extend.Entitys.Dto.LqMdTarget
58 58 public decimal educationDepartmentTarget { get; set; }
59 59  
60 60 /// <summary>
  61 + /// 大项目部业绩目标
  62 + /// </summary>
  63 + public decimal majorProjectDepartmentTarget { get; set; }
  64 +
  65 + /// <summary>
61 66 /// 事业部总经理
62 67 /// </summary>
63 68 public string businessUnitGeneralManager { get; set; }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/Dto/LqMdTarget/LqMdTargetListOutput.cs
... ... @@ -58,6 +58,11 @@ namespace NCC.Extend.Entitys.Dto.LqMdTarget
58 58 public decimal educationDepartmentTarget { get; set; }
59 59  
60 60 /// <summary>
  61 + /// 大项目部业绩目标
  62 + /// </summary>
  63 + public decimal majorProjectDepartmentTarget { get; set; }
  64 +
  65 + /// <summary>
61 66 /// 事业部总经理
62 67 /// </summary>
63 68 public string businessUnitGeneralManager { get; set; }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/Dto/LqMdTarget/LqMdTargetUpInput.cs
... ... @@ -57,6 +57,11 @@ namespace NCC.Extend.Entitys.Dto.LqMdTarget
57 57 public decimal educationDepartmentTarget { get; set; } = 0;
58 58  
59 59 /// <summary>
  60 + /// 大项目部业绩目标
  61 + /// </summary>
  62 + public decimal majorProjectDepartmentTarget { get; set; } = 0;
  63 +
  64 + /// <summary>
60 65 /// 事业部总经理
61 66 /// </summary>
62 67 public string businessUnitGeneralManager { get; set; }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_md_target/LqMdTargetEntity.cs
... ... @@ -72,6 +72,12 @@ namespace NCC.Extend.Entitys.lq_md_target
72 72 public decimal EducationDepartmentTarget { get; set; } = 0;
73 73  
74 74 /// <summary>
  75 + /// 大项目部业绩目标
  76 + /// </summary>
  77 + [SugarColumn(ColumnName = "F_MajorProjectDepartmentTarget")]
  78 + public decimal MajorProjectDepartmentTarget { get; set; } = 0;
  79 +
  80 + /// <summary>
75 81 /// 事业部总经理
76 82 /// </summary>
77 83 [SugarColumn(ColumnName = "F_BusinessUnitGeneralManager")]
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqDailyReportService.cs
... ... @@ -191,7 +191,7 @@ namespace NCC.Extend
191 191 /// 返回说明:
192 192 /// - StoreId: 门店ID
193 193 /// - StoreName: 门店名称
194   - /// - TargetPerformance: 目标业绩(生命线,来自门店信息表
  194 + /// - TargetPerformance: 目标业绩(门店目标业绩,来自门店目标表lq_md_target的F_StoreTarget字段,根据开始时间所在月份获取,如果未查询到则为0
195 195 /// - BillingPerformance: 开单业绩(开单业绩总和)
196 196 /// - RefundPerformance: 退款业绩(退卡业绩总和)
197 197 /// - ActualPerformance: 实际业绩(开单业绩 - 退款业绩)
... ... @@ -210,6 +210,9 @@ namespace NCC.Extend
210 210 // 获取时间范围
211 211 var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
212 212  
  213 + // 根据开始时间确定月份(YYYYMM格式)
  214 + var month = startDate.ToString("yyyyMM");
  215 +
213 216 // 构建门店过滤条件
214 217 var storeFilter = "";
215 218 if (input.StoreIds != null && input.StoreIds.Any())
... ... @@ -223,8 +226,8 @@ namespace NCC.Extend
223 226 SELECT
224 227 store.F_Id as StoreId,
225 228 store.dm as StoreName,
226   - -- 目标业绩(生命线)
227   - COALESCE(store.xsyj, 0) as TargetPerformance,
  229 + -- 目标业绩(门店目标业绩,来自门店目标表)
  230 + COALESCE(target.F_StoreTarget, 0) as TargetPerformance,
228 231 -- 开单业绩总和
229 232 COALESCE((
230 233 SELECT SUM(billing.sfyj)
... ... @@ -236,7 +239,7 @@ namespace NCC.Extend
236 239 ), 0) as BillingPerformance,
237 240 -- 退款业绩总和(退卡业绩)
238 241 COALESCE((
239   - SELECT SUM(refund.tkje)
  242 + SELECT SUM(refund.F_ActualRefundAmount)
240 243 FROM lq_hytk_hytk refund
241 244 WHERE refund.md = store.F_Id
242 245 AND refund.F_IsEffective = 1
... ... @@ -244,6 +247,7 @@ namespace NCC.Extend
244 247 AND DATE(refund.tksj) <= '{endDate:yyyy-MM-dd}'
245 248 ), 0) as RefundPerformance
246 249 FROM lq_mdxx store
  250 + LEFT JOIN lq_md_target target ON target.F_StoreId = store.F_Id AND target.F_Month = '{month}'
247 251 WHERE 1=1 {storeFilter}
248 252 ORDER BY (BillingPerformance - RefundPerformance) DESC";
249 253  
... ... @@ -298,10 +302,10 @@ namespace NCC.Extend
298 302 /// 返回说明:
299 303 /// - BusinessUnitId: 事业部ID
300 304 /// - BusinessUnitName: 事业部名称
301   - /// - TargetPerformance: 目标业绩(管理门店的生命线总和
  305 + /// - TargetPerformance: 目标业绩(来自门店目标表lq_md_target的F_BusinessUnitTarget字段,根据开始时间所在月份获取,通过F_BusinessUnit字段关联,如果未查询到则为0
302 306 /// - CompletedPerformance: 完成业绩(指定时间范围内的开单业绩总和)
303 307 /// - CompletionRate: 完成率(百分比,CompletedPerformance / TargetPerformance * 100)
304   - /// - StoreCount: 门店数量
  308 + /// - StoreCount: 门店数量(根据门店目标表中归属该事业部的门店数统计)
305 309 /// </remarks>
306 310 /// <param name="input">查询参数</param>
307 311 /// <returns>事业部业绩完成情况列表</returns>
... ... @@ -315,6 +319,9 @@ namespace NCC.Extend
315 319 // 获取时间范围
316 320 var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
317 321  
  322 + // 根据开始时间确定月份(YYYYMM格式)
  323 + var month = startDate.ToString("yyyyMM");
  324 +
318 325 // 构建事业部过滤条件
319 326 var businessUnitFilter = "";
320 327 if (input.BusinessUnitIds != null && input.BusinessUnitIds.Any())
... ... @@ -329,10 +336,10 @@ namespace NCC.Extend
329 336 SELECT
330 337 o.F_Id as BusinessUnitId,
331 338 o.F_FullName as BusinessUnitName,
332   - COALESCE(SUM(store.xsyj), 0) as TargetPerformance,
333   - COUNT(DISTINCT store.F_Id) as StoreCount
  339 + COALESCE(SUM(target.F_BusinessUnitTarget), 0) as TargetPerformance,
  340 + COUNT(DISTINCT target.F_StoreId) as StoreCount
334 341 FROM base_organize o
335   - LEFT JOIN lq_mdxx store ON store.syb = o.F_Id
  342 + LEFT JOIN lq_md_target target ON target.F_BusinessUnit = o.F_Id AND target.F_Month = '{month}'
336 343 WHERE o.F_Category = 'department'
337 344 AND (o.F_DeleteMark IS NULL OR o.F_DeleteMark != 1)
338 345 AND o.F_FullName IN ('事业一部', '事业二部', '事业三部', '事业四部', '事业五部', '事业六部')
... ... @@ -432,10 +439,10 @@ namespace NCC.Extend
432 439 /// 返回说明:
433 440 /// - DepartmentId: 部门ID
434 441 /// - DepartmentName: 部门名称(教育一部、教育二部、科技一部、科技二部、大项目一部、大项目二部)
435   - /// - TargetPerformance: 目标业绩(管理门店的生命线总和
  442 + /// - TargetPerformance: 目标业绩(来自门店目标表lq_md_target,根据部门类型使用对应字段:教育部使用F_EducationDepartmentTarget,科技部使用F_TechDepartmentTarget,大项目部使用F_MajorProjectDepartmentTarget,根据开始时间所在月份获取,通过对应归属字段关联,如果未查询到则为0
436 443 /// - CompletedPerformance: 完成业绩(指定时间范围内的开单业绩总和)
437 444 /// - CompletionRate: 完成率(百分比,CompletedPerformance / TargetPerformance * 100)
438   - /// - StoreCount: 门店数量
  445 + /// - StoreCount: 门店数量(根据门店目标表中归属该部门的门店数统计)
439 446 /// </remarks>
440 447 /// <param name="input">查询参数</param>
441 448 /// <returns>天王团业绩完成情况列表</returns>
... ... @@ -449,6 +456,9 @@ namespace NCC.Extend
449 456 // 获取时间范围
450 457 var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
451 458  
  459 + // 根据开始时间确定月份(YYYYMM格式)
  460 + var month = startDate.ToString("yyyyMM");
  461 +
452 462 // 构建部门过滤条件
453 463 var departmentFilter = "";
454 464 if (input.DepartmentIds != null && input.DepartmentIds.Any())
... ... @@ -457,12 +467,12 @@ namespace NCC.Extend
457 467 departmentFilter = $"AND o.F_Id IN ('{filterDeptIdsStr}')";
458 468 }
459 469  
460   - // 天王团部门信息(字段名和部门名称的映射)
461   - var tianwangDepartments = new Dictionary<string, (string fieldName, string[] departmentNames)>
  470 + // 天王团部门信息(字段名、目标字段名和部门名称的映射)
  471 + var tianwangDepartments = new Dictionary<string, (string fieldName, string targetFieldName, string[] departmentNames)>
462 472 {
463   - { "jyb", ("jyb", new[] { "教育一部", "教育二部" }) },
464   - { "kjb", ("kjb", new[] { "科技一部", "科技二部" }) },
465   - { "dxmb", ("dxmb", new[] { "大项目一部", "大项目二部" }) }
  473 + { "jyb", ("F_EducationDepartment", "F_EducationDepartmentTarget", new[] { "教育一部", "教育二部" }) },
  474 + { "kjb", ("F_TechDepartment", "F_TechDepartmentTarget", new[] { "科技一部", "科技二部" }) },
  475 + { "dxmb", ("F_MajorProjectDepartment", "F_MajorProjectDepartmentTarget", new[] { "大项目一部", "大项目二部" }) }
466 476 };
467 477  
468 478 // 分步查询,提高效率
... ... @@ -480,10 +490,10 @@ namespace NCC.Extend
480 490 SELECT
481 491 o.F_Id as DepartmentId,
482 492 o.F_FullName as DepartmentName,
483   - COALESCE(SUM(store.xsyj), 0) as TargetPerformance,
484   - COUNT(DISTINCT store.F_Id) as StoreCount
  493 + COALESCE(SUM(target.{deptType.Value.targetFieldName}), 0) as TargetPerformance,
  494 + COUNT(DISTINCT target.F_StoreId) as StoreCount
485 495 FROM base_organize o
486   - LEFT JOIN lq_mdxx store ON store.{deptType.Key} = o.F_Id
  496 + LEFT JOIN lq_md_target target ON target.{deptType.Value.fieldName} = o.F_Id AND target.F_Month = '{month}'
487 497 WHERE o.F_Category = 'department'
488 498 AND (o.F_DeleteMark IS NULL OR o.F_DeleteMark != 1)
489 499 AND o.F_FullName IN ('{deptNamesStr}')
... ... @@ -608,7 +618,7 @@ namespace NCC.Extend
608 618 /// - ManagerId: 经理用户ID
609 619 /// - ManagerName: 经理姓名
610 620 /// - StoreId/StoreName: 门店信息
611   - /// - Target1/2/3: 目标业绩一/二/三阶段(smx1/smx2/smx3
  621 + /// - Target1/2/3: 目标业绩一/二/三阶段(来自门店总经理生命线设置表lq_md_general_manager_lifeline的F_Lifeline1/F_Lifeline2/F_Lifeline3字段,根据开始时间所在月份获取,如果未查询到则为0
612 622 /// - CompletedPerformance: 完成业绩(指定时间范围内的开单业绩总和)
613 623 /// - CompletionRate1/2/3: 完成率各阶段(百分比)
614 624 /// </remarks>
... ... @@ -624,38 +634,41 @@ namespace NCC.Extend
624 634 // 获取时间范围
625 635 var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
626 636  
  637 + // 根据开始时间确定月份(YYYYMM格式)
  638 + var month = startDate.ToString("yyyyMM");
  639 +
627 640 // 构建经理过滤条件
628 641 var managerFilter = "";
629 642 if (!string.IsNullOrWhiteSpace(input.ManagerId))
630 643 {
631   - managerFilter = $"AND target.zjl_userid = '{input.ManagerId}'";
  644 + managerFilter = $"AND target.F_GeneralManagerId = '{input.ManagerId}'";
632 645 }
633 646  
634 647 // SQL查询:获取经理在各门店的目标业绩和完成业绩
635 648 var sql = $@"
636 649 SELECT
637   - target.zjl_userid as ManagerId,
  650 + target.F_GeneralManagerId as ManagerId,
638 651 u.F_RealName as ManagerName,
639   - target.md_id as StoreId,
  652 + target.F_StoreId as StoreId,
640 653 store.dm as StoreName,
641   - target.smx1 as Target1,
642   - target.smx2 as Target2,
643   - target.smx3 as Target3,
  654 + target.F_Lifeline1 as Target1,
  655 + target.F_Lifeline2 as Target2,
  656 + target.F_Lifeline3 as Target3,
644 657 -- 完成业绩
645 658 COALESCE((
646 659 SELECT SUM(billing.sfyj)
647 660 FROM lq_kd_kdjlb billing
648   - WHERE billing.djmd = target.md_id
  661 + WHERE billing.djmd = target.F_StoreId
649 662 AND billing.F_IsEffective = 1
650 663 AND DATE(billing.kdrq) >= '{startDate:yyyy-MM-dd}'
651 664 AND DATE(billing.kdrq) <= '{endDate:yyyy-MM-dd}'
652 665 ), 0) as CompletedPerformance
653   - FROM lq_zjl_mdsmxsz target
654   - INNER JOIN BASE_USER u ON target.zjl_userid = u.F_Id
655   - INNER JOIN lq_mdxx store ON target.md_id = store.F_Id
656   - WHERE target.deletemark = 0
  666 + FROM lq_md_general_manager_lifeline target
  667 + INNER JOIN BASE_USER u ON target.F_GeneralManagerId = u.F_Id
  668 + INNER JOIN lq_mdxx store ON target.F_StoreId = store.F_Id
  669 + WHERE target.F_Month = '{month}'
657 670 {managerFilter}
658   - ORDER BY target.zjl_userid, store.dm";
  671 + ORDER BY target.F_GeneralManagerId, store.dm";
659 672  
660 673 var result = await _db.Ado.SqlQueryAsync<dynamic>(sql);
661 674  
... ... @@ -712,10 +725,10 @@ namespace NCC.Extend
712 725 /// 返回说明:
713 726 /// - ManagerId: 经理用户ID
714 727 /// - ManagerName: 经理姓名
715   - /// - TotalTarget1/2/3: 总目标业绩一/二/三阶段
  728 + /// - TotalTarget1/2/3: 总目标业绩一/二/三阶段(来自门店总经理生命线设置表lq_md_general_manager_lifeline的F_Lifeline1/F_Lifeline2/F_Lifeline3字段,根据开始时间所在月份获取并汇总)
716 729 /// - TotalCompletedPerformance: 总完成业绩(指定时间范围内的开单业绩总和)
717 730 /// - TotalCompletionRate1/2/3: 总完成率各阶段
718   - /// - StoreCount: 管理门店数量
  731 + /// - StoreCount: 管理门店数量(根据门店总经理生命线设置表中归属该经理的门店数统计)
719 732 /// </remarks>
720 733 /// <param name="input">查询参数</param>
721 734 /// <returns>经理汇总业绩完成情况列表</returns>
... ... @@ -729,37 +742,40 @@ namespace NCC.Extend
729 742 // 获取时间范围
730 743 var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
731 744  
  745 + // 根据开始时间确定月份(YYYYMM格式)
  746 + var month = startDate.ToString("yyyyMM");
  747 +
732 748 // 构建经理过滤条件
733 749 var managerFilter = "";
734 750 if (!string.IsNullOrWhiteSpace(input.ManagerId))
735 751 {
736   - managerFilter = $"AND target.zjl_userid = '{input.ManagerId}'";
  752 + managerFilter = $"AND target.F_GeneralManagerId = '{input.ManagerId}'";
737 753 }
738 754  
739 755 // SQL查询:获取经理汇总业绩
740 756 var sql = $@"
741 757 SELECT
742   - target.zjl_userid as ManagerId,
  758 + target.F_GeneralManagerId as ManagerId,
743 759 u.F_RealName as ManagerName,
744   - SUM(target.smx1) as TotalTarget1,
745   - COALESCE(SUM(target.smx2), 0) as TotalTarget2,
746   - COALESCE(SUM(target.smx3), 0) as TotalTarget3,
747   - COUNT(DISTINCT target.md_id) as StoreCount,
  760 + SUM(target.F_Lifeline1) as TotalTarget1,
  761 + COALESCE(SUM(target.F_Lifeline2), 0) as TotalTarget2,
  762 + COALESCE(SUM(target.F_Lifeline3), 0) as TotalTarget3,
  763 + COUNT(DISTINCT target.F_StoreId) as StoreCount,
748 764 -- 总完成业绩
749 765 SUM(COALESCE((
750 766 SELECT SUM(billing.sfyj)
751 767 FROM lq_kd_kdjlb billing
752   - WHERE billing.djmd = target.md_id
  768 + WHERE billing.djmd = target.F_StoreId
753 769 AND billing.F_IsEffective = 1
754 770 AND DATE(billing.kdrq) >= '{startDate:yyyy-MM-dd}'
755 771 AND DATE(billing.kdrq) <= '{endDate:yyyy-MM-dd}'
756 772 ), 0)) as TotalCompletedPerformance
757   - FROM lq_zjl_mdsmxsz target
758   - INNER JOIN BASE_USER u ON target.zjl_userid = u.F_Id
759   - INNER JOIN lq_mdxx store ON target.md_id = store.F_Id
760   - WHERE target.deletemark = 0
  773 + FROM lq_md_general_manager_lifeline target
  774 + INNER JOIN BASE_USER u ON target.F_GeneralManagerId = u.F_Id
  775 + INNER JOIN lq_mdxx store ON target.F_StoreId = store.F_Id
  776 + WHERE target.F_Month = '{month}'
761 777 {managerFilter}
762   - GROUP BY target.zjl_userid, u.F_RealName
  778 + GROUP BY target.F_GeneralManagerId, u.F_RealName
763 779 ORDER BY TotalCompletedPerformance DESC";
764 780  
765 781 var result = await _db.Ado.SqlQueryAsync<dynamic>(sql);
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqMdGeneralManagerLifelineService.cs
... ... @@ -66,7 +66,7 @@ namespace NCC.Extend.LqMdGeneralManagerLifeline
66 66 [HttpGet("")]
67 67 public async Task<dynamic> GetList([FromQuery] LqMdGeneralManagerLifelineListQueryInput input)
68 68 {
69   - var sidx = input.sidx == null ? "F_Id" : input.sidx;
  69 + var sidx = input.sidx == null ? "id" : input.sidx;
70 70 var data = await _db.Queryable<LqMdGeneralManagerLifelineEntity>()
71 71 .WhereIF(!string.IsNullOrEmpty(input.storeId), p => p.StoreId.Contains(input.storeId))
72 72 .WhereIF(!string.IsNullOrEmpty(input.month), p => p.Month == input.month)
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqMdTargetService.cs
... ... @@ -67,7 +67,8 @@ namespace NCC.Extend.LqMdTarget
67 67 [HttpGet("")]
68 68 public async Task<dynamic> GetList([FromQuery] LqMdTargetListQueryInput input)
69 69 {
70   - var sidx = input.sidx == null ? "F_Id" : input.sidx;
  70 + var sidx = input.sidx == null ? "id" : input.sidx;
  71 + var sort = string.IsNullOrEmpty(input.sort) ? "DESC" : input.sort;
71 72 var data = await _db.Queryable<LqMdTargetEntity>()
72 73 .WhereIF(!string.IsNullOrEmpty(input.storeId), p => p.StoreId.Contains(input.storeId))
73 74 .WhereIF(!string.IsNullOrEmpty(input.month), p => p.Month == input.month)
... ... @@ -87,6 +88,7 @@ namespace NCC.Extend.LqMdTarget
87 88 businessUnitTarget = it.BusinessUnitTarget,
88 89 techDepartmentTarget = it.TechDepartmentTarget,
89 90 educationDepartmentTarget = it.EducationDepartmentTarget,
  91 + majorProjectDepartmentTarget = it.MajorProjectDepartmentTarget,
90 92 businessUnitGeneralManager = it.BusinessUnitGeneralManager,
91 93 businessUnitManager = it.BusinessUnitManager,
92 94 storeTarget = it.StoreTarget,
... ... @@ -102,7 +104,7 @@ namespace NCC.Extend.LqMdTarget
102 104 updateUser = it.UpdateUser,
103 105 })
104 106 .MergeTable()
105   - .OrderBy(sidx + " " + input.sort)
  107 + .OrderBy($"{sidx} {sort}")
106 108 .ToPagedListAsync(input.currentPage, input.pageSize);
107 109 return PageResult<LqMdTargetListOutput>.SqlSugarPageResult(data);
108 110 }
... ... @@ -151,43 +153,67 @@ namespace NCC.Extend.LqMdTarget
151 153 public async Task<dynamic> BatchCreateByStores([FromQuery] string month)
152 154 {
153 155 var userInfo = await _userManager.GetUserInfo();
  156 + if (userInfo == null || string.IsNullOrEmpty(userInfo.userId))
  157 + {
  158 + throw NCCException.Oh("用户信息获取失败,请重新登录");
  159 + }
154 160 // 验证月份格式
155 161 if (string.IsNullOrEmpty(month) || month.Length != 6 || !Regex.IsMatch(month, @"^\d{6}$"))
156 162 {
157   - throw NCCException.Oh(ErrorCode.COM1000, "月份格式必须为YYYYMM(如:202501)");
  163 + throw NCCException.Oh("月份格式必须为YYYYMM(如:202501)");
158 164 }
159 165 //查询门店列表
160   - var storeList = await _db.Queryable<LqMdxxEntity>().Where(p => p.Status == StatusEnum.有效.GetHashCode()).Select(p => p.Id).ToListAsync();
  166 + var storeList = await _db.Queryable<LqMdxxEntity>().Select(p => p.Id).ToListAsync();
  167 +
  168 + if (storeList == null || storeList.Count == 0)
  169 + {
  170 + return new { success = true, message = "没有有效的门店数据", createdCount = 0 };
  171 + }
  172 +
161 173 // 删除设置月份的所有门店数据
162 174 await _db.Deleteable<LqMdTargetEntity>().Where(p => p.Month == month).ExecuteCommandAsync();
  175 +
163 176 // 批量创建
164   - var entities = storeList.Select(storeId => new LqMdTargetEntity
  177 + var entities = new List<LqMdTargetEntity>();
  178 + foreach (var storeId in storeList)
  179 + {
  180 + if (string.IsNullOrEmpty(storeId))
  181 + continue;
  182 +
  183 + entities.Add(new LqMdTargetEntity
  184 + {
  185 + Id = YitIdHelper.NextId().ToString(),
  186 + StoreId = storeId,
  187 + Month = month,
  188 + BusinessUnit = "",
  189 + TechDepartment = "",
  190 + EducationDepartment = "",
  191 + MajorProjectDepartment = "",
  192 + BusinessUnitTarget = 0,
  193 + TechDepartmentTarget = 0,
  194 + EducationDepartmentTarget = 0,
  195 + BusinessUnitGeneralManager = "",
  196 + BusinessUnitManager = "",
  197 + StoreTarget = 0,
  198 + StoreLifeline = 0,
  199 + StoreConsumeTarget = 0,
  200 + StoreProjectTarget = 0,
  201 + StoreHeadcountTarget = 0,
  202 + AssistantHeadcountTargetStage1 = 0,
  203 + AssistantHeadcountTargetStage2 = 0,
  204 + CreateTime = DateTime.Now,
  205 + CreateUser = userInfo.userId,
  206 + });
  207 + }
  208 +
  209 + if (entities.Count == 0)
165 210 {
166   - Id = YitIdHelper.NextId().ToString(),
167   - StoreId = storeId,
168   - Month = month,
169   - BusinessUnit = "",
170   - TechDepartment = "",
171   - EducationDepartment = "",
172   - MajorProjectDepartment = "",
173   - BusinessUnitTarget = 0,
174   - TechDepartmentTarget = 0,
175   - EducationDepartmentTarget = 0,
176   - BusinessUnitGeneralManager = "",
177   - BusinessUnitManager = "",
178   - StoreTarget = 0,
179   - StoreLifeline = 0,
180   - StoreConsumeTarget = 0,
181   - StoreProjectTarget = 0,
182   - StoreHeadcountTarget = 0,
183   - AssistantHeadcountTargetStage1 = 0,
184   - AssistantHeadcountTargetStage2 = 0,
185   - CreateTime = DateTime.Now,
186   - CreateUser = userInfo.userId,
187   - }).ToList();
  211 + return new { success = true, message = "没有有效的门店数据可创建", createdCount = 0 };
  212 + }
  213 +
188 214 var isOk = await _db.Insertable(entities).ExecuteCommandAsync();
189 215 if (!(isOk > 0))
190   - throw NCCException.Oh(ErrorCode.COM1000);
  216 + throw NCCException.Oh(ErrorCode.COM1000, "批量创建失败");
191 217 return new { success = true, message = $"成功创建{isOk}条记录", createdCount = isOk };
192 218 }
193 219 #endregion
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs
... ... @@ -3644,7 +3644,7 @@ namespace NCC.Extend.LqStatistics
3644 3644 SELECT COALESCE(SUM(pxmx.F_ProjectNumber), 0) as Count
3645 3645 FROM lq_kd_jksyj jksyj
3646 3646 INNER JOIN lq_kd_pxmx pxmx ON jksyj.F_kdpxid = pxmx.F_Id
3647   - WHERE jksyj.jkszh = '{userId}'
  3647 + WHERE jksyj.jks = '{userId}'
3648 3648 AND jksyj.F_IsEffective = 1
3649 3649 AND DATE_FORMAT(jksyj.yjsj, '%Y%m') = '{month}'";
3650 3650  
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqXhHyhkService.cs
... ... @@ -172,12 +172,361 @@ namespace NCC.Extend.LqXhHyhk
172 172 /// <summary>
173 173 /// 获取会员耗卡列表
174 174 /// </summary>
175   - /// <param name="input">请求参数</param>
176   - /// <returns></returns>
  175 + /// <remarks>
  176 + /// 根据多种条件查询会员耗卡记录列表,支持分页、排序、筛选等功能
  177 + ///
  178 + /// 示例请求:
  179 + /// GET /api/Extend/LqXhHyhk/GetList?currentPage=1&amp;pageSize=10&amp;jksId=健康师ID&amp;startTime=2025-01-01&amp;endTime=2025-01-31
  180 + ///
  181 + /// 传入参数说明:
  182 + /// - currentPage: 当前页码(必填,默认1)
  183 + /// - pageSize: 每页数量(必填,默认10)
  184 + /// - sidx: 排序字段(可选,默认"id")
  185 + /// - sort: 排序方式(可选,ASC/DESC,默认DESC)
  186 + /// - keyword: 关键字搜索(可选,搜索会员名称、账号、手机号)
  187 + /// - id: 耗卡编号(可选,模糊匹配)
  188 + /// - md: 门店ID(可选,精确匹配)
  189 + /// - mdbh: 门店编号(可选,模糊匹配)
  190 + /// - mdmc: 门店名称(可选,模糊匹配)
  191 + /// - hy: 会员ID(可选,精确匹配)
  192 + /// - hyzh: 会员账号(可选,模糊匹配)
  193 + /// - hymc: 会员名称(可选,模糊匹配)
  194 + /// - gklx: 顾客类型(可选,精确匹配)
  195 + /// - sfykjb: 是否有科技部(可选,精确匹配)
  196 + /// - hksj: 耗卡时间(可选,格式:开始时间,结束时间,如:2025-01-01,2025-01-31)
  197 + /// - czry: 操作人员ID(可选,精确匹配)
  198 + /// - isEffective: 是否有效(可选,0=全部,1=有效,2=无效,默认0)
  199 + /// - jksId: 健康师ID(可选,传入后只返回该健康师参与的耗卡记录)
  200 + /// - kjblsId: 科技部老师ID(可选,传入后只返回该老师参与的耗卡记录)
  201 + ///
  202 + /// 返回结果说明:
  203 + /// - code: 响应状态码(200=成功)
  204 + /// - msg: 响应消息
  205 + /// - data: 分页数据对象
  206 + /// - list: 耗卡记录列表,每个记录包含:
  207 + /// - id: 耗卡编号
  208 + /// - md: 门店ID
  209 + /// - mdbh: 门店编号
  210 + /// - mdmc: 门店名称
  211 + /// - hy: 会员ID
  212 + /// - hyzh: 会员账号
  213 + /// - hymc: 会员名称
  214 + /// - memberPhone: 会员手机号
  215 + /// - gklx: 顾客类型
  216 + /// - xfje: 消费金额
  217 + /// - sgfy: 手工费用
  218 + /// - sfykjb: 是否有科技部
  219 + /// - hksj: 耗卡时间
  220 + /// - czry: 操作人员ID
  221 + /// - isEffective: 是否有效
  222 + /// - signatureFile: 签名文件
  223 + /// - overtimeCoefficient: 加班系数(NULL或0表示非加班单,大于0表示加班单)
  224 + /// - originalSgfy: 原始手工费(用户输入的原始值)
  225 + /// - overtimeSgfy: 加班手工费(加班计算后的增量值)
  226 + /// - ConsumeDetails: 耗卡明细列表(品项明细),每个明细包含:
  227 + /// - id: 明细编号
  228 + /// - consumeInfoId: 耗卡记录ID
  229 + /// - billingItemId: 开单品项明细表ID
  230 + /// - px: 品项编号
  231 + /// - pxmc: 品项名称
  232 + /// - pxjg: 品项价格
  233 + /// - memberId: 会员ID
  234 + /// - createTime: 创建时间
  235 + /// - projectNumber: 项目次数
  236 + /// - originalProjectNumber: 原始项目次数
  237 + /// - overtimeProjectNumber: 加班项目次数
  238 + /// - sourceType: 来源类型(开卡/赠送/其他)
  239 + /// - totalPrice: 合计金额(品项价格 × 项目次数)
  240 + /// - isEffective: 是否有效
  241 + /// - lqXhJksyjList: 健康师业绩列表,每个业绩包含:
  242 + /// - id: 业绩编号
  243 + /// - glkdbh: 关联耗卡编号
  244 + /// - jks: 健康师ID
  245 + /// - jksxm: 健康师姓名
  246 + /// - jkszh: 健康师账号
  247 + /// - jksyj: 健康师业绩
  248 + /// - yjsj: 业绩时间
  249 + /// - jsjId: 金三角ID
  250 + /// - kdpxid: 耗卡品项ID
  251 + /// - laborCost: 手工费
  252 + /// - kdpxNumber: 耗卡品项次数
  253 + /// - originalKdpxNumber: 原始耗卡品项次数
  254 + /// - overtimeKdpxNumber: 加班耗卡品项次数
  255 + /// - originalLaborCost: 原始手工费
  256 + /// - overtimeLaborCost: 加班手工费
  257 + /// - isAccompanied: 是否陪同(0=否,1=是)
  258 + /// - accompaniedProjectNumber: 陪同项目数
  259 + /// - memberId: 会员ID
  260 + /// - memberName: 会员名称
  261 + /// - lqXhKjbsyjList: 科技部老师业绩列表,每个业绩包含:
  262 + /// - id: 业绩编号
  263 + /// - glkdbh: 关联耗卡编号
  264 + /// - kjbls: 科技部老师ID
  265 + /// - kjblsxm: 科技部老师姓名
  266 + /// - kjblszh: 科技部老师账号
  267 + /// - kjblsyj: 科技部老师业绩
  268 + /// - yjsj: 业绩时间
  269 + /// - hkpxid: 耗卡品项ID
  270 + /// - laborCost: 手工费
  271 + /// - hdpxNumber: 耗卡品项次数
  272 + /// - originalHdpxNumber: 原始耗卡品项次数
  273 + /// - overtimeHdpxNumber: 加班耗卡品项次数
  274 + /// - originalLaborCost: 原始手工费
  275 + /// - overtimeLaborCost: 加班手工费
  276 + /// - pagination: 分页信息
  277 + /// - total: 总记录数
  278 + /// - pageSize: 每页数量
  279 + /// - currentPage: 当前页码
  280 + /// - totalPages: 总页数
  281 + /// </remarks>
  282 + /// <param name="input">查询参数</param>
  283 + /// <returns>分页的耗卡记录列表,包含耗卡基本信息、耗卡明细、健康师业绩、科技部老师业绩</returns>
  284 + /// <response code="200">成功返回耗卡列表</response>
  285 + /// <response code="400">参数错误</response>
  286 + /// <response code="500">服务器内部错误</response>
177 287 [HttpGet("")]
178 288 public async Task<dynamic> GetList([FromQuery] LqXhHyhkListQueryInput input)
179 289 {
180 290 var sidx = input.sidx == null ? "id" : input.sidx;
  291 + var sort = string.IsNullOrEmpty(input.sort) ? "DESC" : input.sort;
  292 + List<string> queryHksj = input.hksj != null ? input.hksj.Split(',').ToObeject<List<string>>() : null;
  293 + DateTime? startHksj = queryHksj != null ? Ext.GetDateTime(queryHksj.First()) : null;
  294 + DateTime? endHksj = queryHksj != null ? Ext.GetDateTime(queryHksj.Last()) : null;
  295 +
  296 + // 根据是否传入健康师ID或科技部老师ID来决定查询方式
  297 + ISugarQueryable<LqXhHyhkEntity> query = null;
  298 +
  299 + // 如果两个都传入了,需要同时JOIN两个表
  300 + if (!string.IsNullOrEmpty(input.jksId) && !string.IsNullOrEmpty(input.kjblsId))
  301 + {
  302 + query = _db.Queryable<LqXhJksyjEntity, LqXhKjbsyjEntity, LqXhHyhkEntity>(
  303 + (jksyj, kjbsyj, hyhk) => jksyj.Glkdbh == hyhk.Id && kjbsyj.Glkdbh == hyhk.Id)
  304 + .Where((jksyj, kjbsyj, hyhk) => jksyj.Jkszh == input.jksId && jksyj.IsEffective == StatusEnum.有效.GetHashCode())
  305 + .Where((jksyj, kjbsyj, hyhk) => kjbsyj.Kjblszh == input.kjblsId && kjbsyj.IsEffective == StatusEnum.有效.GetHashCode())
  306 + .Select((jksyj, kjbsyj, hyhk) => hyhk)
  307 + .Distinct()
  308 + .MergeTable(); // 将多表结果集变成单表,后续可以使用it别名
  309 + }
  310 + // 如果只传入了健康师ID,需要通过JOIN健康师业绩表来过滤
  311 + else if (!string.IsNullOrEmpty(input.jksId))
  312 + {
  313 + query = _db.Queryable<LqXhJksyjEntity, LqXhHyhkEntity>(
  314 + (jksyj, hyhk) => jksyj.Glkdbh == hyhk.Id)
  315 + .Where((jksyj, hyhk) => jksyj.Jkszh == input.jksId && jksyj.IsEffective == StatusEnum.有效.GetHashCode())
  316 + .Select((jksyj, hyhk) => hyhk)
  317 + .Distinct()
  318 + .MergeTable(); // 将多表结果集变成单表,后续可以使用it别名
  319 + }
  320 + // 如果只传入了科技部老师ID,需要通过JOIN科技部老师业绩表来过滤
  321 + else if (!string.IsNullOrEmpty(input.kjblsId))
  322 + {
  323 + query = _db.Queryable<LqXhKjbsyjEntity, LqXhHyhkEntity>(
  324 + (kjbsyj, hyhk) => kjbsyj.Glkdbh == hyhk.Id)
  325 + .Where((kjbsyj, hyhk) => kjbsyj.Kjblszh == input.kjblsId && kjbsyj.IsEffective == StatusEnum.有效.GetHashCode())
  326 + .Select((kjbsyj, hyhk) => hyhk)
  327 + .Distinct()
  328 + .MergeTable(); // 将多表结果集变成单表,后续可以使用it别名
  329 + }
  330 + // 如果都没有传入,直接查询耗卡表
  331 + else
  332 + {
  333 + query = _db.Queryable<LqXhHyhkEntity>();
  334 + }
  335 +
  336 + var data = await query
  337 + .WhereIF(!string.IsNullOrEmpty(input.keyword), p => p.Hymc.Contains(input.keyword) || p.Hyzh.Contains(input.keyword) || p.MemberPhone.Contains(input.keyword))
  338 + .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id))
  339 + .WhereIF(!string.IsNullOrEmpty(input.md), p => p.Md.Equals(input.md))
  340 + .WhereIF(!string.IsNullOrEmpty(input.mdbh), p => p.Mdbh.Contains(input.mdbh))
  341 + .WhereIF(!string.IsNullOrEmpty(input.mdmc), p => p.Mdmc.Contains(input.mdmc))
  342 + .WhereIF(!string.IsNullOrEmpty(input.hy), p => p.Hy.Equals(input.hy))
  343 + .WhereIF(!string.IsNullOrEmpty(input.hyzh), p => p.Hyzh.Contains(input.hyzh))
  344 + .WhereIF(!string.IsNullOrEmpty(input.hymc), p => p.Hymc.Contains(input.hymc))
  345 + .WhereIF(!string.IsNullOrEmpty(input.gklx), p => p.Gklx.Equals(input.gklx))
  346 + .WhereIF(!string.IsNullOrEmpty(input.sfykjb), p => p.Sfykjb.Equals(input.sfykjb))
  347 + .WhereIF(queryHksj != null, p => p.Hksj >= new DateTime(startHksj.ToDate().Year, startHksj.ToDate().Month, startHksj.ToDate().Day, 0, 0, 0))
  348 + .WhereIF(queryHksj != null, p => p.Hksj <= new DateTime(endHksj.ToDate().Year, endHksj.ToDate().Month, endHksj.ToDate().Day, 23, 59, 59))
  349 + .WhereIF(!string.IsNullOrEmpty(input.czry), p => p.Czry.Equals(input.czry))
  350 + .WhereIF(input.isEffective != 0, p => p.IsEffective == input.isEffective)
  351 + .Select(it => new LqXhHyhkListOutput
  352 + {
  353 + id = it.Id,
  354 + md = it.Md,
  355 + mdbh = it.Mdbh,
  356 + mdmc = it.Mdmc,
  357 + hy = it.Hy,
  358 + hyzh = it.Hyzh,
  359 + hymc = SqlFunc.Subqueryable<LqKhxxEntity>().Where(w => w.Id == it.Hy).Select(w => w.Khmc),
  360 + gklx = it.Gklx,
  361 + xfje = SqlFunc.ToString(it.Xfje),
  362 + sgfy = SqlFunc.ToString(it.Sgfy),
  363 + sfykjb = it.Sfykjb,
  364 + hksj = it.Hksj,
  365 + czry = it.Czry,
  366 + memberPhone = SqlFunc.Subqueryable<LqKhxxEntity>().Where(w => w.Id == it.Hy).Select(w => w.Sjh),
  367 + isEffective = it.IsEffective,
  368 + signatureFile = it.SignatureFile,
  369 + overtimeCoefficient = it.OvertimeCoefficient,
  370 + originalSgfy = it.OriginalSgfy,
  371 + overtimeSgfy = it.OvertimeSgfy,
  372 + })
  373 + .MergeTable()
  374 + .OrderBy($"{sidx} {sort}")
  375 + .ToPagedListAsync(input.currentPage, input.pageSize);
  376 +
  377 + // 获取当前页的耗卡记录ID列表
  378 + var consumeIds = data.list.Select(x => x.id).ToList();
  379 +
  380 + // 批量查询耗卡明细
  381 + var consumeDetails = new List<LqXhPxmxInfoOutput>();
  382 + if (consumeIds.Any())
  383 + {
  384 + consumeDetails = await _db.Queryable<LqXhPxmxEntity>()
  385 + .Where(x => consumeIds.Contains(x.ConsumeInfoId) && x.IsEffective == StatusEnum.有效.GetHashCode())
  386 + .Select(x => new LqXhPxmxInfoOutput
  387 + {
  388 + id = x.Id,
  389 + consumeInfoId = x.ConsumeInfoId,
  390 + billingItemId = x.BillingItemId,
  391 + px = x.Px,
  392 + pxmc = x.Pxmc,
  393 + pxjg = x.Pxjg,
  394 + memberId = x.MemberId,
  395 + createTime = x.CreateTIme,
  396 + projectNumber = x.ProjectNumber,
  397 + originalProjectNumber = x.OriginalProjectNumber,
  398 + overtimeProjectNumber = x.OvertimeProjectNumber,
  399 + sourceType = x.SourceType,
  400 + totalPrice = x.TotalPrice,
  401 + isEffective = x.IsEffective,
  402 + })
  403 + .ToListAsync();
  404 + }
  405 +
  406 + // 按耗卡记录ID分组耗卡明细
  407 + var consumeDetailsGrouped = consumeDetails.GroupBy(x => x.consumeInfoId)
  408 + .ToDictionary(g => g.Key, g => g.ToList());
  409 +
  410 + // 批量查询健康师业绩(性能优化:一次性查询所有耗卡的健康师业绩)
  411 + var jksyjList = new List<LqXhJksyjInfoOutput>();
  412 + if (consumeIds.Any())
  413 + {
  414 + // 先查询业绩数据
  415 + var jksyjEntities = await _db.Queryable<LqXhJksyjEntity>()
  416 + .Where(x => consumeIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode())
  417 + .ToListAsync();
  418 +
  419 + // 批量查询耗卡记录获取会员ID
  420 + var hyhkList = await _db.Queryable<LqXhHyhkEntity>()
  421 + .Where(x => consumeIds.Contains(x.Id))
  422 + .Select(x => new { x.Id, x.Hy })
  423 + .ToListAsync();
  424 + var hyhkDict = hyhkList.ToDictionary(x => x.Id, x => x.Hy);
  425 +
  426 + // 批量查询会员信息
  427 + var memberIds = hyhkDict.Values.Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList();
  428 + var memberList = new List<(string Id, string Khmc)>();
  429 + if (memberIds.Any())
  430 + {
  431 + var memberData = await _db.Queryable<LqKhxxEntity>()
  432 + .Where(x => memberIds.Contains(x.Id))
  433 + .Select(x => new { x.Id, x.Khmc })
  434 + .ToListAsync();
  435 + memberList = memberData.Select(x => (x.Id, x.Khmc)).ToList();
  436 + }
  437 + var memberDict = memberList.ToDictionary(x => x.Id, x => x.Khmc);
  438 +
  439 + // 转换为输出DTO
  440 + jksyjList = jksyjEntities.Select(x => new LqXhJksyjInfoOutput
  441 + {
  442 + id = x.Id,
  443 + glkdbh = x.Glkdbh,
  444 + jks = x.Jks,
  445 + jksxm = x.Jksxm,
  446 + jkszh = x.Jkszh,
  447 + jksyj = x.Jksyj?.ToString() ?? "0",
  448 + yjsj = x.Yjsj,
  449 + jsjId = x.JsjId,
  450 + kdpxid = x.Kdpxid,
  451 + laborCost = x.LaborCost,
  452 + kdpxNumber = x.KdpxNumber,
  453 + originalKdpxNumber = x.OriginalKdpxNumber,
  454 + overtimeKdpxNumber = x.OvertimeKdpxNumber,
  455 + originalLaborCost = x.OriginalLaborCost,
  456 + overtimeLaborCost = x.OvertimeLaborCost,
  457 + isAccompanied = x.IsAccompanied,
  458 + accompaniedProjectNumber = x.AccompaniedProjectNumber,
  459 + memberId = hyhkDict.ContainsKey(x.Glkdbh) ? hyhkDict[x.Glkdbh] : null,
  460 + memberName = hyhkDict.ContainsKey(x.Glkdbh) && memberDict.ContainsKey(hyhkDict[x.Glkdbh])
  461 + ? memberDict[hyhkDict[x.Glkdbh]]
  462 + : null,
  463 + }).ToList();
  464 + }
  465 +
  466 + // 批量查询科技部老师业绩(性能优化:一次性查询所有耗卡的科技部老师业绩)
  467 + var kjbsyjList = new List<LqXhKjbsyjInfoOutput>();
  468 + if (consumeIds.Any())
  469 + {
  470 + kjbsyjList = await _db.Queryable<LqXhKjbsyjEntity>()
  471 + .Where(x => consumeIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode())
  472 + .Select(x => new LqXhKjbsyjInfoOutput
  473 + {
  474 + id = x.Id,
  475 + glkdbh = x.Glkdbh,
  476 + kjbls = x.Kjbls,
  477 + kjblsxm = x.Kjblsxm,
  478 + kjblszh = x.Kjblszh,
  479 + kjblsyj = SqlFunc.ToString(x.Kjblsyj),
  480 + yjsj = x.Yjsj,
  481 + hkpxid = x.Hkpxid,
  482 + laborCost = x.LaborCost,
  483 + hdpxNumber = x.HdpxNumber,
  484 + originalHdpxNumber = x.OriginalHdpxNumber,
  485 + overtimeHdpxNumber = x.OvertimeHdpxNumber,
  486 + originalLaborCost = x.OriginalLaborCost,
  487 + overtimeLaborCost = x.OvertimeLaborCost,
  488 + })
  489 + .ToListAsync();
  490 + }
  491 +
  492 + // 按耗卡记录ID分组健康师业绩
  493 + var jksyjGrouped = jksyjList.GroupBy(x => x.glkdbh)
  494 + .ToDictionary(g => g.Key, g => g.ToList());
  495 +
  496 + // 按耗卡记录ID分组科技部老师业绩
  497 + var kjbsyjGrouped = kjbsyjList.GroupBy(x => x.glkdbh)
  498 + .ToDictionary(g => g.Key, g => g.ToList());
  499 +
  500 + // 为每个耗卡记录分配耗卡明细、健康师业绩和科技部老师业绩
  501 + foreach (var item in data.list)
  502 + {
  503 + item.ConsumeDetails = consumeDetailsGrouped.ContainsKey(item.id)
  504 + ? consumeDetailsGrouped[item.id]
  505 + : new List<LqXhPxmxInfoOutput>();
  506 +
  507 + item.lqXhJksyjList = jksyjGrouped.ContainsKey(item.id)
  508 + ? jksyjGrouped[item.id]
  509 + : new List<LqXhJksyjInfoOutput>();
  510 +
  511 + item.lqXhKjbsyjList = kjbsyjGrouped.ContainsKey(item.id)
  512 + ? kjbsyjGrouped[item.id]
  513 + : new List<LqXhKjbsyjInfoOutput>();
  514 + }
  515 +
  516 + return PageResult<LqXhHyhkListOutput>.SqlSugarPageResult(data);
  517 + }
  518 + #endregion
  519 +
  520 + #region 获取会员耗卡列表(备份)
  521 + /// <summary>
  522 + /// 获取会员耗卡列表
  523 + /// </summary>
  524 + /// <param name="input">请求参数</param>
  525 + /// <returns></returns>
  526 + [HttpGet("GetListBak")]
  527 + public async Task<dynamic> GetListBak([FromQuery] LqXhHyhkListQueryInput input)
  528 + {
  529 + var sidx = input.sidx == null ? "id" : input.sidx;
181 530 List<string> queryHksj = input.hksj != null ? input.hksj.Split(',').ToObeject<List<string>>() : null;
182 531 DateTime? startHksj = queryHksj != null ? Ext.GetDateTime(queryHksj.First()) : null;
183 532 DateTime? endHksj = queryHksj != null ? Ext.GetDateTime(queryHksj.Last()) : null;
... ... @@ -263,6 +612,294 @@ namespace NCC.Extend.LqXhHyhk
263 612 }
264 613 #endregion
265 614  
  615 + #region 根据健康师ID获取耗卡列表
  616 + /// <summary>
  617 + /// 根据健康师ID获取耗卡列表
  618 + /// </summary>
  619 + /// <remarks>
  620 + /// 根据健康师ID查询该健康师参与的所有耗卡记录,支持时间周期查询和分页
  621 + ///
  622 + /// 示例请求:
  623 + /// GET /api/Extend/LqXhHyhk/GetListByJksId?jksId=健康师ID&amp;startTime=2025-01-01&amp;endTime=2025-01-31&amp;currentPage=1&amp;pageSize=10
  624 + ///
  625 + /// 参数说明:
  626 + /// - jksId: 健康师ID(必填)
  627 + /// - startTime: 开始时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss)
  628 + /// - endTime: 结束时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss)
  629 + /// - md: 门店ID(可选)
  630 + /// - isEffective: 是否有效(可选,0=全部,1=有效,2=无效,默认1)
  631 + /// - currentPage: 当前页码(必填)
  632 + /// - pageSize: 每页数量(必填)
  633 + ///
  634 + /// 返回说明:
  635 + /// - 返回格式与GetList接口相同,包含耗卡基本信息及耗卡明细列表
  636 + /// </remarks>
  637 + /// <param name="input">查询参数</param>
  638 + /// <returns>耗卡列表(分页)</returns>
  639 + /// <response code="200">查询成功</response>
  640 + /// <response code="400">参数错误</response>
  641 + /// <response code="500">服务器内部错误</response>
  642 + [HttpGet("GetListByJksId")]
  643 + public async Task<dynamic> GetListByJksId([FromQuery] LqXhHyhkListByJksQueryInput input)
  644 + {
  645 + try
  646 + {
  647 + if (string.IsNullOrEmpty(input.jksId))
  648 + {
  649 + throw NCCException.Oh("健康师ID不能为空");
  650 + }
  651 +
  652 + var sidx = input.sidx == null ? "hksj" : input.sidx;
  653 + var sort = string.IsNullOrEmpty(input.sort) ? "DESC" : input.sort;
  654 +
  655 + // 解析时间范围
  656 + DateTime? startDate = null;
  657 + DateTime? endDate = null;
  658 + if (!string.IsNullOrEmpty(input.startTime))
  659 + {
  660 + startDate = Ext.GetDateTime(input.startTime);
  661 + }
  662 + if (!string.IsNullOrEmpty(input.endTime))
  663 + {
  664 + endDate = Ext.GetDateTime(input.endTime);
  665 + // 如果只传了日期,则设置为当天的23:59:59
  666 + if (endDate.HasValue && !input.endTime.Contains(":"))
  667 + {
  668 + endDate = new DateTime(endDate.Value.Year, endDate.Value.Month, endDate.Value.Day, 23, 59, 59);
  669 + }
  670 + }
  671 +
  672 + // 通过健康师业绩表关联查询耗卡记录
  673 + var data = await _db.Queryable<LqXhJksyjEntity, LqXhHyhkEntity>(
  674 + (jksyj, hyhk) => jksyj.Glkdbh == hyhk.Id)
  675 + .Where((jksyj, hyhk) => jksyj.Jkszh == input.jksId)
  676 + .WhereIF(input.isEffective != 0, (jksyj, hyhk) => jksyj.IsEffective == input.isEffective && hyhk.IsEffective == input.isEffective)
  677 + .WhereIF(input.isEffective == 0, (jksyj, hyhk) => jksyj.IsEffective == StatusEnum.有效.GetHashCode() && hyhk.IsEffective == StatusEnum.有效.GetHashCode())
  678 + .WhereIF(startDate.HasValue, (jksyj, hyhk) => hyhk.Hksj >= startDate.Value)
  679 + .WhereIF(endDate.HasValue, (jksyj, hyhk) => hyhk.Hksj <= endDate.Value)
  680 + .WhereIF(!string.IsNullOrEmpty(input.md), (jksyj, hyhk) => hyhk.Md == input.md)
  681 + .Select((jksyj, hyhk) => new LqXhHyhkListOutput
  682 + {
  683 + id = hyhk.Id,
  684 + md = hyhk.Md,
  685 + mdbh = hyhk.Mdbh,
  686 + mdmc = hyhk.Mdmc,
  687 + hy = hyhk.Hy,
  688 + hyzh = hyhk.Hyzh,
  689 + hymc = SqlFunc.Subqueryable<LqKhxxEntity>().Where(w => w.Id == hyhk.Hy).Select(w => w.Khmc),
  690 + gklx = hyhk.Gklx,
  691 + xfje = SqlFunc.ToString(hyhk.Xfje),
  692 + sgfy = SqlFunc.ToString(hyhk.Sgfy),
  693 + sfykjb = hyhk.Sfykjb,
  694 + hksj = hyhk.Hksj,
  695 + czry = hyhk.Czry,
  696 + memberPhone = SqlFunc.Subqueryable<LqKhxxEntity>().Where(w => w.Id == hyhk.Hy).Select(w => w.Sjh),
  697 + isEffective = hyhk.IsEffective,
  698 + signatureFile = hyhk.SignatureFile,
  699 + overtimeCoefficient = hyhk.OvertimeCoefficient,
  700 + originalSgfy = hyhk.OriginalSgfy,
  701 + overtimeSgfy = hyhk.OvertimeSgfy,
  702 + })
  703 + .MergeTable()
  704 + .Distinct() // 去重,因为一个耗卡可能对应多个健康师业绩记录
  705 + .OrderBy($"{sidx} {sort}")
  706 + .ToPagedListAsync(input.currentPage, input.pageSize);
  707 +
  708 + // 获取当前页的耗卡记录ID列表
  709 + var consumeIds = data.list.Select(x => x.id).ToList();
  710 +
  711 + // 批量查询耗卡明细
  712 + var consumeDetails = new List<LqXhPxmxInfoOutput>();
  713 + if (consumeIds.Any())
  714 + {
  715 + consumeDetails = await _db.Queryable<LqXhPxmxEntity>()
  716 + .Where(x => consumeIds.Contains(x.ConsumeInfoId) && x.IsEffective == StatusEnum.有效.GetHashCode())
  717 + .Select(x => new LqXhPxmxInfoOutput
  718 + {
  719 + id = x.Id,
  720 + consumeInfoId = x.ConsumeInfoId,
  721 + billingItemId = x.BillingItemId,
  722 + px = x.Px,
  723 + pxmc = x.Pxmc,
  724 + pxjg = x.Pxjg,
  725 + memberId = x.MemberId,
  726 + createTime = x.CreateTIme,
  727 + projectNumber = x.ProjectNumber,
  728 + originalProjectNumber = x.OriginalProjectNumber,
  729 + overtimeProjectNumber = x.OvertimeProjectNumber,
  730 + sourceType = x.SourceType,
  731 + totalPrice = x.TotalPrice,
  732 + isEffective = x.IsEffective,
  733 + })
  734 + .ToListAsync();
  735 + }
  736 +
  737 + // 按耗卡记录ID分组耗卡明细
  738 + var consumeDetailsGrouped = consumeDetails.GroupBy(x => x.consumeInfoId)
  739 + .ToDictionary(g => g.Key, g => g.ToList());
  740 +
  741 + // 为每个耗卡记录分配耗卡明细
  742 + foreach (var item in data.list)
  743 + {
  744 + item.ConsumeDetails = consumeDetailsGrouped.ContainsKey(item.id)
  745 + ? consumeDetailsGrouped[item.id]
  746 + : new List<LqXhPxmxInfoOutput>();
  747 + }
  748 +
  749 + return PageResult<LqXhHyhkListOutput>.SqlSugarPageResult(data);
  750 + }
  751 + catch (Exception ex)
  752 + {
  753 + _logger.LogError(ex, $"根据健康师ID获取耗卡列表失败 - 健康师ID: {input?.jksId}, 开始时间: {input?.startTime}, 结束时间: {input?.endTime}");
  754 + throw NCCException.Oh($"根据健康师ID获取耗卡列表失败: {ex.Message}");
  755 + }
  756 + }
  757 + #endregion
  758 +
  759 + #region 根据科技部老师ID获取耗卡列表
  760 + /// <summary>
  761 + /// 根据科技部老师ID获取耗卡列表
  762 + /// </summary>
  763 + /// <remarks>
  764 + /// 根据科技部老师ID查询该老师参与的所有耗卡记录,支持时间周期查询和分页
  765 + ///
  766 + /// 示例请求:
  767 + /// GET /api/Extend/LqXhHyhk/GetListByKjbId?kjblsId=科技部老师ID&amp;startTime=2025-01-01&amp;endTime=2025-01-31&amp;currentPage=1&amp;pageSize=10
  768 + ///
  769 + /// 参数说明:
  770 + /// - kjblsId: 科技部老师ID(必填)
  771 + /// - startTime: 开始时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss)
  772 + /// - endTime: 结束时间(可选,格式:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss)
  773 + /// - md: 门店ID(可选)
  774 + /// - isEffective: 是否有效(可选,0=全部,1=有效,2=无效,默认1)
  775 + /// - currentPage: 当前页码(必填)
  776 + /// - pageSize: 每页数量(必填)
  777 + ///
  778 + /// 返回说明:
  779 + /// - 返回格式与GetList接口相同,包含耗卡基本信息及耗卡明细列表
  780 + /// </remarks>
  781 + /// <param name="input">查询参数</param>
  782 + /// <returns>耗卡列表(分页)</returns>
  783 + /// <response code="200">查询成功</response>
  784 + /// <response code="400">参数错误</response>
  785 + /// <response code="500">服务器内部错误</response>
  786 + [HttpGet("GetListByKjbId")]
  787 + public async Task<dynamic> GetListByKjbId([FromQuery] LqXhHyhkListByKjbQueryInput input)
  788 + {
  789 + try
  790 + {
  791 + if (string.IsNullOrEmpty(input.kjblsId))
  792 + {
  793 + throw NCCException.Oh("科技部老师ID不能为空");
  794 + }
  795 +
  796 + var sidx = input.sidx == null ? "hksj" : input.sidx;
  797 + var sort = string.IsNullOrEmpty(input.sort) ? "DESC" : input.sort;
  798 +
  799 + // 解析时间范围
  800 + DateTime? startDate = null;
  801 + DateTime? endDate = null;
  802 + if (!string.IsNullOrEmpty(input.startTime))
  803 + {
  804 + startDate = Ext.GetDateTime(input.startTime);
  805 + }
  806 + if (!string.IsNullOrEmpty(input.endTime))
  807 + {
  808 + endDate = Ext.GetDateTime(input.endTime);
  809 + // 如果只传了日期,则设置为当天的23:59:59
  810 + if (endDate.HasValue && !input.endTime.Contains(":"))
  811 + {
  812 + endDate = new DateTime(endDate.Value.Year, endDate.Value.Month, endDate.Value.Day, 23, 59, 59);
  813 + }
  814 + }
  815 +
  816 + // 通过科技部老师业绩表关联查询耗卡记录
  817 + var data = await _db.Queryable<LqXhKjbsyjEntity, LqXhHyhkEntity>(
  818 + (kjbsyj, hyhk) => kjbsyj.Glkdbh == hyhk.Id)
  819 + .Where((kjbsyj, hyhk) => kjbsyj.Kjblszh == input.kjblsId)
  820 + .WhereIF(input.isEffective != 0, (kjbsyj, hyhk) => kjbsyj.IsEffective == input.isEffective && hyhk.IsEffective == input.isEffective)
  821 + .WhereIF(input.isEffective == 0, (kjbsyj, hyhk) => kjbsyj.IsEffective == StatusEnum.有效.GetHashCode() && hyhk.IsEffective == StatusEnum.有效.GetHashCode())
  822 + .WhereIF(startDate.HasValue, (kjbsyj, hyhk) => hyhk.Hksj >= startDate.Value)
  823 + .WhereIF(endDate.HasValue, (kjbsyj, hyhk) => hyhk.Hksj <= endDate.Value)
  824 + .WhereIF(!string.IsNullOrEmpty(input.md), (kjbsyj, hyhk) => hyhk.Md == input.md)
  825 + .Select((kjbsyj, hyhk) => new LqXhHyhkListOutput
  826 + {
  827 + id = hyhk.Id,
  828 + md = hyhk.Md,
  829 + mdbh = hyhk.Mdbh,
  830 + mdmc = hyhk.Mdmc,
  831 + hy = hyhk.Hy,
  832 + hyzh = hyhk.Hyzh,
  833 + hymc = SqlFunc.Subqueryable<LqKhxxEntity>().Where(w => w.Id == hyhk.Hy).Select(w => w.Khmc),
  834 + gklx = hyhk.Gklx,
  835 + xfje = SqlFunc.ToString(hyhk.Xfje),
  836 + sgfy = SqlFunc.ToString(hyhk.Sgfy),
  837 + sfykjb = hyhk.Sfykjb,
  838 + hksj = hyhk.Hksj,
  839 + czry = hyhk.Czry,
  840 + memberPhone = SqlFunc.Subqueryable<LqKhxxEntity>().Where(w => w.Id == hyhk.Hy).Select(w => w.Sjh),
  841 + isEffective = hyhk.IsEffective,
  842 + signatureFile = hyhk.SignatureFile,
  843 + overtimeCoefficient = hyhk.OvertimeCoefficient,
  844 + originalSgfy = hyhk.OriginalSgfy,
  845 + overtimeSgfy = hyhk.OvertimeSgfy,
  846 + })
  847 + .MergeTable()
  848 + .Distinct() // 去重,因为一个耗卡可能对应多个科技部老师业绩记录
  849 + .OrderBy($"{sidx} {sort}")
  850 + .ToPagedListAsync(input.currentPage, input.pageSize);
  851 +
  852 + // 获取当前页的耗卡记录ID列表
  853 + var consumeIds = data.list.Select(x => x.id).ToList();
  854 +
  855 + // 批量查询耗卡明细
  856 + var consumeDetails = new List<LqXhPxmxInfoOutput>();
  857 + if (consumeIds.Any())
  858 + {
  859 + consumeDetails = await _db.Queryable<LqXhPxmxEntity>()
  860 + .Where(x => consumeIds.Contains(x.ConsumeInfoId) && x.IsEffective == StatusEnum.有效.GetHashCode())
  861 + .Select(x => new LqXhPxmxInfoOutput
  862 + {
  863 + id = x.Id,
  864 + consumeInfoId = x.ConsumeInfoId,
  865 + billingItemId = x.BillingItemId,
  866 + px = x.Px,
  867 + pxmc = x.Pxmc,
  868 + pxjg = x.Pxjg,
  869 + memberId = x.MemberId,
  870 + createTime = x.CreateTIme,
  871 + projectNumber = x.ProjectNumber,
  872 + originalProjectNumber = x.OriginalProjectNumber,
  873 + overtimeProjectNumber = x.OvertimeProjectNumber,
  874 + sourceType = x.SourceType,
  875 + totalPrice = x.TotalPrice,
  876 + isEffective = x.IsEffective,
  877 + })
  878 + .ToListAsync();
  879 + }
  880 +
  881 + // 按耗卡记录ID分组耗卡明细
  882 + var consumeDetailsGrouped = consumeDetails.GroupBy(x => x.consumeInfoId)
  883 + .ToDictionary(g => g.Key, g => g.ToList());
  884 +
  885 + // 为每个耗卡记录分配耗卡明细
  886 + foreach (var item in data.list)
  887 + {
  888 + item.ConsumeDetails = consumeDetailsGrouped.ContainsKey(item.id)
  889 + ? consumeDetailsGrouped[item.id]
  890 + : new List<LqXhPxmxInfoOutput>();
  891 + }
  892 +
  893 + return PageResult<LqXhHyhkListOutput>.SqlSugarPageResult(data);
  894 + }
  895 + catch (Exception ex)
  896 + {
  897 + _logger.LogError(ex, $"根据科技部老师ID获取耗卡列表失败 - 科技部老师ID: {input?.kjblsId}, 开始时间: {input?.startTime}, 结束时间: {input?.endTime}");
  898 + throw NCCException.Oh($"根据科技部老师ID获取耗卡列表失败: {ex.Message}");
  899 + }
  900 + }
  901 + #endregion
  902 +
266 903 #region 新建会员耗卡
267 904 /// <summary>
268 905 /// 新建会员耗卡
... ...
netcore/src/Modularity/Extend/NCC.Extend/Utils/WeChatBotService.cs
... ... @@ -17,7 +17,7 @@ namespace NCC.Extend.Utils
17 17 //https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=581c22a6-cb67-42e5-8c76-b8e90052e188
18 18 //测试地址
19 19 //https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=6f8686ec-5011-4c1d-bae9-d82a2a2f4d83
20   - private const string WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=581c22a6-cb67-42e5-8c76-b8e90052e188";
  20 + private const string WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=496f1add-122b-43fc-9e38-0ca79c48b33f";
21 21 private const string WEBHOOK_URL_TEST = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=6f8686ec-5011-4c1d-bae9-d82a2a2f4d83";
22 22  
23 23 public WeChatBotService(HttpClient httpClient)
... ... @@ -37,6 +37,7 @@ namespace NCC.Extend.Utils
37 37 var requestData = new
38 38 {
39 39 webhookUrl = WEBHOOK_URL,
  40 + // webhookUrl = WEBHOOK_URL_TEST,
40 41 content = content,
41 42 mentionedList = (string)null,
42 43 mentionedMobileList = (string)null,
... ...