Demo:支持节点链接开发中
This commit is contained in:
parent
0f9ae45784
commit
697cee0b46
@ -205,7 +205,8 @@ export const nodeDataNoStylePropList = [
|
|||||||
'checkbox',
|
'checkbox',
|
||||||
'dir',
|
'dir',
|
||||||
'needUpdate', // 重新创建节点内容
|
'needUpdate', // 重新创建节点内容
|
||||||
'imgMap'
|
'imgMap',
|
||||||
|
'nodeLink'
|
||||||
]
|
]
|
||||||
|
|
||||||
// 错误类型
|
// 错误类型
|
||||||
|
|||||||
@ -134,6 +134,9 @@
|
|||||||
<div class="item" @click="exec('REMOVE_NOTE')" v-if="hasNote">
|
<div class="item" @click="exec('REMOVE_NOTE')" v-if="hasNote">
|
||||||
<span class="name">{{ $t('contextmenu.removeNote') }}</span>
|
<span class="name">{{ $t('contextmenu.removeNote') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="item" @click="exec('LINK_NODE')">
|
||||||
|
<span class="name">链接到指定节点</span>
|
||||||
|
</div>
|
||||||
<div class="item" @click="exec('REMOVE_CUSTOM_STYLES')">
|
<div class="item" @click="exec('REMOVE_CUSTOM_STYLES')">
|
||||||
<span class="name">{{ $t('contextmenu.removeCustomStyles') }}</span>
|
<span class="name">{{ $t('contextmenu.removeCustomStyles') }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -478,6 +481,10 @@ export default {
|
|||||||
case 'REMOVE_NOTE':
|
case 'REMOVE_NOTE':
|
||||||
this.node.setNote('')
|
this.node.setNote('')
|
||||||
break
|
break
|
||||||
|
case 'LINK_NODE':
|
||||||
|
this.$bus.$emit('show_link_node', this.node)
|
||||||
|
this.hide()
|
||||||
|
break
|
||||||
case 'EXPORT_CUR_NODE_TO_PNG':
|
case 'EXPORT_CUR_NODE_TO_PNG':
|
||||||
this.mindMap.export(
|
this.mindMap.export(
|
||||||
'png',
|
'png',
|
||||||
|
|||||||
@ -54,6 +54,10 @@
|
|||||||
<NodeNoteSidebar v-if="mindMap" :mindMap="mindMap"></NodeNoteSidebar>
|
<NodeNoteSidebar v-if="mindMap" :mindMap="mindMap"></NodeNoteSidebar>
|
||||||
<AiCreate v-if="mindMap && enableAi" :mindMap="mindMap"></AiCreate>
|
<AiCreate v-if="mindMap && enableAi" :mindMap="mindMap"></AiCreate>
|
||||||
<AiChat v-if="enableAi"></AiChat>
|
<AiChat v-if="enableAi"></AiChat>
|
||||||
|
<LinkNodeSelect
|
||||||
|
v-if="mindMap && supportNodeLink"
|
||||||
|
:mindMap="mindMap"
|
||||||
|
></LinkNodeSelect>
|
||||||
<div
|
<div
|
||||||
class="dragMask"
|
class="dragMask"
|
||||||
v-if="showDragMask"
|
v-if="showDragMask"
|
||||||
@ -92,7 +96,7 @@ import NodeBase64ImageStorage from 'simple-mind-map/src/plugins/NodeBase64ImageS
|
|||||||
import Themes from 'simple-mind-map-plugin-themes'
|
import Themes from 'simple-mind-map-plugin-themes'
|
||||||
// 协同编辑插件
|
// 协同编辑插件
|
||||||
// import Cooperate from 'simple-mind-map/src/plugins/Cooperate.js'
|
// import Cooperate from 'simple-mind-map/src/plugins/Cooperate.js'
|
||||||
// 以下插件为付费插件,详情请查看开发文档。依次为:手绘风格插件、标记插件、编号插件、Freemind软件格式导入导出插件、Excel软件格式导入导出插件、待办插件、节点连线流动效果插件、动量效果插件
|
// 以下插件为付费插件,详情请查看开发文档。依次为:手绘风格插件、标记插件、编号插件、Freemind软件格式导入导出插件、Excel软件格式导入导出插件、待办插件、节点连线流动效果插件、动量效果插件、向右鱼骨图插件、节点链接插件、扩展节点形状插件、扩展主题列表插件
|
||||||
import HandDrawnLikeStyle from 'simple-mind-map-plugin-handdrawnlikestyle'
|
import HandDrawnLikeStyle from 'simple-mind-map-plugin-handdrawnlikestyle'
|
||||||
import Notation from 'simple-mind-map-plugin-notation'
|
import Notation from 'simple-mind-map-plugin-notation'
|
||||||
import Numbers from 'simple-mind-map-plugin-numbers'
|
import Numbers from 'simple-mind-map-plugin-numbers'
|
||||||
@ -102,9 +106,12 @@ import Checkbox from 'simple-mind-map-plugin-checkbox'
|
|||||||
import LineFlow from 'simple-mind-map-plugin-lineflow'
|
import LineFlow from 'simple-mind-map-plugin-lineflow'
|
||||||
import Momentum from 'simple-mind-map-plugin-momentum'
|
import Momentum from 'simple-mind-map-plugin-momentum'
|
||||||
import RightFishbone from 'simple-mind-map-plugin-right-fishbone'
|
import RightFishbone from 'simple-mind-map-plugin-right-fishbone'
|
||||||
|
import NodeLink from 'simple-mind-map-plugin-node-link'
|
||||||
import MoreShapes from 'simple-mind-map-plugin-more-shapes'
|
import MoreShapes from 'simple-mind-map-plugin-more-shapes'
|
||||||
import MoreThemes from 'simple-mind-map-plugin-more-themes'
|
import MoreThemes from 'simple-mind-map-plugin-more-themes'
|
||||||
// npm link simple-mind-map-plugin-excel simple-mind-map-plugin-freemind simple-mind-map-plugin-numbers simple-mind-map-plugin-notation simple-mind-map-plugin-handdrawnlikestyle simple-mind-map-plugin-checkbox simple-mind-map simple-mind-map-plugin-themes simple-mind-map-plugin-lineflow simple-mind-map-plugin-momentum simple-mind-map-plugin-right-fishbone simple-mind-map-plugin-more-themes simple-mind-map-plugin-more-shapes
|
// npm link simple-mind-map simple-mind-map-plugin-excel simple-mind-map-plugin-freemind simple-mind-map-plugin-numbers simple-mind-map-plugin-notation simple-mind-map-plugin-handdrawnlikestyle simple-mind-map-plugin-checkbox simple-mind-map-plugin-lineflow simple-mind-map-plugin-momentum simple-mind-map-plugin-right-fishbone simple-mind-map-plugin-node-link
|
||||||
|
// simple-mind-map-plugin-themes
|
||||||
|
// simple-mind-map-plugin-more-themes simple-mind-map-plugin-more-shapes
|
||||||
import OutlineSidebar from './OutlineSidebar.vue'
|
import OutlineSidebar from './OutlineSidebar.vue'
|
||||||
import Style from './Style.vue'
|
import Style from './Style.vue'
|
||||||
import BaseStyle from './BaseStyle.vue'
|
import BaseStyle from './BaseStyle.vue'
|
||||||
@ -147,6 +154,7 @@ import NodeImgPlacementToolbar from './NodeImgPlacementToolbar.vue'
|
|||||||
import NodeNoteSidebar from './NodeNoteSidebar.vue'
|
import NodeNoteSidebar from './NodeNoteSidebar.vue'
|
||||||
import AiCreate from './AiCreate.vue'
|
import AiCreate from './AiCreate.vue'
|
||||||
import AiChat from './AiChat.vue'
|
import AiChat from './AiChat.vue'
|
||||||
|
import LinkNodeSelect from './LinkNodeSelect.vue'
|
||||||
|
|
||||||
// 注册插件
|
// 注册插件
|
||||||
MindMap.usePlugin(MiniMap)
|
MindMap.usePlugin(MiniMap)
|
||||||
@ -168,7 +176,6 @@ MindMap.usePlugin(MiniMap)
|
|||||||
.usePlugin(OuterFrame)
|
.usePlugin(OuterFrame)
|
||||||
.usePlugin(MindMapLayoutPro)
|
.usePlugin(MindMapLayoutPro)
|
||||||
.usePlugin(NodeBase64ImageStorage)
|
.usePlugin(NodeBase64ImageStorage)
|
||||||
.usePlugin(RightFishbone)
|
|
||||||
// .usePlugin(Cooperate) // 协同插件
|
// .usePlugin(Cooperate) // 协同插件
|
||||||
|
|
||||||
// 注册主题
|
// 注册主题
|
||||||
@ -209,7 +216,8 @@ export default {
|
|||||||
NodeImgPlacementToolbar,
|
NodeImgPlacementToolbar,
|
||||||
NodeNoteSidebar,
|
NodeNoteSidebar,
|
||||||
AiCreate,
|
AiCreate,
|
||||||
AiChat
|
AiChat,
|
||||||
|
LinkNodeSelect
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -235,7 +243,8 @@ export default {
|
|||||||
isUseMomentum: state => state.localConfig.isUseMomentum,
|
isUseMomentum: state => state.localConfig.isUseMomentum,
|
||||||
extraTextOnExport: state => state.extraTextOnExport,
|
extraTextOnExport: state => state.extraTextOnExport,
|
||||||
isDragOutlineTreeNode: state => state.isDragOutlineTreeNode,
|
isDragOutlineTreeNode: state => state.isDragOutlineTreeNode,
|
||||||
enableAi: state => state.localConfig.enableAi
|
enableAi: state => state.localConfig.enableAi,
|
||||||
|
supportNodeLink: state => state.supportNodeLink
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -703,6 +712,14 @@ export default {
|
|||||||
this.mindMap.addPlugin(LineFlow)
|
this.mindMap.addPlugin(LineFlow)
|
||||||
this.$store.commit('setSupportLineFlow', true)
|
this.$store.commit('setSupportLineFlow', true)
|
||||||
}
|
}
|
||||||
|
if (typeof RightFishbone !== 'undefined') {
|
||||||
|
this.mindMap.addPlugin(RightFishbone)
|
||||||
|
this.$store.commit('setSupportRightFishbone', true)
|
||||||
|
}
|
||||||
|
if (typeof NodeLink !== 'undefined') {
|
||||||
|
this.mindMap.addPlugin(NodeLink)
|
||||||
|
this.$store.commit('setSupportNodeLink', true)
|
||||||
|
}
|
||||||
if (typeof MoreShapes !== 'undefined') {
|
if (typeof MoreShapes !== 'undefined') {
|
||||||
this.mindMap.addPlugin(MoreShapes)
|
this.mindMap.addPlugin(MoreShapes)
|
||||||
this.$store.commit('setSupportMoreShapes', true)
|
this.$store.commit('setSupportMoreShapes', true)
|
||||||
|
|||||||
152
web/src/pages/Edit/components/LinkNodeSelect.vue
Normal file
152
web/src/pages/Edit/components/LinkNodeSelect.vue
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
class="nodeLinkSelectDialog"
|
||||||
|
title="链接到指定节点"
|
||||||
|
:visible.sync="dialogVisible"
|
||||||
|
:show-close="false"
|
||||||
|
append-to-body
|
||||||
|
width="400px"
|
||||||
|
>
|
||||||
|
<div class="nodeTreeWrap">
|
||||||
|
<el-tree
|
||||||
|
ref="tree"
|
||||||
|
class="outlineTree"
|
||||||
|
node-key="uid"
|
||||||
|
default-expand-all
|
||||||
|
:class="{ isDark: isDark }"
|
||||||
|
:data="treeData"
|
||||||
|
:props="defaultProps"
|
||||||
|
:highlight-current="true"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
@current-change="onCurrentChange"
|
||||||
|
>
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="footer">
|
||||||
|
<el-checkbox v-model="isAddReturn" style="margin-right: auto;">是否添加反向链接</el-checkbox>
|
||||||
|
<el-button @click="cancel">{{
|
||||||
|
$t('dialog.cancel')
|
||||||
|
}}</el-button>
|
||||||
|
<el-button type="primary" @click="confirm">{{
|
||||||
|
$t('dialog.confirm')
|
||||||
|
}}</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
nodeRichTextToTextWithWrap,
|
||||||
|
htmlEscape
|
||||||
|
} from 'simple-mind-map/src/utils'
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
mindMap: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
treeData: [],
|
||||||
|
defaultProps: {
|
||||||
|
label: 'label'
|
||||||
|
},
|
||||||
|
currentNodeData: null,
|
||||||
|
node: null,
|
||||||
|
isAddReturn: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
isDark: state => state.localConfig.isDark
|
||||||
|
})
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.$bus.$on('show_link_node', this.onShowDialog)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.$bus.$off('show_link_node', this.onShowDialog)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onShowDialog(node) {
|
||||||
|
this.node = node
|
||||||
|
let data = this.mindMap.getData()
|
||||||
|
let walk = root => {
|
||||||
|
let text = root.data.richText
|
||||||
|
? nodeRichTextToTextWithWrap(root.data.text)
|
||||||
|
: root.data.text
|
||||||
|
text = htmlEscape(text)
|
||||||
|
text = text.replace(/\n/g, '<br>')
|
||||||
|
root.label = text
|
||||||
|
root.uid = root.data.uid
|
||||||
|
if (root.children && root.children.length > 0) {
|
||||||
|
root.children.forEach(item => {
|
||||||
|
walk(item)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
walk(data)
|
||||||
|
this.treeData = [data]
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.dialogVisible = false
|
||||||
|
this.node = null
|
||||||
|
this.treeData = []
|
||||||
|
this.currentNodeData = null
|
||||||
|
this.isAddReturn = false
|
||||||
|
},
|
||||||
|
|
||||||
|
// 当前选中的树节点变化事件
|
||||||
|
onCurrentChange(data) {
|
||||||
|
this.currentNodeData = data
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.close()
|
||||||
|
},
|
||||||
|
|
||||||
|
confirm() {
|
||||||
|
if (!this.currentNodeData) {
|
||||||
|
this.$message.warning('请选择要链接到的节点')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.currentNodeData.uid === this.node.getData('uid')) {
|
||||||
|
this.$message.warning('不能链接自己')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$bus.$emit(
|
||||||
|
'execCommand',
|
||||||
|
'SET_NODE_LINK',
|
||||||
|
this.node,
|
||||||
|
this.currentNodeData.uid,
|
||||||
|
this.isAddReturn
|
||||||
|
)
|
||||||
|
this.$message.success('链接成功')
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.nodeLinkSelectDialog {
|
||||||
|
/deep/ .el-dialog__body {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nodeTreeWrap {
|
||||||
|
height: 400px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -350,7 +350,8 @@ export default {
|
|||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="less">
|
||||||
.outlineTree {
|
.outlineTree {
|
||||||
&.isDark {
|
&.isDark {
|
||||||
background-color: #262a2e;
|
background-color: #262a2e;
|
||||||
|
|||||||
@ -362,67 +362,4 @@ export default {
|
|||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.outlineTree {
|
|
||||||
&.isDark {
|
|
||||||
background-color: #262a2e;
|
|
||||||
|
|
||||||
.customNode {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.el-tree--highlight-current {
|
|
||||||
/deep/ .el-tree-node.is-current > .el-tree-node__content {
|
|
||||||
background-color: hsla(0, 0%, 100%, 0.05) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/deep/ .el-tree-node__content:hover,
|
|
||||||
.el-upload-list__item:hover {
|
|
||||||
background-color: hsla(0, 0%, 100%, 0.02) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/deep/ .el-tree-node__content {
|
|
||||||
.el-tree-node__expand-icon {
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
&.is-leaf {
|
|
||||||
&::after {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/deep/ .el-tree-node > .el-tree-node__children {
|
|
||||||
overflow: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/deep/ .el-tree-node__content {
|
|
||||||
height: auto;
|
|
||||||
margin: 5px 0;
|
|
||||||
|
|
||||||
.el-tree-node__expand-icon {
|
|
||||||
color: #262a2e;
|
|
||||||
|
|
||||||
&.is-leaf {
|
|
||||||
color: transparent;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
background-color: #262a2e;
|
|
||||||
position: absolute;
|
|
||||||
content: '';
|
|
||||||
width: 5px;
|
|
||||||
height: 5px;
|
|
||||||
border-radius: 50%;
|
|
||||||
left: 10px;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -38,7 +38,9 @@ const store = new Vuex.Store({
|
|||||||
supportCheckbox: false, // 是否支持Checkbox插件
|
supportCheckbox: false, // 是否支持Checkbox插件
|
||||||
supportLineFlow: false, // 是否支持LineFlow插件
|
supportLineFlow: false, // 是否支持LineFlow插件
|
||||||
supportMomentum: false, // 是否支持Momentum插件
|
supportMomentum: false, // 是否支持Momentum插件
|
||||||
supportMoreShapes: false,// 是否支持MoreShapes插件
|
supportRightFishbone: false, // 是否支持RightFishbone插件
|
||||||
|
supportNodeLink: false, // 是否支持NodeLink插件
|
||||||
|
supportMoreShapes: false, // 是否支持MoreShapes插件
|
||||||
isDragOutlineTreeNode: false, // 当前是否正在拖拽大纲树的节点
|
isDragOutlineTreeNode: false, // 当前是否正在拖拽大纲树的节点
|
||||||
aiConfig: {
|
aiConfig: {
|
||||||
api: 'http://ark.cn-beijing.volces.com/api/v3/chat/completions',
|
api: 'http://ark.cn-beijing.volces.com/api/v3/chat/completions',
|
||||||
@ -139,6 +141,16 @@ const store = new Vuex.Store({
|
|||||||
state.supportMomentum = data
|
state.supportMomentum = data
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 设置是否支持RightFishbone插件
|
||||||
|
setSupportRightFishbone(state, data) {
|
||||||
|
state.supportRightFishbone = data
|
||||||
|
},
|
||||||
|
|
||||||
|
// 设置是否支持NodeLink插件
|
||||||
|
setSupportNodeLink(state, data) {
|
||||||
|
state.supportNodeLink = data
|
||||||
|
},
|
||||||
|
|
||||||
// 设置是否支持MoreShapes插件
|
// 设置是否支持MoreShapes插件
|
||||||
setSupportMoreShapes(state, data) {
|
setSupportMoreShapes(state, data) {
|
||||||
state.supportMoreShapes = data
|
state.supportMoreShapes = data
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user