fix: 修复更改节点名称导致重新渲染的bug

This commit is contained in:
zhanghao 2025-12-17 13:39:02 +08:00
parent 11f369452c
commit d1742ae98c
6 changed files with 248 additions and 196 deletions

View File

@ -11,7 +11,7 @@
/></el-icon> /></el-icon>
</div> </div>
<div class="input_name_container" v-else> <div class="input_name_container" v-else>
<el-input v-model="nodeName" /> <el-input v-model="nodeName" @keydown="handleInputKeydown" />
<el-button <el-button
class="input_name_select" class="input_name_select"
circle circle
@ -112,17 +112,13 @@ const props = defineProps({
} }
}) })
const emits = defineEmits(['zoom']) const emits = defineEmits(['zoom', 'setNodeName'])
const showTextTitle = ref(true) const showTextTitle = ref(true)
const nodeName = ref(props.nodeProperties.name || props.nodeName) const nodeName = ref(props.nodeProperties.name || props.nodeName)
const confirmNodeName = () => { const confirmNodeName = () => {
const properties = lf.getProperties(props.nodeId) emits('setNodeName', nodeName.value)
lf.setProperties(props.nodeId, {
...properties,
name: nodeName.value
})
showTextTitle.value = true showTextTitle.value = true
} }
@ -165,6 +161,15 @@ const execute = () => {
}); });
document.dispatchEvent(myEvent); document.dispatchEvent(myEvent);
} }
const handleInputKeydown = (e) => {
// Logic Flow
e.stopPropagation();
// Ctrl+V
if ((e.ctrlKey || e.metaKey) && e.key === "v") {
e.returnValue = true; //
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.title__container { .title__container {

View File

@ -39,6 +39,7 @@
:nodeDesc="props.properties.desc" :nodeDesc="props.properties.desc"
:zoom-state="nodeZoom" :zoom-state="nodeZoom"
@zoom="zoom" @zoom="zoom"
@setNodeName="setNodeName"
/> />
<div class="input__container" v-show="nodeZoom"> <div class="input__container" v-show="nodeZoom">
<div class="title"> <div class="title">
@ -293,6 +294,15 @@ const setNodeProperties = async () => {
} }
}; };
const setNodeName = (name) => {
const properties = lf.getProperties(props.model.id);
lf.setProperties(props.model.id, {
...properties,
name
});
emits("contentChange");
}
const nodeOperatingStatus = ref("NORMAL"); const nodeOperatingStatus = ref("NORMAL");
const inputJsonData = ref({}); const inputJsonData = ref({});
const outputJsonData = ref({}); const outputJsonData = ref({});

View File

@ -7,6 +7,7 @@
:nodeName="props.properties?.name || '循环'" :nodeName="props.properties?.name || '循环'"
nodeDesc="循环执行一系列任务,直至输出所有结果" nodeDesc="循环执行一系列任务,直至输出所有结果"
:showZoom="false" :showZoom="false"
@setNodeName="setNodeName"
/> />
<div class="loop__container"> <div class="loop__container">
<div> <div>
@ -198,6 +199,15 @@ const setNodeProperties = async () => {
} }
}; };
const setNodeName = (name) => {
const properties = lf.getProperties(props.model.id);
lf.setProperties(props.model.id, {
...properties,
name
});
emits("contentChange");
}
const visibleChange = async (value, index, quote) => { const visibleChange = async (value, index, quote) => {
if (value) { if (value) {
const option = getInput(props.model.id); const option = getInput(props.model.id);

View File

@ -27,6 +27,7 @@
:nodeDesc="props.properties.desc" :nodeDesc="props.properties.desc"
:zoom-state="nodeZoom" :zoom-state="nodeZoom"
@zoom="zoom" @zoom="zoom"
@setNodeName="setNodeName"
/> />
<div class="input__container" v-show="nodeZoom"> <div class="input__container" v-show="nodeZoom">
<div class="title"> <div class="title">
@ -194,6 +195,15 @@ const setNodeProperties = async () => {
} }
}; };
const setNodeName = (name) => {
const properties = lf.getProperties(props.model.id);
lf.setProperties(props.model.id, {
...properties,
name
});
emits("contentChange");
}
const nodeOperatingStatus = ref("NORMAL"); const nodeOperatingStatus = ref("NORMAL");
const inputJsonData = ref({}); const inputJsonData = ref({});
const outputJsonData = ref({}); const outputJsonData = ref({});

View File

@ -1,190 +1,197 @@
<template> <template>
<div class="node__container" > <div class="node__container" >
<!-- 状态栏 --> <!-- 状态栏 -->
<NodeTitle :icon="stopLoop" :nodeId="props.model.id" :nodeProperties="props.properties" :nodeName="props.properties?.name || '结束循环'" nodeDesc="用于立即终止当前所在的循环,跳出循环体" /> <NodeTitle :icon="stopLoop" :nodeId="props.model.id" :nodeProperties="props.properties" :nodeName="props.properties?.name || '结束循环'" nodeDesc="用于立即终止当前所在的循环,跳出循环体" @setNodeName="setNodeName" />
</div> </div>
</template> </template>
<script setup> <script setup>
import NodeTitle from '../../components/NodeTitle.vue' import NodeTitle from '../../components/NodeTitle.vue'
import stopLoop from '../../icon/stopLoop.svg' import stopLoop from '../../icon/stopLoop.svg'
const props = defineProps({ const props = defineProps({
model: Object, model: Object,
graphModel: Object, graphModel: Object,
properties: Object, properties: Object,
text: String, text: String,
}); });
const setNodeName = (name) => {
</script> const properties = lf.getProperties(props.model.id);
lf.setProperties(props.model.id, {
<style lang="scss" scoped> ...properties,
@keyframes rotateAnimation { name
from { });
transform: rotate(0deg); }
}
to { </script>
transform: rotate(360deg);
} <style lang="scss" scoped>
} @keyframes rotateAnimation {
from {
.node__container { transform: rotate(0deg);
width: 300px; }
height: auto; to {
background: #fff; transform: rotate(360deg);
padding: 12px; }
cursor: default; }
border-radius: 12px;
border: 2px solid white; .node__container {
box-shadow: 0 5px 15px 0#00000008; width: 300px;
position: relative; height: auto;
background: #fff;
.title__container { padding: 12px;
.title { cursor: default;
display: flex; border-radius: 12px;
align-items: center; border: 2px solid white;
box-shadow: 0 5px 15px 0#00000008;
img { position: relative;
width: 24px;
height: 24px; .title__container {
} .title {
display: flex;
.text { align-items: center;
font-size: 16px;
font-weight: bold; img {
margin-left: 12px; width: 24px;
} height: 24px;
} }
.subTitle { .text {
color: #737a87; font-size: 16px;
font-size: 12px; font-weight: bold;
margin: 8px 0; margin-left: 12px;
} }
}
}
.subTitle {
.input__container { color: #737a87;
width: 100%; font-size: 12px;
background-color: #fafbfc; margin: 8px 0;
padding: 0 16px; }
border-radius: 8px;
box-sizing: border-box; }
.title { .input__container {
height: 32px; width: 100%;
display: flex; background-color: #fafbfc;
align-items: center; padding: 0 16px;
justify-content: space-between; border-radius: 8px;
box-sizing: border-box;
.left {
display: flex; .title {
align-items: center; height: 32px;
display: flex;
.tag { align-items: center;
width: 3px; justify-content: space-between;
height: 16px;
background: #1664ff; .left {
border-radius: 0 4px 4px 0; display: flex;
margin-right: 12px; align-items: center;
}
.tag {
.text { width: 3px;
font-size: 16px; height: 16px;
font-weight: 700; background: #1664ff;
color: #0c0d0e; border-radius: 0 4px 4px 0;
} margin-right: 12px;
} }
.right { .text {
.addFormItem { font-size: 16px;
border: none; font-weight: 700;
background: transparent; color: #0c0d0e;
cursor: pointer; }
} }
}
} .right {
.addFormItem {
.form__container { border: none;
margin: 12px 0; background: transparent;
cursor: pointer;
.sub-properties { }
margin-left: 10px; }
.zw { }
margin-left: 15px;
&::before { .form__container {
content: ""; margin: 12px 0;
position: absolute;
left: 0; .sub-properties {
top: -4px; margin-left: 10px;
width: 10px; .zw {
border-left: 1px solid gray; margin-left: 15px;
border-bottom: 1px solid gray; &::before {
border-bottom-left-radius: 4px; content: "";
background-color: transparent; position: absolute;
height: 24px; left: 0;
} top: -4px;
} width: 10px;
} border-left: 1px solid gray;
border-bottom: 1px solid gray;
.gSon-properties { border-bottom-left-radius: 4px;
margin-left: 10px; background-color: transparent;
.zw { height: 24px;
margin-left: 15px; }
&::before { }
content: ""; }
position: absolute;
left: 0; .gSon-properties {
top: -4px; margin-left: 10px;
width: 10px; .zw {
border-left: 1px solid gray; margin-left: 15px;
border-bottom: 1px solid gray; &::before {
border-bottom-left-radius: 4px; content: "";
background-color: transparent; position: absolute;
height: 24px; left: 0;
} top: -4px;
} width: 10px;
} border-left: 1px solid gray;
border-bottom: 1px solid gray;
.deleteBtn { border-bottom-left-radius: 4px;
margin-bottom: 22px; background-color: transparent;
cursor: pointer; height: 24px;
} }
}
.addBtn { }
margin-bottom: 22px;
cursor: pointer; .deleteBtn {
} margin-bottom: 22px;
cursor: pointer;
.el-row { }
align-items: end;
} .addBtn {
margin-bottom: 22px;
.el-input { cursor: pointer;
--el-input-width: 170px; }
}
.el-row {
.el-select { align-items: end;
--el-select-width: 170px; }
}
} .el-input {
} --el-input-width: 170px;
} }
</style>
.el-select {
<style lang="scss"> --el-select-width: 170px;
.popover__container { }
min-width: 300px !important; }
}
.params__container { }
margin-bottom: 12px; </style>
.paramsTitle { <style lang="scss">
color: #0c0d0e; .popover__container {
font-size: 14px; min-width: 300px !important;
font-weight: 500;
} .params__container {
} margin-bottom: 12px;
}
.paramsTitle {
color: #0c0d0e;
font-size: 14px;
font-weight: 500;
}
}
}
</style> </style>

View File

@ -14,6 +14,7 @@
:nodeProperties="props.properties" :nodeProperties="props.properties"
:nodeName="props.properties?.name || '分支'" :nodeName="props.properties?.name || '分支'"
nodeDesc="连接多个下游分支,根据设定的条件按照顺序查找的方式来匹配运行的分支,如果匹配到某条件则只运行该条件对应的分支,否则继续匹配下一条件直至结束" nodeDesc="连接多个下游分支,根据设定的条件按照顺序查找的方式来匹配运行的分支,如果匹配到某条件则只运行该条件对应的分支,否则继续匹配下一条件直至结束"
@setNodeName="setNodeName"
/> />
<div class="condition_title_container"> <div class="condition_title_container">
<div class="left"> <div class="left">
@ -362,6 +363,15 @@ const setNodeProperties = async () => {
} }
}; };
const setNodeName = (name) => {
const properties = lf.getProperties(props.model.id);
lf.setProperties(props.model.id, {
...properties,
name
});
emits("contentChange");
}
const visibleChange = (value) => { const visibleChange = (value) => {
if (value) { if (value) {
const option = getInput(props.model.id); const option = getInput(props.model.id);