Files
workspace/code/fms/.codebuddy/plans/fix-i18n-auto-generate-on-edit_2a35d5e3.md
T
2026-07-27 22:51:41 +08:00

5.0 KiB
Raw Blame History

name, overview, todos
name overview todos
fix-i18n-auto-generate-on-edit 修复模块管理页面:编辑模块编码/字段名/权限编码时不再实时生成多语言受管键,改为点击「保存」时根据最终草稿生成。
id content status
i18n-panel-override 修改 ModuleI18nPanel 的 reconcileManagedRows 支持 itemsOverride 参数并在 defineExpose 暴露 completed
id content status dependencies
index-originals-i18n 将 index.vue 的 i18nItems 改为基于 originals 计算,并新增基于 drafts 的 finalI18nItems completed
i18n-panel-override
id content status dependencies
save-all-reconcile 在 index.vue 的 saveAll 保存多语言前调用 i18nPanelRef.reconcileManagedRows(finalI18nItems) completed
index-originals-i18n
id content status dependencies
verify-fmt 运行 pnpm fmt:check 校验格式,核对三类受管键仅保存时生成 completed
save-all-reconcile

用户需求

模块管理页面编辑模块编码/字段名/权限编码时,多语言面板会实时生成受管多语言行,且使用的是草稿中尚未保存的默认值("旧值")。用户希望:只有点击「保存」时才根据最终的模块编码生成多语言,编辑过程中不要实时生成。

核心功能

  • 编辑模块编码(基本信息面板)时,多语言面板不再实时生成/重命名受管键。
  • 编辑字段定义中的字段名、权限配置中的权限编码时,同样不再实时生成对应受管键。
  • 点击「保存」时,依据最终填写的模块编码、字段名、权限编码生成并落库多语言受管键。

影响范围

  • 该问题由同一根因引起,覆盖「模块编码、字段定义、权限」三类受管多语言键,一次修复即可全部覆盖。
  • 仅前端修改,不涉及后端、迁移脚本、b_user_power 逻辑。

技术栈

  • 前端:Vue 3 <script setup> SFC + Pinia + antdv-next(沿用现有框架,不改变技术栈)。
  • 数据层:复用通用 loadDataApi / saveObjectApi,不新增接口。

实现方案

根因:父组件 index.vue 的 i18nItems computed 由 drafts(实时编辑态)计算,并传给 ModuleI18nPanel 的 :i18n-items;面板内 watch(() => props.i18nItems, reconcileManagedRows, { deep: true }) 在每次变化时立即创建/重命名受管多语言行,造成"输入即生成",且 i18nItems 用 module?.b_code 作为字段/权限 key 前缀,导致模块编码变更会级联影响字段与权限的受管键。

关键决策:分离"实时展示快照"与"保存时最终态"。

  1. 实时传给面板的 i18nItems 改为基于 originals(已保存快照)计算,编辑过程中 originals 不变,reconcileManagedRows 不会因草稿改动而触发实时生成。
  2. 新增 finalI18nItems computed 基于 drafts(最终编辑态)计算,仅供保存使用。
  3. 在 saveAll 调用 i18nPanel.buildSaveRequest() 前,调用 i18nPanelRef.value.reconcileManagedRows(finalI18nItems.value),将最终草稿中的受管键推入面板,由 buildSaveRequest 收集并随保存落库(此时才按模块编码生成)。
  4. ModuleI18nPanel.reconcileManagedRows(itemsOverride?) 增加可选参数,缺省回退到 managedItems.value;watch 不传参行为不变。并在 defineExpose 暴露它。

性能与可靠性:

  • 仅调整数据源(originals/drafts),不引入新的渲染或网络开销;reconcileManagedRows 仍为 O(n) 遍历,开销可忽略。
  • 保存后 originals.value = cloneData(drafts.value) 与 markSaved() 已存在,originals 驱动下的 i18nItems 会在保存后自然包含最终键,且 markSaved 将 originalsFlat 同步为保存后的扁平数据,避免重复保存。
  • 子面板(ModuleBasicPanel.onCodeInput、ModuleFieldsPanel/ModulePowersPanel 的 syncModuleItemI18nKeys)仍会写入草稿 b_i18n,但面板实时项已改为 originals 驱动,不再触发实时生成;saveAll 仍会重写为最终值,功能不受影响。
  • loadI18n / requestedKeys 基于 props.i18nItems(originals 驱动)后,仅加载已保存 key,符合预期。

实施要点

  • 修改需保持范围最小,不触碰无关的通用端点、共享组件或全局样式。
  • 因前端无单测脚本,交付后运行 pnpm fmt:check 校验格式,不自动构建/启动。

目录结构(仅列出将修改的文件)

fms-vue/src/views/module-management/
├── index.vue                                  # [MODIFY] i18nItems 改为基于 originals;
│                                              #   新增 finalI18nItems(基于 drafts);
│                                              #   在 saveAll 保存多语言前调用
│                                              #   i18nPanelRef.reconcileManagedRows(finalI18nItems)
└── components/
    └── ModuleI18nPanel.vue                    # [MODIFY] reconcileManagedRows 支持 itemsOverride;
                                               #   defineExpose 暴露 reconcileManagedRows