Commit c57c36d2c1ee18c1e14d4499400c55e9f4af0581

Authored by 李宇
2 parents 8b66cf2b f987b6a6

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

Showing 21 changed files with 1190 additions and 217 deletions
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/BillingRecordSummaryQueryInput.cs 0 → 100644
  1 +using System;
  2 +using System.ComponentModel.DataAnnotations;
  3 +using NCC.Common.Filter;
  4 +
  5 +namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
  6 +{
  7 + /// <summary>
  8 + /// 开单记录汇总查询输入
  9 + /// </summary>
  10 + public class BillingRecordSummaryQueryInput : PageInputBase
  11 + {
  12 + /// <summary>
  13 + /// 门店ID
  14 + /// </summary>
  15 + [Required(ErrorMessage = "门店ID不能为空")]
  16 + [Display(Name = "门店ID", Description = "查询开单记录汇总的门店ID")]
  17 + public string StoreId { get; set; }
  18 +
  19 + /// <summary>
  20 + /// 开始时间
  21 + /// </summary>
  22 + [Display(Name = "开始时间", Description = "查询开单记录的开始时间")]
  23 + public DateTime? StartTime { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 结束时间
  27 + /// </summary>
  28 + [Display(Name = "结束时间", Description = "查询开单记录的结束时间")]
  29 + public DateTime? EndTime { get; set; }
  30 + }
  31 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbInfoOutput.cs
... ... @@ -163,6 +163,16 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
163 163 public string cancelRefRemarks { get; set; }
164 164  
165 165 /// <summary>
  166 + /// 营销活动ID
  167 + /// </summary>
  168 + public string activityId { get; set; }
  169 +
  170 + /// <summary>
  171 + /// 营销活动名称
  172 + /// </summary>
  173 + public string activityName { get; set; }
  174 +
  175 + /// <summary>
166 176 /// 健康师业绩
167 177 /// </summary>
168 178 public List<LqKdJksyjInfoOutput> lqKdJksyjList { get; set; }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbListOutput.cs
... ... @@ -143,8 +143,16 @@ namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
143 143 /// </summary>
144 144 public string cancelRefRemarks { get; set; }
145 145  
  146 + /// <summary>
  147 + /// 营销活动ID
  148 + /// </summary>
  149 + public string activityId { get; set; }
146 150  
147 151 /// <summary>
  152 + /// 营销活动名称
  153 + /// </summary>
  154 + public string activityName { get; set; }
  155 + /// <summary>
148 156 /// 补缴开单ID
149 157 /// </summary>
150 158 public string supplementBillingId { get; set; }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqKdKdjlb/LqKdKdjlbUpdateAmountInput.cs 0 → 100644
  1 +using System;
  2 +using System.Collections.Generic;
  3 +using System.ComponentModel.DataAnnotations;
  4 +
  5 +namespace NCC.Extend.Entitys.Dto.LqKdKdjlb
  6 +{
  7 + /// <summary>
  8 + /// 修改开单金额输入
  9 + /// </summary>
  10 + public class LqKdKdjlbUpdateAmountInput
  11 + {
  12 + /// <summary>
  13 + /// 开单记录ID
  14 + /// </summary>
  15 + [Required(ErrorMessage = "开单记录ID不能为空")]
  16 + public string BillingId { get; set; }
  17 +
  18 + /// <summary>
  19 + /// 整单业绩
  20 + /// </summary>
  21 + [Range(0, double.MaxValue, ErrorMessage = "整单业绩必须大于等于0")]
  22 + public decimal Zdyj { get; set; }
  23 +
  24 + /// <summary>
  25 + /// 实付业绩
  26 + /// </summary>
  27 + [Range(0, double.MaxValue, ErrorMessage = "实付业绩必须大于等于0")]
  28 + public decimal Sfyj { get; set; }
  29 +
  30 + /// <summary>
  31 + /// 储扣总金额
  32 + /// </summary>
  33 + [Range(0, double.MaxValue, ErrorMessage = "储扣总金额必须大于等于0")]
  34 + public decimal DeductAmount { get; set; }
  35 +
  36 + /// <summary>
  37 + /// 欠款
  38 + /// </summary>
  39 + [Range(0, double.MaxValue, ErrorMessage = "欠款必须大于等于0")]
  40 + public decimal Qk { get; set; }
  41 +
  42 + /// <summary>
  43 + /// 品项明细金额列表
  44 + /// </summary>
  45 + public List<LqKdPxmxAmountUpdate> ItemDetails { get; set; } = new List<LqKdPxmxAmountUpdate>();
  46 +
  47 + /// <summary>
  48 + /// 修改备注
  49 + /// </summary>
  50 + public string Remark { get; set; }
  51 + }
  52 +
  53 + /// <summary>
  54 + /// 品项明细金额更新
  55 + /// </summary>
  56 + public class LqKdPxmxAmountUpdate
  57 + {
  58 + /// <summary>
  59 + /// 品项明细ID
  60 + /// </summary>
  61 + [Required(ErrorMessage = "品项明细ID不能为空")]
  62 + public string ItemDetailId { get; set; }
  63 +
  64 + /// <summary>
  65 + /// 品项价格
  66 + /// </summary>
  67 + [Range(0, double.MaxValue, ErrorMessage = "品项价格必须大于等于0")]
  68 + public decimal Pxjg { get; set; }
  69 +
  70 + /// <summary>
  71 + /// 金额合计
  72 + /// </summary>
  73 + [Range(0, double.MaxValue, ErrorMessage = "金额合计必须大于等于0")]
  74 + public decimal TotalPrice { get; set; }
  75 +
  76 + /// <summary>
  77 + /// 实付金额
  78 + /// </summary>
  79 + [Range(0, double.MaxValue, ErrorMessage = "实付金额必须大于等于0")]
  80 + public decimal ActualPrice { get; set; }
  81 + }
  82 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/LqPackageInfoListOutput.cs
... ... @@ -12,54 +12,84 @@ namespace NCC.Extend.Entitys.Dto.LqPackageInfo
12 12 /// 营销活动ID
13 13 /// </summary>
14 14 [Display(Name = "营销活动ID", Description = "营销活动的唯一标识")]
15   - public string Id { get; set; }
  15 + public string id { get; set; }
16 16  
17 17 /// <summary>
18 18 /// 活动名称
19 19 /// </summary>
20 20 [Display(Name = "活动名称", Description = "营销活动的名称")]
21   - public string ActivityName { get; set; }
  21 + public string activityName { get; set; }
22 22  
23 23 /// <summary>
24 24 /// 活动描述
25 25 /// </summary>
26 26 [Display(Name = "活动描述", Description = "营销活动的描述")]
27   - public string ActivityDesc { get; set; }
  27 + public string activityDesc { get; set; }
28 28  
29 29 /// <summary>
30 30 /// 活动开始时间
31 31 /// </summary>
32 32 [Display(Name = "活动开始时间", Description = "营销活动的开始时间")]
33   - public DateTime StartTime { get; set; }
  33 + public DateTime startTime { get; set; }
34 34  
35 35 /// <summary>
36 36 /// 活动结束时间
37 37 /// </summary>
38 38 [Display(Name = "活动结束时间", Description = "营销活动的结束时间")]
39   - public DateTime EndTime { get; set; }
  39 + public DateTime endTime { get; set; }
40 40  
41 41 /// <summary>
42 42 /// 至少购买品项数量
43 43 /// </summary>
44 44 [Display(Name = "至少购买品项数量", Description = "参与活动需要购买的最少品项数量")]
45   - public int MinItemQuantity { get; set; }
  45 + public int minItemQuantity { get; set; }
46 46  
47 47 /// <summary>
48 48 /// 活动规则说明
49 49 /// </summary>
50 50 [Display(Name = "活动规则说明", Description = "营销活动的规则说明")]
51   - public string ActivityRules { get; set; }
  51 + public string activityRules { get; set; }
52 52  
53 53 /// <summary>
54 54 /// 排序
55 55 /// </summary>
56 56 [Display(Name = "排序", Description = "营销活动的显示排序")]
57   - public int SortOrder { get; set; }
  57 + public int sortOrder { get; set; }
58 58  
59 59 /// <summary>
60 60 /// 创建时间
61 61 /// </summary>
62 62 [Display(Name = "创建时间", Description = "营销活动的创建时间")]
63   - public DateTime CreateTime { get; set; }
  63 + public DateTime createTime { get; set; }
  64 +
  65 + /// <summary>
  66 + /// 是否有效
  67 + /// </summary>
  68 + [Display(Name = "是否有效", Description = "营销活动是否有效")]
  69 + public int isEffective { get; set; }
  70 +
  71 + /// <summary>
  72 + /// 创建人
  73 + /// </summary>
  74 + [Display(Name = "创建人", Description = "营销活动的创建人")]
  75 + public string createUser { get; set; }
  76 +
  77 + /// <summary>
  78 + /// 更新时间
  79 + /// </summary>
  80 + [Display(Name = "更新时间", Description = "营销活动的更新时间")]
  81 + public DateTime updateTime { get; set; }
  82 +
  83 + /// <summary>
  84 + /// 更新人
  85 + /// </summary>
  86 + [Display(Name = "更新人", Description = "营销活动的更新人")]
  87 + public string updateUser { get; set; }
  88 +
  89 + /// <summary>
  90 + /// 活动图片
  91 + /// </summary>
  92 + [Display(Name = "活动图片", Description = "营销活动的图片")]
  93 + public string activityImages { get; set; }
64 94 }
65 95 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/LqPackageInfoListQueryInput.cs
... ... @@ -62,5 +62,11 @@ namespace NCC.Extend.Entitys.Dto.LqPackageInfo
62 62 /// </summary>
63 63 [Display(Name = "创建时间结束", Description = "创建时间范围结束")]
64 64 public DateTime? CreateTimeEnd { get; set; }
  65 +
  66 + /// <summary>
  67 + /// 是否有效
  68 + /// </summary>
  69 + [Display(Name = "是否有效", Description = "营销活动是否有效")]
  70 + public int? IsEffective { get; set; }
65 71 }
66 72 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatisticsPersonalPerformance/LqStatisticsPersonalPerformanceListQueryInput.cs
... ... @@ -19,6 +19,11 @@ namespace NCC.Extend.Entitys.Dto.LqStatisticsPersonalPerformance
19 19 public string StoreId { get; set; }
20 20  
21 21 /// <summary>
  22 + /// 门店名称
  23 + /// </summary>
  24 + public string StoreName { get; set; }
  25 +
  26 + /// <summary>
22 27 /// 员工ID
23 28 /// </summary>
24 29 public string EmployeeId { get; set; }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXmzl/LqXmzlCrInput.cs
... ... @@ -58,15 +58,6 @@ namespace NCC.Extend.Entitys.Dto.LqXmzl
58 58 /// </summary>
59 59 public string fl4 { get; set; }
60 60  
61   - /// <summary>
62   - /// 统计类别
63   - /// </summary>
64   - public string tjlb { get; set; }
65   -
66   - /// <summary>
67   - /// 折扣类别
68   - /// </summary>
69   - public string zklb { get; set; }
70 61  
71 62 /// <summary>
72 63 /// 分类
... ... @@ -83,25 +74,21 @@ namespace NCC.Extend.Entitys.Dto.LqXmzl
83 74 /// </summary>
84 75 public string qt2 { get; set; }
85 76  
86   - /// <summary>
87   - /// 溯源金额
88   - /// </summary>
89   - public decimal? syje { get; set; }
90 77  
91 78 /// <summary>
92   - /// Cell金额
  79 + /// 手工费
93 80 /// </summary>
94   - public decimal? cellje { get; set; }
  81 + public decimal? sgf { get; set; }
95 82  
96 83 /// <summary>
97   - /// 手工费
  84 + /// 科美类型
98 85 /// </summary>
99   - public decimal? sgf { get; set; }
  86 + public string beautyType { get; set; }
100 87  
101 88 /// <summary>
102   - /// 项目次数
  89 + /// 是否有效
103 90 /// </summary>
104   - public int? projectNumber { get; set; }
  91 + public int isEffective { get; set; }
105 92  
106 93 /// <summary>
107 94 /// 来源类型
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXmzl/LqXmzlInfoOutput.cs
... ... @@ -12,101 +12,88 @@ namespace NCC.Extend.Entitys.Dto.LqXmzl
12 12 /// 主键
13 13 /// </summary>
14 14 public string id { get; set; }
15   -
  15 +
16 16 /// <summary>
17 17 /// 项目编号
18 18 /// </summary>
19 19 public string xmbh { get; set; }
20   -
  20 +
21 21 /// <summary>
22 22 /// 项目名称
23 23 /// </summary>
24 24 public string xmmc { get; set; }
25   -
  25 +
26 26 /// <summary>
27 27 /// 标准价格
28 28 /// </summary>
29 29 public decimal bzjg { get; set; }
30   -
  30 +
31 31 /// <summary>
32 32 /// 项目时长(分钟)
33 33 /// </summary>
34 34 public int? xmsc { get; set; }
35   -
  35 +
36 36 /// <summary>
37 37 /// 基础服务提成
38 38 /// </summary>
39 39 public decimal jcfwtc { get; set; }
40   -
  40 +
41 41 /// <summary>
42 42 /// 分类①-汇总表
43 43 /// </summary>
44 44 public string fl1 { get; set; }
45   -
  45 +
46 46 /// <summary>
47 47 /// 分类②-汇总表
48 48 /// </summary>
49 49 public string fl2 { get; set; }
50   -
  50 +
51 51 /// <summary>
52 52 /// 分类③-工资用
53 53 /// </summary>
54 54 public string fl3 { get; set; }
55   -
  55 +
56 56 /// <summary>
57 57 /// 分类④-统计品项用
58 58 /// </summary>
59 59 public string fl4 { get; set; }
60   -
61   - /// <summary>
62   - /// 统计类别
63   - /// </summary>
64   - public string tjlb { get; set; }
65   -
66   - /// <summary>
67   - /// 折扣类别
68   - /// </summary>
69   - public string zklb { get; set; }
70   -
  60 +
  61 +
71 62 /// <summary>
72 63 /// 分类
73 64 /// </summary>
74 65 public string fl { get; set; }
75   -
  66 +
76 67 /// <summary>
77 68 /// 其它1
78 69 /// </summary>
79 70 public string qt1 { get; set; }
80   -
  71 +
81 72 /// <summary>
82 73 /// 其它2
83 74 /// </summary>
84 75 public string qt2 { get; set; }
85   -
86   - /// <summary>
87   - /// 溯源金额
88   - /// </summary>
89   - public decimal? syje { get; set; }
90   -
91   - /// <summary>
92   - /// Cell金额
93   - /// </summary>
94   - public decimal? cellje { get; set; }
95   -
  76 +
  77 +
96 78 /// <summary>
97 79 /// 手工费
98 80 /// </summary>
99 81 public decimal? sgf { get; set; }
100 82  
101 83 /// <summary>
102   - /// 项目次数
  84 + /// 科美类型
103 85 /// </summary>
104   - public int? projectNumber { get; set; }
105   -
  86 + public string beautyType { get; set; }
  87 +
  88 + /// <summary>
  89 + /// 是否有效
  90 + /// </summary>
  91 + public int isEffective { get; set; }
  92 +
106 93 /// <summary>
107 94 /// 来源类型
108 95 /// </summary>
109 96 public string sourceType { get; set; }
110   -
  97 +
111 98 }
112 99 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXmzl/LqXmzlListOutput.cs
... ... @@ -57,15 +57,6 @@ namespace NCC.Extend.Entitys.Dto.LqXmzl
57 57 /// </summary>
58 58 public string fl4 { get; set; }
59 59  
60   - /// <summary>
61   - /// 统计类别
62   - /// </summary>
63   - public string tjlb { get; set; }
64   -
65   - /// <summary>
66   - /// 折扣类别
67   - /// </summary>
68   - public string zklb { get; set; }
69 60  
70 61 /// <summary>
71 62 /// 分类
... ... @@ -82,25 +73,21 @@ namespace NCC.Extend.Entitys.Dto.LqXmzl
82 73 /// </summary>
83 74 public string qt2 { get; set; }
84 75  
85   - /// <summary>
86   - /// 溯源金额
87   - /// </summary>
88   - public decimal? syje { get; set; }
89 76  
90 77 /// <summary>
91   - /// Cell金额
  78 + /// 手工费
92 79 /// </summary>
93   - public decimal? cellje { get; set; }
  80 + public decimal? sgf { get; set; }
94 81  
95 82 /// <summary>
96   - /// 手工费
  83 + /// 科美类型
97 84 /// </summary>
98   - public decimal? sgf { get; set; }
  85 + public string beautyType { get; set; }
99 86  
100 87 /// <summary>
101   - /// 项目次数
  88 + /// 是否有效
102 89 /// </summary>
103   - public int? projectNumber { get; set; }
  90 + public int isEffective { get; set; }
104 91  
105 92 /// <summary>
106 93 /// 来源类型
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXmzl/LqXmzlListQueryInput.cs
... ... @@ -23,91 +23,106 @@ namespace NCC.Extend.Entitys.Dto.LqXmzl
23 23 /// 主键
24 24 /// </summary>
25 25 public string id { get; set; }
26   -
  26 +
27 27 /// <summary>
28 28 /// 项目编号
29 29 /// </summary>
30 30 public string xmbh { get; set; }
31   -
  31 +
32 32 /// <summary>
33 33 /// 项目名称
34 34 /// </summary>
35 35 public string xmmc { get; set; }
36   -
  36 +
37 37 /// <summary>
38 38 /// 标准价格
39 39 /// </summary>
40 40 public string bzjg { get; set; }
41   -
  41 +
42 42 /// <summary>
43 43 /// 项目时长(分钟)
44 44 /// </summary>
45 45 public string xmsc { get; set; }
46   -
  46 +
47 47 /// <summary>
48 48 /// 基础服务提成
49 49 /// </summary>
50 50 public string jcfwtc { get; set; }
51   -
  51 +
52 52 /// <summary>
53 53 /// 分类①-汇总表
54 54 /// </summary>
55 55 public string fl1 { get; set; }
56   -
  56 +
57 57 /// <summary>
58 58 /// 分类②-汇总表
59 59 /// </summary>
60 60 public string fl2 { get; set; }
61   -
  61 +
62 62 /// <summary>
63 63 /// 分类③-工资用
64 64 /// </summary>
65 65 public string fl3 { get; set; }
66   -
  66 +
67 67 /// <summary>
68 68 /// 分类④-统计品项用
69 69 /// </summary>
70 70 public string fl4 { get; set; }
71   -
  71 +
72 72 /// <summary>
73 73 /// 统计类别
74 74 /// </summary>
75 75 public string tjlb { get; set; }
76   -
  76 +
77 77 /// <summary>
78 78 /// 折扣类别
79 79 /// </summary>
80 80 public string zklb { get; set; }
81   -
  81 +
82 82 /// <summary>
83 83 /// 分类
84 84 /// </summary>
85 85 public string fl { get; set; }
86   -
  86 +
87 87 /// <summary>
88 88 /// 其它1
89 89 /// </summary>
90 90 public string qt1 { get; set; }
91   -
  91 +
92 92 /// <summary>
93 93 /// 其它2
94 94 /// </summary>
95 95 public string qt2 { get; set; }
96   -
  96 +
97 97 /// <summary>
98 98 /// 溯源金额
99 99 /// </summary>
100 100 public string syje { get; set; }
101   -
  101 +
102 102 /// <summary>
103 103 /// Cell金额
104 104 /// </summary>
105 105 public string cellje { get; set; }
106   -
  106 +
107 107 /// <summary>
108 108 /// 手工费
109 109 /// </summary>
110 110 public string sgf { get; set; }
111   -
  111 +
  112 + /// <summary>
  113 + /// 科美类型
  114 + /// </summary>
  115 + public string beautyType { get; set; }
  116 +
  117 + /// <summary>
  118 + /// 是否有效
  119 + /// </summary>
  120 + public int isEffective { get; set; } = 0;
  121 +
  122 + /// <summary>
  123 + /// 来源类型
  124 + /// </summary>
  125 + public string sourceType { get; set; }
  126 +
112 127 }
113 128 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqXmzl/LqXmzlUpInput.cs
... ... @@ -12,6 +12,6 @@ namespace NCC.Extend.Entitys.Dto.LqXmzl
12 12 /// 主键
13 13 /// </summary>
14 14 public string id { get; set; }
15   -
  15 +
16 16 }
17 17 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqYyjl/LqYyjlCrInput.cs
... ... @@ -12,66 +12,66 @@ namespace NCC.Extend.Entitys.Dto.LqYyjl
12 12 /// 预约编号
13 13 /// </summary>
14 14 public string id { get; set; }
15   -
  15 +
16 16 /// <summary>
17 17 /// 单据门店
18 18 /// </summary>
19 19 public string djmd { get; set; }
20   -
  20 +
21 21 /// <summary>
22 22 /// 邀约人
23 23 /// </summary>
24 24 public string yyr { get; set; }
25   -
  25 +
26 26 /// <summary>
27 27 /// 顾客类型
28 28 /// </summary>
29 29 public string gklx { get; set; }
30   -
  30 +
31 31 /// <summary>
32 32 /// 预约体验项目
33 33 /// </summary>
34 34 public string yytyxm { get; set; }
35   -
  35 +
36 36 /// <summary>
37 37 /// 操作人
38 38 /// </summary>
39 39 public string czr { get; set; }
40   -
  40 +
41 41 /// <summary>
42 42 /// 操作时间
43 43 /// </summary>
44 44 public DateTime? czsj { get; set; }
45   -
  45 +
46 46 /// <summary>
47 47 /// 顾客
48 48 /// </summary>
49 49 public string gk { get; set; }
50   -
  50 +
51 51 /// <summary>
52 52 /// 顾客姓名
53 53 /// </summary>
54 54 public string gkxm { get; set; }
55   -
  55 +
56 56 /// <summary>
57 57 /// 预约健康师
58 58 /// </summary>
59 59 public string yyjks { get; set; }
60   -
  60 +
61 61 /// <summary>
62 62 /// 预约开始时间
63 63 /// </summary>
64 64 public DateTime? yysj { get; set; }
65   -
  65 +
66 66 /// <summary>
67 67 /// 预约结束时间
68 68 /// </summary>
69 69 public DateTime? yyjs { get; set; }
70   -
  70 +
71 71 /// <summary>
72 72 /// 预约状态
73 73 /// </summary>
74 74 public string F_Status { get; set; }
75   -
  75 +
76 76 }
77 77 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_tkjlb/LqTkjlbEntity.cs
... ... @@ -95,5 +95,11 @@ namespace NCC.Extend.Entitys.lq_tkjlb
95 95 [SugarColumn(ColumnName = "F_CreateTime")]
96 96 public DateTime CreateTime { get; set; } = DateTime.Now;
97 97  
  98 + /// <summary>
  99 + /// 会员id
  100 + /// </summary>
  101 + [SugarColumn(ColumnName = "F_MemberId")]
  102 + public string MemberId { get; set; }
  103 +
98 104 }
99 105 }
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_xmzl/LqXmzlEntity.cs
... ... @@ -16,119 +16,103 @@ namespace NCC.Extend.Entitys.lq_xmzl
16 16 /// </summary>
17 17 [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)]
18 18 public string Id { get; set; }
19   -
  19 +
20 20 /// <summary>
21 21 /// 项目编号
22 22 /// </summary>
23   - [SugarColumn(ColumnName = "xmbh")]
  23 + [SugarColumn(ColumnName = "xmbh")]
24 24 public string Xmbh { get; set; }
25   -
  25 +
26 26 /// <summary>
27 27 /// 项目名称
28 28 /// </summary>
29   - [SugarColumn(ColumnName = "xmmc")]
  29 + [SugarColumn(ColumnName = "xmmc")]
30 30 public string Xmmc { get; set; }
31   -
  31 +
32 32 /// <summary>
33 33 /// 标准价格
34 34 /// </summary>
35   - [SugarColumn(ColumnName = "bzjg")]
  35 + [SugarColumn(ColumnName = "bzjg")]
36 36 public decimal Bzjg { get; set; }
37   -
  37 +
38 38 /// <summary>
39 39 /// 项目时长(分钟)
40 40 /// </summary>
41   - [SugarColumn(ColumnName = "xmsc")]
  41 + [SugarColumn(ColumnName = "xmsc")]
42 42 public int? Xmsc { get; set; }
43   -
  43 +
44 44 /// <summary>
45 45 /// 基础服务提成
46 46 /// </summary>
47   - [SugarColumn(ColumnName = "jcfwtc")]
  47 + [SugarColumn(ColumnName = "jcfwtc")]
48 48 public decimal Jcfwtc { get; set; }
49   -
  49 +
50 50 /// <summary>
51 51 /// 分类①-汇总表
52 52 /// </summary>
53   - [SugarColumn(ColumnName = "fl1")]
  53 + [SugarColumn(ColumnName = "fl1")]
54 54 public string Fl1 { get; set; }
55   -
  55 +
56 56 /// <summary>
57 57 /// 分类②-汇总表
58 58 /// </summary>
59   - [SugarColumn(ColumnName = "fl2")]
  59 + [SugarColumn(ColumnName = "fl2")]
60 60 public string Fl2 { get; set; }
61   -
  61 +
62 62 /// <summary>
63 63 /// 分类③-工资用
64 64 /// </summary>
65   - [SugarColumn(ColumnName = "fl3")]
  65 + [SugarColumn(ColumnName = "fl3")]
66 66 public string Fl3 { get; set; }
67   -
  67 +
68 68 /// <summary>
69 69 /// 分类④-统计品项用
70 70 /// </summary>
71   - [SugarColumn(ColumnName = "fl4")]
  71 + [SugarColumn(ColumnName = "fl4")]
72 72 public string Fl4 { get; set; }
73   -
74   - /// <summary>
75   - /// 统计类别
76   - /// </summary>
77   - [SugarColumn(ColumnName = "tjlb")]
78   - public string Tjlb { get; set; }
79   -
80   - /// <summary>
81   - /// 折扣类别
82   - /// </summary>
83   - [SugarColumn(ColumnName = "zklb")]
84   - public string Zklb { get; set; }
85   -
  73 +
  74 +
86 75 /// <summary>
87 76 /// 分类
88 77 /// </summary>
89   - [SugarColumn(ColumnName = "fl")]
  78 + [SugarColumn(ColumnName = "fl")]
90 79 public string Fl { get; set; }
91   -
  80 +
92 81 /// <summary>
93 82 /// 其它1
94 83 /// </summary>
95   - [SugarColumn(ColumnName = "qt1")]
  84 + [SugarColumn(ColumnName = "qt1")]
96 85 public string Qt1 { get; set; }
97   -
  86 +
98 87 /// <summary>
99 88 /// 其它2
100 89 /// </summary>
101   - [SugarColumn(ColumnName = "qt2")]
  90 + [SugarColumn(ColumnName = "qt2")]
102 91 public string Qt2 { get; set; }
103   -
104   - /// <summary>
105   - /// 溯源金额
106   - /// </summary>
107   - [SugarColumn(ColumnName = "syje")]
108   - public decimal? Syje { get; set; }
109   -
110   - /// <summary>
111   - /// Cell金额
112   - /// </summary>
113   - [SugarColumn(ColumnName = "cellje")]
114   - public decimal? Cellje { get; set; }
115   -
  92 +
  93 +
116 94 /// <summary>
117 95 /// 手工费
118 96 /// </summary>
119   - [SugarColumn(ColumnName = "sgf")]
  97 + [SugarColumn(ColumnName = "sgf")]
120 98 public decimal? Sgf { get; set; }
121 99  
122 100 /// <summary>
123   - /// 项目次数
  101 + /// 科美类型
  102 + /// </summary>
  103 + [SugarColumn(ColumnName = "F_BeautyType")]
  104 + public string BeautyType { get; set; }
  105 +
  106 + /// <summary>
  107 + /// 是否有效
124 108 /// </summary>
125   - [SugarColumn(ColumnName = "F_ProjectNumber")]
126   - public int? ProjectNumber { get; set; }
  109 + [SugarColumn(ColumnName = "F_IsEffective")]
  110 + public int IsEffective { get; set; }
127 111  
128 112 /// <summary>
129 113 /// 来源类型
130 114 /// </summary>
131   - [SugarColumn(ColumnName = "F_SourceType")]
  115 + [SugarColumn(ColumnName = "F_SourceType")]
132 116 public string SourceType { get; set; }
133 117 }
134 118 }
135 119 \ No newline at end of file
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqAttendanceSummaryService.cs
... ... @@ -325,6 +325,7 @@ namespace NCC.Extend
325 325 .WhereIF(input.Year.HasValue, a => a.Year == input.Year)
326 326 .WhereIF(input.Month.HasValue, a => a.Month == input.Month)
327 327 .WhereIF(input.EmployeeStatus.HasValue, a => a.EmployeeStatus == input.EmployeeStatus)
  328 +
328 329 .Select(a => new LqAttendanceSummaryListOutput
329 330 {
330 331 id = a.Id,
... ... @@ -353,7 +354,26 @@ namespace NCC.Extend
353 354 #endregion
354 355  
355 356 #region 清空某一个月的数据
356   -
  357 + /// <summary>
  358 + /// 清空某一个月的数据
  359 + /// </summary>
  360 + /// <param name="year">年份</param>
  361 + /// <param name="month">月份</param>
  362 + /// <returns></returns>
  363 + [HttpDelete("DeleteByMonth/{year}/{month}")]
  364 + public async Task<dynamic> DeleteByMonth(string year, string month)
  365 + {
  366 + int yearInt = int.Parse(year);
  367 + int monthInt = int.Parse(month);
  368 + await _db.Deleteable<LqAttendanceSummaryEntity>().Where(p => p.Year == yearInt && p.Month == monthInt).ExecuteCommandAsync();
  369 + return new
  370 + {
  371 + success = true,
  372 + message = "清空成功"
  373 + };
  374 + }
357 375 #endregion
  376 +
  377 +
358 378 }
359 379 }
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs
... ... @@ -39,6 +39,7 @@ using NCC.JsonSerialization;
39 39 using NCC.System.Entitys.Permission;
40 40 using SqlSugar;
41 41 using Yitter.IdGenerator;
  42 +using NCC.Extend.Entitys.lq_package_info;
42 43  
43 44 namespace NCC.Extend.LqKdKdjlb
44 45 {
... ... @@ -117,6 +118,10 @@ namespace NCC.Extend.LqKdKdjlb
117 118 var MemberInfo = await _db.Queryable<LqKhxxEntity>().FirstAsync(p => p.Id == entity.Kdhy);
118 119 output.kdhyc = MemberInfo.Khmc;
119 120 output.kdhysjh = MemberInfo.Sjh;
  121 + if (!string.IsNullOrEmpty(entity.ActivityId))
  122 + {
  123 + output.activityName = await _db.Queryable<LqPackageInfoEntity>().Where(x => x.Id == entity.ActivityId).Select(x => x.ActivityName).FirstAsync();
  124 + }
120 125 // 2. 查询品项明细列表
121 126 var lqKdPxmxList = await _db.Queryable<LqKdPxmxEntity>().Where(w => w.Glkdbh == entity.Id).ToListAsync();
122 127  
... ... @@ -251,6 +256,8 @@ namespace NCC.Extend.LqKdKdjlb
251 256 isEffective = it.IsEffective,
252 257 createUser = it.CreateUser,
253 258 createUserName = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id == it.CreateUser).Select(x => x.RealName),
  259 + activityId = it.ActivityId,
  260 + activityName = SqlFunc.Subqueryable<LqPackageInfoEntity>().Where(x => x.Id == it.ActivityId).Select(x => x.ActivityName),
254 261 })
255 262 .MergeTable()
256 263 .OrderBy(sidx + " " + input.sort)
... ... @@ -1381,11 +1388,11 @@ namespace NCC.Extend.LqKdKdjlb
1381 1388 //关闭事务
1382 1389 _db.CommitTran();
1383 1390 }
1384   - catch (Exception)
  1391 + catch (Exception ex)
1385 1392 {
1386 1393 //回滚事务
1387 1394 _db.RollbackTran();
1388   - throw NCCException.Oh(ErrorCode.COM1001);
  1395 + throw NCCException.Oh($"创建开单记录失败: {ex.Message}");
1389 1396 }
1390 1397 }
1391 1398 #endregion
... ... @@ -1896,6 +1903,356 @@ namespace NCC.Extend.LqKdKdjlb
1896 1903 }
1897 1904 #endregion
1898 1905  
  1906 + #region 修改开单金额
  1907 + /// <summary>
  1908 + /// 修改开单金额
  1909 + /// </summary>
  1910 + /// <param name="input">修改开单金额输入</param>
  1911 + /// <returns>修改结果</returns>
  1912 + /// <remarks>
  1913 + /// 修改开单记录表的金额以及品项明细表里面的金额
  1914 + ///
  1915 + /// 示例请求:
  1916 + /// ```json
  1917 + /// {
  1918 + /// "billingId": "123456789",
  1919 + /// "zdyj": 1000.00,
  1920 + /// "sfyj": 800.00,
  1921 + /// "deductAmount": 200.00,
  1922 + /// "qk": 0.00,
  1923 + /// "itemDetails": [
  1924 + /// {
  1925 + /// "itemDetailId": "item001",
  1926 + /// "pxjg": 500.00,
  1927 + /// "totalPrice": 500.00,
  1928 + /// "actualPrice": 400.00
  1929 + /// }
  1930 + /// ],
  1931 + /// "remark": "金额调整"
  1932 + /// }
  1933 + /// ```
  1934 + ///
  1935 + /// 参数说明:
  1936 + /// - billingId: 开单记录ID(必填)
  1937 + /// - zdyj: 整单业绩
  1938 + /// - sfyj: 实付业绩
  1939 + /// - deductAmount: 储扣总金额
  1940 + /// - qk: 欠款
  1941 + /// - itemDetails: 品项明细金额列表
  1942 + /// - remark: 修改备注
  1943 + /// </remarks>
  1944 + /// <response code="200">成功修改开单金额</response>
  1945 + /// <response code="400">请求参数错误</response>
  1946 + /// <response code="404">开单记录不存在</response>
  1947 + /// <response code="500">服务器内部错误</response>
  1948 + [HttpPut("UpdateBillingAmount")]
  1949 + public async Task<dynamic> UpdateBillingAmount(LqKdKdjlbUpdateAmountInput input)
  1950 + {
  1951 + try
  1952 + {
  1953 + // 验证输入参数
  1954 + if (string.IsNullOrEmpty(input.BillingId))
  1955 + {
  1956 + throw NCCException.Oh("开单记录ID不能为空");
  1957 + }
  1958 + // 检查开单记录是否存在且有效
  1959 + var billingEntity = await _db.Queryable<LqKdKdjlbEntity>().Where(w => w.Id == input.BillingId && w.IsEffective == StatusEnum.有效.GetHashCode()).FirstAsync();
  1960 + if (billingEntity == null)
  1961 + {
  1962 + throw NCCException.Oh("开单记录不存在或已作废");
  1963 + }
  1964 + // 验证品项明细
  1965 + if (input.ItemDetails != null && input.ItemDetails.Any())
  1966 + {
  1967 + var itemDetailIds = input.ItemDetails.Select(x => x.ItemDetailId).ToList();
  1968 + var existingItems = await _db.Queryable<LqKdPxmxEntity>().Where(w => w.Glkdbh == input.BillingId && itemDetailIds.Contains(w.Id)).ToListAsync();
  1969 + if (existingItems.Count != input.ItemDetails.Count)
  1970 + {
  1971 + throw NCCException.Oh("部分品项明细不存在或不属于该开单记录");
  1972 + }
  1973 + }
  1974 + // 开始事务
  1975 + _db.BeginTran();
  1976 + try
  1977 + {
  1978 + // 更新开单记录金额
  1979 + var updateResult = await _db.Updateable<LqKdKdjlbEntity>().SetColumns(it => new LqKdKdjlbEntity
  1980 + {
  1981 + Zdyj = input.Zdyj,
  1982 + Sfyj = input.Sfyj,
  1983 + DeductAmount = input.DeductAmount,
  1984 + Qk = input.Qk,
  1985 + UpdateTime = DateTime.Now
  1986 + }).Where(w => w.Id == input.BillingId).ExecuteCommandAsync();
  1987 +
  1988 + if (updateResult <= 0)
  1989 + {
  1990 + throw NCCException.Oh("更新开单记录金额失败");
  1991 + }
  1992 +
  1993 + // 更新品项明细金额
  1994 + if (input.ItemDetails != null && input.ItemDetails.Any())
  1995 + {
  1996 + foreach (var itemDetail in input.ItemDetails)
  1997 + {
  1998 + var itemUpdateResult = await _db.Updateable<LqKdPxmxEntity>().SetColumns(it => new LqKdPxmxEntity
  1999 + {
  2000 + Pxjg = itemDetail.Pxjg,
  2001 + TotalPrice = itemDetail.TotalPrice,
  2002 + ActualPrice = itemDetail.ActualPrice
  2003 + }).Where(w => w.Id == itemDetail.ItemDetailId && w.Glkdbh == input.BillingId).ExecuteCommandAsync();
  2004 +
  2005 + if (itemUpdateResult <= 0)
  2006 + {
  2007 + throw NCCException.Oh($"更新品项明细金额失败,品项ID: {itemDetail.ItemDetailId}");
  2008 + }
  2009 + }
  2010 + }
  2011 + // 提交事务
  2012 + _db.CommitTran();
  2013 + return "修改开单金额成功";
  2014 + }
  2015 + catch (Exception ex)
  2016 + {
  2017 + // 回滚事务
  2018 + _db.RollbackTran();
  2019 + throw NCCException.Oh($"修改开单金额失败: {ex.Message}");
  2020 + }
  2021 + }
  2022 + catch (Exception ex)
  2023 + {
  2024 + throw NCCException.Oh($"修改开单金额时发生错误: {ex.Message}");
  2025 + }
  2026 + }
  2027 + #endregion
  2028 +
  2029 + #region 获取门店某个时间段的开单记录汇总信息
  2030 + /// <summary>
  2031 + /// 获取门店某个时间段的开单记录汇总信息
  2032 + /// </summary>
  2033 + /// <param name="input">查询参数</param>
  2034 + /// <returns>开单记录汇总信息</returns>
  2035 + [HttpGet("GetBillingRecordSummaryByStoreId")]
  2036 + public async Task<dynamic> GetBillingRecordSummaryByStoreId([FromQuery] BillingRecordSummaryQueryInput input)
  2037 + {
  2038 + try
  2039 + {
  2040 + // 验证参数
  2041 + if (string.IsNullOrEmpty(input.StoreId))
  2042 + {
  2043 + throw NCCException.Oh("门店ID不能为空");
  2044 + }
  2045 +
  2046 + // 如果开始时间和结束时间为空,就默认是当月
  2047 + if (input.StartTime == null || input.EndTime == null)
  2048 + {
  2049 + input.StartTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
  2050 + input.EndTime = DateTime.Now.AddDays(DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month));
  2051 + }
  2052 +
  2053 + // 查询开单记录
  2054 + var billingRecords = await _db.Queryable<LqKdKdjlbEntity>()
  2055 + .Where(w => w.Djmd == input.StoreId
  2056 + && w.Kdrq >= input.StartTime
  2057 + && w.Kdrq <= input.EndTime
  2058 + && w.IsEffective == StatusEnum.有效.GetHashCode())
  2059 + .Select(it => new
  2060 + {
  2061 + id = it.Id,
  2062 + djmd = it.Djmd,
  2063 + jsj = it.Jsj,
  2064 + kdrq = it.Kdrq,
  2065 + gjlx = it.Gjlx,
  2066 + zdyj = it.Zdyj,
  2067 + sfyj = it.Sfyj,
  2068 + qk = it.Qk,
  2069 + kdhyc = it.Kdhyc,
  2070 + kdhysjh = it.Kdhysjh,
  2071 + fkfs = it.Fkfs, // 付款方式
  2072 + khly = it.Khly, // 客户来源
  2073 + bz = it.Bz, // 备注
  2074 + createTime = it.CreateTime
  2075 + })
  2076 + .ToListAsync();
  2077 +
  2078 + if (!billingRecords.Any())
  2079 + {
  2080 + return new
  2081 + {
  2082 + success = true,
  2083 + data = new
  2084 + {
  2085 + billingSummary = new
  2086 + {
  2087 + totalCount = 0,
  2088 + totalAmount = 0,
  2089 + totalPaidAmount = 0,
  2090 + totalDebt = 0,
  2091 + billingRecords = new List<object>()
  2092 + },
  2093 + itemSummary = new
  2094 + {
  2095 + purchased = new { count = 0, totalAmount = 0, items = new List<object>() },
  2096 + gifted = new { count = 0, totalAmount = 0, items = new List<object>() },
  2097 + experience = new { count = 0, totalAmount = 0, items = new List<object>() }
  2098 + },
  2099 + healthTeacherSummary = new
  2100 + {
  2101 + totalCount = 0,
  2102 + teachers = new List<object>()
  2103 + }
  2104 + },
  2105 + message = "该时间段内无开单记录"
  2106 + };
  2107 + }
  2108 +
  2109 + var billingIds = billingRecords.Select(x => x.id).ToList();
  2110 +
  2111 + // 查询品项明细,按F_SourceType分类
  2112 + var itemDetails = await _db.Queryable<LqKdPxmxEntity>()
  2113 + .Where(w => billingIds.Contains(w.Glkdbh) && w.IsEffective == StatusEnum.有效.GetHashCode())
  2114 + .Select(it => new
  2115 + {
  2116 + id = it.Id,
  2117 + glkdbh = it.Glkdbh,
  2118 + px = it.Px,
  2119 + pxmc = it.Pxmc,
  2120 + pxjg = it.Pxjg,
  2121 + sourceType = it.SourceType,
  2122 + totalPrice = it.TotalPrice,
  2123 + actualPrice = it.ActualPrice,
  2124 + projectNumber = it.ProjectNumber,
  2125 + remark = it.Remark
  2126 + })
  2127 + .ToListAsync();
  2128 +
  2129 + // 按来源类型分类品项
  2130 + var purchasedItems = itemDetails.Where(x => x.sourceType == "购买").ToList();
  2131 + var giftedItems = itemDetails.Where(x => x.sourceType == "赠送").ToList();
  2132 + var experienceItems = itemDetails.Where(x => x.sourceType == "体验").ToList();
  2133 +
  2134 + // 查询健康师业绩数据
  2135 + var healthTeacherData = await _db.Queryable<LqKdJksyjEntity>()
  2136 + .Where(w => billingIds.Contains(w.Glkdbh) && w.IsEffective == StatusEnum.有效.GetHashCode())
  2137 + .Select(it => new
  2138 + {
  2139 + id = it.Id,
  2140 + glkdbh = it.Glkdbh,
  2141 + jks = it.Jks,
  2142 + jksxm = it.Jksxm,
  2143 + jkszh = it.Jkszh,
  2144 + jksyj = it.Jksyj,
  2145 + kdpxid = it.Kdpxid,
  2146 + yjsj = it.Yjsj,
  2147 + jsj_id = it.Jsj_id
  2148 + })
  2149 + .ToListAsync();
  2150 +
  2151 + // 构建按开单记录分组的详细数据
  2152 + var detailedRecords = billingRecords.Select(billing => new
  2153 + {
  2154 + // 基本信息
  2155 + date = billing.kdrq?.ToString("yyyy-MM-dd"),
  2156 + customerName = billing.kdhyc,
  2157 + customerPhone = billing.kdhysjh,
  2158 + storeId = billing.djmd,
  2159 + goldTriangle = billing.jsj,
  2160 + customerType = billing.gjlx,
  2161 +
  2162 + // 品项分类
  2163 + purchasedItems = itemDetails.Where(x => x.glkdbh == billing.id && x.sourceType == "购买").Select(x => new
  2164 + {
  2165 + id = x.id,
  2166 + itemName = x.pxmc,
  2167 + itemCode = x.px,
  2168 + price = x.pxjg,
  2169 + totalPrice = x.totalPrice,
  2170 + actualPrice = x.actualPrice,
  2171 + projectNumber = x.projectNumber,
  2172 + remark = x.remark
  2173 + }).ToList(),
  2174 +
  2175 + giftedItems = itemDetails.Where(x => x.glkdbh == billing.id && x.sourceType == "赠送").Select(x => new
  2176 + {
  2177 + id = x.id,
  2178 + itemName = x.pxmc,
  2179 + itemCode = x.px,
  2180 + price = x.pxjg,
  2181 + totalPrice = x.totalPrice,
  2182 + actualPrice = x.actualPrice,
  2183 + projectNumber = x.projectNumber,
  2184 + remark = x.remark
  2185 + }).ToList(),
  2186 +
  2187 + experienceItems = itemDetails.Where(x => x.glkdbh == billing.id && x.sourceType == "体验").Select(x => new
  2188 + {
  2189 + id = x.id,
  2190 + itemName = x.pxmc,
  2191 + itemCode = x.px,
  2192 + price = x.pxjg,
  2193 + totalPrice = x.totalPrice,
  2194 + actualPrice = x.actualPrice,
  2195 + projectNumber = x.projectNumber,
  2196 + remark = x.remark
  2197 + }).ToList(),
  2198 +
  2199 + // 金额信息
  2200 + paidAmount = billing.sfyj,
  2201 + debtAmount = billing.qk,
  2202 + totalAmount = billing.zdyj,
  2203 +
  2204 + // 健康师信息
  2205 + healthTeachers = healthTeacherData.Where(x => x.glkdbh == billing.id).Select(x => new
  2206 + {
  2207 + teacherId = x.jks,
  2208 + teacherName = x.jksxm,
  2209 + teacherAccount = x.jkszh,
  2210 + performance = x.jksyj,
  2211 + performanceTime = x.yjsj,
  2212 + itemDetailId = x.kdpxid,
  2213 + goldTriangleId = x.jsj_id
  2214 + }).ToList(),
  2215 +
  2216 + // 其他信息
  2217 + source = billing.khly, // 客户来源
  2218 + paymentMethod = billing.fkfs, // 支付方式
  2219 + remark = billing.bz, // 备注
  2220 + createTime = billing.createTime
  2221 + }).OrderByDescending(x => x.date).ToList();
  2222 +
  2223 + // 构建返回结果
  2224 + var result = new
  2225 + {
  2226 + success = true,
  2227 + data = new
  2228 + {
  2229 + // 汇总统计
  2230 + summary = new
  2231 + {
  2232 + totalCount = billingRecords.Count,
  2233 + totalAmount = billingRecords.Sum(x => x.zdyj),
  2234 + totalPaidAmount = billingRecords.Sum(x => x.sfyj),
  2235 + totalDebt = billingRecords.Sum(x => x.qk),
  2236 + totalPurchasedItems = purchasedItems.Count,
  2237 + totalGiftedItems = giftedItems.Count,
  2238 + totalExperienceItems = experienceItems.Count,
  2239 + totalHealthTeachers = healthTeacherData.GroupBy(x => x.jks).Count()
  2240 + },
  2241 + // 详细记录列表
  2242 + records = detailedRecords
  2243 + },
  2244 + message = "获取开单记录汇总信息成功"
  2245 + };
  2246 +
  2247 + return result;
  2248 + }
  2249 + catch (Exception ex)
  2250 + {
  2251 + throw NCCException.Oh($"获取开单记录汇总信息失败:{ex.Message}");
  2252 + }
  2253 + }
  2254 + #endregion
  2255 +
1899 2256 #region 私有方法
1900 2257 /// <summary>
1901 2258 /// 检查开单记录是否可以操作
... ... @@ -1918,27 +2275,27 @@ namespace NCC.Extend.LqKdKdjlb
1918 2275 return (false, "该开单记录已经作废");
1919 2276 }
1920 2277 // 判断是否有对应的补缴记录
1921   - var qkbjList = await _db.Queryable<LqKdKdjlbEntity>().Where(p => p.SupplementBillingId == billingId).ToListAsync();
  2278 + var qkbjList = await _db.Queryable<LqKdKdjlbEntity>().Where(p => p.SupplementBillingId == billingId && p.IsEffective == StatusEnum.有效.GetHashCode()).ToListAsync();
1922 2279 if (qkbjList.Any())
1923 2280 {
1924 2281 return (false, "该开单记录有对应的补缴记录,不能进行操作");
1925 2282 }
1926 2283 // 查询开单记录下的品项明细ID列表
1927   - var pxmxIdList = await _db.Queryable<LqKdPxmxEntity>().Where(p => p.Glkdbh == billingId).Select(p => p.Id).Distinct().ToListAsync();
  2284 + var pxmxIdList = await _db.Queryable<LqKdPxmxEntity>().Where(p => p.Glkdbh == billingId && p.IsEffective == StatusEnum.有效.GetHashCode()).Select(p => p.Id).Distinct().ToListAsync();
1928 2285 // 判断是否有对应的消耗记录
1929   - var xhPxmxList = await _db.Queryable<LqXhPxmxEntity>().Where(p => pxmxIdList.Contains(p.BillingItemId)).ToListAsync();
  2286 + var xhPxmxList = await _db.Queryable<LqXhPxmxEntity>().Where(p => pxmxIdList.Contains(p.BillingItemId) && p.IsEffective == StatusEnum.有效.GetHashCode()).ToListAsync();
1930 2287 if (xhPxmxList.Any())
1931 2288 {
1932 2289 return (false, "该开单记录有对应的消耗记录,不能进行操作");
1933 2290 }
1934 2291 // 判断是否有退卡记录
1935   - var hytkMxList = await _db.Queryable<LqHytkMxEntity>().Where(p => pxmxIdList.Contains(p.BillingItemId)).ToListAsync();
  2292 + var hytkMxList = await _db.Queryable<LqHytkMxEntity>().Where(p => pxmxIdList.Contains(p.BillingItemId) && p.IsEffective == StatusEnum.有效.GetHashCode()).ToListAsync();
1936 2293 if (hytkMxList.Any())
1937 2294 {
1938 2295 return (false, "该开单记录有对应的退卡记录,不能进行操作");
1939 2296 }
1940 2297 // 判断是否已经有储扣记录
1941   - var deductInfoList = await _db.Queryable<LqKdDeductinfoEntity>().Where(p => pxmxIdList.Contains(p.DeductId)).ToListAsync();
  2298 + var deductInfoList = await _db.Queryable<LqKdDeductinfoEntity>().Where(p => pxmxIdList.Contains(p.DeductId) && p.IsEffective == StatusEnum.有效.GetHashCode()).ToListAsync();
1942 2299 if (deductInfoList.Any())
1943 2300 {
1944 2301 return (false, "该开单记录有对应的储扣记录,不能进行操作");
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqPackageInfoService.cs
... ... @@ -9,9 +9,11 @@ using NCC.Common.Filter;
9 9 using NCC.Dependency;
10 10 using NCC.DynamicApiController;
11 11 using NCC.Extend.Entitys.Dto.LqPackageInfo;
  12 +using NCC.Extend.Entitys.Dto.LqXmzl;
12 13 using NCC.Extend.Entitys.Enum;
13 14 using NCC.Extend.Entitys.lq_package_info;
14 15 using NCC.Extend.Entitys.lq_package_item_detail;
  16 +using NCC.Extend.Entitys.lq_xmzl;
15 17 using NCC.Extend.Interfaces.LqPackageInfo;
16 18 using NCC.FriendlyException;
17 19 using SqlSugar;
... ... @@ -197,17 +199,23 @@ namespace NCC.Extend.LqPackageInfo
197 199 .WhereIF(input.MinItemQuantity.HasValue, w => w.MinItemQuantity == input.MinItemQuantity.Value)
198 200 .WhereIF(input.CreateTimeStart.HasValue, w => w.CreateTime >= input.CreateTimeStart.Value)
199 201 .WhereIF(input.CreateTimeEnd.HasValue, w => w.CreateTime <= input.CreateTimeEnd.Value)
  202 + .WhereIF(input.IsEffective.HasValue, w => w.IsEffective == input.IsEffective.Value)
200 203 .Select(it => new LqPackageInfoListOutput
201 204 {
202   - Id = it.Id,
203   - ActivityName = it.ActivityName,
204   - ActivityDesc = it.ActivityDesc,
205   - StartTime = it.StartTime,
206   - EndTime = it.EndTime,
207   - MinItemQuantity = it.MinItemQuantity,
208   - ActivityRules = it.ActivityRules,
209   - SortOrder = it.SortOrder,
210   - CreateTime = it.CreateTime
  205 + id = it.Id,
  206 + activityName = it.ActivityName,
  207 + activityDesc = it.ActivityDesc,
  208 + startTime = it.StartTime,
  209 + endTime = it.EndTime,
  210 + minItemQuantity = it.MinItemQuantity,
  211 + activityRules = it.ActivityRules,
  212 + sortOrder = it.SortOrder,
  213 + createTime = it.CreateTime,
  214 + isEffective = it.IsEffective,
  215 + createUser = it.CreateUser,
  216 + updateUser = it.UpdateUser,
  217 + updateTime = it.UpdateTime,
  218 + activityImages = it.ActivityImages,
211 219 }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
212 220 return PageResult<LqPackageInfoListOutput>.SqlSugarPageResult(data);
213 221 }
... ... @@ -218,13 +226,72 @@ namespace NCC.Extend.LqPackageInfo
218 226 /// 获取营销活动详情
219 227 /// </summary>
220 228 /// <param name="id">营销活动ID</param>
221   - /// <returns>营销活动详情</returns>
  229 + /// <returns>营销活动详情(包含品项信息)</returns>
  230 + /// <remarks>
  231 + /// 获取营销活动详情,包括活动基本信息和对应的品项明细列表
  232 + ///
  233 + /// 返回数据说明:
  234 + /// - 活动基本信息:活动名称、描述、时间、规则等
  235 + /// - 品项明细列表:该活动包含的所有品项信息
  236 + /// </remarks>
  237 + /// <response code="200">成功获取营销活动详情</response>
  238 + /// <response code="404">营销活动不存在</response>
  239 + /// <response code="500">服务器内部错误</response>
222 240 [HttpGet("GetPackageInfoDetailAsync")]
223 241 public async Task<dynamic> GetPackageInfoDetailAsync(string id)
224 242 {
225   - var data = await _db.Queryable<LqPackageInfoEntity>().Where(w => w.Id == id).FirstAsync();
226   - var output = data.Adapt<LqPackageInfoListOutput>();
227   - return output;
  243 + try
  244 + {
  245 + // 获取营销活动基本信息
  246 + var packageInfo = await _db.Queryable<LqPackageInfoEntity>().Where(w => w.Id == id).FirstAsync();
  247 + if (packageInfo == null)
  248 + {
  249 + throw NCCException.Oh("营销活动不存在");
  250 + }
  251 + // 获取品项明细信息
  252 + var activityItems = await _db.Queryable<LqPackageItemDetailEntity>()
  253 + .Where(w => w.ActivityId == id && w.IsEffective == StatusEnum.有效.GetHashCode())
  254 + .OrderBy(w => w.CreateTime)
  255 + .Select(it => new
  256 + {
  257 + id = it.Id,
  258 + activityId = it.ActivityId,
  259 + itemId = it.ItemId,
  260 + itemName = it.ItemName,
  261 + itemCategory = it.ItemCategory,
  262 + itemRemark = it.ItemRemark,
  263 + createTime = it.CreateTime
  264 + })
  265 + .ToListAsync();
  266 + // 构建返回结果
  267 + var result = new
  268 + {
  269 + // 活动基本信息
  270 + id = packageInfo.Id,
  271 + activityName = packageInfo.ActivityName,
  272 + activityDesc = packageInfo.ActivityDesc,
  273 + startTime = packageInfo.StartTime,
  274 + endTime = packageInfo.EndTime,
  275 + minItemQuantity = packageInfo.MinItemQuantity,
  276 + activityRules = packageInfo.ActivityRules,
  277 + activityImages = packageInfo.ActivityImages,
  278 + sortOrder = packageInfo.SortOrder,
  279 + createTime = packageInfo.CreateTime,
  280 + updateTime = packageInfo.UpdateTime,
  281 + createUser = packageInfo.CreateUser,
  282 + updateUser = packageInfo.UpdateUser,
  283 + isEffective = packageInfo.IsEffective,
  284 +
  285 + // 品项明细列表
  286 + activityItems = activityItems
  287 + };
  288 +
  289 + return result;
  290 + }
  291 + catch (Exception ex)
  292 + {
  293 + throw NCCException.Oh($"获取营销活动详情失败:{ex.Message}");
  294 + }
228 295 }
229 296 #endregion
230 297  
... ... @@ -400,6 +467,77 @@ namespace NCC.Extend.LqPackageInfo
400 467 }
401 468 #endregion
402 469  
  470 + #region 根据营销活动ID获取品项详情
  471 + /// <summary>
  472 + /// 根据营销活动ID获取品项详情
  473 + /// </summary>
  474 + /// <param name="activityId">营销活动ID</param>
  475 + /// <returns>品项详情列表</returns>
  476 + /// <remarks>
  477 + /// 通过营销活动ID获取对应的品项ID,然后查询品项表获取完整的品项信息
  478 + ///
  479 + /// 查询流程:
  480 + /// 1. 根据营销活动ID查询营销活动品项明细表,获取品项ID列表
  481 + /// 2. 根据品项ID列表查询项目资料表,获取完整的品项信息
  482 + /// 3. 返回品项详情列表
  483 + /// </remarks>
  484 + /// <response code="200">成功获取品项详情</response>
  485 + /// <response code="404">营销活动不存在或没有品项</response>
  486 + /// <response code="500">服务器内部错误</response>
  487 + [HttpGet("GetPackageItemDetailByActivityIdAsync/{activityId}")]
  488 + public async Task<dynamic> GetPackageItemDetailByActivityIdAsync(string activityId)
  489 + {
  490 + try
  491 + {
  492 + // 验证参数
  493 + if (string.IsNullOrEmpty(activityId))
  494 + {
  495 + throw NCCException.Oh("营销活动ID不能为空");
  496 + }
  497 + // 检查营销活动是否存在
  498 + var activityExists = await _db.Queryable<LqPackageInfoEntity>().Where(w => w.Id == activityId && w.IsEffective == StatusEnum.有效.GetHashCode()).AnyAsync();
  499 + if (!activityExists)
  500 + {
  501 + throw NCCException.Oh("营销活动不存在或已失效");
  502 + }
  503 + // 获取营销活动下的品项ID列表
  504 + var itemIds = await _db.Queryable<LqPackageItemDetailEntity>().Where(w => w.ActivityId == activityId && w.IsEffective == StatusEnum.有效.GetHashCode()).Select(w => w.ItemId).ToListAsync();
  505 + if (!itemIds.Any())
  506 + {
  507 + throw NCCException.Oh("该营销活动暂无品项");
  508 + }
  509 + // 根据品项ID查询项目资料表
  510 + var itemDetails = await _db.Queryable<LqXmzlEntity>()
  511 + .Where(w => itemIds.Contains(w.Id) && w.IsEffective == StatusEnum.有效.GetHashCode())
  512 + .Select(it => new LqXmzlListOutput
  513 + {
  514 + id = it.Id,
  515 + xmbh = it.Xmbh,
  516 + xmmc = it.Xmmc,
  517 + bzjg = it.Bzjg,
  518 + xmsc = it.Xmsc,
  519 + jcfwtc = it.Jcfwtc,
  520 + fl1 = it.Fl1,
  521 + fl2 = it.Fl2,
  522 + fl3 = it.Fl3,
  523 + fl4 = it.Fl4,
  524 + fl = it.Fl,
  525 + qt1 = it.Qt1,
  526 + qt2 = it.Qt2,
  527 + sgf = it.Sgf,
  528 + beautyType = it.BeautyType,
  529 + isEffective = it.IsEffective,
  530 + sourceType = it.SourceType
  531 + }).MergeTable().ToPagedListAsync(1, 50);
  532 + return PageResult<LqXmzlListOutput>.SqlSugarPageResult(itemDetails);
  533 + }
  534 + catch (Exception ex)
  535 + {
  536 + throw NCCException.Oh($"获取品项详情失败: {ex.Message}");
  537 + }
  538 + }
  539 + #endregion
  540 +
403 541 #region 获取当前时间有效的活动
404 542 /// <summary>
405 543 /// 获取当前时间有效的活动
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs
... ... @@ -1696,6 +1696,7 @@ namespace NCC.Extend.LqStatistics
1696 1696 // 添加查询条件
1697 1697 query = query.WhereIF(!string.IsNullOrEmpty(input.StatisticsMonth), x => x.StatisticsMonth == input.StatisticsMonth);
1698 1698 query = query.WhereIF(!string.IsNullOrEmpty(input.StoreId), x => x.StoreId == input.StoreId);
  1699 + query = query.WhereIF(!string.IsNullOrEmpty(input.StoreName), x => x.StoreName.Contains(input.StoreName));
1699 1700 query = query.WhereIF(!string.IsNullOrEmpty(input.EmployeeId), x => x.EmployeeId == input.EmployeeId);
1700 1701 query = query.WhereIF(!string.IsNullOrEmpty(input.EmployeeName), x => x.EmployeeName.Contains(input.EmployeeName));
1701 1702 query = query.WhereIF(!string.IsNullOrEmpty(input.GoldTriangleId), x => x.GoldTriangleId == input.GoldTriangleId);
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqTkjlbService.cs
... ... @@ -169,6 +169,8 @@ namespace NCC.Extend.LqTkjlb
169 169 {
170 170 throw NCCException.Oh("未找到对应的拓客活动用户信息,请确认活动ID和用户ID是否正确");
171 171 }
  172 + var MemberNumber = "LQ" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
  173 + var MemberId = YitIdHelper.NextId().ToString();
172 174 var eventUserInfo = eventUserInfoList.First();
173 175 // 创建拓客记录
174 176 var entity = input.Adapt<LqTkjlbEntity>();
... ... @@ -177,16 +179,17 @@ namespace NCC.Extend.LqTkjlb
177 179 entity.StoreId = eventUserInfo.StoreId;
178 180 entity.DepId = eventUserInfo.DepId;
179 181 entity.ExpansionTime = DateTime.Now;
  182 + entity.MemberId = MemberId;
180 183 var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
181 184 if (!(isOk > 0))
182 185 throw NCCException.Oh("创建拓客记录失败");
183 186 // 创建客户信息
184 187 LqKhxxEntity MemberInfo = new LqKhxxEntity();
185   - MemberInfo.Id = YitIdHelper.NextId().ToString();
  188 + MemberInfo.Id = MemberId;
186 189 MemberInfo.Khmc = entity.CustomerName;
187 190 MemberInfo.Sjh = input.customerPhone; // 设置手机号
188 191 MemberInfo.Khlx = MemberTypeEnum.线索.GetHashCode().ToString();
189   - MemberInfo.Dah = "LQ" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
  192 + MemberInfo.Dah = MemberNumber;
190 193 MemberInfo.Jdqd = "19.9卡";
191 194  
192 195 //找到input.expansionUserId的用户信息
... ... @@ -526,5 +529,239 @@ namespace NCC.Extend.LqTkjlb
526 529 }
527 530 #endregion
528 531  
  532 + #region 漏斗统计
  533 + /// <summary>
  534 + /// 获取拓客活动漏斗统计数据
  535 + /// </summary>
  536 + /// <param name="eventId">活动ID</param>
  537 + /// <returns>漏斗统计数据</returns>
  538 + [HttpGet("GetFunnelStatistics/{eventId}")]
  539 + public async Task<dynamic> GetFunnelStatistics(string eventId)
  540 + {
  541 + try
  542 + {
  543 + var sql = @"
  544 + SELECT
  545 + md.F_Id as store_id,
  546 + md.dm as store_name,
  547 + COUNT(DISTINCT tk.F_Id) as tk_count, -- 拓客数量
  548 + COUNT(DISTINCT CASE WHEN yy.F_Id IS NOT NULL THEN tk.F_CustomerPhone END) as yy_count, -- 预约人数(已确认)
  549 + COUNT(DISTINCT CASE WHEN xh.F_Id IS NOT NULL THEN tk.F_CustomerPhone END) as hk_count, -- 耗卡人数
  550 + COALESCE(SUM(CASE WHEN xh.F_Id IS NOT NULL THEN xh.xfje END), 0) as hk_amount, -- 耗卡金额
  551 + ROUND(
  552 + COUNT(DISTINCT CASE WHEN yy.F_Id IS NOT NULL THEN tk.F_CustomerPhone END) * 100.0 /
  553 + COUNT(DISTINCT tk.F_Id), 2
  554 + ) as yy_conversion_rate, -- 预约转化率(预约人数/拓客数量)
  555 + ROUND(
  556 + COUNT(DISTINCT CASE WHEN xh.F_Id IS NOT NULL THEN tk.F_CustomerPhone END) * 100.0 /
  557 + COUNT(DISTINCT CASE WHEN yy.F_Id IS NOT NULL THEN tk.F_CustomerPhone END), 2
  558 + ) as hk_conversion_rate -- 耗卡转化率(耗卡人数/预约人数)
  559 + FROM lq_tkjlb tk
  560 + JOIN lq_mdxx md ON tk.F_StoreId = md.F_Id
  561 + LEFT JOIN lq_yyjl yy ON tk.F_MemberId = yy.gk
  562 + AND yy.F_Status = '已确认'
  563 + LEFT JOIN lq_xh_hyhk xh ON tk.F_MemberId = xh.hy
  564 + AND xh.F_IsEffective = 1
  565 + WHERE tk.F_EventId = @eventId
  566 + GROUP BY md.F_Id, md.dm
  567 + ORDER BY tk_count DESC";
  568 +
  569 + var result = await _db.Ado.SqlQueryAsync<dynamic>(sql, new { eventId });
  570 +
  571 + return new
  572 + {
  573 + success = true,
  574 + data = result,
  575 + message = "获取漏斗统计数据成功"
  576 + };
  577 + }
  578 + catch (Exception ex)
  579 + {
  580 + throw NCCException.Oh("获取漏斗统计数据失败:" + ex.Message);
  581 + }
  582 + }
  583 +
  584 + /// <summary>
  585 + /// 获取拓客活动总体漏斗统计
  586 + /// </summary>
  587 + /// <param name="eventId">活动ID</param>
  588 + /// <returns>总体漏斗统计数据</returns>
  589 + [HttpGet("GetOverallFunnelStatistics/{eventId}")]
  590 + public async Task<dynamic> GetOverallFunnelStatistics(string eventId)
  591 + {
  592 + try
  593 + {
  594 + var sql = @"
  595 + SELECT
  596 + COUNT(DISTINCT tk.F_Id) as total_tk_count, -- 总拓客数量
  597 + COUNT(DISTINCT CASE WHEN yy.F_Id IS NOT NULL THEN tk.F_CustomerPhone END) as total_yy_count, -- 总预约人数
  598 + COUNT(DISTINCT CASE WHEN xh.F_Id IS NOT NULL THEN tk.F_CustomerPhone END) as total_hk_count, -- 总耗卡人数
  599 + COALESCE(SUM(CASE WHEN xh.F_Id IS NOT NULL THEN xh.xfje END), 0) as total_hk_amount, -- 总耗卡金额
  600 + ROUND(
  601 + COUNT(DISTINCT CASE WHEN yy.F_Id IS NOT NULL THEN tk.F_CustomerPhone END) * 100.0 /
  602 + COUNT(DISTINCT tk.F_Id), 2
  603 + ) as overall_yy_conversion_rate, -- 总体预约转化率
  604 + ROUND(
  605 + COUNT(DISTINCT CASE WHEN xh.F_Id IS NOT NULL THEN tk.F_CustomerPhone END) * 100.0 /
  606 + COUNT(DISTINCT CASE WHEN yy.F_Id IS NOT NULL THEN tk.F_CustomerPhone END), 2
  607 + ) as overall_hk_conversion_rate -- 总体耗卡转化率
  608 + FROM lq_tkjlb tk
  609 + LEFT JOIN lq_yyjl yy ON tk.F_MemberId = yy.gk
  610 + AND yy.F_Status = '已确认'
  611 + LEFT JOIN lq_xh_hyhk xh ON tk.F_MemberId = xh.hy
  612 + AND xh.F_IsEffective = 1
  613 + WHERE tk.F_EventId = @eventId";
  614 +
  615 + var result = await _db.Ado.SqlQueryAsync<dynamic>(sql, new { eventId });
  616 +
  617 + return new
  618 + {
  619 + success = true,
  620 + data = result?.FirstOrDefault(),
  621 + message = "获取总体漏斗统计数据成功"
  622 + };
  623 + }
  624 + catch (Exception ex)
  625 + {
  626 + throw NCCException.Oh("获取总体漏斗统计数据失败:" + ex.Message);
  627 + }
  628 + }
  629 + #endregion
  630 +
  631 + #region 门店顾客详情
  632 + /// <summary>
  633 + /// 获取门店拓客活动顾客详情
  634 + /// </summary>
  635 + /// <param name="eventId">活动ID</param>
  636 + /// <param name="storeId">门店ID</param>
  637 + /// <returns>门店顾客详情列表</returns>
  638 + [HttpGet("GetStoreCustomerDetails/{eventId}/{storeId}")]
  639 + public async Task<dynamic> GetStoreCustomerDetails(string eventId, string storeId)
  640 + {
  641 + try
  642 + {
  643 + var sql = @"
  644 + SELECT
  645 + tk.F_Id as tk_id, -- 拓客记录ID
  646 + tk.F_CustomerPhone as customer_phone, -- 顾客手机号
  647 + tk.F_MemberId as member_id, -- 会员ID
  648 + tk.F_CustomerName as customer_name, -- 顾客姓名
  649 + tk.F_CreateTime as tk_time, -- 拓客时间
  650 + yy.F_Id as yy_id, -- 预约ID
  651 + yy.F_Status as yy_status, -- 预约状态
  652 + yy.F_CreateTime as yy_time, -- 预约时间
  653 + yy.yysj as appointment_time, -- 预约到店时间
  654 + xh.F_Id as xh_id, -- 耗卡ID
  655 + xh.F_CreateTime as xh_time, -- 耗卡时间
  656 + xh.xfje as consume_amount, -- 耗卡金额
  657 + CASE
  658 + WHEN yy.F_Id IS NOT NULL THEN '已预约'
  659 + ELSE '未预约'
  660 + END as appointment_status, -- 预约状态描述
  661 + CASE
  662 + WHEN xh.F_Id IS NOT NULL THEN '已耗卡'
  663 + ELSE '未耗卡'
  664 + END as consume_status -- 耗卡状态描述
  665 + FROM lq_tkjlb tk
  666 + LEFT JOIN lq_yyjl yy ON tk.F_MemberId = yy.gk
  667 + AND yy.F_Status = '已确认'
  668 + LEFT JOIN lq_xh_hyhk xh ON tk.F_MemberId = xh.hy
  669 + AND xh.F_IsEffective = 1
  670 + WHERE tk.F_EventId = @eventId
  671 + AND tk.F_StoreId = @storeId
  672 + ORDER BY tk.F_CreateTime DESC";
  673 +
  674 + var result = await _db.Ado.SqlQueryAsync<dynamic>(sql, new { eventId, storeId });
  675 +
  676 + return new
  677 + {
  678 + success = true,
  679 + data = result,
  680 + message = "获取门店顾客详情成功"
  681 + };
  682 + }
  683 + catch (Exception ex)
  684 + {
  685 + throw NCCException.Oh("获取门店顾客详情失败:" + ex.Message);
  686 + }
  687 + }
  688 +
  689 + /// <summary>
  690 + /// 获取门店拓客活动顾客详情(分页)
  691 + /// </summary>
  692 + /// <param name="eventId">活动ID</param>
  693 + /// <param name="storeId">门店ID</param>
  694 + /// <param name="pageIndex">页码</param>
  695 + /// <param name="pageSize">页大小</param>
  696 + /// <returns>分页的门店顾客详情列表</returns>
  697 + [HttpGet("GetStoreCustomerDetailsPaged/{eventId}/{storeId}")]
  698 + public async Task<dynamic> GetStoreCustomerDetailsPaged(string eventId, string storeId, int pageIndex = 1, int pageSize = 20)
  699 + {
  700 + try
  701 + {
  702 + var sql = @"
  703 + SELECT
  704 + tk.F_Id as tk_id, -- 拓客记录ID
  705 + tk.F_CustomerPhone as customer_phone, -- 顾客手机号
  706 + tk.F_MemberId as member_id, -- 会员ID
  707 + tk.F_CustomerName as customer_name, -- 顾客姓名
  708 + tk.F_CreateTime as tk_time, -- 拓客时间
  709 + yy.F_Id as yy_id, -- 预约ID
  710 + yy.F_Status as yy_status, -- 预约状态
  711 + yy.F_CreateTime as yy_time, -- 预约时间
  712 + yy.yysj as appointment_time, -- 预约到店时间
  713 + xh.F_Id as xh_id, -- 耗卡ID
  714 + xh.F_CreateTime as xh_time, -- 耗卡时间
  715 + xh.xfje as consume_amount, -- 耗卡金额
  716 + CASE
  717 + WHEN yy.F_Id IS NOT NULL THEN '已预约'
  718 + ELSE '未预约'
  719 + END as appointment_status, -- 预约状态描述
  720 + CASE
  721 + WHEN xh.F_Id IS NOT NULL THEN '已耗卡'
  722 + ELSE '未耗卡'
  723 + END as consume_status -- 耗卡状态描述
  724 + FROM lq_tkjlb tk
  725 + LEFT JOIN lq_yyjl yy ON tk.F_MemberId = yy.gk
  726 + AND yy.F_Status = '已确认'
  727 + LEFT JOIN lq_xh_hyhk xh ON tk.F_MemberId = xh.hy
  728 + AND xh.F_IsEffective = 1
  729 + WHERE tk.F_EventId = @eventId
  730 + AND tk.F_StoreId = @storeId
  731 + ORDER BY tk.F_CreateTime DESC
  732 + LIMIT @offset, @pageSize";
  733 +
  734 + var countSql = @"
  735 + SELECT COUNT(*) as total
  736 + FROM lq_tkjlb tk
  737 + WHERE tk.F_EventId = @eventId
  738 + AND tk.F_StoreId = @storeId";
  739 +
  740 + var offset = (pageIndex - 1) * pageSize;
  741 + var result = await _db.Ado.SqlQueryAsync<dynamic>(sql, new { eventId, storeId, offset, pageSize });
  742 + var totalResult = await _db.Ado.SqlQueryAsync<dynamic>(countSql, new { eventId, storeId });
  743 + var total = totalResult?.FirstOrDefault()?.total ?? 0;
  744 +
  745 + return new
  746 + {
  747 + success = true,
  748 + data = new
  749 + {
  750 + list = result,
  751 + total = total,
  752 + pageIndex = pageIndex,
  753 + pageSize = pageSize,
  754 + totalPages = (int)Math.Ceiling((double)total / pageSize)
  755 + },
  756 + message = "获取门店顾客详情成功"
  757 + };
  758 + }
  759 + catch (Exception ex)
  760 + {
  761 + throw NCCException.Oh("获取门店顾客详情失败:" + ex.Message);
  762 + }
  763 + }
  764 + #endregion
  765 +
529 766 }
530 767 }
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqXmzlService.cs
... ... @@ -61,8 +61,8 @@ namespace NCC.Extend.LqXmzl
61 61 return output;
62 62 }
63 63 #endregion
64   -
65   - #region 获取项目资料列表
  64 +
  65 + #region 获取项目资料列表
66 66 /// <summary>
67 67 /// 获取项目资料列表
68 68 /// </summary>
... ... @@ -83,14 +83,13 @@ namespace NCC.Extend.LqXmzl
83 83 .WhereIF(!string.IsNullOrEmpty(input.fl2), p => p.Fl2.Contains(input.fl2))
84 84 .WhereIF(!string.IsNullOrEmpty(input.fl3), p => p.Fl3.Contains(input.fl3))
85 85 .WhereIF(!string.IsNullOrEmpty(input.fl4), p => p.Fl4.Contains(input.fl4))
86   - .WhereIF(!string.IsNullOrEmpty(input.tjlb), p => p.Tjlb.Contains(input.tjlb))
87   - .WhereIF(!string.IsNullOrEmpty(input.zklb), p => p.Zklb.Contains(input.zklb))
88 86 .WhereIF(!string.IsNullOrEmpty(input.fl), p => p.Fl.Contains(input.fl))
89 87 .WhereIF(!string.IsNullOrEmpty(input.qt1), p => p.Qt1.Contains(input.qt1))
90 88 .WhereIF(!string.IsNullOrEmpty(input.qt2), p => p.Qt2.Contains(input.qt2))
91   - .WhereIF(!string.IsNullOrEmpty(input.syje), p => p.Syje.Equals(input.syje))
92   - .WhereIF(!string.IsNullOrEmpty(input.cellje), p => p.Cellje.Equals(input.cellje))
93 89 .WhereIF(!string.IsNullOrEmpty(input.sgf), p => p.Sgf.Equals(input.sgf))
  90 + .WhereIF(!string.IsNullOrEmpty(input.beautyType), p => p.BeautyType.Contains(input.beautyType))
  91 + .WhereIF(input.isEffective != 0, p => p.IsEffective.Equals(input.isEffective))
  92 + .WhereIF(!string.IsNullOrEmpty(input.sourceType), p => p.SourceType.Contains(input.sourceType))
94 93 .Select(it => new LqXmzlListOutput
95 94 {
96 95 id = it.Id,
... ... @@ -103,16 +102,13 @@ namespace NCC.Extend.LqXmzl
103 102 fl2 = it.Fl2,
104 103 fl3 = it.Fl3,
105 104 fl4 = it.Fl4,
106   - tjlb = it.Tjlb,
107   - zklb = it.Zklb,
108 105 fl = it.Fl,
109 106 qt1 = it.Qt1,
110 107 qt2 = it.Qt2,
111   - syje = it.Syje,
112   - cellje = it.Cellje,
113 108 sgf = it.Sgf,
114   - projectNumber = it.ProjectNumber,
  109 + beautyType = it.BeautyType,
115 110 sourceType = it.SourceType,
  111 + isEffective = it.IsEffective,
116 112 }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
117 113 return PageResult<LqXmzlListOutput>.SqlSugarPageResult(data);
118 114 }
... ... @@ -156,13 +152,9 @@ namespace NCC.Extend.LqXmzl
156 152 .WhereIF(!string.IsNullOrEmpty(input.fl2), p => p.Fl2.Contains(input.fl2))
157 153 .WhereIF(!string.IsNullOrEmpty(input.fl3), p => p.Fl3.Contains(input.fl3))
158 154 .WhereIF(!string.IsNullOrEmpty(input.fl4), p => p.Fl4.Contains(input.fl4))
159   - .WhereIF(!string.IsNullOrEmpty(input.tjlb), p => p.Tjlb.Contains(input.tjlb))
160   - .WhereIF(!string.IsNullOrEmpty(input.zklb), p => p.Zklb.Contains(input.zklb))
161 155 .WhereIF(!string.IsNullOrEmpty(input.fl), p => p.Fl.Contains(input.fl))
162 156 .WhereIF(!string.IsNullOrEmpty(input.qt1), p => p.Qt1.Contains(input.qt1))
163 157 .WhereIF(!string.IsNullOrEmpty(input.qt2), p => p.Qt2.Contains(input.qt2))
164   - .WhereIF(!string.IsNullOrEmpty(input.syje), p => p.Syje.Equals(input.syje))
165   - .WhereIF(!string.IsNullOrEmpty(input.cellje), p => p.Cellje.Equals(input.cellje))
166 158 .WhereIF(!string.IsNullOrEmpty(input.sgf), p => p.Sgf.Equals(input.sgf))
167 159 .Select(it => new LqXmzlListOutput
168 160 {
... ... @@ -176,13 +168,9 @@ namespace NCC.Extend.LqXmzl
176 168 fl2 = it.Fl2,
177 169 fl3 = it.Fl3,
178 170 fl4 = it.Fl4,
179   - tjlb = it.Tjlb,
180   - zklb = it.Zklb,
181 171 fl = it.Fl,
182 172 qt1 = it.Qt1,
183 173 qt2 = it.Qt2,
184   - syje = it.Syje,
185   - cellje = it.Cellje,
186 174 sgf = it.Sgf,
187 175 }).MergeTable().OrderBy(sidx + " " + input.sort).ToListAsync();
188 176 return data;
... ... @@ -246,6 +234,7 @@ namespace NCC.Extend.LqXmzl
246 234 [HttpPost("batchRemove")]
247 235 public async Task BatchRemove([FromBody] List<string> ids)
248 236 {
  237 + throw NCCException.Oh("不允许删除项目资料");
249 238 var entitys = await _db.Queryable<LqXmzlEntity>().In(it => it.Id, ids).ToListAsync();
250 239 if (entitys.Count > 0)
251 240 {
... ... @@ -284,19 +273,112 @@ namespace NCC.Extend.LqXmzl
284 273 }
285 274 #endregion
286 275  
287   - #region 删除项目资料
  276 + #region 删除项目资料
288 277 /// <summary>
289 278 /// 删除项目资料
290 279 /// </summary>
  280 + /// <param name="id">主键</param>
291 281 /// <returns></returns>
292 282 [HttpDelete("{id}")]
293 283 public async Task Delete(string id)
294 284 {
295   - var entity = await _db.Queryable<LqXmzlEntity>().FirstAsync(p => p.Id == id);
296   - _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005);
297   - var isOk = await _db.Deleteable<LqXmzlEntity>().Where(d => d.Id == id).ExecuteCommandAsync();
298   - if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1002);
  285 + throw NCCException.Oh("不允许删除项目资料");
299 286 }
300 287 #endregion
  288 +
  289 + #region 获取字段去重数据
  290 + /// <summary>
  291 + /// 获取指定字段的去重数据
  292 + /// </summary>
  293 + /// <param name="fieldName">字段名称,支持:fl1、fl2、fl3、fl4、fl、qt1、beautyType、sourceType</param>
  294 + /// <returns>去重后的字段数据</returns>
  295 + [HttpPost("GetDistinctFieldData")]
  296 + public async Task<dynamic> GetDistinctFieldData([FromBody] string fieldName)
  297 + {
  298 + try
  299 + {
  300 + // 验证字段名称
  301 + var validFields = new[] { "fl1", "fl2", "fl3", "fl4", "fl", "qt1", "beautyType", "sourceType" };
  302 + if (!validFields.Contains(fieldName))
  303 + {
  304 + throw NCCException.Oh($"无效的字段名称: {fieldName}。支持的字段: {string.Join(", ", validFields)}");
  305 + }
  306 +
  307 + List<string> distinctValues = new List<string>();
  308 +
  309 + switch (fieldName)
  310 + {
  311 + case "fl1":
  312 + distinctValues = await _db.Queryable<LqXmzlEntity>()
  313 + .Where(p => !string.IsNullOrEmpty(p.Fl1))
  314 + .Select(p => p.Fl1)
  315 + .Distinct()
  316 + .ToListAsync();
  317 + break;
  318 + case "fl2":
  319 + distinctValues = await _db.Queryable<LqXmzlEntity>()
  320 + .Where(p => !string.IsNullOrEmpty(p.Fl2))
  321 + .Select(p => p.Fl2)
  322 + .Distinct()
  323 + .ToListAsync();
  324 + break;
  325 + case "fl3":
  326 + distinctValues = await _db.Queryable<LqXmzlEntity>()
  327 + .Where(p => !string.IsNullOrEmpty(p.Fl3))
  328 + .Select(p => p.Fl3)
  329 + .Distinct()
  330 + .ToListAsync();
  331 + break;
  332 + case "fl4":
  333 + distinctValues = await _db.Queryable<LqXmzlEntity>()
  334 + .Where(p => !string.IsNullOrEmpty(p.Fl4))
  335 + .Select(p => p.Fl4)
  336 + .Distinct()
  337 + .ToListAsync();
  338 + break;
  339 + case "fl":
  340 + distinctValues = await _db.Queryable<LqXmzlEntity>()
  341 + .Where(p => !string.IsNullOrEmpty(p.Fl))
  342 + .Select(p => p.Fl)
  343 + .Distinct()
  344 + .ToListAsync();
  345 + break;
  346 + case "qt1":
  347 + distinctValues = await _db.Queryable<LqXmzlEntity>()
  348 + .Where(p => !string.IsNullOrEmpty(p.Qt1))
  349 + .Select(p => p.Qt1)
  350 + .Distinct()
  351 + .ToListAsync();
  352 + break;
  353 + case "beautyType":
  354 + distinctValues = await _db.Queryable<LqXmzlEntity>()
  355 + .Where(p => !string.IsNullOrEmpty(p.BeautyType))
  356 + .Select(p => p.BeautyType)
  357 + .Distinct()
  358 + .ToListAsync();
  359 + break;
  360 + case "sourceType":
  361 + distinctValues = await _db.Queryable<LqXmzlEntity>()
  362 + .Where(p => !string.IsNullOrEmpty(p.SourceType))
  363 + .Select(p => p.SourceType)
  364 + .Distinct()
  365 + .ToListAsync();
  366 + break;
  367 + }
  368 +
  369 + return new
  370 + {
  371 + fieldName = fieldName,
  372 + values = distinctValues.OrderBy(x => x).ToList()
  373 + };
  374 + }
  375 + catch (Exception ex)
  376 + {
  377 + throw NCCException.Oh($"获取字段去重数据失败:{ex.Message}");
  378 + }
  379 + }
  380 + #endregion
  381 +
  382 +
301 383 }
302 384 }
... ...