import { ref, computed } from "vue"; import { NODE_TYPE, NODE_DATATYPE } from '../tools/index.d' import { ElMessageBox } from 'element-plus' import i18n from '@/lang' const t = i18n.global.t export interface NodesItem { id: string type: string class: string position: { x: number, y: number } data: { component: any, type: string, superiorID?: string } } export class StateManager { vueFlow: any activeNodeID: any nodes: any nodes_: any edges: any zoom: any tool: any cursor: any // 节点是否可拖动 nodesDraggable: any // 拖动时是否可以平移画布 panOnDrag: any // 历史记录-撤回/重做 mxHistory: any historyList: any historyIndex: any // 管理器 eventManager: any flowManager: any nodeManager: any toolManager: any generateManager: any // 设置管理器 setManager(options) { options.eventManager && (this.eventManager = options.eventManager) options.flowManager && (this.flowManager = options.flowManager) options.nodeManager && (this.nodeManager = options.nodeManager) options.toolManager && (this.toolManager = options.toolManager) options.generateManager && (this.generateManager = options.generateManager) } constructor(options) { this.vueFlow = options.vueFlow this.zoom = ref(1) this.tool = ref("") this.cursor = ref("") this.nodesDraggable = ref(false) this.panOnDrag = ref(false) this.mxHistory = ref(50) this.historyList = ref([]) this.historyIndex = ref(0) this.activeNodeID = ref("") this.nodes = ref([]); this.nodes_ = computed(() => { return this.nodes.value.map((node, index) => { const obj = node; const superiorID = node.data.superiorID; const isSuperior = this.nodes.value.some((v) => v.id === superiorID) const isSubord = this.nodes.value.some((v) => v.data.superiorID === node.id) if (!isSuperior && isSubord) {// 没有上级 有下级 obj.type = NODE_TYPE.INPUT; } else if (isSuperior && isSubord) {// 有上级 有下级 obj.type = NODE_TYPE.SECONDARY; } else if (isSuperior && !isSubord) {// 有上级 没有下级 obj.type = NODE_TYPE.OUTPUT; } else {// 其他情况-没有上级 没有下级 obj.type = NODE_TYPE.ALONE; } return obj }) }) this.edges = computed(() => { const arr = [] this.nodes.value.forEach((node, index) => { const superiorID = node.data.superiorID; const isSuperior = this.nodes.value.some((v) => v.id === superiorID) if (superiorID && isSuperior) { const source = node.data.superiorID const target = node.id arr.push({ id: `el-${source}-${target}`, source: source, target: target, selectable: false, visible: (node.data.type !== NODE_DATATYPE.RESULT_IMAGE || node.data.isActive), type: 'default' }) } }) return arr }) window.nodes = this.nodes } /** 设置激活节点 */ setActiveNodeID(id: string) { this.activeNodeID.value = id } /** 添加节点 */ addNode(node: NodesItem) { this.nodes.value.push(node); this.recordState() } /** 删除节点 */ async deleteNode(id: string, { isElMessageBox } = { isElMessageBox: false }) { const node = this.getNodeById(id) if (!node) return console.warn(`没有找到指定id:${id}`) if (node.data.disableDelete) return console.warn('该节点禁用删除') let deletePromise: any = true if (isElMessageBox) { deletePromise = await new Promise((resolve, reject) => { ElMessageBox.confirm( t('flowCanvas.deleteCardConfirm'), '', { confirmButtonText: t('flowCanvas.confirm'), cancelButtonText: t('flowCanvas.cancel'), } ).then(() => { resolve(true) }).catch(() => { resolve(false) }) }) } if (!deletePromise) return console.log('删除操作被取消') this.nodes.value = this.nodes.value.filter((node: NodesItem) => node.id !== id) this.recordState() } /** 获取节点 */ getNodeById(id: string) { return this.nodes.value.find((node: NodesItem) => node.id === id) } /** 获取下级节点 */ getSubordNodeById(id: string) { return this.nodes.value.find((node: NodesItem) => node.data.superiorID === id) } getLastNode() { console.log(this.nodes.value); return this.nodes.value[this.nodes.value.length - 1] } /** 设置工具 */ setTool(tool: string) { this.tool.value = tool } /** 设置光标 */ setCursor(v: string) { this.cursor.value = v } /** 设置节点是否可拖动 */ setNodesDraggable(v: boolean) { this.nodesDraggable.value = v } /** 设置是否可以平移画布 */ setPanOnDrag(v: boolean) { this.panOnDrag.value = v } /** 设置节点层级至最顶部 */ bringToFont(id) { const fromIndex = this.nodes.value.findIndex(item => item.id === id) if (fromIndex === -1) return console.warn(`没有找到指定id:${id}`) this.nodes.value.splice(this.nodes.value.length - 1, 0, ...this.nodes.value.splice(fromIndex, 1)) } /** 设置节点层级至最低部 */ sendToBack(id) { const fromIndex = this.nodes.value.findIndex(item => item.id === id) if (fromIndex === -1) return console.warn(`没有找到指定id:${id}`) this.nodes.value.splice(0, 0, ...this.nodes.value.splice(fromIndex, 1)) } /** 记录状态 */ recordState() { if (this.historyIndex.value < this.historyList.value.length - 1) { this.historyList.value.splice(this.historyIndex.value + 1) } const state = { nodes: JSON.stringify(this.nodes.value) } this.historyList.value.push(state) const size = this.historyList.value.length - this.mxHistory.value if (size > 0) this.historyList.value.splice(0, size) this.historyIndex.value = this.historyList.value.length - 1 } /** 撤回状态 */ undoState() { var index = this.historyIndex.value - 1 const state = this.historyList.value[index] if (!state) return this.historyIndex.value = index this.nodes.value = JSON.parse(state.nodes) } /** 重做状态 */ redoState() { var index = this.historyIndex.value + 1 const state = this.historyList.value[index] if (!state) return this.historyIndex.value = index this.nodes.value = JSON.parse(state.nodes) } /** 显示指定子节点和父节点连接线,隐藏父节点和其他子节点链接线, */ showNodeConnections(id: string) { const node = this.getNodeById(id) if(node.data.component != NODE_DATATYPE.RESULT_IMAGE && node.data.superiorID) return let edges_ = JSON.parse(JSON.stringify(this.edges.value)) this.nodes.value.forEach((nodeItem) => { if(node.data.superiorID === nodeItem.data.superiorID && nodeItem.id == id) { nodeItem.data.isActive = true }else if(node.data.superiorID == nodeItem.data.superiorID){ nodeItem.data.isActive = false } }) } dispose() { this.historyList.value = [] this.historyIndex.value = 0 } }