From 5be800e579cebdc97dd5ce14856452d999a2d9b3 Mon Sep 17 00:00:00 2001 From: zhanghao <774378400@qq.com> Date: Mon, 29 Jun 2026 17:13:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A7=86=E9=A2=91=E6=92=AD=E6=94=BE?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IPlayer/config.ts | 0 .../IPlayer/index.vue | 0 .../components/LogicFlow/CustomGroup.js | 103 ------ .../components/LogicFlow/customFlow.vue | 238 -------------- .../components/LogicFlow/customFlowNode.js | 134 -------- .../register/components/LogicFlow/index.vue | 294 ------------------ src/views/flow/nodes/common/serviceNode.vue | 2 +- src/views/flow/nodes/function/codeNode.vue | 2 +- src/views/flow/nodes/function/currentLoop.vue | 2 +- src/views/flow/nodes/function/httpNode.vue | 2 +- src/views/flow/nodes/function/sdAgent.vue | 2 +- src/views/flow/nodes/function/sleep.vue | 2 +- 12 files changed, 6 insertions(+), 775 deletions(-) rename src/{views/device/register/components/LogicFlow => components}/IPlayer/config.ts (100%) rename src/{views/device/register/components/LogicFlow => components}/IPlayer/index.vue (100%) delete mode 100644 src/views/device/register/components/LogicFlow/CustomGroup.js delete mode 100644 src/views/device/register/components/LogicFlow/customFlow.vue delete mode 100644 src/views/device/register/components/LogicFlow/customFlowNode.js delete mode 100644 src/views/device/register/components/LogicFlow/index.vue diff --git a/src/views/device/register/components/LogicFlow/IPlayer/config.ts b/src/components/IPlayer/config.ts similarity index 100% rename from src/views/device/register/components/LogicFlow/IPlayer/config.ts rename to src/components/IPlayer/config.ts diff --git a/src/views/device/register/components/LogicFlow/IPlayer/index.vue b/src/components/IPlayer/index.vue similarity index 100% rename from src/views/device/register/components/LogicFlow/IPlayer/index.vue rename to src/components/IPlayer/index.vue diff --git a/src/views/device/register/components/LogicFlow/CustomGroup.js b/src/views/device/register/components/LogicFlow/CustomGroup.js deleted file mode 100644 index 7cc34cf..0000000 --- a/src/views/device/register/components/LogicFlow/CustomGroup.js +++ /dev/null @@ -1,103 +0,0 @@ - -import { GroupNodeModel, GroupNode } from '@logicflow/extension' -import { recursiveFilter } from "@/utils/convertNodeRedToLogicFlow"; - -class CustomGroupModel extends GroupNodeModel { - initNodeData(data) { - super.initNodeData(data); - this.children = new Set(data.children || []) - this.zIndex = 0; - - this.width = data.w + 80; // 增加内边距 - this.height = data.h + 80; - this.x = data.x; - this.y = data.y; - - setTimeout(() => { - this.updateSize() - const nodes = this.graphModel.nodes; - const arr = recursiveFilter(nodes, this.id) - arr.forEach((item) => { - item.updateSize() - }) - }, 0) - } - - setAttributes() { - this.text.editable = false; - } - - getTextStyle() { - const style = super.getTextStyle(); - style.fill = this.properties.style?.color || '#333'; - style.fontSize = 16; - return style; - } - - updateSize() { - const children = [] - this.children.forEach((id) => { - children.push(this.graphModel.getNodeModelById(id)) - }); - if (children.length === 0) return; - - let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity; - children.forEach((node) => { - minX = Math.min(minX, node.x - node.width / 2); - maxX = Math.max(maxX, node.x + node.width / 2); - minY = Math.min(minY, node.y - node.height / 2); - maxY = Math.max(maxY, node.y + node.height / 2); - }); - - this.width = maxX - minX + 80; // 增加内边距 - this.height = maxY - minY + 80; - this.x = (minX + maxX) / 2; - this.y = (minY + maxY) / 2; - this.setTextCoordinate(this.width, this.height, this.x, this.y) - } - - setTextCoordinate(width, height, x, y) { - const strategies = { - "n": () => { - this.text.x = x - this.text.y = y - height / 2 + 20 - }, - "ne": () => { - this.text.x = x + width / 2 - 20 - this.text.y = y - height / 2 + 20 - }, - "sw": () => { - this.text.x = x - width / 2 + 20 - this.text.y = y + height / 2 - 20 - }, - "s": () => { - this.text.x = x - this.text.y = y + height / 2 - 20 - }, - "se": () => { - this.text.x = x + width / 2 - 20 - this.text.y = y + height / 2 - 20 - }, - "default": () => { - this.text.x = x - width / 2 + 20 - this.text.y = y - height / 2 + 20 - } - }; - const labelPosition = this.properties.style?.['label-position'] || 'default' - const action = strategies[labelPosition] - action(); - } - - removeChild(id) { - this.children.delete(id) // 现在可安全调用 - } -} - -// 导出方法注册 -export function registerCustomGroup(lf) { - lf.register({ - type: "customGroup", - view: GroupNode, - model: CustomGroupModel - }) -} diff --git a/src/views/device/register/components/LogicFlow/customFlow.vue b/src/views/device/register/components/LogicFlow/customFlow.vue deleted file mode 100644 index 9ba9db2..0000000 --- a/src/views/device/register/components/LogicFlow/customFlow.vue +++ /dev/null @@ -1,238 +0,0 @@ - - - - - {{ props.text || "--" }} - - 详情 - - 节点类型: {{ props.properties.type }} - - 状态:{{ stateMap[props.properties.state] }} - - - - - {{ props.text || "--" }} - - - - - - - 输入参数 - - - - - - - 输出参数 - - - - - - - - - - - - - - - - - - diff --git a/src/views/device/register/components/LogicFlow/customFlowNode.js b/src/views/device/register/components/LogicFlow/customFlowNode.js deleted file mode 100644 index 447800b..0000000 --- a/src/views/device/register/components/LogicFlow/customFlowNode.js +++ /dev/null @@ -1,134 +0,0 @@ -// 导入 HtmlNode 及其模型,为后续继承做准备 -import { HtmlNode, HtmlNodeModel } from '@logicflow/core'; -// 导入 Vue 相关方法,用于渲染组件 -import { createApp, h } from 'vue'; -import ElementPlus from 'element-plus' -// 导入 Vue 组件 -import CustomFlow from './customFlow.vue'; - -/** - * 定义一个 元素的 HTML 节点类,继承自 HtmlNode - * 该类负责在 HTML 中渲染 元素,并处理其交互逻辑 - */ -class CustomFlowHtmlNode extends HtmlNode { - isMounted; // 标记组件是否已挂载 - r; // 渲染函数 - app; // Vue 应用实例 - - /** - * 构造函数 - * @param props 传递给节点的属性,包括模型、图模型等 - */ - constructor(props) { - super(props); - this.isMounted = false; - // 创建 元素的渲染函数 - this.r = h(CustomFlow, { - model: props.model, - graphModel: props.graphModel, - properties: { - ...props.model.getProperties(), - }, - text: props.model.text.value, - }); - - // 创建 Vue 应用实例,并指定渲染函数 - this.app = createApp({ - render: () => this.r - }); - } - - /** - * 将 HTML 内容设置到指定的根元素上 - * @param rootEl 根元素 - */ - setHtml(rootEl) { - if (!this.isMounted) { - this.isMounted = true; - const node = document.createElement('div'); - node.style.width = '100%' - node.style.height = '100%' - rootEl.appendChild(node); - this.app.use(ElementPlus) // 关键:单独注册ElementPlus - this.app.mount(node); - } else { - this.r.component.props.properties = this.props.model.getProperties(); - } - } - - /** - * 获取节点文本内容 - * 对于元素,返回 null,因为其内容由特定组件渲染 - * @returns {null} - */ - getText() { - return null; - } -} - -/** - * 定义一个元素的 HTML 模型类,继承自 HtmlNodeModel - * 该类主要设置节点的属性和样式 - */ -class CustomFlowHtmlModel extends HtmlNodeModel { - initNodeData(data) { - super.initNodeData(data); - // 仅允许从底部锚点连出 - this.sourceRules.push({ - message: '只能从输出锚点连线', - validate: (sourceNode, targetNode, sourceAnchor) => - // sourceAnchor.name === 'right' - sourceAnchor.properties.connectionType === 'source' - }); - - // 仅允许连接到顶部锚点 - this.targetRules.push({ - message: '只能连接到输入锚点', - validate: (sourceNode, targetNode, targetAnchor) => - // targetAnchor.name === 'left' - targetAnchor.properties.connectionType === 'target' - }); - } - - /** - * 设置节点属性 - * 包括宽度、高度、文本编辑属性等 - */ - setAttributes() { - this.width = 200; - this.height = 100; - this.text.editable = false; - } - - // 定义节点只有左右两个锚点. 锚点位置通过中心点和宽度算出来。 - getDefaultAnchor() { - let _a = this, x = _a.x, y = _a.y, width = _a.width, height = _a.height; - return [ - // { x: x, y: y - height / 2, id: "".concat(this.id, "_0") }, - { x: x + width / 2, y: y, name: 'left', id: "".concat(this.id, "_1"), properties: { connectionType: 'target' } }, - // { x: x, y: y + height / 2, id: "".concat(this.id, "_2") }, - { x: x - width / 2, y: y, name: 'right', id: "".concat(this.id, "_3"), properties: { connectionType: 'source' } }, - ]; - } - - /** - * 获取节点轮廓样式 - * 覆盖父类方法,设置 stroke 属性为 none,以适应特定的视觉效果 - * @returns {object} 节点轮廓样式 - */ - getOutlineStyle() { - const style = super.getOutlineStyle(); - style.stroke = 'none'; - style.hover.stroke = 'none'; - return style; - } -} - -// 导出方法注册 -export function registerCustomNode(lf) { - lf.register({ - type: "CustomNode", - view: CustomFlowHtmlNode, - model: CustomFlowHtmlModel - }) -} \ No newline at end of file diff --git a/src/views/device/register/components/LogicFlow/index.vue b/src/views/device/register/components/LogicFlow/index.vue deleted file mode 100644 index facfd2a..0000000 --- a/src/views/device/register/components/LogicFlow/index.vue +++ /dev/null @@ -1,294 +0,0 @@ - - - - 实例状态:{{ stateMap[instStatus]}} - lfRef.translateCenter()">居中 - lfRef.fitView()">适应屏幕 - 停止 - 暂停 - 恢复 - - - - - - \ No newline at end of file diff --git a/src/views/flow/nodes/common/serviceNode.vue b/src/views/flow/nodes/common/serviceNode.vue index 6af53a7..c0d2b5e 100644 --- a/src/views/flow/nodes/common/serviceNode.vue +++ b/src/views/flow/nodes/common/serviceNode.vue @@ -54,7 +54,7 @@ import NodeTitle from "../../components/NodeTitle.vue"; import NodeState from "../../components/NodeState.vue"; import "vue3-json-viewer/dist/index.css"; import { emitter } from "@/utils/eventBus"; -import IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue"; +import IPlayer from "@/components/IPlayer/index.vue"; const props = defineProps({ model: Object, diff --git a/src/views/flow/nodes/function/codeNode.vue b/src/views/flow/nodes/function/codeNode.vue index 32a2469..da98c45 100644 --- a/src/views/flow/nodes/function/codeNode.vue +++ b/src/views/flow/nodes/function/codeNode.vue @@ -50,7 +50,7 @@ import { ref, onMounted, onUnmounted } from "vue"; import NodeTitle from "../../components/NodeTitle.vue"; import NodeState from "../../components/NodeState.vue"; import { emitter } from "@/utils/eventBus"; -import IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue"; +import IPlayer from "@/components/IPlayer/index.vue"; const props = defineProps({ model: Object, diff --git a/src/views/flow/nodes/function/currentLoop.vue b/src/views/flow/nodes/function/currentLoop.vue index 7703d20..98777a1 100644 --- a/src/views/flow/nodes/function/currentLoop.vue +++ b/src/views/flow/nodes/function/currentLoop.vue @@ -37,7 +37,7 @@ import NodeTitle from "../../components/NodeTitle.vue"; import NodeState from "../../components/NodeState.vue"; import "vue3-json-viewer/dist/index.css"; import { emitter } from "@/utils/eventBus"; -import IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue"; +import IPlayer from "@/components/IPlayer/index.vue"; const props = defineProps({ model: Object, diff --git a/src/views/flow/nodes/function/httpNode.vue b/src/views/flow/nodes/function/httpNode.vue index 96823ae..3adbcea 100644 --- a/src/views/flow/nodes/function/httpNode.vue +++ b/src/views/flow/nodes/function/httpNode.vue @@ -53,7 +53,7 @@ import NodeTitle from "../../components/NodeTitle.vue"; import NodeState from "../../components/NodeState.vue"; import "vue3-json-viewer/dist/index.css"; import { emitter } from "@/utils/eventBus"; -import IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue"; +import IPlayer from "@/components/IPlayer/index.vue"; const props = defineProps({ model: Object, diff --git a/src/views/flow/nodes/function/sdAgent.vue b/src/views/flow/nodes/function/sdAgent.vue index c3e98c1..420399e 100644 --- a/src/views/flow/nodes/function/sdAgent.vue +++ b/src/views/flow/nodes/function/sdAgent.vue @@ -37,7 +37,7 @@ import NodeTitle from "../../components/NodeTitle.vue"; import NodeState from "../../components/NodeState.vue"; import "vue3-json-viewer/dist/index.css"; import { emitter } from "@/utils/eventBus"; -import IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue"; +import IPlayer from "@/components/IPlayer/index.vue"; const props = defineProps({ model: Object, diff --git a/src/views/flow/nodes/function/sleep.vue b/src/views/flow/nodes/function/sleep.vue index fe66088..d880fa9 100644 --- a/src/views/flow/nodes/function/sleep.vue +++ b/src/views/flow/nodes/function/sleep.vue @@ -38,7 +38,7 @@ import NodeTitle from "../../components/NodeTitle.vue"; import NodeState from "../../components/NodeState.vue"; import "vue3-json-viewer/dist/index.css"; import { emitter } from "@/utils/eventBus"; -import IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue"; +import IPlayer from "@/components/IPlayer/index.vue"; const props = defineProps({ model: Object,