diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/BusinessUnitPerformanceCompletionInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/BusinessUnitPerformanceCompletionInput.cs
new file mode 100644
index 0000000..341cca3
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/BusinessUnitPerformanceCompletionInput.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 事业部业绩完成情况输入参数
+ ///
+ public class BusinessUnitPerformanceCompletionInput
+ {
+ ///
+ /// 开始时间(可选,不传则默认为当月1号)
+ ///
+ public DateTime? StartTime { get; set; }
+
+ ///
+ /// 结束时间(可选,不传则默认为今天)
+ ///
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 事业部ID列表(可选,为空则查询所有事业部)
+ ///
+ public List BusinessUnitIds { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/BusinessUnitPerformanceCompletionOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/BusinessUnitPerformanceCompletionOutput.cs
new file mode 100644
index 0000000..1209cba
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/BusinessUnitPerformanceCompletionOutput.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 事业部业绩完成情况输出结果
+ ///
+ public class BusinessUnitPerformanceCompletionOutput
+ {
+ ///
+ /// 事业部ID
+ ///
+ public string BusinessUnitId { get; set; }
+
+ ///
+ /// 事业部名称
+ ///
+ public string BusinessUnitName { get; set; }
+
+ ///
+ /// 目标业绩(管理门店的生命线总和)
+ ///
+ public decimal TargetPerformance { get; set; }
+
+ ///
+ /// 完成业绩(管理门店的开单业绩总和)
+ ///
+ public decimal CompletedPerformance { get; set; }
+
+ ///
+ /// 完成率(百分比)
+ ///
+ public decimal CompletionRate { get; set; }
+
+ ///
+ /// 门店数量
+ ///
+ public int StoreCount { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/ManagerPerformanceCompletionInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/ManagerPerformanceCompletionInput.cs
new file mode 100644
index 0000000..e8f12d2
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/ManagerPerformanceCompletionInput.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 经理业绩完成情况输入参数
+ ///
+ public class ManagerPerformanceCompletionInput
+ {
+ ///
+ /// 开始时间(可选,不传则默认为当月1号)
+ ///
+ public DateTime? StartTime { get; set; }
+
+ ///
+ /// 结束时间(可选,不传则默认为今天)
+ ///
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 经理用户ID(可选)
+ ///
+ public string ManagerId { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/ManagerPerformanceCompletionOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/ManagerPerformanceCompletionOutput.cs
new file mode 100644
index 0000000..3f01cc4
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/ManagerPerformanceCompletionOutput.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 经理业绩完成情况输出结果
+ ///
+ public class ManagerPerformanceCompletionOutput
+ {
+ ///
+ /// 经理用户ID
+ ///
+ public string ManagerId { get; set; }
+
+ ///
+ /// 经理姓名
+ ///
+ public string ManagerName { get; set; }
+
+ ///
+ /// 门店ID
+ ///
+ public string StoreId { get; set; }
+
+ ///
+ /// 门店名称
+ ///
+ public string StoreName { get; set; }
+
+ ///
+ /// 目标业绩一阶段(smx1)
+ ///
+ public decimal Target1 { get; set; }
+
+ ///
+ /// 目标业绩二阶段(smx2)
+ ///
+ public decimal? Target2 { get; set; }
+
+ ///
+ /// 目标业绩三阶段(smx3)
+ ///
+ public decimal? Target3 { get; set; }
+
+ ///
+ /// 完成业绩
+ ///
+ public decimal CompletedPerformance { get; set; }
+
+ ///
+ /// 完成率一阶段(%)
+ ///
+ public decimal CompletionRate1 { get; set; }
+
+ ///
+ /// 完成率二阶段(%)
+ ///
+ public decimal? CompletionRate2 { get; set; }
+
+ ///
+ /// 完成率三阶段(%)
+ ///
+ public decimal? CompletionRate3 { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/ManagerSummaryPerformanceCompletionOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/ManagerSummaryPerformanceCompletionOutput.cs
new file mode 100644
index 0000000..20b8242
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/ManagerSummaryPerformanceCompletionOutput.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 经理汇总业绩完成情况输出结果
+ ///
+ public class ManagerSummaryPerformanceCompletionOutput
+ {
+ ///
+ /// 经理用户ID
+ ///
+ public string ManagerId { get; set; }
+
+ ///
+ /// 经理姓名
+ ///
+ public string ManagerName { get; set; }
+
+ ///
+ /// 总目标业绩一阶段
+ ///
+ public decimal TotalTarget1 { get; set; }
+
+ ///
+ /// 总目标业绩二阶段
+ ///
+ public decimal TotalTarget2 { get; set; }
+
+ ///
+ /// 总目标业绩三阶段
+ ///
+ public decimal TotalTarget3 { get; set; }
+
+ ///
+ /// 总完成业绩
+ ///
+ public decimal TotalCompletedPerformance { get; set; }
+
+ ///
+ /// 总完成率一阶段(%)
+ ///
+ public decimal TotalCompletionRate1 { get; set; }
+
+ ///
+ /// 总完成率二阶段(%)
+ ///
+ public decimal TotalCompletionRate2 { get; set; }
+
+ ///
+ /// 总完成率三阶段(%)
+ ///
+ public decimal TotalCompletionRate3 { get; set; }
+
+ ///
+ /// 管理门店数量
+ ///
+ public int StoreCount { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StoreDailyStatisticsInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StoreDailyStatisticsInput.cs
new file mode 100644
index 0000000..d25c47d
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StoreDailyStatisticsInput.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 门店每日统计输入参数
+ ///
+ public class StoreDailyStatisticsInput
+ {
+ ///
+ /// 开始时间(可选,不传则默认为当月1号)
+ ///
+ public DateTime? StartTime { get; set; }
+
+ ///
+ /// 结束时间(可选,不传则默认为今天)
+ ///
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 门店ID列表(可选,为空则查询所有门店)
+ ///
+ public List StoreIds { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StoreDailyStatisticsOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StoreDailyStatisticsOutput.cs
new file mode 100644
index 0000000..c1830e9
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StoreDailyStatisticsOutput.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 门店每日统计输出结果
+ ///
+ public class StoreDailyStatisticsOutput
+ {
+ ///
+ /// 门店ID
+ ///
+ public string StoreId { get; set; }
+
+ ///
+ /// 门店名称
+ ///
+ public string StoreName { get; set; }
+
+ ///
+ /// 在职员工数
+ ///
+ public int EmployeeCount { get; set; }
+
+ ///
+ /// 人头数(去重后的消费会员数)
+ ///
+ public int HeadCount { get; set; }
+
+ ///
+ /// 人次(日度去重客户数)
+ ///
+ public int PersonCount { get; set; }
+
+ ///
+ /// 项目数(消耗的项目总数)
+ ///
+ public int ProjectCount { get; set; }
+
+ ///
+ /// 消耗业绩(总金额)
+ ///
+ public decimal ConsumePerformance { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StorePerformanceCompletionInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StorePerformanceCompletionInput.cs
new file mode 100644
index 0000000..2d833a2
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StorePerformanceCompletionInput.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 门店业绩完成情况输入参数
+ ///
+ public class StorePerformanceCompletionInput
+ {
+ ///
+ /// 开始时间(可选,不传则默认为当月1号)
+ ///
+ public DateTime? StartTime { get; set; }
+
+ ///
+ /// 结束时间(可选,不传则默认为今天)
+ ///
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 门店ID列表(可选,为空则查询所有门店)
+ ///
+ public List StoreIds { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StorePerformanceCompletionOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StorePerformanceCompletionOutput.cs
new file mode 100644
index 0000000..29b0936
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/StorePerformanceCompletionOutput.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 门店业绩完成情况输出结果
+ ///
+ public class StorePerformanceCompletionOutput
+ {
+ ///
+ /// 门店ID
+ ///
+ public string StoreId { get; set; }
+
+ ///
+ /// 门店名称
+ ///
+ public string StoreName { get; set; }
+
+ ///
+ /// 目标业绩(生命线)
+ ///
+ public decimal TargetPerformance { get; set; }
+
+ ///
+ /// 完成业绩(开单业绩)
+ ///
+ public decimal CompletedPerformance { get; set; }
+
+ ///
+ /// 完成率(百分比)
+ ///
+ public decimal CompletionRate { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TechTeacherDailyStatisticsInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TechTeacherDailyStatisticsInput.cs
new file mode 100644
index 0000000..60c77b2
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TechTeacherDailyStatisticsInput.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 科技部老师统计输入参数
+ ///
+ public class TechTeacherDailyStatisticsInput
+ {
+ ///
+ /// 开始时间(可选,不传则默认为当月1号)
+ ///
+ public DateTime? StartTime { get; set; }
+
+ ///
+ /// 结束时间(可选,不传则默认为今天)
+ ///
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 科技部ID(可选,不传则查询所有科技部)
+ ///
+ public string TechDepartmentId { get; set; }
+
+ ///
+ /// 老师ID列表(可选)
+ ///
+ public List TeacherIds { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TechTeacherDailyStatisticsOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TechTeacherDailyStatisticsOutput.cs
new file mode 100644
index 0000000..ac3290a
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TechTeacherDailyStatisticsOutput.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 科技部老师统计输出结果
+ ///
+ public class TechTeacherDailyStatisticsOutput
+ {
+ ///
+ /// 科技部ID
+ ///
+ public string TechDepartmentId { get; set; }
+
+ ///
+ /// 科技部名称
+ ///
+ public string TechDepartmentName { get; set; }
+
+ ///
+ /// 老师ID
+ ///
+ public string TeacherId { get; set; }
+
+ ///
+ /// 老师姓名
+ ///
+ public string TeacherName { get; set; }
+
+ ///
+ /// 见客数(不同客户数量)
+ ///
+ public int CustomerCount { get; set; }
+
+ ///
+ /// 消耗项目数
+ ///
+ public int ConsumeProjectCount { get; set; }
+
+ ///
+ /// 消耗业绩
+ ///
+ public decimal ConsumeAchievement { get; set; }
+
+ ///
+ /// 开单业绩
+ ///
+ public decimal OrderAchievement { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TianwangGroupPerformanceCompletionInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TianwangGroupPerformanceCompletionInput.cs
new file mode 100644
index 0000000..567f81b
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TianwangGroupPerformanceCompletionInput.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 天王团业绩完成情况输入参数
+ ///
+ public class TianwangGroupPerformanceCompletionInput
+ {
+ ///
+ /// 开始时间(可选,不传则默认为当月1号)
+ ///
+ public DateTime? StartTime { get; set; }
+
+ ///
+ /// 结束时间(可选,不传则默认为今天)
+ ///
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 天王团部门ID列表(可选,为空则查询所有天王团)
+ ///
+ public List DepartmentIds { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TianwangGroupPerformanceCompletionOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TianwangGroupPerformanceCompletionOutput.cs
new file mode 100644
index 0000000..b033c17
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqDailyReport/TianwangGroupPerformanceCompletionOutput.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqDailyReport
+{
+ ///
+ /// 天王团业绩完成情况输出结果
+ ///
+ public class TianwangGroupPerformanceCompletionOutput
+ {
+ ///
+ /// 部门ID
+ ///
+ public string DepartmentId { get; set; }
+
+ ///
+ /// 部门名称
+ ///
+ public string DepartmentName { get; set; }
+
+ ///
+ /// 目标业绩(管理门店的生命线总和)
+ ///
+ public decimal TargetPerformance { get; set; }
+
+ ///
+ /// 完成业绩(管理门店的开单业绩总和)
+ ///
+ public decimal CompletedPerformance { get; set; }
+
+ ///
+ /// 完成率(百分比)
+ ///
+ public decimal CompletionRate { get; set; }
+
+ ///
+ /// 门店数量
+ ///
+ public int StoreCount { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/ActivityStatisticsInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/ActivityStatisticsInput.cs
index be246de..e958e3a 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/ActivityStatisticsInput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/ActivityStatisticsInput.cs
@@ -28,5 +28,15 @@ namespace NCC.Extend.Entitys.Dto.LqPackageInfo
/// 门店ID列表(可选)
///
public string[] StoreIds { get; set; }
+
+ ///
+ /// 页码(默认1)
+ ///
+ public int PageIndex { get; set; } = 1;
+
+ ///
+ /// 每页数量(默认20)
+ ///
+ public int PageSize { get; set; } = 20;
}
}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/ActivityStatisticsOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/ActivityStatisticsOutput.cs
index 2cc73dc..7f81c61 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/ActivityStatisticsOutput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqPackageInfo/ActivityStatisticsOutput.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace NCC.Extend.Entitys.Dto.LqPackageInfo
{
@@ -28,28 +29,59 @@ namespace NCC.Extend.Entitys.Dto.LqPackageInfo
public decimal BillingAmount { get; set; }
///
- /// 退卡数量
+ /// 欠款金额(所有开单的欠款总和)
///
- public int RefundCount { get; set; }
+ public decimal DebtAmount { get; set; }
///
- /// 退卡金额
+ /// 开单列表
///
- public decimal RefundAmount { get; set; }
+ public List BillingList { get; set; }
+ }
+
+ ///
+ /// 活动开单项
+ ///
+ public class ActivityBillingItem
+ {
+ ///
+ /// 开单ID
+ ///
+ public string BillingId { get; set; }
+
+ ///
+ /// 开单日期
+ ///
+ public DateTime? BillingDate { get; set; }
///
- /// 净开单数量(开单数量 - 退卡数量)
+ /// 客户名称
///
- public int NetBillingCount { get; set; }
+ public string CustomerName { get; set; }
///
- /// 净开单金额(开单金额 - 退卡金额)
+ /// 客户电话
+ ///
+ public string CustomerPhone { get; set; }
+
+ ///
+ /// 门店ID
+ ///
+ public string StoreId { get; set; }
+
+ ///
+ /// 门店名称
+ ///
+ public string StoreName { get; set; }
+
+ ///
+ /// 开单金额
///
- public decimal NetBillingAmount { get; set; }
+ public decimal Amount { get; set; }
///
- /// 退卡率(退卡数量 / 开单数量)
+ /// 欠款金额
///
- public decimal RefundRate { get; set; }
+ public decimal DebtAmount { get; set; }
}
}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReport/BusinessStatisticsOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReport/BusinessStatisticsOutput.cs
index 5f59484..5288ed5 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReport/BusinessStatisticsOutput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReport/BusinessStatisticsOutput.cs
@@ -34,5 +34,30 @@ namespace NCC.Extend.Entitys.Dto.LqReport
/// 退卡人数
///
public int RefundCount { get; set; }
+
+ ///
+ /// 消耗目标业绩(所有门店xhyj字段的总和)
+ ///
+ public decimal TargetConsumeAmount { get; set; }
+
+ ///
+ /// 消耗完成率(耗卡总金额 / 消耗目标业绩 * 100)
+ ///
+ public decimal ConsumeCompletionRate { get; set; }
+
+ ///
+ /// 开单目标业绩(所有门店xsyj字段的总和)
+ ///
+ public decimal TargetBillingAmount { get; set; }
+
+ ///
+ /// 开单完成业绩(开单总金额 - 退卡总金额)
+ ///
+ public decimal CompletedBillingAmount { get; set; }
+
+ ///
+ /// 开单完成率(完成业绩 / 开单目标业绩 * 100)
+ ///
+ public decimal BillingCompletionRate { get; set; }
}
}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/EmployeePerformanceStatisticsOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/EmployeePerformanceStatisticsOutput.cs
index f86697b..3ded29a 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/EmployeePerformanceStatisticsOutput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/EmployeePerformanceStatisticsOutput.cs
@@ -69,5 +69,15 @@ namespace NCC.Extend.Entitys.Dto.LqStatistics
/// 人次(日度去重客户数)
///
public int PersonCount { get; set; }
+
+ ///
+ /// 开单项目数(项目次数总和)
+ ///
+ public int BillingProjectCount { get; set; }
+
+ ///
+ /// 消耗项目数(项目次数总和)
+ ///
+ public int ConsumeProjectCount { get; set; }
}
}
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.Interfaces/LqDailyReport/ILqDailyReportService.cs b/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqDailyReport/ILqDailyReportService.cs
new file mode 100644
index 0000000..2ef49a6
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqDailyReport/ILqDailyReportService.cs
@@ -0,0 +1,62 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using NCC.Extend.Entitys.Dto.LqDailyReport;
+
+namespace NCC.Extend.Interfaces.LqDailyReport
+{
+ ///
+ /// 日报服务接口
+ ///
+ public interface ILqDailyReportService
+ {
+ ///
+ /// 获取门店每日运营统计数据
+ ///
+ /// 查询参数
+ /// 门店统计数据列表
+ Task> GetStoreDailyStatistics(StoreDailyStatisticsInput input);
+
+ ///
+ /// 获取门店业绩完成情况
+ ///
+ /// 查询参数
+ /// 门店业绩完成情况列表
+ Task> GetStorePerformanceCompletion(StorePerformanceCompletionInput input);
+
+ ///
+ /// 获取事业部业绩完成情况
+ ///
+ /// 查询参数
+ /// 事业部业绩完成情况列表
+ Task> GetBusinessUnitPerformanceCompletion(BusinessUnitPerformanceCompletionInput input);
+
+ ///
+ /// 获取天王团业绩完成情况
+ ///
+ /// 查询参数
+ /// 天王团业绩完成情况列表
+ Task> GetTianwangGroupPerformanceCompletion(TianwangGroupPerformanceCompletionInput input);
+
+ ///
+ /// 获取经理业绩完成情况
+ ///
+ /// 查询参数
+ /// 经理业绩完成情况列表
+ Task> GetManagerPerformanceCompletion(ManagerPerformanceCompletionInput input);
+
+ ///
+ /// 获取经理汇总业绩完成情况
+ ///
+ /// 查询参数
+ /// 经理汇总业绩完成情况列表
+ Task> GetManagerSummaryPerformanceCompletion(ManagerPerformanceCompletionInput input);
+
+ ///
+ /// 获取科技部老师日报统计
+ ///
+ /// 查询参数
+ /// 科技部老师统计列表
+ Task> GetTechTeacherDailyStatistics(TechTeacherDailyStatisticsInput input);
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqDailyReportService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqDailyReportService.cs
new file mode 100644
index 0000000..3f1b0a9
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend/LqDailyReportService.cs
@@ -0,0 +1,921 @@
+using NCC.Common.Core.Manager;
+using NCC.Common.Enum;
+using NCC.Common.Extension;
+using NCC.Common.Filter;
+using NCC.Dependency;
+using NCC.DynamicApiController;
+using NCC.FriendlyException;
+using NCC.Extend.Interfaces.LqDailyReport;
+using Mapster;
+using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Yitter.IdGenerator;
+using NCC.Common.Helper;
+using NCC.JsonSerialization;
+using NCC.Common.Model.NPOI;
+using NCC.Common.Configuration;
+using NCC.DataEncryption;
+using NCC.ClayObject;
+using NCC.Extend.Entitys.Dto.LqDailyReport;
+using NCC.Extend.Entitys.lq_kd_kdjlb;
+
+namespace NCC.Extend
+{
+ ///
+ /// 日报服务
+ ///
+ [ApiDescriptionSettings(Tag = "绿纤日报服务", Name = "LqDailyReport", Order = 200)]
+ [Route("api/Extend/[controller]")]
+ public class LqDailyReportService : ILqDailyReportService, IDynamicApiController, ITransient
+ {
+ private readonly ISqlSugarRepository _repository;
+ private readonly SqlSugarScope _db;
+ private readonly IUserManager _userManager;
+
+ ///
+ /// 初始化一个类型的新实例
+ ///
+ public LqDailyReportService(
+ ISqlSugarRepository repository,
+ IUserManager userManager)
+ {
+ _repository = repository;
+ _db = _repository.Context;
+ _userManager = userManager;
+ }
+
+ ///
+ /// 获取时间范围,如果未传入则默认为本月
+ ///
+ private (DateTime startDate, DateTime endDate) GetTimeRange(DateTime? startTime, DateTime? endTime)
+ {
+ var now = DateTime.Now;
+ var start = startTime ?? new DateTime(now.Year, now.Month, 1);
+ var end = endTime ?? now;
+
+ // 确保开始时间不晚于结束时间
+ if (start > end)
+ {
+ var temp = start;
+ start = end;
+ end = temp;
+ }
+
+ return (start, end);
+ }
+
+ #region 获取门店每日运营统计数据
+ ///
+ /// 获取门店每日运营统计数据
+ ///
+ ///
+ /// 根据指定时间范围统计各门店的运营数据,包括在职员工数、人头数、人次、项目数、消耗业绩等信息
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "startTime": "2025-10-01",
+ /// "endTime": "2025-10-27",
+ /// "storeIds": ["门店ID1", "门店ID2"]
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - startTime: 开始时间,可选,不传则默认为当月1号
+ /// - endTime: 结束时间,可选,不传则默认为今天
+ /// - storeIds: 门店ID列表,可选,不传则查询所有门店
+ ///
+ /// 返回说明:
+ /// - StoreId: 门店ID
+ /// - StoreName: 门店名称
+ /// - EmployeeCount: 在职员工数(F_EnabledMark=1且有岗位)
+ /// - HeadCount: 人头数(去重后的消费会员数)
+ /// - PersonCount: 人次(日度去重客户数,同一天同一客户只算一次)
+ /// - ProjectCount: 项目数(消耗的项目总数)
+ /// - ConsumePerformance: 消耗业绩(总金额)
+ ///
+ /// 查询参数
+ /// 门店统计数据列表
+ /// 成功返回门店统计列表
+ /// 日期格式错误或参数无效
+ /// 服务器内部错误
+ [HttpPost("get-store-daily-statistics")]
+ public async Task> GetStoreDailyStatistics(StoreDailyStatisticsInput input)
+ {
+ // 获取时间范围
+ var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
+
+ // 构建门店过滤条件
+ var storeFilter = "";
+ if (input.StoreIds != null && input.StoreIds.Any())
+ {
+ var storeIdsStr = string.Join("','", input.StoreIds);
+ storeFilter = $"AND consume.Md IN ('{storeIdsStr}')";
+ }
+
+ // SQL查询:获取门店每日运营数据
+ var sql = $@"
+ SELECT
+ consume.Md as StoreId,
+ MAX(store.dm) as StoreName,
+ -- 在职员工数
+ COALESCE((
+ SELECT COUNT(DISTINCT u.F_Id)
+ FROM BASE_USER u
+ WHERE u.F_MDID = consume.Md
+ AND u.F_EnabledMark = 1
+ AND (u.F_DeleteMark IS NULL OR u.F_DeleteMark = 0)
+ AND u.F_GW IS NOT NULL
+ ), 0) as EmployeeCount,
+ -- 人头数(去重后的消费会员数)
+ COALESCE(COUNT(DISTINCT consume.Hy), 0) as HeadCount,
+ -- 人次(日度去重客户数)
+ COALESCE(COUNT(DISTINCT CONCAT(consume.Hy, '-', DATE(consume.Hksj))), 0) as PersonCount,
+ -- 项目数(消耗的项目总数)
+ COALESCE(SUM(project.F_ProjectNumber), 0) as ProjectCount,
+ -- 消耗业绩(总金额)
+ COALESCE(SUM(project.F_TotalPrice), 0) as ConsumePerformance
+ FROM lq_xh_hyhk consume
+ LEFT JOIN lq_mdxx store ON consume.Md = store.F_Id
+ LEFT JOIN lq_xh_pxmx project ON consume.F_Id = project.F_ConsumeInfoId AND project.F_IsEffective = 1
+ WHERE consume.F_IsEffective = 1
+ AND DATE(consume.Hksj) >= '{startDate:yyyy-MM-dd}'
+ AND DATE(consume.Hksj) <= '{endDate:yyyy-MM-dd}'
+ {storeFilter}
+ GROUP BY consume.Md
+ ORDER BY ConsumePerformance DESC";
+
+ var result = await _db.Ado.SqlQueryAsync(sql);
+
+ var outputList = result.Select(item => new StoreDailyStatisticsOutput
+ {
+ StoreId = item.StoreId,
+ StoreName = item.StoreName,
+ EmployeeCount = Convert.ToInt32(item.EmployeeCount),
+ HeadCount = Convert.ToInt32(item.HeadCount),
+ PersonCount = Convert.ToInt32(item.PersonCount),
+ ProjectCount = Convert.ToInt32(item.ProjectCount),
+ ConsumePerformance = Convert.ToDecimal(item.ConsumePerformance)
+ }).ToList();
+ return outputList;
+ }
+ #endregion
+
+ #region 获取门店业绩完成情况
+ ///
+ /// 获取门店业绩完成情况
+ ///
+ ///
+ /// 根据指定日期统计各门店的业绩完成情况,包括目标业绩、完成业绩、完成率
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "startTime": "2025-10-01",
+ /// "endTime": "2025-10-22",
+ /// "storeIds": ["门店ID1", "门店ID2"]
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - startTime: 开始时间,可选,不传则默认为当月1号
+ /// - endTime: 结束时间,可选,不传则默认为今天
+ /// - storeIds: 门店ID列表,可选,不传则查询所有门店
+ ///
+ /// 返回说明:
+ /// - StoreId: 门店ID
+ /// - StoreName: 门店名称
+ /// - TargetPerformance: 目标业绩(生命线,来自门店信息表)
+ /// - CompletedPerformance: 完成业绩(当月1号至统计日期的开单业绩总和)
+ /// - CompletionRate: 完成率(百分比,CompletedPerformance / TargetPerformance * 100)
+ ///
+ /// 查询参数
+ /// 门店业绩完成情况列表
+ /// 成功返回门店业绩完成情况列表
+ /// 日期格式错误或参数无效
+ /// 服务器内部错误
+ [HttpPost("get-store-performance-completion")]
+ public async Task> GetStorePerformanceCompletion(StorePerformanceCompletionInput input)
+ {
+ // 获取时间范围
+ var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
+
+ // 构建门店过滤条件
+ var storeFilter = "";
+ if (input.StoreIds != null && input.StoreIds.Any())
+ {
+ var storeIdsStr = string.Join("','", input.StoreIds);
+ storeFilter = $"AND store.F_Id IN ('{storeIdsStr}')";
+ }
+
+ // SQL查询:获取门店业绩完成情况
+ var sql = $@"
+ SELECT
+ store.F_Id as StoreId,
+ store.dm as StoreName,
+ -- 目标业绩(生命线)
+ COALESCE(store.xsyj, 0) as TargetPerformance,
+ -- 完成业绩(开单业绩总和)
+ COALESCE((
+ SELECT SUM(billing.sfyj)
+ FROM lq_kd_kdjlb billing
+ WHERE billing.djmd = store.F_Id
+ AND billing.F_IsEffective = 1
+ AND DATE(billing.kdrq) >= '{startDate:yyyy-MM-dd}'
+ AND DATE(billing.kdrq) <= '{endDate:yyyy-MM-dd}'
+ ), 0) as CompletedPerformance
+ FROM lq_mdxx store
+ WHERE 1=1 {storeFilter}
+ ORDER BY CompletedPerformance DESC";
+
+ var result = await _db.Ado.SqlQueryAsync(sql);
+
+ var outputList = result.Select(item =>
+ {
+ var targetPerformance = Convert.ToDecimal(item.TargetPerformance);
+ var completedPerformance = Convert.ToDecimal(item.CompletedPerformance);
+ var completionRate = targetPerformance > 0 ? (completedPerformance / targetPerformance * 100m) : 0m;
+
+ return new StorePerformanceCompletionOutput
+ {
+ StoreId = item.StoreId,
+ StoreName = item.StoreName,
+ TargetPerformance = targetPerformance,
+ CompletedPerformance = completedPerformance,
+ CompletionRate = decimal.Round(completionRate, 2)
+ };
+ }).ToList();
+
+ return outputList;
+ }
+ #endregion
+
+ #region 获取事业部业绩完成情况
+ ///
+ /// 获取事业部业绩完成情况
+ ///
+ ///
+ /// 根据指定日期统计各事业部的业绩完成情况,包括目标业绩、完成业绩、完成率
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "startTime": "2025-10-01",
+ /// "endTime": "2025-10-22",
+ /// "businessUnitIds": ["事业部ID1", "事业部ID2"]
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - startTime: 开始时间,可选,不传则默认为当月1号
+ /// - endTime: 结束时间,可选,不传则默认为今天
+ /// - businessUnitIds: 事业部ID列表,可选,不传则查询所有事业部
+ ///
+ /// 返回说明:
+ /// - BusinessUnitId: 事业部ID
+ /// - BusinessUnitName: 事业部名称
+ /// - TargetPerformance: 目标业绩(管理门店的生命线总和)
+ /// - CompletedPerformance: 完成业绩(指定时间范围内的开单业绩总和)
+ /// - CompletionRate: 完成率(百分比,CompletedPerformance / TargetPerformance * 100)
+ /// - StoreCount: 门店数量
+ ///
+ /// 查询参数
+ /// 事业部业绩完成情况列表
+ /// 成功返回事业部业绩完成情况列表
+ /// 日期格式错误或参数无效
+ /// 服务器内部错误
+ [HttpPost("get-business-unit-performance-completion")]
+ public async Task> GetBusinessUnitPerformanceCompletion(BusinessUnitPerformanceCompletionInput input)
+ {
+ // 获取时间范围
+ var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
+
+ // 构建事业部过滤条件
+ var businessUnitFilter = "";
+ if (input.BusinessUnitIds != null && input.BusinessUnitIds.Any())
+ {
+ var filterUnitIdsStr = string.Join("','", input.BusinessUnitIds);
+ businessUnitFilter = $"AND o.F_Id IN ('{filterUnitIdsStr}')";
+ }
+
+ // 分步查询,提高效率
+ // 第一步:获取事业部列表及目标业绩(只统计事业一部到事业六部)
+ var businessUnitSql = $@"
+ SELECT
+ o.F_Id as BusinessUnitId,
+ o.F_FullName as BusinessUnitName,
+ COALESCE(SUM(store.xsyj), 0) as TargetPerformance,
+ COUNT(DISTINCT store.F_Id) as StoreCount
+ FROM base_organize o
+ LEFT JOIN lq_mdxx store ON store.syb = o.F_Id
+ WHERE o.F_Category = 'department'
+ AND (o.F_DeleteMark IS NULL OR o.F_DeleteMark != 1)
+ AND o.F_FullName IN ('事业一部', '事业二部', '事业三部', '事业四部', '事业五部', '事业六部')
+ {businessUnitFilter}
+ GROUP BY o.F_Id, o.F_FullName";
+
+ var businessUnits = await _db.Ado.SqlQueryAsync(businessUnitSql);
+
+ if (businessUnits == null || !businessUnits.Any())
+ {
+ return new List();
+ }
+
+ var businessUnitDict = new Dictionary();
+
+ foreach (var unit in businessUnits)
+ {
+ businessUnitDict[unit.BusinessUnitId.ToString()] = new BusinessUnitPerformanceCompletionOutput
+ {
+ BusinessUnitId = unit.BusinessUnitId.ToString(),
+ BusinessUnitName = unit.BusinessUnitName.ToString(),
+ TargetPerformance = Convert.ToDecimal(unit.TargetPerformance),
+ CompletedPerformance = 0,
+ CompletionRate = 0,
+ StoreCount = Convert.ToInt32(unit.StoreCount)
+ };
+ }
+
+ // 第二步:统计各事业部的完成业绩
+ var businessUnitIds = businessUnitDict.Keys.ToList();
+ var unitIdsStr = string.Join("','", businessUnitIds);
+
+ var completedPerformanceSql = $@"
+ SELECT
+ store.syb as BusinessUnitId,
+ COALESCE(SUM(billing.sfyj), 0) as CompletedPerformance
+ FROM lq_kd_kdjlb billing
+ INNER JOIN lq_mdxx store ON billing.djmd = store.F_Id
+ INNER JOIN base_organize o ON store.syb = o.F_Id
+ WHERE billing.F_IsEffective = 1
+ AND o.F_Category = 'department'
+ AND (o.F_DeleteMark IS NULL OR o.F_DeleteMark != 1)
+ AND o.F_FullName IN ('事业一部', '事业二部', '事业三部', '事业四部', '事业五部', '事业六部')
+ AND DATE(billing.kdrq) >= '{startDate:yyyy-MM-dd}'
+ AND DATE(billing.kdrq) <= '{endDate:yyyy-MM-dd}'
+ AND store.syb IN ('{unitIdsStr}')
+ GROUP BY store.syb";
+
+ var completedPerformanceData = await _db.Ado.SqlQueryAsync(completedPerformanceSql);
+
+ // 第三步:合并数据并计算完成率
+ foreach (var item in completedPerformanceData)
+ {
+ var businessUnitId = item.BusinessUnitId.ToString();
+ if (businessUnitDict.ContainsKey(businessUnitId))
+ {
+ var completedPerformance = Convert.ToDecimal(item.CompletedPerformance);
+ var unit = businessUnitDict[businessUnitId];
+ unit.CompletedPerformance = completedPerformance;
+
+ var completionRate = unit.TargetPerformance > 0
+ ? (completedPerformance / unit.TargetPerformance * 100m)
+ : 0m;
+ unit.CompletionRate = decimal.Round(completionRate, 2);
+ }
+ }
+
+ var outputList = businessUnitDict.Values
+ .OrderByDescending(x => x.CompletedPerformance)
+ .ToList();
+
+ return outputList;
+ }
+ #endregion
+
+ #region 获取天王团业绩完成情况
+ ///
+ /// 获取天王团业绩完成情况
+ ///
+ ///
+ /// 根据指定日期统计各天王团的业绩完成情况,包括目标业绩、完成业绩、完成率
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "startTime": "2025-10-01",
+ /// "endTime": "2025-10-22",
+ /// "departmentIds": ["部门ID1", "部门ID2"]
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - startTime: 开始时间,可选,不传则默认为当月1号
+ /// - endTime: 结束时间,可选,不传则默认为今天
+ /// - departmentIds: 天王团部门ID列表,可选,不传则查询所有天王团
+ ///
+ /// 返回说明:
+ /// - DepartmentId: 部门ID
+ /// - DepartmentName: 部门名称(教育一部、教育二部、科技一部、科技二部、大项目一部、大项目二部)
+ /// - TargetPerformance: 目标业绩(管理门店的生命线总和)
+ /// - CompletedPerformance: 完成业绩(指定时间范围内的开单业绩总和)
+ /// - CompletionRate: 完成率(百分比,CompletedPerformance / TargetPerformance * 100)
+ /// - StoreCount: 门店数量
+ ///
+ /// 查询参数
+ /// 天王团业绩完成情况列表
+ /// 成功返回天王团业绩完成情况列表
+ /// 日期格式错误或参数无效
+ /// 服务器内部错误
+ [HttpPost("get-tianwang-group-performance-completion")]
+ public async Task> GetTianwangGroupPerformanceCompletion(TianwangGroupPerformanceCompletionInput input)
+ {
+ // 获取时间范围
+ var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
+
+ // 构建部门过滤条件
+ var departmentFilter = "";
+ if (input.DepartmentIds != null && input.DepartmentIds.Any())
+ {
+ var filterDeptIdsStr = string.Join("','", input.DepartmentIds);
+ departmentFilter = $"AND o.F_Id IN ('{filterDeptIdsStr}')";
+ }
+
+ // 天王团部门信息(字段名和部门名称的映射)
+ var tianwangDepartments = new Dictionary
+ {
+ { "jyb", ("jyb", new[] { "教育一部", "教育二部" }) },
+ { "kjb", ("kjb", new[] { "科技一部", "科技二部" }) },
+ { "dxmb", ("dxmb", new[] { "大项目一部", "大项目二部" }) }
+ };
+
+ // 分步查询,提高效率
+ var departmentDict = new Dictionary();
+ var allDeptNames = new List();
+
+ // 循环查询每个天王团类型
+ foreach (var deptType in tianwangDepartments)
+ {
+ var deptNamesStr = string.Join("','", deptType.Value.departmentNames);
+ allDeptNames.AddRange(deptType.Value.departmentNames);
+
+ // 第一步:获取天王团列表及目标业绩
+ var departmentSql = $@"
+ SELECT
+ o.F_Id as DepartmentId,
+ o.F_FullName as DepartmentName,
+ COALESCE(SUM(store.xsyj), 0) as TargetPerformance,
+ COUNT(DISTINCT store.F_Id) as StoreCount
+ FROM base_organize o
+ LEFT JOIN lq_mdxx store ON store.{deptType.Key} = o.F_Id
+ WHERE o.F_Category = 'department'
+ AND (o.F_DeleteMark IS NULL OR o.F_DeleteMark != 1)
+ AND o.F_FullName IN ('{deptNamesStr}')
+ {departmentFilter}
+ GROUP BY o.F_Id, o.F_FullName";
+
+ var departments = await _db.Ado.SqlQueryAsync(departmentSql);
+
+ foreach (var dept in departments ?? Enumerable.Empty())
+ {
+ if (!departmentDict.ContainsKey(dept.DepartmentId.ToString()))
+ {
+ departmentDict[dept.DepartmentId.ToString()] = new TianwangGroupPerformanceCompletionOutput
+ {
+ DepartmentId = dept.DepartmentId.ToString(),
+ DepartmentName = dept.DepartmentName.ToString(),
+ TargetPerformance = Convert.ToDecimal(dept.TargetPerformance),
+ CompletedPerformance = 0,
+ CompletionRate = 0,
+ StoreCount = Convert.ToInt32(dept.StoreCount)
+ };
+ }
+ }
+ }
+
+ if (!departmentDict.Any())
+ {
+ return new List();
+ }
+
+ // 第二步:统计各天王团的完成业绩(分类型统计)
+ var completedPerformanceDataList = new List();
+
+ foreach (var deptType in tianwangDepartments)
+ {
+ var deptIdsStrForQuery = string.Join("','", departmentDict.Keys);
+
+ var completedPerformanceSql = $@"
+ SELECT
+ o.F_Id as DepartmentId,
+ COALESCE(SUM(billing.sfyj), 0) as CompletedPerformance
+ FROM lq_kd_kdjlb billing
+ INNER JOIN lq_mdxx store ON billing.djmd = store.F_Id
+ INNER JOIN base_organize o ON store.{deptType.Key} = o.F_Id
+ WHERE billing.F_IsEffective = 1
+ AND o.F_Category = 'department'
+ AND (o.F_DeleteMark IS NULL OR o.F_DeleteMark != 1)
+ AND DATE(billing.kdrq) >= '{startDate:yyyy-MM-dd}'
+ AND DATE(billing.kdrq) <= '{endDate:yyyy-MM-dd}'
+ AND o.F_Id IN ('{deptIdsStrForQuery}')
+ GROUP BY o.F_Id";
+
+ var completedPerformanceData = await _db.Ado.SqlQueryAsync(completedPerformanceSql);
+ if (completedPerformanceData != null)
+ {
+ completedPerformanceDataList.AddRange(completedPerformanceData);
+ }
+ }
+
+ // 第三步:合并数据并计算完成率(按部门ID去重累加)
+ var departmentPerformanceDict = new Dictionary();
+ foreach (var item in completedPerformanceDataList)
+ {
+ var departmentId = item.DepartmentId.ToString();
+ var completedPerformance = Convert.ToDecimal(item.CompletedPerformance);
+
+ if (departmentPerformanceDict.ContainsKey(departmentId))
+ {
+ departmentPerformanceDict[departmentId] += completedPerformance;
+ }
+ else
+ {
+ departmentPerformanceDict[departmentId] = completedPerformance;
+ }
+ }
+
+ // 计算完成率
+ foreach (var kvp in departmentPerformanceDict)
+ {
+ if (departmentDict.ContainsKey(kvp.Key))
+ {
+ var dept = departmentDict[kvp.Key];
+ dept.CompletedPerformance = kvp.Value;
+
+ var completionRate = dept.TargetPerformance > 0
+ ? (kvp.Value / dept.TargetPerformance * 100m)
+ : 0m;
+ dept.CompletionRate = decimal.Round(completionRate, 2);
+ }
+ }
+
+ var outputList = departmentDict.Values
+ .OrderByDescending(x => x.CompletedPerformance)
+ .ToList();
+
+ return outputList;
+ }
+ #endregion
+
+ #region 获取经理业绩完成情况
+ ///
+ /// 获取经理业绩完成情况
+ ///
+ ///
+ /// 根据指定日期统计各经理在各门店的业绩完成情况,包括目标业绩(三个阶段)、完成业绩、完成率
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "startTime": "2025-10-01",
+ /// "endTime": "2025-10-22",
+ /// "managerId": "经理ID"
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - startTime: 开始时间,可选,不传则默认为当月1号
+ /// - endTime: 结束时间,可选,不传则默认为今天
+ /// - managerId: 经理用户ID,可选,不传则查询所有经理
+ ///
+ /// 返回说明:
+ /// - ManagerId: 经理用户ID
+ /// - ManagerName: 经理姓名
+ /// - StoreId/StoreName: 门店信息
+ /// - Target1/2/3: 目标业绩一/二/三阶段(smx1/smx2/smx3)
+ /// - CompletedPerformance: 完成业绩(指定时间范围内的开单业绩总和)
+ /// - CompletionRate1/2/3: 完成率各阶段(百分比)
+ ///
+ /// 查询参数
+ /// 经理业绩完成情况列表
+ /// 成功返回经理业绩完成情况列表
+ /// 日期格式错误或参数无效
+ /// 服务器内部错误
+ [HttpPost("get-manager-performance-completion")]
+ public async Task> GetManagerPerformanceCompletion(ManagerPerformanceCompletionInput input)
+ {
+ // 获取时间范围
+ var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
+
+ // 构建经理过滤条件
+ var managerFilter = "";
+ if (!string.IsNullOrWhiteSpace(input.ManagerId))
+ {
+ managerFilter = $"AND target.zjl_userid = '{input.ManagerId}'";
+ }
+
+ // SQL查询:获取经理在各门店的目标业绩和完成业绩
+ var sql = $@"
+ SELECT
+ target.zjl_userid as ManagerId,
+ u.F_RealName as ManagerName,
+ target.md_id as StoreId,
+ store.dm as StoreName,
+ target.smx1 as Target1,
+ target.smx2 as Target2,
+ target.smx3 as Target3,
+ -- 完成业绩
+ COALESCE((
+ SELECT SUM(billing.sfyj)
+ FROM lq_kd_kdjlb billing
+ WHERE billing.djmd = target.md_id
+ AND billing.F_IsEffective = 1
+ AND DATE(billing.kdrq) >= '{startDate:yyyy-MM-dd}'
+ AND DATE(billing.kdrq) <= '{endDate:yyyy-MM-dd}'
+ ), 0) as CompletedPerformance
+ FROM lq_zjl_mdsmxsz target
+ INNER JOIN BASE_USER u ON target.zjl_userid = u.F_Id
+ INNER JOIN lq_mdxx store ON target.md_id = store.F_Id
+ WHERE target.deletemark = 0
+ {managerFilter}
+ ORDER BY target.zjl_userid, store.dm";
+
+ var result = await _db.Ado.SqlQueryAsync(sql);
+
+ var outputList = result.Select(item =>
+ {
+ var target1 = Convert.ToDecimal(item.Target1);
+ var target2 = item.Target2 != null ? Convert.ToDecimal(item.Target2) : 0;
+ var target3 = item.Target3 != null ? Convert.ToDecimal(item.Target3) : 0;
+ var completed = Convert.ToDecimal(item.CompletedPerformance);
+
+ var rate1 = target1 > 0 ? (completed / target1 * 100m) : 0m;
+ var rate2 = target2 > 0 ? (completed / target2 * 100m) : 0m;
+ var rate3 = target3 > 0 ? (completed / target3 * 100m) : 0m;
+
+ return new ManagerPerformanceCompletionOutput
+ {
+ ManagerId = item.ManagerId.ToString(),
+ ManagerName = item.ManagerName.ToString(),
+ StoreId = item.StoreId.ToString(),
+ StoreName = item.StoreName.ToString(),
+ Target1 = target1,
+ Target2 = target2 > 0 ? target2 : (decimal?)null,
+ Target3 = target3 > 0 ? target3 : (decimal?)null,
+ CompletedPerformance = completed,
+ CompletionRate1 = decimal.Round(rate1, 2),
+ CompletionRate2 = target2 > 0 ? decimal.Round(rate2, 2) : (decimal?)null,
+ CompletionRate3 = target3 > 0 ? decimal.Round(rate3, 2) : (decimal?)null
+ };
+ }).ToList();
+
+ return outputList;
+ }
+
+ ///
+ /// 获取经理汇总业绩完成情况
+ ///
+ ///
+ /// 根据指定日期统计各经理的总业绩完成情况,汇总所有管理门店的数据
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "startTime": "2025-10-01",
+ /// "endTime": "2025-10-22",
+ /// "managerId": "经理ID"
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - startTime: 开始时间,可选,不传则默认为当月1号
+ /// - endTime: 结束时间,可选,不传则默认为今天
+ /// - managerId: 经理用户ID,可选,不传则查询所有经理
+ ///
+ /// 返回说明:
+ /// - ManagerId: 经理用户ID
+ /// - ManagerName: 经理姓名
+ /// - TotalTarget1/2/3: 总目标业绩一/二/三阶段
+ /// - TotalCompletedPerformance: 总完成业绩(指定时间范围内的开单业绩总和)
+ /// - TotalCompletionRate1/2/3: 总完成率各阶段
+ /// - StoreCount: 管理门店数量
+ ///
+ /// 查询参数
+ /// 经理汇总业绩完成情况列表
+ /// 成功返回经理汇总业绩完成情况列表
+ /// 日期格式错误或参数无效
+ /// 服务器内部错误
+ [HttpPost("get-manager-summary-performance-completion")]
+ public async Task> GetManagerSummaryPerformanceCompletion(ManagerPerformanceCompletionInput input)
+ {
+ // 获取时间范围
+ var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
+
+ // 构建经理过滤条件
+ var managerFilter = "";
+ if (!string.IsNullOrWhiteSpace(input.ManagerId))
+ {
+ managerFilter = $"AND target.zjl_userid = '{input.ManagerId}'";
+ }
+
+ // SQL查询:获取经理汇总业绩
+ var sql = $@"
+ SELECT
+ target.zjl_userid as ManagerId,
+ u.F_RealName as ManagerName,
+ SUM(target.smx1) as TotalTarget1,
+ COALESCE(SUM(target.smx2), 0) as TotalTarget2,
+ COALESCE(SUM(target.smx3), 0) as TotalTarget3,
+ COUNT(DISTINCT target.md_id) as StoreCount,
+ -- 总完成业绩
+ SUM(COALESCE((
+ SELECT SUM(billing.sfyj)
+ FROM lq_kd_kdjlb billing
+ WHERE billing.djmd = target.md_id
+ AND billing.F_IsEffective = 1
+ AND DATE(billing.kdrq) >= '{startDate:yyyy-MM-dd}'
+ AND DATE(billing.kdrq) <= '{endDate:yyyy-MM-dd}'
+ ), 0)) as TotalCompletedPerformance
+ FROM lq_zjl_mdsmxsz target
+ INNER JOIN BASE_USER u ON target.zjl_userid = u.F_Id
+ INNER JOIN lq_mdxx store ON target.md_id = store.F_Id
+ WHERE target.deletemark = 0
+ {managerFilter}
+ GROUP BY target.zjl_userid, u.F_RealName
+ ORDER BY TotalCompletedPerformance DESC";
+
+ var result = await _db.Ado.SqlQueryAsync(sql);
+
+ var outputList = result.Select(item =>
+ {
+ var totalTarget1 = Convert.ToDecimal(item.TotalTarget1);
+ var totalTarget2 = Convert.ToDecimal(item.TotalTarget2);
+ var totalTarget3 = Convert.ToDecimal(item.TotalTarget3);
+ var totalCompleted = Convert.ToDecimal(item.TotalCompletedPerformance);
+
+ var rate1 = totalTarget1 > 0 ? (totalCompleted / totalTarget1 * 100m) : 0m;
+ var rate2 = totalTarget2 > 0 ? (totalCompleted / totalTarget2 * 100m) : 0m;
+ var rate3 = totalTarget3 > 0 ? (totalCompleted / totalTarget3 * 100m) : 0m;
+
+ return new ManagerSummaryPerformanceCompletionOutput
+ {
+ ManagerId = item.ManagerId.ToString(),
+ ManagerName = item.ManagerName.ToString(),
+ TotalTarget1 = totalTarget1,
+ TotalTarget2 = totalTarget2,
+ TotalTarget3 = totalTarget3,
+ TotalCompletedPerformance = totalCompleted,
+ TotalCompletionRate1 = decimal.Round(rate1, 2),
+ TotalCompletionRate2 = decimal.Round(rate2, 2),
+ TotalCompletionRate3 = decimal.Round(rate3, 2),
+ StoreCount = Convert.ToInt32(item.StoreCount)
+ };
+ }).ToList();
+
+ return outputList;
+ }
+ #endregion
+
+ #region 获取科技部老师统计
+ ///
+ /// 获取科技部老师统计
+ ///
+ ///
+ /// 根据指定日期统计科技部老师的业绩情况,包括见客数、消耗项目数、消耗业绩、开单业绩
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "startTime": "2025-10-01",
+ /// "endTime": "2025-10-22",
+ /// "techDepartmentId": "科技部ID",
+ /// "teacherIds": ["老师ID1", "老师ID2"]
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - startTime: 开始时间,可选,不传则默认为当月1号
+ /// - endTime: 结束时间,可选,不传则默认为今天
+ /// - techDepartmentId: 科技部ID,可选,不传则查询所有科技部
+ /// - teacherIds: 老师ID列表,可选
+ ///
+ /// 返回说明:
+ /// - TechDepartmentId: 科技部ID
+ /// - TechDepartmentName: 科技部名称
+ /// - TeacherId: 老师ID
+ /// - TeacherName: 老师姓名
+ /// - CustomerCount: 见客数(不同客户数量)
+ /// - ConsumeProjectCount: 消耗项目数
+ /// - ConsumeAchievement: 消耗业绩
+ /// - OrderAchievement: 开单业绩
+ ///
+ /// 查询参数
+ /// 科技部老师统计列表
+ /// 成功返回科技部老师统计列表
+ /// 日期格式错误或参数无效
+ /// 服务器内部错误
+ [HttpPost("get-tech-teacher-daily-statistics")]
+ public async Task> GetTechTeacherDailyStatistics(TechTeacherDailyStatisticsInput input)
+ {
+ // 获取时间范围
+ var (startDate, endDate) = GetTimeRange(input.StartTime, input.EndTime);
+
+ // 构建过滤条件
+ var techFilter = "";
+ if (!string.IsNullOrWhiteSpace(input.TechDepartmentId))
+ {
+ techFilter = $"AND techDept.F_Id = '{input.TechDepartmentId}'";
+ }
+
+ var teacherFilter = "";
+ if (input.TeacherIds != null && input.TeacherIds.Any())
+ {
+ var teacherIdsStr = string.Join("','", input.TeacherIds);
+ teacherFilter = $"AND consume.kjbls IN ('{teacherIdsStr}')";
+ }
+
+ var teacherFilterForOrder = "";
+ if (input.TeacherIds != null && input.TeacherIds.Any())
+ {
+ var teacherIdsStr = string.Join("','", input.TeacherIds);
+ teacherFilterForOrder = $"AND ord.kjbls IN ('{teacherIdsStr}')";
+ }
+
+ // SQL查询:统计科技部老师的消耗业绩、见客数、项目数
+ var consumeSql = $@"
+ SELECT
+ techDept.F_Id as TechDepartmentId,
+ techDept.F_FullName as TechDepartmentName,
+ consume.kjbls as TeacherId,
+ consume.kjblsxm as TeacherName,
+ COUNT(DISTINCT hyhk.hy) as CustomerCount,
+ SUM(consume.F_hdpxNumber) as ConsumeProjectCount,
+ SUM(consume.kjblsyj) as ConsumeAchievement
+ FROM lq_xh_kjbsyj consume
+ INNER JOIN lq_xh_hyhk hyhk ON consume.glkdbh = hyhk.F_Id
+ INNER JOIN lq_mdxx store ON hyhk.md = store.F_Id
+ LEFT JOIN base_organize techDept ON store.kjb = techDept.F_Id
+ WHERE consume.F_IsEffective = 1
+ AND hyhk.F_IsEffective = 1
+ AND DATE(hyhk.hksj) >= '{startDate:yyyy-MM-dd}'
+ AND DATE(hyhk.hksj) <= '{endDate:yyyy-MM-dd}'
+ {techFilter}
+ {teacherFilter}
+ GROUP BY techDept.F_Id, techDept.F_FullName, consume.kjbls, consume.kjblsxm";
+
+ var consumeResult = await _db.Ado.SqlQueryAsync(consumeSql);
+
+ // 查询开单业绩
+ var orderSql = $@"
+ SELECT
+ techDept.F_Id as TechDepartmentId,
+ ord.kjbls as TeacherId,
+ SUM(ord.kjblsyj) as OrderAchievement
+ FROM lq_kd_kjbsyj ord
+ INNER JOIN lq_kd_kdjlb kdjlb ON ord.glkdbh = kdjlb.F_Id
+ INNER JOIN lq_mdxx store ON kdjlb.djmd = store.F_Id
+ LEFT JOIN base_organize techDept ON store.kjb = techDept.F_Id
+ WHERE ord.F_IsEffective = 1
+ AND kdjlb.F_IsEffective = 1
+ AND DATE(kdjlb.kdrq) >= '{startDate:yyyy-MM-dd}'
+ AND DATE(kdjlb.kdrq) <= '{endDate:yyyy-MM-dd}'
+ {techFilter}
+ {teacherFilterForOrder}
+ GROUP BY techDept.F_Id, ord.kjbls";
+
+ var orderResult = await _db.Ado.SqlQueryAsync(orderSql);
+
+ // 合并数据
+ var teacherDict = new Dictionary();
+
+ foreach (var item in consumeResult ?? Enumerable.Empty())
+ {
+ var key = $"{item.TechDepartmentId}_{item.TeacherId}";
+ teacherDict[key] = new TechTeacherDailyStatisticsOutput
+ {
+ TechDepartmentId = item.TechDepartmentId?.ToString(),
+ TechDepartmentName = item.TechDepartmentName?.ToString(),
+ TeacherId = item.TeacherId?.ToString(),
+ TeacherName = item.TeacherName?.ToString(),
+ CustomerCount = Convert.ToInt32(item.CustomerCount),
+ ConsumeProjectCount = Convert.ToInt32(item.ConsumeProjectCount),
+ ConsumeAchievement = Convert.ToDecimal(item.ConsumeAchievement),
+ OrderAchievement = 0
+ };
+ }
+
+ // 合并开单业绩
+ foreach (var item in orderResult ?? Enumerable.Empty())
+ {
+ var key = $"{item.TechDepartmentId}_{item.TeacherId}";
+ if (teacherDict.ContainsKey(key))
+ {
+ teacherDict[key].OrderAchievement = Convert.ToDecimal(item.OrderAchievement);
+ }
+ }
+
+ var outputList = teacherDict.Values
+ .OrderBy(x => x.TechDepartmentName)
+ .ThenBy(x => x.TeacherName)
+ .ToList();
+
+ return outputList;
+ }
+ #endregion
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqEventService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqEventService.cs
index 333e74d..eab0601 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend/LqEventService.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend/LqEventService.cs
@@ -800,6 +800,8 @@ namespace NCC.Extend.LqEvent
}
#endregion
+
+
#region 根据活动ID获取人员统计数据
///
diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqPackageInfoService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqPackageInfoService.cs
index 2b4aff6..4ad743a 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend/LqPackageInfoService.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend/LqPackageInfoService.cs
@@ -557,8 +557,8 @@ namespace NCC.Extend.LqPackageInfo
/// 获取营销活动统计数据
///
///
- /// 统计指定营销活动的开单、退卡相关数据
- /// 包括:开单数量、开单金额、退卡数量、退卡金额、净开单数量、净开单金额、退卡率
+ /// 统计指定营销活动的开单数据,支持分页
+ /// 包括:总记录数、开单总金额、欠款总金额、开单列表
///
/// 示例请求:
/// ```json
@@ -566,7 +566,9 @@ namespace NCC.Extend.LqPackageInfo
/// "activityId": "营销活动ID",
/// "startTime": "2025-10-01",
/// "endTime": "2025-10-31",
- /// "storeIds": ["门店ID1", "门店ID2"]
+ /// "storeIds": ["门店ID1", "门店ID2"],
+ /// "pageIndex": 1,
+ /// "pageSize": 20
/// }
/// ```
///
@@ -575,17 +577,16 @@ namespace NCC.Extend.LqPackageInfo
/// - startTime: 开始时间(可选,默认为活动开始时间)
/// - endTime: 结束时间(可选,默认为活动结束时间)
/// - storeIds: 门店ID列表(可选)
+ /// - pageIndex: 页码(默认1)
+ /// - pageSize: 每页数量(默认20)
///
/// 返回字段说明:
/// - ActivityId: 营销活动ID
/// - ActivityName: 营销活动名称
/// - BillingCount: 开单数量
- /// - BillingAmount: 开单金额
- /// - RefundCount: 退卡数量
- /// - RefundAmount: 退卡金额
- /// - NetBillingCount: 净开单数量(开单数量 - 退卡数量)
- /// - NetBillingAmount: 净开单金额(开单金额 - 退卡金额)
- /// - RefundRate: 退卡率(退卡数量 / 开单数量)
+ /// - BillingAmount: 开单总金额
+ /// - DebtAmount: 欠款总金额
+ /// - BillingList: 开单列表(包含开单ID、日期、客户信息、门店信息、金额、欠款等)
///
/// 查询参数
/// 营销活动统计数据
@@ -611,95 +612,78 @@ namespace NCC.Extend.LqPackageInfo
var startTime = input.StartTime ?? activity.StartTime;
var endTime = input.EndTime ?? activity.EndTime;
- // 3. 获取营销活动关联的品项ID列表
- var itemIds = await _db.Queryable()
- .Where(x => x.ActivityId == input.ActivityId && x.IsEffective == StatusEnum.有效.GetHashCode())
- .Select(x => x.ItemId)
- .ToListAsync();
-
- if (!itemIds.Any())
- {
- return new ActivityStatisticsOutput
- {
- ActivityId = input.ActivityId,
- ActivityName = activity.ActivityName,
- BillingCount = 0,
- BillingAmount = 0,
- RefundCount = 0,
- RefundAmount = 0,
- NetBillingCount = 0,
- NetBillingAmount = 0,
- RefundRate = 0
- };
- }
-
- // 4. 构建品项ID过滤条件
- var itemIdsStr = string.Join("','", itemIds);
- var itemIdsFilter = $"AND px.px IN ('{itemIdsStr}')";
- var itemIdsFilterRefund = $"AND hytkmx.px IN ('{itemIdsStr}')";
-
- // 5. 构建门店过滤条件
+ // 3. 构建门店过滤条件
string storeFilter = "";
- string storeFilterRefund = "";
if (input.StoreIds != null && input.StoreIds.Any())
{
var storeIdsStr = string.Join("','", input.StoreIds);
storeFilter = $"AND kd.djmd IN ('{storeIdsStr}')";
- storeFilterRefund = $"AND hytk.md IN ('{storeIdsStr}')";
}
- // 6. 开单统计
- var billingSql = $@"
+ // 4. 获取总记录数和总金额
+ var totalSql = $@"
SELECT
- COUNT(DISTINCT kd.F_Id) as billing_count,
- SUM(CAST(px.F_ActualPrice AS DECIMAL(18,2))) as billing_amount
- FROM lq_kd_pxmx px
- LEFT JOIN lq_kd_kdjlb kd ON px.glkdbh = kd.F_Id
- WHERE px.F_IsEffective = 1
- {itemIdsFilter}
- AND px.yjsj >= '{startTime:yyyy-MM-dd HH:mm:ss}'
- AND px.yjsj <= '{endTime:yyyy-MM-dd HH:mm:ss}'
+ COUNT(*) as total,
+ COALESCE(SUM(CAST(kd.sfyj AS DECIMAL(18,2))), 0) as billing_amount,
+ COALESCE(SUM(CAST(kd.qk AS DECIMAL(18,2))), 0) as debt_amount
+ FROM lq_kd_kdjlb kd
+ WHERE kd.F_IsEffective = 1
+ AND kd.F_ActivityId = '{input.ActivityId}'
+ AND kd.kdrq >= '{startTime:yyyy-MM-dd HH:mm:ss}'
+ AND kd.kdrq <= '{endTime:yyyy-MM-dd HH:mm:ss}'
{storeFilter}";
- var billingData = await _db.Ado.SqlQueryAsync(billingSql);
- var billingCount = Convert.ToInt32(billingData.FirstOrDefault()?.billing_count ?? 0);
- var billingAmount = Convert.ToDecimal(billingData.FirstOrDefault()?.billing_amount ?? 0);
+ var totalData = await _db.Ado.SqlQueryAsync(totalSql);
+ var billingCount = Convert.ToInt32(totalData.FirstOrDefault()?.total ?? 0);
+ var billingAmount = Convert.ToDecimal(totalData.FirstOrDefault()?.billing_amount ?? 0);
+ var debtAmount = Convert.ToDecimal(totalData.FirstOrDefault()?.debt_amount ?? 0);
- // 7. 退卡统计
- var refundSql = $@"
+ // 5. 分页查询开单列表
+ var offset = (input.PageIndex - 1) * input.PageSize;
+ var billingListSql = $@"
SELECT
- COUNT(DISTINCT hytk.F_Id) as refund_count,
- SUM(CAST(hytkmx.tkje AS DECIMAL(18,2))) as refund_amount
- FROM lq_hytk_mx hytkmx
- LEFT JOIN lq_hytk_hytk hytk ON hytkmx.F_RefundInfoId = hytk.F_Id
- WHERE hytkmx.F_IsEffective = 1
- {itemIdsFilterRefund}
- AND hytkmx.tksj >= '{startTime:yyyy-MM-dd HH:mm:ss}'
- AND hytkmx.tksj <= '{endTime:yyyy-MM-dd HH:mm:ss}'
- {storeFilterRefund}";
-
- var refundData = await _db.Ado.SqlQueryAsync(refundSql);
- var refundCount = Convert.ToInt32(refundData.FirstOrDefault()?.refund_count ?? 0);
- var refundAmount = Convert.ToDecimal(refundData.FirstOrDefault()?.refund_amount ?? 0);
-
- // 8. 计算净值和退卡率
- var netBillingCount = billingCount - refundCount;
- var netBillingAmount = billingAmount - refundAmount;
- var refundRate = billingCount > 0 ? Math.Round((decimal)refundCount / billingCount * 100, 2) : 0;
-
- // 9. 返回统计结果
+ kd.F_Id as BillingId,
+ kd.kdrq as BillingDate,
+ COALESCE(kh.khmc, '') as CustomerName,
+ COALESCE(kh.sjh, '') as CustomerPhone,
+ kd.djmd as StoreId,
+ COALESCE(md.dm, '') as StoreName,
+ CAST(kd.sfyj AS DECIMAL(18,2)) as Amount,
+ CAST(kd.qk AS DECIMAL(18,2)) as DebtAmount
+ FROM lq_kd_kdjlb kd
+ LEFT JOIN lq_khxx kh ON kd.kdhy = kh.F_Id
+ LEFT JOIN lq_mdxx md ON kd.djmd = md.F_Id
+ WHERE kd.F_IsEffective = 1
+ AND kd.F_ActivityId = '{input.ActivityId}'
+ AND kd.kdrq >= '{startTime:yyyy-MM-dd HH:mm:ss}'
+ AND kd.kdrq <= '{endTime:yyyy-MM-dd HH:mm:ss}'
+ {storeFilter}
+ ORDER BY kd.kdrq DESC
+ LIMIT {input.PageSize} OFFSET {offset}";
+
+ var billingListData = await _db.Ado.SqlQueryAsync(billingListSql);
+ var billingList = billingListData?.Select(item => new ActivityBillingItem
+ {
+ BillingId = item.BillingId?.ToString(),
+ BillingDate = item.BillingDate != null ? (DateTime?)item.BillingDate : null,
+ CustomerName = item.CustomerName?.ToString(),
+ CustomerPhone = item.CustomerPhone?.ToString(),
+ StoreId = item.StoreId?.ToString(),
+ StoreName = item.StoreName?.ToString(),
+ Amount = Convert.ToDecimal(item.Amount ?? 0),
+ DebtAmount = Convert.ToDecimal(item.DebtAmount ?? 0)
+ }).ToList() ?? new List();
+
+ // 6. 返回统计结果
return new ActivityStatisticsOutput
{
ActivityId = input.ActivityId,
ActivityName = activity.ActivityName,
BillingCount = billingCount,
BillingAmount = billingAmount,
- RefundCount = refundCount,
- RefundAmount = refundAmount,
- NetBillingCount = netBillingCount,
- NetBillingAmount = netBillingAmount,
- RefundRate = refundRate
+ DebtAmount = debtAmount,
+ BillingList = billingList
};
}
catch (Exception ex)
diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqReportService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqReportService.cs
index d440254..ba5ec9e 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend/LqReportService.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend/LqReportService.cs
@@ -715,12 +715,17 @@ namespace NCC.Extend
/// - storeIds: 门店ID列表(可选)
///
/// 返回字段说明:
- /// - TotalBillingAmount: 开单总金额
+ /// - TotalBillingAmount: 开单总金额(未扣除退卡)
/// - TotalConsumeAmount: 耗卡总金额
/// - TotalRefundAmount: 退卡总金额
/// - BillingCount: 开单人数(按客户去重)
/// - ConsumeCount: 耗卡人数(按客户去重)
/// - RefundCount: 退卡人数(按客户去重)
+ /// - TargetConsumeAmount: 消耗目标业绩(所有门店xhyj字段的总和)
+ /// - ConsumeCompletionRate: 消耗完成率(百分比)
+ /// - TargetBillingAmount: 开单目标业绩(所有门店xsyj字段的总和)
+ /// - CompletedBillingAmount: 开单完成业绩(开单总金额 - 退卡总金额)
+ /// - BillingCompletionRate: 开单完成率(百分比)
///
/// 查询参数
/// 业务统计数据
@@ -749,7 +754,7 @@ namespace NCC.Extend
object billingParameters;
if (input.StoreIds != null && input.StoreIds.Any())
{
- billingSql += " AND kd.F_StoreId IN @storeIds";
+ billingSql += " AND kd.djmd IN @storeIds";
billingParameters = new { startTime, endTime, storeIds = input.StoreIds };
}
else
@@ -774,7 +779,7 @@ namespace NCC.Extend
object consumeParameters;
if (input.StoreIds != null && input.StoreIds.Any())
{
- consumeSql += " AND xh.F_StoreId IN @storeIds";
+ consumeSql += " AND xh.md IN @storeIds";
consumeParameters = new { startTime, endTime, storeIds = input.StoreIds };
}
else
@@ -799,7 +804,7 @@ namespace NCC.Extend
object refundParameters;
if (input.StoreIds != null && input.StoreIds.Any())
{
- refundSql += " AND hytk.F_StoreId IN @storeIds";
+ refundSql += " AND hytk.md IN @storeIds";
refundParameters = new { startTime, endTime, storeIds = input.StoreIds };
}
else
@@ -811,6 +816,50 @@ namespace NCC.Extend
var refundCount = Convert.ToInt32(refundResult?.FirstOrDefault()?.refund_count ?? 0);
var refundAmount = Convert.ToDecimal(refundResult?.FirstOrDefault()?.refund_amount ?? 0m);
+ // 第四步:获取消耗目标业绩(所有门店xhyj字段的总和)
+ var targetConsumeSql = "SELECT COALESCE(SUM(CAST(md.xhyj AS DECIMAL(18,2))), 0) as target_consume_amount FROM lq_mdxx md WHERE 1=1";
+ object targetConsumeParameters = null;
+
+ if (input.StoreIds != null && input.StoreIds.Any())
+ {
+ targetConsumeSql += " AND md.F_Id IN @storeIds";
+ targetConsumeParameters = new { storeIds = input.StoreIds };
+ }
+
+ var targetConsumeResult = await _db.Ado.SqlQueryAsync(targetConsumeSql, targetConsumeParameters);
+ var targetConsumeAmount = Convert.ToDecimal(targetConsumeResult?.FirstOrDefault()?.target_consume_amount ?? 0m);
+
+ // 第五步:获取开单目标业绩(所有门店xsyj字段的总和)
+ var targetBillingSql = "SELECT COALESCE(SUM(CAST(md.xsyj AS DECIMAL(18,2))), 0) as target_billing_amount FROM lq_mdxx md WHERE 1=1";
+ object targetBillingParameters = null;
+
+ if (input.StoreIds != null && input.StoreIds.Any())
+ {
+ targetBillingSql += " AND md.F_Id IN @storeIds";
+ targetBillingParameters = new { storeIds = input.StoreIds };
+ }
+
+ var targetBillingResult = await _db.Ado.SqlQueryAsync(targetBillingSql, targetBillingParameters);
+ var targetBillingAmount = Convert.ToDecimal(targetBillingResult?.FirstOrDefault()?.target_billing_amount ?? 0m);
+
+ // 计算开单完成业绩(开单总金额 - 退卡总金额)
+ var completedBillingAmount = billingAmount - refundAmount;
+
+ // 计算完成率
+ var consumeCompletionRate = 0m;
+ if (targetConsumeAmount > 0)
+ {
+ consumeCompletionRate = (consumeAmount / targetConsumeAmount) * 100m;
+ consumeCompletionRate = decimal.Round(consumeCompletionRate, 2);
+ }
+
+ var billingCompletionRate = 0m;
+ if (targetBillingAmount > 0)
+ {
+ billingCompletionRate = (completedBillingAmount / targetBillingAmount) * 100m;
+ billingCompletionRate = decimal.Round(billingCompletionRate, 2);
+ }
+
var result = new BusinessStatisticsOutput
{
TotalBillingAmount = billingAmount,
@@ -818,7 +867,12 @@ namespace NCC.Extend
TotalRefundAmount = refundAmount,
BillingCount = billingCount,
ConsumeCount = consumeCount,
- RefundCount = refundCount
+ RefundCount = refundCount,
+ TargetConsumeAmount = targetConsumeAmount,
+ ConsumeCompletionRate = consumeCompletionRate,
+ TargetBillingAmount = targetBillingAmount,
+ CompletedBillingAmount = completedBillingAmount,
+ BillingCompletionRate = billingCompletionRate
};
return result;
@@ -878,6 +932,7 @@ namespace NCC.Extend
var endTime = input.EndTime ?? DateTime.Now;
// 第一步:获取客户类型统计
+ // 注意:lq_khxx表没有门店字段,无法按门店过滤
var customerTypeSql = $@"
SELECT
SUM(CASE WHEN kh.khlx = '{MemberTypeEnum.线索.GetHashCode()}' THEN 1 ELSE 0 END) as lead_count,
@@ -888,16 +943,7 @@ namespace NCC.Extend
WHERE kh.F_CreateTime >= @startTime
AND kh.F_CreateTime <= @endTime";
- object customerTypeParameters;
- if (input.StoreIds != null && input.StoreIds.Any())
- {
- customerTypeSql += " AND kh.F_StoreId IN @storeIds";
- customerTypeParameters = new { startTime, endTime, storeIds = input.StoreIds };
- }
- else
- {
- customerTypeParameters = new { startTime, endTime };
- }
+ object customerTypeParameters = new { startTime, endTime };
var customerTypeResult = await _db.Ado.SqlQueryAsync(customerTypeSql, customerTypeParameters);
var leadCount = Convert.ToInt32(customerTypeResult?.FirstOrDefault()?.lead_count ?? 0);
@@ -938,7 +984,7 @@ namespace NCC.Extend
object consumeParameters;
if (input.StoreIds != null && input.StoreIds.Any())
{
- consumeSql += " AND xh.F_StoreId IN @storeIds";
+ consumeSql += " AND xh.md IN @storeIds";
consumeParameters = new { startTime, endTime, storeIds = input.StoreIds };
}
else
diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs
index 797600e..4ead485 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs
@@ -3389,7 +3389,7 @@ namespace NCC.Extend.LqStatistics
///
///
/// 根据员工ID和月份统计员工的完整业绩数据
- /// 包括:拓客人数、邀约人数、预约人数、开单、消耗、退卡、人头、人次
+ /// 包括:拓客人数、邀约人数、预约人数、开单、消耗、退卡、人头、人次、项目数
///
/// 示例请求:
/// ```json
@@ -3411,8 +3411,10 @@ namespace NCC.Extend.LqStatistics
/// - AppointmentCount: 预约人数
/// - BillingCount: 开单数量
/// - BillingAmount: 开单金额
+ /// - BillingProjectCount: 开单项目数(项目次数总和)
/// - ConsumeCount: 消耗数量
/// - ConsumeAmount: 消耗金额
+ /// - ConsumeProjectCount: 消耗项目数(项目次数总和)
/// - RefundCount: 退卡数量
/// - RefundAmount: 退卡金额
/// - HeadCount: 人头(月度去重客户数)
@@ -3461,6 +3463,12 @@ namespace NCC.Extend.LqStatistics
// 8. 人次统计
var personCount = await GetPersonCount(input.UserId, statisticsMonth);
+ // 9. 开单项目数统计
+ var billingProjectCount = await GetBillingProjectCount(input.UserId, statisticsMonth);
+
+ // 10. 消耗项目数统计
+ var consumeProjectCount = await GetConsumeProjectCount(input.UserId, statisticsMonth);
+
return new EmployeePerformanceStatisticsOutput
{
UserId = input.UserId,
@@ -3475,7 +3483,9 @@ namespace NCC.Extend.LqStatistics
RefundCount = refundStats.Count,
RefundAmount = refundStats.Amount,
HeadCount = headCount,
- PersonCount = personCount
+ PersonCount = personCount,
+ BillingProjectCount = billingProjectCount,
+ ConsumeProjectCount = consumeProjectCount
};
}
catch (Exception ex)
@@ -3625,6 +3635,42 @@ namespace NCC.Extend.LqStatistics
return Convert.ToInt32(result.FirstOrDefault()?.Count ?? 0);
}
+ ///
+ /// 统计开单项目数(项目次数总和)
+ ///
+ private async Task GetBillingProjectCount(string userId, string month)
+ {
+ var sql = $@"
+ SELECT COALESCE(SUM(pxmx.F_ProjectNumber), 0) as Count
+ FROM lq_kd_jksyj jksyj
+ INNER JOIN lq_kd_pxmx pxmx ON jksyj.F_kdpxid = pxmx.F_Id
+ WHERE jksyj.jkszh = '{userId}'
+ AND jksyj.F_IsEffective = 1
+ AND DATE_FORMAT(jksyj.yjsj, '%Y%m') = '{month}'";
+
+ var result = await _db.Ado.SqlQueryAsync(sql);
+ return Convert.ToInt32(result.FirstOrDefault()?.Count ?? 0);
+ }
+
+ ///
+ /// 统计消耗项目数(项目次数总和)
+ ///
+ private async Task GetConsumeProjectCount(string userId, string month)
+ {
+ var sql = $@"
+ SELECT COALESCE(SUM(pxmx.F_ProjectNumber), 0) as Count
+ FROM lq_xh_jksyj jksyj
+ INNER JOIN lq_xh_hyhk hyhk ON jksyj.glkdbh = hyhk.F_Id
+ INNER JOIN lq_xh_pxmx pxmx ON pxmx.F_ConsumeInfoId = hyhk.F_Id
+ WHERE jksyj.jkszh = '{userId}'
+ AND jksyj.F_IsEffective = 1
+ AND hyhk.F_IsEffective = 1
+ AND DATE_FORMAT(hyhk.hksj, '%Y%m') = '{month}'";
+
+ var result = await _db.Ado.SqlQueryAsync(sql);
+ return Convert.ToInt32(result.FirstOrDefault()?.Count ?? 0);
+ }
+
#endregion
}
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
+
}
}