From 592ebddc251aaa95f7aa24df1671c42b306aed82 Mon Sep 17 00:00:00 2001 From: zhanghao <774378400@qq.com> Date: Thu, 13 Nov 2025 21:55:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9C=BA=E5=99=A8=E4=BA=BA=E8=AF=B4?= =?UTF-8?q?=E8=AF=9D=E5=92=8C=E8=A1=A8=E6=83=85=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/flow/config.js | 69 ++++++++++++++++++++- src/views/flow/icon/expression.svg | 1 + src/views/flow/nodes/common/serviceNode.vue | 14 ++++- 3 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 src/views/flow/icon/expression.svg diff --git a/src/views/flow/config.js b/src/views/flow/config.js index 2b528ad..46b30e1 100644 --- a/src/views/flow/config.js +++ b/src/views/flow/config.js @@ -17,6 +17,7 @@ import awakenSvg from './icon/awaken.svg' import dialogueSvg from './icon/dialogue.svg' import audioSvg from './icon/audio.svg' import touchSvg from './icon/touch.svg' +import expressionSvg from './icon/expression.svg' import { v4 as randomUUID } from 'uuid' @@ -74,11 +75,39 @@ export const registerCustomizeNode = (lf) => { }; const deviceOptions = () => { - return ['cam1', 'cam2', 'cam3', 'cam4'] + return [{ + value: 'cam1', + label: 'cam1' + }, { + value: 'cam2', + label: 'cam2' + }, { + value: 'cam3', + label: 'cam3' + }, { + value: 'cam4', + label: 'cam4' + }] } const audioOptions = () => { - return ['spk1'] + return [{ + value: 'spk1', + label: 'spk1' + }] +} + +const expressOptions = () => { + return [{ + value: 1, + label: '高兴' + }, { + value: 2, + label: '惊讶' + }, { + value: 3, + label: '疲惫' + }] } export const collapseList = [ @@ -365,7 +394,41 @@ export const collapseList = [ { name: "touchParams", type: "input", input: "", disabled: true } ], outputType: 'json', - } + }, + { + icon: expressionSvg, + name: "开始说话", + type: "serviceNode", + desc: "控制机器人说话", + action: 'BIO_HEAD_SPEAK_START', + nodeParams: [ + { name: "deviceId", type: "input", input: "", disabled: true } + ], + outputType: 'json', + }, + { + icon: expressionSvg, + name: "停止说话", + type: "serviceNode", + desc: "停止机器人说话", + action: 'BIO_HEAD_SPEAK_STOP', + nodeParams: [ + { name: "deviceId", type: "input", input: "", disabled: true } + ], + outputType: 'json', + }, + { + icon: expressionSvg, + name: "表情", + type: "serviceNode", + desc: "控制机器人的面部表情", + action: 'BIO_HEAD_SPECIAL_EXPRESSION', + nodeParams: [ + { name: "deviceId", type: "input", input: "", disabled: true }, + { name: "expressKey", type: "input",componentType: 'select', selectOptions: expressOptions(), disabled: true }, + ], + outputType: 'json', + }, ], }, ] diff --git a/src/views/flow/icon/expression.svg b/src/views/flow/icon/expression.svg new file mode 100644 index 0000000..ae84256 --- /dev/null +++ b/src/views/flow/icon/expression.svg @@ -0,0 +1 @@ + \ 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 dab8b6c..6e0956d 100644 --- a/src/views/flow/nodes/common/serviceNode.vue +++ b/src/views/flow/nodes/common/serviceNode.vue @@ -62,6 +62,7 @@ @@ -81,9 +82,9 @@ > - + - + { + // 阻止事件冒泡到 Logic Flow 节点,避免被其事件拦截 + e.stopPropagation(); + // 可选:明确放行 Ctrl+V(增强兼容性) + if ((e.ctrlKey || e.metaKey) && e.key === 'v') { + e.returnValue = true; // 允许默认粘贴行为 + } +} + onMounted(() => { emitter.on("changeNodeState", (data) => { if (data.nodeId === props.model.id) {