1. 04. 文件编辑
石墨文档中台-开发文档
  • 1. 适用范围
  • 00. 概述
    • 石墨文档中台能做什么?
    • 三种典型的业务接入场景
    • 石墨文档中台支持哪些格式?
  • 01. 快速开始
    • 基本概念
    • 场景一:10 分钟创建预览文件
    • 场景二:10 分钟创建协同编辑文件
  • 02. 鉴权与安全
    • 整体概述
    • 签名凭证 Token
    • 签名凭证 Signature
  • 03. 文件预览
    • 整体概述
    • 如何预热预览缓存
    • 如何防盗链
    • 常见问题处理
  • 04. 文件编辑
    • 整体概述
    • 协同文档权限设计
    • 协同文件保存与更新机制
    • 协同文件复制与删除
  • 05. 文件导入导出
    • 整体概述
    • 常见问题处理
  • 06. 石墨前端 API
    • 整体概述
    • 公共 API
      • 公共处理方法
      • 顶部栏定制 HeaderBars
    • 编辑器 API
      • 轻文档
      • 传统文档
      • 表格
      • 幻灯片
      • 表单
      • 应用表格
  • 07. 石墨后端 API
    • 整体概述
    • 错误码说明
    • 文件-预览 API
      • 访问预览文件
      • 创建文件预览缓存
    • 文件-协同编辑文件管理 API
      • 访问协同编辑文件
      • 创建协同文件
      • 创建协同文件副本
      • 删除协同文件
    • 文件-导入导出 API
      • 文件导入
        • 文件导入说明
        • 创建导入任务
        • 获取导入进度
        • 创建导入任务(旧版)
        • 获取导入进度(旧版)
      • 文件导出
        • 文件导出流程
        • 创建导出任务
        • 获取导出进度
    • 文件-表格文件(Excel) API
      • 表格接口参数说明
      • 获取表格内容
      • 获取表格中的评论数
      • 更新表格内容
      • 追加表格内容
      • 删除表格行
      • 新增表格工作表
    • 文件-文稿文件(Word) API
      • 文稿书签说明
      • 读取文稿书签内容
      • 替换文稿书签内容
    • 文件-文档文件(类 Markdown) API
      • 获取文档中的评论列表
    • 文件-应用表格文件(多维表格)API
      • 应用表格列及单元格值结构
      • 应用表格接口调用规则
      • 获取数据表列表
      • 创建数据表
      • 获取字段列表
      • 创建字段
      • 更新字段
      • 删除字段
      • 新增行
      • 获取单行
      • 更新行
      • 删除行
    • 文件-获取额外信息 API
      • 获取文件的纯文本内容
      • 文件纯文本字数统计
      • 获取文件的历史列表
      • 获取文件的版本列表
      • 获取文件内容中所有的 @ 人信息列表
      • 还原文件历史版本
    • 系统管理 API
      • 应用管理
        • 获取应用详情
        • 更新应用回调地址
      • 用户席位管理
        • 用户席位状态说明
        • 获取用户列表和席位状态
        • 激活用户席位​
        • 取消用户席位​
        • 批量设置用户席位
    • 其他 API
      • 上报事件
      • 创建行为历史
      • 推送文件内全部的用户
      • 推送用户全部的 websocket 连接
    • 获取行列表
  • 08. 回调接口(你的应用需实现的接口)
    • 整体概述
    • 文件信息
      • 文件权限说明
      • [重要] 获取文件元信息-协同文档
      • [重要] 获取文件元信息-预览文档
      • 获取当前用户的文件列表
      • 获取文件的协作者列表
      • 获取接入方指定文件的完整访问地址
      • 获取文件元信息-协同文档自动任务(admin)
      • 根据指定用户获取文件元信息-协同文档(admin)
    • 用户信息
      • 批量获取用户信息(admin)
      • [重要] 获取当前用户信息
      • 获取当前用户所在团队信息
      • 获取指定用户信息
      • 获取用户水印信息
      • 获取用户部门路径
      • 批量获取用户信息
    • 团队和部门
      • 特殊部门 ID 说明
      • 获取团队下的成员列表
      • 获取部门信息
      • 获取部门的下级部门节点
      • 获取部门下的成员分页列表
    • 搜索功能
      • 获取与文件相关的用户列表
      • 获取与文件相关的文件列表
      • 按关键字搜索文件和用户列表
    • 事件推送
      • 整体概述
      • 评论(Comment)
        • 轻文档
          • 添加评论
          • 删除评论
          • 结束评论
          • 对于评论的回复评论
        • 表格
          • 添加评论
          • 删除评论
          • 结束评论
          • 对于评论的回复评论
        • 传统文档
          • 对于评论的回复评论
          • 添加评论
          • 更新评论
          • 删除评论
        • 幻灯片
          • 添加评论
          • 删除评论
          • 结束评论
          • 对于评论的回复评论
        • 应用表格
          • 添加评论
          • 对于评论的回复评论
          • 删除评论
      • 讨论(Discussion)
        • 轻文档
          • 发送讨论消息
      • 提及(MentionAt @ 人)
        • 轻文档
          • 在评论中 at
          • 在讨论中 at
          • 在正文中 at
        • 表格
          • 在评论中 at
          • 在正文中 at
        • 传统文档
          • 在评论中 at
          • 在正文中 at
        • 应用表格
          • 在评论中 at
          • 在正文中 at
      • 日期提醒 (DateMention)
        • 轻文档
          • 创建
          • 修改
          • 删除
        • 表格
          • 创建
          • 修改
          • 删除
        • 传统文档
          • 创建
          • 修改
          • 删除
      • 文件内容更新 (FileContent)
        • 文件内容更新
      • 文档协作者协同状态变化 (Collaborator)
        • 文档协作者协同状态变化
      • 文件版本 (Revision)
        • 版本
      • 系统事件 (System)
        • 系统事件
      • 回调请求错误(实验性)
        • 回调请求错误
  • 09. 核心模型
    • 你的应用如何设计应用(app)模型?
    • 你的应用如何设计文件数据模型?
    • 你的应用如何设计通讯录模型?
    • 你的应用系统如何设计文件权限模型?
  • 10. 典型场景方案
    • 云盘场景
    • IM 场景
    • 示例代码仓库
  • 11. 常见问题
    • 访问接口提示 Signature
    • 文件预览或导入报错
    • 首次接入 SDK 报错
    • 文档预览如何做防盗链
    • 复制粘贴、全屏操作不正常
    • 如何实现文档模板功能
    • 文档内容何时保存
    • 移动端不支持 blob 协议导致预览失败
    • 如何实现文件重命名
    • 如何通过接口修改文档内容
    • @人员时如何直接跳转至对应锚点
  1. 04. 文件编辑

协同文档权限设计

协同文档的权限由接入方在两个回调接口里返回 —— 当前用户回调确认"是谁",文件元信息回调告诉石墨"这个人对这篇文档能做什么"。石墨编辑器拿到这两份数据后才决定能否打开、能编辑哪些区域、能不能评论、复制、导出。本文系统讲清楚这套权限模型、字段含义、计算实现,以及调试方法。

一、权限模型总览#

协同文档权限不是文件本身的静态属性,而是一个 (用户, 文件) → 权限集合 的动态运算结果。每次用户打开文档,石墨都会向接入方发起两次回调,按当前实时业务规则取一次最新结果,再据此渲染编辑器。
四件事可以从这张图直接读出来:
权限不能在创建文档时永久写死。文件被分享、用户离职、审批撤回、文档归档之后,下次回调必须返回新结果。
权限计算只能放在回调里实时跑,不要在接入方侧缓存"上一次回调返回了什么"。
同一份文档不同用户拿到的 permissions 可能完全不同,回调里要按 X-Shimo-Token 解出的 uid 区分计算。
石墨编辑器信任接入方返回的权限值,无法替接入方做"用户是否真的有权操作"的校验。

二、回调接口与权限字段#

2.1 当前用户回调#

GET {endpoint_url}/users/current/info
Header: X-Shimo-Token: <前端传入的 token>
返回当前用户的身份信息:
{
  "id": "userid123",
  "name": "张三",
  "avatar": "https://example.com/user-123.png",
  "email": "user123@example.com",
  "teamGuid": "team_001"
}
身份决定权限计算的"主体"。如果 X-Shimo-Token 解出的 uid 和接入方业务库里的人对不上,所有权限字段都没意义。

2.2 文件元信息回调#

GET {endpoint_url}/files/{fileId}
Header: X-Shimo-Token: <前端传入的 token>
返回这个 fileId 下"当前用户"对应的权限集合:
{
  "id": "doc_38291",
  "name": "Q3 战略规划",
  "type": "documentPro",
  "permissions": {
    "readable": true,
    "editable": true,
    "commentable": true,
    "copyable": true,
    "exportable": true,
    "manageable": false,
    "copyablePasteClipboard": true,
    "attachmentCopyable": true,
    "cutable": true,
    "attachmentPreviewable": true,
    "attachmentDownloadable": true,
    "imageDownloadable": true
  },
  "creatorId": "userid123",
  "createdAt": "2026-04-01T08:00:00Z",
  "updatedAt": "2026-04-02T09:30:00Z",
  "teamGuid": "team_001"
}

2.3 权限字段全表#

字段必填默认值含义影响
readable是—能否打开文档false 时编辑器拒绝加载
editable是—能否编辑正文false 时编辑器进入只读模式
commentable是—能否评论 / 回复控制评论区开关
copyable是—能否复制文档内容false 时禁用复制 / 剪切
exportable是—能否导出文档控制导出菜单
manageable是—是否为管理者见下文管理者权限说明
copyablePasteClipboard否true能否把内容粘贴到文档外只有 copyable: true 时才会生效
attachmentCopyable否true能否复制附件—
cutable否true能否剪切内容—
attachmentPreviewable否true能否预览附件—
attachmentDownloadable否true能否下载附件—
imageDownloadable否true能否下载图片—
前 6 个字段必填,缺一个就会出现石墨拒绝加载或权限错误的兜底逻辑;后 6 个是高级权限,不传默认 true,只在需要细粒度限制时显式返回 false。
manageable: true 的影响范围(来自官方文档):
调用石墨"删除文件"接口时必须为 true。
表格锁定操作里被识别为管理者。
更新 / 删除他人创建的版本时必须为 true。
表格导出时,true 才能导出锁定内容。
建议至少把文件创建者标记为 manageable: true。

三、字段之间的依赖关系#

权限字段之间不是完全独立的 —— 有些字段在逻辑上必然依赖另一些字段。下图把所有依赖关系画出来,箭头表示"被依赖"方向(A → B 意为 "B 需要 A 为 true 才能为 true")。
可以直接落到代码里的规则:
editable = true 时 copyable 必须为 true(官方明确约束)。可以编辑就必然可以读到内容,禁止复制没有实际意义。
readable = false 时其它字段全部应当为 false,没必要也不应该给"看不到的人"任何子权限。
copyablePasteClipboard = true 前提是 copyable = true。否则石墨会忽略这个高级权限。
manageable 与其它字段在逻辑上独立 —— 管理者不必然可读,可读者也不必然是管理者;但实践中"非可读用户却是管理者"几乎不会出现。

四、典型权限组合#

按业务侧的角色或状态,回调可以直接套用下面这五种模板:
角色 / 状态readableeditablecommentablecopyableexportablemanageable
文档所有者 / 管理员truetruetruetruetruetrue
普通编辑者truetruetruetruetruefalse
评论者(只读 + 评论)truefalsetruetruetruefalse
只读用户truefalsefalsetruetruefalse
无权访问 / 被拒绝falsefalsefalsefalsefalsefalse
实际业务里常见的扩展模板:
审批中:通常退化为"只读用户",并在业务侧弹窗提示"审批通过后可编辑"。
文档已归档 / 已删除:返回"无权访问",让编辑器直接拒绝加载。
离职用户访问:同上。
外发分享给企业外用户:基于"只读 + 关闭导出 + 关闭复制粘贴外发" → readable: true, editable: false, copyable: false, exportable: false, copyablePasteClipboard: false。

五、权限计算的实现建议#

权限计算只能放在元信息回调里按请求实时跑。下面这段伪代码涵盖了大多数业务侧需要考虑的输入维度:
四件事要注意:
绝不要在创建文档时把权限快照写到表里再原样返回,权限永远从源头实时算。
不要缓存这个计算的结果。即使为了性能想加缓存,TTL 也要小于 30 秒,并且当业务侧权限变化时主动失效。
强制约束兜底(步骤 3)要放在返回前的最后一步,避免上游 bug 让返回值违反官方约束。
创建者识别要稳定。creatorId 不要写成"当前登录用户",应该写文件的真正创建者,否则换人打开后 manageable 行为会乱。

六、权限变更如何传到编辑器#

业务侧改了权限之后,石墨编辑器并不会主动感知 —— 它只在用户下一次打开文档时通过回调拉到新权限。这条传播路径是:
接入方需要在业务层面处理"权限刚被回收但用户还在编辑"这个窗口。常用兜底有三种:
1.
依赖石墨的协同会话失效机制。用户被踢出 / 文档被删除时,石墨会断开 WebSocket 会话;接入方在业务侧补一条"主动调用石墨删除接口"。
2.
业务侧推送 + 引导刷新。改权限后通过站内信、消息中心提示在线用户刷新页面。
3.
保存校验。即使编辑器允许编辑,业务侧的保存事件接收端也应该再做一次权限校验,避免"前端 UI 允许编辑但保存被拒"留下脏数据。

七、常见误区#

误区实际影响正确做法
创建文档时把权限写死、回调时原样返回权限变化失效回调里实时按业务规则算
editable: true 但 copyable: false违反官方约束,行为未定义始终保证 editable → copyable
用文件创建者作为"管理者",但 creatorId 字段填了打开者任何人都成了管理者creatorId 必须是真正创建者
不区分用户:所有人返回同一份 permissions越权 / 误授权必须基于 X-Shimo-Token 解出的 uid 区分计算
把高级权限当必填字段返回 false文档功能被无意关闭不需要限制时不传,让石墨用默认 true
业务库权限改了,但元信息回调里读的是冷缓存用户看到的还是旧权限回调直接读源数据;缓存 TTL ≤ 30s 或主动失效
协同文档元信息回调和预览文档共用 URL 但没按 type 区分协同文档退化为预览,缺字段按 type 分发两套返回结构

八、调试 checklist#

按这套流程基本能定位 95% 的权限问题:
准备三个测试用户:所有者、编辑者、只读 / 评论者
三个用户分别打开同一个 fileId,记录回调入参(X-Shimo-Token)和回调返回的 permissions 全量
比对每个用户的 permissions 是否与业务期望一致
修改某个用户的业务权限,让该用户关闭并重新打开文档,再次记录回调返回
验证 editable: true ↔ copyable: true 始终成立
验证业务里的"审批中 / 已归档 / 离职"等状态会触发正确的权限退化
验证creatorId 在所有用户视角下都指向同一个真实创建者
用 curl 直接调一次回调接口(带正确的 X-Shimo-Token),确认它对石墨服务端公网可达且返回 200
检查日志里同一个 fileId 的多次回调是否走的同一份计算逻辑(防止线上有冷缓存绕开)

九、与相关文档的关系#

关注点文档
协同编辑接入完整流程协同编辑接入完整流程
文件元信息字段全量定义获取文件元信息-协同文档
当前用户信息字段定义获取当前用户信息
Token 透传与解析签名凭证-Token
接入排查思路文件预览失败排查指南(链路通用)

十、小结#

协同文档权限的本质就两句话:
权限是 (用户, 文件) 的动态运算,永远在回调里实时算,永远不要写死。
石墨完全信任接入方返回的 permissions,所以接入方既要算对、又要算稳、还要给保存事件再做一次校验作为底线。
字段层面记住三条强制约束 —— editable → copyable、!readable ⇒ 全 false、copyablePasteClipboard ≤ copyable —— 其余按业务规则展开就行。
修改于 2026-06-22 02:43:30
上一页
整体概述
下一页
协同文件保存与更新机制
Built with