CMVR-IOT-UI/src/views/flow/components/NodeTitle.vue

272 lines
6.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="title__container">
<div class="title">
<div class="left">
<img :src="imageUrl()" alt="" />
<div class="text__container">
<div class="text__title" v-if="showTextTitle">
<span class="text">{{ localName }}</span>
<el-icon class="editIcon" @click="startEditing"><EditPen/></el-icon>
</div>
<div class="input_name_container" v-else >
<el-input
v-model="localName"
@focus="handleInputFocus"
@keydown="handleInputKeydown"
@click.stop
@mousedown.stop
/>
<el-button
class="input_name_select"
circle
size="small"
@click="confirmNodeName"
>
<el-icon><Select /></el-icon>
</el-button>
<el-button
class="input_name_closeBold"
circle
size="small"
@click="cancelNodeName"
>
<el-icon><CloseBold /></el-icon>
</el-button>
</div>
</div>
</div>
<div class="right">
<el-tooltip
class="box-item"
effect="dark"
content="执行"
placement="top"
>
<el-button v-if="nodeType && nodeType !=='NONE'" circle @click="execute">
<el-icon>
<VideoPlay />
</el-icon>
</el-button>
</el-tooltip>
<el-tooltip
class="box-item"
effect="dark"
content="删除"
placement="top"
>
<el-button circle @click="deleteNode">
<el-icon><Delete /></el-icon>
</el-button>
</el-tooltip>
</div>
</div>
<div class="subTitle">{{ props.nodeDesc }}</div>
</div>
</template>
<script setup lang="js">
import { onUnmounted, ref } from 'vue'
import { EditPen, Select, CloseBold, Delete, VideoPlay } from '@element-plus/icons-vue'
import { ElMessageBox } from 'element-plus'
import { computed } from 'vue'
import { emitter } from "@/utils/eventBus";
const props = defineProps({
icon: {
type: String,
default: ''
},
nodeId: {
type: String,
default: ''
},
nodeProperties: {
type: Object,
default: () => {}
},
nodeDesc: {
type: String,
default: ''
},
nodeName: {
type: String,
default: ''
},
nodeType: {
type: String,
default: ''
},
})
const emits = defineEmits(['setNodeName'])
const showTextTitle = ref(true)
const localName = ref('')
// 开始编辑
const startEditing = () => {
showTextTitle.value = false
}
const confirmNodeName = () => {
emits('setNodeName', localName.value)
showTextTitle.value = true
}
const cancelNodeName = () => {
localName.value = props.nodeProperties?.name || props.nodeName
showTextTitle.value = true
}
const deleteNode = () => {
ElMessageBox.confirm(
'是否删除该节点?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
if (props.nodeType === 'selectArea') {
const children = lf.getNodeModelById(props.nodeId).children
lf.getNodeModelById(props.nodeId).children = []
children.forEach(item => {
lf.getNodeModelById(item).draggable = true
})
}
lf.deleteNode(props.nodeId);
emitter.emit('deleteNode', props.nodeId);
})
}
const execute = () => {
const myEvent = new CustomEvent('singleNodeExecution', {
bubbles: false, // 是否冒泡(默认 false
cancelable: false, // 是否可被 preventDefault() 取消(默认 false
detail: { ...props.nodeProperties } // 自定义数据(任意类型,通过 event.detail 读取)
});
document.dispatchEvent(myEvent);
}
const handleInputFocus = (e) => {
// 阻止事件冒泡到流程画布
e.stopPropagation()
e.preventDefault()
}
const handleInputKeydown = (e) => {
// 阻止事件冒泡到流程节点,避免被画布快捷键拦截
e.stopPropagation();
// 可选:明确放行 Ctrl+V增强兼容性
if ((e.ctrlKey || e.metaKey) && e.key === "v") {
e.returnValue = true; // 允许默认粘贴行为
}
}
const imageUrl = () => {
return new URL(props.icon, import.meta.url).href;
}
onMounted(() => {
localName.value = props.nodeProperties?.name || props.nodeName
})
onUnmounted(() => {
emitter.off("deleteNode");
})
</script>
<style lang="scss" scoped>
.title__container {
.title {
display: flex;
align-items: center;
justify-content: space-between;
.left {
display: flex;
align-items: center; // 添加垂直居中
img {
width: 24px;
height: 24px;
}
.text__container {
.text__title {
display: flex;
align-items: center;
.text {
font-size: 16px;
font-weight: bold;
margin: 0 12px;
}
.editIcon {
cursor: pointer;
}
}
.input_name_container {
display: flex;
align-items: center;
.el-input {
margin-left: 12px;
width: 120px;
// 确保输入框有更高的 z-index
position: relative;
z-index: 1000;
// 覆盖 Element Plus 的默认样式,确保焦点状态明显
:deep(.el-input__wrapper) {
box-shadow: 0 0 0 1px #409eff !important;
&:focus-within {
box-shadow: 0 0 0 2px #409eff !important;
}
}
}
.input_name_select {
color: #00b42a;
margin-left: 4px;
border: none;
}
.input_name_closeBold {
color: #f53f3f;
margin-left: 4px;
border: none;
}
}
}
}
.right {
cursor: pointer;
.el-button {
border: none;
font-size: 24px;
}
}
}
.subTitle {
color: #737a87;
font-size: 12px;
margin: 8px 0;
}
}
// 添加全局样式,确保输入框焦点不被其他元素干扰
:global(.lf-node) {
.el-input__inner {
user-select: text !important;
}
}
</style>