Blame view

项目文档相关/docs/开单升单逻辑Bug排查报告.md 6.51 KB
f891e7d4   “wangming”   1
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
  # 开单升单逻辑Bug排查报告
  
  ## 排查目的
  确认 `UpdateForNoDelete` 方法中是否存在升单字段赋值错误,因为这是生产环境,需要谨慎验证。
  
  ---
  
  ## 代码对比分析
  
  ### 1. Create方法(新增开单)- 第856-884行
  
  **逻辑正确**
  
  ```csharp
  //判断升医美:当前开单包含医美品项 + 之前有医美类型的开单记录 + 实付业绩>=1000
  if (hasMedicalItemInCurrentBilling && hasPreviousMedicalBilling && MedicalItemInCurrentBillingAmount >= 1000)
  {
      entity.UpgradeMedicalBeauty = "是";  // ✅ 正确
  }
  
  //判断升科美:当前开单包含科美品项 + 之前有科美类型的开单记录
  if (hasTechItemInCurrentBilling && hasPreviousTechBilling)
  {
      entity.UpgradeTechBeauty = "是";  // ✅ 正确
  }
  
  //判断升生美:当前开单包含生美品项 + 之前有生美类型的开单记录
  if (hasLifeItemInCurrentBilling && hasPreviousLifeBilling)
  {
      entity.UpgradeLifeBeauty = "是";  // ✅ 正确
  }
  ```
  
  ---
  
  ### 2. UpdateForNoDelete方法(更新开单)- 第1192-1220行
  
  **逻辑存在Bug**
  
  ```csharp
  // 第1192行:判断升医美的条件
  var isMedicalProject = hasMedicalItemInCurrentBilling && await _db.Queryable<LqKdPxmxEntity>()
      .Where(x => x.MemberId == entity.Kdhy 
          && x.IsEffective == StatusEnum.有效.GetHashCode() 
          && x.ItemCategory == "医美"  // 判断医美
          && x.ActualPrice > 0 
          && x.Px != "61" 
          && x.Glkdbh != id)
      .AnyAsync();
  
  // 第1193-1200行:判断升医美,但赋值错误
  if (isMedicalProject && MedicalItemInCurrentBillingAmount >= 1000)
  {
      entity.UpgradeLifeBeauty = "是";  // ❌ BUG:应该是 UpgradeMedicalBeauty
  }
  else
  {
      entity.UpgradeLifeBeauty = "否";  // ❌ BUG:应该是 UpgradeMedicalBeauty
  }
  
  // 第1202行:判断升科美的条件
  var isTechProject = hasTechItemInCurrentBilling && await _db.Queryable<LqKdPxmxEntity>()
      .Where(x => x.MemberId == entity.Kdhy 
          && x.IsEffective == StatusEnum.有效.GetHashCode() 
          && x.ItemCategory == "科美"  // 判断科美
          && x.ActualPrice > 0 
          && x.Px != "61" 
          && x.Glkdbh != id)
      .AnyAsync();
  
  // 第1203-1210行:判断升科美,赋值正确
  if (isTechProject)
  {
      entity.UpgradeTechBeauty = "是";  // ✅ 正确
  }
  
  // 第1212行:判断升生美的条件
  var isLifeProject = hasLifeItemInCurrentBilling && await _db.Queryable<LqKdPxmxEntity>()
      .Where(x => x.MemberId == entity.Kdhy 
          && x.IsEffective == StatusEnum.有效.GetHashCode() 
          && x.ItemCategory == "生美"  // 判断生美
          && x.ActualPrice > 0 
          && x.Px != "61" 
          && x.Glkdbh != id)
      .AnyAsync();
  
  // 第1213-1220行:判断升生美,但赋值错误
  if (isLifeProject)
  {
      entity.UpgradeMedicalBeauty = "是";  // ❌ BUG:应该是 UpgradeLifeBeauty
  }
  else
  {
      entity.UpgradeMedicalBeauty = "否";  // ❌ BUG:应该是 UpgradeLifeBeauty
  }
  ```
  
  ---
  
  ### 3. 批量处理方法(BatchProcessHistoricalUpgradeTypes)- 第4342-4348行
  
  **逻辑正确**
  
  ```csharp
  // 判断升医美
  billing.UpgradeMedicalBeauty = (hasMedicalItem && hasPreviousMedical && medicalItemAmount >= 1000) ? "是" : "否";
  
  // 判断升科美
  billing.UpgradeTechBeauty = (hasTechItem && hasPreviousTech) ? "是" : "否";
  
  // 判断升生美
  billing.UpgradeLifeBeauty = (hasLifeItem && hasPreviousLife) ? "是" : "否";
  ```
  
  ---
  
  ## Bug确认
  
  ### Bug 1:升医美判断错误赋值
  - **位置**:第1193-1200行
  - **问题**:判断升医美的条件,但赋值给了 `UpgradeLifeBeauty`(升生美字段)
  - **正确应该是**:赋值给 `UpgradeMedicalBeauty`
  
  ### Bug 2:升生美判断错误赋值
  - **位置**:第1213-1220行
  - **问题**:判断升生美的条件,但赋值给了 `UpgradeMedicalBeauty`(升医美字段)
  - **正确应该是**:赋值给 `UpgradeLifeBeauty`
  
  ---
  
  ## 影响分析
  
  ### 受影响的操作
  - **UpdateForNoDelete方法**:当通过此方法更新开单记录时,升单标记会被错误赋值
  
  ### 不受影响的操作
  - **Create方法**:新增开单时,升单标记是正确的
  - **批量处理方法**:批量处理历史数据时,升单标记是正确的
  
  ### 实际影响
  1. **如果开单记录只通过Create方法创建,从未通过Update方法更新**
     - ✅ 升单标记是正确的
  
  2. **如果开单记录通过Update方法更新过**
     - ❌ 升医美的标记会被错误地写入 `UpgradeLifeBeauty` 字段
     - ❌ 升生美的标记会被错误地写入 `UpgradeMedicalBeauty` 字段
     - ✅ 升科美的标记是正确的
  
  3. **数据混乱情况**
     - 如果一个开单同时满足升医美和升生美的条件,通过Update方法更新后:
       - `UpgradeLifeBeauty` 会被设置为"是"(但实际应该是升医美)
       - `UpgradeMedicalBeauty` 会被设置为"是"(但实际应该是升生美)
       - 数据完全错位
  
  ---
  
  ## 验证建议
  
  ### 1. 检查Update方法使用频率
  - 查询最近几个月通过 `UpdateForNoDelete` 方法更新的开单记录数量
  - 确认是否有大量数据受到影响
  
  ### 2. 抽样验证数据
  - 随机抽取一些通过Update方法更新的开单记录
  - 检查其升单标记是否与品项明细匹配
  - 如果发现不匹配,说明Bug确实存在
  
  ### 3. 对比Create和Update的数据
  - 对比同一时间段通过Create和Update方法处理的升单标记
  - 如果Update方法处理的数据有明显异常,说明Bug存在
  
  ---
  
  ## 修复方案
  
  ### 修复代码位置
  - **文件**`netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs`
  - **方法**`UpdateForNoDelete`
  - **行数**:第1195行和第1215行
  
  ### 修复内容
  
  **第1195行**
  ```csharp
  // 修复前
  entity.UpgradeLifeBeauty = "是";
  
  // 修复后
  entity.UpgradeMedicalBeauty = "是";
  ```
  
  **第1199行**
  ```csharp
  // 修复前
  entity.UpgradeLifeBeauty = "否";
  
  // 修复后
  entity.UpgradeMedicalBeauty = "否";
  ```
  
  **第1215行**
  ```csharp
  // 修复前
  entity.UpgradeMedicalBeauty = "是";
  
  // 修复后
  entity.UpgradeLifeBeauty = "是";
  ```
  
  **第1219行**
  ```csharp
  // 修复前
  entity.UpgradeMedicalBeauty = "否";
  
  // 修复后
  entity.UpgradeLifeBeauty = "否";
  ```
  
  ---
  
  ## 结论
  
  **Bug确实存在**,但需要确认:
  1. `UpdateForNoDelete` 方法在生产环境中的使用频率
  2. 是否有历史数据受到影响
  3. 是否需要修复历史数据
  
  **建议**
  1. 先修复代码Bug
  2. 评估是否需要修复历史数据(如果Update方法使用频率不高,可能影响范围有限)
  3. 如果影响范围大,考虑使用批量处理方法重新计算受影响的开单记录的升单标记