Home
Perfecto的头像

Perfecto

如何设计一个草稿功能

1. 概述

1.1 背景介绍

在复杂的报告编辑过程中,用户可能需要临时保存未完成的工作,以便后续继续编辑。报告中心草稿功能旨在解决这一需求,为用户提供自动保存和恢复编辑状态的能力,确保重要数据不会因意外中断而丢失。

1.2 功能目标

  • 自动保存用户编辑中的报告内容
  • 在用户重新进入编辑页面时恢复先前的编辑状态
  • 支持版本更新时的草稿数据迁移策略
  • 提供良好的用户体验,使保存过程对用户透明

2. 技术架构

2.1 整体架构

graph TD
    A[用户界面] --> B[草稿管理模块]
    B --> C[本地存储层]
    B --> D[远程数据同步]

    subgraph 草稿管理模块
    E[draft_mixin.js] --> F[草稿保存逻辑]
    E --> G[草稿加载逻辑]
    E --> H[版本管理]
    end

    subgraph 工具类
    I[draft_tool.ts] --> J[哈希版本管理]
    I --> K[存储接口]
    end

    H -.-> J
    F -.-> K
    G -.-> K

2.2 核心组件

  1. draft_mixin.js:提供草稿功能的核心混入组件
  2. draft_tool.ts:工具函数集,管理版本哈希和存储操作

3. 详细设计

3.1 数据存储结构

草稿数据存储在 localStorage 中,使用以下命名空间:

`${DRAFT_NAMESPACE}_${userInfo._id}`

数据结构如下:

interface DraftStorage {
  [templateID: string]: {
    formValue: object;          // 表单数据
    editorContent: any;         // 富文本编辑器内容
    pptReportData: object;      // PPT报告数据
    params: object;             // 请求参数
  }
}

3.2 版本管理机制

sequenceDiagram
    participant 用户
    participant 草稿模块
    participant 版本管理器
    participant 本地存储
    participant 服务端

    用户->>草稿模块: 初始化草稿功能
    草稿模块->>版本管理器: 获取本地存储的版本哈希
    版本管理器->>本地存储: 读取 DRAFT_VERSION
    本地存储-->>版本管理器: 返回存储的哈希值
    版本管理器->>服务端: 请求最新版本信息
    服务端-->>版本管理器: 返回当前系统版本

    alt 版本一致
        版本管理器-->>草稿模块: 版本一致,可以使用草稿
    else 版本不一致
        版本管理器->>本地存储: 更新版本哈希
        版本管理器->>本地存储: 清空旧版本草稿数据
        版本管理器-->>草稿模块: 版本已更新,草稿已重置
    end

3.3 草稿保存流程

flowchart TD
    A[用户编辑内容] --> B{是否单一导出模式?}
    B -->|是| C{草稿功能是否已启动?}
    B -->|否| H[不保存草稿]
    C -->|是| D[触发防抖保存]
    C -->|否| H
    D --> E{组件是否处于loading状态?}
    E -->|是| F[延迟5秒后重试]
    E -->|否| G[保存草稿到localStorage]
    F --> E
    G --> I[显示自动保存成功提示]
    G --> J[更新路由参数移除taskID]

3.4 防抖策略

为避免频繁存储操作,系统采用了两种防抖策略:

  1. 常规防抖:编辑操作后延迟 5 秒保存
this._draftMixin_debounceSave = debounce(this._beforeSave, 5000);
  1. 即时防抖:特定场景下需要快速保存时使用,延迟仅 50ms
this._draftMixin_immediateDebounceSave = debounce(this._beforeSave, 50);

3.5 草稿数据管理 API

方法名
功能描述
$_draftMixin_startDraft
开启草稿功能
$_draftMixin_initDraftStorage
初始化草稿存储,处理版本更新
$_draftMixin_debounceDraft
防抖保存草稿
$_draftMixin_immediateDraft
立即保存草稿
$_draftMixin_saveDraft
执行保存草稿操作
$_draftMixin_removeTemplateDraft
移除指定模板的草稿
$_draftMixin_getTemplateDraft
获取指定模板的草稿
$_draftMixin_emptyStorage
清空所有草稿

4. 用户体验设计

4.1 自动保存策略

系统采用以下场景触发自动保存:

  1. 用户编辑内容后自动延迟保存(5 秒后)
  2. 用户执行关键操作后立即保存(如切换 tab 等)
  3. 组件加载状态结束后保存(避免保存不完整数据)

4.2 用户通知机制

sequenceDiagram
    participant 用户
    participant 编辑器
    participant 草稿模块
    participant 存储系统

    用户->>编辑器: 编辑内容
    编辑器->>草稿模块: 触发变更事件
    草稿模块->>草稿模块: 防抖处理
    草稿模块->>存储系统: 保存草稿
    草稿模块->>用户: 显示轻量级保存成功提示
    Note over 用户,草稿模块: 提示1秒后自动消失

4.3 加载性能优化

为优化草稿加载性能,系统采取以下措施:

  1. 使用版本哈希缓存避免重复请求
  2. 仅在必要时清空草稿数据
  3. 优先采用本地存储提高访问速度

5. 版本兼容性

5.1 版本更新策略

系统通过以下步骤处理版本更新:

  1. 存储当前 UI 组件版本哈希作为草稿版本标识
  2. 系统更新后,比对新旧版本哈希
  3. 版本不一致时,清空草稿避免兼容性问题
graph TD
    A[获取存储的草稿版本哈希] --> B{存在哈希值?}
    B -->|是| C[获取当前系统版本哈希]
    B -->|否| G[设置新哈希并清空草稿]

    C --> D{哈希值一致?}
    D -->|是| E[保持草稿数据]
    D -->|否| F[版本已更新]
    F --> G

5.2 版本哈希生成

版本哈希基于多个 UI 组件版本组合生成:

const uiName = ['ui-base', 'ui-report', 'ui-efficiency'];
versionHash = uiName.map((name) => versionMap[name]).join('-');

6. 安全性考虑

6.1 数据隔离

  • 基于用户 ID 隔离不同用户的草稿数据
  • 基于模板 ID 隔离不同报告模板的草稿数据

6.2 存储限制

使用 localStorage 存在以下限制:

  • 每个域名下存储上限约为 5MB
  • 数据仅存储在本地,切换设备无法恢复

7. 未来优化方向

7.1 潜在改进点

  1. 远程存储支持:实现草稿数据云端同步,支持跨设备使用
  2. 增量保存机制:只保存变更部分,减少存储开销
  3. 草稿管理界面:提供用户可见的草稿列表和管理功能
  4. 冲突处理机制:解决多终端编辑的数据冲突问题

7.2 优化架构

graph TD
    A[用户界面层] --> B[草稿控制层]
    B --> C[本地存储适配器]
    B --> D[远程存储适配器]

    subgraph 存储策略
    C
    D
    end

    B --> E[版本控制模块]
    B --> F[冲突解决模块]

    G[用户偏好设置] --> B

8. 总结

报告中心草稿功能采用混入模式实现,通过 localStorage 提供自动保存能力。系统使用防抖策略避免频繁存储,通过版本哈希比对处理系统更新带来的兼容性问题。整体设计遵循轻量级、低感知的原则,为用户提供无缝的草稿保存体验。

该方案在复杂报告编辑场景下有效保护用户数据,未来可通过引入远程存储和增量同步进一步增强功能。

软件架构