评论
评论功能允许用户在文档中添加评论和回复,便于团队成员之间的交流和协作。
预设模式
安装
pnpm add @univerjs/preset-sheets-thread-commentnpm install @univerjs/preset-sheets-thread-commentyarn add @univerjs/preset-sheets-thread-commentbun add @univerjs/preset-sheets-thread-comment使用
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreZhCN from '@univerjs/preset-sheets-core/locales/zh-CN'import { UniverSheetsThreadCommentPreset } from '@univerjs/preset-sheets-thread-comment'import UniverPresetSheetsThreadCommentZhCN from '@univerjs/preset-sheets-thread-comment/locales/zh-CN'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import '@univerjs/preset-sheets-core/lib/index.css'import '@univerjs/preset-sheets-thread-comment/lib/index.css'const { univerAPI } = createUniver({ locale: LocaleType.ZH_CN, locales: { [LocaleType.ZH_CN]: mergeLocales( UniverPresetSheetsCoreZhCN, UniverPresetSheetsThreadCommentZhCN, ), }, presets: [ UniverSheetsCorePreset(), UniverSheetsThreadCommentPreset(), ],})插件模式
安装
pnpm add @univerjs/thread-comment @univerjs/thread-comment-ui @univerjs/sheets-thread-comment @univerjs/sheets-thread-comment-uinpm install @univerjs/thread-comment @univerjs/thread-comment-ui @univerjs/sheets-thread-comment @univerjs/sheets-thread-comment-uiyarn add @univerjs/thread-comment @univerjs/thread-comment-ui @univerjs/sheets-thread-comment @univerjs/sheets-thread-comment-uibun add @univerjs/thread-comment @univerjs/thread-comment-ui @univerjs/sheets-thread-comment @univerjs/sheets-thread-comment-ui使用
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'import { UniverSheetsThreadCommentPlugin } from '@univerjs/sheets-thread-comment'import { UniverSheetsThreadCommentUIPlugin } from '@univerjs/sheets-thread-comment-ui'import SheetsThreadCommentUIZhCN from '@univerjs/sheets-thread-comment-ui/locale/zh-CN'import { UniverThreadCommentPlugin } from '@univerjs/thread-comment'import { UniverThreadCommentUIPlugin } from '@univerjs/thread-comment-ui'import ThreadCommentUIZhCN from '@univerjs/thread-comment-ui/locale/zh-CN'import '@univerjs/sheets-thread-comment-ui/lib/index.css'import '@univerjs/thread-comment-ui/lib/index.css'import '@univerjs/sheets-thread-comment/facade'const univer = new Univer({ locale: LocaleType.ZH_CN, locales: { [LocaleType.ZH_CN]: mergeLocales( ThreadCommentUIZhCN, SheetsThreadCommentUIZhCN, ), },})univer.registerPlugin(UniverThreadCommentPlugin)univer.registerPlugin(UniverThreadCommentUIPlugin)univer.registerPlugin(UniverSheetsThreadCommentPlugin)univer.registerPlugin(UniverSheetsThreadCommentUIPlugin)配合协同编辑使用
如使用协同编辑功能,需参照以下方式配置:
pnpm add @univerjs-pro/thread-comment-datasourcenpm install @univerjs-pro/thread-comment-datasourceyarn add @univerjs-pro/thread-comment-datasourcebun add @univerjs-pro/thread-comment-datasourceimport { UniverThreadCommentDataSourcePlugin } from '@univerjs-pro/thread-comment-datasource'univer.registerPlugin(UniverThreadCommentDataSourcePlugin)Facade API
完整 Facade API 类型定义,请查看 FacadeAPI
引入
插件模式提示
仅插件模式需要手动引入 Facade 包。预设模式已内置对应的 Facade 包,无需额外导入。
import '@univerjs/sheets-thread-comment/facade'创建单元格评论
univerAPI.newTheadComment() 创建一个新的评论构建器,返回一个 FTheadCommentBuilder 实例,可以通过链式调用生成评论。
以下是 FTheadCommentBuilder 上的一些成员方法:
| 方法 | 描述 |
|---|---|
| setContent | 设置评论的内容 |
| setPersonId | 设置评论的人员 id |
| setDateTime | 设置评论的日期时间 |
| setId | 设置评论的 id |
| setThreadId | 设置评论的主题 id |
// 创建一个新的评论const richText = univerAPI.newRichText().insertText('hello univer')const commentBuilder = univerAPI.newTheadComment() .setContent(richText)console.log(commentBuilder.content.toPlainText())// 添加评论到 A1 单元格const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const cell = fWorksheet.getRange('A1')const result = await cell.addCommentAsync(commentBuilder)获取单元格评论
可以通过以下方法获取评论,返回 FThreadComment 实例,可以进行评论的更新、删除、解决等操作。
FWorkbook.getComments(): 获取工作簿的所有评论FfWorksheet.getComments(): 获取工作表的所有评论FRange.getComment(): 获取范围左上角单元格的评论FRange.getComments(): 获取范围内所有单元格的评论
以下是 FThreadComment 上的一些成员方法:
| 方法 | 描述 |
|---|---|
| getIsRoot | 是否是根评论 |
| getCommentData | 获取评论数据 |
| getReplies | 获取评论的回复列表 |
| getRange | 获取评论的范围 |
| getRichText | 获取评论的富文本内容 |
| deleteAsync | 删除评论及其回复 |
| updateAsync | 更新评论内容 |
| resolveAsync | 解决评论 |
| replyAsync | 回复评论 |
// 获取工作簿的所有评论const fWorkbook = univerAPI.getActiveWorkbook()fWorkbook.getComments()// 获取活动工作表的所有评论const fWorksheet = fWorkbook.getActiveSheet()fWorksheet.getComments()const fRange = fWorksheet.getRange('A1:B2')// 获取 A1 单元格的评论fRange.getComment()// 获取 A1:B2 范围的所有评论fRange.getComments()清除单元格评论
FWorkbook.clearComments(): 清除工作簿的所有评论FWorksheet.clearComments(): 清除工作表的所有评论FRange.clearCommentAsync(): 清除范围左上角单元格的评论FRange.clearCommentsAsync(): 清除范围内所有单元格的评论
// 清除工作簿的所有评论const fWorkbook = univerAPI.getActiveWorkbook()await fWorkbook.clearComments()// 清除活动工作表的所有评论const fWorksheet = fWorkbook.getActiveSheet()await fWorksheet.clearComments()const fRange = fWorksheet.getRange('A1:B2')// 清除 A1 单元格的评论await fRange.clearCommentAsync()// 清除 A1:B2 范围的所有评论await fRange.clearCommentsAsync()获取评论回复列表
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// 获取工作表的所有评论const comments = fWorksheet.getComments()comments.forEach((comment) => { // 如果该评论是根评论,则获取其回复列表 if (comment.getIsRoot()) { const replies = comment.getReplies() replies.forEach((reply) => { console.log(reply.getCommentData()) }) }})更新/删除/解决/回复评论
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// 创建一个新的评论并添加到 A1 单元格const richText = univerAPI.newRichText().insertText('hello univer')const commentBuilder = univerAPI.newTheadComment() .setContent(richText) .setId('mock-comment-id')const cell = fWorksheet.getRange('A1')await cell.addCommentAsync(commentBuilder)// 3 秒后更新评论并回复setTimeout(async () => { // 更新评论 const comment = fWorksheet.getCommentById('mock-comment-id') const newRichText = univerAPI.newRichText().insertText('Hello Univer AI') await comment.updateAsync(newRichText) // 回复评论 const replyText = univerAPI.newRichText().insertText('Hello Univer AI! GO! GO! GO!') const reply = univerAPI.newTheadComment().setContent(replyText) await comment.replyAsync(reply)}, 3000)// 6 秒后解决评论并删除setTimeout(async () => { const comment = fWorksheet.getCommentById('mock-comment-id') await comment.resolveAsync() await comment.deleteAsync()}, 6000)事件监听
完整事件类型定义,请查看 Events。
评论模块提供了一系列事件用于监听评论的添加、更新、删除和解决状态变更。所有事件都可以通过 univerAPI.addEvent() 进行监听。
评论添加事件
univerAPI.Event.CommentAdded: 评论添加后触发
const disposable = univerAPI.addEvent(univerAPI.Event.CommentAdded, (params) => { const { comment, workbook, worksheet, row, col } = params})// 移除事件监听器,使用 `disposable.dispose()`univerAPI.Event.BeforeCommentAdd: 评论添加前触发
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentAdd, (params) => { const { comment, workbook, worksheet, row, col } = params // 取消评论添加操作 params.cancel = true})// 移除事件监听器,使用 `disposable.dispose()`评论更新事件
univerAPI.Event.CommentUpdated: 评论更新后触发
const disposable = univerAPI.addEvent(univerAPI.Event.CommentUpdated, (params) => { const { comment, workbook, worksheet, row, col } = params})// 移除事件监听器,使用 `disposable.dispose()`univerAPI.Event.BeforeCommentUpdate: 评论更新前触发
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentUpdate, (params) => { const { comment, workbook, worksheet, row, col, newContent } = params // 取消评论更新操作 params.cancel = true})// 移除事件监听器,使用 `disposable.dispose()`评论删除事件
univerAPI.Event.CommentDeleted: 评论删除后触发
const disposable = univerAPI.addEvent(univerAPI.Event.CommentDeleted, (params) => { const { commentId, workbook, worksheet } = params})// 移除事件监听器,使用 `disposable.dispose()`univerAPI.Event.BeforeCommentDelete: 评论删除前触发
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentDelete, (params) => { const { comment, workbook, worksheet, row, col } = params // 取消评论删除操作 params.cancel = true})// 移除事件监听器,使用 `disposable.dispose()`评论解决状态事件
univerAPI.Event.CommentResolved: 评论解决状态变更后触发
const disposable = univerAPI.addEvent(univerAPI.Event.CommentResolved, (params) => { const { comment, row, col, resolved, workbook, worksheet } = params})// 移除事件监听器,使用 `disposable.dispose()`univerAPI.Event.BeforeCommentResolve: 评论解决状态变更前触发
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentResolve, (params) => { const { comment, row, col, resolved, workbook, worksheet } = params // 取消评论解决操作 params.cancel = true})// 移除事件监听器,使用 `disposable.dispose()`每个事件都包含以下通用参数:
workbook: 当前工作簿实例worksheet: 当前工作表实例row: 评论所在的行索引col: 评论所在的列索引comment: 评论对象(删除后事件仅包含commentId)
特殊参数:
BeforeCommentUpdate事件包含newContent: 新的评论内容(RichTextValue 类型)CommentResolved和BeforeCommentResolve事件包含resolved: 评论的解决状态
所有 Before 前缀的事件回调函数都可以返回 params.cancel = true 来阻止对应的操作。
通用评论操作
调用前同时导入通用评论 Facade 和品类 Facade。品类方法负责建立稳定锚点,通用 API 用于回复、修改、解决和删除评论。getComments() 读取本地状态;listCommentsAsync() 通过已配置的数据源同步已知线程,不会发现服务端的全部线程。
import '@univerjs/thread-comment/facade'const [thread] = univerAPI.getComments({ resolved: false })if (thread) { await univerAPI.replyCommentAsync({ unitId: thread.unitId, subUnitId: thread.subUnitId, threadId: thread.threadId, content: 'Reviewed.', })}共享讨论
共享讨论需要先通过 Server SDK 集成 Comment Service 和 Endpoint,再在协同与许可证配置之后注册 @univerjs-pro/thread-comment-datasource 的 UniverThreadCommentDataSourcePlugin。内置数据源访问 /universer-api/comment/unit/{unitId}/... 和 /universer-api/user/list,请通过应用暴露这些路由。服务端需要独立验证评论读写权限,不能仅依赖文档编辑权限。
你觉得这篇文档如何?