|
@@ -16,7 +16,7 @@ import { NodeRenderer } from '../node-renderer.jsx';
|
|
|
import './echo-node.css';
|
|
import './echo-node.css';
|
|
|
|
|
|
|
|
export function EchoNode(props) {
|
|
export function EchoNode(props) {
|
|
|
- const { node, connections, onPortMouseDown, onPortMouseUp } = props;
|
|
|
|
|
|
|
+ const { node, connections, onPortMouseDown, onPortMouseUp, onNodeUpdate } = props;
|
|
|
const [segments, setSegments] = useState([]);
|
|
const [segments, setSegments] = useState([]);
|
|
|
|
|
|
|
|
console.log(`🎨 [EchoNode] 渲染 Echo 节点:`, { id: node.id, x: node.x, y: node.y, value: node.data?.value });
|
|
console.log(`🎨 [EchoNode] 渲染 Echo 节点:`, { id: node.id, x: node.x, y: node.y, value: node.data?.value });
|
|
@@ -38,6 +38,27 @@ export function EchoNode(props) {
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ // 添加新变量的处理函数
|
|
|
|
|
+ const handleAddVariable = (e) => {
|
|
|
|
|
+ e.stopPropagation();
|
|
|
|
|
+ console.log(`➕ [EchoNode] 添加新变量`);
|
|
|
|
|
+
|
|
|
|
|
+ // 在当前 value 的末尾添加一个新的变量占位符
|
|
|
|
|
+ const currentValue = node.data?.value || '';
|
|
|
|
|
+ const newVarName = `var${segments.length + 1}`;
|
|
|
|
|
+ const newValue = currentValue + `{{${newVarName}}}`;
|
|
|
|
|
+
|
|
|
|
|
+ console.log(` 📝 更新 value: "${currentValue}" -> "${newValue}"`);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新节点数据
|
|
|
|
|
+ if (onNodeUpdate) {
|
|
|
|
|
+ onNodeUpdate(node.id, {
|
|
|
|
|
+ ...node.data,
|
|
|
|
|
+ value: newValue
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
// 数据端口
|
|
// 数据端口
|
|
|
const dataPorts = node.inputs?.filter(p => p.type === 'data') || [];
|
|
const dataPorts = node.inputs?.filter(p => p.type === 'data') || [];
|
|
|
|
|
|
|
@@ -51,88 +72,102 @@ export function EchoNode(props) {
|
|
|
console.log(` 🎨 [EchoNode renderCustomBody] 开始渲染,segments 数量: ${segments.length}, dataPorts 数量: ${dataPorts.length}`);
|
|
console.log(` 🎨 [EchoNode renderCustomBody] 开始渲染,segments 数量: ${segments.length}, dataPorts 数量: ${dataPorts.length}`);
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
- <div className="Blueprint-echo-node-content">
|
|
|
|
|
- {segments.map((segment, index) => {
|
|
|
|
|
- const port = dataPorts.find(p => p.segmentIndex === index);
|
|
|
|
|
- console.log(` 🔍 渲染 segment[${index}]:`, segment, `找到的 port:`, port);
|
|
|
|
|
-
|
|
|
|
|
- if (!port) {
|
|
|
|
|
- console.log(` ⚠️ segment[${index}] 没有对应的 port,跳过渲染`);
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const connected = isPortConnected(port.id);
|
|
|
|
|
- const portClass = 'port-string';
|
|
|
|
|
-
|
|
|
|
|
- // 文本片段:空心圆 + 输入框(既可输入也可连接)
|
|
|
|
|
- if (segment.type === 'text') {
|
|
|
|
|
- console.log(` ✅ 渲染 segment[${index}] (text) - 空心圆 + 输入框`);
|
|
|
|
|
- return (
|
|
|
|
|
- <div key={index} className="Blueprint-echo-segment">
|
|
|
|
|
- <div className="Blueprint-echo-text-segment">
|
|
|
|
|
- <div
|
|
|
|
|
- className={`Blueprint-node-port input ${portClass} ${connected ? 'connected' : 'disconnected'}`}
|
|
|
|
|
- data-port-type="data"
|
|
|
|
|
- onMouseDown={(e) => {
|
|
|
|
|
- e.stopPropagation();
|
|
|
|
|
- onPortMouseDown?.(node.id, port.id);
|
|
|
|
|
- }}
|
|
|
|
|
- onMouseUp={(e) => {
|
|
|
|
|
- e.stopPropagation();
|
|
|
|
|
- onPortMouseUp?.(node.id, port.id);
|
|
|
|
|
- }}
|
|
|
|
|
- title="文本输入(可连接变量)"
|
|
|
|
|
- >
|
|
|
|
|
- <div className="Blueprint-node-port-dot hollow"></div>
|
|
|
|
|
|
|
+ <>
|
|
|
|
|
+ <div className="Blueprint-echo-node-content">
|
|
|
|
|
+ {segments.map((segment, index) => {
|
|
|
|
|
+ const port = dataPorts.find(p => p.segmentIndex === index);
|
|
|
|
|
+ console.log(` 🔍 渲染 segment[${index}]:`, segment, `找到的 port:`, port);
|
|
|
|
|
+
|
|
|
|
|
+ if (!port) {
|
|
|
|
|
+ console.log(` ⚠️ segment[${index}] 没有对应的 port,跳过渲染`);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const connected = isPortConnected(port.id);
|
|
|
|
|
+ const portClass = 'port-string';
|
|
|
|
|
+
|
|
|
|
|
+ // 文本片段:空心圆 + 输入框(既可输入也可连接)
|
|
|
|
|
+ if (segment.type === 'text') {
|
|
|
|
|
+ console.log(` ✅ 渲染 segment[${index}] (text) - 空心圆 + 输入框`);
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div key={index} className="Blueprint-echo-segment">
|
|
|
|
|
+ <div className="Blueprint-echo-text-segment">
|
|
|
|
|
+ <div
|
|
|
|
|
+ className={`Blueprint-node-port input ${portClass} ${connected ? 'connected' : 'disconnected'}`}
|
|
|
|
|
+ data-port-type="data"
|
|
|
|
|
+ onMouseDown={(e) => {
|
|
|
|
|
+ e.stopPropagation();
|
|
|
|
|
+ onPortMouseDown?.(node.id, port.id);
|
|
|
|
|
+ }}
|
|
|
|
|
+ onMouseUp={(e) => {
|
|
|
|
|
+ e.stopPropagation();
|
|
|
|
|
+ onPortMouseUp?.(node.id, port.id);
|
|
|
|
|
+ }}
|
|
|
|
|
+ title="文本输入(可连接变量)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div className="Blueprint-node-port-dot hollow"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <input
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ className="Blueprint-echo-text-input"
|
|
|
|
|
+ defaultValue={segment.content}
|
|
|
|
|
+ placeholder="文本"
|
|
|
|
|
+ onClick={(e) => e.stopPropagation()}
|
|
|
|
|
+ onMouseDown={(e) => e.stopPropagation()}
|
|
|
|
|
+ onChange={(e) => {
|
|
|
|
|
+ // TODO: 更新 value 字段
|
|
|
|
|
+ const newValue = e.target.value;
|
|
|
|
|
+ // 需要重新组合整个 value
|
|
|
|
|
+ }}
|
|
|
|
|
+ />
|
|
|
</div>
|
|
</div>
|
|
|
- <input
|
|
|
|
|
- type="text"
|
|
|
|
|
- className="Blueprint-echo-text-input"
|
|
|
|
|
- defaultValue={segment.content}
|
|
|
|
|
- placeholder="文本"
|
|
|
|
|
- onClick={(e) => e.stopPropagation()}
|
|
|
|
|
- onMouseDown={(e) => e.stopPropagation()}
|
|
|
|
|
- onChange={(e) => {
|
|
|
|
|
- // TODO: 更新 value 字段
|
|
|
|
|
- const newValue = e.target.value;
|
|
|
|
|
- // 需要重新组合整个 value
|
|
|
|
|
- }}
|
|
|
|
|
- />
|
|
|
|
|
</div>
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 变量引用:实心圆 + 标签(专门连接变量)
|
|
|
|
|
- if (segment.type === 'variable') {
|
|
|
|
|
- console.log(` ✅ 渲染 segment[${index}] (variable) - 实心圆 + 标签`);
|
|
|
|
|
- return (
|
|
|
|
|
- <div key={index} className="Blueprint-echo-segment">
|
|
|
|
|
- <div className="Blueprint-echo-variable-segment">
|
|
|
|
|
- <div
|
|
|
|
|
- className={`Blueprint-node-port input ${portClass} ${connected ? 'connected' : 'disconnected'}`}
|
|
|
|
|
- data-port-type="data"
|
|
|
|
|
- onMouseDown={(e) => {
|
|
|
|
|
- e.stopPropagation();
|
|
|
|
|
- onPortMouseDown?.(node.id, port.id);
|
|
|
|
|
- }}
|
|
|
|
|
- onMouseUp={(e) => {
|
|
|
|
|
- e.stopPropagation();
|
|
|
|
|
- onPortMouseUp?.(node.id, port.id);
|
|
|
|
|
- }}
|
|
|
|
|
- title={`变量: ${segment.content}`}
|
|
|
|
|
- >
|
|
|
|
|
- <div className="Blueprint-node-port-dot solid"></div>
|
|
|
|
|
- <span className="Blueprint-node-port-label">{segment.content}</span>
|
|
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 变量引用:实心圆 + 标签(专门连接变量)
|
|
|
|
|
+ if (segment.type === 'variable') {
|
|
|
|
|
+ console.log(` ✅ 渲染 segment[${index}] (variable) - 实心圆 + 标签`);
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div key={index} className="Blueprint-echo-segment">
|
|
|
|
|
+ <div className="Blueprint-echo-variable-segment">
|
|
|
|
|
+ <div
|
|
|
|
|
+ className={`Blueprint-node-port input ${portClass} ${connected ? 'connected' : 'disconnected'}`}
|
|
|
|
|
+ data-port-type="data"
|
|
|
|
|
+ onMouseDown={(e) => {
|
|
|
|
|
+ e.stopPropagation();
|
|
|
|
|
+ onPortMouseDown?.(node.id, port.id);
|
|
|
|
|
+ }}
|
|
|
|
|
+ onMouseUp={(e) => {
|
|
|
|
|
+ e.stopPropagation();
|
|
|
|
|
+ onPortMouseUp?.(node.id, port.id);
|
|
|
|
|
+ }}
|
|
|
|
|
+ title={`变量: ${segment.content}`}
|
|
|
|
|
+ >
|
|
|
|
|
+ <div className="Blueprint-node-port-dot solid"></div>
|
|
|
|
|
+ <span className="Blueprint-node-port-label">{segment.content}</span>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return null;
|
|
|
|
|
- })}
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return null;
|
|
|
|
|
+ })}
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 添加变量按钮 */}
|
|
|
|
|
+ <div className="Blueprint-echo-node-footer">
|
|
|
|
|
+ <button
|
|
|
|
|
+ className="Blueprint-echo-add-button"
|
|
|
|
|
+ onClick={handleAddVariable}
|
|
|
|
|
+ onMouseDown={(e) => e.stopPropagation()}
|
|
|
|
|
+ title="添加变量"
|
|
|
|
|
+ >
|
|
|
|
|
+ +
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </>
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|
|
|
|
|
|