Commit 0b62180f0c9cbf6bd2fe28d3725e0285a79a93e7

Authored by 李宇
2 parents 262c3578 14cbcfd9

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

Showing 40 changed files with 1385 additions and 252 deletions
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/BillingItemDetailListOutput.cs
@@ -66,6 +66,16 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb @@ -66,6 +66,16 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
66 /// 备注 66 /// 备注
67 /// </summary> 67 /// </summary>
68 public string remark { get; set; } 68 public string remark { get; set; }
  69 +
  70 + /// <summary>
  71 + /// 门店ID
  72 + /// </summary>
  73 + public string storeId { get; set; }
  74 +
  75 + /// <summary>
  76 + /// 门店名称
  77 + /// </summary>
  78 + public string storeName { get; set; }
69 } 79 }
70 } 80 }
71 81
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/BillingItemDetailListQueryInput.cs
@@ -66,6 +66,11 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb @@ -66,6 +66,11 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
66 /// 来源类型(购买/赠送/体验) 66 /// 来源类型(购买/赠送/体验)
67 /// </summary> 67 /// </summary>
68 public string SourceType { get; set; } 68 public string SourceType { get; set; }
  69 +
  70 + /// <summary>
  71 + /// 门店ID
  72 + /// </summary>
  73 + public string StoreId { get; set; }
69 } 74 }
70 } 75 }
71 76
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbCrInput.cs
@@ -146,6 +146,11 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb @@ -146,6 +146,11 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
146 public decimal supplementAmount { get; set; } 146 public decimal supplementAmount { get; set; }
147 147
148 /// <summary> 148 /// <summary>
  149 + /// 预约记录ID
  150 + /// </summary>
  151 + public string appointmentId { get; set; }
  152 +
  153 + /// <summary>
149 /// 扣款信息 154 /// 扣款信息
150 /// </summary> 155 /// </summary>
151 public List<LqKdDeductinfoCrInput> lqKdKdjlbDeductList { get; set; } 156 public List<LqKdDeductinfoCrInput> lqKdKdjlbDeductList { get; set; }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbInfoOutput.cs
@@ -173,6 +173,16 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb @@ -173,6 +173,16 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
173 public string activityName { get; set; } 173 public string activityName { get; set; }
174 174
175 /// <summary> 175 /// <summary>
  176 + /// 预约记录ID
  177 + /// </summary>
  178 + public string appointmentId { get; set; }
  179 +
  180 + /// <summary>
  181 + /// 预约记录时间
  182 + /// </summary>
  183 + public DateTime? appointmentTime { get; set; }
  184 +
  185 + /// <summary>
176 /// 健康师业绩 186 /// 健康师业绩
177 /// </summary> 187 /// </summary>
178 public List<LqKdJksyjInfoOutput> lqKdJksyjList { get; set; } 188 public List<LqKdJksyjInfoOutput> lqKdJksyjList { get; set; }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbListOutput.cs
1 using System; 1 using System;
2 using System.Collections.Generic; 2 using System.Collections.Generic;
  3 +using NCC.Extend.Entitys.Dto.LqKdDeductinfo;
3 4
4 namespace NCC.Extend.Entitys.Dto.LqKdKdjlb 5 namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
5 { 6 {
@@ -167,6 +168,15 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb @@ -167,6 +168,15 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
167 public string createUserName { get; set; } 168 public string createUserName { get; set; }
168 169
169 /// <summary> 170 /// <summary>
  171 + /// 预约记录ID
  172 + /// </summary>
  173 + public string appointmentId { get; set; }
  174 + /// <summary>
  175 + /// 预约记录时间
  176 + /// </summary>
  177 + public DateTime? appointmentTime { get; set; }
  178 +
  179 + /// <summary>
170 /// 开单品项明细列表 180 /// 开单品项明细列表
171 /// </summary> 181 /// </summary>
172 public List<LqKdPxmxInfoOutput> ItemDetails { get; set; } 182 public List<LqKdPxmxInfoOutput> ItemDetails { get; set; }
@@ -180,5 +190,10 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb @@ -180,5 +190,10 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
180 /// 科技部老师业绩列表 190 /// 科技部老师业绩列表
181 /// </summary> 191 /// </summary>
182 public List<LqKdKjbsyjInfoOutput> lqKdKjbsyjList { get; set; } 192 public List<LqKdKjbsyjInfoOutput> lqKdKjbsyjList { get; set; }
  193 +
  194 + /// <summary>
  195 + /// 储扣扣款信息列表
  196 + /// </summary>
  197 + public List<LqKdDeductinfoInfoOutput> lqKdDeductList { get; set; }
183 } 198 }
184 } 199 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPersonTimesRecord/LqPersonTimesRecordCrInput.cs 0 → 100644
  1 +using System;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqPersonTimesRecord
  4 +{
  5 + /// <summary>
  6 + /// 人次记录创建输入参数
  7 + /// </summary>
  8 + public class LqPersonTimesRecordCrInput
  9 + {
  10 + /// <summary>
  11 + /// 主键ID
  12 + /// </summary>
  13 + public string id { get; set; }
  14 +
  15 + /// <summary>
  16 + /// 关联业务记录ID
  17 + /// </summary>
  18 + public string businessId { get; set; }
  19 +
  20 + /// <summary>
  21 + /// 业务类型(耗卡/开单)
  22 + /// </summary>
  23 + public string businessType { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 人员类型(健康师/科技老师)
  27 + /// </summary>
  28 + public string personType { get; set; }
  29 +
  30 + /// <summary>
  31 + /// 人员ID
  32 + /// </summary>
  33 + public string personId { get; set; }
  34 +
  35 + /// <summary>
  36 + /// 人员姓名
  37 + /// </summary>
  38 + public string personName { get; set; }
  39 +
  40 + /// <summary>
  41 + /// 客户ID
  42 + /// </summary>
  43 + public string memberId { get; set; }
  44 +
  45 + /// <summary>
  46 + /// 客户姓名
  47 + /// </summary>
  48 + public string memberName { get; set; }
  49 +
  50 + /// <summary>
  51 + /// 工作日期(用于人次统计,格式:YYYY-MM-DD)
  52 + /// </summary>
  53 + public DateTime? workDate { get; set; }
  54 +
  55 + /// <summary>
  56 + /// 工作月份(用于人头统计,格式:202511)
  57 + /// </summary>
  58 + public string workMonth { get; set; }
  59 +
  60 + /// <summary>
  61 + /// 数量
  62 + /// </summary>
  63 + public decimal? quantity { get; set; }
  64 + }
  65 +}
  66 +
  67 +
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPersonTimesRecord/LqPersonTimesRecordInfoOutput.cs 0 → 100644
  1 +using System;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqPersonTimesRecord
  4 +{
  5 + /// <summary>
  6 + /// 人次记录信息输出参数
  7 + /// </summary>
  8 + public class LqPersonTimesRecordInfoOutput
  9 + {
  10 + /// <summary>
  11 + /// 主键ID
  12 + /// </summary>
  13 + public string id { get; set; }
  14 +
  15 + /// <summary>
  16 + /// 关联业务记录ID
  17 + /// </summary>
  18 + public string businessId { get; set; }
  19 +
  20 + /// <summary>
  21 + /// 业务类型(耗卡/开单)
  22 + /// </summary>
  23 + public string businessType { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 人员类型(健康师/科技老师)
  27 + /// </summary>
  28 + public string personType { get; set; }
  29 +
  30 + /// <summary>
  31 + /// 人员ID
  32 + /// </summary>
  33 + public string personId { get; set; }
  34 +
  35 + /// <summary>
  36 + /// 人员姓名
  37 + /// </summary>
  38 + public string personName { get; set; }
  39 +
  40 + /// <summary>
  41 + /// 客户ID
  42 + /// </summary>
  43 + public string memberId { get; set; }
  44 +
  45 + /// <summary>
  46 + /// 客户姓名
  47 + /// </summary>
  48 + public string memberName { get; set; }
  49 +
  50 + /// <summary>
  51 + /// 工作日期(用于人次统计,格式:YYYY-MM-DD)
  52 + /// </summary>
  53 + public DateTime? workDate { get; set; }
  54 +
  55 + /// <summary>
  56 + /// 工作月份(用于人头统计,格式:202511)
  57 + /// </summary>
  58 + public string workMonth { get; set; }
  59 +
  60 + /// <summary>
  61 + /// 数量
  62 + /// </summary>
  63 + public decimal? quantity { get; set; }
  64 +
  65 + /// <summary>
  66 + /// 创建时间
  67 + /// </summary>
  68 + public DateTime? createTime { get; set; }
  69 +
  70 + /// <summary>
  71 + /// 是否有效
  72 + /// </summary>
  73 + public int isEffective { get; set; }
  74 + }
  75 +}
  76 +
  77 +
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPersonTimesRecord/LqPersonTimesRecordListOutput.cs 0 → 100644
  1 +using System;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqPersonTimesRecord
  4 +{
  5 + /// <summary>
  6 + /// 人次记录列表输出参数
  7 + /// </summary>
  8 + public class LqPersonTimesRecordListOutput
  9 + {
  10 + /// <summary>
  11 + /// 主键ID
  12 + /// </summary>
  13 + public string id { get; set; }
  14 +
  15 + /// <summary>
  16 + /// 关联业务记录ID
  17 + /// </summary>
  18 + public string businessId { get; set; }
  19 +
  20 + /// <summary>
  21 + /// 业务类型(耗卡/开单)
  22 + /// </summary>
  23 + public string businessType { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 人员类型(健康师/科技老师)
  27 + /// </summary>
  28 + public string personType { get; set; }
  29 +
  30 + /// <summary>
  31 + /// 人员ID
  32 + /// </summary>
  33 + public string personId { get; set; }
  34 +
  35 + /// <summary>
  36 + /// 人员姓名
  37 + /// </summary>
  38 + public string personName { get; set; }
  39 +
  40 + /// <summary>
  41 + /// 客户ID
  42 + /// </summary>
  43 + public string memberId { get; set; }
  44 +
  45 + /// <summary>
  46 + /// 客户姓名
  47 + /// </summary>
  48 + public string memberName { get; set; }
  49 +
  50 + /// <summary>
  51 + /// 工作日期(用于人次统计,格式:YYYY-MM-DD)
  52 + /// </summary>
  53 + public DateTime? workDate { get; set; }
  54 +
  55 + /// <summary>
  56 + /// 工作月份(用于人头统计,格式:202511)
  57 + /// </summary>
  58 + public string workMonth { get; set; }
  59 +
  60 + /// <summary>
  61 + /// 数量
  62 + /// </summary>
  63 + public decimal? quantity { get; set; }
  64 +
  65 + /// <summary>
  66 + /// 创建时间
  67 + /// </summary>
  68 + public DateTime? createTime { get; set; }
  69 +
  70 + /// <summary>
  71 + /// 是否有效
  72 + /// </summary>
  73 + public int isEffective { get; set; }
  74 + }
  75 +}
  76 +
  77 +
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPersonTimesRecord/LqPersonTimesRecordUpInput.cs 0 → 100644
  1 +namespace NCC.Extend.Entitys.Dto.LqPersonTimesRecord
  2 +{
  3 + /// <summary>
  4 + /// 人次记录更新输入参数
  5 + /// </summary>
  6 + public class LqPersonTimesRecordUpInput : LqPersonTimesRecordCrInput
  7 + {
  8 + /// <summary>
  9 + /// 主键ID
  10 + /// </summary>
  11 + public string id { get; set; }
  12 + }
  13 +}
  14 +
  15 +
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXhHyhk/LqXhHyhkCrInput.cs
@@ -84,6 +84,10 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk @@ -84,6 +84,10 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk
84 /// </summary> 84 /// </summary>
85 public decimal? overtimeCoefficient { get; set; } = 0; 85 public decimal? overtimeCoefficient { get; set; } = 0;
86 86
  87 + /// <summary>
  88 + /// 预约记录ID
  89 + /// </summary>
  90 + public string appointmentId { get; set; }
87 91
88 /// <summary> 92 /// <summary>
89 /// 耗卡_品项明细 93 /// 耗卡_品项明细
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXhHyhk/LqXhHyhkInfoOutput.cs
1 using System; 1 using System;
2 using System.Collections.Generic; 2 using System.Collections.Generic;
  3 +using NCC.Extend.Entitys.Dto.LqPersonTimesRecord;
3 using NCC.Extend.Entitys.Dto.LqXhJksyj; 4 using NCC.Extend.Entitys.Dto.LqXhJksyj;
4 using NCC.Extend.Entitys.Dto.LqXhKjbsyj; 5 using NCC.Extend.Entitys.Dto.LqXhKjbsyj;
5 using NCC.Extend.Entitys.Dto.LqXhPxmx; 6 using NCC.Extend.Entitys.Dto.LqXhPxmx;
@@ -141,5 +142,15 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk @@ -141,5 +142,15 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk
141 /// </summary> 142 /// </summary>
142 public List<LqXhPxmxInfoOutput> lqXhPxmxList { get; set; } 143 public List<LqXhPxmxInfoOutput> lqXhPxmxList { get; set; }
143 144
  145 + /// <summary>
  146 + /// 预约记录ID
  147 + /// </summary>
  148 + public string appointmentId { get; set; }
  149 +
  150 + /// <summary>
  151 + /// 人次记录列表
  152 + /// </summary>
  153 + public List<LqPersonTimesRecordListOutput> personTimesRecordList { get; set; }
  154 +
144 } 155 }
145 } 156 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXhHyhk/LqXhHyhkListOutput.cs
1 using System; 1 using System;
2 using System.Collections.Generic; 2 using System.Collections.Generic;
  3 +using NCC.Extend.Entitys.Dto.LqPersonTimesRecord;
3 using NCC.Extend.Entitys.Dto.LqXhJksyj; 4 using NCC.Extend.Entitys.Dto.LqXhJksyj;
4 using NCC.Extend.Entitys.Dto.LqXhKjbsyj; 5 using NCC.Extend.Entitys.Dto.LqXhKjbsyj;
5 using NCC.Extend.Entitys.Dto.LqXhPxmx; 6 using NCC.Extend.Entitys.Dto.LqXhPxmx;
  7 +using NCC.Extend.Entitys.Dto.LqYyjl;
6 8
7 namespace NCC.Extend.Entitys.Dto.LqXhHyhk 9 namespace NCC.Extend.Entitys.Dto.LqXhHyhk
8 { 10 {
@@ -122,5 +124,15 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk @@ -122,5 +124,15 @@ namespace NCC.Extend.Entitys.Dto.LqXhHyhk
122 /// </summary> 124 /// </summary>
123 public List<LqXhKjbsyjInfoOutput> lqXhKjbsyjList { get; set; } 125 public List<LqXhKjbsyjInfoOutput> lqXhKjbsyjList { get; set; }
124 126
  127 + /// <summary>
  128 + /// 预约记录ID
  129 + /// </summary>
  130 + public string appointmentId { get; set; }
  131 +
  132 + /// <summary>
  133 + /// 人次记录列表
  134 + /// </summary>
  135 + public List<LqPersonTimesRecordListOutput> personTimesRecordList { get; set; }
  136 +
125 } 137 }
126 } 138 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXhPxmx/LqXhPxmxCrInput.cs
1 using System; 1 using System;
2 using System.Collections.Generic; 2 using System.Collections.Generic;
  3 +using NCC.Extend.Entitys.Dto.LqXhJksyj;
  4 +using NCC.Extend.Entitys.Dto.LqXhKjbsyj;
3 5
4 namespace NCC.Extend.Entitys.Dto.LqXhPxmx 6 namespace NCC.Extend.Entitys.Dto.LqXhPxmx
5 { 7 {
@@ -66,11 +68,11 @@ namespace NCC.Extend.Entitys.Dto.LqXhPxmx @@ -66,11 +68,11 @@ namespace NCC.Extend.Entitys.Dto.LqXhPxmx
66 /// <summary> 68 /// <summary>
67 /// 健康师业绩 69 /// 健康师业绩
68 /// </summary> 70 /// </summary>
69 - public List<LqXhJksyj.LqXhJksyjCrInput> lqXhJksyjList { get; set; } 71 + public List<LqXhJksyjCrInput> lqXhJksyjList { get; set; }
70 72
71 /// <summary> 73 /// <summary>
72 /// 科技部老师业绩 74 /// 科技部老师业绩
73 /// </summary> 75 /// </summary>
74 - public List<LqXhKjbsyj.LqXhKjbsyjCrInput> lqXhKjbsyjList { get; set; } 76 + public List<LqXhKjbsyjCrInput> lqXhKjbsyjList { get; set; }
75 } 77 }
76 } 78 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqYaoyjl/LqYaoyjlCrInput.cs
@@ -48,5 +48,10 @@ namespace NCC.Extend.Entitys.Dto.LqYaoyjl @@ -48,5 +48,10 @@ namespace NCC.Extend.Entitys.Dto.LqYaoyjl
48 /// </summary> 48 /// </summary>
49 public string lxjl { get; set; } 49 public string lxjl { get; set; }
50 50
  51 + /// <summary>
  52 + /// 拓客编号
  53 + /// </summary>
  54 + public string tkbh { get; set; }
  55 +
51 } 56 }
52 } 57 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqYaoyjl/LqYaoyjlListOutput.cs
@@ -53,6 +53,11 @@ namespace NCC.Extend.Entitys.Dto.LqYaoyjl @@ -53,6 +53,11 @@ namespace NCC.Extend.Entitys.Dto.LqYaoyjl
53 public string lxjl { get; set; } 53 public string lxjl { get; set; }
54 54
55 /// <summary> 55 /// <summary>
  56 + /// 拓客编号
  57 + /// </summary>
  58 + public string tkbh { get; set; }
  59 +
  60 + /// <summary>
56 /// 所属门店ID 61 /// 所属门店ID
57 /// </summary> 62 /// </summary>
58 public string storeId { get; set; } 63 public string storeId { get; set; }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqYyjl/LqYyjlAddNoDealRemarkInput.cs 0 → 100644
  1 +namespace NCC.Extend.Entitys.Dto.LqYyjl
  2 +{
  3 + /// <summary>
  4 + /// 添加未成交说明输入参数
  5 + /// </summary>
  6 + public class LqYyjlAddNoDealRemarkInput
  7 + {
  8 + /// <summary>
  9 + /// 预约记录ID
  10 + /// </summary>
  11 + public string id { get; set; }
  12 +
  13 + /// <summary>
  14 + /// 未成交说明
  15 + /// </summary>
  16 + public string noDealRemark { get; set; }
  17 + }
  18 +}
  19 +
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqYyjl/LqYyjlCrInput.cs
@@ -73,5 +73,10 @@ namespace NCC.Extend.Entitys.Dto.LqYyjl @@ -73,5 +73,10 @@ namespace NCC.Extend.Entitys.Dto.LqYyjl
73 /// </summary> 73 /// </summary>
74 public string F_Status { get; set; } 74 public string F_Status { get; set; }
75 75
  76 + /// <summary>
  77 + /// 邀约记录ID
  78 + /// </summary>
  79 + public string InviteId { get; set; }
  80 +
76 } 81 }
77 } 82 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqYyjl/LqYyjlInfoOutput.cs
@@ -88,5 +88,19 @@ namespace NCC.Extend.Entitys.Dto.LqYyjl @@ -88,5 +88,19 @@ namespace NCC.Extend.Entitys.Dto.LqYyjl
88 /// </summary> 88 /// </summary>
89 public string F_Status { get; set; } 89 public string F_Status { get; set; }
90 90
  91 + /// <summary>
  92 + /// 未成交说明
  93 + /// </summary>
  94 + public string NoDealRemark { get; set; }
  95 +
  96 + /// <summary>
  97 + /// 邀约记录ID
  98 + /// </summary>
  99 + public string InviteId { get; set; }
  100 +
  101 + /// <summary>
  102 + /// 邀约记录时间
  103 + /// </summary>
  104 + public DateTime? InviteTime { get; set; }
91 } 105 }
92 } 106 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqYyjl/LqYyjlListOutput.cs
@@ -87,5 +87,20 @@ namespace NCC.Extend.Entitys.Dto.LqYyjl @@ -87,5 +87,20 @@ namespace NCC.Extend.Entitys.Dto.LqYyjl
87 /// </summary> 87 /// </summary>
88 public string F_Status { get; set; } 88 public string F_Status { get; set; }
89 89
  90 + /// <summary>
  91 + /// 未成交说明
  92 + /// </summary>
  93 + public string NoDealRemark { get; set; }
  94 +
  95 + /// <summary>
  96 + /// 邀约记录ID
  97 + /// </summary>
  98 + public string InviteId { get; set; }
  99 +
  100 + /// <summary>
  101 + /// 邀约记录时间
  102 + /// </summary>
  103 + public DateTime? InviteTime { get; set; }
  104 +
90 } 105 }
91 } 106 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_hytk_mx/LqHytkMxEntity.cs
@@ -49,6 +49,12 @@ namespace NCC.Extend.Entitys.lq_hytk_mx @@ -49,6 +49,12 @@ namespace NCC.Extend.Entitys.lq_hytk_mx
49 public string Pxmc { get; set; } 49 public string Pxmc { get; set; }
50 50
51 /// <summary> 51 /// <summary>
  52 + /// 品项分类
  53 + /// </summary>
  54 + [SugarColumn(ColumnName = "F_ItemCategory")]
  55 + public string ItemCategory { get; set; }
  56 +
  57 + /// <summary>
52 /// 品项价格 58 /// 品项价格
53 /// </summary> 59 /// </summary>
54 [SugarColumn(ColumnName = "pxjg")] 60 [SugarColumn(ColumnName = "pxjg")]
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_kd_deductinfo/LqKdDeductinfoEntity.cs
@@ -66,6 +66,12 @@ namespace NCC.Extend.Entitys.lq_kd_deductinfo @@ -66,6 +66,12 @@ namespace NCC.Extend.Entitys.lq_kd_deductinfo
66 public string ItemId { get; set; } 66 public string ItemId { get; set; }
67 67
68 /// <summary> 68 /// <summary>
  69 + /// 品项分类
  70 + /// </summary>
  71 + [SugarColumn(ColumnName = "F_ItemCategory")]
  72 + public string ItemCategory { get; set; }
  73 +
  74 + /// <summary>
69 /// 创建时间 75 /// 创建时间
70 /// </summary> 76 /// </summary>
71 [SugarColumn(ColumnName = "F_CreateTime")] 77 [SugarColumn(ColumnName = "F_CreateTime")]
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_kd_kdjlb/LqKdKdjlbEntity.cs
@@ -207,6 +207,12 @@ namespace NCC.Extend.Entitys.lq_kd_kdjlb @@ -207,6 +207,12 @@ namespace NCC.Extend.Entitys.lq_kd_kdjlb
207 public string ActivityId { get; set; } 207 public string ActivityId { get; set; }
208 208
209 /// <summary> 209 /// <summary>
  210 + /// 预约记录ID(关联lq_yyjl.F_Id,用于统计预约→开单转化率)
  211 + /// </summary>
  212 + [SugarColumn(ColumnName = "F_AppointmentId")]
  213 + public string AppointmentId { get; set; }
  214 +
  215 + /// <summary>
210 /// 已缴欠款 216 /// 已缴欠款
211 /// </summary> 217 /// </summary>
212 [SugarColumn(ColumnName = "F_PaidDebt")] 218 [SugarColumn(ColumnName = "F_PaidDebt")]
@@ -223,5 +229,23 @@ namespace NCC.Extend.Entitys.lq_kd_kdjlb @@ -223,5 +229,23 @@ namespace NCC.Extend.Entitys.lq_kd_kdjlb
223 /// </summary> 229 /// </summary>
224 [SugarColumn(ColumnName = "F_SupplementAmount")] 230 [SugarColumn(ColumnName = "F_SupplementAmount")]
225 public decimal SupplementAmount { get; set; } 231 public decimal SupplementAmount { get; set; }
  232 +
  233 + /// <summary>
  234 + /// 升生美(再次开单时,包含生美品项的订单)
  235 + /// </summary>
  236 + [SugarColumn(ColumnName = "F_UpgradeLifeBeauty")]
  237 + public string UpgradeLifeBeauty { get; set; }
  238 +
  239 + /// <summary>
  240 + /// 升科美(再次开单时,包含科美品项的订单)
  241 + /// </summary>
  242 + [SugarColumn(ColumnName = "F_UpgradeTechBeauty")]
  243 + public string UpgradeTechBeauty { get; set; }
  244 +
  245 + /// <summary>
  246 + /// 升医美(再次开单时,包含医美品项的订单)
  247 + /// </summary>
  248 + [SugarColumn(ColumnName = "F_UpgradeMedicalBeauty")]
  249 + public string UpgradeMedicalBeauty { get; set; }
226 } 250 }
227 } 251 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_kd_pxmx/LqKdPxmxEntity.cs
@@ -36,6 +36,12 @@ namespace NCC.Extend.Entitys.lq_kd_pxmx @@ -36,6 +36,12 @@ namespace NCC.Extend.Entitys.lq_kd_pxmx
36 public string Pxmc { get; set; } 36 public string Pxmc { get; set; }
37 37
38 /// <summary> 38 /// <summary>
  39 + /// 品项分类
  40 + /// </summary>
  41 + [SugarColumn(ColumnName = "F_ItemCategory")]
  42 + public string ItemCategory { get; set; }
  43 +
  44 + /// <summary>
39 /// 品项价格 45 /// 品项价格
40 /// </summary> 46 /// </summary>
41 [SugarColumn(ColumnName = "pxjg")] 47 [SugarColumn(ColumnName = "pxjg")]
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_person_times_record/LqPersonTimesRecordEntity.cs 0 → 100644
  1 +using System;
  2 +using NCC.Common.Const;
  3 +using NCC.Extend.Entitys.Enum;
  4 +using SqlSugar;
  5 +
  6 +namespace NCC.Extend.Entitys.lq_person_times_record
  7 +{
  8 + /// <summary>
  9 + /// 人次记录表
  10 + /// </summary>
  11 + [SugarTable("lq_person_times_record")]
  12 + [Tenant(ClaimConst.TENANT_ID)]
  13 + public class LqPersonTimesRecordEntity
  14 + {
  15 + /// <summary>
  16 + /// 主键ID
  17 + /// </summary>
  18 + [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)]
  19 + public string Id { get; set; }
  20 +
  21 + /// <summary>
  22 + /// 关联业务记录ID
  23 + /// </summary>
  24 + [SugarColumn(ColumnName = "F_BusinessId")]
  25 + public string BusinessId { get; set; }
  26 +
  27 + /// <summary>
  28 + /// 业务类型(耗卡/开单)
  29 + /// </summary>
  30 + [SugarColumn(ColumnName = "F_BusinessType")]
  31 + public string BusinessType { get; set; }
  32 +
  33 + /// <summary>
  34 + /// 人员类型(健康师/科技老师)
  35 + /// </summary>
  36 + [SugarColumn(ColumnName = "F_PersonType")]
  37 + public string PersonType { get; set; }
  38 +
  39 + /// <summary>
  40 + /// 人员ID
  41 + /// </summary>
  42 + [SugarColumn(ColumnName = "F_PersonId")]
  43 + public string PersonId { get; set; }
  44 +
  45 + /// <summary>
  46 + /// 人员姓名
  47 + /// </summary>
  48 + [SugarColumn(ColumnName = "F_PersonName")]
  49 + public string PersonName { get; set; }
  50 +
  51 + /// <summary>
  52 + /// 客户ID
  53 + /// </summary>
  54 + [SugarColumn(ColumnName = "F_MemberId")]
  55 + public string MemberId { get; set; }
  56 +
  57 + /// <summary>
  58 + /// 客户姓名
  59 + /// </summary>
  60 + [SugarColumn(ColumnName = "F_MemberName")]
  61 + public string MemberName { get; set; }
  62 +
  63 + /// <summary>
  64 + /// 工作日期(用于人次统计,格式:YYYY-MM-DD)
  65 + /// </summary>
  66 + [SugarColumn(ColumnName = "F_WorkDate")]
  67 + public DateTime? WorkDate { get; set; }
  68 +
  69 + /// <summary>
  70 + /// 工作月份(用于人头统计,格式:202511)
  71 + /// </summary>
  72 + [SugarColumn(ColumnName = "F_WorkMonth")]
  73 + public string WorkMonth { get; set; }
  74 +
  75 + /// <summary>
  76 + /// 数量
  77 + /// </summary>
  78 + [SugarColumn(ColumnName = "F_Quantity")]
  79 + public decimal? Quantity { get; set; }
  80 +
  81 + /// <summary>
  82 + /// 创建时间
  83 + /// </summary>
  84 + [SugarColumn(ColumnName = "F_CreateTime")]
  85 + public DateTime? CreateTime { get; set; }
  86 +
  87 + /// <summary>
  88 + /// 是否有效
  89 + /// </summary>
  90 + [SugarColumn(ColumnName = "F_IsEffective")]
  91 + public int IsEffective { get; set; } = StatusEnum.有效.GetHashCode();
  92 + }
  93 +}
  94 +
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_xh_hyhk/LqXhHyhkEntity.cs
@@ -144,5 +144,11 @@ namespace NCC.Extend.Entitys.lq_xh_hyhk @@ -144,5 +144,11 @@ namespace NCC.Extend.Entitys.lq_xh_hyhk
144 /// </summary> 144 /// </summary>
145 [SugarColumn(ColumnName = "F_OvertimeSgfy")] 145 [SugarColumn(ColumnName = "F_OvertimeSgfy")]
146 public decimal? OvertimeSgfy { get; set; } 146 public decimal? OvertimeSgfy { get; set; }
  147 +
  148 + /// <summary>
  149 + /// 预约记录ID(关联lq_yyjl.F_Id,用于统计预约→耗卡转化率)
  150 + /// </summary>
  151 + [SugarColumn(ColumnName = "F_AppointmentId")]
  152 + public string AppointmentId { get; set; }
147 } 153 }
148 } 154 }
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_xh_pxmx/LqXhPxmxEntity.cs
@@ -42,6 +42,12 @@ namespace NCC.Extend.Entitys.lq_xh_pxmx @@ -42,6 +42,12 @@ namespace NCC.Extend.Entitys.lq_xh_pxmx
42 public string Pxmc { get; set; } 42 public string Pxmc { get; set; }
43 43
44 /// <summary> 44 /// <summary>
  45 + /// 品项分类
  46 + /// </summary>
  47 + [SugarColumn(ColumnName = "F_ItemCategory")]
  48 + public string ItemCategory { get; set; }
  49 +
  50 + /// <summary>
45 /// 品项价格 51 /// 品项价格
46 /// </summary> 52 /// </summary>
47 [SugarColumn(ColumnName = "pxjg")] 53 [SugarColumn(ColumnName = "pxjg")]
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_yyjl/LqYyjlEntity.cs
@@ -90,6 +90,18 @@ namespace NCC.Extend.Entitys.lq_yyjl @@ -90,6 +90,18 @@ namespace NCC.Extend.Entitys.lq_yyjl
90 public string F_Status { get; set; } 90 public string F_Status { get; set; }
91 91
92 /// <summary> 92 /// <summary>
  93 + /// 邀约记录ID(关联lq_yaoyjl.F_Id,用于统计邀约→预约转化率)
  94 + /// </summary>
  95 + [SugarColumn(ColumnName = "F_InviteId")]
  96 + public string InviteId { get; set; }
  97 +
  98 + /// <summary>
  99 + /// 未成交说明
  100 + /// </summary>
  101 + [SugarColumn(ColumnName = "F_NoDealRemark")]
  102 + public string NoDealRemark { get; set; }
  103 +
  104 + /// <summary>
93 /// 创建时间 105 /// 创建时间
94 /// </summary> 106 /// </summary>
95 [SugarColumn(ColumnName = "F_CreateTime")] 107 [SugarColumn(ColumnName = "F_CreateTime")]
netcore/src/Modularity/Extend/NCC.Extend/LqHytkHytkService.cs
@@ -25,6 +25,7 @@ using NCC.Extend.Entitys.lq_hytk_jksyj; @@ -25,6 +25,7 @@ using NCC.Extend.Entitys.lq_hytk_jksyj;
25 using NCC.Extend.Entitys.lq_hytk_kjbsyj; 25 using NCC.Extend.Entitys.lq_hytk_kjbsyj;
26 using NCC.Extend.Entitys.lq_hytk_mx; 26 using NCC.Extend.Entitys.lq_hytk_mx;
27 using NCC.Extend.Entitys.lq_kd_pxmx; 27 using NCC.Extend.Entitys.lq_kd_pxmx;
  28 +using NCC.Extend.Entitys.lq_xmzl;
28 using NCC.Extend.Interfaces.LqHytkHytk; 29 using NCC.Extend.Interfaces.LqHytkHytk;
29 using NCC.FriendlyException; 30 using NCC.FriendlyException;
30 using NCC.JsonSerialization; 31 using NCC.JsonSerialization;
@@ -408,6 +409,7 @@ namespace NCC.Extend.LqHytkHytk @@ -408,6 +409,7 @@ namespace NCC.Extend.LqHytkHytk
408 SourceType = item.F_SourceType, 409 SourceType = item.F_SourceType,
409 TotalPrice = item.F_TotalPrice ?? (item.pxjg * (item.F_ProjectNumber ?? 1)), 410 TotalPrice = item.F_TotalPrice ?? (item.pxjg * (item.F_ProjectNumber ?? 1)),
410 IsEffective = StatusEnum.有效.GetHashCode(), 411 IsEffective = StatusEnum.有效.GetHashCode(),
  412 + ItemCategory = await _db.Queryable<LqXmzlEntity>().Where(x => x.Id == item.px).Select(x => x.Qt2).FirstAsync(),
411 }; 413 };
412 allMxEntities.Add(lqHytkMxEntity); 414 allMxEntities.Add(lqHytkMxEntity);
413 415
@@ -559,6 +561,7 @@ namespace NCC.Extend.LqHytkHytk @@ -559,6 +561,7 @@ namespace NCC.Extend.LqHytkHytk
559 ProjectNumber = item.F_ProjectNumber ?? 1, 561 ProjectNumber = item.F_ProjectNumber ?? 1,
560 SourceType = item.F_SourceType, 562 SourceType = item.F_SourceType,
561 TotalPrice = item.F_TotalPrice ?? (item.pxjg * (item.F_ProjectNumber ?? 1)), 563 TotalPrice = item.F_TotalPrice ?? (item.pxjg * (item.F_ProjectNumber ?? 1)),
  564 + ItemCategory = await _db.Queryable<LqXmzlEntity>().Where(x => x.Id == item.px).Select(x => x.Qt2).FirstAsync(),
562 }; 565 };
563 allMxEntities.Add(lqHytkMxEntity); 566 allMxEntities.Add(lqHytkMxEntity);
564 567
netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs
@@ -46,6 +46,7 @@ using NCC.Extend.Entitys.lq_package_info; @@ -46,6 +46,7 @@ using NCC.Extend.Entitys.lq_package_info;
46 using NCC.Extend.Entitys.lq_mdxx; 46 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 50
50 namespace NCC.Extend.LqKdKdjlb 51 namespace NCC.Extend.LqKdKdjlb
51 { 52 {
@@ -124,8 +125,11 @@ namespace NCC.Extend.LqKdKdjlb @@ -124,8 +125,11 @@ namespace NCC.Extend.LqKdKdjlb
124 { 125 {
125 throw NCCException.Oh(ErrorCode.COM1005, "开单记录不存在"); 126 throw NCCException.Oh(ErrorCode.COM1005, "开单记录不存在");
126 } 127 }
127 -  
128 var output = entity.Adapt<LqKdKdjlbInfoOutput>(); 128 var output = entity.Adapt<LqKdKdjlbInfoOutput>();
  129 + if (!string.IsNullOrEmpty(entity.AppointmentId))
  130 + {
  131 + output.appointmentTime = await _db.Queryable<LqYyjlEntity>().Where(x => x.Id == entity.AppointmentId).Select(x => x.Yysj).FirstAsync();
  132 + }
129 if (output.activityId != null) 133 if (output.activityId != null)
130 { 134 {
131 output.activityName = await _db.Queryable<LqPackageInfoEntity>().Where(x => x.Id == entity.ActivityId).Select(x => x.ActivityName).FirstAsync(); 135 output.activityName = await _db.Queryable<LqPackageInfoEntity>().Where(x => x.Id == entity.ActivityId).Select(x => x.ActivityName).FirstAsync();
@@ -317,6 +321,8 @@ namespace NCC.Extend.LqKdKdjlb @@ -317,6 +321,8 @@ namespace NCC.Extend.LqKdKdjlb
317 createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == it.CreateUser).Select(x => x.RealName), 321 createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == it.CreateUser).Select(x => x.RealName),
318 activityId = it.ActivityId, 322 activityId = it.ActivityId,
319 activityName = SqlFunc.Subqueryable<LqPackageInfoEntity>().Where(x => x.Id == it.ActivityId).Select(x => x.ActivityName), 323 activityName = SqlFunc.Subqueryable<LqPackageInfoEntity>().Where(x => x.Id == it.ActivityId).Select(x => x.ActivityName),
  324 + appointmentId = it.AppointmentId,
  325 + appointmentTime = it.AppointmentId == null ? (DateTime?)null : SqlFunc.Subqueryable<LqYyjlEntity>().Where(x => x.Id == it.AppointmentId).Select(x => SqlFunc.ToDate(x.Yysj)),
320 }) 326 })
321 .MergeTable() 327 .MergeTable()
322 .OrderBy(sidx + " " + input.sort) 328 .OrderBy(sidx + " " + input.sort)
@@ -357,65 +363,77 @@ namespace NCC.Extend.LqKdKdjlb @@ -357,65 +363,77 @@ namespace NCC.Extend.LqKdKdjlb
357 var jksyjList = new List<LqKdJksyjInfoOutput>(); 363 var jksyjList = new List<LqKdJksyjInfoOutput>();
358 if (billingIds.Any()) 364 if (billingIds.Any())
359 { 365 {
360 - jksyjList = await _db.Queryable<LqKdJksyjEntity>()  
361 - .Where(x => billingIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode())  
362 - .Select(x => new LqKdJksyjInfoOutput  
363 - {  
364 - id = x.Id,  
365 - glkdbh = x.Glkdbh,  
366 - kdpxid = x.Kdpxid,  
367 - jks = x.Jks,  
368 - jksxm = x.Jksxm,  
369 - jkszh = x.Jkszh,  
370 - jksyj = x.Jksyj,  
371 - yjsj = x.Yjsj,  
372 - jsj_id = x.Jsj_id,  
373 - isEffective = x.IsEffective  
374 - })  
375 - .ToListAsync(); 366 + jksyjList = await _db.Queryable<LqKdJksyjEntity>().Where(x => billingIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode()).Select(x => new LqKdJksyjInfoOutput
  367 + {
  368 + id = x.Id,
  369 + glkdbh = x.Glkdbh,
  370 + kdpxid = x.Kdpxid,
  371 + jks = x.Jks,
  372 + jksxm = x.Jksxm,
  373 + jkszh = x.Jkszh,
  374 + jksyj = x.Jksyj,
  375 + yjsj = x.Yjsj,
  376 + jsj_id = x.Jsj_id,
  377 + isEffective = x.IsEffective
  378 + }).ToListAsync();
376 } 379 }
377 380
378 // 批量查询科技部老师业绩(性能优化:一次性查询所有开单的科技部老师业绩) 381 // 批量查询科技部老师业绩(性能优化:一次性查询所有开单的科技部老师业绩)
379 var kjbsyjList = new List<LqKdKjbsyjInfoOutput>(); 382 var kjbsyjList = new List<LqKdKjbsyjInfoOutput>();
380 if (billingIds.Any()) 383 if (billingIds.Any())
381 { 384 {
382 - kjbsyjList = await _db.Queryable<LqKdKjbsyjEntity>()  
383 - .Where(x => billingIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode())  
384 - .Select(x => new LqKdKjbsyjInfoOutput 385 + kjbsyjList = await _db.Queryable<LqKdKjbsyjEntity>().Where(x => billingIds.Contains(x.Glkdbh) && x.IsEffective == StatusEnum.有效.GetHashCode()).Select(x => new LqKdKjbsyjInfoOutput
  386 + {
  387 + id = x.Id,
  388 + glkdbh = x.Glkdbh,
  389 + kdpxid = x.Kdpxid,
  390 + kjbls = x.Kjbls,
  391 + kjblsxm = x.Kjblsxm,
  392 + kjblszh = x.Kjblszh,
  393 + kjblsyj = x.Kjblsyj,
  394 + yjsj = x.Yjsj,
  395 + isEffective = x.IsEffective
  396 + })
  397 + .ToListAsync();
  398 + }
  399 +
  400 + // 批量查询储扣扣款信息(性能优化:一次性查询所有开单的储扣扣款信息)
  401 + var deductinfoList = new List<LqKdDeductinfoInfoOutput>();
  402 + if (billingIds.Any())
  403 + {
  404 + deductinfoList = await _db.Queryable<LqKdDeductinfoEntity>().Where(x => billingIds.Contains(x.BillingId) && x.IsEffective == StatusEnum.有效.GetHashCode())
  405 + .Select(x => new LqKdDeductinfoInfoOutput
385 { 406 {
386 id = x.Id, 407 id = x.Id,
387 - glkdbh = x.Glkdbh,  
388 - kdpxid = x.Kdpxid,  
389 - kjbls = x.Kjbls,  
390 - kjblsxm = x.Kjblsxm,  
391 - kjblszh = x.Kjblszh,  
392 - kjblsyj = x.Kjblsyj,  
393 - yjsj = x.Yjsj,  
394 - isEffective = x.IsEffective 408 + deductType = x.DeductType,
  409 + deductId = x.DeductId,
  410 + billingId = x.BillingId,
  411 + amount = x.Amount,
  412 + isEffective = x.IsEffective,
  413 + unitPrice = x.UnitPrice,
  414 + itemName = x.ItemName,
  415 + itemId = x.ItemId,
  416 + createTime = x.CreateTime,
  417 + projectNumber = x.ProjectNumber,
  418 +
395 }) 419 })
396 .ToListAsync(); 420 .ToListAsync();
397 } 421 }
398 422
  423 + // 按开单ID分组储扣扣款信息
  424 + var deductinfoGrouped = deductinfoList.GroupBy(x => x.billingId).ToDictionary(g => g.Key, g => g.ToList());
399 // 按开单ID分组健康师业绩 425 // 按开单ID分组健康师业绩
400 - var jksyjGrouped = jksyjList.GroupBy(x => x.glkdbh)  
401 - .ToDictionary(g => g.Key, g => g.ToList());  
402 - 426 + var jksyjGrouped = jksyjList.GroupBy(x => x.glkdbh).ToDictionary(g => g.Key, g => g.ToList());
403 // 按开单ID分组科技部老师业绩 427 // 按开单ID分组科技部老师业绩
404 - var kjbsyjGrouped = kjbsyjList.GroupBy(x => x.glkdbh)  
405 - .ToDictionary(g => g.Key, g => g.ToList()); 428 + var kjbsyjGrouped = kjbsyjList.GroupBy(x => x.glkdbh).ToDictionary(g => g.Key, g => g.ToList());
406 429
407 // 为每个开单记录分配品项明细、健康师业绩和科技部老师业绩 430 // 为每个开单记录分配品项明细、健康师业绩和科技部老师业绩
408 foreach (var item in data.list) 431 foreach (var item in data.list)
409 { 432 {
410 - item.ItemDetails = itemDetailsGrouped.ContainsKey(item.id)  
411 - ? itemDetailsGrouped[item.id]  
412 - : new List<LqKdPxmxInfoOutput>();  
413 - item.lqKdJksyjList = jksyjGrouped.ContainsKey(item.id)  
414 - ? jksyjGrouped[item.id]  
415 - : new List<LqKdJksyjInfoOutput>();  
416 - item.lqKdKjbsyjList = kjbsyjGrouped.ContainsKey(item.id)  
417 - ? kjbsyjGrouped[item.id]  
418 - : new List<LqKdKjbsyjInfoOutput>(); 433 + item.ItemDetails = itemDetailsGrouped.ContainsKey(item.id) ? itemDetailsGrouped[item.id] : new List<LqKdPxmxInfoOutput>();
  434 + item.lqKdJksyjList = jksyjGrouped.ContainsKey(item.id) ? jksyjGrouped[item.id] : new List<LqKdJksyjInfoOutput>();
  435 + item.lqKdKjbsyjList = kjbsyjGrouped.ContainsKey(item.id) ? kjbsyjGrouped[item.id] : new List<LqKdKjbsyjInfoOutput>();
  436 + item.lqKdDeductList = deductinfoGrouped.ContainsKey(item.id) ? deductinfoGrouped[item.id] : new List<LqKdDeductinfoInfoOutput>();
419 } 437 }
420 438
421 return PageResult<LqKdKdjlbListOutput>.SqlSugarPageResult(data); 439 return PageResult<LqKdKdjlbListOutput>.SqlSugarPageResult(data);
@@ -516,6 +534,8 @@ namespace NCC.Extend.LqKdKdjlb @@ -516,6 +534,8 @@ namespace NCC.Extend.LqKdKdjlb
516 createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == kdjlb.CreateUser).Select(x => x.RealName), 534 createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == kdjlb.CreateUser).Select(x => x.RealName),
517 activityId = kdjlb.ActivityId, 535 activityId = kdjlb.ActivityId,
518 activityName = SqlFunc.Subqueryable<LqPackageInfoEntity>().Where(x => x.Id == kdjlb.ActivityId).Select(x => x.ActivityName), 536 activityName = SqlFunc.Subqueryable<LqPackageInfoEntity>().Where(x => x.Id == kdjlb.ActivityId).Select(x => x.ActivityName),
  537 + appointmentId = kdjlb.AppointmentId,
  538 + appointmentTime = kdjlb.AppointmentId == null ? (DateTime?)null : SqlFunc.Subqueryable<LqYyjlEntity>().Where(x => x.Id == kdjlb.AppointmentId).Select(x => SqlFunc.ToDate(x.Yysj)),
519 }) 539 })
520 .MergeTable() 540 .MergeTable()
521 .Distinct() // 去重,因为一个开单可能对应多个健康师业绩记录 541 .Distinct() // 去重,因为一个开单可能对应多个健康师业绩记录
@@ -670,6 +690,8 @@ namespace NCC.Extend.LqKdKdjlb @@ -670,6 +690,8 @@ namespace NCC.Extend.LqKdKdjlb
670 createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == kdjlb.CreateUser).Select(x => x.RealName), 690 createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == kdjlb.CreateUser).Select(x => x.RealName),
671 activityId = kdjlb.ActivityId, 691 activityId = kdjlb.ActivityId,
672 activityName = SqlFunc.Subqueryable<LqPackageInfoEntity>().Where(x => x.Id == kdjlb.ActivityId).Select(x => x.ActivityName), 692 activityName = SqlFunc.Subqueryable<LqPackageInfoEntity>().Where(x => x.Id == kdjlb.ActivityId).Select(x => x.ActivityName),
  693 + appointmentId = kdjlb.AppointmentId,
  694 + appointmentTime = kdjlb.AppointmentId == null ? (DateTime?)null : SqlFunc.Subqueryable<LqYyjlEntity>().Where(x => x.Id == kdjlb.AppointmentId).Select(x => SqlFunc.ToDate(x.Yysj)),
673 }) 695 })
674 .MergeTable() 696 .MergeTable()
675 .Distinct() // 去重,因为一个开单可能对应多个科技部老师业绩记录 697 .Distinct() // 去重,因为一个开单可能对应多个科技部老师业绩记录
@@ -747,35 +769,6 @@ namespace NCC.Extend.LqKdKdjlb @@ -747,35 +769,6 @@ namespace NCC.Extend.LqKdKdjlb
747 { 769 {
748 //开启事务 770 //开启事务
749 _db.BeginTran(); 771 _db.BeginTran();
750 - //判断是否有作废关联id  
751 - //暂时先不需要  
752 - // if (!string.IsNullOrEmpty(input.cancelRefId))  
753 - // {  
754 - // //查询作废关联id  
755 - // var cancelRefEntity = await _db.Queryable<LqKdKdjlbEntity>().FirstAsync(p => p.Id == input.cancelRefId);  
756 - // if (cancelRefEntity == null || cancelRefEntity.IsEffective == StatusEnum.无效.GetHashCode())  
757 - // {  
758 - // throw NCCException.Oh("该开单记录已经作废");  
759 - // }  
760 - // // 检查作废关联记录是否可以作废  
761 - // var (canCancel, errorMessage) = await CheckBillingCanCancelAsync(input.cancelRefId);  
762 - // if (!canCancel)  
763 - // {  
764 - // throw NCCException.Oh(errorMessage);  
765 - // }  
766 -  
767 - // //将作废关联id的IsEffective设置为无效  
768 - // cancelRefEntity.IsEffective = StatusEnum.无效.GetHashCode();  
769 - // await _db.Updateable(cancelRefEntity).ExecuteCommandAsync();  
770 - // //把品项明细表的IsEffective设置为无效  
771 - // await _db.Updateable<LqKdPxmxEntity>().Where(p => p.Glkdbh == input.cancelRefId).UpdateColumns(p => new LqKdPxmxEntity { IsEffective = StatusEnum.无效.GetHashCode() }).ExecuteCommandAsync();  
772 - // //把健康师业绩表的IsEffective设置为无效  
773 - // await _db.Updateable<LqKdJksyjEntity>().Where(p => p.Glkdbh == input.cancelRefId).UpdateColumns(p => new LqKdJksyjEntity { IsEffective = StatusEnum.无效.GetHashCode() }).ExecuteCommandAsync();  
774 - // //把科技部老师业绩表的IsEffective设置为无效  
775 - // await _db.Updateable<LqKdKjbsyjEntity>().Where(p => p.Glkdbh == input.cancelRefId).UpdateColumns(p => new LqKdKjbsyjEntity { IsEffective = StatusEnum.无效.GetHashCode() }).ExecuteCommandAsync();  
776 - // //把扣款信息表的IsEffective设置为无效  
777 - // await _db.Updateable<LqKdDeductinfoEntity>().Where(p => p.BillingId == input.cancelRefId).UpdateColumns(p => new LqKdDeductinfoEntity { IsEffective = StatusEnum.无效.GetHashCode() }).ExecuteCommandAsync();  
778 - // }  
779 772
780 //判断是否有补缴开单ID 773 //判断是否有补缴开单ID
781 if (!string.IsNullOrEmpty(input.supplementBillingId)) 774 if (!string.IsNullOrEmpty(input.supplementBillingId))
@@ -796,6 +789,8 @@ namespace NCC.Extend.LqKdKdjlb @@ -796,6 +789,8 @@ namespace NCC.Extend.LqKdKdjlb
796 //新增开单记录表记录 789 //新增开单记录表记录
797 entity.CreateUser = userInfo.userId; 790 entity.CreateUser = userInfo.userId;
798 entity.DeductAmount = input.lqKdKdjlbDeductList.Sum(x => x.Amount ?? 0);//计算储扣总金额 791 entity.DeductAmount = input.lqKdKdjlbDeductList.Sum(x => x.Amount ?? 0);//计算储扣总金额
  792 +
  793 + //保存开单记录
799 var newEntity = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteReturnEntityAsync(); 794 var newEntity = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteReturnEntityAsync();
800 //循环品相信息 795 //循环品相信息
801 // 收集所有需要插入的实体,然后批量插入 796 // 收集所有需要插入的实体,然后批量插入
@@ -819,6 +814,7 @@ namespace NCC.Extend.LqKdKdjlb @@ -819,6 +814,7 @@ namespace NCC.Extend.LqKdKdjlb
819 ItemId = item.ItemId, 814 ItemId = item.ItemId,
820 IsEffective = StatusEnum.有效.GetHashCode(), // 设置为有效 815 IsEffective = StatusEnum.有效.GetHashCode(), // 设置为有效
821 CreateTime = DateTime.Now, // 设置创建时间 816 CreateTime = DateTime.Now, // 设置创建时间
  817 + ItemCategory = await _db.Queryable<LqXmzlEntity>().Where(x => x.Id == item.ItemId).Select(x => x.Qt2).FirstAsync(),
822 }; 818 };
823 allDeductEntities.Add(lqKdDeductEntity); 819 allDeductEntities.Add(lqKdDeductEntity);
824 } 820 }
@@ -844,6 +840,7 @@ namespace NCC.Extend.LqKdKdjlb @@ -844,6 +840,7 @@ namespace NCC.Extend.LqKdKdjlb
844 Remark = item.remark, 840 Remark = item.remark,
845 IsEffective = StatusEnum.有效.GetHashCode(), 841 IsEffective = StatusEnum.有效.GetHashCode(),
846 ActivityId = input.activityId, 842 ActivityId = input.activityId,
  843 + ItemCategory = await _db.Queryable<LqXmzlEntity>().Where(x => x.Id == item.px).Select(x => x.Qt2).FirstAsync(),
847 }; 844 };
848 allPxmxEntities.Add(lqKdPxmxEntity); 845 allPxmxEntities.Add(lqKdPxmxEntity);
849 846
@@ -1563,6 +1560,7 @@ namespace NCC.Extend.LqKdKdjlb @@ -1563,6 +1560,7 @@ namespace NCC.Extend.LqKdKdjlb
1563 ItemId = item.ItemId, 1560 ItemId = item.ItemId,
1564 IsEffective = StatusEnum.有效.GetHashCode(), // 设置为有效 1561 IsEffective = StatusEnum.有效.GetHashCode(), // 设置为有效
1565 CreateTime = DateTime.Now, // 设置创建时间 1562 CreateTime = DateTime.Now, // 设置创建时间
  1563 + ItemCategory = await _db.Queryable<LqXmzlEntity>().Where(x => x.Id == item.DeductId).Select(x => x.Qt2).FirstAsync(),
1566 }; 1564 };
1567 allDeductEntities.Add(lqKdDeductEntity); 1565 allDeductEntities.Add(lqKdDeductEntity);
1568 } 1566 }
@@ -1588,6 +1586,7 @@ namespace NCC.Extend.LqKdKdjlb @@ -1588,6 +1586,7 @@ namespace NCC.Extend.LqKdKdjlb
1588 Remark = item.remark, 1586 Remark = item.remark,
1589 IsEffective = StatusEnum.有效.GetHashCode(), 1587 IsEffective = StatusEnum.有效.GetHashCode(),
1590 ActivityId = input.activityId, 1588 ActivityId = input.activityId,
  1589 + ItemCategory = await _db.Queryable<LqXmzlEntity>().Where(x => x.Id == item.px).Select(x => x.Qt2).FirstAsync(),
1591 }; 1590 };
1592 allPxmxEntities.Add(lqKdPxmxEntity); 1591 allPxmxEntities.Add(lqKdPxmxEntity);
1593 1592
@@ -2113,6 +2112,7 @@ namespace NCC.Extend.LqKdKdjlb @@ -2113,6 +2112,7 @@ namespace NCC.Extend.LqKdKdjlb
2113 isEffective = it.IsEffective, 2112 isEffective = it.IsEffective,
2114 createUser = it.CreateUser, 2113 createUser = it.CreateUser,
2115 createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == it.CreateUser).Select(x => x.RealName), 2114 createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == it.CreateUser).Select(x => x.RealName),
  2115 + appointmentId = it.AppointmentId,
2116 }) 2116 })
2117 .MergeTable() 2117 .MergeTable()
2118 .OrderBy(sidx + " " + input.sort) 2118 .OrderBy(sidx + " " + input.sort)
@@ -3237,7 +3237,8 @@ namespace NCC.Extend.LqKdKdjlb @@ -3237,7 +3237,8 @@ namespace NCC.Extend.LqKdKdjlb
3237 /// "ItemId": "品项ID", 3237 /// "ItemId": "品项ID",
3238 /// "ItemName": "品项名称", 3238 /// "ItemName": "品项名称",
3239 /// "ItemType": "品项类型", 3239 /// "ItemType": "品项类型",
3240 - /// "SourceType": "来源类型" 3240 + /// "SourceType": "来源类型",
  3241 + /// "StoreId": "门店ID"
3241 /// } 3242 /// }
3242 /// ``` 3243 /// ```
3243 /// 3244 ///
@@ -3258,6 +3259,7 @@ namespace NCC.Extend.LqKdKdjlb @@ -3258,6 +3259,7 @@ namespace NCC.Extend.LqKdKdjlb
3258 /// - ItemName: 品项名称(可选,模糊查询) 3259 /// - ItemName: 品项名称(可选,模糊查询)
3259 /// - ItemType: 品项类型(可选,精确匹配,对应项目资料表的qt2字段) 3260 /// - ItemType: 品项类型(可选,精确匹配,对应项目资料表的qt2字段)
3260 /// - SourceType: 来源类型(可选,精确匹配,如:购买、赠送、体验) 3261 /// - SourceType: 来源类型(可选,精确匹配,如:购买、赠送、体验)
  3262 + /// - StoreId: 门店ID(可选,精确匹配,根据开单记录表的门店ID筛选)
3261 /// 3263 ///
3262 /// 返回数据结构: 3264 /// 返回数据结构:
3263 /// ```json 3265 /// ```json
@@ -3280,7 +3282,9 @@ namespace NCC.Extend.LqKdKdjlb @@ -3280,7 +3282,9 @@ namespace NCC.Extend.LqKdKdjlb
3280 /// "actualPrice": 500.00, 3282 /// "actualPrice": 500.00,
3281 /// "projectNumber": 5.0, 3283 /// "projectNumber": 5.0,
3282 /// "sourceType": "购买", 3284 /// "sourceType": "购买",
3283 - /// "remark": "备注" 3285 + /// "remark": "备注",
  3286 + /// "storeId": "门店ID",
  3287 + /// "storeName": "门店名称"
3284 /// } 3288 /// }
3285 /// ] 3289 /// ]
3286 /// } 3290 /// }
@@ -3299,6 +3303,8 @@ namespace NCC.Extend.LqKdKdjlb @@ -3299,6 +3303,8 @@ namespace NCC.Extend.LqKdKdjlb
3299 /// - projectNumber: 项目次数(decimal类型,支持小数) 3303 /// - projectNumber: 项目次数(decimal类型,支持小数)
3300 /// - sourceType: 来源类型(字符串,如:购买、赠送、体验) 3304 /// - sourceType: 来源类型(字符串,如:购买、赠送、体验)
3301 /// - remark: 备注(字符串) 3305 /// - remark: 备注(字符串)
  3306 + /// - storeId: 门店ID(关联开单记录表的门店ID)
  3307 + /// - storeName: 门店名称(关联门店表的店名字段)
3302 /// </remarks> 3308 /// </remarks>
3303 /// <param name="input">查询参数</param> 3309 /// <param name="input">查询参数</param>
3304 /// <returns>开单品项明细记录列表(分页)</returns> 3310 /// <returns>开单品项明细记录列表(分页)</returns>
@@ -3341,7 +3347,8 @@ namespace NCC.Extend.LqKdKdjlb @@ -3341,7 +3347,8 @@ namespace NCC.Extend.LqKdKdjlb
3341 // 2. 通过 EXISTS 子查询筛选关联字段(在分页前筛选,确保分页准确) 3347 // 2. 通过 EXISTS 子查询筛选关联字段(在分页前筛选,确保分页准确)
3342 baseQuery = baseQuery.WhereIF(!string.IsNullOrEmpty(input.MemberName), pxmx => SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == pxmx.MemberId && x.Khmc != null && x.Khmc.Contains(input.MemberName)).Any()) 3348 baseQuery = baseQuery.WhereIF(!string.IsNullOrEmpty(input.MemberName), pxmx => SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == pxmx.MemberId && x.Khmc != null && x.Khmc.Contains(input.MemberName)).Any())
3343 .WhereIF(!string.IsNullOrEmpty(input.MemberPhone), pxmx => SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == pxmx.MemberId && x.Sjh == input.MemberPhone).Any()) 3349 .WhereIF(!string.IsNullOrEmpty(input.MemberPhone), pxmx => SqlFunc.Subqueryable<LqKhxxEntity>().Where(x => x.Id == pxmx.MemberId && x.Sjh == input.MemberPhone).Any())
3344 - .WhereIF(!string.IsNullOrEmpty(input.ItemType), pxmx => SqlFunc.Subqueryable<LqXmzlEntity>().Where(x => x.Id == pxmx.Px && x.Fl4 == input.ItemType).Any()); 3350 + .WhereIF(!string.IsNullOrEmpty(input.ItemType), pxmx => SqlFunc.Subqueryable<LqXmzlEntity>().Where(x => x.Id == pxmx.Px && x.Fl4 == input.ItemType).Any())
  3351 + .WhereIF(!string.IsNullOrEmpty(input.StoreId), pxmx => SqlFunc.Subqueryable<LqKdKdjlbEntity>().Where(x => x.Id == pxmx.Glkdbh && x.Djmd == input.StoreId).Any());
3345 3352
3346 // 3. 先分页查询主表数据(查询实体类,提高性能) 3353 // 3. 先分页查询主表数据(查询实体类,提高性能)
3347 var pagedData = await baseQuery.OrderBy(sidx + " " + sort).ToPagedListAsync(input.currentPage, input.pageSize); 3354 var pagedData = await baseQuery.OrderBy(sidx + " " + sort).ToPagedListAsync(input.currentPage, input.pageSize);
@@ -3351,6 +3358,7 @@ namespace NCC.Extend.LqKdKdjlb @@ -3351,6 +3358,7 @@ namespace NCC.Extend.LqKdKdjlb
3351 var memberIds = pagedData.list.Where(x => !string.IsNullOrEmpty(x.MemberId)).Select(x => x.MemberId).Distinct().ToList(); 3358 var memberIds = pagedData.list.Where(x => !string.IsNullOrEmpty(x.MemberId)).Select(x => x.MemberId).Distinct().ToList();
3352 var activityIds = pagedData.list.Where(x => !string.IsNullOrEmpty(x.ActivityId)).Select(x => x.ActivityId).Distinct().ToList(); 3359 var activityIds = pagedData.list.Where(x => !string.IsNullOrEmpty(x.ActivityId)).Select(x => x.ActivityId).Distinct().ToList();
3353 var projectIds = pagedData.list.Where(x => !string.IsNullOrEmpty(x.Px)).Select(x => x.Px).Distinct().ToList(); 3360 var projectIds = pagedData.list.Where(x => !string.IsNullOrEmpty(x.Px)).Select(x => x.Px).Distinct().ToList();
  3361 + var billingIds = pagedData.list.Where(x => !string.IsNullOrEmpty(x.Glkdbh)).Select(x => x.Glkdbh).Distinct().ToList();
3354 3362
3355 // 批量查询会员信息 3363 // 批量查询会员信息
3356 var memberDict = new Dictionary<string, (string Name, string Phone)>(); 3364 var memberDict = new Dictionary<string, (string Name, string Phone)>();
@@ -3376,6 +3384,23 @@ namespace NCC.Extend.LqKdKdjlb @@ -3376,6 +3384,23 @@ namespace NCC.Extend.LqKdKdjlb
3376 projectDict = projects.ToDictionary(x => x.Id, x => x.Qt2 ?? ""); 3384 projectDict = projects.ToDictionary(x => x.Id, x => x.Qt2 ?? "");
3377 } 3385 }
3378 3386
  3387 + // 批量查询开单记录,获取门店ID
  3388 + var billingStoreDict = new Dictionary<string, string>();
  3389 + if (billingIds.Any())
  3390 + {
  3391 + var billings = await _db.Queryable<LqKdKdjlbEntity>().Where(x => billingIds.Contains(x.Id)).Select(x => new { x.Id, x.Djmd }).ToListAsync();
  3392 + billingStoreDict = billings.ToDictionary(x => x.Id, x => x.Djmd ?? "");
  3393 + }
  3394 +
  3395 + // 批量查询门店信息
  3396 + var storeDict = new Dictionary<string, string>();
  3397 + var storeIds = billingStoreDict.Values.Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList();
  3398 + if (storeIds.Any())
  3399 + {
  3400 + var stores = await _db.Queryable<LqMdxxEntity>().Where(x => storeIds.Contains(x.Id)).Select(x => new { x.Id, x.Dm }).ToListAsync();
  3401 + storeDict = stores.ToDictionary(x => x.Id, x => x.Dm ?? "");
  3402 + }
  3403 +
3379 // 5. 组装返回数据 3404 // 5. 组装返回数据
3380 var resultList = pagedData.list.Select(pxmx => new BillingItemDetailListOutput 3405 var resultList = pagedData.list.Select(pxmx => new BillingItemDetailListOutput
3381 { 3406 {
@@ -3390,7 +3415,9 @@ namespace NCC.Extend.LqKdKdjlb @@ -3390,7 +3415,9 @@ namespace NCC.Extend.LqKdKdjlb
3390 actualPrice = pxmx.ActualPrice, 3415 actualPrice = pxmx.ActualPrice,
3391 projectNumber = pxmx.ProjectNumber, 3416 projectNumber = pxmx.ProjectNumber,
3392 sourceType = pxmx.SourceType, 3417 sourceType = pxmx.SourceType,
3393 - remark = pxmx.Remark 3418 + remark = pxmx.Remark,
  3419 + storeId = pxmx.Glkdbh != null && billingStoreDict.ContainsKey(pxmx.Glkdbh) ? billingStoreDict[pxmx.Glkdbh] : "",
  3420 + storeName = pxmx.Glkdbh != null && billingStoreDict.ContainsKey(pxmx.Glkdbh) && !string.IsNullOrEmpty(billingStoreDict[pxmx.Glkdbh]) && storeDict.ContainsKey(billingStoreDict[pxmx.Glkdbh]) ? storeDict[billingStoreDict[pxmx.Glkdbh]] : ""
3394 }).ToList(); 3421 }).ToList();
3395 3422
3396 // 6. 返回分页结果 3423 // 6. 返回分页结果
netcore/src/Modularity/Extend/NCC.Extend/LqKhxxService.cs
@@ -28,6 +28,7 @@ using NCC.Extend.Entitys.lq_khxx; @@ -28,6 +28,7 @@ using NCC.Extend.Entitys.lq_khxx;
28 using NCC.Extend.Entitys.lq_mdxx; 28 using NCC.Extend.Entitys.lq_mdxx;
29 using NCC.Extend.Entitys.lq_xh_hyhk; 29 using NCC.Extend.Entitys.lq_xh_hyhk;
30 using NCC.Extend.Entitys.lq_xh_pxmx; 30 using NCC.Extend.Entitys.lq_xh_pxmx;
  31 +using NCC.Extend.Entitys.lq_xmzl;
31 using NCC.Extend.Interfaces.LqKhxx; 32 using NCC.Extend.Interfaces.LqKhxx;
32 using NCC.System.Entitys.Permission; 33 using NCC.System.Entitys.Permission;
33 using NCC.FriendlyException; 34 using NCC.FriendlyException;
@@ -366,6 +367,89 @@ namespace NCC.Extend.LqKhxx @@ -366,6 +367,89 @@ namespace NCC.Extend.LqKhxx
366 } 367 }
367 #endregion 368 #endregion
368 369
  370 + #region 判断客户是否开过指定类型的开单
  371 + /// <summary>
  372 + /// 判断客户是否开过生美的开单
  373 + /// </summary>
  374 + /// <param name="memberId">会员ID</param>
  375 + /// <returns>1表示有,0表示没有</returns>
  376 + [HttpGet("has-life-beauty-billing/{memberId}")]
  377 + public async Task<int> HasLifeBeautyBilling(string memberId)
  378 + {
  379 + if (string.IsNullOrEmpty(memberId))
  380 + {
  381 + throw NCCException.Oh("会员ID不能为空");
  382 + }
  383 +
  384 + // 查询该会员是否有开过生美品项的开单
  385 + var hasBilling = await _db.Queryable<LqKdKdjlbEntity>()
  386 + .InnerJoin<LqKdPxmxEntity>((kdjlb, pxmx) => kdjlb.Id == pxmx.Glkdbh)
  387 + .InnerJoin<LqXmzlEntity>((kdjlb, pxmx, xmzl) => pxmx.Px == xmzl.Id)
  388 + .Where((kdjlb, pxmx, xmzl) => kdjlb.Kdhy == memberId
  389 + && kdjlb.IsEffective == StatusEnum.有效.GetHashCode()
  390 + && pxmx.IsEffective == StatusEnum.有效.GetHashCode()
  391 + && xmzl.IsEffective == StatusEnum.有效.GetHashCode()
  392 + && xmzl.Qt2 == "生美")
  393 + .AnyAsync();
  394 +
  395 + return hasBilling ? 1 : 0;
  396 + }
  397 +
  398 + /// <summary>
  399 + /// 判断客户是否开过科美的开单
  400 + /// </summary>
  401 + /// <param name="memberId">会员ID</param>
  402 + /// <returns>1表示有,0表示没有</returns>
  403 + [HttpGet("has-tech-beauty-billing/{memberId}")]
  404 + public async Task<int> HasTechBeautyBilling(string memberId)
  405 + {
  406 + if (string.IsNullOrEmpty(memberId))
  407 + {
  408 + throw NCCException.Oh("会员ID不能为空");
  409 + }
  410 +
  411 + // 查询该会员是否有开过科美品项的开单
  412 + var hasBilling = await _db.Queryable<LqKdKdjlbEntity>()
  413 + .InnerJoin<LqKdPxmxEntity>((kdjlb, pxmx) => kdjlb.Id == pxmx.Glkdbh)
  414 + .InnerJoin<LqXmzlEntity>((kdjlb, pxmx, xmzl) => pxmx.Px == xmzl.Id)
  415 + .Where((kdjlb, pxmx, xmzl) => kdjlb.Kdhy == memberId
  416 + && kdjlb.IsEffective == StatusEnum.有效.GetHashCode()
  417 + && pxmx.IsEffective == StatusEnum.有效.GetHashCode()
  418 + && xmzl.IsEffective == StatusEnum.有效.GetHashCode()
  419 + && xmzl.Qt2 == "科美")
  420 + .AnyAsync();
  421 +
  422 + return hasBilling ? 1 : 0;
  423 + }
  424 +
  425 + /// <summary>
  426 + /// 判断客户是否开过医美的开单
  427 + /// </summary>
  428 + /// <param name="memberId">会员ID</param>
  429 + /// <returns>1表示有,0表示没有</returns>
  430 + [HttpGet("has-medical-beauty-billing/{memberId}")]
  431 + public async Task<int> HasMedicalBeautyBilling(string memberId)
  432 + {
  433 + if (string.IsNullOrEmpty(memberId))
  434 + {
  435 + throw NCCException.Oh("会员ID不能为空");
  436 + }
  437 +
  438 + // 查询该会员是否有开过医美品项的开单
  439 + var hasBilling = await _db.Queryable<LqKdKdjlbEntity>()
  440 + .InnerJoin<LqKdPxmxEntity>((kdjlb, pxmx) => kdjlb.Id == pxmx.Glkdbh)
  441 + .InnerJoin<LqXmzlEntity>((kdjlb, pxmx, xmzl) => pxmx.Px == xmzl.Id)
  442 + .Where((kdjlb, pxmx, xmzl) => kdjlb.Kdhy == memberId
  443 + && kdjlb.IsEffective == StatusEnum.有效.GetHashCode()
  444 + && pxmx.IsEffective == StatusEnum.有效.GetHashCode()
  445 + && xmzl.IsEffective == StatusEnum.有效.GetHashCode()
  446 + && xmzl.Qt2 == "医美")
  447 + .AnyAsync();
  448 +
  449 + return hasBilling ? 1 : 0;
  450 + }
  451 + #endregion
  452 +
369 #region 导出客户资料 453 #region 导出客户资料
370 /// <summary> 454 /// <summary>
371 /// 导出客户资料 455 /// 导出客户资料
netcore/src/Modularity/Extend/NCC.Extend/LqReimbursementApplicationService.cs
@@ -28,7 +28,7 @@ namespace NCC.Extend.LqReimbursementApplication @@ -28,7 +28,7 @@ namespace NCC.Extend.LqReimbursementApplication
28 /// <summary> 28 /// <summary>
29 /// 报销申请表服务 29 /// 报销申请表服务
30 /// </summary> 30 /// </summary>
31 - [ApiDescriptionSettings(Tag = "Extend",Name = "LqReimbursementApplication", Order = 200)] 31 + [ApiDescriptionSettings(Tag = "Extend", Name = "LqReimbursementApplication", Order = 200)]
32 [Route("api/Extend/[controller]")] 32 [Route("api/Extend/[controller]")]
33 public class LqReimbursementApplicationService : ILqReimbursementApplicationService, IDynamicApiController, ITransient 33 public class LqReimbursementApplicationService : ILqReimbursementApplicationService, IDynamicApiController, ITransient
34 { 34 {
@@ -43,7 +43,7 @@ namespace NCC.Extend.LqReimbursementApplication @@ -43,7 +43,7 @@ namespace NCC.Extend.LqReimbursementApplication
43 ISqlSugarRepository<LqReimbursementApplicationEntity> lqReimbursementApplicationRepository, 43 ISqlSugarRepository<LqReimbursementApplicationEntity> lqReimbursementApplicationRepository,
44 IUserManager userManager) 44 IUserManager userManager)
45 { 45 {
46 - _lqReimbursementApplicationRepository = lqReimbursementApplicationRepository; 46 + _lqReimbursementApplicationRepository = lqReimbursementApplicationRepository;
47 _db = _lqReimbursementApplicationRepository.Context; 47 _db = _lqReimbursementApplicationRepository.Context;
48 _userManager = userManager; 48 _userManager = userManager;
49 } 49 }
@@ -86,23 +86,23 @@ namespace NCC.Extend.LqReimbursementApplication @@ -86,23 +86,23 @@ namespace NCC.Extend.LqReimbursementApplication
86 .WhereIF(!string.IsNullOrEmpty(input.amount), p => p.Amount.Contains(input.amount)) 86 .WhereIF(!string.IsNullOrEmpty(input.amount), p => p.Amount.Contains(input.amount))
87 .WhereIF(!string.IsNullOrEmpty(input.approveUser), p => p.ApproveUser.Equals(input.approveUser)) 87 .WhereIF(!string.IsNullOrEmpty(input.approveUser), p => p.ApproveUser.Equals(input.approveUser))
88 .WhereIF(!string.IsNullOrEmpty(input.approveStatus), p => p.ApproveStatus.Contains(input.approveStatus)) 88 .WhereIF(!string.IsNullOrEmpty(input.approveStatus), p => p.ApproveStatus.Contains(input.approveStatus))
89 - // .WhereIF(queryApproveTime != null, p => p.ApproveTime >= new DateTime(startApproveTime.ToDate().Year, startApproveTime.ToDate().Month, startApproveTime.ToDate().Day, 0, 0, 0)) 89 + // .WhereIF(queryApproveTime != null, p => p.ApproveTime >= new DateTime(startApproveTime.ToDate().Year, startApproveTime.ToDate().Month, startApproveTime.ToDate().Day, 0, 0, 0))
90 //.WhereIF(queryApproveTime != null, p => p.ApproveTime <= new DateTime(endApproveTime.ToDate().Year, endApproveTime.ToDate().Month, endApproveTime.ToDate().Day, 23, 59, 59)) 90 //.WhereIF(queryApproveTime != null, p => p.ApproveTime <= new DateTime(endApproveTime.ToDate().Year, endApproveTime.ToDate().Month, endApproveTime.ToDate().Day, 23, 59, 59))
91 .WhereIF(!string.IsNullOrEmpty(input.purchaseRecordsId), p => p.PurchaseRecordsId.Contains(input.purchaseRecordsId)) 91 .WhereIF(!string.IsNullOrEmpty(input.purchaseRecordsId), p => p.PurchaseRecordsId.Contains(input.purchaseRecordsId))
92 - .Select(it=> new LqReimbursementApplicationListOutput 92 + .Select(it => new LqReimbursementApplicationListOutput
93 { 93 {
94 id = it.Id, 94 id = it.Id,
95 - applicationUserId=it.ApplicationUserId,  
96 - applicationUserName=it.ApplicationUserName,  
97 - applicationStoreId=it.ApplicationStoreId,  
98 - applicationTime=it.ApplicationTime,  
99 - amount=it.Amount,  
100 - approveUser=it.ApproveUser,  
101 - approveStatus=it.ApproveStatus,  
102 - approveTime=it.ApproveTime,  
103 - purchaseRecordsId=it.PurchaseRecordsId,  
104 - }).MergeTable().OrderBy(sidx+" "+input.sort).ToPagedListAsync(input.currentPage, input.pageSize);  
105 - return PageResult<LqReimbursementApplicationListOutput>.SqlSugarPageResult(data); 95 + applicationUserId = it.ApplicationUserId,
  96 + applicationUserName = it.ApplicationUserName,
  97 + applicationStoreId = it.ApplicationStoreId,
  98 + applicationTime = it.ApplicationTime,
  99 + amount = it.Amount,
  100 + approveUser = it.ApproveUser,
  101 + approveStatus = it.ApproveStatus,
  102 + approveTime = it.ApproveTime,
  103 + purchaseRecordsId = it.PurchaseRecordsId,
  104 + }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
  105 + return PageResult<LqReimbursementApplicationListOutput>.SqlSugarPageResult(data);
106 } 106 }
107 107
108 /// <summary> 108 /// <summary>
@@ -116,16 +116,16 @@ namespace NCC.Extend.LqReimbursementApplication @@ -116,16 +116,16 @@ namespace NCC.Extend.LqReimbursementApplication
116 var userInfo = await _userManager.GetUserInfo(); 116 var userInfo = await _userManager.GetUserInfo();
117 var entity = input.Adapt<LqReimbursementApplicationEntity>(); 117 var entity = input.Adapt<LqReimbursementApplicationEntity>();
118 entity.Id = YitIdHelper.NextId().ToString(); 118 entity.Id = YitIdHelper.NextId().ToString();
119 - 119 +
120 try 120 try
121 { 121 {
122 //开启事务 122 //开启事务
123 _db.BeginTran(); 123 _db.BeginTran();
124 - 124 +
125 // 保存报销申请表 125 // 保存报销申请表
126 var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync(); 126 var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
127 if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1000); 127 if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1000);
128 - 128 +
129 // 更新购买记录的审批单编号和审批状态为"待审批" 129 // 更新购买记录的审批单编号和审批状态为"待审批"
130 if (input.selectedPurchaseRecordIds != null && input.selectedPurchaseRecordIds.Count > 0) 130 if (input.selectedPurchaseRecordIds != null && input.selectedPurchaseRecordIds.Count > 0)
131 { 131 {
@@ -134,14 +134,14 @@ namespace NCC.Extend.LqReimbursementApplication @@ -134,14 +134,14 @@ namespace NCC.Extend.LqReimbursementApplication
134 .SetColumns(it => it.ApplicationId == entity.Id) 134 .SetColumns(it => it.ApplicationId == entity.Id)
135 .Where(it => input.selectedPurchaseRecordIds.Contains(it.Id)) 135 .Where(it => input.selectedPurchaseRecordIds.Contains(it.Id))
136 .ExecuteCommandAsync(); 136 .ExecuteCommandAsync();
137 - 137 +
138 // 再更新ApproveStatus(分开更新确保都能执行) 138 // 再更新ApproveStatus(分开更新确保都能执行)
139 await _db.Updateable<LqPurchaseRecordsEntity>() 139 await _db.Updateable<LqPurchaseRecordsEntity>()
140 .SetColumns(it => it.ApproveStatus == "待审批") 140 .SetColumns(it => it.ApproveStatus == "待审批")
141 .Where(it => input.selectedPurchaseRecordIds.Contains(it.Id)) 141 .Where(it => input.selectedPurchaseRecordIds.Contains(it.Id))
142 .ExecuteCommandAsync(); 142 .ExecuteCommandAsync();
143 } 143 }
144 - 144 +
145 //关闭事务 145 //关闭事务
146 _db.CommitTran(); 146 _db.CommitTran();
147 } 147 }
@@ -178,23 +178,23 @@ namespace NCC.Extend.LqReimbursementApplication @@ -178,23 +178,23 @@ namespace NCC.Extend.LqReimbursementApplication
178 .WhereIF(!string.IsNullOrEmpty(input.amount), p => p.Amount.Contains(input.amount)) 178 .WhereIF(!string.IsNullOrEmpty(input.amount), p => p.Amount.Contains(input.amount))
179 .WhereIF(!string.IsNullOrEmpty(input.approveUser), p => p.ApproveUser.Equals(input.approveUser)) 179 .WhereIF(!string.IsNullOrEmpty(input.approveUser), p => p.ApproveUser.Equals(input.approveUser))
180 .WhereIF(!string.IsNullOrEmpty(input.approveStatus), p => p.ApproveStatus.Contains(input.approveStatus)) 180 .WhereIF(!string.IsNullOrEmpty(input.approveStatus), p => p.ApproveStatus.Contains(input.approveStatus))
181 - // .WhereIF(queryApproveTime != null, p => p.ApproveTime >= new DateTime(startApproveTime.ToDate().Year, startApproveTime.ToDate().Month, startApproveTime.ToDate().Day, 0, 0, 0))  
182 - // .WhereIF(queryApproveTime != null, p => p.ApproveTime <= new DateTime(endApproveTime.ToDate().Year, endApproveTime.ToDate().Month, endApproveTime.ToDate().Day, 23, 59, 59)) 181 + // .WhereIF(queryApproveTime != null, p => p.ApproveTime >= new DateTime(startApproveTime.ToDate().Year, startApproveTime.ToDate().Month, startApproveTime.ToDate().Day, 0, 0, 0))
  182 + // .WhereIF(queryApproveTime != null, p => p.ApproveTime <= new DateTime(endApproveTime.ToDate().Year, endApproveTime.ToDate().Month, endApproveTime.ToDate().Day, 23, 59, 59))
183 .WhereIF(!string.IsNullOrEmpty(input.purchaseRecordsId), p => p.PurchaseRecordsId.Contains(input.purchaseRecordsId)) 183 .WhereIF(!string.IsNullOrEmpty(input.purchaseRecordsId), p => p.PurchaseRecordsId.Contains(input.purchaseRecordsId))
184 - .Select(it=> new LqReimbursementApplicationListOutput 184 + .Select(it => new LqReimbursementApplicationListOutput
185 { 185 {
186 id = it.Id, 186 id = it.Id,
187 - applicationUserId=it.ApplicationUserId,  
188 - applicationUserName=it.ApplicationUserName,  
189 - applicationStoreId=it.ApplicationStoreId,  
190 - applicationTime=it.ApplicationTime,  
191 - amount=it.Amount,  
192 - approveUser=it.ApproveUser,  
193 - approveStatus=it.ApproveStatus,  
194 - approveTime=it.ApproveTime,  
195 - purchaseRecordsId=it.PurchaseRecordsId,  
196 - }).MergeTable().OrderBy(sidx+" "+input.sort).ToListAsync();  
197 - return data; 187 + applicationUserId = it.ApplicationUserId,
  188 + applicationUserName = it.ApplicationUserName,
  189 + applicationStoreId = it.ApplicationStoreId,
  190 + applicationTime = it.ApplicationTime,
  191 + amount = it.Amount,
  192 + approveUser = it.ApproveUser,
  193 + approveStatus = it.ApproveStatus,
  194 + approveTime = it.ApproveTime,
  195 + purchaseRecordsId = it.PurchaseRecordsId,
  196 + }).MergeTable().OrderBy(sidx + " " + input.sort).ToListAsync();
  197 + return data;
198 } 198 }
199 199
200 /// <summary> 200 /// <summary>
@@ -216,7 +216,7 @@ namespace NCC.Extend.LqReimbursementApplication @@ -216,7 +216,7 @@ namespace NCC.Extend.LqReimbursementApplication
216 { 216 {
217 exportData = await this.GetNoPagingList(input); 217 exportData = await this.GetNoPagingList(input);
218 } 218 }
219 - List<ParamsModel> paramList = "[{\"value\":\"申请编号\",\"field\":\"id\"},{\"value\":\"申请人编号\",\"field\":\"applicationUserId\"},{\"value\":\"申请人姓名\",\"field\":\"applicationUserName\"},{\"value\":\"申请门店\",\"field\":\"applicationStoreId\"},{\"value\":\"申请时间\",\"field\":\"applicationTime\"},{\"value\":\"总金额\",\"field\":\"amount\"},{\"value\":\"审批人\",\"field\":\"approveUser\"},{\"value\":\"审批结果\",\"field\":\"approveStatus\"},{\"value\":\"审批时间\",\"field\":\"approveTime\"},{\"value\":\"关联购买编号\",\"field\":\"purchaseRecordsId\"},]".ToList<ParamsModel>(); 219 + List<ParamsModel> paramList = "[{\"value\":\"申请编号\",\"field\":\"id\"},{\"value\":\"申请人编号\",\"field\":\"applicationUserId\"},{\"value\":\"申请人姓名\",\"field\":\"applicationUserName\"},{\"value\":\"申请门店\",\"field\":\"applicationStoreId\"},{\"value\":\"申请时间\",\"field\":\"applicationTime\"},{\"value\":\"总金额\",\"field\":\"amount\"},{\"value\":\"审批人\",\"field\":\"approveUser\"},{\"value\":\"审批结果\",\"field\":\"approveStatus\"},{\"value\":\"审批时间\",\"field\":\"approveTime\"},{\"value\":\"关联购买编号\",\"field\":\"purchaseRecordsId\"},]".ToList<ParamsModel>();
220 ExcelConfig excelconfig = new ExcelConfig(); 220 ExcelConfig excelconfig = new ExcelConfig();
221 excelconfig.FileName = "报销申请表.xls"; 221 excelconfig.FileName = "报销申请表.xls";
222 excelconfig.HeadFont = "微软雅黑"; 222 excelconfig.HeadFont = "微软雅黑";
@@ -259,7 +259,7 @@ namespace NCC.Extend.LqReimbursementApplication @@ -259,7 +259,7 @@ namespace NCC.Extend.LqReimbursementApplication
259 //开启事务 259 //开启事务
260 _db.BeginTran(); 260 _db.BeginTran();
261 //批量删除报销申请表 261 //批量删除报销申请表
262 - await _db.Deleteable<LqReimbursementApplicationEntity>().In(d => d.Id,ids).ExecuteCommandAsync(); 262 + await _db.Deleteable<LqReimbursementApplicationEntity>().In(d => d.Id, ids).ExecuteCommandAsync();
263 //关闭事务 263 //关闭事务
264 _db.CommitTran(); 264 _db.CommitTran();
265 } 265 }
@@ -285,7 +285,7 @@ namespace NCC.Extend.LqReimbursementApplication @@ -285,7 +285,7 @@ namespace NCC.Extend.LqReimbursementApplication
285 { 285 {
286 //开启事务 286 //开启事务
287 _db.BeginTran(); 287 _db.BeginTran();
288 - 288 +
289 // 获取原有的关联购买记录ID 289 // 获取原有的关联购买记录ID
290 var oldEntity = await _db.Queryable<LqReimbursementApplicationEntity>().FirstAsync(p => p.Id == id); 290 var oldEntity = await _db.Queryable<LqReimbursementApplicationEntity>().FirstAsync(p => p.Id == id);
291 var oldIds = new List<string>(); 291 var oldIds = new List<string>();
@@ -294,10 +294,10 @@ namespace NCC.Extend.LqReimbursementApplication @@ -294,10 +294,10 @@ namespace NCC.Extend.LqReimbursementApplication
294 // 获取原有购买记录ID列表 294 // 获取原有购买记录ID列表
295 oldIds = oldEntity.PurchaseRecordsId.Split(',').Where(x => !string.IsNullOrEmpty(x)).ToList(); 295 oldIds = oldEntity.PurchaseRecordsId.Split(',').Where(x => !string.IsNullOrEmpty(x)).ToList();
296 } 296 }
297 - 297 +
298 // 获取新的购买记录ID列表 298 // 获取新的购买记录ID列表
299 var newIds = input.selectedPurchaseRecordIds ?? new List<string>(); 299 var newIds = input.selectedPurchaseRecordIds ?? new List<string>();
300 - 300 +
301 // 确保 purchaseRecordsId 字段包含所有选中的记录ID(逗号分隔) 301 // 确保 purchaseRecordsId 字段包含所有选中的记录ID(逗号分隔)
302 if (newIds.Count > 0) 302 if (newIds.Count > 0)
303 { 303 {
@@ -307,27 +307,27 @@ namespace NCC.Extend.LqReimbursementApplication @@ -307,27 +307,27 @@ namespace NCC.Extend.LqReimbursementApplication
307 { 307 {
308 input.purchaseRecordsId = null; 308 input.purchaseRecordsId = null;
309 } 309 }
310 - 310 +
311 // 找出需要移除关联的记录(在旧列表中但不在新列表中) 311 // 找出需要移除关联的记录(在旧列表中但不在新列表中)
312 var idsToRemove = oldIds.Where(x => !newIds.Contains(x)).ToList(); 312 var idsToRemove = oldIds.Where(x => !newIds.Contains(x)).ToList();
313 if (idsToRemove.Count > 0) 313 if (idsToRemove.Count > 0)
314 { 314 {
315 // 清除这些购买记录的审批单编号和审批状态 315 // 清除这些购买记录的审批单编号和审批状态
316 await _db.Updateable<LqPurchaseRecordsEntity>() 316 await _db.Updateable<LqPurchaseRecordsEntity>()
317 - .SetColumns(it => new LqPurchaseRecordsEntity  
318 - { 317 + .SetColumns(it => new LqPurchaseRecordsEntity
  318 + {
319 ApplicationId = null, 319 ApplicationId = null,
320 ApproveStatus = "未审批" 320 ApproveStatus = "未审批"
321 }) 321 })
322 .Where(it => idsToRemove.Contains(it.Id)) 322 .Where(it => idsToRemove.Contains(it.Id))
323 .ExecuteCommandAsync(); 323 .ExecuteCommandAsync();
324 } 324 }
325 - 325 +
326 // 更新报销申请表(确保 purchaseRecordsId 字段被正确更新) 326 // 更新报销申请表(确保 purchaseRecordsId 字段被正确更新)
327 var entity = input.Adapt<LqReimbursementApplicationEntity>(); 327 var entity = input.Adapt<LqReimbursementApplicationEntity>();
328 var isOk = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); 328 var isOk = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
329 if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1001); 329 if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1001);
330 - 330 +
331 // 更新所有选中的购买记录的审批单编号和审批状态为"待审批" 331 // 更新所有选中的购买记录的审批单编号和审批状态为"待审批"
332 // 包括新追加的记录和已存在的记录(确保状态正确) 332 // 包括新追加的记录和已存在的记录(确保状态正确)
333 if (newIds.Count > 0) 333 if (newIds.Count > 0)
@@ -337,14 +337,14 @@ namespace NCC.Extend.LqReimbursementApplication @@ -337,14 +337,14 @@ namespace NCC.Extend.LqReimbursementApplication
337 .SetColumns(it => it.ApplicationId == id) 337 .SetColumns(it => it.ApplicationId == id)
338 .Where(it => newIds.Contains(it.Id)) 338 .Where(it => newIds.Contains(it.Id))
339 .ExecuteCommandAsync(); 339 .ExecuteCommandAsync();
340 - 340 +
341 // 再更新ApproveStatus(分开更新确保都能执行) 341 // 再更新ApproveStatus(分开更新确保都能执行)
342 await _db.Updateable<LqPurchaseRecordsEntity>() 342 await _db.Updateable<LqPurchaseRecordsEntity>()
343 .SetColumns(it => it.ApproveStatus == "待审批") 343 .SetColumns(it => it.ApproveStatus == "待审批")
344 .Where(it => newIds.Contains(it.Id)) 344 .Where(it => newIds.Contains(it.Id))
345 .ExecuteCommandAsync(); 345 .ExecuteCommandAsync();
346 } 346 }
347 - 347 +
348 //关闭事务 348 //关闭事务
349 _db.CommitTran(); 349 _db.CommitTran();
350 } 350 }
@@ -380,18 +380,18 @@ namespace NCC.Extend.LqReimbursementApplication @@ -380,18 +380,18 @@ namespace NCC.Extend.LqReimbursementApplication
380 var userInfo = await _userManager.GetUserInfo(); 380 var userInfo = await _userManager.GetUserInfo();
381 var entity = await _db.Queryable<LqReimbursementApplicationEntity>().FirstAsync(p => p.Id == id); 381 var entity = await _db.Queryable<LqReimbursementApplicationEntity>().FirstAsync(p => p.Id == id);
382 _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); 382 _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005);
383 - 383 +
384 try 384 try
385 { 385 {
386 //开启事务 386 //开启事务
387 _db.BeginTran(); 387 _db.BeginTran();
388 - 388 +
389 // 更新申请表的审批状态 389 // 更新申请表的审批状态
390 entity.ApproveStatus = "已审批"; 390 entity.ApproveStatus = "已审批";
391 entity.ApproveTime = DateTime.Now; 391 entity.ApproveTime = DateTime.Now;
392 entity.ApproveUser = userInfo.userId; 392 entity.ApproveUser = userInfo.userId;
393 await _db.Updateable(entity).ExecuteCommandAsync(); 393 await _db.Updateable(entity).ExecuteCommandAsync();
394 - 394 +
395 // 更新关联的购买记录 395 // 更新关联的购买记录
396 if (!string.IsNullOrEmpty(entity.PurchaseRecordsId)) 396 if (!string.IsNullOrEmpty(entity.PurchaseRecordsId))
397 { 397 {
@@ -399,8 +399,8 @@ namespace NCC.Extend.LqReimbursementApplication @@ -399,8 +399,8 @@ namespace NCC.Extend.LqReimbursementApplication
399 if (purchaseIds.Count > 0) 399 if (purchaseIds.Count > 0)
400 { 400 {
401 await _db.Updateable<LqPurchaseRecordsEntity>() 401 await _db.Updateable<LqPurchaseRecordsEntity>()
402 - .SetColumns(it => new LqPurchaseRecordsEntity  
403 - { 402 + .SetColumns(it => new LqPurchaseRecordsEntity
  403 + {
404 ApproveStatus = "已审批", 404 ApproveStatus = "已审批",
405 ApproveTime = DateTime.Now, 405 ApproveTime = DateTime.Now,
406 ApproveUser = userInfo.userId 406 ApproveUser = userInfo.userId
@@ -409,7 +409,7 @@ namespace NCC.Extend.LqReimbursementApplication @@ -409,7 +409,7 @@ namespace NCC.Extend.LqReimbursementApplication
409 .ExecuteCommandAsync(); 409 .ExecuteCommandAsync();
410 } 410 }
411 } 411 }
412 - 412 +
413 //关闭事务 413 //关闭事务
414 _db.CommitTran(); 414 _db.CommitTran();
415 } 415 }
@@ -432,18 +432,18 @@ namespace NCC.Extend.LqReimbursementApplication @@ -432,18 +432,18 @@ namespace NCC.Extend.LqReimbursementApplication
432 var userInfo = await _userManager.GetUserInfo(); 432 var userInfo = await _userManager.GetUserInfo();
433 var entity = await _db.Queryable<LqReimbursementApplicationEntity>().FirstAsync(p => p.Id == id); 433 var entity = await _db.Queryable<LqReimbursementApplicationEntity>().FirstAsync(p => p.Id == id);
434 _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); 434 _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005);
435 - 435 +
436 try 436 try
437 { 437 {
438 //开启事务 438 //开启事务
439 _db.BeginTran(); 439 _db.BeginTran();
440 - 440 +
441 // 更新申请表的审批状态 441 // 更新申请表的审批状态
442 entity.ApproveStatus = "未通过"; 442 entity.ApproveStatus = "未通过";
443 entity.ApproveTime = DateTime.Now; 443 entity.ApproveTime = DateTime.Now;
444 entity.ApproveUser = userInfo.userId; 444 entity.ApproveUser = userInfo.userId;
445 await _db.Updateable(entity).ExecuteCommandAsync(); 445 await _db.Updateable(entity).ExecuteCommandAsync();
446 - 446 +
447 // 更新关联的购买记录 447 // 更新关联的购买记录
448 if (!string.IsNullOrEmpty(entity.PurchaseRecordsId)) 448 if (!string.IsNullOrEmpty(entity.PurchaseRecordsId))
449 { 449 {
@@ -451,8 +451,8 @@ namespace NCC.Extend.LqReimbursementApplication @@ -451,8 +451,8 @@ namespace NCC.Extend.LqReimbursementApplication
451 if (purchaseIds.Count > 0) 451 if (purchaseIds.Count > 0)
452 { 452 {
453 await _db.Updateable<LqPurchaseRecordsEntity>() 453 await _db.Updateable<LqPurchaseRecordsEntity>()
454 - .SetColumns(it => new LqPurchaseRecordsEntity  
455 - { 454 + .SetColumns(it => new LqPurchaseRecordsEntity
  455 + {
456 ApproveStatus = "未通过", 456 ApproveStatus = "未通过",
457 ApproveTime = DateTime.Now, 457 ApproveTime = DateTime.Now,
458 ApproveUser = userInfo.userId 458 ApproveUser = userInfo.userId
@@ -461,7 +461,7 @@ namespace NCC.Extend.LqReimbursementApplication @@ -461,7 +461,7 @@ namespace NCC.Extend.LqReimbursementApplication
461 .ExecuteCommandAsync(); 461 .ExecuteCommandAsync();
462 } 462 }
463 } 463 }
464 - 464 +
465 //关闭事务 465 //关闭事务
466 _db.CommitTran(); 466 _db.CommitTran();
467 } 467 }
netcore/src/Modularity/Extend/NCC.Extend/LqTkjlbService.cs
@@ -1127,7 +1127,7 @@ namespace NCC.Extend.LqTkjlb @@ -1127,7 +1127,7 @@ namespace NCC.Extend.LqTkjlb
1127 FROM lq_tkjlb tk 1127 FROM lq_tkjlb tk
1128 INNER JOIN lq_kd_kdjlb kd ON tk.F_MemberId = kd.kdhy 1128 INNER JOIN lq_kd_kdjlb kd ON tk.F_MemberId = kd.kdhy
1129 AND kd.F_IsEffective = 1 1129 AND kd.F_IsEffective = 1
1130 - WHERE 1=1 {timeFilter} {eventFilter} {storeFilter}"; 1130 + WHERE 1=1 AND kd.sfyj > 0 {timeFilter} {eventFilter} {storeFilter}";
1131 1131
1132 var kdResult = await _db.Ado.SqlQueryAsync<dynamic>(kdSql); 1132 var kdResult = await _db.Ado.SqlQueryAsync<dynamic>(kdSql);
1133 var kdCount = Convert.ToInt32(kdResult?.FirstOrDefault()?.kd_count ?? 0); 1133 var kdCount = Convert.ToInt32(kdResult?.FirstOrDefault()?.kd_count ?? 0);
netcore/src/Modularity/Extend/NCC.Extend/LqXhHyhkService.cs
@@ -16,18 +16,22 @@ using NCC.Common.Model.NPOI; @@ -16,18 +16,22 @@ using NCC.Common.Model.NPOI;
16 using NCC.DataEncryption; 16 using NCC.DataEncryption;
17 using NCC.Dependency; 17 using NCC.Dependency;
18 using NCC.DynamicApiController; 18 using NCC.DynamicApiController;
  19 +using NCC.Extend.Entitys.Dto.LqPersonTimesRecord;
19 using NCC.Extend.Entitys.Dto.LqXhHyhk; 20 using NCC.Extend.Entitys.Dto.LqXhHyhk;
20 using NCC.Extend.Entitys.Dto.LqXhJksyj; 21 using NCC.Extend.Entitys.Dto.LqXhJksyj;
21 using NCC.Extend.Entitys.Dto.LqXhKjbsyj; 22 using NCC.Extend.Entitys.Dto.LqXhKjbsyj;
22 using NCC.Extend.Entitys.Dto.LqXhPxmx; 23 using NCC.Extend.Entitys.Dto.LqXhPxmx;
  24 +using NCC.Extend.Entitys.Dto.LqYyjl;
23 using NCC.Extend.Entitys.Enum; 25 using NCC.Extend.Entitys.Enum;
24 using NCC.Extend.Entitys.lq_kd_kdjlb; 26 using NCC.Extend.Entitys.lq_kd_kdjlb;
25 using NCC.Extend.Entitys.lq_kd_pxmx; 27 using NCC.Extend.Entitys.lq_kd_pxmx;
26 using NCC.Extend.Entitys.lq_khxx; 28 using NCC.Extend.Entitys.lq_khxx;
  29 +using NCC.Extend.Entitys.lq_person_times_record;
27 using NCC.Extend.Entitys.lq_xh_hyhk; 30 using NCC.Extend.Entitys.lq_xh_hyhk;
28 using NCC.Extend.Entitys.lq_xh_jksyj; 31 using NCC.Extend.Entitys.lq_xh_jksyj;
29 using NCC.Extend.Entitys.lq_xh_kjbsyj; 32 using NCC.Extend.Entitys.lq_xh_kjbsyj;
30 using NCC.Extend.Entitys.lq_xh_pxmx; 33 using NCC.Extend.Entitys.lq_xh_pxmx;
  34 +using NCC.Extend.Entitys.lq_xmzl;
31 using NCC.Extend.Interfaces.LqXhHyhk; 35 using NCC.Extend.Interfaces.LqXhHyhk;
32 using NCC.FriendlyException; 36 using NCC.FriendlyException;
33 using NCC.JsonSerialization; 37 using NCC.JsonSerialization;
@@ -111,13 +115,12 @@ namespace NCC.Extend.LqXhHyhk @@ -111,13 +115,12 @@ namespace NCC.Extend.LqXhHyhk
111 115
112 // 2. 查询品项明细列表 116 // 2. 查询品项明细列表
113 var lqXhPxmxList = await _db.Queryable<LqXhPxmxEntity>().Where(w => w.ConsumeInfoId == entity.Id).ToListAsync(); 117 var lqXhPxmxList = await _db.Queryable<LqXhPxmxEntity>().Where(w => w.ConsumeInfoId == entity.Id).ToListAsync();
114 -  
115 // 3. 查询健康师业绩列表 118 // 3. 查询健康师业绩列表
116 var lqXhJksyjList = await _db.Queryable<LqXhJksyjEntity>().Where(w => w.Glkdbh == entity.Id).ToListAsync(); 119 var lqXhJksyjList = await _db.Queryable<LqXhJksyjEntity>().Where(w => w.Glkdbh == entity.Id).ToListAsync();
117 -  
118 // 4. 查询科技部老师业绩列表 120 // 4. 查询科技部老师业绩列表
119 var lqXhKjbsyjList = await _db.Queryable<LqXhKjbsyjEntity>().Where(w => w.Glkdbh == entity.Id).ToListAsync(); 121 var lqXhKjbsyjList = await _db.Queryable<LqXhKjbsyjEntity>().Where(w => w.Glkdbh == entity.Id).ToListAsync();
120 - 122 + // 获取人次记录列表
  123 + var personTimesRecordList = await _db.Queryable<LqPersonTimesRecordEntity>().Where(x => x.BusinessId == entity.Id && x.IsEffective == StatusEnum.有效.GetHashCode()).ToListAsync();
121 // 5. 构建品项明细输出,每个品项关联对应的业绩信息 124 // 5. 构建品项明细输出,每个品项关联对应的业绩信息
122 var pxmxOutputList = new List<LqXhPxmxInfoOutput>(); 125 var pxmxOutputList = new List<LqXhPxmxInfoOutput>();
123 foreach (var pxmx in lqXhPxmxList) 126 foreach (var pxmx in lqXhPxmxList)
@@ -299,8 +302,7 @@ namespace NCC.Extend.LqXhHyhk @@ -299,8 +302,7 @@ namespace NCC.Extend.LqXhHyhk
299 // 如果两个都传入了,需要同时JOIN两个表 302 // 如果两个都传入了,需要同时JOIN两个表
300 if (!string.IsNullOrEmpty(input.jksId) && !string.IsNullOrEmpty(input.kjblsId)) 303 if (!string.IsNullOrEmpty(input.jksId) && !string.IsNullOrEmpty(input.kjblsId))
301 { 304 {
302 - query = _db.Queryable<LqXhJksyjEntity, LqXhKjbsyjEntity, LqXhHyhkEntity>(  
303 - (jksyj, kjbsyj, hyhk) => jksyj.Glkdbh == hyhk.Id && kjbsyj.Glkdbh == hyhk.Id) 305 + query = _db.Queryable<LqXhJksyjEntity, LqXhKjbsyjEntity, LqXhHyhkEntity>((jksyj, kjbsyj, hyhk) => jksyj.Glkdbh == hyhk.Id && kjbsyj.Glkdbh == hyhk.Id)
304 .Where((jksyj, kjbsyj, hyhk) => jksyj.Jkszh == input.jksId && jksyj.IsEffective == StatusEnum.有效.GetHashCode()) 306 .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()) 307 .Where((jksyj, kjbsyj, hyhk) => kjbsyj.Kjblszh == input.kjblsId && kjbsyj.IsEffective == StatusEnum.有效.GetHashCode())
306 .Select((jksyj, kjbsyj, hyhk) => hyhk) 308 .Select((jksyj, kjbsyj, hyhk) => hyhk)
@@ -369,6 +371,7 @@ namespace NCC.Extend.LqXhHyhk @@ -369,6 +371,7 @@ namespace NCC.Extend.LqXhHyhk
369 overtimeCoefficient = it.OvertimeCoefficient, 371 overtimeCoefficient = it.OvertimeCoefficient,
370 originalSgfy = it.OriginalSgfy, 372 originalSgfy = it.OriginalSgfy,
371 overtimeSgfy = it.OvertimeSgfy, 373 overtimeSgfy = it.OvertimeSgfy,
  374 + appointmentId = it.AppointmentId,
372 }) 375 })
373 .MergeTable() 376 .MergeTable()
374 .OrderBy($"{sidx} {sort}") 377 .OrderBy($"{sidx} {sort}")
@@ -517,101 +520,6 @@ namespace NCC.Extend.LqXhHyhk @@ -517,101 +520,6 @@ namespace NCC.Extend.LqXhHyhk
517 } 520 }
518 #endregion 521 #endregion
519 522
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;  
530 - List<string> queryHksj = input.hksj != null ? input.hksj.Split(',').ToObeject<List<string>>() : null;  
531 - DateTime? startHksj = queryHksj != null ? Ext.GetDateTime(queryHksj.First()) : null;  
532 - DateTime? endHksj = queryHksj != null ? Ext.GetDateTime(queryHksj.Last()) : null;  
533 - var data = await _db.Queryable<LqXhHyhkEntity>()  
534 - .WhereIF(!string.IsNullOrEmpty(input.keyword), p => p.Hymc.Contains(input.keyword) || p.Hyzh.Contains(input.keyword) || p.MemberPhone.Contains(input.keyword))  
535 - .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id))  
536 - .WhereIF(!string.IsNullOrEmpty(input.md), p => p.Md.Equals(input.md))  
537 - .WhereIF(!string.IsNullOrEmpty(input.mdbh), p => p.Mdbh.Contains(input.mdbh))  
538 - .WhereIF(!string.IsNullOrEmpty(input.mdmc), p => p.Mdmc.Contains(input.mdmc))  
539 - .WhereIF(!string.IsNullOrEmpty(input.hy), p => p.Hy.Equals(input.hy))  
540 - .WhereIF(!string.IsNullOrEmpty(input.hyzh), p => p.Hyzh.Contains(input.hyzh))  
541 - .WhereIF(!string.IsNullOrEmpty(input.hymc), p => p.Hymc.Contains(input.hymc))  
542 - .WhereIF(!string.IsNullOrEmpty(input.gklx), p => p.Gklx.Equals(input.gklx))  
543 - .WhereIF(!string.IsNullOrEmpty(input.sfykjb), p => p.Sfykjb.Equals(input.sfykjb))  
544 - .WhereIF(queryHksj != null, p => p.Hksj >= new DateTime(startHksj.ToDate().Year, startHksj.ToDate().Month, startHksj.ToDate().Day, 0, 0, 0))  
545 - .WhereIF(queryHksj != null, p => p.Hksj <= new DateTime(endHksj.ToDate().Year, endHksj.ToDate().Month, endHksj.ToDate().Day, 23, 59, 59))  
546 - .WhereIF(!string.IsNullOrEmpty(input.czry), p => p.Czry.Equals(input.czry))  
547 - .WhereIF(input.isEffective != 0, p => p.IsEffective == input.isEffective)  
548 - .Select(it => new LqXhHyhkListOutput  
549 - {  
550 - id = it.Id,  
551 - md = it.Md,  
552 - mdbh = it.Mdbh,  
553 - mdmc = it.Mdmc,  
554 - hy = it.Hy,  
555 - hyzh = it.Hyzh,  
556 - hymc = SqlFunc.Subqueryable<LqKhxxEntity>().Where(w => w.Id == it.Hy).Select(w => w.Khmc),  
557 - gklx = it.Gklx,  
558 - xfje = SqlFunc.ToString(it.Xfje),  
559 - sgfy = SqlFunc.ToString(it.Sgfy),  
560 - sfykjb = it.Sfykjb,  
561 - hksj = it.Hksj,  
562 - czry = it.Czry,  
563 - memberPhone = SqlFunc.Subqueryable<LqKhxxEntity>().Where(w => w.Id == it.Hy).Select(w => w.Sjh),  
564 - isEffective = it.IsEffective,  
565 - })  
566 - .MergeTable()  
567 - .OrderBy(sidx + " " + input.sort)  
568 - .ToPagedListAsync(input.currentPage, input.pageSize);  
569 -  
570 - // 获取当前页的耗卡记录ID列表  
571 - var consumeIds = data.list.Select(x => x.id).ToList();  
572 -  
573 - // 批量查询耗卡明细  
574 - var consumeDetails = new List<LqXhPxmxInfoOutput>();  
575 - if (consumeIds.Any())  
576 - {  
577 - consumeDetails = await _db.Queryable<LqXhPxmxEntity>()  
578 - .Where(x => consumeIds.Contains(x.ConsumeInfoId) && x.IsEffective == StatusEnum.有效.GetHashCode())  
579 - .Select(x => new LqXhPxmxInfoOutput  
580 - {  
581 - id = x.Id,  
582 - consumeInfoId = x.ConsumeInfoId,  
583 - billingItemId = x.BillingItemId,  
584 - px = x.Px,  
585 - pxmc = x.Pxmc,  
586 - pxjg = x.Pxjg,  
587 - memberId = x.MemberId,  
588 - createTime = x.CreateTIme,  
589 - projectNumber = x.ProjectNumber,  
590 - originalProjectNumber = x.OriginalProjectNumber,  
591 - overtimeProjectNumber = x.OvertimeProjectNumber,  
592 - sourceType = x.SourceType,  
593 - totalPrice = x.TotalPrice,  
594 - isEffective = x.IsEffective,  
595 - })  
596 - .ToListAsync();  
597 - }  
598 -  
599 - // 按耗卡记录ID分组耗卡明细  
600 - var consumeDetailsGrouped = consumeDetails.GroupBy(x => x.consumeInfoId)  
601 - .ToDictionary(g => g.Key, g => g.ToList());  
602 -  
603 - // 为每个耗卡记录分配耗卡明细  
604 - foreach (var item in data.list)  
605 - {  
606 - item.ConsumeDetails = consumeDetailsGrouped.ContainsKey(item.id)  
607 - ? consumeDetailsGrouped[item.id]  
608 - : new List<LqXhPxmxInfoOutput>();  
609 - }  
610 -  
611 - return PageResult<LqXhHyhkListOutput>.SqlSugarPageResult(data);  
612 - }  
613 - #endregion  
614 -  
615 #region 根据健康师ID获取耗卡列表 523 #region 根据健康师ID获取耗卡列表
616 /// <summary> 524 /// <summary>
617 /// 根据健康师ID获取耗卡列表 525 /// 根据健康师ID获取耗卡列表
@@ -670,8 +578,7 @@ namespace NCC.Extend.LqXhHyhk @@ -670,8 +578,7 @@ namespace NCC.Extend.LqXhHyhk
670 } 578 }
671 579
672 // 通过健康师业绩表关联查询耗卡记录 580 // 通过健康师业绩表关联查询耗卡记录
673 - var data = await _db.Queryable<LqXhJksyjEntity, LqXhHyhkEntity>(  
674 - (jksyj, hyhk) => jksyj.Glkdbh == hyhk.Id) 581 + var data = await _db.Queryable<LqXhJksyjEntity, LqXhHyhkEntity>((jksyj, hyhk) => jksyj.Glkdbh == hyhk.Id)
675 .Where((jksyj, hyhk) => jksyj.Jkszh == input.jksId) 582 .Where((jksyj, hyhk) => jksyj.Jkszh == input.jksId)
676 .WhereIF(input.isEffective != 0, (jksyj, hyhk) => jksyj.IsEffective == input.isEffective && hyhk.IsEffective == input.isEffective) 583 .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()) 584 .WhereIF(input.isEffective == 0, (jksyj, hyhk) => jksyj.IsEffective == StatusEnum.有效.GetHashCode() && hyhk.IsEffective == StatusEnum.有效.GetHashCode())
@@ -705,15 +612,41 @@ namespace NCC.Extend.LqXhHyhk @@ -705,15 +612,41 @@ namespace NCC.Extend.LqXhHyhk
705 .OrderBy($"{sidx} {sort}") 612 .OrderBy($"{sidx} {sort}")
706 .ToPagedListAsync(input.currentPage, input.pageSize); 613 .ToPagedListAsync(input.currentPage, input.pageSize);
707 614
  615 +
  616 +
708 // 获取当前页的耗卡记录ID列表 617 // 获取当前页的耗卡记录ID列表
709 var consumeIds = data.list.Select(x => x.id).ToList(); 618 var consumeIds = data.list.Select(x => x.id).ToList();
710 - 619 + // 获取人次记录列表
  620 + var personTimesRecordList = await _db.Queryable<LqPersonTimesRecordEntity>().Where(x => consumeIds.Contains(x.BusinessId) && x.IsEffective == StatusEnum.有效.GetHashCode())
  621 + .Select(x => new LqPersonTimesRecordListOutput
  622 + {
  623 + id = x.Id,
  624 + businessId = x.BusinessId,
  625 + businessType = x.BusinessType,
  626 + personType = x.PersonType,
  627 + personId = x.PersonId,
  628 + personName = x.PersonName,
  629 + memberId = x.MemberId,
  630 + memberName = x.MemberName,
  631 + workDate = x.WorkDate,
  632 + workMonth = x.WorkMonth,
  633 + quantity = x.Quantity,
  634 + createTime = x.CreateTime,
  635 + isEffective = x.IsEffective,
  636 + })
  637 + .ToListAsync();
  638 + // 按耗卡记录ID分组人次记录
  639 + var personTimesRecordGrouped = personTimesRecordList.GroupBy(x => x.businessId).ToDictionary(g => g.Key, g => g.ToList());
  640 + // 为每个耗卡记录分配人次记录
  641 + foreach (var item in data.list)
  642 + {
  643 + item.personTimesRecordList = personTimesRecordGrouped.ContainsKey(item.id) ? personTimesRecordGrouped[item.id] : new List<LqPersonTimesRecordListOutput>();
  644 + }
711 // 批量查询耗卡明细 645 // 批量查询耗卡明细
712 var consumeDetails = new List<LqXhPxmxInfoOutput>(); 646 var consumeDetails = new List<LqXhPxmxInfoOutput>();
713 if (consumeIds.Any()) 647 if (consumeIds.Any())
714 { 648 {
715 - consumeDetails = await _db.Queryable<LqXhPxmxEntity>()  
716 - .Where(x => consumeIds.Contains(x.ConsumeInfoId) && x.IsEffective == StatusEnum.有效.GetHashCode()) 649 + consumeDetails = await _db.Queryable<LqXhPxmxEntity>().Where(x => consumeIds.Contains(x.ConsumeInfoId) && x.IsEffective == StatusEnum.有效.GetHashCode())
717 .Select(x => new LqXhPxmxInfoOutput 650 .Select(x => new LqXhPxmxInfoOutput
718 { 651 {
719 id = x.Id, 652 id = x.Id,
@@ -733,19 +666,13 @@ namespace NCC.Extend.LqXhHyhk @@ -733,19 +666,13 @@ namespace NCC.Extend.LqXhHyhk
733 }) 666 })
734 .ToListAsync(); 667 .ToListAsync();
735 } 668 }
736 -  
737 // 按耗卡记录ID分组耗卡明细 669 // 按耗卡记录ID分组耗卡明细
738 - var consumeDetailsGrouped = consumeDetails.GroupBy(x => x.consumeInfoId)  
739 - .ToDictionary(g => g.Key, g => g.ToList());  
740 - 670 + var consumeDetailsGrouped = consumeDetails.GroupBy(x => x.consumeInfoId).ToDictionary(g => g.Key, g => g.ToList());
741 // 为每个耗卡记录分配耗卡明细 671 // 为每个耗卡记录分配耗卡明细
742 foreach (var item in data.list) 672 foreach (var item in data.list)
743 { 673 {
744 - item.ConsumeDetails = consumeDetailsGrouped.ContainsKey(item.id)  
745 - ? consumeDetailsGrouped[item.id]  
746 - : new List<LqXhPxmxInfoOutput>(); 674 + item.ConsumeDetails = consumeDetailsGrouped.ContainsKey(item.id) ? consumeDetailsGrouped[item.id] : new List<LqXhPxmxInfoOutput>();
747 } 675 }
748 -  
749 return PageResult<LqXhHyhkListOutput>.SqlSugarPageResult(data); 676 return PageResult<LqXhHyhkListOutput>.SqlSugarPageResult(data);
750 } 677 }
751 catch (Exception ex) 678 catch (Exception ex)
@@ -956,6 +883,7 @@ namespace NCC.Extend.LqXhHyhk @@ -956,6 +883,7 @@ namespace NCC.Extend.LqXhHyhk
956 entity.UpdateTime = DateTime.Now; 883 entity.UpdateTime = DateTime.Now;
957 entity.OvertimeCoefficient = input.overtimeCoefficient ?? 0; 884 entity.OvertimeCoefficient = input.overtimeCoefficient ?? 0;
958 entity.OriginalSgfy = input.sgfy; 885 entity.OriginalSgfy = input.sgfy;
  886 + entity.AppointmentId = input.appointmentId;
959 //加班手工费 = 原始手工费 * 加班系数 887 //加班手工费 = 原始手工费 * 加班系数
960 entity.OvertimeSgfy = entity.OriginalSgfy * entity.OvertimeCoefficient; 888 entity.OvertimeSgfy = entity.OriginalSgfy * entity.OvertimeCoefficient;
961 //最终手工费 = 原始手工费 + 加班手工费 889 //最终手工费 = 原始手工费 + 加班手工费
@@ -979,6 +907,7 @@ namespace NCC.Extend.LqXhHyhk @@ -979,6 +907,7 @@ namespace NCC.Extend.LqXhHyhk
979 var allPxmxEntities = new List<LqXhPxmxEntity>(); 907 var allPxmxEntities = new List<LqXhPxmxEntity>();
980 var allJksyjEntities = new List<LqXhJksyjEntity>(); 908 var allJksyjEntities = new List<LqXhJksyjEntity>();
981 var allKjbsyjEntities = new List<LqXhKjbsyjEntity>(); 909 var allKjbsyjEntities = new List<LqXhKjbsyjEntity>();
  910 + var allPersonTimesRecordEntities = new List<LqPersonTimesRecordEntity>();
982 // 处理品项明细列表 911 // 处理品项明细列表
983 if (input.lqXhPxmxList != null && input.lqXhPxmxList.Any()) 912 if (input.lqXhPxmxList != null && input.lqXhPxmxList.Any())
984 { 913 {
@@ -1002,7 +931,7 @@ namespace NCC.Extend.LqXhHyhk @@ -1002,7 +931,7 @@ namespace NCC.Extend.LqXhHyhk
1002 Pxjg = item.pxjg, 931 Pxjg = item.pxjg,
1003 SourceType = item.sourceType, 932 SourceType = item.sourceType,
1004 IsEffective = StatusEnum.有效.GetHashCode(), 933 IsEffective = StatusEnum.有效.GetHashCode(),
1005 - 934 + ItemCategory = await _db.Queryable<LqXmzlEntity>().Where(x => x.Id == item.px).Select(x => x.Qt2).FirstAsync(),
1006 }; 935 };
1007 allPxmxEntities.Add(lqXhPxmxEntity); 936 allPxmxEntities.Add(lqXhPxmxEntity);
1008 937
@@ -1074,6 +1003,57 @@ namespace NCC.Extend.LqXhHyhk @@ -1074,6 +1003,57 @@ namespace NCC.Extend.LqXhHyhk
1074 } 1003 }
1075 } 1004 }
1076 } 1005 }
  1006 + //获取这次耗卡有多少个健康师
  1007 + var jksCount = allJksyjEntities.GroupBy(x => x.Jks).Count();
  1008 + //添加到人次表里面去
  1009 + foreach (var item in allJksyjEntities.Select(x => x.Jks).Distinct())
  1010 + {
  1011 + LqPersonTimesRecordEntity personTimesRecordEntity = new LqPersonTimesRecordEntity
  1012 + {
  1013 + Id = YitIdHelper.NextId().ToString(),
  1014 + BusinessId = newEntity.Id,
  1015 + BusinessType = "耗卡",
  1016 + PersonType = "健康师",
  1017 + PersonId = item,
  1018 + PersonName = allJksyjEntities.Where(x => x.Jks == item).Select(x => x.Jksxm).First(),
  1019 + MemberId = entity.Hy,
  1020 + MemberName = memberInfo.Khmc,
  1021 + WorkDate = input.hksj,
  1022 + WorkMonth = input.hksj.ToDate().ToString("yyyyMM"),
  1023 + Quantity = 1 / (decimal)jksCount,
  1024 + CreateTime = DateTime.Now,
  1025 + IsEffective = StatusEnum.有效.GetHashCode(),
  1026 + };
  1027 + allPersonTimesRecordEntities.Add(personTimesRecordEntity);
  1028 + }
  1029 + //获取这次耗卡有多少个科技部老师
  1030 + var kjbCount = allKjbsyjEntities.GroupBy(x => x.Kjbls).Count();
  1031 + //添加到人次表里面去
  1032 + foreach (var item in allKjbsyjEntities.Select(x => x.Kjbls).Distinct())
  1033 + {
  1034 + LqPersonTimesRecordEntity personTimesRecordEntity = new LqPersonTimesRecordEntity
  1035 + {
  1036 + Id = YitIdHelper.NextId().ToString(),
  1037 + BusinessId = newEntity.Id,
  1038 + BusinessType = "耗卡",
  1039 + PersonType = "科技部老师",
  1040 + PersonId = item,
  1041 + PersonName = allKjbsyjEntities.Where(x => x.Kjbls == item).Select(x => x.Kjblsxm).First(),
  1042 + MemberId = entity.Hy,
  1043 + MemberName = memberInfo.Khmc,
  1044 + WorkDate = input.hksj,
  1045 + WorkMonth = input.hksj.ToDate().ToString("yyyyMM"),
  1046 + Quantity = 1 / (decimal)kjbCount,
  1047 + CreateTime = DateTime.Now,
  1048 + IsEffective = StatusEnum.有效.GetHashCode(),
  1049 + };
  1050 + allPersonTimesRecordEntities.Add(personTimesRecordEntity);
  1051 + }
  1052 + // 批量插入人次记录
  1053 + if (allPersonTimesRecordEntities.Any())
  1054 + {
  1055 + await _db.Insertable(allPersonTimesRecordEntities).ExecuteCommandAsync();
  1056 + }
1077 // 批量插入品项明细 1057 // 批量插入品项明细
1078 if (allPxmxEntities.Any()) 1058 if (allPxmxEntities.Any())
1079 { 1059 {
@@ -1264,6 +1244,7 @@ namespace NCC.Extend.LqXhHyhk @@ -1264,6 +1244,7 @@ namespace NCC.Extend.LqXhHyhk
1264 entity.OriginalSgfy = input.sgfy; 1244 entity.OriginalSgfy = input.sgfy;
1265 entity.OvertimeSgfy = (decimal)(entity.OvertimeCoefficient * input.sgfy); 1245 entity.OvertimeSgfy = (decimal)(entity.OvertimeCoefficient * input.sgfy);
1266 entity.Sgfy = entity.OriginalSgfy + entity.OvertimeSgfy; 1246 entity.Sgfy = entity.OriginalSgfy + entity.OvertimeSgfy;
  1247 + entity.AppointmentId = input.appointmentId;
1267 //更新会员耗卡记录 1248 //更新会员耗卡记录
1268 await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); 1249 await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
1269 1250
@@ -1280,10 +1261,12 @@ namespace NCC.Extend.LqXhHyhk @@ -1280,10 +1261,12 @@ namespace NCC.Extend.LqXhHyhk
1280 await _db.Deleteable<LqXhJksyjEntity>().Where(u => u.Glkdbh == id).ExecuteCommandAsync(); 1261 await _db.Deleteable<LqXhJksyjEntity>().Where(u => u.Glkdbh == id).ExecuteCommandAsync();
1281 await _db.Deleteable<LqXhKjbsyjEntity>().Where(u => u.Glkdbh == id).ExecuteCommandAsync(); 1262 await _db.Deleteable<LqXhKjbsyjEntity>().Where(u => u.Glkdbh == id).ExecuteCommandAsync();
1282 await _db.Deleteable<LqXhPxmxEntity>().Where(u => u.ConsumeInfoId == id).ExecuteCommandAsync(); 1263 await _db.Deleteable<LqXhPxmxEntity>().Where(u => u.ConsumeInfoId == id).ExecuteCommandAsync();
  1264 + await _db.Deleteable<LqPersonTimesRecordEntity>().Where(u => u.BusinessId == id).ExecuteCommandAsync();
1283 // 收集所有需要插入的实体,然后批量插入 1265 // 收集所有需要插入的实体,然后批量插入
1284 var allPxmxEntities = new List<LqXhPxmxEntity>(); 1266 var allPxmxEntities = new List<LqXhPxmxEntity>();
1285 var allJksyjEntities = new List<LqXhJksyjEntity>(); 1267 var allJksyjEntities = new List<LqXhJksyjEntity>();
1286 var allKjbsyjEntities = new List<LqXhKjbsyjEntity>(); 1268 var allKjbsyjEntities = new List<LqXhKjbsyjEntity>();
  1269 + var allPersonTimesRecordEntities = new List<LqPersonTimesRecordEntity>();
1287 // 处理品项明细列表 1270 // 处理品项明细列表
1288 if (input.lqXhPxmxList != null && input.lqXhPxmxList.Any()) 1271 if (input.lqXhPxmxList != null && input.lqXhPxmxList.Any())
1289 { 1272 {
@@ -1307,6 +1290,7 @@ namespace NCC.Extend.LqXhHyhk @@ -1307,6 +1290,7 @@ namespace NCC.Extend.LqXhHyhk
1307 OriginalProjectNumber = item.projectNumber ?? 0, 1290 OriginalProjectNumber = item.projectNumber ?? 0,
1308 OvertimeProjectNumber = (decimal)(entity.OvertimeCoefficient * (item.projectNumber ?? 0)), 1291 OvertimeProjectNumber = (decimal)(entity.OvertimeCoefficient * (item.projectNumber ?? 0)),
1309 ProjectNumber = (decimal)((item.projectNumber ?? 0) + (entity.OvertimeCoefficient * (item.projectNumber ?? 0))), 1292 ProjectNumber = (decimal)((item.projectNumber ?? 0) + (entity.OvertimeCoefficient * (item.projectNumber ?? 0))),
  1293 + ItemCategory = await _db.Queryable<LqXmzlEntity>().Where(x => x.Id == item.px).Select(x => x.Qt2).FirstAsync(),
1310 }; 1294 };
1311 allPxmxEntities.Add(lqXhPxmxEntity); 1295 allPxmxEntities.Add(lqXhPxmxEntity);
1312 1296
@@ -1376,6 +1360,57 @@ namespace NCC.Extend.LqXhHyhk @@ -1376,6 +1360,57 @@ namespace NCC.Extend.LqXhHyhk
1376 } 1360 }
1377 } 1361 }
1378 } 1362 }
  1363 + //获取这次耗卡有多少个健康师
  1364 + var jksCount = allJksyjEntities.GroupBy(x => x.Jks).Count();
  1365 + //添加到人次表里面去
  1366 + foreach (var item in allJksyjEntities.Select(x => x.Jks).Distinct())
  1367 + {
  1368 + LqPersonTimesRecordEntity personTimesRecordEntity = new LqPersonTimesRecordEntity
  1369 + {
  1370 + Id = YitIdHelper.NextId().ToString(),
  1371 + BusinessId = input.id,
  1372 + BusinessType = "耗卡",
  1373 + PersonType = "健康师",
  1374 + PersonId = item,
  1375 + PersonName = allJksyjEntities.Where(x => x.Jks == item).Select(x => x.Jksxm).First(),
  1376 + MemberId = entity.Hy,
  1377 + MemberName = memberInfo.Khmc,
  1378 + WorkDate = input.hksj,
  1379 + WorkMonth = input.hksj.ToDate().ToString("yyyyMM"),
  1380 + Quantity = 1 / (decimal)jksCount,
  1381 + CreateTime = DateTime.Now,
  1382 + IsEffective = StatusEnum.有效.GetHashCode(),
  1383 + };
  1384 + allPersonTimesRecordEntities.Add(personTimesRecordEntity);
  1385 + }
  1386 + //获取这次耗卡有多少个科技部老师
  1387 + var kjbCount = allKjbsyjEntities.GroupBy(x => x.Kjbls).Count();
  1388 + //添加到人次表里面去
  1389 + foreach (var item in allKjbsyjEntities.Select(x => x.Kjbls).Distinct())
  1390 + {
  1391 + LqPersonTimesRecordEntity personTimesRecordEntity = new LqPersonTimesRecordEntity
  1392 + {
  1393 + Id = YitIdHelper.NextId().ToString(),
  1394 + BusinessId = input.id,
  1395 + BusinessType = "耗卡",
  1396 + PersonType = "科技部老师",
  1397 + PersonId = item,
  1398 + PersonName = allKjbsyjEntities.Where(x => x.Kjbls == item).Select(x => x.Kjblsxm).First(),
  1399 + MemberId = entity.Hy,
  1400 + MemberName = memberInfo.Khmc,
  1401 + WorkDate = input.hksj,
  1402 + WorkMonth = input.hksj.ToDate().ToString("yyyyMM"),
  1403 + Quantity = 1 / (decimal)kjbCount,
  1404 + CreateTime = DateTime.Now,
  1405 + IsEffective = StatusEnum.有效.GetHashCode(),
  1406 + };
  1407 + allPersonTimesRecordEntities.Add(personTimesRecordEntity);
  1408 + }
  1409 + // 批量插入人次记录
  1410 + if (allPersonTimesRecordEntities.Any())
  1411 + {
  1412 + await _db.Insertable(allPersonTimesRecordEntities).ExecuteCommandAsync();
  1413 + }
1379 // 批量插入品项明细 1414 // 批量插入品项明细
1380 if (allPxmxEntities.Any()) 1415 if (allPxmxEntities.Any())
1381 { 1416 {
@@ -1430,6 +1465,9 @@ namespace NCC.Extend.LqXhHyhk @@ -1430,6 +1465,9 @@ namespace NCC.Extend.LqXhHyhk
1430 //清空子表数据 1465 //清空子表数据
1431 await _db.Deleteable<LqXhPxmxEntity>().Where(u => u.ConsumeInfoId == id).ExecuteCommandAsync(); 1466 await _db.Deleteable<LqXhPxmxEntity>().Where(u => u.ConsumeInfoId == id).ExecuteCommandAsync();
1432 1467
  1468 + //清空子表数据
  1469 + await _db.Deleteable<LqPersonTimesRecordEntity>().Where(u => u.BusinessId == id).ExecuteCommandAsync();
  1470 +
1433 //关闭事务 1471 //关闭事务
1434 _db.CommitTran(); 1472 _db.CommitTran();
1435 } 1473 }
@@ -1550,6 +1588,8 @@ namespace NCC.Extend.LqXhHyhk @@ -1550,6 +1588,8 @@ namespace NCC.Extend.LqXhHyhk
1550 await _db.Updateable<LqXhJksyjEntity>().SetColumns(it => new LqXhJksyjEntity { IsEffective = StatusEnum.无效.GetHashCode() }).Where(w => w.Glkdbh == id).ExecuteCommandAsync(); 1588 await _db.Updateable<LqXhJksyjEntity>().SetColumns(it => new LqXhJksyjEntity { IsEffective = StatusEnum.无效.GetHashCode() }).Where(w => w.Glkdbh == id).ExecuteCommandAsync();
1551 //更新科技部老师业绩表状态 1589 //更新科技部老师业绩表状态
1552 await _db.Updateable<LqXhKjbsyjEntity>().SetColumns(it => new LqXhKjbsyjEntity { IsEffective = StatusEnum.无效.GetHashCode() }).Where(w => w.Glkdbh == id).ExecuteCommandAsync(); 1590 await _db.Updateable<LqXhKjbsyjEntity>().SetColumns(it => new LqXhKjbsyjEntity { IsEffective = StatusEnum.无效.GetHashCode() }).Where(w => w.Glkdbh == id).ExecuteCommandAsync();
  1591 + //更新人次记录表状态
  1592 + await _db.Updateable<LqPersonTimesRecordEntity>().SetColumns(it => new LqPersonTimesRecordEntity { IsEffective = StatusEnum.无效.GetHashCode() }).Where(w => w.BusinessId == id).ExecuteCommandAsync();
1553 //关闭事务 1593 //关闭事务
1554 _db.CommitTran(); 1594 _db.CommitTran();
1555 return LqhyhkInfo; 1595 return LqhyhkInfo;
netcore/src/Modularity/Extend/NCC.Extend/LqYaoyjlService.cs
@@ -61,7 +61,7 @@ namespace NCC.Extend.LqYaoyjl @@ -61,7 +61,7 @@ namespace NCC.Extend.LqYaoyjl
61 { 61 {
62 var entity = await _db.Queryable<LqYaoyjlEntity>().FirstAsync(p => p.Id == id); 62 var entity = await _db.Queryable<LqYaoyjlEntity>().FirstAsync(p => p.Id == id);
63 var output = entity.Adapt<LqYaoyjlInfoOutput>(); 63 var output = entity.Adapt<LqYaoyjlInfoOutput>();
64 - output.storeName = SqlFunc.Subqueryable<LqMdxxEntity>().Where(u => u.Id == entity.StoreId).Select(u => u.Dm); 64 + output.storeName = _db.Queryable<LqMdxxEntity>().Where(u => u.Id == entity.StoreId).Select(u => u.Dm).First();
65 return output; 65 return output;
66 } 66 }
67 #endregion 67 #endregion
@@ -108,6 +108,7 @@ namespace NCC.Extend.LqYaoyjl @@ -108,6 +108,7 @@ namespace NCC.Extend.LqYaoyjl
108 storeName = SqlFunc.Subqueryable<LqMdxxEntity>().Where(u => u.Id == it.StoreId).Select(u => u.Dm), 108 storeName = SqlFunc.Subqueryable<LqMdxxEntity>().Where(u => u.Id == it.StoreId).Select(u => u.Dm),
109 createTime = it.CreateTime, 109 createTime = it.CreateTime,
110 yyrName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == it.Yyr).Select(u => u.RealName), 110 yyrName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == it.Yyr).Select(u => u.RealName),
  111 + tkbh = it.Tkbh,
111 }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize); 112 }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
112 return PageResult<LqYaoyjlListOutput>.SqlSugarPageResult(data); 113 return PageResult<LqYaoyjlListOutput>.SqlSugarPageResult(data);
113 } 114 }
@@ -171,6 +172,7 @@ namespace NCC.Extend.LqYaoyjl @@ -171,6 +172,7 @@ namespace NCC.Extend.LqYaoyjl
171 lxsj = it.Lxsj, 172 lxsj = it.Lxsj,
172 lxjl = it.Lxjl, 173 lxjl = it.Lxjl,
173 yyrName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.MobilePhone == it.Yyr).Select(u => u.RealName), 174 yyrName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.MobilePhone == it.Yyr).Select(u => u.RealName),
  175 + tkbh = it.Tkbh,
174 }).MergeTable().OrderBy(sidx + " " + input.sort).ToListAsync(); 176 }).MergeTable().OrderBy(sidx + " " + input.sort).ToListAsync();
175 return data; 177 return data;
176 } 178 }
netcore/src/Modularity/Extend/NCC.Extend/LqYyjlService.cs
@@ -17,6 +17,7 @@ using NCC.Dependency; @@ -17,6 +17,7 @@ using NCC.Dependency;
17 using NCC.DynamicApiController; 17 using NCC.DynamicApiController;
18 using NCC.Extend.Entitys.Dto.LqYyjl; 18 using NCC.Extend.Entitys.Dto.LqYyjl;
19 using NCC.Extend.Entitys.lq_mdxx; 19 using NCC.Extend.Entitys.lq_mdxx;
  20 +using NCC.Extend.Entitys.lq_yaoyjl;
20 using NCC.Extend.Entitys.lq_yyjl; 21 using NCC.Extend.Entitys.lq_yyjl;
21 using NCC.Extend.Interfaces.LqYyjl; 22 using NCC.Extend.Interfaces.LqYyjl;
22 using NCC.FriendlyException; 23 using NCC.FriendlyException;
@@ -47,6 +48,7 @@ namespace NCC.Extend.LqYyjl @@ -47,6 +48,7 @@ namespace NCC.Extend.LqYyjl
47 _db = _lqYyjlRepository.Context; 48 _db = _lqYyjlRepository.Context;
48 _userManager = userManager; 49 _userManager = userManager;
49 } 50 }
  51 +
50 #region 预约记录 52 #region 预约记录
51 /// <summary> 53 /// <summary>
52 /// 获取预约记录 54 /// 获取预约记录
@@ -80,6 +82,13 @@ namespace NCC.Extend.LqYyjl @@ -80,6 +82,13 @@ namespace NCC.Extend.LqYyjl
80 output.yyjksName = healthCoach?.RealName; 82 output.yyjksName = healthCoach?.RealName;
81 } 83 }
82 84
  85 + //获取邀约记录
  86 + if (!string.IsNullOrEmpty(entity.InviteId))
  87 + {
  88 + var invite = await _db.Queryable<LqYaoyjlEntity>().Where(u => u.Id == entity.InviteId).FirstAsync();
  89 + output.InviteTime = invite?.Yysj;
  90 + }
  91 +
83 return output; 92 return output;
84 } 93 }
85 #endregion 94 #endregion
@@ -138,6 +147,9 @@ namespace NCC.Extend.LqYyjl @@ -138,6 +147,9 @@ namespace NCC.Extend.LqYyjl
138 yyrName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == it.Yyr).Select(u => u.RealName), 147 yyrName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == it.Yyr).Select(u => u.RealName),
139 yyjksName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == it.Yyjks).Select(u => u.RealName), 148 yyjksName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == it.Yyjks).Select(u => u.RealName),
140 djmdName = SqlFunc.Subqueryable<LqMdxxEntity>().Where(u => u.Id == it.Djmd).Select(u => u.Dm), 149 djmdName = SqlFunc.Subqueryable<LqMdxxEntity>().Where(u => u.Id == it.Djmd).Select(u => u.Dm),
  150 + NoDealRemark = it.NoDealRemark,
  151 + InviteId = it.InviteId,
  152 + InviteTime = SqlFunc.Subqueryable<LqYaoyjlEntity>().Where(u => u.Id == it.InviteId).Select(u => SqlFunc.ToDate(u.Yysj)),
141 }) 153 })
142 .MergeTable() 154 .MergeTable()
143 .OrderBy(sidx + " " + input.sort) 155 .OrderBy(sidx + " " + input.sort)
@@ -155,12 +167,20 @@ namespace NCC.Extend.LqYyjl @@ -155,12 +167,20 @@ namespace NCC.Extend.LqYyjl
155 [HttpPost("")] 167 [HttpPost("")]
156 public async Task Create([FromBody] LqYyjlCrInput input) 168 public async Task Create([FromBody] LqYyjlCrInput input)
157 { 169 {
158 - var userInfo = await _userManager.GetUserInfo();  
159 var entity = input.Adapt<LqYyjlEntity>(); 170 var entity = input.Adapt<LqYyjlEntity>();
160 entity.Id = YitIdHelper.NextId().ToString(); 171 entity.Id = YitIdHelper.NextId().ToString();
161 entity.Czr = _userManager.UserId; 172 entity.Czr = _userManager.UserId;
162 entity.Czsj = DateTime.Now; 173 entity.Czsj = DateTime.Now;
163 entity.CreateTime = DateTime.Now; 174 entity.CreateTime = DateTime.Now;
  175 + //判断邀约记录是否存在
  176 + if (!string.IsNullOrEmpty(input.InviteId))
  177 + {
  178 + var invite = await _db.Queryable<LqYaoyjlEntity>().Where(u => u.Id == input.InviteId).FirstAsync();
  179 + if (invite == null)
  180 + {
  181 + throw NCCException.Oh("邀约记录不存在");
  182 + }
  183 + }
164 var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync(); 184 var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
165 if (!(isOk > 0)) 185 if (!(isOk > 0))
166 throw NCCException.Oh(ErrorCode.COM1000); 186 throw NCCException.Oh(ErrorCode.COM1000);
@@ -337,5 +357,23 @@ namespace NCC.Extend.LqYyjl @@ -337,5 +357,23 @@ namespace NCC.Extend.LqYyjl
337 throw NCCException.Oh(ErrorCode.COM1002); 357 throw NCCException.Oh(ErrorCode.COM1002);
338 } 358 }
339 #endregion 359 #endregion
  360 +
  361 + #region 添加未成交说明
  362 + /// <summary>
  363 + /// 添加未成交说明
  364 + /// </summary>
  365 + /// <param name="input">参数</param>
  366 + /// <returns></returns>
  367 + [HttpPost("AddNoDealRemark")]
  368 + public async Task AddNoDealRemark([FromBody] LqYyjlAddNoDealRemarkInput input)
  369 + {
  370 + var entity = await _db.Queryable<LqYyjlEntity>().FirstAsync(p => p.Id == input.id);
  371 + _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005);
  372 + entity.NoDealRemark = input.noDealRemark;
  373 + var isOk = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
  374 + if (!(isOk > 0))
  375 + throw NCCException.Oh(ErrorCode.COM1001);
  376 + }
  377 + #endregion
340 } 378 }
341 } 379 }
sql/创建人次记录表.sql 0 → 100644
  1 +-- ============================================
  2 +-- 创建人次记录表(lq_person_times_record)
  3 +-- ============================================
  4 +-- 说明:用于记录耗卡/开单时健康师或科技老师的工作人次
  5 +-- 支持人头统计(按健康师+月份+客户去重累加)和人次统计(按健康师+日期+客户去重累加)
  6 +--
  7 +-- 业务场景:
  8 +-- 1. 耗卡时记录健康师或科技老师的工作人次
  9 +-- 2. 未来可能记录开单时的工作人次
  10 +--
  11 +-- 统计规则:
  12 +-- - 人头统计:按健康师+月份+客户去重,累加数量
  13 +-- - 人次统计:按健康师+日期+客户去重,累加数量
  14 +-- ============================================
  15 +
  16 +CREATE TABLE IF NOT EXISTS `lq_person_times_record` (
  17 + `F_Id` VARCHAR(50) NOT NULL COMMENT '主键ID',
  18 + `F_BusinessId` VARCHAR(50) NULL COMMENT '关联业务记录ID',
  19 + `F_BusinessType` VARCHAR(20) NULL COMMENT '业务类型(耗卡/开单)',
  20 + `F_PersonType` VARCHAR(20) NULL COMMENT '人员类型(健康师/科技老师)',
  21 + `F_PersonId` VARCHAR(50) NULL COMMENT '人员ID',
  22 + `F_PersonName` VARCHAR(100) NULL COMMENT '人员姓名',
  23 + `F_MemberId` VARCHAR(50) NULL COMMENT '客户ID',
  24 + `F_MemberName` VARCHAR(100) NULL COMMENT '客户姓名',
  25 + `F_WorkDate` DATE NULL COMMENT '工作日期(用于人次统计,格式:YYYY-MM-DD)',
  26 + `F_WorkMonth` VARCHAR(6) NULL COMMENT '工作月份(用于人头统计,格式:202511)',
  27 + `F_Quantity` DECIMAL(10,2) NULL COMMENT '数量',
  28 + `F_CreateTime` DATETIME NULL COMMENT '创建时间',
  29 + `F_IsEffective` INT NULL DEFAULT 1 COMMENT '是否有效',
  30 + PRIMARY KEY (`F_Id`),
  31 + INDEX `idx_person_month_member` (`F_PersonId`, `F_WorkMonth`, `F_MemberId`) COMMENT '人头统计索引(健康师+月份+客户)',
  32 + INDEX `idx_person_date_member` (`F_PersonId`, `F_WorkDate`, `F_MemberId`) COMMENT '人次统计索引(健康师+日期+客户)',
  33 + INDEX `idx_business` (`F_BusinessId`, `F_BusinessType`) COMMENT '业务查询索引'
  34 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='人次记录表';
  35 +
  36 +-- ============================================
  37 +-- 验证表结构
  38 +-- ============================================
  39 +-- SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, COLUMN_COMMENT
  40 +-- FROM INFORMATION_SCHEMA.COLUMNS
  41 +-- WHERE TABLE_NAME = 'lq_person_times_record'
  42 +-- ORDER BY ORDINAL_POSITION;
  43 +
  44 +-- ============================================
  45 +-- 验证索引
  46 +-- ============================================
  47 +-- SHOW INDEX FROM lq_person_times_record;
  48 +
sql/查询邀约时间和联系时间不在同一天的记录.sql 0 → 100644
  1 +-- ============================================
  2 +-- 查询 lq_yaoyjl 表中邀约时间(yysj)和联系时间(lxsj)不在同一天的记录
  3 +-- ============================================
  4 +-- 说明:查询邀约时间和联系时间不在同一天的数据,用于数据校验或分析
  5 +--
  6 +-- 查询逻辑:
  7 +-- 1. 两个时间都不为空,但日期不同
  8 +-- 2. 其中一个为空,另一个不为空(视为不在同一天)
  9 +-- 3. 两个都为空的情况不包含在结果中(因为无法判断是否在同一天)
  10 +
  11 +-- ============================================
  12 +-- 基础查询:查询不在同一天的记录
  13 +-- ============================================
  14 +SELECT
  15 + F_Id AS 邀约编号,
  16 + yyr AS 邀约人,
  17 + yysj AS 邀约时间,
  18 + DATE(yysj) AS 邀约日期,
  19 + lxsj AS 联系时间,
  20 + DATE(lxsj) AS 联系日期,
  21 + yykh AS 邀约客户,
  22 + yykhxm AS 邀约客户姓名,
  23 + F_CreateTime AS 创建时间
  24 +FROM lq_yaoyjl
  25 +WHERE (
  26 + -- 两个时间都不为空,但日期不同
  27 + (yysj IS NOT NULL AND lxsj IS NOT NULL AND DATE(yysj) != DATE(lxsj))
  28 + OR
  29 + -- 邀约时间为空,联系时间不为空
  30 + (yysj IS NULL AND lxsj IS NOT NULL)
  31 + OR
  32 + -- 联系时间为空,邀约时间不为空
  33 + (yysj IS NOT NULL AND lxsj IS NULL)
  34 +)
  35 +ORDER BY F_CreateTime DESC;
  36 +
  37 +-- ============================================
  38 +-- 统计查询:统计不在同一天的记录数量
  39 +-- ============================================
  40 +SELECT
  41 + COUNT(*) AS 不在同一天的记录数,
  42 + COUNT(CASE WHEN yysj IS NOT NULL AND lxsj IS NOT NULL AND DATE(yysj) != DATE(lxsj) THEN 1 END) AS 两个时间都有但日期不同,
  43 + COUNT(CASE WHEN yysj IS NULL AND lxsj IS NOT NULL THEN 1 END) AS 邀约时间为空,
  44 + COUNT(CASE WHEN yysj IS NOT NULL AND lxsj IS NULL THEN 1 END) AS 联系时间为空
  45 +FROM lq_yaoyjl
  46 +WHERE (
  47 + (yysj IS NOT NULL AND lxsj IS NOT NULL AND DATE(yysj) != DATE(lxsj))
  48 + OR (yysj IS NULL AND lxsj IS NOT NULL)
  49 + OR (yysj IS NOT NULL AND lxsj IS NULL)
  50 +);
  51 +
  52 +-- ============================================
  53 +-- 详细分析查询:按日期差异分组统计
  54 +-- ============================================
  55 +SELECT
  56 + CASE
  57 + WHEN yysj IS NULL AND lxsj IS NOT NULL THEN '邀约时间为空'
  58 + WHEN yysj IS NOT NULL AND lxsj IS NULL THEN '联系时间为空'
  59 + WHEN yysj IS NOT NULL AND lxsj IS NOT NULL THEN CONCAT('相差', DATEDIFF(lxsj, yysj), '天')
  60 + END AS 日期差异类型,
  61 + COUNT(*) AS 记录数
  62 +FROM lq_yaoyjl
  63 +WHERE (
  64 + (yysj IS NOT NULL AND lxsj IS NOT NULL AND DATE(yysj) != DATE(lxsj))
  65 + OR (yysj IS NULL AND lxsj IS NOT NULL)
  66 + OR (yysj IS NOT NULL AND lxsj IS NULL)
  67 +)
  68 +GROUP BY
  69 + CASE
  70 + WHEN yysj IS NULL AND lxsj IS NOT NULL THEN '邀约时间为空'
  71 + WHEN yysj IS NOT NULL AND lxsj IS NULL THEN '联系时间为空'
  72 + WHEN yysj IS NOT NULL AND lxsj IS NOT NULL THEN CONCAT('相差', DATEDIFF(lxsj, yysj), '天')
  73 + END
  74 +ORDER BY 记录数 DESC;
  75 +
sql/添加品项分类字段.sql 0 → 100644
  1 +-- ============================================
  2 +-- 为品项明细表添加品项分类字段
  3 +-- ============================================
  4 +-- 说明:此脚本为品项明细相关表添加品项分类字段,用于存储品项的分类(医美、科美、生美)
  5 +--
  6 +-- 字段说明:
  7 +-- F_ItemCategory:品项分类,用于存储"医美"、"科美"、"生美"等分类值
  8 +--
  9 +-- 业务含义:
  10 +-- - 品项分类用于区分不同类型的品项,便于统计和分析
  11 +-- - 分类值来源于项目资料表(lq_xmzl)的 qt2 字段
  12 +--
  13 +-- 注意事项:
  14 +-- - 字段类型为VARCHAR(20),可存储"医美"、"科美"、"生美"等分类值
  15 +-- - 所有字段允许为NULL,因为历史数据可能没有这些分类信息
  16 +-- - 字段位置:放在品项相关字段(px、pxmc)之后
  17 +
  18 +-- ============================================
  19 +-- 1. lq_kd_pxmx(开单品项明细表) - 添加品项分类字段
  20 +-- ============================================
  21 +ALTER TABLE lq_kd_pxmx
  22 +ADD COLUMN F_ItemCategory VARCHAR(20) NULL COMMENT '品项分类(医美/科美/生美)' AFTER pxmc;
  23 +
  24 +-- ============================================
  25 +-- 2. lq_kd_deductinfo(开单扣减信息表) - 添加品项分类字段
  26 +-- ============================================
  27 +ALTER TABLE lq_kd_deductinfo
  28 +ADD COLUMN F_ItemCategory VARCHAR(20) NULL COMMENT '品项分类(医美/科美/生美)' AFTER F_ItemName;
  29 +
  30 +-- ============================================
  31 +-- 3. lq_xh_pxmx(耗卡品项明细表) - 添加品项分类字段
  32 +-- ============================================
  33 +ALTER TABLE lq_xh_pxmx
  34 +ADD COLUMN F_ItemCategory VARCHAR(20) NULL COMMENT '品项分类(医美/科美/生美)' AFTER pxmc;
  35 +
  36 +-- ============================================
  37 +-- 4. lq_hytk_mx(会员退卡明细表) - 添加品项分类字段
  38 +-- ============================================
  39 +ALTER TABLE lq_hytk_mx
  40 +ADD COLUMN F_ItemCategory VARCHAR(20) NULL COMMENT '品项分类(医美/科美/生美)' AFTER pxmc;
  41 +
  42 +-- ============================================
  43 +-- 5. 验证字段创建
  44 +-- ============================================
  45 +-- 验证 lq_kd_pxmx 表
  46 +-- SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_COMMENT
  47 +-- FROM INFORMATION_SCHEMA.COLUMNS
  48 +-- WHERE TABLE_NAME = 'lq_kd_pxmx'
  49 +-- AND COLUMN_NAME = 'F_ItemCategory';
  50 +
  51 +-- 验证 lq_kd_deductinfo 表
  52 +-- SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_COMMENT
  53 +-- FROM INFORMATION_SCHEMA.COLUMNS
  54 +-- WHERE TABLE_NAME = 'lq_kd_deductinfo'
  55 +-- AND COLUMN_NAME = 'F_ItemCategory';
  56 +
  57 +-- 验证 lq_xh_pxmx 表
  58 +-- SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_COMMENT
  59 +-- FROM INFORMATION_SCHEMA.COLUMNS
  60 +-- WHERE TABLE_NAME = 'lq_xh_pxmx'
  61 +-- AND COLUMN_NAME = 'F_ItemCategory';
  62 +
  63 +-- 验证 lq_hytk_mx 表
  64 +-- SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_COMMENT
  65 +-- FROM INFORMATION_SCHEMA.COLUMNS
  66 +-- WHERE TABLE_NAME = 'lq_hytk_mx'
  67 +-- AND COLUMN_NAME = 'F_ItemCategory';
  68 +
sql/添加开单记录表升单类型字段.sql 0 → 100644
  1 +-- ============================================
  2 +-- 为开单记录表添加升单类型字段
  3 +-- ============================================
  4 +-- 说明:此脚本为开单记录表添加升单类型标记字段,用于标识再次开单时包含的品项类型
  5 +--
  6 +-- 字段说明:
  7 +-- 1. F_UpgradeLifeBeauty:升生美(再次开单时,包含生美品项的订单)
  8 +-- 2. F_UpgradeTechBeauty:升科美(再次开单时,包含科美品项的订单)
  9 +-- 3. F_UpgradeMedicalBeauty:升医美(再次开单时,包含医美品项的订单)
  10 +--
  11 +-- 业务含义:
  12 +-- - 升单:已经开过会员再次消费属于升单
  13 +-- - 这三个字段用于标记升单中是否包含对应类型的品项(生美、科美、医美)
  14 +--
  15 +-- 注意事项:
  16 +-- - 字段类型为VARCHAR(10),可存储"是"/"否"或其他标记值
  17 +-- - 所有字段允许为NULL,因为历史数据可能没有这些标记
  18 +-- - 字段位置:放在 F_SupplementAmount 之后
  19 +
  20 +-- ============================================
  21 +-- 1. lq_kd_kdjlb(开单记录表) - 添加升单类型字段
  22 +-- ============================================
  23 +ALTER TABLE lq_kd_kdjlb
  24 +ADD COLUMN F_UpgradeLifeBeauty VARCHAR(10) NULL COMMENT '升生美(再次开单时,包含生美品项的订单)' AFTER F_SupplementAmount,
  25 +ADD COLUMN F_UpgradeTechBeauty VARCHAR(10) NULL COMMENT '升科美(再次开单时,包含科美品项的订单)' AFTER F_UpgradeLifeBeauty,
  26 +ADD COLUMN F_UpgradeMedicalBeauty VARCHAR(10) NULL COMMENT '升医美(再次开单时,包含医美品项的订单)' AFTER F_UpgradeTechBeauty;
  27 +
  28 +-- ============================================
  29 +-- 2. 验证字段创建
  30 +-- ============================================
  31 +-- 验证 lq_kd_kdjlb 表
  32 +-- SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_COMMENT
  33 +-- FROM INFORMATION_SCHEMA.COLUMNS
  34 +-- WHERE TABLE_NAME = 'lq_kd_kdjlb'
  35 +-- AND (COLUMN_NAME = 'F_UpgradeLifeBeauty'
  36 +-- OR COLUMN_NAME = 'F_UpgradeTechBeauty'
  37 +-- OR COLUMN_NAME = 'F_UpgradeMedicalBeauty');
  38 +
  39 +-- ============================================
  40 +-- 3. 业务逻辑说明(供参考)
  41 +-- ============================================
  42 +-- 判断逻辑:
  43 +-- 1. 判断是否为升单:查询该会员(kdhy)是否有历史开单记录
  44 +-- 2. 判断是否包含生美:查询该开单的品项明细(lq_kd_pxmx)中是否有品项类型(lq_xmzl.qt2)为"生美"的记录
  45 +-- 3. 判断是否包含科美:查询该开单的品项明细中是否有品项类型为"科美"的记录
  46 +-- 4. 判断是否包含医美:查询该开单的品项明细中是否有品项类型为"医美"的记录
  47 +--
  48 +-- 示例SQL(判断升单并标记品项类型):
  49 +-- UPDATE lq_kd_kdjlb kdjlb
  50 +-- SET
  51 +-- F_UpgradeLifeBeauty = CASE
  52 +-- WHEN EXISTS (
  53 +-- SELECT 1 FROM lq_kd_kdjlb kd2
  54 +-- WHERE kd2.kdhy = kdjlb.kdhy
  55 +-- AND kd2.F_Id != kdjlb.F_Id
  56 +-- AND kd2.kdrq < kdjlb.kdrq
  57 +-- ) AND EXISTS (
  58 +-- SELECT 1 FROM lq_kd_pxmx pxmx
  59 +-- INNER JOIN lq_xmzl xmzl ON pxmx.px = xmzl.F_Id
  60 +-- WHERE pxmx.glkdbh = kdjlb.F_Id
  61 +-- AND pxmx.F_IsEffective = 1
  62 +-- AND xmzl.qt2 = '生美'
  63 +-- ) THEN '是'
  64 +-- ELSE '否'
  65 +-- END,
  66 +-- F_UpgradeTechBeauty = CASE
  67 +-- WHEN EXISTS (
  68 +-- SELECT 1 FROM lq_kd_kdjlb kd2
  69 +-- WHERE kd2.kdhy = kdjlb.kdhy
  70 +-- AND kd2.F_Id != kdjlb.F_Id
  71 +-- AND kd2.kdrq < kdjlb.kdrq
  72 +-- ) AND EXISTS (
  73 +-- SELECT 1 FROM lq_kd_pxmx pxmx
  74 +-- INNER JOIN lq_xmzl xmzl ON pxmx.px = xmzl.F_Id
  75 +-- WHERE pxmx.glkdbh = kdjlb.F_Id
  76 +-- AND pxmx.F_IsEffective = 1
  77 +-- AND xmzl.qt2 = '科美'
  78 +-- ) THEN '是'
  79 +-- ELSE '否'
  80 +-- END,
  81 +-- F_UpgradeMedicalBeauty = CASE
  82 +-- WHEN EXISTS (
  83 +-- SELECT 1 FROM lq_kd_kdjlb kd2
  84 +-- WHERE kd2.kdhy = kdjlb.kdhy
  85 +-- AND kd2.F_Id != kdjlb.F_Id
  86 +-- AND kd2.kdrq < kdjlb.kdrq
  87 +-- ) AND EXISTS (
  88 +-- SELECT 1 FROM lq_kd_pxmx pxmx
  89 +-- INNER JOIN lq_xmzl xmzl ON pxmx.px = xmzl.F_Id
  90 +-- WHERE pxmx.glkdbh = kdjlb.F_Id
  91 +-- AND pxmx.F_IsEffective = 1
  92 +-- AND xmzl.qt2 = '医美'
  93 +-- ) THEN '是'
  94 +-- ELSE '否'
  95 +-- END
  96 +-- WHERE kdjlb.F_IsEffective = 1;
  97 +
sql/添加转化率统计关联字段.sql 0 → 100644
  1 +-- ============================================
  2 +-- 为转化率统计添加关联字段
  3 +-- ============================================
  4 +-- 说明:此脚本为转化率统计功能添加关联字段,用于追踪邀约→预约→开单/耗卡的完整业务链路
  5 +-- 执行顺序:按照业务链路顺序依次执行
  6 +--
  7 +-- 业务链路:
  8 +-- 邀约记录 (lq_yaoyjl) → 预约记录 (lq_yyjl) → 开单记录 (lq_kd_kdjlb) / 耗卡记录 (lq_xh_hyhk)
  9 +--
  10 +-- 字段说明:
  11 +-- 1. lq_yyjl.F_InviteId:关联邀约记录ID,用于统计邀约→预约转化率
  12 +-- 2. lq_kd_kdjlb.F_AppointmentId:关联预约记录ID,用于统计预约→开单转化率
  13 +-- 3. lq_xh_hyhk.F_AppointmentId:关联预约记录ID,用于统计预约→耗卡转化率
  14 +--
  15 +-- 注意事项:
  16 +-- - 所有字段允许为NULL,因为历史数据可能没有这些关联
  17 +-- - 字段类型为VARCHAR(50),与其他ID字段保持一致
  18 +-- - 已为所有字段创建索引,以优化查询性能
  19 +
  20 +-- ============================================
  21 +-- 1. lq_yyjl(预约记录表) - 添加邀约ID字段和未成交说明字段
  22 +-- ============================================
  23 +-- 说明:关联邀约记录,用于统计邀约→预约转化率
  24 +ALTER TABLE lq_yyjl
  25 +ADD COLUMN F_InviteId VARCHAR(50) NULL COMMENT '邀约记录ID(关联lq_yaoyjl.F_Id,用于统计邀约→预约转化率)' AFTER F_Status,
  26 +ADD COLUMN F_NoDealRemark VARCHAR(2000) NULL COMMENT '未成交说明' AFTER F_InviteId;
  27 +
  28 +-- 创建索引以优化查询性能
  29 +CREATE INDEX idx_yyjl_invite_id ON lq_yyjl(F_InviteId);
  30 +
  31 +-- ============================================
  32 +-- 2. lq_kd_kdjlb(开单记录表) - 添加预约ID字段
  33 +-- ============================================
  34 +-- 说明:关联预约记录,用于统计预约→开单转化率
  35 +ALTER TABLE lq_kd_kdjlb
  36 +ADD COLUMN F_AppointmentId VARCHAR(50) NULL COMMENT '预约记录ID(关联lq_yyjl.F_Id,用于统计预约→开单转化率)' AFTER F_ActivityId;
  37 +
  38 +-- 创建索引以优化查询性能
  39 +CREATE INDEX idx_kdjlb_appointment_id ON lq_kd_kdjlb(F_AppointmentId);
  40 +
  41 +-- ============================================
  42 +-- 3. lq_xh_hyhk(耗卡记录表) - 添加预约ID字段
  43 +-- ============================================
  44 +-- 说明:关联预约记录,用于统计预约→耗卡转化率
  45 +ALTER TABLE lq_xh_hyhk
  46 +ADD COLUMN F_AppointmentId VARCHAR(50) NULL COMMENT '预约记录ID(关联lq_yyjl.F_Id,用于统计预约→耗卡转化率)' AFTER F_OvertimeSgfy;
  47 +
  48 +-- 创建索引以优化查询性能
  49 +CREATE INDEX idx_hyhk_appointment_id ON lq_xh_hyhk(F_AppointmentId);
  50 +
  51 +-- ============================================
  52 +-- 4. 验证字段创建
  53 +-- ============================================
  54 +-- 验证 lq_yyjl 表
  55 +-- SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_COMMENT
  56 +-- FROM INFORMATION_SCHEMA.COLUMNS
  57 +-- WHERE TABLE_NAME = 'lq_yyjl'
  58 +-- AND (COLUMN_NAME = 'F_InviteId' OR COLUMN_NAME = 'F_NoDealRemark');
  59 +
  60 +-- 验证 lq_kd_kdjlb 表
  61 +-- SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_COMMENT
  62 +-- FROM INFORMATION_SCHEMA.COLUMNS
  63 +-- WHERE TABLE_NAME = 'lq_kd_kdjlb'
  64 +-- AND COLUMN_NAME = 'F_AppointmentId';
  65 +
  66 +-- 验证 lq_xh_hyhk 表
  67 +-- SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_COMMENT
  68 +-- FROM INFORMATION_SCHEMA.COLUMNS
  69 +-- WHERE TABLE_NAME = 'lq_xh_hyhk'
  70 +-- AND COLUMN_NAME = 'F_AppointmentId';
  71 +
  72 +-- ============================================
  73 +-- 5. 验证索引创建
  74 +-- ============================================
  75 +-- 验证索引
  76 +-- SHOW INDEX FROM lq_yyjl WHERE Key_name = 'idx_yyjl_invite_id';
  77 +-- SHOW INDEX FROM lq_kd_kdjlb WHERE Key_name = 'idx_kdjlb_appointment_id';
  78 +-- SHOW INDEX FROM lq_xh_hyhk WHERE Key_name = 'idx_hyhk_appointment_id';
  79 +
  80 +-- ============================================
  81 +-- 6. 转化率统计示例SQL(供参考)
  82 +-- ============================================
  83 +-- 示例1:邀约→预约转化率
  84 +-- SELECT
  85 +-- COUNT(DISTINCT yyjl.F_Id) AS 预约数量,
  86 +-- COUNT(DISTINCT yyjl.F_InviteId) AS 来自邀约的预约数量,
  87 +-- COUNT(DISTINCT yyjl.F_InviteId) * 100.0 / COUNT(DISTINCT yyjl.F_Id) AS 转化率百分比
  88 +-- FROM lq_yyjl yyjl
  89 +-- WHERE yyjl.F_CreateTime >= '2024-01-01';
  90 +
  91 +-- 示例2:预约→开单转化率
  92 +-- SELECT
  93 +-- COUNT(DISTINCT yyjl.F_Id) AS 预约数量,
  94 +-- COUNT(DISTINCT kdjlb.F_Id) AS 开单数量,
  95 +-- COUNT(DISTINCT kdjlb.F_Id) * 100.0 / COUNT(DISTINCT yyjl.F_Id) AS 转化率百分比
  96 +-- FROM lq_yyjl yyjl
  97 +-- LEFT JOIN lq_kd_kdjlb kdjlb ON kdjlb.F_AppointmentId = yyjl.F_Id AND kdjlb.F_IsEffective = 1
  98 +-- WHERE yyjl.F_CreateTime >= '2024-01-01';
  99 +
  100 +-- 示例3:预约→耗卡转化率
  101 +-- SELECT
  102 +-- COUNT(DISTINCT yyjl.F_Id) AS 预约数量,
  103 +-- COUNT(DISTINCT hyhk.F_Id) AS 耗卡数量,
  104 +-- COUNT(DISTINCT hyhk.F_Id) * 100.0 / COUNT(DISTINCT yyjl.F_Id) AS 转化率百分比
  105 +-- FROM lq_yyjl yyjl
  106 +-- LEFT JOIN lq_xh_hyhk hyhk ON hyhk.F_AppointmentId = yyjl.F_Id AND hyhk.F_IsEffective = 1
  107 +-- WHERE yyjl.F_CreateTime >= '2024-01-01';
  108 +
  109 +-- 示例4:邀约→开单转化率(跨步转化)
  110 +-- SELECT
  111 +-- COUNT(DISTINCT yaoyjl.F_Id) AS 邀约数量,
  112 +-- COUNT(DISTINCT kdjlb.F_Id) AS 开单数量,
  113 +-- COUNT(DISTINCT kdjlb.F_Id) * 100.0 / COUNT(DISTINCT yaoyjl.F_Id) AS 转化率百分比
  114 +-- FROM lq_yaoyjl yaoyjl
  115 +-- LEFT JOIN lq_yyjl yyjl ON yyjl.F_InviteId = yaoyjl.F_Id
  116 +-- LEFT JOIN lq_kd_kdjlb kdjlb ON kdjlb.F_AppointmentId = yyjl.F_Id AND kdjlb.F_IsEffective = 1
  117 +-- WHERE yaoyjl.F_CreateTime >= '2024-01-01';
  118 +