55bd8d57
“wangming”
fix: 修复全员战报明细到店数统...
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# 全员战报明细到店数统计问题修复
## 📋 问题描述
在全员战报明细统计中,发现有的数据的到店数比拓客数还多,不符合业务逻辑。
**业务规则**:
- 一个人多次到店的话在这里就算一次
- 到店数应该小于等于拓客数
## 🔍 问题分析
### 问题位置
**文件**: `netcore/src/Modularity/Extend/NCC.Extend/LqTkDashboardService.cs`
**方法**: `GetEmployeeParticipationStatistics`
**行数**: 第575-588行(修复前)
### 问题原因
**修复前的SQL逻辑**:
```sql
LEFT JOIN (
-- 到店人数统计
SELECT
tk.F_ExpansionUserId as EmployeeId,
COUNT(DISTINCT tk.F_MemberId) as VisitCount
FROM lq_tkjlb tk
INNER JOIN lq_xh_hyhk xh ON tk.F_MemberId = xh.hy AND xh.F_IsEffective = 1
WHERE {eventFilter}
AND tk.F_ExpansionTime >= '{startTimeStr}'
AND tk.F_ExpansionTime <= '{endTimeStr}'
AND xh.hksj >= '{startTimeStr}'
AND xh.hksj <= '{endTimeStr}'
GROUP BY tk.F_ExpansionUserId
) visit ON emp.EmployeeId = visit.EmployeeId
```
**问题点**:
1. **缺少时间关联约束**:没有限制到店时间必须在拓客时间之后,可能统计到拓客之前的到店记录
2. **JOIN导致重复计数**:当同一个会员被同一个员工多次拓客,且该会员多次到店时,`INNER JOIN` 会产生多行记录
3. **虽然使用了 DISTINCT,但 JOIN 的逻辑可能导致计数不准确**
### 问题场景示例
假设:
- 员工A在1月1日拓客了会员B
- 员工A在1月5日又拓客了会员B(重复拓客)
- 会员B在1月3日到店1次
- 会员B在1月6日到店1次
**修复前的统计结果**:
- 拓客数:1(COUNT(DISTINCT tk.F_MemberId))
- 到店数:2(因为 JOIN 产生了2条记录:1月1日拓客+1月3日到店,1月5日拓客+1月6日到店)
**问题**:到店数(2)> 拓客数(1),不符合逻辑
## ✅ 修复方案
### 修复后的SQL逻辑(最终版本)
```sql
LEFT JOIN (
-- 到店人数统计(一个人多次到店只算一次)
-- 先找出每个员工拓客的所有会员(去重),然后统计这些会员中有到店记录的会员数
SELECT
emp_members.EmployeeId,
COUNT(DISTINCT CASE WHEN xh.hy IS NOT NULL THEN emp_members.MemberId END) as VisitCount
FROM (
-- 先获取每个员工拓客的所有会员(去重),并记录首次拓客时间
SELECT DISTINCT
tk.F_ExpansionUserId as EmployeeId,
tk.F_MemberId as MemberId,
MIN(tk.F_ExpansionTime) as FirstExpansionTime
FROM lq_tkjlb tk
WHERE {eventFilter}
AND tk.F_ExpansionTime >= '{startTimeStr}'
AND tk.F_ExpansionTime <= '{endTimeStr}'
AND tk.F_MemberId IS NOT NULL
GROUP BY tk.F_ExpansionUserId, tk.F_MemberId
) emp_members
LEFT JOIN lq_xh_hyhk xh ON emp_members.MemberId = xh.hy
AND xh.F_IsEffective = 1
AND xh.hksj >= emp_members.FirstExpansionTime
AND xh.hksj >= '{startTimeStr}'
AND xh.hksj <= '{endTimeStr}'
GROUP BY emp_members.EmployeeId
) visit ON emp.EmployeeId = visit.EmployeeId
```
### 修复要点
1. **先获取拓客会员列表(去重)**:
- 使用子查询先找出每个员工拓客的所有会员(去重)
- 记录每个会员的首次拓客时间(`MIN(tk.F_ExpansionTime)`)
- 确保同一个会员只出现一次,即使被多次拓客
2. **统计有到店记录的会员数**:
- 在去重后的会员列表中,LEFT JOIN 耗卡表
- 使用 `COUNT(DISTINCT CASE WHEN xh.hy IS NOT NULL THEN emp_members.MemberId END)` 统计有到店记录的会员数
- 确保到店时间在首次拓客时间之后(`xh.hksj >= emp_members.FirstExpansionTime`)
3. **双重去重保障**:
- 第一层:在子查询中使用 `GROUP BY tk.F_ExpansionUserId, tk.F_MemberId` 确保每个员工-会员组合只出现一次
- 第二层:使用 `COUNT(DISTINCT ...)` 确保最终统计时每个会员只算一次
### 修复后的统计结果(使用上面的示例)
- 拓客数:1(COUNT(DISTINCT tk.F_MemberId))
- 到店数:1(会员B有到店记录,只算一次)
**结果**:到店数(1)≤ 拓客数(1),符合逻辑 ✅
## 📝 修改文件
- **文件**: `netcore/src/Modularity/Extend/NCC.Extend/LqTkDashboardService.cs`
- **方法**: `GetEmployeeParticipationStatistics`
- **修改位置**: 第575-590行
## ✅ 验证建议
1. **验证到店数 ≤ 拓客数**:检查所有员工的统计数据,确保到店数不超过拓客数
2. **验证去重逻辑**:选择一个多次到店的会员,验证其只被统计一次
3. **验证时间约束**:选择一个拓客前有到店记录的会员,验证不会被统计到
## 🔗 相关接口
**接口地址**: `POST /api/Extend/LqTkDashboard/GetEmployeeParticipationStatistics`
**接口说明**: 获取员工参与统计(全员战报明细)
**返回字段**:
- `ExpansionCount`: 拓客数
- `VisitCount`: 到店数(修复后)
- `BillingCount`: 开单数
- `BillingAmount`: 开单金额
|