# 历史记录

- Human documentation: [https://docs.univer.ai/zh-CN/guides/boards/features/edit-history](https://docs.univer.ai/zh-CN/guides/boards/features/edit-history)

- Agent Markdown: [https://docs.univer.ai/zh-CN/guides/boards/features/edit-history.md](https://docs.univer.ai/zh-CN/guides/boards/features/edit-history.md)

- Requested language: `zh-CN`

- Content language: `zh-CN`

- Documentation version: `1.0.0-rc.0`

- Source: [boards/features/edit-history.zh-CN.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/boards/features/edit-history.zh-CN.mdx)

---

#### Package metadata

```json
{
  "preset": [],
  "plugins": [
    {
      "client": "@univerjs-pro/edit-history",
      "facade": "@univerjs-pro/edit-history/facade"
    },
    {
      "client": "@univerjs-pro/edit-history-ui",
      "locale": "@univerjs-pro/edit-history-ui/locale/zh-CN",
      "style": "@univerjs-pro/edit-history-ui/lib/index.css"
    },
    {
      "client": "@univerjs-pro/boards-history"
    },
    {
      "client": "@univerjs-pro/boards-history-ui",
      "locale": "@univerjs-pro/boards-history-ui/locale/zh-CN",
      "style": "@univerjs-pro/boards-history-ui/lib/index.css"
    }
  ],
  "license": true,
  "server": true
}
```

例如，移动元素、修改文字或调整连线后，可以打开历史记录查看先前版本、比较变化，并在有权限时恢复版本。历史记录读取服务端保存的版本；当前页面的撤销、重做不需要历史服务，两者不能互相替代。

## 先准备协同和历史服务

先按[协同集成](https://docs.univer.ai/zh-CN/server/collaboration/browser-integration.md)连接编辑器，并完成[许可证配置](https://docs.univer.ai/zh-CN/guides/license.md)。确认两端能编辑同一份 Boards 文档，刷新后内容仍然保留。

然后按 [Office 协同扩展模块](https://docs.univer.ai/zh-CN/server/collaboration/extensions.md)和 [History 示例](https://docs.univer.ai/zh-CN/server/collaboration/examples.md#history)接入历史服务、存储和权限。核心协同不会自动启用历史记录；后端还需提供历史列表、版本内容和恢复操作所需的能力。

## 添加历史记录插件

在已有产品、许可证和协同插件配置中添加以下代码。若预设或现有配置已注册这些插件，修改原配置即可，不要重复注册。

#### npm

```bash
npm install @univerjs-pro/edit-history @univerjs-pro/edit-history-ui @univerjs-pro/boards-history @univerjs-pro/boards-history-ui
```

#### pnpm

```bash
pnpm add @univerjs-pro/edit-history @univerjs-pro/edit-history-ui @univerjs-pro/boards-history @univerjs-pro/boards-history-ui
```

#### yarn

```bash
yarn add @univerjs-pro/edit-history @univerjs-pro/edit-history-ui @univerjs-pro/boards-history @univerjs-pro/boards-history-ui
```

#### bun

```bash
bun add @univerjs-pro/edit-history @univerjs-pro/edit-history-ui @univerjs-pro/boards-history @univerjs-pro/boards-history-ui
```

```ts
import { UniverEditHistoryPlugin } from '@univerjs-pro/edit-history'
import EditHistoryLocale from '@univerjs-pro/edit-history-ui/locale/zh-CN'
import { UniverBoardsHistoryPlugin } from '@univerjs-pro/boards-history'
import { UniverBoardsHistoryUIPlugin } from '@univerjs-pro/boards-history-ui'
import HistoryLocale from '@univerjs-pro/boards-history-ui/locale/zh-CN'
import { LocaleType, mergeLocales } from '@univerjs/core'

import '@univerjs-pro/edit-history-ui/lib/index.css'
import '@univerjs-pro/boards-history-ui/lib/index.css'

const historyServerUrl = '/api/history'

univerAPI.loadLocales(LocaleType.ZH_CN, mergeLocales(EditHistoryLocale, HistoryLocale))
univer.registerPlugin(UniverEditHistoryPlugin, { historyServerUrl })
univer.registerPlugin(UniverBoardsHistoryPlugin)
univer.registerPlugin(UniverBoardsHistoryUIPlugin, {
  univerContainerId: 'app',
  historyServerUrl,
})
```

`/api/history` 是示例地址，请替换成应用实际提供的历史接口地址，并确保接口与客户端请求匹配。两个 `historyServerUrl` 保持一致，`univerContainerId` 与编辑器容器的 DOM ID 一致。语言资源应与编辑器当前语言一致。

历史查看器会创建独立的只读编辑器。如果文档包含自定义内容，通过 `viewerPlugins` 添加查看器尚未内置的插件；不要重复添加内置插件。

## 查看和恢复版本

从编辑器菜单打开历史记录，选择版本查看内容和变化。恢复版本会修改当前共享文档，应只向有恢复权限的用户开放，并由服务端再次检查权限。

接入后，移动元素、修改文字或调整连线，等待协同确认，再检查历史列表和版本内容。重新打开应用及重启服务后再次读取；恢复一个旧版本后，确认另一个浏览器会话也收到恢复结果。

如果面板为空，先检查历史服务是否记录了当前文档，以及请求中的文档 ID 和服务地址是否正确。版本能查看但无法恢复时，检查恢复权限和协同连接。历史版本可能包含后来删除的数据，读取历史也必须执行权限检查。

## 比较快照

如果需要构建审阅界面，或向 AI Agent 提供变更信息，可以调用 `compareUnitData()`，也可以用 `prepareUnitComparison()` 只计算一次并重复查询。先注册本品类的 History 插件并导入 Facade 入口，再将同一文档的两份完整快照作为 `beforeSnapshot` 和 `afterSnapshot` 传入。只读比较不需要历史服务，也不会恢复或合并内容。

```ts
import { UnitComparisonDetailLevel, UnitComparisonFidelity } from '@univerjs-pro/edit-history'
import { UniverInstanceType } from '@univerjs/core'

import '@univerjs-pro/edit-history/facade'

const comparison = univerAPI.prepareUnitComparison({
  comparisonId: 'review-1',
  unitId: beforeSnapshot.id,
  type: UniverInstanceType.UNIVER_BOARD,
  fidelity: UnitComparisonFidelity.SNAPSHOT,
  leftData: beforeSnapshot,
  rightData: afterSnapshot,
})
const overview = comparison.query({ detail: UnitComparisonDetailLevel.SUMMARY })
const scope = overview.scopes[0]
const page = comparison.query({ scope, offset: 0, limit: 100 })
console.log(page.items, page.page.hasMore, page.diagnostics)
```

通过 `scopes` 获取可用视图，再将选中的范围传给 `query()`，即可筛选结果而不重新计算差异。默认每页返回 100 项，最多 1,000 项；结合 `page.hasMore` 和 `offset` 获取后续内容。`summary` 始终描述整个比较，不随条目筛选变化。使用结果前检查 `diagnostics.readiness` 和 `diagnostics.codes`，避免将降级结果当作完整比较。无需编辑器的 Node.js 或 CLI 用法见[无界面比较 API](https://docs.univer.ai/zh-CN/reference/packages/plugins/univerjs-pro/edit-history.md#headless-comparison)。
