e1dcb3a0
“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
232
233
234
235
236
|
# 品项名称改造方案(按 ID 关联显示)
## 1. 背景与目标
当前系统已运行较长时间,品项名称在多个业务环节被“快照存储”(例如开单/耗卡/退卡/业绩明细),导致“主档改名后历史数据是否跟随变化”成为核心问题。
本方案目标:
- 以 `品项ID` 作为唯一业务事实源;
- 查询/统计场景可按 `ID -> 当前主档名称` 展示最新名称;
- 保留历史快照名称用于审计与追溯;
- 在不破坏生产数据稳定性的前提下,分阶段完成改造。
## 2. 关键结论
- **同意“按 ID 关联即可”**,但必须区分“展示口径”和“审计口径”。
- 不建议直接全量回写历史快照名称(风险高、不可逆、对账成本大)。
- 推荐“双字段口径”:
- `itemNameSnapshot`:历史快照名(业务发生当时)
- `itemNameCurrent`:按 ID 关联主档实时名(当前名称)
## 3. 现状梳理(影响面)
### 3.1 主档与产品主数据
- `lq_xmzl.xmmc`(项目资料)
- `lq_product.F_ProductName`(库存产品)
### 3.2 历史快照字段(重点)
以下表存在名称快照字段,主档改名后不会自动联动:
- `lq_kd_pxmx.pxmc`(开单明细)
- `lq_xh_pxmx.pxmc`(耗卡明细)
- `lq_hytk_mx.pxmc`(退卡明细)
- `lq_yyjl_px.F_Pxmc`(预约明细)
- `lq_kd_jksyj.F_ItemName`、`lq_kd_kjbsyj.F_ItemName`
- `lq_xh_jksyj.F_ItemName`、`lq_xh_kjbsyj.F_ItemName`
- `lq_hytk_jksyj.F_ItemName`、`lq_hytk_kjbsyj.F_ItemName`
- `lq_kd_deductinfo.F_ItemName`
- `lq_yjmxb.xmmc`
### 3.3 后端服务与接口(高频)
- 项目资料:`LqXmzlService`
- 开单:`LqKdKdjlbService`
- 耗卡:`LqXhHyhkService`
- 退卡:`LqHytkHytkService`
- 统计/报表:`LqStatisticsService`、`LqReportService`
- 库存使用:`LqInventoryUsageService`
### 3.4 前端三端
- 管理后台:`antis-ncc-admin`
- 门店 PC:`store-pc`
- 手机端:`绿纤uni-app`
存在大量 `xmmc / itemName / pxmc / productName` 展示与搜索逻辑,需要统一口径。
## 4. 改造原则
1. **业务判断永远用 ID / 分类编码,不用名称字符串判断。**
2. **保存时保留快照**(兼容历史与审计)。
3. **查询时可选“当前名称”展示**(用户视角一致)。
4. **导出口径可配置**:审计导出用快照;运营报表可用当前名。
5. **渐进式发布**:先“加字段不替换”,再页面逐步切换。
## 5. 目标数据模型(接口返回层)
对涉及品项的列表/明细 DTO 增加统一字段(命名可按现有风格微调):
- `itemId`(已有则复用)
- `itemNameSnapshot`(来自明细表快照字段)
- `itemNameCurrent`(通过 itemId 关联 `lq_xmzl` 或 `lq_product` 得到)
- `itemNameDisplay`(后端统一赋值:优先 current,兜底 snapshot)
说明:
- 不强制修改现有数据库表结构;
- 以“查询拼装”实现,优先低风险落地。
## 6. 分阶段实施计划
### Phase 0:基线与开关(1-2 天)
- 建“名称显示口径”开关(建议放系统配置):
- `snapshot`:显示历史快照
- `current`:显示当前主档名(默认)
- `both`:显示“当前名(历史名)”
- 梳理核心接口清单并建立回归用例。
交付物:
- 口径开关配置
- 接口改造白名单
- 回归清单 v1
### Phase 1:后端查询层改造(3-5 天)
- 先改高频接口:开单、耗卡、退卡、统计看板、库存使用。
- 统一在服务层拼装 `itemNameCurrent` 与 `itemNameDisplay`。
- 导出接口补“显示口径”参数(默认 current,审计类可切 snapshot)。
交付物:
- 后端接口新增字段并兼容老字段
- 导出口径参数
- 核心接口测试通过
### Phase 2:前端三端展示切换(3-5 天)
- 三端页面统一显示 `itemNameDisplay`;
- 搜索支持“名称(当前名/快照名)+ ID”混合查询;
- 关键页面加 tooltip(显示历史名,便于核对)。
交付物:
- admin/store-pc/uni-app 主流程页面切换完成
- 页面回归通过
### Phase 3:统计与导出全覆盖(2-4 天)
- 统计报表全部统一名称口径;
- 导出模板区分“运营版(当前名)/审计版(快照名)”。
交付物:
- 报表与导出口径一致性验收
- 业务方签字确认
### Phase 4:可选增强(后续)
- 增加“品项名称变更日志表”(记录旧名、新名、操作人、时间)。
- 提供“历史名称映射查询”能力,辅助追溯。
## 7. 兼容与风险控制
### 7.1 兼容策略
- 老字段不删:`xmmc/pxmc/F_ItemName` 继续保留。
- 新字段增量返回,不破坏现有前端。
- 分批切页面,先灰度后全量。
### 7.2 主要风险
- 同名不同 ID 的品项被误归并。
- 历史单据显示变化引发财务误解。
- 导出模板与页面口径不一致。
- 局部代码仍用“品项名称字符串”做业务判断,改名后会误判。
- 聚合 SQL 同时按 `itemId + itemName` 分组,改名前后可能被拆成两行。
- 查询参数仍按名称模糊匹配时,用户可能误以为“数据丢失”。
### 7.3 防控措施
- 所有聚合统计以 `itemId` 为主键分组。
- 报表标题显式标注“按当前名称展示/按历史快照展示”。
- 发布前做“同一时间区间、新旧口径对比报表”。
- 对“名称参与业务判断”的代码做专项整改清单并逐条回归(见第 11 节)。
- 所有搜索接口支持“名称 + ID 双通道”检索,避免仅靠名称检索导致漏数。
## 8. 验收标准(必须通过)
1. 主档改名后,开单/耗卡/退卡新数据立即显示新名称。
2. 历史数据在“当前口径”下可显示新名称,在“审计口径”下可显示旧名称。
3. 所有统计页与导出页口径一致,不出现同 ID 双名称拆分。
4. 不出现任何基于名称字符串的业务判断回归问题。
5. 全流程回归通过:开单、耗卡(医美 T 区/科美)、退卡、薪资、分摊、看板、导出。
## 9. 建议上线顺序
1. 后端接口先增量返回新字段(不切前端)。
2. 管理后台先切换并灰度给运营。
3. 门店 PC 与手机端随后切换。
4. 最后切导出默认口径,并保留审计口径开关。
## 10. 需要产品/业务确认的决策项
上线前请明确以下口径:
- 默认展示口径:`current` 还是 `both`?
- 财务导出默认用快照名还是当前名?
- 历史页面是否允许看到“当前名(历史名)”双显?
- 是否需要落地“名称变更日志”审计功能?
## 11. 本轮复盘补充的遗漏点(必须纳入改造)
### 11.1 逻辑层仍存在“按名称判断”的代码(高风险)
已发现典型位置(示例):
- `LqXhHyhkService.AppointmentConsume` 中存在 `string.Equals(a.Pxmc, item.pxmc)` 等按名称比对逻辑。
- 这类逻辑在品项改名后会直接出现“同一品项无法匹配/重复匹配”问题。
要求:
- 统一改为 `itemId` 比对(如 `Px` / `F_ItemId`)。
- 名称仅用于提示文案,不作为判定条件。
### 11.2 聚合/统计存在“ID + 名称”双字段分组(高风险)
已发现示例:
- `LqReportService` 中 `GROUP BY xhpx.px, xhpx.pxmc`、`GROUP BY kdpx.px, kdpx.pxmc`
- `LqPackageInfoService` 中 `GroupBy(new { ItemId = px.Px, ItemName = px.Pxmc })`
风险:
- 改名前后同一 `itemId` 可能因为 `itemName` 不同而被拆分成多行统计结果。
要求:
- 聚合一律按 `itemId` 分组;
- 名称由关联主档或聚合后再映射,避免分组维度携带名称。
### 11.3 搜索条件目前大量按名称模糊查询(中风险)
现状:
- 多个接口 `WhereIF(input.ItemName, ... Contains(Pxmc))`;
- 用户只记得新名称时,若页面仍走快照字段搜索,会查不到部分历史数据。
要求:
- 查询参数升级为:`itemKeyword`(名称或编码),并支持 `itemId` 精确查询;
- 在口径切换为 current 时,搜索需兼容快照名与当前名。
### 11.4 导出与接口说明文档口径同步(中风险)
现状:
- 导出列大量使用“品项名称”单字段;
- 接口文档/前端说明仍默认“品项名称唯一”。
要求:
- 导出增加“名称口径”标识或参数;
- 文档示例同步为 `itemNameSnapshot/itemNameCurrent/itemNameDisplay`。
### 11.5 数据前置校验(已核验)
本次查库结果(开发库):
- 核心明细表 `itemId` 缺失量为 0(开单/耗卡/退卡/预约/业绩表均可按 ID 关联)。
- 说明:以 ID 关联改造具备可落地数据基础,无需先做大规模补数。
## 12. 增补后的实施清单(执行版)
在原 Phase 计划基础上,新增强制任务:
1. **专项任务 A:名称判定逻辑清零**
- 扫描并替换所有 `pxmc/xmmc/itemName` 参与判定、去重、匹配的代码。
- 验收标准:业务判定逻辑中不再出现名称等值比较。
2. **专项任务 B:聚合 SQL 维度整改**
- 所有 `GROUP BY` 涉及品项维度时,只允许 `itemId` 作为主分组键。
- 验收标准:同一 `itemId` 不会因改名前后名称变化而拆分。
3. **专项任务 C:查询参数升级**
- 列表接口统一支持 `itemId` 精确过滤;
- 名称搜索支持“当前名+快照名”兼容检索。
4. **专项任务 D:文档与导出口径统一**
- 对外接口文档、前端调用说明、导出模板说明全部补充口径说明。
---
该方案遵循“ID 作为业务主键、名称作为展示属性”的原则,可在不改历史数据的前提下实现平滑升级,并保留审计可追溯能力。
|