Комментарии
Комментарии позволяют пользователям оставлять в документах сообщения и ответы, упрощая общение и совместную работу в команде.
Режим плагинов
Установка
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 SheetsThreadCommentUIEnUS from '@univerjs/sheets-thread-comment-ui/locale/en-US'import { UniverThreadCommentPlugin } from '@univerjs/thread-comment'import { UniverThreadCommentUIPlugin } from '@univerjs/thread-comment-ui'import ThreadCommentUIEnUS from '@univerjs/thread-comment-ui/locale/en-US'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.EN_US, locales: { [LocaleType.EN_US]: mergeLocales( ThreadCommentUIEnUS, SheetsThreadCommentUIEnUS, ), },})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; не регистрируйте оба варианта.
| Пакет | Настольная регистрация | Мобильная регистрация |
|---|---|---|
@univerjs/sheets-thread-comment-ui | UniverSheetsThreadCommentUIPlugin | UniverSheetsThreadCommentMobileUIPlugin |
@univerjs/thread-comment-ui | UniverThreadCommentUIPlugin | UniverThreadCommentMobileUIPlugin |
Режим предустановок
Установка
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 UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsThreadCommentPreset } from '@univerjs/preset-sheets-thread-comment'import UniverPresetSheetsThreadCommentEnUS from '@univerjs/preset-sheets-thread-comment/locales/en-US'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.EN_US, locales: { [LocaleType.EN_US]: mergeLocales( UniverPresetSheetsCoreEnUS, UniverPresetSheetsThreadCommentEnUS, ), }, presets: [ UniverSheetsCorePreset(), UniverSheetsThreadCommentPreset(), ],})Facade API
Полные определения типов Facade API доступны в разделе FacadeAPI.
Импорт
Примечание о режиме плагинов
Вручную импортировать пакет Facade требуется только в режиме плагинов. В режиме предустановок соответствующий пакет Facade уже включён, поэтому дополнительный импорт не нужен.
import '@univerjs/sheets-thread-comment/facade'Создание комментария к ячейке
Создать новый конструктор комментария можно с помощью univerAPI.newTheadComment(), который возвращает экземпляр FTheadCommentBuilder. Методы можно вызывать цепочкой, задавая различные свойства комментария.
Ниже перечислены некоторые методы FTheadCommentBuilder:
| Метод | Описание |
|---|---|
| setContent | Задаёт содержимое комментария |
| setPersonId | Задаёт идентификатор автора комментария |
| setDateTime | Задаёт дату и время комментария |
| setId | Задаёт идентификатор комментария |
| setThreadId | Задаёт идентификатор ветки комментариев |
// Create a new commentconst richText = univerAPI.newRichText().insertText('hello univer')const commentBuilder = univerAPI.newTheadComment() .setContent(richText)console.log(commentBuilder.content.toPlainText())// Add the comment to cell A1const 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 | Отвечает на комментарий |
// Get all comments in the workbookconst fWorkbook = univerAPI.getActiveWorkbook()fWorkbook.getComments()// Get all comments in the active worksheetconst fWorksheet = fWorkbook.getActiveSheet()fWorksheet.getComments()const fRange = fWorksheet.getRange('A1:B2')// Get the comment of cell A1fRange.getComment()// Get all comments in the range A1:B2fRange.getComments()Очистка комментариев к ячейкам
FWorkbook.clearComments(): удалить все комментарии в книгеFWorksheet.clearComments(): удалить все комментарии на листеFRange.clearCommentAsync(): удалить комментарий верхней левой ячейки диапазонаFRange.clearCommentsAsync(): удалить все комментарии в диапазоне
// Clear all comments in the workbookconst fWorkbook = univerAPI.getActiveWorkbook()await fWorkbook.clearComments()// Clear all comments in the active worksheetconst fWorksheet = fWorkbook.getActiveSheet()await fWorksheet.clearComments()const fRange = fWorksheet.getRange('A1:B2')// Clear the comment of cell A1await fRange.clearCommentAsync()// Clear all comments in the range A1:B2await fRange.clearCommentsAsync()Получение списка ответов на комментарий
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Get all comments in the worksheetconst comments = fWorksheet.getComments()comments.forEach((comment) => { // If the comment is a root comment, get its replies if (comment.getIsRoot()) { const replies = comment.getReplies() replies.forEach((reply) => { console.log(reply.getCommentData()) }) }})Обновление, удаление, завершение и ответы на комментарии
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Create a new comment and add it to cell A1const 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)// Update the comment and reply after 3 secondssetTimeout(async () => { // Get the comment by ID and update its content const comment = fWorksheet.getCommentById('mock-comment-id') const newRichText = univerAPI.newRichText().insertText('Hello Univer AI') await comment.updateAsync(newRichText) // Create a new reply comment and set its content const replyText = univerAPI.newRichText().insertText('Hello Univer AI! GO! GO! GO!') const reply = univerAPI.newTheadComment().setContent(replyText) await comment.replyAsync(reply)}, 3000)// Resolve the comment and delete it after 6 secondssetTimeout(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})// Remove the event listener, use `disposable.dispose()`univerAPI.Event.BeforeCommentAdd: срабатывает перед добавлением комментария
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentAdd, (params) => { const { comment, workbook, worksheet, row, col } = params // Cancel the comment addition operation params.cancel = true})// Remove the event listener, use `disposable.dispose()`События обновления комментариев
univerAPI.Event.CommentUpdated: срабатывает после обновления комментария
const disposable = univerAPI.addEvent(univerAPI.Event.CommentUpdated, (params) => { const { comment, workbook, worksheet, row, col } = params})// Remove the event listener, use `disposable.dispose()`univerAPI.Event.BeforeCommentUpdate: срабатывает перед обновлением комментария
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentUpdate, (params) => { const { comment, workbook, worksheet, row, col, newContent } = params // Cancel the comment update operation params.cancel = true})// Remove the event listener, use `disposable.dispose()`События удаления комментариев
univerAPI.Event.CommentDeleted: срабатывает после удаления комментария
const disposable = univerAPI.addEvent(univerAPI.Event.CommentDeleted, (params) => { const { commentId, workbook, worksheet } = params})// Remove the event listener, use `disposable.dispose()`univerAPI.Event.BeforeCommentDelete: срабатывает перед удалением комментария
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentDelete, (params) => { const { comment, workbook, worksheet, row, col } = params // Cancel the comment deletion operation params.cancel = true})// Remove the event listener, use `disposable.dispose()`События изменения статуса комментария
univerAPI.Event.CommentResolved: срабатывает после изменения статуса комментария
const disposable = univerAPI.addEvent(univerAPI.Event.CommentResolved, (params) => { const { comment, row, col, resolved, workbook, worksheet } = params})// Remove the event listener, use `disposable.dispose()`univerAPI.Event.BeforeCommentResolve: срабатывает перед изменением статуса комментария
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentResolve, (params) => { const { comment, row, col, resolved, workbook, worksheet } = params // Cancel the comment resolution operation params.cancel = true})// Remove the event listener, use `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.', })}Общие обсуждения
Интегрируйте Comment Service и Endpoint через Server SDK, затем после настройки совместного редактирования и лицензии зарегистрируйте UniverThreadCommentDataSourcePlugin из @univerjs-pro/thread-comment-datasource. Источник использует /universer-api/comment/unit/{unitId}/... и /universer-api/user/list: предоставьте эти маршруты в приложении. Сервер должен отдельно проверять права на чтение и запись комментариев, не полагаясь на право редактирования документа.
Насколько полезно это руководство?