Skip to content

文档 API

文档模块提供文档的创建、编辑、版本控制、发布等功能。

接口列表

方法路径说明认证
POST/documents创建文档
GET/documents文档列表
GET/documents/search搜索文档
GET/documents/:docId文档详情
GET/documents/:docId/content文档内容/渲染树
PATCH/documents/:docId更新文档元数据
POST/documents/:docId/publish发布文档
POST/documents/:docId/move移动文档
DELETE/documents/:docId删除文档
GET/documents/:docId/revisions修订历史
GET/documents/:docId/diff版本对比
POST/documents/:docId/revert回滚到指定版本
POST/documents/:docId/snapshots创建快照
POST/documents/:docId/commit手动触发创建版本
GET/documents/:docId/pending-versions获取待创建版本数量

创建文档

接口: POST /api/v1/documents

说明: 创建新文档,系统会自动创建根块和初始版本

请求头:

Authorization: Bearer <your-access-token>
Content-Type: application/json

请求体:

json
{
  "workspaceId": "ws_1705123456789_abc123",
  "title": "我的第一篇文档",
  "icon": "📄",
  "cover": "https://example.com/cover.jpg",
  "visibility": "workspace",
  "parentId": null,
  "tags": ["tag_1234567890_abc123", "tag_1234567890_def456"],
  "category": "技术文档"
}

字段说明:

字段类型必填说明
workspaceIdstring工作空间ID
titlestring文档标题,1-255个字符
iconstring文档图标(emoji),最多10个字符
coverstring文档封面URL,最多500个字符
visibilitystring可见性:private(默认)、workspacepublic
parentIdstring父文档ID(用于文档树结构)
tagsstring[]标签ID列表(tagId数组),系统会自动校验标签是否存在并更新使用统计
categorystring分类,最多50个字符

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "workspaceId": "ws_1705123456789_abc123",
    "title": "我的第一篇文档",
    "icon": "📄",
    "rootBlockId": "b_1705123456789_root789",
    "head": 1,
    "publishedHead": 0,
    "status": "draft",
    "visibility": "workspace",
    "tags": ["tag_1234567890_abc123", "tag_1234567890_def456"],
    "category": "技术文档",
    "createdAt": "2024-01-15T10:30:00.000Z"
  }
}

重要说明:

  • 创建文档时会自动创建根块rootBlockId),无需手动创建
  • 创建文档时会自动创建初始版本head = 1
  • 如果指定了 parentId,父文档必须属于同一工作空间
  • 标签字段tags 字段应传入标签ID(tagId)数组,不是标签名称
    • 系统会自动校验标签ID是否存在,不存在会返回错误
    • 标签的 usageCount 会自动更新(+1)

状态码:

  • 201 Created - 创建成功
  • 400 Bad Request - 请求参数错误
  • 403 Forbidden - 没有权限访问工作空间

获取文档列表

接口: GET /api/v1/documents

说明: 获取文档列表,支持多种过滤条件

请求头:

Authorization: Bearer <your-access-token>

查询参数:

参数类型必填说明
workspaceIdstring工作空间ID(不传则查询有权限的所有空间)
statusstring文档状态:draftnormalarchived
visibilitystring可见性:privateworkspacepublic
parentIdstring父文档ID(用于查询子文档)
tagsstring[]标签ID过滤(tagId数组),查询包含指定标签的文档
categorystring分类过滤
sortBystring排序字段:updatedAt(默认)、createdAttitle
sortOrderstring排序顺序:DESC(默认)、ASC
pagenumber页码,默认 1
pageSizenumber每页数量,默认 20

响应示例:

json
{
  "success": true,
  "data": {
    "items": [
      {
        "docId": "doc_1705123456789_xyz456",
        "title": "我的第一篇文档",
        "icon": "📄",
        "status": "draft",
        "visibility": "workspace",
        "updatedAt": "2024-01-15T10:30:00.000Z"
      }
    ],
    "total": 1,
    "page": 1,
    "pageSize": 20
  }
}

状态码:

  • 200 OK - 获取成功

搜索文档

接口: GET /api/v1/documents/search

说明: 搜索文档,支持全文搜索

请求头:

Authorization: Bearer <your-access-token>

查询参数:

参数类型必填说明
querystring搜索关键词
workspaceIdstring工作空间ID
statusstring文档状态:draftnormalarchived
tagsstring[]标签ID过滤(tagId数组),搜索包含指定标签的文档
pagenumber页码,默认 1
pageSizenumber每页数量,默认 20

响应示例:

json
{
  "success": true,
  "data": {
    "items": [
      {
        "docId": "doc_1705123456789_xyz456",
        "title": "我的第一篇文档",
        "icon": "📄",
        "status": "draft",
        "updatedAt": "2024-01-15T10:30:00.000Z"
      }
    ],
    "total": 1,
    "page": 1,
    "pageSize": 20
  }
}

搜索说明:

  • 使用 PostgreSQL 的 tsvector 进行全文搜索
  • 搜索文档标题和内容
  • 支持中文搜索

状态码:

  • 200 OK - 搜索成功

获取文档详情

接口: GET /api/v1/documents/:docId

说明: 获取文档的详细信息

请求头:

Authorization: Bearer <your-access-token>

路径参数:

参数类型说明
docIdstring文档ID

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "workspaceId": "ws_1705123456789_abc123",
    "title": "我的第一篇文档",
    "icon": "📄",
    "cover": "https://example.com/cover.jpg",
    "rootBlockId": "b_1705123456789_root789",
    "head": 5,
    "publishedHead": 3,
    "status": "normal",
    "visibility": "workspace",
    "tags": ["tag_1234567890_abc123", "tag_1234567890_def456"],
    "category": "技术文档",
    "viewCount": 10,
    "favoriteCount": 2,
    "createdAt": "2024-01-15T10:30:00.000Z",
    "updatedAt": "2024-01-15T12:00:00.000Z"
  }
}

状态码:

  • 200 OK - 获取成功
  • 404 Not Found - 文档不存在
  • 403 Forbidden - 没有权限访问

获取文档内容

接口: GET /api/v1/documents/:docId/content

说明: 获取文档的内容树(渲染树),支持分页加载,适用于超大型文档

请求头:

Authorization: Bearer <your-access-token>

路径参数:

参数类型说明
docIdstring文档ID

查询参数:

参数类型必填说明
versionnumber文档版本号(不传则使用最新版本 head
maxDepthnumber最大层级深度(从根块开始计算,0=只返回根块,1=根块+第一层,默认返回所有层级)
startBlockIdstring起始块ID(用于分页,返回该块及其后续兄弟块)
limitnumber每页返回的最大块数量(默认1000,最大10000)

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "docVer": 5,
    "title": "我的第一篇文档",
    "tree": {
      "blockId": "b_1705123456789_root789",
      "type": "root",
      "payload": {
        "type": "root",
        "children": []
      },
      "parentId": "",
      "sortKey": "0",
      "indent": 0,
      "collapsed": false,
      "children": [
        {
          "blockId": "b_1705123456790_block001",
          "type": "paragraph",
          "payload": {
            "text": "这是第一段内容"
          },
          "parentId": "b_1705123456789_root789",
          "sortKey": "1000000",
          "indent": 0,
          "collapsed": false,
          "children": []
        }
      ]
    },
    "pagination": {
      "totalBlocks": 1500,
      "returnedBlocks": 1000,
      "hasMore": true,
      "nextStartBlockId": "b_1705123456800_block1000"
    }
  }
}

字段说明:

字段类型说明
treeobject文档内容树(根块及其子块)
pagination.totalBlocksnumber文档中的总块数
pagination.returnedBlocksnumber本次返回的块数量
pagination.hasMoreboolean是否还有更多块未返回
pagination.nextStartBlockIdstring下次请求的起始块ID(当 hasMore 为 true 时)

分页使用说明:

  • 按需加载:对于超大型文档,建议使用 maxDepthlimit 参数控制返回的数据量
  • 层级加载:使用 maxDepth=0 只获取根块,然后按需加载子块
  • 分页加载:当 hasMore=true 时,使用 nextStartBlockId 作为 startBlockId 参数继续获取后续内容
  • 性能优化:默认 limit=1000,可根据前端渲染能力调整(建议不超过5000)

使用示例:

typescript
// 1. 首次加载:只加载前2层,最多100个块
GET /api/v1/documents/doc_123/content?maxDepth=1&limit=100

// 2. 继续加载:从指定块开始加载后续内容
GET /api/v1/documents/doc_123/content?startBlockId=b_xxx&limit=100

// 3. 加载完整文档(不推荐用于超大型文档)
GET /api/v1/documents/doc_123/content

说明:

  • tree 包含根块及其子块的树形结构
  • 如果不指定 version,返回最新版本(head)的内容
  • 如果指定 version,返回该版本的内容(基于时间点计算)
  • 分页功能:系统针对超大型文档优化,支持按层级和数量分页,避免一次性返回过多数据

状态码:

  • 200 OK - 获取成功
  • 404 Not Found - 文档或版本不存在
  • 403 Forbidden - 没有权限访问

更新文档元数据

接口: PATCH /api/v1/documents/:docId

说明: 更新文档的标题、图标、标签等元数据。更新标签时会自动校验标签ID并更新使用统计。

请求头:

Authorization: Bearer <your-access-token>
Content-Type: application/json

路径参数:

参数类型说明
docIdstring文档ID

请求体:

json
{
  "title": "更新后的标题",
  "icon": "📝",
  "tags": ["tag_1234567890_abc123", "tag_1234567890_def456"],
  "visibility": "public"
}

字段说明:

字段类型必填说明
titlestring文档标题,1-255个字符
iconstring文档图标(emoji),最多10个字符
coverstring文档封面URL,最多500个字符
visibilitystring可见性:privateworkspacepublic
tagsstring[]标签ID列表(tagId数组),系统会自动校验标签是否存在并更新使用统计
categorystring分类,最多50个字符
statusstring文档状态:draftnormalarchived

权限要求: owner、admin 或 editor

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "title": "更新后的标题",
    "icon": "📝",
    ...
  }
}

状态码:

  • 200 OK - 更新成功
  • 404 Not Found - 文档不存在
  • 403 Forbidden - 没有权限

发布文档

接口: POST /api/v1/documents/:docId/publish

说明: 发布文档,将 publishedHead 设置为当前 head

请求头:

Authorization: Bearer <your-access-token>

路径参数:

参数类型说明
docIdstring文档ID

权限要求: owner、admin 或 editor

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "publishedHead": 5,
    "head": 5,
    ...
  }
}

说明:

  • 发布后,publishedHead 指向当前 head
  • 已发布的版本内容不会因后续编辑而改变
  • 可以通过 GET /documents/:docId/content?version=<publishedHead> 获取已发布版本

状态码:

  • 201 Created - 发布成功
  • 404 Not Found - 文档不存在
  • 403 Forbidden - 没有权限

移动文档

接口: POST /api/v1/documents/:docId/move

说明: 移动文档到新的位置(改变父文档或排序)

请求头:

Authorization: Bearer <your-access-token>
Content-Type: application/json

路径参数:

参数类型说明
docIdstring文档ID

请求体:

json
{
  "parentId": "doc_parent_123",
  "sortOrder": 1
}

字段说明:

字段类型必填说明
parentIdstring新的父文档ID(不传则移动到根目录)
sortOrdernumber新的排序顺序

权限要求: owner、admin 或 editor

限制:

  • 不能移动到自身或形成循环引用

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "parentId": "doc_parent_123",
    "sortOrder": 1,
    ...
  }
}

状态码:

  • 200 OK - 移动成功
  • 404 Not Found - 文档不存在
  • 403 Forbidden - 没有权限
  • 400 Bad Request - 移动操作无效(如循环引用)

删除文档

接口: DELETE /api/v1/documents/:docId

说明: 删除文档(软删除)

请求头:

Authorization: Bearer <your-access-token>

路径参数:

参数类型说明
docIdstring文档ID

权限要求: owner 或 admin

响应示例:

json
{
  "success": true,
  "data": {
    "message": "文档已删除"
  }
}

说明:

  • 删除是软删除,文档不会被物理删除
  • 删除文档会级联删除其所有子文档

状态码:

  • 200 OK - 删除成功
  • 404 Not Found - 文档不存在
  • 403 Forbidden - 没有权限

版本控制相关接口

获取修订历史

接口: GET /api/v1/documents/:docId/revisions

说明: 获取文档的版本修订历史

请求头:

Authorization: Bearer <your-access-token>

查询参数:

参数类型必填说明
pagenumber页码,默认 1
pageSizenumber每页数量,默认 20

响应示例:

json
{
  "success": true,
  "data": {
    "items": [
      {
        "revisionId": "doc_123@5",
        "docVer": 5,
        "message": "Document updated",
        "createdAt": "2024-01-15T12:00:00.000Z",
        "createdBy": "u_1705123456789_abc123"
      }
    ],
    "total": 5,
    "page": 1,
    "pageSize": 20
  }
}

版本对比 BUG

接口: GET /api/v1/documents/:docId/diff

说明: 对比两个版本之间的差异

请求头:

Authorization: Bearer <your-access-token>

查询参数:

参数类型必填说明
fromVernumber起始版本号
toVernumber目标版本号

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "fromVer": 3,
    "toVer": 5,
    "fromContent": { ... },
    "toContent": { ... }
  }
}

回滚到指定版本 BUG

接口: POST /api/v1/documents/:docId/revert

说明: 将文档回滚到指定版本

请求头:

Authorization: Bearer <your-access-token>
Content-Type: application/json

请求体:

json
{
  "version": 3
}

字段说明:

字段类型必填说明
versionnumber要回滚到的版本号

权限要求: owner、admin 或 editor

说明:

  • 回滚会创建新版本(head 递增),不会覆盖历史版本
  • 回滚后可以再次回滚到更早的版本

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "head": 6,
    ...
  }
}

创建快照 BUG

接口: POST /api/v1/documents/:docId/snapshots

说明: 创建文档快照,保存当前版本的完整块版本映射

请求头:

Authorization: Bearer <your-access-token>

权限要求: owner、admin 或 editor

响应示例:

json
{
  "success": true,
  "data": {
    "snapshotId": "doc_123@snap@5",
    "docId": "doc_1705123456789_xyz456",
    "docVer": 5,
    "blockVersionMap": {
      "b_root": 1,
      "b_block_001": 3,
      "b_block_002": 2
    },
    "createdAt": "2024-01-15T12:00:00.000Z"
  }
}

说明:

  • 快照是幂等的:如果已存在相同 docVer 的快照,直接返回
  • 快照保存的是当前 head 的完整状态,可用于快速恢复

手动触发创建版本

接口: POST /api/v1/documents/:docId/commit

说明: 手动触发创建文档版本,将所有待创建的操作合并为一个版本

请求头:

Authorization: Bearer <your-access-token>
Content-Type: application/json

请求体:

json
{
  "message": "完成编辑"
}

字段说明:

字段类型必填说明
messagestring版本消息,最多500个字符

权限要求: owner、admin 或 editor

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "version": 5,
    "pendingOperations": 3,
    "message": "完成编辑"
  }
}

说明:

  • 如果文档没有待创建的版本(pendingCount = 0),会返回 400 Bad Request
  • 创建的版本会包含所有待处理操作的数量信息
  • 创建版本后,待创建版本计数会被清除

状态码:

  • 200 OK - 版本创建成功
  • 400 Bad Request - 没有待创建的版本
  • 404 Not Found - 文档不存在
  • 403 Forbidden - 没有权限

获取待创建版本数量

接口: GET /api/v1/documents/:docId/pending-versions

说明: 查询文档当前有多少待创建的版本

请求头:

Authorization: Bearer <your-access-token>

响应示例:

json
{
  "success": true,
  "data": {
    "docId": "doc_1705123456789_xyz456",
    "pendingCount": 3,
    "hasPending": true
  }
}

字段说明:

字段类型说明
pendingCountnumber待创建版本的数量
hasPendingboolean是否有待创建的版本

状态码:

  • 200 OK - 获取成功
  • 404 Not Found - 文档不存在
  • 403 Forbidden - 没有权限访问

基于 NestJS 构建的个人知识库后端系统