Commit a78c0ae8c55c3de6aee30ea290908ab4154f4409

Authored by “wangming”
1 parent 5e629136

feat: 退卡服务添加健康师和科技部老师筛选功能,返回品项明细和业绩数据;开单服务添加健康师和科技部老师筛选及业绩返回;科技部老师统计添加手工费统计;修复Ge…

…tTechTeacherStatistics方法错误;WeChatBot配置化
netcore/src/Application/NCC.API/appsettings.json
... ... @@ -181,6 +181,11 @@
181 181 "scope": "snsapi_userinfo"
182 182 }
183 183 },
  184 + "WeChatBot": {
  185 + "BotApiUrl": "http://wx.lvqianmeiye.com/api/Bot/send-text",
  186 + "WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=496f1add-122b-43fc-9e38-0ca79c48b33f",
  187 + "WebhookUrlTest": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=6f8686ec-5011-4c1d-bae9-d82a2a2f4d83"
  188 + },
184 189 "NCC_App": {
185 190 "CodeAreasName": "SubDev,Food,Extend,test",
186 191 //系统文件路径(末尾必须带斜杆)
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqHytkHytk/LqHytkHytkListOutput.cs
1 1 using System;
  2 +using System.Collections.Generic;
  3 +using NCC.Extend.Entitys.Dto.LqHytkMx;
  4 +using NCC.Extend.Entitys.Dto.LqHytkJksyj;
  5 +using NCC.Extend.Entitys.Dto.LqHytkKjbsyj;
2 6  
3 7 namespace NCC.Extend.Entitys.Dto.LqHytkHytk
4 8 {
... ... @@ -102,5 +106,19 @@ namespace NCC.Extend.Entitys.Dto.LqHytkHytk
102 106 /// </summary>
103 107 public string cancelRemark { get; set; }
104 108  
  109 + /// <summary>
  110 + /// 退卡品项明细列表
  111 + /// </summary>
  112 + public List<LqHytkMxInfoOutput> lqHytkMxList { get; set; }
  113 +
  114 + /// <summary>
  115 + /// 健康师业绩列表
  116 + /// </summary>
  117 + public List<LqHytkJksyjInfoOutput> lqHytkJksyjList { get; set; }
  118 +
  119 + /// <summary>
  120 + /// 科技部老师业绩列表
  121 + /// </summary>
  122 + public List<LqHytkKjbsyjInfoOutput> lqHytkKjbsyjList { get; set; }
105 123 }
106 124 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqHytkHytk/LqHytkHytkListQueryInput.cs
... ... @@ -93,5 +93,14 @@ namespace NCC.Extend.Entitys.Dto.LqHytkHytk
93 93 /// </summary>
94 94 public int isEffective { get; set; } = 0;
95 95  
  96 + /// <summary>
  97 + /// 健康师ID(可选,传入后只返回该健康师参与的退卡记录)
  98 + /// </summary>
  99 + public string jksId { get; set; }
  100 +
  101 + /// <summary>
  102 + /// 科技部老师ID(可选,传入后只返回该老师参与的退卡记录)
  103 + /// </summary>
  104 + public string kjblsId { get; set; }
96 105 }
97 106 }
98 107 \ No newline at end of file
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/TechTeacherSimpleStatisticsOutput.cs
... ... @@ -41,5 +41,10 @@ namespace NCC.Extend.Entitys.Dto.LqStatistics
41 41 /// 耗卡品项次数
42 42 /// </summary>
43 43 public int ConsumeItemCount { get; set; }
  44 +
  45 + /// <summary>
  46 + /// 消耗手工费(耗卡手工费)
  47 + /// </summary>
  48 + public decimal ConsumeLaborCost { get; set; }
44 49 }
45 50 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXhHyhk/MemberRemainingItemsOutput.cs
... ... @@ -25,6 +25,7 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk
25 25 public string MemberName { get; set; }
26 26  
27 27 /// <summary>
  28 + /// <summary>
28 29 /// 剩余品项列表
29 30 /// </summary>
30 31 /// <remarks>按剩余数量降序排列的品项列表</remarks>
... ... @@ -71,6 +72,12 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk
71 72 public string SourceType { get; set; }
72 73  
73 74 /// <summary>
  75 + /// 备注
  76 + /// </summary>
  77 + /// <example>备注</example>
  78 + public string Remark { get; set; }
  79 +
  80 + /// <summary>
74 81 /// 总购买数量
75 82 /// </summary>
76 83 /// <remarks>该品项的总购买次数</remarks>
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqHytkHytkService.cs
... ... @@ -70,8 +70,35 @@ namespace NCC.Extend.LqHytkHytk
70 70 /// <summary>
71 71 /// 获取退卡信息列表
72 72 /// </summary>
  73 + /// <remarks>
  74 + /// 获取退卡记录列表,支持根据健康师ID或科技部老师ID筛选,返回品项明细、健康师业绩和科技部老师业绩
  75 + ///
  76 + /// 示例请求:
  77 + /// ```json
  78 + /// GET /api/Extend/LqHytkHytk?jksId=健康师ID&amp;kjblsId=科技部老师ID&amp;currentPage=1&amp;pageSize=10
  79 + /// ```
  80 + ///
  81 + /// 参数说明:
  82 + /// - jksId: 健康师ID(可选,传入后只返回该健康师参与的退卡记录)
  83 + /// - kjblsId: 科技部老师ID(可选,传入后只返回该老师参与的退卡记录)
  84 + /// - id: 退卡编号(可选)
  85 + /// - md: 门店ID(可选)
  86 + /// - hy: 会员ID(可选)
  87 + /// - tksj: 退卡时间(可选,格式:yyyy-MM-dd,yyyy-MM-dd)
  88 + /// - currentPage: 当前页码(必填)
  89 + /// - pageSize: 每页数量(必填)
  90 + ///
  91 + /// 返回数据说明:
  92 + /// - 退卡基本信息:id、门店信息、会员信息、退卡金额、退卡时间等
  93 + /// - lqHytkMxList: 退卡品项明细列表,每个明细包含品项信息、退款金额、项目次数等
  94 + /// - lqHytkJksyjList: 健康师业绩列表,每个业绩包含健康师信息、业绩金额、手工费、退卡品项次数等
  95 + /// - lqHytkKjbsyjList: 科技部老师业绩列表,每个业绩包含科技部老师信息、业绩金额、手工费、退卡品项次数等
  96 + /// </remarks>
73 97 /// <param name="input">查询参数</param>
74   - /// <returns></returns>
  98 + /// <returns>分页的退卡记录列表,包含退卡基本信息、品项明细、健康师业绩、科技部老师业绩</returns>
  99 + /// <response code="200">成功返回退卡列表</response>
  100 + /// <response code="400">参数错误</response>
  101 + /// <response code="500">服务器内部错误</response>
75 102 [HttpGet("")]
76 103 public async Task<dynamic> GetList([FromQuery] LqHytkHytkListQueryInput input)
77 104 {
... ... @@ -79,7 +106,48 @@ namespace NCC.Extend.LqHytkHytk
79 106 List<string> queryTksj = input.tksj != null ? input.tksj.Split(',').ToObeject<List<string>>() : null;
80 107 DateTime? startTksj = queryTksj != null ? Ext.GetDateTime(queryTksj.First()) : null;
81 108 DateTime? endTksj = queryTksj != null ? Ext.GetDateTime(queryTksj.Last()) : null;
82   - var data = await _db.Queryable<LqHytkHytkEntity>()
  109 +
  110 + // 根据是否传入健康师ID或科技部老师ID,动态构建查询
  111 + ISugarQueryable<LqHytkHytkEntity> baseQuery = null;
  112 +
  113 + if (!string.IsNullOrEmpty(input.jksId) && !string.IsNullOrEmpty(input.kjblsId))
  114 + {
  115 + // 同时传入健康师ID和科技部老师ID,需要同时关联两个业绩表(不过滤有效性)
  116 + baseQuery = _db.Queryable<LqHytkJksyjEntity, LqHytkKjbsyjEntity, LqHytkHytkEntity>(
  117 + (jksyj, kjbsyj, hytk) => jksyj.Gltkbh == hytk.Id && kjbsyj.Gltkbh == hytk.Id)
  118 + .Where((jksyj, kjbsyj, hytk) => jksyj.Jkszh == input.jksId)
  119 + .Where((jksyj, kjbsyj, hytk) => kjbsyj.Kjblszh == input.kjblsId)
  120 + .Select((jksyj, kjbsyj, hytk) => hytk)
  121 + .Distinct()
  122 + .MergeTable();
  123 + }
  124 + else if (!string.IsNullOrEmpty(input.jksId))
  125 + {
  126 + // 只传入健康师ID,关联健康师业绩表(不过滤有效性)
  127 + baseQuery = _db.Queryable<LqHytkJksyjEntity, LqHytkHytkEntity>(
  128 + (jksyj, hytk) => jksyj.Gltkbh == hytk.Id)
  129 + .Where((jksyj, hytk) => jksyj.Jkszh == input.jksId)
  130 + .Select((jksyj, hytk) => hytk)
  131 + .Distinct()
  132 + .MergeTable();
  133 + }
  134 + else if (!string.IsNullOrEmpty(input.kjblsId))
  135 + {
  136 + // 只传入科技部老师ID,关联科技部老师业绩表(不过滤有效性)
  137 + baseQuery = _db.Queryable<LqHytkKjbsyjEntity, LqHytkHytkEntity>(
  138 + (kjbsyj, hytk) => kjbsyj.Gltkbh == hytk.Id)
  139 + .Where((kjbsyj, hytk) => kjbsyj.Kjblszh == input.kjblsId)
  140 + .Select((kjbsyj, hytk) => hytk)
  141 + .Distinct()
  142 + .MergeTable();
  143 + }
  144 + else
  145 + {
  146 + // 没有传入健康师ID或科技部老师ID,使用原来的查询逻辑
  147 + baseQuery = _db.Queryable<LqHytkHytkEntity>();
  148 + }
  149 +
  150 + var data = await baseQuery
83 151 .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id))
84 152 .WhereIF(!string.IsNullOrEmpty(input.md), p => p.Md.Equals(input.md))
85 153 .WhereIF(!string.IsNullOrEmpty(input.mdbh), p => p.Mdbh.Contains(input.mdbh))
... ... @@ -123,6 +191,104 @@ namespace NCC.Extend.LqHytkHytk
123 191 .MergeTable()
124 192 .OrderBy(sidx + " " + input.sort)
125 193 .ToPagedListAsync(input.currentPage, input.pageSize);
  194 +
  195 + // 获取当前页的退卡记录ID列表
  196 + var refundIds = data.list.Select(x => x.id).ToList();
  197 +
  198 + // 批量查询品项明细(不过滤有效性,返回所有记录)
  199 + var itemDetails = new List<LqHytkMxInfoOutput>();
  200 + if (refundIds.Any())
  201 + {
  202 + itemDetails = await _db.Queryable<LqHytkMxEntity>()
  203 + .Where(x => refundIds.Contains(x.RefundInfoId))
  204 + .Select(x => new LqHytkMxInfoOutput
  205 + {
  206 + id = x.Id,
  207 + refundInfoId = x.RefundInfoId,
  208 + billingItemId = x.BillingItemId,
  209 + px = x.Px,
  210 + pxmc = x.Pxmc,
  211 + pxjg = x.Pxjg,
  212 + tkje = x.Tkje,
  213 + projectNumber = x.ProjectNumber,
  214 + isEffective = x.IsEffective,
  215 + sourceType = x.SourceType,
  216 + totalPrice = x.TotalPrice
  217 + })
  218 + .ToListAsync();
  219 + }
  220 +
  221 + // 批量查询健康师业绩(性能优化:一次性查询所有退卡的健康师业绩,不过滤有效性)
  222 + var jksyjList = new List<LqHytkJksyjInfoOutput>();
  223 + if (refundIds.Any())
  224 + {
  225 + jksyjList = await _db.Queryable<LqHytkJksyjEntity>()
  226 + .Where(x => refundIds.Contains(x.Gltkbh))
  227 + .Select(x => new LqHytkJksyjInfoOutput
  228 + {
  229 + id = x.Id,
  230 + gltkbh = x.Gltkbh,
  231 + jks = x.Jks,
  232 + jksxm = x.Jksxm,
  233 + jkszh = x.Jkszh,
  234 + jksyj = x.Jksyj,
  235 + tksj = x.Tksj,
  236 + F_jsjid = x.F_jsjid,
  237 + F_tkpxid = x.F_tkpxid,
  238 + F_LaborCost = x.F_LaborCost,
  239 + F_tkpxNumber = x.F_tkpxNumber
  240 + })
  241 + .ToListAsync();
  242 + }
  243 +
  244 + // 批量查询科技部老师业绩(性能优化:一次性查询所有退卡的科技部老师业绩,不过滤有效性)
  245 + var kjbsyjList = new List<LqHytkKjbsyjInfoOutput>();
  246 + if (refundIds.Any())
  247 + {
  248 + kjbsyjList = await _db.Queryable<LqHytkKjbsyjEntity>()
  249 + .Where(x => refundIds.Contains(x.Gltkbh))
  250 + .Select(x => new LqHytkKjbsyjInfoOutput
  251 + {
  252 + id = x.Id,
  253 + gltkbh = x.Gltkbh,
  254 + kjbls = x.Kjbls,
  255 + kjblsxm = x.Kjblsxm,
  256 + kjblszh = x.Kjblszh,
  257 + kjblsyj = x.Kjblsyj,
  258 + tksj = x.Tksj,
  259 + F_tkpxid = x.F_tkpxid,
  260 + F_LaborCost = x.F_LaborCost,
  261 + F_tkpxNumber = x.F_tkpxNumber
  262 + })
  263 + .ToListAsync();
  264 + }
  265 +
  266 + // 按退卡ID分组品项明细
  267 + var itemDetailsGrouped = itemDetails.GroupBy(x => x.refundInfoId)
  268 + .ToDictionary(g => g.Key, g => g.ToList());
  269 +
  270 + // 按退卡ID分组健康师业绩
  271 + var jksyjGrouped = jksyjList.GroupBy(x => x.gltkbh)
  272 + .ToDictionary(g => g.Key, g => g.ToList());
  273 +
  274 + // 按退卡ID分组科技部老师业绩
  275 + var kjbsyjGrouped = kjbsyjList.GroupBy(x => x.gltkbh)
  276 + .ToDictionary(g => g.Key, g => g.ToList());
  277 +
  278 + // 为每个退卡记录分配品项明细、健康师业绩和科技部老师业绩
  279 + foreach (var item in data.list)
  280 + {
  281 + item.lqHytkMxList = itemDetailsGrouped.ContainsKey(item.id)
  282 + ? itemDetailsGrouped[item.id]
  283 + : new List<LqHytkMxInfoOutput>();
  284 + item.lqHytkJksyjList = jksyjGrouped.ContainsKey(item.id)
  285 + ? jksyjGrouped[item.id]
  286 + : new List<LqHytkJksyjInfoOutput>();
  287 + item.lqHytkKjbsyjList = kjbsyjGrouped.ContainsKey(item.id)
  288 + ? kjbsyjGrouped[item.id]
  289 + : new List<LqHytkKjbsyjInfoOutput>();
  290 + }
  291 +
126 292 return PageResult<LqHytkHytkListOutput>.SqlSugarPageResult(data);
127 293 }
128 294 #endregion
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs
... ... @@ -454,10 +454,8 @@ namespace NCC.Extend.LqKdKdjlb
454 454 {
455 455 throw NCCException.Oh("健康师ID不能为空");
456 456 }
457   -
458 457 var sidx = input.sidx == null ? "kdrq" : input.sidx;
459 458 var sort = string.IsNullOrEmpty(input.sort) ? "DESC" : input.sort;
460   -
461 459 // 解析时间范围
462 460 DateTime? startDate = null;
463 461 DateTime? endDate = null;
... ... @@ -476,8 +474,7 @@ namespace NCC.Extend.LqKdKdjlb
476 474 }
477 475  
478 476 // 通过健康师业绩表关联查询开单记录
479   - var data = await _db.Queryable<LqKdJksyjEntity, LqKdKdjlbEntity>(
480   - (jksyj, kdjlb) => jksyj.Glkdbh == kdjlb.Id)
  477 + var data = await _db.Queryable<LqKdJksyjEntity, LqKdKdjlbEntity>((jksyj, kdjlb) => jksyj.Glkdbh == kdjlb.Id)
481 478 .Where((jksyj, kdjlb) => jksyj.Jkszh == input.jksId)
482 479 .WhereIF(input.isEffective != 0, (jksyj, kdjlb) => jksyj.IsEffective == input.isEffective && kdjlb.IsEffective == input.isEffective)
483 480 .WhereIF(input.isEffective == 0, (jksyj, kdjlb) => jksyj.IsEffective == StatusEnum.有效.GetHashCode() && kdjlb.IsEffective == StatusEnum.有效.GetHashCode())
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqKhxxService.cs
... ... @@ -551,7 +551,8 @@ namespace NCC.Extend.LqKhxx
551 551 x.Pxmc,
552 552 x.Pxjg,
553 553 x.SourceType,
554   - x.ProjectNumber
  554 + x.ProjectNumber,
  555 + x.Remark
555 556 })
556 557 .ToListAsync();
557 558  
... ... @@ -600,6 +601,7 @@ namespace NCC.Extend.LqKhxx
600 601 ItemPrice = item.Pxjg,
601 602 SourceType = item.SourceType,
602 603 TotalPurchased = item.ProjectNumber,
  604 + Remark = item.Remark,
603 605 ConsumedCount = consumedData.FirstOrDefault(c => c.BillingItemId == item.Id)?.TotalConsumed ?? 0,
604 606 RefundedCount = refundedData.FirstOrDefault(r => r.BillingItemId == item.Id)?.TotalRefunded ?? 0,
605 607 DeductCount = deductData.FirstOrDefault(d => d.BillingItemId == item.Id)?.TotalDeduct ?? 0,
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs
... ... @@ -831,8 +831,40 @@ namespace NCC.Extend.LqStatistics
831 831 /// <summary>
832 832 /// 获取科技部老师业绩统计
833 833 /// </summary>
  834 + /// <remarks>
  835 + /// 统计科技部老师的开单业绩、消耗业绩、手工费等相关数据
  836 + ///
  837 + /// 示例请求:
  838 + /// ```json
  839 + /// {
  840 + /// "startDate": "2025-01-01T00:00:00",
  841 + /// "endDate": "2025-01-31T23:59:59",
  842 + /// "teacherId": "科技部老师ID(可选)",
  843 + /// "teacherName": "科技部老师姓名(可选)"
  844 + /// }
  845 + /// ```
  846 + ///
  847 + /// 参数说明:
  848 + /// - startDate: 开始日期(可选)
  849 + /// - endDate: 结束日期(可选)
  850 + /// - teacherId: 科技部老师ID(可选)
  851 + /// - teacherName: 科技部老师姓名(可选)
  852 + ///
  853 + /// 返回数据说明:
  854 + /// - DepartmentName: 部门名称(固定为"科技部")
  855 + /// - TeacherName: 老师姓名
  856 + /// - ConsumeProjectCount: 消耗项目数
  857 + /// - ConsumeAchievement: 消耗业绩
  858 + /// - OrderAchievement: 开单业绩(开卡业绩)
  859 + /// - OrderItemCount: 开单品项次数
  860 + /// - ConsumeItemCount: 耗卡品项次数
  861 + /// - ConsumeLaborCost: 消耗手工费(耗卡手工费)
  862 + /// </remarks>
834 863 /// <param name="input">查询参数</param>
835   - /// <returns>科技部老师业绩统计结果</returns>
  864 + /// <returns>科技部老师业绩统计结果列表,包含开单业绩、消耗业绩、手工费等数据</returns>
  865 + /// <response code="200">成功返回统计数据</response>
  866 + /// <response code="400">参数错误</response>
  867 + /// <response code="500">服务器内部错误</response>
836 868 [HttpPost("GetTechTeacherStatistics")]
837 869 [AllowAnonymous]
838 870 public async Task<List<TechTeacherSimpleStatisticsOutput>> GetTechTeacherStatistics(TechTeacherStatisticsInput input)
... ... @@ -852,10 +884,21 @@ namespace NCC.Extend.LqStatistics
852 884 // 2. 获取业绩流水数据
853 885 var flowQuery = _db.Queryable<VTechTeacherFlowEntity>();
854 886  
855   - // 老师过滤
  887 + // 老师过滤(支持通过ID或账号匹配)
856 888 if (!string.IsNullOrEmpty(input.TeacherId))
857 889 {
858   - flowQuery = flowQuery.Where(x => x.TeacherId == input.TeacherId);
  890 + // 先通过用户ID查询账号,然后同时匹配ID和账号
  891 + var teacherAccount = allTeachers.FirstOrDefault(t => t.TeacherId == input.TeacherId)?.TeacherAccount;
  892 + if (!string.IsNullOrEmpty(teacherAccount))
  893 + {
  894 + // 同时匹配ID和账号(因为视图中的teacher_id可能是ID或账号)
  895 + flowQuery = flowQuery.Where(x => x.TeacherId == input.TeacherId || x.TeacherAccount == teacherAccount);
  896 + }
  897 + else
  898 + {
  899 + // 如果找不到账号,只匹配ID
  900 + flowQuery = flowQuery.Where(x => x.TeacherId == input.TeacherId);
  901 + }
859 902 }
860 903  
861 904 if (!string.IsNullOrEmpty(input.TeacherName))
... ... @@ -876,23 +919,25 @@ namespace NCC.Extend.LqStatistics
876 919  
877 920 var flowRecords = await flowQuery.ToListAsync();
878 921  
879   - // 3. 按老师分组统计业绩数据
  922 + // 3. 按老师账号分组统计业绩数据(包括耗卡手工费)
  923 + // 注意:视图中的teacher_id是kjbls,teacher_account是kjblszh,使用账号来匹配更准确
880 924 var teacherStatsDict = flowRecords
881 925 .GroupBy(x => new
882 926 {
883   - x.TeacherId,
884   - x.TeacherName,
885   - x.TeacherAccount,
  927 + TeacherAccount = x.TeacherAccount ?? string.Empty,
  928 + TeacherId = x.TeacherId ?? string.Empty,
  929 + TeacherName = x.TeacherName ?? string.Empty,
886 930 })
887 931 .ToDictionary(
888   - g => g.Key,
  932 + g => g.Key.TeacherAccount ?? string.Empty,
889 933 g => new
890 934 {
891   - ConsumeProjectCount = (int)g.Where(x => x.BusinessType == "耗卡").Sum(x => x.ProjectCount),
  935 + ConsumeProjectCount = (int)(g.Where(x => x.BusinessType == "耗卡").Sum(x => x.ProjectCount)),
892 936 ConsumeAchievement = g.Where(x => x.BusinessType == "耗卡").Sum(x => x.Achievement),
893 937 OrderAchievement = g.Where(x => x.BusinessType == "开卡").Sum(x => x.Achievement),
894 938 OrderItemCount = g.Where(x => x.BusinessType == "开卡").Sum(x => x.ItemCount),
895 939 ConsumeItemCount = g.Where(x => x.BusinessType == "耗卡").Sum(x => x.ItemCount),
  940 + ConsumeLaborCost = g.Where(x => x.BusinessType == "耗卡").Sum(x => x.LaborCost),
896 941 }
897 942 );
898 943  
... ... @@ -908,13 +953,10 @@ namespace NCC.Extend.LqStatistics
908 953 if (!string.IsNullOrEmpty(input.TeacherName) && !teacher.TeacherName.Contains(input.TeacherName))
909 954 continue;
910 955  
  956 + // 使用账号来匹配业绩数据(因为视图中的teacher_account是kjblszh)
  957 + var teacherAccount = teacher.TeacherAccount ?? string.Empty;
911 958 var stats = teacherStatsDict.GetValueOrDefault(
912   - new
913   - {
914   - TeacherId = teacher.TeacherId,
915   - TeacherName = teacher.TeacherName,
916   - TeacherAccount = teacher.TeacherAccount,
917   - },
  959 + teacherAccount,
918 960 new
919 961 {
920 962 ConsumeProjectCount = 0,
... ... @@ -922,6 +964,7 @@ namespace NCC.Extend.LqStatistics
922 964 OrderAchievement = 0m,
923 965 OrderItemCount = 0,
924 966 ConsumeItemCount = 0,
  967 + ConsumeLaborCost = 0m,
925 968 }
926 969 );
927 970  
... ... @@ -934,6 +977,7 @@ namespace NCC.Extend.LqStatistics
934 977 OrderAchievement = stats.OrderAchievement,
935 978 OrderItemCount = stats.OrderItemCount,
936 979 ConsumeItemCount = stats.ConsumeItemCount,
  980 + ConsumeLaborCost = stats.ConsumeLaborCost,
937 981 };
938 982  
939 983 result.Add(teacherStats);
... ... @@ -3672,6 +3716,5 @@ namespace NCC.Extend.LqStatistics
3672 3716 }
3673 3717  
3674 3718 #endregion
3675   -
3676 3719 }
3677 3720 }
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqXhHyhkService.cs
... ... @@ -1043,12 +1043,18 @@ namespace NCC.Extend.LqXhHyhk
1043 1043 Kjblsyj = ikjbs_tem.kjblsyj,
1044 1044 Yjsj = DateTime.Now,
1045 1045 Hkpxid = lqXhPxmxEntity.Id,
  1046 + // OriginalHdpxNumber = ikjbs_tem.hdpxNumber,
  1047 + // OvertimeHdpxNumber = (decimal)(entity.OvertimeCoefficient * (ikjbs_tem.hdpxNumber ?? 0)),
  1048 + // HdpxNumber = (decimal)((ikjbs_tem.hdpxNumber ?? 0) + (entity.OvertimeCoefficient * (ikjbs_tem.hdpxNumber ?? 0))),
1046 1049 OriginalHdpxNumber = ikjbs_tem.hdpxNumber,
1047   - OvertimeHdpxNumber = (decimal)(entity.OvertimeCoefficient * (ikjbs_tem.hdpxNumber ?? 0)),
1048   - HdpxNumber = (decimal)((ikjbs_tem.hdpxNumber ?? 0) + (entity.OvertimeCoefficient * (ikjbs_tem.hdpxNumber ?? 0))),
  1050 + OvertimeHdpxNumber = 0,
  1051 + HdpxNumber = ikjbs_tem.hdpxNumber,
  1052 + // OriginalLaborCost = ikjbs_tem.laborCost,
  1053 + // OvertimeLaborCost = (decimal)(entity.OvertimeCoefficient * (ikjbs_tem.laborCost ?? 0)),
  1054 + // LaborCost = (decimal)((ikjbs_tem.laborCost ?? 0) + (entity.OvertimeCoefficient * (ikjbs_tem.laborCost ?? 0))),
1049 1055 OriginalLaborCost = ikjbs_tem.laborCost,
1050   - OvertimeLaborCost = (decimal)(entity.OvertimeCoefficient * (ikjbs_tem.laborCost ?? 0)),
1051   - LaborCost = (decimal)((ikjbs_tem.laborCost ?? 0) + (entity.OvertimeCoefficient * (ikjbs_tem.laborCost ?? 0))),
  1056 + OvertimeLaborCost = 0,
  1057 + LaborCost = ikjbs_tem.laborCost,
1052 1058 IsEffective = StatusEnum.有效.GetHashCode(),
1053 1059 }
1054 1060 );
... ... @@ -1328,12 +1334,18 @@ namespace NCC.Extend.LqXhHyhk
1328 1334 Kjblsyj = ikjbs_tem.kjblsyj,
1329 1335 Yjsj = DateTime.Now,
1330 1336 Hkpxid = lqXhPxmxEntity.Id,
  1337 + // OriginalHdpxNumber = ikjbs_tem.hdpxNumber,
  1338 + // OvertimeHdpxNumber = (decimal)(entity.OvertimeCoefficient * (ikjbs_tem.hdpxNumber ?? 0)),
  1339 + // HdpxNumber = (decimal)((ikjbs_tem.hdpxNumber ?? 0) + (entity.OvertimeCoefficient * (ikjbs_tem.hdpxNumber ?? 0))),
  1340 + // OriginalLaborCost = ikjbs_tem.laborCost,
  1341 + // OvertimeLaborCost = (decimal)(entity.OvertimeCoefficient * (ikjbs_tem.laborCost ?? 0)),
  1342 + // LaborCost = (decimal)((ikjbs_tem.laborCost ?? 0) + (entity.OvertimeCoefficient * (ikjbs_tem.laborCost ?? 0))),
1331 1343 OriginalHdpxNumber = ikjbs_tem.hdpxNumber,
1332   - OvertimeHdpxNumber = (decimal)(entity.OvertimeCoefficient * (ikjbs_tem.hdpxNumber ?? 0)),
1333   - HdpxNumber = (decimal)((ikjbs_tem.hdpxNumber ?? 0) + (entity.OvertimeCoefficient * (ikjbs_tem.hdpxNumber ?? 0))),
  1344 + OvertimeHdpxNumber = 0,
  1345 + HdpxNumber = ikjbs_tem.hdpxNumber,
1334 1346 OriginalLaborCost = ikjbs_tem.laborCost,
1335   - OvertimeLaborCost = (decimal)(entity.OvertimeCoefficient * (ikjbs_tem.laborCost ?? 0)),
1336   - LaborCost = (decimal)((ikjbs_tem.laborCost ?? 0) + (entity.OvertimeCoefficient * (ikjbs_tem.laborCost ?? 0))),
  1347 + OvertimeLaborCost = 0,
  1348 + LaborCost = ikjbs_tem.laborCost,
1337 1349 IsEffective = StatusEnum.有效.GetHashCode(),
1338 1350 });
1339 1351 }
... ...
netcore/src/Modularity/Extend/NCC.Extend/Utils/WeChatBotService.cs
... ... @@ -3,6 +3,7 @@ using System.Net.Http;
3 3 using System.Text;
4 4 using System.Threading.Tasks;
5 5 using Newtonsoft.Json;
  6 +using NCC;
6 7  
7 8 namespace NCC.Extend.Utils
8 9 {
... ... @@ -12,17 +13,28 @@ namespace NCC.Extend.Utils
12 13 public class WeChatBotService
13 14 {
14 15 private readonly HttpClient _httpClient;
15   - private const string BOT_API_URL = "http://wx.lvqianmeiye.com/api/Bot/send-text";
16   - //正式地址
17   - //https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=581c22a6-cb67-42e5-8c76-b8e90052e188
18   - //测试地址
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=496f1add-122b-43fc-9e38-0ca79c48b33f";
21   - private const string WEBHOOK_URL_TEST = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=6f8686ec-5011-4c1d-bae9-d82a2a2f4d83";
  16 + private readonly string _botApiUrl;
  17 + private readonly string _webhookUrl;
22 18  
  19 + /// <summary>
  20 + /// 初始化企业微信机器人服务
  21 + /// </summary>
  22 + /// <param name="httpClient">HTTP客户端</param>
23 23 public WeChatBotService(HttpClient httpClient)
24 24 {
25 25 _httpClient = httpClient;
  26 +
  27 + // 从配置文件中读取企业微信机器人配置
  28 + _botApiUrl = App.Configuration["WeChatBot:BotApiUrl"] ?? "http://wx.lvqianmeiye.com/api/Bot/send-text";
  29 +
  30 + // 从配置文件中读取Webhook地址(正式或测试地址,通过配置文件切换)
  31 + _webhookUrl = App.Configuration["WeChatBot:WebhookUrl"];
  32 +
  33 + // 如果配置文件中没有配置,使用默认值
  34 + if (string.IsNullOrEmpty(_webhookUrl))
  35 + {
  36 + _webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=496f1add-122b-43fc-9e38-0ca79c48b33f";
  37 + }
26 38 }
27 39  
28 40 /// <summary>
... ... @@ -36,8 +48,7 @@ namespace NCC.Extend.Utils
36 48 {
37 49 var requestData = new
38 50 {
39   - webhookUrl = WEBHOOK_URL,
40   - // webhookUrl = WEBHOOK_URL_TEST,
  51 + webhookUrl = _webhookUrl,
41 52 content = content,
42 53 mentionedList = (string)null,
43 54 mentionedMobileList = (string)null,
... ... @@ -46,7 +57,7 @@ namespace NCC.Extend.Utils
46 57 var json = JsonConvert.SerializeObject(requestData);
47 58 var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
48 59  
49   - var response = await _httpClient.PostAsync(BOT_API_URL, httpContent);
  60 + var response = await _httpClient.PostAsync(_botApiUrl, httpContent);
50 61  
51 62 if (response.IsSuccessStatusCode)
52 63 {
... ...