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 + } }