Initial TrueGrowth source import

This commit is contained in:
2026-07-07 09:36:36 +08:00
commit 3b6781d695
2283 changed files with 691996 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
# 备份恢复弹窗 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`
- 手动检查备份页仅保留内容多选,恢复页保留合并/覆盖语义。