no message

This commit is contained in:
KuroSago 2025-05-07 21:48:13 +08:00
parent 947fd3374b
commit 2755ece84b
8 changed files with 201 additions and 19 deletions

View File

@ -535,6 +535,7 @@ export default {
//
updateOtherConfig(key, value) {
console.log({key, value})
if (key === 'openBlankMode') {
this.mindMap.updateConfig({
demonstrateConfig: {

View File

@ -23,6 +23,7 @@ function remove() {
return true;
},
nodeId: uid,
allowRemoveWithChildren : false
});
}
}

View File

@ -0,0 +1,117 @@
import { insertChildNode } from "./insertChildNode";
import { insertSiblingNode } from "./insertSiblingNode";
import { useMindMapStore } from "../index";
const ICON_PLUS = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 15 15"><!-- Icon from Radix Icons by WorkOS - https://github.com/radix-ui/icons/blob/master/LICENSE --><path fill="currentColor" fill-rule="evenodd" d="M7.5.877a6.623 6.623 0 1 0 0 13.246A6.623 6.623 0 0 0 7.5.877M1.827 7.5a5.673 5.673 0 1 1 11.346 0a5.673 5.673 0 0 1-11.346 0M7.5 4a.5.5 0 0 1 .5.5V7h2.5a.5.5 0 1 1 0 1H8v2.5a.5.5 0 0 1-1 0V8H4.5a.5.5 0 0 1 0-1H7V4.5a.5.5 0 0 1 .5-.5" clip-rule="evenodd"/></svg>'
const ICON_EDIT = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 15 15"><!-- Icon from Radix Icons by WorkOS - https://github.com/radix-ui/icons/blob/master/LICENSE --><path fill="currentColor" fill-rule="evenodd" d="M12.146 1.146a.5.5 0 0 1 .707 0l2 2a.5.5 0 0 1 0 .708l-3.942 3.942a1 1 0 0 1-.26.188L6.724 9.947a.5.5 0 0 1-.671-.67l1.963-3.928a1 1 0 0 1 .188-.26zm.354 1.061l-3.59 3.59l-1.037 2.076l.254.254l2.077-1.038L13.793 3.5zM10 2L9 3H4.9c-.428 0-.72 0-.944.019c-.22.018-.332.05-.41.09a1 1 0 0 0-.437.437c-.04.078-.072.19-.09.41C3 4.18 3 4.472 3 4.9v6.2c0 .428 0 .72.019.944c.018.22.05.332.09.41a1 1 0 0 0 .437.437c.078.04.19.072.41.09c.225.019.516.019.944.019h6.2c.428 0 .72 0 .944-.019c.22-.018.332-.05.41-.09a1 1 0 0 0 .437-.437c.04-.078.072-.19.09-.41c.019-.225.019-.516.019-.944V7l1-1v5.12c0 .403 0 .735-.022 1.006c-.023.281-.072.54-.196.782a2 2 0 0 1-.874.874c-.243.124-.501.173-.782.196c-.27.022-.603.022-1.005.022H4.88c-.403 0-.735 0-1.006-.022c-.281-.023-.54-.072-.782-.196a2 2 0 0 1-.874-.874c-.124-.243-.173-.501-.196-.782C2 11.856 2 11.523 2 11.12V4.88c0-.403 0-.735.022-1.006c.023-.281.072-.54.196-.782a2 2 0 0 1 .874-.874c.243-.124.501-.173.782-.196C4.144 2 4.477 2 4.88 2z" clip-rule="evenodd"/></svg>'
const ICON_DELETE = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 15 15"><!-- Icon from Radix Icons by WorkOS - https://github.com/radix-ui/icons/blob/master/LICENSE --><path fill="currentColor" fill-rule="evenodd" d="M5.5 1a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1zM3 3.5a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1H11v8a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4h-.5a.5.5 0 0 1-.5-.5M5 4h5v8H5z" clip-rule="evenodd"/></svg>'
/**
* -
* @returns
*/
export function getCustomNodeContent() {
// 按钮配置
const buttonConfig = {
padding: 5, // 按钮内边距
gap: 4, // 按钮间距
fontSize: 12, // 字体大小
height: 24, // 按钮高度
// 每个按钮的估计宽度 (图标大约占12px + 左右内边距共10px)
buttonWidth: 22
};
// 所有按钮配置
const buttons = [
{ icon: ICON_PLUS, color: "#4CAF50", title: "添加子节点", action: "addChild" },
{ icon: ICON_EDIT, color: "#FF9800", title: "编辑节点", action: "edit" },
{ icon: ICON_DELETE, color: "#2196F3", title: "删除", action: "addSibling" },
];
// 预计算总宽度
const totalWidth = buttons.length * buttonConfig.buttonWidth +
(buttons.length - 1) * buttonConfig.gap;
return {
// 创建自定义DOM元素
create: (node: any) => {
// 创建包含按钮的容器
const container = document.createElement("div");
container.style.display = "flex";
container.style.gap = `${buttonConfig.gap}px`;
// 通用创建按钮的函数,减少重复代码
const createButton = (icon: string, color: string, title: string, action: string) => {
const btn = document.createElement("button");
btn.innerHTML = icon;
btn.title = title;
// 通用样式
Object.assign(btn.style, {
border: "none",
background: color,
color: "white",
borderRadius: "3px",
cursor: "pointer",
padding: `2px ${buttonConfig.padding}px`,
fontSize: `${buttonConfig.fontSize}px`,
minWidth: `${buttonConfig.buttonWidth - buttonConfig.padding * 2}px`
});
btn.onclick = (e) => {
e.stopPropagation(); // 阻止事件冒泡
// 根据按钮类型执行不同操作
switch (action) {
case "addChild":
insertChildNode({
beforeInsertCallback: async () => ({ uid: "", text: "新子节点" }),
parentNodeId: node.uid,
});
break;
case "addSibling":
insertSiblingNode({
beforeInsertCallback: async () => ({ uid: "", text: "新同级节点" }),
nodeId: node.uid,
});
break;
case "edit":
// const { getMindMapInstance } = useMindMapStore();
break;
}
};
return btn;
};
// 创建并添加所有按钮
buttons.forEach(buttonInfo => {
const btn = createButton(
buttonInfo.icon,
buttonInfo.color,
buttonInfo.title,
buttonInfo.action
);
container.appendChild(btn);
});
// 返回容器元素和预计算的尺寸
return {
el: container,
width: totalWidth, // 预计算的容器总宽度
height: buttonConfig.height // 容器高度
};
},
// 处理生成的SVG.js的ForeignObject节点实例
handle: ({ element, node }: { content: any; element: any; node: any }) => {
console.log({ element, node })
node.height += 34
// 设置自定义内容的位置 - 位于节点下方
element.attr({
x: 0, // 水平居中
y: node.height + 5 // 位于节点下方5px的位置
});
},
};
}

View File

@ -0,0 +1,17 @@
import MindMap from "simple-mind-map";
// import { keyMap } from 'simple-mind-map/src/core/command/keyMap'
// 键盘事件
export function keyCommand(MindMapConstructor: MindMap) {
removeKeyCommand(MindMapConstructor);
}
// 移除指令
export function removeKeyCommand(MindMapConstructor: MindMap) {
// console.log('移除指令 =>' , keyMap)
// Backspace // Tab // Enter
MindMapConstructor?.keyCommand?.removeShortcut('Tab' , null)
MindMapConstructor?.keyCommand?.removeShortcut('Enter' , null)
MindMapConstructor?.keyCommand?.removeShortcut('Backspace' , null)
// MindMapConstructor?.keyCommand?.pause();
}

View File

@ -4,11 +4,13 @@ import { useMindMapStore } from "../../store/index";
*
* @param beforeRemoveCallback false则取消删除操作
* @param nodeId ID
* @param allowRemoveWithChildren true
* @returns Promise
*/
export async function removeNode(params: {
beforeRemoveCallback?: () => Promise<boolean>;
nodeId?: string | number;
allowRemoveWithChildren?: boolean;
}): Promise<void> {
const { getMindMapInstance } = useMindMapStore();
@ -23,10 +25,28 @@ export async function removeNode(params: {
const node = getMindMapInstance()?.renderer?.findNodeByUid(
params.nodeId
);
if (node) {
// 检查节点是否有子节点且不允许删除有子节点的情况
if (params.allowRemoveWithChildren === false) {
const children = node.children;
if (children && children.length > 0) {
console.warn("节点存在子节点,根据设置不允许删除");
return;
}
}
return getMindMapInstance()?.execCommand("REMOVE_NODE", [node]);
}
} else {
// 删除当前选中的节点
if (params.allowRemoveWithChildren === false) {
const selectedNode = getMindMapInstance()?.renderer?.activeNodeList[0];
if (selectedNode && selectedNode.children && selectedNode.children.length > 0) {
console.warn("节点存在子节点,根据设置不允许删除");
return;
}
}
return getMindMapInstance()?.execCommand("REMOVE_NODE");
}
} catch (error) {

View File

@ -7,6 +7,7 @@ import ExportPDF from 'simple-mind-map/src/plugins/ExportPDF'
import ExportXMind from 'simple-mind-map/src/plugins/ExportXMind'
import Export from 'simple-mind-map/src/plugins/Export'
import MindMapLayoutPro from 'simple-mind-map/src/plugins/MindMapLayoutPro'
// import RichText from 'simple-mind-map/src/plugins/RichText'
export function usePlugins(MindMapConstructor: typeof MindMap) {
@ -15,4 +16,5 @@ export function usePlugins(MindMapConstructor: typeof MindMap) {
MindMapConstructor.usePlugin(ExportXMind);
MindMapConstructor.usePlugin(Export);
MindMapConstructor.usePlugin(MindMapLayoutPro)
// MindMapConstructor.usePlugin(RichText);
}

View File

@ -1,11 +1,13 @@
import { defineStore } from "pinia";
import { ref , shallowRef } from "vue";
import { ref, shallowRef } from "vue";
import { importFile } from "../helpers/import";
import { exportFile } from "../helpers/export";
import { usePlugins } from "../helpers/usePlugin";
import { insertChildNode } from "../helpers/insertChildNode";
import { insertSiblingNode } from "../helpers/insertSiblingNode";
import { removeNode } from "../helpers/removeNode";
import { removeKeyCommand } from "../helpers/keyCommand";
import { getCustomNodeContent } from "../helpers/addCustomContentToNode";
import type MindMapNode from "simple-mind-map/types/src/core/render/node/MindMapNode";
@ -14,48 +16,62 @@ import MindMap from "simple-mind-map";
export const useMindMapStore = defineStore(
"mindMapStore",
() => {
let mindMapInstance : (MindMap | null) =null;
let mindMapInstance: MindMap | null = null;
const mindMapData = ref(null);
// 激活状态节点
const activeNodes = shallowRef<MindMapNode[]>([])
const activeNodes = shallowRef<MindMapNode[]>([]);
usePlugins(MindMap);
function initMindMap(container: HTMLElement) {
mindMapInstance = new MindMap({
el: container,
data : null,
layout: 'mindMap',
data: null,
layout: "mindMap",
fit: false,
nodeTextEditZIndex: 1000,
nodeNoteTooltipZIndex: 1000,
openRealtimeRenderOnNodeTextEdit: true,
enableAutoEnterTextEditWhenKeydown: true,
demonstrateConfig: {
openBlankMode: true
isShowCreateChildBtnIcon: false, // 是否显示添加子节点按钮
enableAutoEnterTextEditWhenKeydown: false, // 键盘输入时自动进入文本编辑 // .updateConfig({ 'openRealtimeRenderOnNodeTextEdit' : value})
createNewNodeBehavior: "activeOnly", // 插入新节点的行为 // activeOnly - 只新建激活不编辑
customQuickCreateChildBtnClick: () => {
console.log("自定义添加按钮点击事件");
},
isUseCustomNodeContent : true, // 是否使用自定义节点内容
// 添加自定义节点内容
addCustomContentToNode: getCustomNodeContent(),
demonstrateConfig: {
openBlankMode: true,
},
});
// 监听节点激活事件
mindMapInstance?.on('node_active', (_ : MindMapNode, activeNodeList : MindMapNode[]) => {
console.log('激活节点', activeNodeList);
activeNodes.value = activeNodeList
})
mindMapInstance?.on(
"node_active",
(_: MindMapNode, activeNodeList: MindMapNode[]) => {
console.log("激活节点", activeNodeList);
activeNodes.value = activeNodeList;
}
);
// 关闭键盘事件
removeKeyCommand(mindMapInstance);
}
// 因为避免使用响应对象
function getMindMapInstance (): MindMap | null {
function getMindMapInstance(): MindMap | null {
return mindMapInstance;
}
return {
mindMapInstance,
mindMapData,

View File

@ -31,4 +31,12 @@ declare module 'simple-mind-map/src/utils' {
import * as utils from 'simple-mind-map/types/src/utils';
export = utils;
}
declare module 'simple-mind-map/src/core/command/keyMap' {
import * as keyMap from 'simple-mind-map/types/src/core/command/keyMap';
export = keyMap;
}
declare module 'simple-mind-map/src/plugins/RichText' {
import RichText from 'simple-mind-map/types/src/plugins/RichText';
export default RichText;
}