协同编辑

GitHub在 GitHub 上编辑
预设信息
@univerjs/preset-docs-collaboration
需要服务端支持

注意事项

协同编辑功能需要 Univer 服务端支持,请确保你已经正确安装并配置了 Univer 服务端。具体请参考:升级 Pro

协同编辑功能允许多个用户同时编辑同一文档,实时同步更改,适用于团队协作和多人编辑场景。

预设模式

安装

@univerjs/preset-docs-collaboration 的 UniverDocsCollaborationPreset 预设在运行时依赖 UniverDocsDrawingPresetUniverDocsAdvancedPreset 预设,请先安装 @univerjs/preset-docs-drawing 和 @univerjs/preset-docs-advanced。

npm install @univerjs/preset-docs-drawing @univerjs/preset-docs-advanced @univerjs/preset-docs-collaboration

使用

import { UniverDocsAdvancedPreset } from '@univerjs/preset-docs-advanced'
import UniverPresetDocsAdvancedZhCN from '@univerjs/preset-docs-advanced/locales/zh-CN'
import { UniverDocsCollaborationPreset } from '@univerjs/preset-docs-collaboration'
import UniverPresetDocsCollaborationZhCN from '@univerjs/preset-docs-collaboration/locales/zh-CN'
import { UniverDocsCorePreset } from '@univerjs/preset-docs-core'
import UniverPresetDocsCoreZhCN from '@univerjs/preset-docs-core/locales/zh-CN'
import { UniverDocsDrawingPreset } from '@univerjs/preset-docs-drawing'
import UniverPresetDocsDrawingZhCN from '@univerjs/preset-docs-drawing/locales/zh-CN'
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'

import '@univerjs/presets/lib/styles/preset-docs-core.css'
import '@univerjs/preset-docs-drawing/lib/index.css'
import '@univerjs/preset-docs-advanced/lib/index.css'
import '@univerjs/preset-docs-collaboration/lib/index.css'

const { univerAPI } = createUniver({
  locale: LocaleType.ZH_CN,
  locales: {
    [LocaleType.ZH_CN]: mergeLocales(
      UniverPresetDocsCoreZhCN,
      UniverPresetDocsDrawingZhCN, 
      UniverPresetDocsAdvancedZhCN, 
      UniverPresetDocsCollaborationZhCN, 
    ),
  },
  collaboration: true, 
  presets: [
    UniverDocsCorePreset(),
    UniverDocsDrawingPreset({ 
      collaboration: true, 
    }), 
    UniverDocsAdvancedPreset({ 
      collaboration: true, 
    }), 
    UniverDocsCollaborationPreset({ 
      universerEndpoint: 'http://localhost:3010', 
    }), 
  ],
})

如果你拥有 Univer 的商业许可证,请参考在客户端使用许可证进行配置。

插件模式

安装

npm install @univerjs-pro/collaboration @univerjs-pro/collaboration-client @univerjs-pro/collaboration-client-ui

使用

import { UniverCollaborationPlugin } from '@univerjs-pro/collaboration'
import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client'
import { BrowserCollaborationSocketService, UniverCollaborationClientUIPlugin } from '@univerjs-pro/collaboration-client-ui'
import CollaborationClientZhCN from '@univerjs-pro/collaboration-client/locale/zh-CN'
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'

import '@univerjs-pro/collaboration-client/facade'
import '@univerjs-pro/collaboration-client-ui/facade'

import '@univerjs-pro/collaboration-client/lib/index.css'

const univer = new Univer({
  locale: LocaleType.ZH_CN,
  locales: {
    [LocaleType.ZH_CN]: mergeLocales(
      CollaborationClientZhCN, 
    ),
  },
})

// 通过将 override 选项设置为 [[IAuthzIoService, null]],可以告诉 Univer 不要注册内置的 IAuthzIoService。
// 通过将 override 选项设置为 [[IUndoRedoService, null]],可以告诉 Univer 不要注册内置的 IUndoRedoService
// 这样,Univer 将使用 UniverCollaborationPlugin 中提供的服务作为权限、重做恢复服务的实现。
const univer = new Univer({
  override: [ 
    [IAuthzIoService, null], 
    [IUndoRedoService, null], 
  ], 
})

univer.registerPlugin(UniverCollaborationPlugin) 
univer.registerPlugin(UniverCollaborationClientPlugin, { 
  socketService: BrowserCollaborationSocketService, 
  authzUrl: 'http://localhost:3010/universer-api/authz', 
  snapshotServerUrl: 'http://localhost:3010/universer-api/snapshot', 
  collabSubmitChangesetUrl: 'http://localhost:3010/universer-api/comb', 
  collabWebSocketUrl: 'ws://localhost:3010/universer-api/comb/connect', 
}) 
univer.registerPlugin(UniverCollaborationClientUIPlugin) 

如果你拥有 Univer 的商业许可证,请参考在客户端使用许可证进行配置。

协同文档数据

协同编辑插件依赖 Univer 服务,协同文档的数据存储在 Univer 服务中。

unitId

每篇协同文档在 Univer 服务中都有一个唯一的 unitId。Univer 协同客户端使用 unitId 可从 Univer 服务获取到对应的协同文档数据进行协同编辑。

type

type 是协同文档的类型,协同文档的类型决定了协同文档的初始数据结构。

创建协同文档

有多种方式在 Univer 服务中创建协同文档:

  • 通过创建文档接口可以创建一篇空白文档。
  • 通过导入插件提供的 FUniver.importDOCXToUnitIdAsync 方法,将 .docx 文件导入到 Univer 服务。

通过 URL 参数加载协同文档

@univerjs-pro/collaboration-client 插件内部提供了根据 URL 参数 unittype 自动加载对应的数据的功能,这可以简化一些场景下的数据加载逻辑。

如果你想使用该特性,你需要适当地修改一下原有的加载数据逻辑,并将 unittype 参数添加到 URL 中,如下所示:

import { UniverInstanceType } from '@univerjs/core'
// 预设模式下 `UniverInstanceType` 可从 @univerjs/presets 导入
import { UniverInstanceType } from '@univerjs/presets'

// 原有逻辑,只适用于非协同文档
univer.createUnit(UniverInstanceType.UNIVER_DOC, {}) 

// 修改后的逻辑,适用于协同文档
const url = new URL(window.location.href) 
const unit = url.searchParams.get('unit') 

if (unit) { 
  // 如果 URL 中包含 unit 参数,则自动加载数据
} else { 
  // 创建一个新的文档
  fetch(`/universer-api/snapshot/${UniverInstanceType.UNIVER_DOC}/unit/-/create`, { 
    method: 'POST', 
    headers: { 
      'Content-Type': 'application/json', 
    }, 
    body: JSON.stringify({ 
      type: UniverInstanceType.UNIVER_DOC, // instance type
      name: 'New Doc By Univer', // doc name
      creator: 'user', // creator name
    }), 
  }).then((response) => { 
    if (!response.ok) { 
      throw new Error('create unit failed') 
    } 
    return response.json() 
  }).then((data) => { 
    if (!data.unitID) { 
      throw new Error('create unit failed') 
    } 
    url.searchParams.set('unit', data.unitID) 
    url.searchParams.set('type', String(UniverInstanceType.UNIVER_DOC)) 
    window.location.href = url.toString() 
  }).catch((error) => { 
    console.error(error) 
  }) 
} 

Facade API

加载协同文档

如果你不想使用 URL 参数来加载协同文档,你也可以通过 Facade API 来加载协同文档。

const collaboration = univerAPI.getCollaboration()
const workbook = await collaboration.loadSheetAsync('your-unit-id')

拓展阅读

如果你想进一步了解协同编辑的工作原理,可以阅读以下文章:

你觉得这篇文档如何?