版本控制
Payload 强大的 Versions 功能允许你保留随时间变化的完整历史记录,并可扩展以适应任何内容发布工作流。
启用后,Payload 会自动在你的数据库中创建一个新的 Collection 来存储文档的版本历史。Admin UI 会扩展额外的视图,让你可以浏览文档版本、查看差异(了解文档具体发生了哪些变化以及何时发生变化),并轻松将文档恢复到之前的版本。
比较文档的旧版本与新版本
使用 Versions 功能,你可以:
- 维护文档所有更改的审计日志/历史记录,包括监控哪个用户做了哪些更改
- 在需要回滚更改时,将文档和 globals 恢复到之前的状态
- 为你的数据构建真正的 Draft Preview 模式
- 通过 Access Control 管理谁可以查看草稿,谁只能查看已发布的文档
- 在 collections 和 globals 上启用 Autosave 功能,避免工作丢失
- 构建强大的发布计划机制,创建文档并在未来指定日期自动公开发布
Versions 功能性能极高且完全可选。它不会改变你的数据结构。所有版本都存储在一个单独的 Collection 中,可以根据需要轻松开启或关闭。
选项
Versions 支持几种不同级别的功能,每种功能都会对文档工作流产生不同的影响。
启用版本控制但禁用草稿模式
如果你启用了版本控制但保持草稿模式禁用状态,Payload 会在每次更新文档时简单地创建一个新版本。这种方式非常适合需要保留文档所有更新历史记录,但始终希望将最新版本视为"已发布"版本的用例。
例如,"启用版本控制但禁用草稿模式"的用例可以应用在用户集合上,你可能想要保留用户所有更改的版本历史(或审计日志)——但对用户的任何更改都应始终被视为"已发布",并且你不需要维护用户的"草稿"版本。
同时启用版本控制和草稿模式
如果你同时启用了版本控制和草稿模式,你将能够控制哪些文档是已发布的,哪些被视为草稿。这让你可以编写访问控制来管理谁可以查看已发布文档,谁可以查看草稿文档。它还允许你保存比最近发布文档更新的版本(草稿),这在你想起草更改甚至可能在发布更改前预览它们时非常有用。了解更多关于草稿模式的信息请点击这里。
同时启用版本控制、草稿模式和自动保存
当你同时启用版本控制、草稿模式和autosave
功能时,Admin UI 会在你编辑文档时自动将更改保存到新的draft
版本中,这确保了你永远不会丢失任何更改。自动保存完全不会影响你已发布的文章——它只会保存你的更改,并让你或你的编辑在准备好时发布它们。了解更多关于自动保存的信息请点击这里。
集合配置
配置版本功能是通过在集合配置中添加 versions
键来实现的。将其设置为 true
可启用默认版本设置,或通过将该属性设置为包含以下可用选项的对象来自定义版本功能:
选项 | 描述 |
---|---|
maxPerDoc | 使用此设置控制每个文档保留的版本数量。必须为整数。默认为 100,设置为 0 可保存所有版本。 |
drafts | 为此集合启用草稿模式。设置为 true 或传递包含草稿选项的对象来启用。 |
全局配置
全局版本功能与集合版本功能类似,但支持的配置属性略有不同。
选项 | 描述 |
---|---|
max | 使用此设置控制每个全局保留的版本数量。必须为整数。 |
drafts | 为此全局启用草稿模式。设置为 true 或传递包含草稿选项的对象来启用。 |
数据库影响
启用 versions
后,系统会创建一个新的数据库集合来存储你的 collection 或 global 的版本。该集合的命名基于 collection 或 global 的 slug
,并遵循以下模式(其中 slug
会被替换为你的 collection 或 global 的 slug
):
_slug_versions
在这个新的 versions
集合中,每个文档都会存储关于版本的元数据属性以及文档的完整副本。例如,一个 Collection 文档的版本数据可能如下所示:
{
"_id": "61cf752c19cdf1b1af7b61f1", // 该版本的唯一 ID
"parent": "61ce1354091d5b3ffc20ea6e", // 父文档的 ID
"autosave": false, // 标记该版本是否通过自动保存创建
"version": {
// 你的文档数据放在这里
// 所有字段都不必是必填的,这个属性可以是部分完成的
},
"createdAt": "2021-12-31T21:25:00.992+00:00",
"updatedAt": "2021-12-31T21:25:00.992+00:00"
}
Global 版本的存储方式与上面展示的 collection 版本相同,只是不包含 parent
属性,因为每个 Global 都有自己的 versions
集合。这意味着我们知道该集合中的所有版本都对应于该特定的 global。
版本操作
版本功能为 collections 和 globals 都提供了新的操作。它们允许你查找和查询版本、通过 ID 查找单个版本,以及通过 ID 发布(或恢复)版本。Collections 和 Globals 都支持相同的新操作。这些操作主要由 admin UI 使用,但如果你在应用中编写自定义逻辑并希望使用它们,也可以通过 REST、GraphQL 和 Local API 来使用这些操作。
Collection REST 端点:
Method | Path | 描述 |
---|---|---|
GET | /api/{collectionSlug}/versions | 查询分页版本 |
GET | /api/{collectionSlug}/versions/:id | 根据 ID 查询特定版本 |
POST | /api/{collectionSlug}/versions/:id | 根据 ID 恢复版本 |
Collection GraphQL 查询:
查询名称 | 操作类型 |
---|---|
version{collection.label.singular} | findVersionByID |
versions{collection.label.plural} | findVersions |
以及变更操作:
查询名称 | 操作类型 |
---|---|
restoreVersion{collection.label.singular} | restoreVersion |
Collection 本地 API 方法:
查询
// 结果将是一个分页的版本集合。
// 更多信息请参阅 /docs/queries/pagination
const result = await payload.findVersions({
collection: 'posts', // 必填
depth: 2,
page: 1,
limit: 10,
where: {}, // 可在此处传递 `where` 查询条件
sort: '-createdAt',
locale: 'en',
fallbackLocale: false,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
根据 ID 查询
// 结果将是一个 Post 文档。
const result = await payload.findVersionByID({
collection: 'posts', // 必填
id: '507f1f77bcf86cd799439013', // 必填
depth: 2,
locale: 'en',
fallbackLocale: false,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
恢复
// 结果将是恢复后的全局文档。
const result = await payload.restoreVersion({
collection: 'posts', // 必填
id: '507f1f77bcf86cd799439013', // 必填
depth: 2,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
全局 REST 端点:
方法 | 路径 | 描述 |
---|---|---|
GET | /api/globals/{globalSlug}/versions | 查找并查询分页版本 |
GET | /api/globals/{globalSlug}/versions/:id | 通过 ID 查找特定版本 |
POST | /api/globals/{globalSlug}/versions/:id | 通过 ID 恢复版本 |
全局 GraphQL 查询:
查询名称 | 操作 |
---|---|
version{global.label} | findVersionByID |
versions{global.label} | findVersions |
全局 GraphQL 变更:
查询名称 | 操作 |
---|---|
restoreVersion{global.label} | restoreVersion |
全局本地 API 方法:
查找
// 结果将是分页的版本集合。
// 更多信息请参阅 /docs/queries/pagination。
const result = await payload.findGlobalVersions({
slug: 'header', // 必填
depth: 2,
page: 1,
limit: 10,
where: {}, // 在此传递 `where` 查询
sort: '-createdAt',
locale: 'en',
fallbackLocale: false,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
通过 ID 查找
// 结果将是一个 Post 文档。
const result = await payload.findGlobalVersionByID({
slug: 'header', // 必填
id: '507f1f77bcf86cd799439013', // 必填
depth: 2,
locale: 'en',
fallbackLocale: false,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
恢复版本
// Result will be the restored global document.
const result = await payload.restoreGlobalVersion({
slug: 'header', // required
id: '507f1f77bcf86cd799439013', // required
depth: 2,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
访问控制
版本功能在 Collections 和 Globals 上都暴露了一个新的 Access Control 函数,允许你控制谁可以查看文档版本,谁不能查看。
函数 | 允许/拒绝访问 |
---|---|
readVersions | 用于控制谁可以读取版本,谁不能读取。将自动限制 Admin UI 中的版本查看权限。 |
有关如何将访问控制与版本功能结合使用的完整详情,请参阅 Access Control 文档。