diff --git a/README.md b/README.md
index 1d963d11..8be3104f 100644
--- a/README.md
+++ b/README.md
@@ -302,4 +302,8 @@ const mindMap = new MindMap({
皇登攀
+
+
+ 风格
+
diff --git a/web/src/assets/avatar/风格.jpg b/web/src/assets/avatar/风格.jpg
new file mode 100644
index 00000000..5536343f
Binary files /dev/null and b/web/src/assets/avatar/风格.jpg differ
diff --git a/web/src/pages/Doc/en/introduction/index.md b/web/src/pages/Doc/en/introduction/index.md
index 4f03fe3c..a43abaa5 100644
--- a/web/src/pages/Doc/en/introduction/index.md
+++ b/web/src/pages/Doc/en/introduction/index.md
@@ -331,4 +331,8 @@ Open source is not easy. If this project is helpful to you, you can invite the a
皇登攀
+
+

+
风格
+
\ No newline at end of file
diff --git a/web/src/pages/Doc/en/introduction/index.vue b/web/src/pages/Doc/en/introduction/index.vue
index d76202ca..d88a68d6 100644
--- a/web/src/pages/Doc/en/introduction/index.vue
+++ b/web/src/pages/Doc/en/introduction/index.vue
@@ -285,6 +285,10 @@ full screen, support mini map
皇登攀
+
+

+
风格
+
diff --git a/web/src/pages/Doc/zh/introduction/index.md b/web/src/pages/Doc/zh/introduction/index.md
index b07ace27..e774e18b 100644
--- a/web/src/pages/Doc/zh/introduction/index.md
+++ b/web/src/pages/Doc/zh/introduction/index.md
@@ -324,4 +324,8 @@
皇登攀
+
+

+
风格
+
\ No newline at end of file
diff --git a/web/src/pages/Doc/zh/introduction/index.vue b/web/src/pages/Doc/zh/introduction/index.vue
index 9489322a..de93c78c 100644
--- a/web/src/pages/Doc/zh/introduction/index.vue
+++ b/web/src/pages/Doc/zh/introduction/index.vue
@@ -279,6 +279,10 @@
皇登攀
+
+

+
风格
+
diff --git a/web/src/pages/Edit/components/Edit.vue b/web/src/pages/Edit/components/Edit.vue
index 70d49932..7f8605b1 100644
--- a/web/src/pages/Edit/components/Edit.vue
+++ b/web/src/pages/Edit/components/Edit.vue
@@ -46,7 +46,7 @@ import Painter from 'simple-mind-map/src/plugins/Painter.js'
import ScrollbarPlugin from 'simple-mind-map/src/plugins/Scrollbar.js'
import Formula from 'simple-mind-map/src/plugins/Formula.js'
// 协同编辑插件
-// import Cooperate from 'simple-mind-map/src/plugins/Cooperate.js'
+import Cooperate from 'simple-mind-map/src/plugins/Cooperate.js'
// 手绘风格插件,该插件为付费插件,详情请查看开发文档
// import HandDrawnLikeStyle from 'simple-mind-map-plugin-handdrawnlikestyle'
import OutlineSidebar from './OutlineSidebar'
@@ -82,6 +82,7 @@ import handleClipboardText from '@/utils/handleClipboardText'
import Scrollbar from './Scrollbar.vue'
import exampleData from 'simple-mind-map/example/exampleData'
import FormulaSidebar from './FormulaSidebar.vue'
+import { isSameObject } from 'simple-mind-map/src/utils';
// 注册插件
MindMap.usePlugin(MiniMap)
@@ -98,7 +99,11 @@ MindMap.usePlugin(MiniMap)
.usePlugin(SearchPlugin)
.usePlugin(Painter)
.usePlugin(Formula)
-// .usePlugin(Cooperate) // 协同插件
+.usePlugin(Cooperate) // 协同插件
+
+const request = (data) => {
+ console.log(data)
+}
// 注册自定义主题
customThemeList.forEach(item => {
@@ -305,7 +310,7 @@ export default {
this.mindMap = new MindMap({
el: this.$refs.mindMapContainer,
data: root,
- fit: false,
+ fit: true,
layout: layout,
theme: theme.template,
themeConfig: theme.config,
@@ -348,6 +353,150 @@ export default {
default:
break
}
+ },
+ onlyOneEnableActiveNodeOnCooperate: true,
+ beforeCooperateUpdate: ({ type, list, data }) => {
+ const { title, userINumber } = this.$route.meta
+ // 所有节点数据
+ const allData = data
+ // 创建或更新节点
+ if (type === 'createOrUpdate') {
+ // 获取节点的父节点的uid
+ const getParentUid = uid => {
+ let res = null
+ Object.keys(allData).forEach(item => {
+ if (allData[item].children.includes(uid)) {
+ res = allData[item].data
+ }
+ })
+ return res ? res.uid : ''
+ }
+ // 找出新创建的
+ const crateList = list
+ .filter(({ oldData }) => {
+ return !oldData
+ })
+ .map(({ uid }) => {
+ return uid
+ })
+ // 遍历所有创建或更新的节点列表
+ list.forEach(({ uid, data, oldData }) => {
+ // 更新版本号
+ if (data.data.version === undefined) {
+ data.data.version = 0
+ }
+ const newVersion = data.data.version + 1
+ data.data.version = newVersion
+ const targetNode = this.mindMap.renderer.findNodeByUid(uid)
+ if (targetNode) {
+ targetNode.setData({
+ version: newVersion
+ })
+ }
+ // 调接口
+ if (!oldData) {
+ // 新增节点
+ request({
+ url: `/addOneNode/${title}/${userINumber}`,
+ method: 'post',
+ data: {
+ parentNodeId: getParentUid(uid),
+ newNodeContent: JSON.stringify(data.data)
+ }
+ })
+ } else {
+ // 更新节点
+ const oldChildrenLength = oldData.children.length
+ const newChildrenLength = data.children.length
+ if (oldChildrenLength !== newChildrenLength) {
+ if (newChildrenLength > oldChildrenLength) {
+ const moveList = data.children.filter(item => {
+ return (
+ !oldData.children.includes(item) &&
+ !crateList.includes(item)
+ )
+ })
+ moveList.forEach(item => {
+ request({
+ url: `/changeNodeParentNode/${title}/${userINumber}`,
+ method: 'post',
+ data: {
+ movedNodeId: item,
+ newParentNodeId: uid
+ }
+ })
+ })
+ }
+ } else {
+ if (!isSameObject(data.data, oldData.data)) {
+ // 关联线
+ const associativeLineTargets =
+ data.data.associativeLineTargets || []
+ const oldDataAssociativeLineTargets =
+ oldData.data.associativeLineTargets || []
+ const newTargets = []
+ const deleteTargets = []
+ associativeLineTargets.forEach(item => {
+ if (!oldDataAssociativeLineTargets.includes(item)) {
+ newTargets.push(item)
+ }
+ })
+ oldDataAssociativeLineTargets.forEach(item => {
+ if (!associativeLineTargets.includes(item)) {
+ deleteTargets.push(item)
+ }
+ })
+ // 添加关联线
+ if (newTargets.length > 0) {
+ newTargets.forEach(item => {
+ request({
+ url: `/addAssociationLine/${title}/${userINumber}`,
+ method: 'post',
+ data: {
+ startNodeId: uid,
+ endNodeId: item
+ }
+ })
+ })
+ } else if (deleteTargets.length > 0) {
+ // 删除关联线
+ deleteTargets.forEach(item => {
+ request({
+ url: `/deleteAssociationLine/${title}/${userINumber}`,
+ method: 'post',
+ data: {
+ startNodeId: uid,
+ endNodeId: item
+ }
+ })
+ })
+ } else {
+ // 更新节点自身内容
+ request({
+ url: `/updateOneNodeContent/${title}/${userINumber}`,
+ method: 'post',
+ data: {
+ mindMapName: title,
+ nodeId: uid,
+ jsonContent: JSON.stringify(data.data)
+ }
+ })
+ }
+ }
+ }
+ }
+ })
+ } else if (type === 'delete') {
+ // 删除
+ const res = this.getTopIdList(list)
+ request({
+ url: `/deleteNodeList/${title}/${userINumber}`,
+ method: 'post',
+ data: {
+ idList: res
+ }
+ })
+ }
}
// beforeShortcutRun: (key, activeNodeList) => {
// console.log(key, activeNodeList)
@@ -478,6 +627,22 @@ export default {
// }, 5000)
},
+ // 获取被删除节点的顶层节点的uid列表
+ getTopIdList(list) {
+ const res = []
+ list.forEach((item) => {
+ const hasParent = list.find((item2) => {
+ return item2.data.children.includes(item.uid)
+ })
+ if (!hasParent) {
+ res.push(item)
+ }
+ })
+ return res.map((item) => {
+ return item.uid
+ })
+ },
+
// url中是否存在要打开的文件
hasFileURL() {
const fileURL = this.$route.query.fileURL
@@ -710,7 +875,7 @@ export default {
if (this.mindMap.cooperate && this.$route.query.userName) {
this.mindMap.cooperate.setProvider(null, {
roomName: 'demo-room',
- signalingList: ['ws://10.16.83.11:4444']
+ signalingList: ['ws://10.16.83.118:4444']
})
this.mindMap.cooperate.setUserInfo({
id: Math.random(),