Files
TrueGrowth/docs/BACKUP_RESTORE_UI_STATE_LESSONS.md

62 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 备份恢复弹窗 UI 与状态管理经验
更新日期2026-04-29
## 背景
完整环境备份恢复能力扩展后,备份弹窗新增了环境、敏感配置、恢复模式等入口。功能变多后,原本单列表单开始出现弹窗过长、底部按钮不可见、概念重复和状态联动错误的问题。
## 问题现象
- 弹窗内容增多后,底部取消/开始按钮可能被挤出视口。
- 备份页同时出现“完整备份 / 增量备份”和 checkbox多了一层用户不需要理解的概念。
- “敏感配置”依赖“环境”,但状态更新时字段覆盖顺序错误,导致敏感配置勾选不上。
- 恢复页确实需要区分是否清空现有数据,但“增量恢复 / 完整恢复”不如“合并恢复 / 覆盖恢复”直观。
## 根因
- 表单内容和操作按钮放在同一个普通文档流里,没有弹窗最大高度和内部滚动区。
- UI 暴露了内部 `backupMode` 概念,但备份页已经通过 checkbox 表达了用户意图。
- 多字段联动直接在对象字面量中重复写字段,后写的旧值覆盖了用户刚触发的新值。
- 恢复模式是破坏性语义,备份模式是导出元数据语义,两者不应在 UI 上对称呈现。
## 修复思路
- 弹窗容器使用 `max-height``overflow: hidden`,面板拆成可滚动 body 与固定 actions。
- 备份页只保留 checkbox用户勾什么就备份什么。
- 导出时根据勾选结果自动推导 `backupMode`:全量安全域且无素材时间筛选时为 `complete`,否则为 `incremental`
- 恢复页保留模式选择,但文案改为“合并恢复 / 覆盖恢复”,明确是否清空现有数据。
- 状态联动先构造 `next`,再按规则修正依赖项,避免字段覆盖。
## 状态管理经验
- 用户可直接理解和操作的状态才放进 UI内部 manifest 字段应尽量从用户选择推导。
- 派生状态尽量在提交动作中计算,不要额外提供一个会和 checkbox 打架的独立开关。
- 有依赖关系的 checkbox 要写成单点状态转换:
- 勾选“敏感配置”时自动勾选“环境”。
- 取消“环境”时自动取消“敏感配置”。
- 避免在同一个对象字面量里既写 `[key]: checked` 又写同名字段旧值;这种写法很容易把新状态覆盖掉。
- 敏感配置必须继续由密码保护,状态修复不能绕过密码校验。
## UI 交互经验
- 功能型弹窗需要优先保证操作按钮始终可见,而不是让整个弹窗跟着内容无限增高。
- 大量 checkbox 可以用紧凑卡片网格承载,但移动端要降为单列,避免文字拥挤。
- 恢复页的模式文案要直接表达结果:
- 合并恢复:不清空现有数据。
- 覆盖恢复:先清空备份中包含的数据域,再还原。
- 不要为了和内部实现对齐而强迫用户理解“增量/完整”这类容易误解的术语。
## 性能与安全注意
- UI 紧凑化不能改变导出/导入的流式处理原则,大素材和任务数据仍需分页或分批处理。
- 完整恢复属于破坏性操作,必须保留二次确认。
- 未输入密码时不能导出敏感配置;未提供正确密码时不能恢复敏感配置。
- 关闭环境备份时必须同步关闭敏感配置,避免产生无效或误导性的备份选项。
## 验证
- `git diff --check`
- `pnpm --filter @aitu/drawnix exec tsc -p tsconfig.lib.json --noEmit --pretty false`
- 手动检查备份页仅保留内容多选,恢复页保留合并/覆盖语义。