diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTkjlb/TkStatisticsInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTkjlb/TkStatisticsInput.cs
new file mode 100644
index 0000000..3850358
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTkjlb/TkStatisticsInput.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace NCC.Extend.Entitys.Dto.LqTkjlb
+{
+ ///
+ /// 拓客统计数据输入
+ ///
+ public class TkStatisticsInput
+ {
+ ///
+ /// 开始时间(可选)
+ ///
+ public DateTime? StartTime { get; set; }
+
+ ///
+ /// 结束时间(可选)
+ ///
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 活动ID(可选)
+ ///
+ public string EventId { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTkjlb/TkStatisticsOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTkjlb/TkStatisticsOutput.cs
new file mode 100644
index 0000000..9bee31c
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTkjlb/TkStatisticsOutput.cs
@@ -0,0 +1,51 @@
+using System;
+
+namespace NCC.Extend.Entitys.Dto.LqTkjlb
+{
+ ///
+ /// 拓客统计数据输出
+ ///
+ public class TkStatisticsOutput
+ {
+ ///
+ /// 拓客人数(去重后的人数)
+ ///
+ public int TkCount { get; set; }
+
+ ///
+ /// 邀约人头(已邀约人数)
+ ///
+ public int YaoyCount { get; set; }
+
+ ///
+ /// 预约人头(已预约人数)
+ ///
+ public int YyCount { get; set; }
+
+ ///
+ /// 到店人头(已到店人数)
+ ///
+ public int DdCount { get; set; }
+
+ ///
+ /// 开单人头(已开单人数)
+ ///
+ public int KdCount { get; set; }
+
+ ///
+ /// 开单金额
+ ///
+ public decimal KdAmount { get; set; }
+
+ ///
+ /// 消费人头(已消费人数)
+ ///
+ public int XfCount { get; set; }
+
+ ///
+ /// 消费金额
+ ///
+ public decimal XfAmount { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/ILqTkjlbService.cs b/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/ILqTkjlbService.cs
index 4a5be4d..d651f5b 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/ILqTkjlbService.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/ILqTkjlbService.cs
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
+using NCC.Extend.Entitys.Dto.LqTkjlb;
namespace NCC.Extend.Interfaces.LqTkjlb
{
@@ -15,5 +16,12 @@ namespace NCC.Extend.Interfaces.LqTkjlb
///
///
Task GetTeamDetail();
+
+ ///
+ /// 获取拓客统计数据
+ ///
+ /// 查询参数
+ /// 拓客统计数据
+ Task GetTkStatistics(TkStatisticsInput input);
}
}
\ No newline at end of file
diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqTkjlbService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqTkjlbService.cs
index 12f8fc7..2d709db 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend/LqTkjlbService.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend/LqTkjlbService.cs
@@ -960,5 +960,159 @@ namespace NCC.Extend.LqTkjlb
}
#endregion
+ #region 拓客统计数据
+ ///
+ /// 获取拓客统计数据
+ ///
+ ///
+ /// 统计拓客相关的各项数据,包括拓客人数、邀约人头、预约人头、到店人头、开单人头、开单金额、消费人头、消费金额
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "startTime": "2025-10-01",
+ /// "endTime": "2025-10-31",
+ /// "eventId": "活动ID"
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - startTime: 开始时间(可选)
+ /// - endTime: 结束时间(可选)
+ /// - eventId: 活动ID(可选)
+ ///
+ /// 返回字段说明:
+ /// - TkCount: 拓客人数
+ /// - YaoyCount: 邀约人头
+ /// - YyCount: 预约人头
+ /// - DdCount: 到店人头
+ /// - KdCount: 开单人头
+ /// - KdAmount: 开单金额
+ /// - XfCount: 消费人头
+ /// - XfAmount: 消费金额
+ ///
+ /// 查询参数
+ /// 拓客统计数据
+ /// 成功返回统计数据
+ /// 参数错误
+ /// 服务器内部错误
+ [HttpPost("get-tk-statistics")]
+ public async Task GetTkStatistics(TkStatisticsInput input)
+ {
+ try
+ {
+ // 构建基本过滤条件
+ string timeFilter = "";
+ if (input.StartTime.HasValue && input.EndTime.HasValue)
+ {
+ timeFilter = $@"
+ AND tk.F_CreateTime >= '{input.StartTime:yyyy-MM-dd HH:mm:ss}'
+ AND tk.F_CreateTime <= '{input.EndTime:yyyy-MM-dd HH:mm:ss}'";
+ }
+ else if (input.StartTime.HasValue)
+ {
+ timeFilter = $"AND tk.F_CreateTime >= '{input.StartTime:yyyy-MM-dd HH:mm:ss}'";
+ }
+ else if (input.EndTime.HasValue)
+ {
+ timeFilter = $"AND tk.F_CreateTime <= '{input.EndTime:yyyy-MM-dd HH:mm:ss}'";
+ }
+
+ string eventFilter = "";
+ if (!string.IsNullOrWhiteSpace(input.EventId))
+ {
+ eventFilter = $"AND tk.F_EventId = '{input.EventId}'";
+ }
+
+ // 第一步:获取拓客人数(去重会员ID)
+ var tkSql = $@"
+ SELECT COUNT(DISTINCT tk.F_MemberId) as tk_count
+ FROM lq_tkjlb tk
+ WHERE 1=1 {timeFilter} {eventFilter}";
+
+ var tkResult = await _db.Ado.SqlQueryAsync(tkSql);
+ var tkCount = Convert.ToInt32(tkResult?.FirstOrDefault()?.tk_count ?? 0);
+
+ // 第二步:获取邀约人头(去重会员ID)
+ var yaoySql = $@"
+ SELECT COUNT(DISTINCT tk.F_MemberId) as yaoy_count
+ FROM lq_tkjlb tk
+ INNER JOIN lq_yaoyjl yy ON tk.F_MemberId = yy.yykh
+ AND yy.F_StoreId = tk.F_StoreId
+ WHERE 1=1 {timeFilter} {eventFilter}";
+
+ var yaoyResult = await _db.Ado.SqlQueryAsync(yaoySql);
+ var yaoyCount = Convert.ToInt32(yaoyResult?.FirstOrDefault()?.yaoy_count ?? 0);
+
+ // 第三步:获取预约人头(去重会员ID)
+ var yySql = $@"
+ SELECT COUNT(DISTINCT tk.F_MemberId) as yy_count
+ FROM lq_tkjlb tk
+ INNER JOIN lq_yyjl yyjl ON tk.F_MemberId = yyjl.gk
+ AND yyjl.F_Status = '已确认'
+ WHERE 1=1 {timeFilter} {eventFilter}";
+
+ var yyResult = await _db.Ado.SqlQueryAsync(yySql);
+ var yyCount = Convert.ToInt32(yyResult?.FirstOrDefault()?.yy_count ?? 0);
+
+ // 第四步:获取到店人头(预约且状态为已确认,假设预约表有到店时间字段)
+ var ddSql = $@"
+ SELECT COUNT(DISTINCT tk.F_MemberId) as dd_count
+ FROM lq_tkjlb tk
+ INNER JOIN lq_yyjl yyjl ON tk.F_MemberId = yyjl.gk
+ AND yyjl.F_Status = '已确认'
+ WHERE yyjl.yysj <= NOW()
+ AND 1=1 {timeFilter} {eventFilter}";
+
+ var ddResult = await _db.Ado.SqlQueryAsync(ddSql);
+ var ddCount = Convert.ToInt32(ddResult?.FirstOrDefault()?.dd_count ?? 0);
+
+ // 第五步:获取开单人头和金额(去重会员ID,金额累加)
+ var kdSql = $@"
+ SELECT
+ COUNT(DISTINCT tk.F_MemberId) as kd_count,
+ COALESCE(SUM(kd.sfyj), 0) as kd_amount
+ FROM lq_tkjlb tk
+ INNER JOIN lq_kd_kdjlb kd ON tk.F_MemberId = kd.kdhy
+ AND kd.F_IsEffective = 1
+ WHERE 1=1 {timeFilter} {eventFilter}";
+
+ var kdResult = await _db.Ado.SqlQueryAsync(kdSql);
+ var kdCount = Convert.ToInt32(kdResult?.FirstOrDefault()?.kd_count ?? 0);
+ var kdAmount = Convert.ToDecimal(kdResult?.FirstOrDefault()?.kd_amount ?? 0);
+
+ // 第六步:获取消费人头和金额(去重会员ID,金额累加)
+ var xfSql = $@"
+ SELECT
+ COUNT(DISTINCT tk.F_MemberId) as xf_count,
+ COALESCE(SUM(xh.xfje), 0) as xf_amount
+ FROM lq_tkjlb tk
+ INNER JOIN lq_xh_hyhk xh ON tk.F_MemberId = xh.hy
+ AND xh.F_IsEffective = 1
+ WHERE 1=1 {timeFilter} {eventFilter}";
+
+ var xfResult = await _db.Ado.SqlQueryAsync(xfSql);
+ var xfCount = Convert.ToInt32(xfResult?.FirstOrDefault()?.xf_count ?? 0);
+ var xfAmount = Convert.ToDecimal(xfResult?.FirstOrDefault()?.xf_amount ?? 0);
+
+ return new TkStatisticsOutput
+ {
+ TkCount = tkCount,
+ YaoyCount = yaoyCount,
+ YyCount = yyCount,
+ DdCount = ddCount,
+ KdCount = kdCount,
+ KdAmount = kdAmount,
+ XfCount = xfCount,
+ XfAmount = xfAmount
+ };
+ }
+ catch (Exception ex)
+ {
+ throw NCCException.Oh($"获取拓客统计数据失败: {ex.Message}");
+ }
+ }
+ #endregion
+
}
}