mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-17 22:08:25 +08:00
完善协同插件
This commit is contained in:
@@ -7,33 +7,70 @@ class Cooperate {
|
||||
constructor(opt) {
|
||||
this.opt = opt
|
||||
this.mindMap = opt.mindMap
|
||||
// yjs文档
|
||||
this.ydoc = new Y.Doc()
|
||||
this.ymap = this.ydoc.getMap()
|
||||
this.provider = new WebrtcProvider('demo-room', this.ydoc, {
|
||||
signaling: ['ws://10.16.83.11:4444']
|
||||
})
|
||||
this.awareness = this.provider.awareness
|
||||
this.currentData = null
|
||||
this.userInfo = null
|
||||
// 共享数据
|
||||
this.ymap = null
|
||||
// 连接提供者
|
||||
this.provider = null
|
||||
// 感知数据
|
||||
this.awareness = null
|
||||
this.currentAwarenessData = []
|
||||
|
||||
// 处理数据
|
||||
if (this.mindMap.opt.data) {
|
||||
this.currentData = this.transformTreeDataToObject(this.mindMap.opt.data)
|
||||
Object.keys(this.currentData).forEach(uid => {
|
||||
this.ymap.set(uid, this.currentData[uid])
|
||||
})
|
||||
}
|
||||
|
||||
// 当前的平级对象类型的思维导图数据
|
||||
this.currentData = null
|
||||
// 用户信息
|
||||
this.userInfo = null
|
||||
// 绑定事件
|
||||
this.bindEvent()
|
||||
// 处理实例化时传入的思维导图数据
|
||||
if (this.mindMap.opt.data) {
|
||||
this.initData(this.mindMap.opt.data)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化数据
|
||||
initData(data) {
|
||||
data = simpleDeepClone(data)
|
||||
// 解绑原来的数据
|
||||
if (this.ymap) {
|
||||
this.ymap.unobserve(this.onObserve)
|
||||
}
|
||||
// 创建共享数据
|
||||
this.ymap = this.ydoc.getMap()
|
||||
// 思维导图树结构转平级对象结构
|
||||
this.currentData = this.transformTreeDataToObject(data)
|
||||
// 将思维导图数据添加到共享数据中
|
||||
Object.keys(this.currentData).forEach(uid => {
|
||||
this.ymap.set(uid, this.currentData[uid])
|
||||
})
|
||||
// 监听数据同步
|
||||
this.onObserve = this.onObserve.bind(this)
|
||||
this.ymap.observe(this.onObserve)
|
||||
}
|
||||
|
||||
// 获取yjs doc实例
|
||||
getDoc() {
|
||||
return this.ydoc
|
||||
}
|
||||
|
||||
// 设置连接提供者
|
||||
setProvider(provider, webrtcProviderConfig = {}) {
|
||||
const { roomName, signalingList, ...otherConfig } = webrtcProviderConfig
|
||||
this.provider =
|
||||
provider ||
|
||||
new WebrtcProvider(roomName, this.ydoc, {
|
||||
signaling: signalingList,
|
||||
...otherConfig
|
||||
})
|
||||
this.awareness = this.provider.awareness
|
||||
|
||||
// 监听状态同步事件
|
||||
this.onAwareness = this.onAwareness.bind(this)
|
||||
this.awareness.on('change', this.onAwareness)
|
||||
}
|
||||
|
||||
// 绑定事件
|
||||
bindEvent() {
|
||||
// 监听数据同步
|
||||
this.onObserve = this.onObserve.bind(this)
|
||||
this.ymap.observe(this.onObserve)
|
||||
|
||||
// 监听思维导图改变
|
||||
this.onDataChange = this.onDataChange.bind(this)
|
||||
this.mindMap.on('data_change', this.onDataChange)
|
||||
@@ -42,31 +79,33 @@ class Cooperate {
|
||||
this.onNodeActive = this.onNodeActive.bind(this)
|
||||
this.mindMap.on('node_active', this.onNodeActive)
|
||||
|
||||
// 监听状态同步事件
|
||||
this.onAwareness = this.onAwareness.bind(this)
|
||||
this.awareness.on('change', this.onAwareness)
|
||||
// 监听设置思维导图数据事件
|
||||
this.initData = this.initData.bind(this)
|
||||
this.mindMap.on('set_data', this.initData)
|
||||
}
|
||||
|
||||
// 解绑事件
|
||||
unBindEvent() {
|
||||
this.ymap.unobserve(this.onObserve)
|
||||
if (this.ymap) {
|
||||
this.ymap.unobserve(this.onObserve)
|
||||
}
|
||||
this.mindMap.off('data_change', this.onDataChange)
|
||||
this.mindMap.off('node_active', this.onNodeActive)
|
||||
this.mindMap.off('set_data', this.initData)
|
||||
this.ydoc.destroy()
|
||||
}
|
||||
|
||||
// 数据同步时的处理,更新当前思维导图
|
||||
onObserve(event) {
|
||||
const data = event.target.toJSON()
|
||||
// 如果数据没有改变直接返回
|
||||
if (isSameObject(data, this.currentData)) return
|
||||
this.currentData = data
|
||||
// 平级对象转树结构
|
||||
const res = this.transformObjectToTreeData(data)
|
||||
if (!res) return
|
||||
if (this.mindMap.richText) {
|
||||
this.mindMap.renderer.renderTree =
|
||||
this.mindMap.richText.handleSetData(res)
|
||||
} else {
|
||||
this.mindMap.renderer.renderTree = res
|
||||
}
|
||||
// 更新思维导图画布
|
||||
this.mindMap.renderer.setData(res)
|
||||
this.mindMap.render()
|
||||
this.mindMap.command.addHistory()
|
||||
}
|
||||
@@ -77,16 +116,37 @@ class Cooperate {
|
||||
this.updateChanges(res)
|
||||
}
|
||||
|
||||
// 节点激活状态改变后触发状态显示同步
|
||||
// 找出更新点
|
||||
updateChanges(data) {
|
||||
const oldData = this.currentData
|
||||
this.currentData = data
|
||||
this.ydoc.transact(() => {
|
||||
// 找出新增的或修改的
|
||||
Object.keys(data).forEach(uid => {
|
||||
// 新增的或已经存在的,如果数据发生了改变
|
||||
if (!oldData[uid] || !isSameObject(oldData[uid], data[uid])) {
|
||||
this.ymap.set(uid, data[uid])
|
||||
}
|
||||
})
|
||||
// 找出删除的
|
||||
Object.keys(oldData).forEach(uid => {
|
||||
if (!data[uid]) {
|
||||
this.ymap.delete(uid)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 节点激活状态改变后触发感知数据同步
|
||||
onNodeActive(node, nodeList) {
|
||||
if (this.userInfo) {
|
||||
this.awareness.setLocalStateField(this.userInfo.name, {
|
||||
// 用户信息
|
||||
userInfo: {
|
||||
// 用户信息
|
||||
...this.userInfo
|
||||
},
|
||||
// 当前激活的节点id列表
|
||||
nodeIdList: nodeList.map(item => {
|
||||
// 当前激活的节点id列表
|
||||
return item.uid
|
||||
})
|
||||
})
|
||||
@@ -112,7 +172,7 @@ class Cooperate {
|
||||
this.userInfo = userInfo || null
|
||||
}
|
||||
|
||||
// 监听状态同步事件
|
||||
// 监听感知数据同步事件
|
||||
onAwareness() {
|
||||
const walk = (list, callback) => {
|
||||
list.forEach(value => {
|
||||
@@ -129,11 +189,11 @@ class Cooperate {
|
||||
})
|
||||
})
|
||||
}
|
||||
// 清除之前的状态
|
||||
// 清除之前的数据
|
||||
walk(this.currentAwarenessData, (node, userInfo) => {
|
||||
node.removeUser(userInfo)
|
||||
})
|
||||
// 设置当前状态
|
||||
// 设置当前数据
|
||||
const data = Array.from(this.awareness.getStates().values())
|
||||
this.currentAwarenessData = data
|
||||
walk(data, (node, userInfo) => {
|
||||
@@ -246,27 +306,6 @@ class Cooperate {
|
||||
return res
|
||||
}
|
||||
|
||||
// 找出更新点
|
||||
updateChanges(data) {
|
||||
const oldData = this.currentData
|
||||
this.currentData = data
|
||||
this.ydoc.transact(() => {
|
||||
// 找出新增的或修改的
|
||||
Object.keys(data).forEach(uid => {
|
||||
// 新增的或已经存在的,如果数据发生了改变
|
||||
if (!oldData[uid] || !isSameObject(oldData[uid], data[uid])) {
|
||||
this.ymap.set(uid, data[uid])
|
||||
}
|
||||
})
|
||||
// 找出删除的
|
||||
Object.keys(oldData).forEach(uid => {
|
||||
if (!data[uid]) {
|
||||
this.ymap.delete(uid)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 插件被移除前做的事情
|
||||
beforePluginRemove() {
|
||||
this.unBindEvent()
|
||||
|
||||
@@ -96,7 +96,7 @@ MindMap.usePlugin(MiniMap)
|
||||
.usePlugin(Painter)
|
||||
.usePlugin(ScrollbarPlugin)
|
||||
.usePlugin(Formula)
|
||||
.usePlugin(Cooperate)
|
||||
// .usePlugin(Cooperate)// 协同插件
|
||||
|
||||
// 注册自定义主题
|
||||
customThemeList.forEach(item => {
|
||||
@@ -389,16 +389,8 @@ export default {
|
||||
if (hasFileURL) {
|
||||
this.$bus.$emit('handle_file_url')
|
||||
}
|
||||
if (this.$route.query.userName) {
|
||||
this.mindMap.cooperate.setUserInfo({
|
||||
id: Math.random(),
|
||||
name: this.$route.query.userName,
|
||||
color: ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399'][
|
||||
Math.floor(Math.random() * 5)
|
||||
],
|
||||
avatar: Math.random() > 0.5 ? 'https://img0.baidu.com/it/u=4270674549,2416627993&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1696006800&t=4d32871d14a7224a4591d0c3c7a97311' : ''
|
||||
})
|
||||
}
|
||||
// 协同测试
|
||||
this.cooperateTest()
|
||||
},
|
||||
|
||||
// url中是否存在要打开的文件
|
||||
@@ -591,6 +583,24 @@ export default {
|
||||
// 动态删除指定节点
|
||||
// this.mindMap.execCommand('REMOVE_NODE', this.mindMap.renderer.root.children[0])
|
||||
}, 5000)
|
||||
},
|
||||
|
||||
// 协同测试
|
||||
cooperateTest() {
|
||||
if (this.mindMap.cooperate && this.$route.query.userName) {
|
||||
this.mindMap.cooperate.setProvider(null, {
|
||||
roomName: 'demo-room',
|
||||
signalingList: ['ws://192.168.3.125:4444']
|
||||
})
|
||||
this.mindMap.cooperate.setUserInfo({
|
||||
id: Math.random(),
|
||||
name: this.$route.query.userName,
|
||||
color: ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399'][
|
||||
Math.floor(Math.random() * 5)
|
||||
],
|
||||
avatar: Math.random() > 0.5 ? 'https://img0.baidu.com/it/u=4270674549,2416627993&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1696006800&t=4d32871d14a7224a4591d0c3c7a97311' : ''
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user