feat: smart field uniqueness, delete button, bulk export in report manage

- TemplateManage: add uniqueness check for smart fields to prevent duplicate inserts
- Add red circular delete button to smart-field-wrapper (visible on hover via CSS)
- Enhance keydown handler to delete smart fields at block-level boundaries
- Update defaultContent.ts smartField() to include delete-btn
- ReportManage: add per-row checkboxes, select-all, bulk delete
- Add single-report export modal (PDF via printDocument, JSON via Blob)
- Add bulk export actions for PDF and JSON
- Update experience record (#16)
This commit is contained in:
2026-04-17 10:32:07 +08:00
parent 38ff67a6a8
commit db5df13a05
8 changed files with 530 additions and 30 deletions

View File

@@ -345,6 +345,38 @@ if ((settings.autoInsertDelay || 0) > 0) {
---
## 记录 16模板字段唯一性、删除按钮与报告批量导出
**A. 具体问题**
1. `TemplateManage` 中智能字段可以重复插入多次,导致模板混乱。
2. 智能字段在某些边界位置(如段落开头/结尾)无法通过 Backspace/Delete 删除。
3. `ReportManage` 缺少报告导出功能和批量操作能力。
**B. 产生问题原因**
1. `insertSmartField` 没有检测 DOM 中是否已存在相同 `data-bind` 的字段节点。
2. 之前的 `keydown` 拦截逻辑只处理了光标在文本节点内的情况,没有处理光标直接在块级父节点边界(`startContainer` 为 `<p>` 等块元素)的场景。
3. `ReportManage` 的设计只支持单条查看/编辑/删除,没有设计多选状态和导出逻辑。
**C. 解决问题方案**
1. **唯一性校验**:在 `insertSmartField` 中通过 `editorRef.current?.querySelector([data-bind="..."])` 预检查,若已存在则 `alert` 并终止插入。
2. **删除按钮**:给 `.smart-field-wrapper` 内部增加一个红色圆形的 `<span class="delete-btn">×</span>`,点击即可删除整个字段节点。同时在 `index.css` 和 `print` 媒体查询中分别定义显示/隐藏样式。
3. **键盘删除增强**:重写 `keydown` 处理器,同时处理 `startContainer` 为 `TEXT_NODE` 和 `ELEMENT_NODE` 两种情况。当光标位于块级父节点的子节点边界时,通过 `el.childNodes[offset - 1]` 或 `el.childNodes[offset]` 定位字段节点并安全删除。
4. **报告批量操作**
- 在 `ReportManage.tsx` 中引入 `selectedIds` 状态,表格每行增加 Checkbox表头支持全选/反选。
- 增加浮动批量操作栏,支持"批量删除"、"批量导出 PDF"、"批量导出 JSON"、"取消选择"。
- 单报告操作列增加"导出"按钮,点击弹出模态框选择 PDF 或 JSON。
- PDF 导出复用现有的 `printDocument(content)`JSON 导出通过 `Blob` + `URL.createObjectURL` 实现下载,数据结构包含 `meta`(报告元信息)和 `fields`(所有 `DEFAULT_FORM_FIELDS` 对应值)。
- 批量 PDF 将多份报告的 HTML 用 `<div style="page-break-after: always;"></div>` 拼接后统一打印。
- 批量 JSON 将多份报告导出为数组形式的单个 `.json` 文件。
**D. 后续如何避免问题**
- 在 `contentEditable` 中插入的任何可复用控件,都应考虑增加唯一性校验和明确的删除入口(可视化按钮 + 键盘事件拦截)。
- 键盘事件处理不能假设 `startContainer` 一定是文本节点,必须覆盖块级元素边界的情况。
- 当列表页需要增加批量操作时,建议将"选择状态"和"批量动作"封装为独立逻辑,保持单条操作按钮的可维护性。
- 导出功能应尽量复用现有的 `printDocument` 等工具函数,减少新依赖引入。
---
## 记录 14智能字段插入间距修复与 Backspace 防误删
**A. 具体问题**