# 需求分析 — TemplateManage 撤销/重做修复与插入字段光标定位(2026-04-17-12-51-47) ## 一、需求来源 用户反馈 TemplateManage 中存在两个严重的交互体验问题: 1. 删除智能字段(包括默认模板自带的和手动插入的)后,撤销/重做按钮完全失效。 2. 点击右侧字段库插入字段时,字段经常跳到下一行或错误位置。 ## 二、具体需求拆解 ### 需求 1:撤销/重做功能修复 **问题**:即使已经将删除逻辑改为 `execCommand('delete')`,撤销/重做按钮仍然无法恢复被删除的字段。 **原因**:浏览器原生的 `undo stack` 在 `contentEditable` 中结合 React 状态更新和强制 Range 操作时非常脆弱,容易被清空或打断。 **期望**:实现一个自定义的 undo/redo 历史栈,完全接管撤销/重做逻辑,确保任何内容变更(键盘输入、插入字段、删除字段)都能被正确撤销和恢复。 ### 需求 2:插入字段光标定位修复 **问题**:点击右侧字段库按钮时,编辑器失去焦点(blur),浏览器内部光标位置丢失。再次 `focus()` 后,光标往往被重置到文档开头/末尾或新块级位置,导致 `insertHTML` 插入的字段跳到下一行。 **期望**: - 点击字段库按钮时不让编辑器失去焦点。 - 若焦点仍丢失,则在插入前恢复上一次保存的光标位置(Range)。 - 插入的字段必须紧跟在插入前的光标位置,不强制换行。 ## 三、影响范围分析 | 文件 | 改动说明 | |------|----------| | `src/pages/TemplateManage.tsx` | 新增 `undoStack` / `redoStack` refs;重写 `handleUndo` / `handleRedo`;替换 `execCmd('undo')` / `execCmd('redo')` 的调用;在关键操作(删除、插入)前增加 `pushHistory`;增加 `saveSelection` 和 `restoreSelection`;字段按钮增加 `onMouseDown={(e) => e.preventDefault()}` 阻止焦点流失。 | ## 四、验收标准 - [ ] 在模板中删除任意智能字段后,点击"撤销"按钮能立即恢复该字段。 - [ ] 撤销恢复后,点击"重做"按钮能再次删除该字段。 - [ ] 连续输入文字、插入字段、删除字段后,撤销/重做能按正确的历史顺序回退/前进。 - [ ] 在文字中间点击插入字段,字段紧跟光标位置,不跳到下一行或文档末尾。 - [ ] 多次在不同位置插入字段,每次都能准确定位。 - [ ] `npm run lint` 无编译错误。