257347ad
“wangming”
feat: enhance fil...
|
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
|
# 事业部开单统计播报问题分析
**问题描述**:绿纤西站店没有在事业部开单统计数据播报中显示
**分析日期**:2025年1月
**问题类型**:数据统计逻辑错误
---
## 一、问题定位
### 1.1 播报流程
**触发时机**:在创建开单记录时(`LqKdKdjlbService.Create` 方法)
**流程**:
1. 开单创建成功后,判断 `sfyj > 0` 且 `kdrq` 有值
2. 调用 `LqDailyReportService.GetBusinessUnitBillingStatisticsText` 获取统计数据文本
3. 如果文本不为空且不包含"暂无开单数据",则发送到企业微信群
**代码位置**:`LqKdKdjlbService.cs` 第1506-1536行
---
### 1.2 统计数据获取逻辑
**方法**:`LqDailyReportService.GetBusinessUnitBillingStatistics`
**位置**:`LqDailyReportService.cs` 第1513-1604行
**当前实现**(❌ **错误**):
```csharp
// 2. 查询指定日期的有效开单记录(有金额的)
var billingQuery = _db.Queryable<LqKdKdjlbEntity, LqMdxxEntity, OrganizeEntity>(
(billing, store, org) => billing.Djmd == store.Id && store.Syb == org.Id)
.Where((billing, store, org) => billing.IsEffective == StatusEnum.有效.GetHashCode())
.Where((billing, store, org) => billing.Sfyj > 0)
.Where((billing, store, org) => billing.Kdrq.HasValue && billing.Kdrq.Value.Date == targetDate.Date)
.Where((billing, store, org) => org.Category == "department")
.Where((billing, store, org) => org.FullName.Contains("事业"))
```
**问题**:
- ❌ 使用 `store.Syb == org.Id` 直接从 `lq_mdxx` 表的 `syb` 字段读取事业部归属
- ❌ 没有考虑月份维度,门店归属可能在不同月份发生变化
- ❌ 违反了项目规范:**门店归属一律从 `lq_md_target` 按月份维度管理**
---
## 二、问题根因分析
### 2.1 项目规范要求
根据项目规范(`.cursor/rules/project_rules.mdc`):
> **lq_mdxx_mdgs (门店归属表) 已弃用**: 门店归属信息不再从 `lq_mdxx` 直接读取
> - **门店归属一律从 `lq_md_target` 按月份维度管理**:通过 `F_StoreId + F_Month` 获取对应月份的事业部/经营部/科技部/旗舰店等归属信息
> - `lq_mdxx` 中的归属字段(`syb`、`jyb`、`kjb`、`dxmb`、`gsqssj`、`gszzsj`、`status`)视为历史字段,**禁止再作为业务统计或归属判断的依据**
### 2.2 正确的实现方式
在同一个文件的 `GetBusinessUnitPerformanceCompletion` 方法中(第418-433行),使用了正确的实现方式:
```sql
SELECT
target.F_BusinessUnit as BusinessUnitId,
COALESCE(SUM(billing.sfyj), 0) as BillingPerformance
FROM lq_kd_kdjlb billing
INNER JOIN lq_md_target target ON billing.djmd = target.F_StoreId AND target.F_Month = '{month}'
INNER JOIN base_organize o ON target.F_BusinessUnit = o.F_Id
WHERE billing.F_IsEffective = 1
AND target.F_BusinessUnit IS NOT NULL
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 target.F_BusinessUnit IN ('{unitIdsStr}')
GROUP BY target.F_BusinessUnit
```
**关键点**:
- ✅ 使用 `lq_md_target` 表获取门店归属
- ✅ 通过 `target.F_Month = '{month}'` 按月份维度筛选
- ✅ 通过 `target.F_BusinessUnit` 获取事业部ID
---
### 2.3 为什么绿纤西站店没有被统计
**可能的原因**:
1. **`lq_mdxx.syb` 字段为空或错误**
- 如果绿纤西站店在 `lq_mdxx` 表的 `syb` 字段中没有正确设置
- 或者 `syb` 字段指向的组织不是"事业X部"(不包含"事业"关键字)
- 则不会被统计进去
2. **`lq_md_target` 表中有正确的归属,但查询没有使用**
- 如果绿纤西站店在 `lq_md_target` 表中有正确的月份归属记录
- 但查询使用的是 `lq_mdxx.syb`,导致数据不一致
3. **月份维度问题**
- 如果查询时使用的月份与 `lq_md_target` 表中的月份不匹配
- 或者该门店在查询月份没有 `lq_md_target` 记录
---
## 三、问题影响
### 3.1 数据准确性
- ❌ 统计数据不准确,可能遗漏部分门店的开单数据
- ❌ 播报内容不完整,影响决策
### 3.2 业务影响
- ❌ 绿纤西站店的开单数据没有被播报
- ❌ 可能导致事业部业绩统计不准确
- ❌ 影响数据分析和决策
---
## 四、修复方案
### 4.1 修复思路
**核心原则**:按照项目规范,门店归属必须从 `lq_md_target` 表按月份维度获取
**修复步骤**:
1. **修改查询逻辑**:
- 不再使用 `lq_mdxx.syb` 字段
- 改为使用 `lq_md_target` 表,通过 `F_StoreId + F_Month` 获取门店归属
2. **确定月份**:
- 根据开单日期(`kdrq`)确定月份(YYYYMM格式)
- 使用该月份在 `lq_md_target` 表中查找门店归属
3. **关联查询**:
- `lq_kd_kdjlb` ← `lq_md_target`(通过门店ID和月份)
- `lq_md_target` ← `base_organize`(通过事业部ID)
---
### 4.2 修复后的查询逻辑
**方案一:使用 SqlSugar 查询(推荐)**
```csharp
// 1. 根据开单日期确定月份(YYYYMM格式)
var month = targetDate.ToString("yyyyMM");
// 2. 查询指定日期的有效开单记录(有金额的)
var billingQuery = _db.Queryable<LqKdKdjlbEntity, LqMdTargetEntity, OrganizeEntity>(
(billing, target, org) =>
billing.Djmd == target.StoreId
&& target.Month == month
&& target.BusinessUnit == org.Id)
.Where((billing, target, org) => billing.IsEffective == StatusEnum.有效.GetHashCode())
.Where((billing, target, org) => billing.Sfyj > 0)
.Where((billing, target, org) => billing.Kdrq.HasValue && billing.Kdrq.Value.Date == targetDate.Date)
.Where((billing, target, org) => target.BusinessUnit != null && target.BusinessUnit != "")
.Where((billing, target, org) => org.Category == "department")
.Where((billing, target, org) => org.FullName.Contains("事业"))
.Select((billing, target, org) => new
{
OrderId = billing.Id,
StoreName = billing.Djmd, // 需要关联门店表获取门店名称
BusinessUnitId = org.Id,
BusinessUnitName = org.FullName,
Amount = billing.Sfyj,
OrderTime = billing.Kdrq,
})
.ToListAsync();
```
**方案二:使用原生SQL查询(更灵活)**
```sql
SELECT
billing.F_Id as OrderId,
store.dm as StoreName,
org.F_Id as BusinessUnitId,
org.F_FullName as BusinessUnitName,
billing.sfyj as Amount,
billing.kdrq as OrderTime
FROM lq_kd_kdjlb billing
INNER JOIN lq_md_target target ON billing.djmd = target.F_StoreId AND target.F_Month = '{month}'
INNER JOIN lq_mdxx store ON billing.djmd = store.F_Id
INNER JOIN base_organize org ON target.F_BusinessUnit = org.F_Id
WHERE billing.F_IsEffective = 1
AND billing.sfyj > 0
AND DATE(billing.kdrq) = '{targetDate:yyyy-MM-dd}'
AND target.F_BusinessUnit IS NOT NULL
AND org.F_Category = 'department'
AND (org.F_DeleteMark IS NULL OR org.F_DeleteMark != 1)
AND org.F_FullName IN ('事业一部', '事业二部', '事业三部', '事业四部', '事业五部', '事业六部')
```
---
### 4.3 需要修改的代码
**文件**:`netcore/src/Modularity/Extend/NCC.Extend/LqDailyReportService.cs`
**方法**:`GetBusinessUnitBillingStatistics`(第1513-1604行)
**修改内容**:
1. 添加月份计算逻辑(根据 `targetDate` 计算月份)
2. 修改查询逻辑,使用 `lq_md_target` 表替代 `lq_mdxx.syb`
3. 添加门店名称的关联查询(如果需要)
---
## 五、验证方案
### 5.1 验证步骤
1. **检查绿纤西站店的数据**:
```sql
-- 检查门店基础信息
SELECT F_Id, dm, syb FROM lq_mdxx WHERE dm LIKE '%西站%';
-- 检查门店目标表中的归属信息
SELECT F_StoreId, F_Month, F_BusinessUnit
FROM lq_md_target
WHERE F_StoreId = (SELECT F_Id FROM lq_mdxx WHERE dm LIKE '%西站%' LIMIT 1)
ORDER BY F_Month DESC;
-- 检查该门店的开单记录
SELECT F_Id, djmd, kdrq, sfyj, F_IsEffective
FROM lq_kd_kdjlb
WHERE djmd = (SELECT F_Id FROM lq_mdxx WHERE dm LIKE '%西站%' LIMIT 1)
AND DATE(kdrq) = '2025-01-23' -- 替换为实际日期
AND sfyj > 0
AND F_IsEffective = 1;
```
2. **对比修复前后的数据**:
- 修复前:使用 `lq_mdxx.syb` 查询
- 修复后:使用 `lq_md_target` 查询
- 验证绿纤西站店是否出现在统计结果中
3. **测试播报功能**:
- 创建一个绿纤西站店的开单记录
- 验证播报内容中是否包含该门店
---
### 5.2 预期结果
修复后:
- ✅ 绿纤西站店的开单数据应该出现在统计结果中
- ✅ 播报内容应该包含该门店的开单信息
- ✅ 统计数据应该与 `lq_md_target` 表中的归属信息一致
---
## 六、风险评估
### 6.1 数据一致性风险
- ⚠️ 如果某些门店在 `lq_md_target` 表中没有对应月份的记录,可能不会被统计
- **建议**:添加容错处理,如果 `lq_md_target` 中没有记录,可以回退到 `lq_mdxx.syb`(但需要记录日志)
### 6.2 性能风险
- ⚠️ 使用 `lq_md_target` 表关联查询可能比直接使用 `lq_mdxx.syb` 稍慢
- **建议**:确保 `lq_md_target` 表有适当的索引(`F_StoreId + F_Month` 唯一索引已存在)
---
## 七、修复优先级
**优先级**:🔴 **高**
**原因**:
1. 影响数据准确性
2. 违反项目规范
3. 导致业务数据不完整
---
## 八、总结
### 8.1 问题根源
**核心问题**:`GetBusinessUnitBillingStatistics` 方法使用了错误的门店归属获取方式
- ❌ 当前实现:从 `lq_mdxx.syb` 字段读取(已弃用的历史字段)
- ✅ 应该使用:从 `lq_md_target` 表按月份维度获取
### 8.2 修复方向
1. **修改查询逻辑**:使用 `lq_md_target` 表替代 `lq_mdxx.syb`
2. **添加月份维度**:根据开单日期确定月份,使用该月份的门店归属
3. **保持一致性**:与其他统计方法(如 `GetBusinessUnitPerformanceCompletion`)保持一致
### 8.3 预期效果
修复后,绿纤西站店(以及其他所有门店)的开单数据将:
- ✅ 根据 `lq_md_target` 表中的月份归属正确统计
- ✅ 出现在对应事业部的播报内容中
- ✅ 符合项目规范要求
---
**文档结束**
|