# 品项名称改造方案(按 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 作为业务主键、名称作为展示属性”的原则,可在不改历史数据的前提下实现平滑升级,并保留审计可追溯能力。