1
This commit is contained in:
parent
d8cc3c0983
commit
debef2f881
@ -1,13 +1,13 @@
|
||||
import React, { useEffect, ReactNode } from 'react';
|
||||
import { Drawer, Form, Input, Select, Button, Space, Divider, Tooltip } from 'antd';
|
||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||
import { Cell } from '@antv/x6';
|
||||
import { NodeDefinition } from '../types';
|
||||
import React, {useEffect, ReactNode} from 'react';
|
||||
import {Drawer, Form, Input, Select, Button, Space, Divider, Tooltip} from 'antd';
|
||||
import {InfoCircleOutlined} from '@ant-design/icons';
|
||||
import {Cell} from '@antv/x6';
|
||||
import {NodeDefinitionResponse} from "@/pages/Workflow/NodeDesign/types";
|
||||
|
||||
interface NodeConfigDrawerProps {
|
||||
visible: boolean;
|
||||
node: Cell | null;
|
||||
nodeDefinition: NodeDefinition | null;
|
||||
nodeDefinition: NodeDefinitionResponse | null;
|
||||
onOk: (values: any) => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
@ -22,11 +22,11 @@ interface SchemaProperty {
|
||||
}
|
||||
|
||||
const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
|
||||
visible,
|
||||
node,
|
||||
nodeDefinition,
|
||||
onOk,
|
||||
onCancel,
|
||||
visible,
|
||||
node,
|
||||
nodeDefinition,
|
||||
onOk,
|
||||
onCancel,
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
@ -34,19 +34,8 @@ const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
|
||||
if (visible && node && nodeDefinition) {
|
||||
const currentConfig = node.getProp('config') || {};
|
||||
if (!currentConfig.name) {
|
||||
currentConfig.name = nodeDefinition.name;
|
||||
currentConfig.name = nodeDefinition.nodeName;
|
||||
}
|
||||
// 从节点定义中获取 delegate 的默认值
|
||||
const defaultDelegate = nodeDefinition.graphConfig.configSchema?.properties?.delegate?.default;
|
||||
// 优先使用当前配置的值,如果没有则使用默认值
|
||||
const delegateValue = currentConfig.delegate !== undefined ? currentConfig.delegate : defaultDelegate;
|
||||
|
||||
// 设置表单值,包括 code 和其他配置项
|
||||
form.setFieldsValue({
|
||||
code: node.getProp('code') === undefined ? nodeDefinition.graphConfig.code : node.getProp('code'),
|
||||
delegate: delegateValue, // 使用当前值或默认值
|
||||
...currentConfig
|
||||
});
|
||||
}
|
||||
}, [visible, node, nodeDefinition, form]);
|
||||
|
||||
@ -73,12 +62,12 @@ const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
|
||||
{property.title}
|
||||
{property.description && (
|
||||
<Tooltip title={property.description}>
|
||||
<InfoCircleOutlined />
|
||||
<InfoCircleOutlined/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
rules: [{ required, message: `请输入${property.title}` }],
|
||||
rules: [{required, message: `请输入${property.title}`}],
|
||||
};
|
||||
|
||||
switch (property.type) {
|
||||
@ -99,16 +88,16 @@ const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
|
||||
return (
|
||||
<Form.Item key={key} {...baseProps}>
|
||||
{property.format === 'textarea' ? (
|
||||
<Input.TextArea rows={3} />
|
||||
<Input.TextArea rows={3}/>
|
||||
) : (
|
||||
<Input />
|
||||
<Input/>
|
||||
)}
|
||||
</Form.Item>
|
||||
);
|
||||
case 'number':
|
||||
return (
|
||||
<Form.Item key={key} {...baseProps}>
|
||||
<Input type="number" />
|
||||
<Input type="number"/>
|
||||
</Form.Item>
|
||||
);
|
||||
case 'boolean':
|
||||
@ -131,7 +120,7 @@ const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
const { configSchema } = nodeDefinition.graphConfig;
|
||||
const {configSchema} = nodeDefinition.graphConfig;
|
||||
console.log('NodeConfigModal - Rendering form items with schema:', configSchema);
|
||||
|
||||
const formItems: ReactNode[] = [];
|
||||
@ -155,7 +144,7 @@ const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
|
||||
const renderNodeDetails = () => {
|
||||
if (!nodeDefinition?.graphConfig.details) return null;
|
||||
|
||||
const { details } = nodeDefinition.graphConfig;
|
||||
const {details} = nodeDefinition.graphConfig;
|
||||
return (
|
||||
<>
|
||||
<Divider orientation="left">节点说明</Divider>
|
||||
@ -188,7 +177,7 @@ const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
title={`编辑节点 - ${nodeDefinition?.graphConfig.name || ''}`}
|
||||
title={`编辑节点 - ${nodeDefinition?.nodeName || ''}`}
|
||||
placement="right"
|
||||
width={480}
|
||||
onClose={handleCancel}
|
||||
@ -210,16 +199,14 @@ const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
|
||||
initialValues={{}}
|
||||
>
|
||||
<Form.Item name="code" hidden>
|
||||
<Input />
|
||||
<Input/>
|
||||
</Form.Item>
|
||||
<Form.Item name="delegate" hidden>
|
||||
<Input />
|
||||
<Input/>
|
||||
</Form.Item>
|
||||
{nodeDefinition?.graphConfig.configSchema &&
|
||||
Object.entries(nodeDefinition.graphConfig.configSchema.properties).map(([key, property]) => {
|
||||
// 跳过 code 和 delegate 字段的显示
|
||||
if (key === 'code' || key === 'delegate') return null;
|
||||
const required = nodeDefinition.graphConfig.configSchema.required?.includes(key) || false;
|
||||
{nodeDefinition?.panelVariablesSchema &&
|
||||
Object.entries(nodeDefinition.panelVariablesSchema.properties).map(([key, property]) => {
|
||||
const required = nodeDefinition.panelVariablesSchema?.properties.required?.includes(key) || false;
|
||||
return renderFormItem(key, property as SchemaProperty, required);
|
||||
})}
|
||||
</Form>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import {Card, Collapse, Tooltip, message, Spin} from 'antd';
|
||||
import {Card, Collapse, Tooltip, message} from 'antd';
|
||||
import type {NodeDefinition, NodeCategory} from '../types';
|
||||
import {
|
||||
PlayCircleOutlined,
|
||||
@ -13,6 +13,7 @@ import {
|
||||
BranchesOutlined
|
||||
} from '@ant-design/icons';
|
||||
import {getNodeDefinitionList} from "@/pages/Workflow/Definition/Design/service";
|
||||
import {NodeDefinitionResponse} from "@/pages/Workflow/NodeDesign/types";
|
||||
|
||||
const {Panel} = Collapse;
|
||||
|
||||
@ -53,19 +54,20 @@ const categoryConfig: Record<NodeCategory, {
|
||||
};
|
||||
|
||||
interface NodePanelProps {
|
||||
onNodeDragStart?: (node: NodeDefinition, e: React.DragEvent) => void,
|
||||
nodeDefinitions?: NodeDefinition[]
|
||||
onNodeDragStart?: (node: NodeDefinitionResponse, e: React.DragEvent) => void,
|
||||
nodeDefinitions?: NodeDefinitionResponse[]
|
||||
}
|
||||
|
||||
const NodePanel: React.FC<NodePanelProps> = ({onNodeDragStart}) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [nodeDefinitions, setNodeDefinitions] = useState<NodeDefinition[]>([]);
|
||||
const [nodeDefinitions, setNodeDefinitions] = useState<NodeDefinitionResponse[]>([]);
|
||||
|
||||
// 加载节点定义列表
|
||||
const loadNodeDefinitions = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const data = await getNodeDefinitionList();
|
||||
console.log(data)
|
||||
setNodeDefinitions(data);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@ -87,29 +89,29 @@ const NodePanel: React.FC<NodePanelProps> = ({onNodeDragStart}) => {
|
||||
}
|
||||
acc[node.category].push(node);
|
||||
return acc;
|
||||
}, {} as Record<NodeCategory, NodeDefinition[]>);
|
||||
}, {} as Record<NodeCategory, NodeDefinitionResponse[]>);
|
||||
|
||||
// 处理节点拖拽开始事件
|
||||
const handleDragStart = (node: NodeDefinition, e: React.DragEvent) => {
|
||||
const handleDragStart = (node: NodeDefinitionResponse, e: React.DragEvent) => {
|
||||
e.dataTransfer.setData('node', JSON.stringify(node));
|
||||
onNodeDragStart?.(node, e);
|
||||
};
|
||||
|
||||
// 渲染节点图标
|
||||
const renderNodeIcon = (node: NodeDefinition) => {
|
||||
const iconName = node.graphConfig.uiSchema.style.icon;
|
||||
const renderNodeIcon = (node: NodeDefinitionResponse) => {
|
||||
const iconName = node.uiVariables?.style.icon;
|
||||
// 首先尝试使用配置的图标
|
||||
let IconComponent = iconMap[iconName];
|
||||
|
||||
// 如果没有找到对应的图标,使用节点类型对应的默认图标
|
||||
if (!IconComponent) {
|
||||
IconComponent = typeIconMap[node.type] || AppstoreOutlined;
|
||||
IconComponent = typeIconMap[node.nodeType] || AppstoreOutlined;
|
||||
}
|
||||
|
||||
return (
|
||||
<IconComponent
|
||||
style={{
|
||||
color: node.graphConfig.uiSchema.style.iconColor || '#1890ff',
|
||||
color: node.uiVariables?.style.iconColor || '#1890ff',
|
||||
fontSize: '16px',
|
||||
marginRight: '6px'
|
||||
}}
|
||||
@ -117,17 +119,17 @@ const NodePanel: React.FC<NodePanelProps> = ({onNodeDragStart}) => {
|
||||
);
|
||||
};
|
||||
|
||||
const getNodeItemStyle = (node: NodeDefinition) => ({
|
||||
const getNodeItemStyle = (node: NodeDefinitionResponse) => ({
|
||||
width: '100%',
|
||||
padding: '10px 12px',
|
||||
border: `1px solid ${node.graphConfig.uiSchema.style.stroke}`,
|
||||
border: `1px solid ${node.uiVariables?.style.stroke}`,
|
||||
borderRadius: '6px',
|
||||
cursor: 'move',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: '10px',
|
||||
background: node.graphConfig.uiSchema.style.fill,
|
||||
background: node.uiVariables?.style.fill,
|
||||
transition: 'all 0.3s',
|
||||
boxShadow: '0 1px 2px rgba(0,0,0,0.05)',
|
||||
'&:hover': {
|
||||
@ -163,19 +165,6 @@ const NodePanel: React.FC<NodePanelProps> = ({onNodeDragStart}) => {
|
||||
title={
|
||||
<div>
|
||||
<div style={{fontSize: '14px', fontWeight: 500}}>{node.description}</div>
|
||||
<div style={{marginTop: 12}}>
|
||||
<div style={{fontSize: '13px', color: '#8c8c8c'}}>功能特点:</div>
|
||||
<ul style={{
|
||||
paddingLeft: 16,
|
||||
margin: '8px 0',
|
||||
fontSize: '13px',
|
||||
color: '#595959'
|
||||
}}>
|
||||
{node.graphConfig.details.features.map((feature, index) => (
|
||||
<li key={index}>{feature}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
overlayStyle={tooltipStyle}
|
||||
@ -201,7 +190,7 @@ const NodePanel: React.FC<NodePanelProps> = ({onNodeDragStart}) => {
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
}}>{node.name}</span>
|
||||
}}>{node.nodeName}({node.nodeType})</span>
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
@ -43,6 +43,7 @@ import {
|
||||
DEFAULT_STYLES,
|
||||
} from './constants';
|
||||
import './index.less';
|
||||
import {NodeDefinitionResponse, NodeDesignDataResponse} from "@/pages/Workflow/NodeDesign/types";
|
||||
|
||||
const WorkflowDesign: React.FC = () => {
|
||||
const {id} = useParams<{ id: string }>();
|
||||
@ -52,10 +53,10 @@ const WorkflowDesign: React.FC = () => {
|
||||
const minimapContainerRef = useRef<HTMLDivElement>(null);
|
||||
const [graph, setGraph] = useState<Graph | null>(null);
|
||||
const [selectedNode, setSelectedNode] = useState<Cell | null>(null);
|
||||
const [selectedNodeDefinition, setSelectedNodeDefinition] = useState<NodeDefinition | null>(null);
|
||||
const [selectedNodeDefinition, setSelectedNodeDefinition] = useState<NodeDefinitionResponse | null>(null);
|
||||
const [configModalVisible, setConfigModalVisible] = useState(false);
|
||||
const [definitionData, setDefinitionData] = useState<any>(null);
|
||||
const [nodeDefinitions, setNodeDefinitions] = useState<NodeDefinition[]>([]);
|
||||
const [nodeDefinitions, setNodeDefinitions] = useState<NodeDefinitionResponse[]>([]);
|
||||
const [isNodeDefinitionsLoaded, setIsNodeDefinitionsLoaded] = useState(false);
|
||||
const [forceUpdate, setForceUpdate] = useState(false);
|
||||
const [scale, setScale] = useState(1);
|
||||
@ -571,9 +572,8 @@ const WorkflowDesign: React.FC = () => {
|
||||
// 节点双击事件
|
||||
graph.on('node:dblclick', ({node}) => {
|
||||
const nodeType = node.getProp('type');
|
||||
console.log(nodeType)
|
||||
// 从节点定义列表中找到对应的定义
|
||||
const nodeDefinition = nodeDefinitions.find(def => def.type === nodeType);
|
||||
const nodeDefinition = nodeDefinitions.find(def => def.nodeType === nodeType);
|
||||
if (nodeDefinition) {
|
||||
setSelectedNode(node);
|
||||
setSelectedNodeDefinition(nodeDefinition);
|
||||
@ -1027,7 +1027,7 @@ const WorkflowDesign: React.FC = () => {
|
||||
}, [graphContainerRef, id, nodeDefinitions, isNodeDefinitionsLoaded]);
|
||||
|
||||
// 处理节点拖拽开始
|
||||
const handleNodeDragStart = (node: NodeDefinition, e: React.DragEvent) => {
|
||||
const handleNodeDragStart = (node: NodeDefinitionResponse, e: React.DragEvent) => {
|
||||
e.dataTransfer.setData('node', JSON.stringify(node));
|
||||
};
|
||||
|
||||
@ -1043,6 +1043,7 @@ const WorkflowDesign: React.FC = () => {
|
||||
const node = JSON.parse(nodeData);
|
||||
const {clientX, clientY} = e;
|
||||
const point = graph.clientToLocal({x: clientX, y: clientY});
|
||||
console.log("dasdasd", graph, node, nodeDefinitions, point);
|
||||
addNodeToGraph(true, graph, node, nodeDefinitions, point);
|
||||
} catch (error) {
|
||||
console.error('创建节点失败:', error);
|
||||
|
||||
@ -5,7 +5,7 @@ import {convertPortConfig} from '../constants';
|
||||
* 添加节点到图形
|
||||
* @param isNew 是否为新节点
|
||||
* @param graph X6 Graph实例
|
||||
* @param workflowDefinitionNode 工作流节点定义
|
||||
* @param nodeDefinitions 工作流节点定义
|
||||
* @param workflowNodeDefinitionList 工作流节点定义列表
|
||||
* @param position 新节点的位置(可选)
|
||||
* @returns 创建的节点实例
|
||||
@ -13,13 +13,13 @@ import {convertPortConfig} from '../constants';
|
||||
export const addNodeToGraph = (
|
||||
isNew: boolean,
|
||||
graph: Graph,
|
||||
workflowDefinitionNode: any,
|
||||
nodeDefinitions: any,
|
||||
workflowNodeDefinitionList: any,
|
||||
position?: { x: number; y: number }
|
||||
) => {
|
||||
let nodeDefinition = workflowNodeDefinitionList.find(def => def.type === workflowDefinitionNode.type);
|
||||
let uiGraph = isNew ? nodeDefinition.graphConfig.uiSchema : workflowDefinitionNode.graph;
|
||||
|
||||
let nodeDefinition = workflowNodeDefinitionList.find(def => def.nodeType === nodeDefinitions.nodeType);
|
||||
let uiGraph = isNew ? nodeDefinition.uiVariables : nodeDefinitions.graph;
|
||||
console.log(uiGraph)
|
||||
// 根据形状类型设置正确的 shape
|
||||
let shape = 'rect'; // 默认使用矩形
|
||||
if (uiGraph.shape === 'circle') {
|
||||
@ -41,12 +41,12 @@ export const addNodeToGraph = (
|
||||
} : {})
|
||||
},
|
||||
label: {
|
||||
text: isNew ? nodeDefinition.name : workflowDefinitionNode.name
|
||||
text: isNew ? nodeDefinition.nodeName : nodeDefinitions.name
|
||||
},
|
||||
},
|
||||
shape,
|
||||
type: isNew ? nodeDefinition.type : workflowDefinitionNode.type,
|
||||
code: uiGraph.code,
|
||||
type: isNew ? nodeDefinition.nodeType : nodeDefinitions.type,
|
||||
code: uiGraph.nodeCode,
|
||||
ports: convertPortConfig(uiGraph.ports),
|
||||
nodeDefinition: nodeDefinition
|
||||
};
|
||||
@ -55,9 +55,9 @@ export const addNodeToGraph = (
|
||||
if (isNew && position) {
|
||||
// 新节点:使用传入的position
|
||||
Object.assign(nodeConfig, { x: position.x, y: position.y });
|
||||
} else if (!isNew && workflowDefinitionNode.graph?.position) {
|
||||
} else if (!isNew && nodeDefinitions.graph?.position) {
|
||||
// 已有节点:使用后端返回的position
|
||||
Object.assign(nodeConfig, { position: workflowDefinitionNode.graph.position });
|
||||
Object.assign(nodeConfig, { position: nodeDefinitions.graph.position });
|
||||
}
|
||||
|
||||
// 设置节点ID(如果有)
|
||||
|
||||
@ -65,8 +65,7 @@ const FormRenderer: React.FC<{
|
||||
schema: any;
|
||||
path?: string;
|
||||
readOnly?: boolean;
|
||||
currentTab?: any;
|
||||
}> = ({schema, path = '', readOnly = false, currentTab}) => {
|
||||
}> = ({schema, path = '', readOnly = false}) => {
|
||||
if (!schema || !schema.properties) return null;
|
||||
const renderPortConfig = (portSchema: any, portPath: string) => {
|
||||
if (!portSchema || !portSchema.properties) return null;
|
||||
@ -86,12 +85,6 @@ const FormRenderer: React.FC<{
|
||||
required={portSchema.required?.includes('position')}
|
||||
initialValue={'default' in position ? position.default : undefined}
|
||||
style={{marginBottom: 16}}
|
||||
rules={[
|
||||
{
|
||||
required: portSchema.required?.includes('position'),
|
||||
message: `请${position.type === 'string' ? '输入' : '选择'}${position.title}`
|
||||
}
|
||||
]}
|
||||
>
|
||||
{readOnly ? (
|
||||
<span style={{color: '#666'}}>{position.default || '-'}</span>
|
||||
@ -119,7 +112,6 @@ const FormRenderer: React.FC<{
|
||||
schema={attrs}
|
||||
path={`${portPath}.attrs`}
|
||||
readOnly={readOnly}
|
||||
currentTab={currentTab}
|
||||
/>
|
||||
</Card>
|
||||
)}
|
||||
@ -200,7 +192,6 @@ const FormRenderer: React.FC<{
|
||||
schema={value}
|
||||
path={fieldPath}
|
||||
readOnly={readOnly}
|
||||
currentTab={currentTab}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
@ -216,15 +207,9 @@ const FormRenderer: React.FC<{
|
||||
</span>
|
||||
}
|
||||
tooltip={value.description}
|
||||
required={currentTab?.schemaKey === 'uiVariables' && schema.required?.includes(key)}
|
||||
required={schema.required?.includes(key)}
|
||||
initialValue={'default' in value ? value.default : undefined}
|
||||
style={{marginBottom: 16}}
|
||||
rules={currentTab?.schemaKey === 'uiVariables' ? [
|
||||
{
|
||||
required: schema.required?.includes(key),
|
||||
message: `请${value.type === 'string' ? '输入' : '选择'}${value.title}`
|
||||
}
|
||||
] : undefined}
|
||||
>
|
||||
{readOnly ? (
|
||||
<span style={{color: '#666'}}>{value.default || '-'}</span>
|
||||
@ -276,7 +261,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
useEffect(() => {
|
||||
const loadNodeDetail = async () => {
|
||||
if (!id) return;
|
||||
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
const data = await service.getNodeDefinition(id);
|
||||
@ -318,7 +303,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
console.log('选择节点:', node);
|
||||
console.log('当前编辑状态:', isEdit);
|
||||
console.log('当前编辑数据:', editData);
|
||||
|
||||
|
||||
setSelectedNode(node);
|
||||
// 更新表单数据
|
||||
form.setFieldsValue({
|
||||
@ -341,7 +326,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
console.log('Form values:', values);
|
||||
|
||||
|
||||
// 提取基本信息字段
|
||||
const baseFields = {
|
||||
nodeType: values['base.nodeType'],
|
||||
@ -362,7 +347,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
// 处理颜色值转换为十六进制
|
||||
const processColorValue = (value: any): any => {
|
||||
if (!value || typeof value !== 'object') return value;
|
||||
|
||||
|
||||
// 如果是 ColorPicker 的值,转换为十六进制
|
||||
if (value.metaColor) {
|
||||
const { r, g, b } = value.metaColor;
|
||||
@ -372,7 +357,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
};
|
||||
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
||||
}
|
||||
|
||||
|
||||
// 如果是普通对象,递归处理
|
||||
if (typeof value === 'object') {
|
||||
const result: any = {};
|
||||
@ -381,39 +366,39 @@ const NodeDesignForm: React.FC = () => {
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
// 将扁平的键值对转换为嵌套对象
|
||||
const convertToNestedObject = (flatObj: any) => {
|
||||
const result: any = {};
|
||||
|
||||
|
||||
Object.keys(flatObj).forEach(key => {
|
||||
const parts = key.split('.');
|
||||
let current = result;
|
||||
|
||||
|
||||
for (let i = 0; i < parts.length - 1; i++) {
|
||||
current[parts[i]] = current[parts[i]] || {};
|
||||
current = current[parts[i]];
|
||||
}
|
||||
|
||||
|
||||
// 处理颜色值
|
||||
const value = processColorValue(flatObj[key]);
|
||||
current[parts[parts.length - 1]] = value;
|
||||
});
|
||||
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
const saveData = {
|
||||
...selectedNode,
|
||||
...baseFields,
|
||||
uiVariables: convertToNestedObject(uiValues)
|
||||
};
|
||||
|
||||
|
||||
console.log('Save data:', saveData);
|
||||
|
||||
|
||||
// 根据是否是编辑模式调用不同的接口
|
||||
if (isEdit && editData?.id) {
|
||||
await service.updateNodeDefinition(editData.id, saveData);
|
||||
@ -438,7 +423,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
console.log('当前 schema:', schema);
|
||||
console.log('是否编辑模式:', isEdit);
|
||||
console.log('编辑数据:', editData);
|
||||
|
||||
|
||||
// 如果是编辑模式且有保存的数据,合并到 schema
|
||||
if (isEdit && editData?.uiVariables) {
|
||||
console.log('开始合并 UI 配置数据');
|
||||
@ -446,7 +431,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
// 处理颜色值
|
||||
const processColorValue = (value: any): string => {
|
||||
if (!value || typeof value !== 'object') return value;
|
||||
|
||||
|
||||
// 如果是颜色对象结构
|
||||
if (value.metaColor) {
|
||||
const { r, g, b } = value.metaColor;
|
||||
@ -457,7 +442,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
};
|
||||
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
||||
}
|
||||
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
@ -466,7 +451,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
console.log('正在处理 schema:', schemaObj);
|
||||
console.log('UI 数据:', uiData);
|
||||
console.log('当前路径:', parentPath);
|
||||
|
||||
|
||||
const result = {...schemaObj};
|
||||
|
||||
// 颜色字段路径列表
|
||||
@ -484,7 +469,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
Object.keys(result.properties).forEach(key => {
|
||||
const currentPath = parentPath ? `${parentPath}.${key}` : key;
|
||||
console.log('处理属性:', currentPath);
|
||||
|
||||
|
||||
// 处理嵌套对象
|
||||
if (result.properties[key].type === 'object') {
|
||||
const nestedValue = currentPath.split('.').reduce((obj, key) => obj?.[key], uiData);
|
||||
@ -492,7 +477,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
if (nestedValue !== undefined) {
|
||||
result.properties[key].default = nestedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理基本类型
|
||||
else {
|
||||
const value = currentPath.split('.').reduce((obj, key) => obj?.[key], uiData);
|
||||
@ -506,11 +491,11 @@ const NodeDesignForm: React.FC = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 递归处理嵌套属性
|
||||
result.properties[key] = mergeUiVariables(
|
||||
result.properties[key],
|
||||
uiData,
|
||||
result.properties[key],
|
||||
uiData,
|
||||
currentPath
|
||||
);
|
||||
});
|
||||
@ -527,7 +512,7 @@ const NodeDesignForm: React.FC = () => {
|
||||
console.log('合并后的 schema:', mergedSchema);
|
||||
return mergedSchema;
|
||||
}
|
||||
|
||||
|
||||
console.log('使用原始 schema');
|
||||
return schema;
|
||||
};
|
||||
@ -551,8 +536,8 @@ const NodeDesignForm: React.FC = () => {
|
||||
<Tabs
|
||||
tabPosition="left"
|
||||
type="card"
|
||||
activeKey={isEdit && editData?.nodeType ?
|
||||
nodeDefinitionsDefined.find(n => n.nodeType === editData.nodeType)?.nodeCode || selectedNode?.nodeCode :
|
||||
activeKey={isEdit && editData?.nodeType ?
|
||||
nodeDefinitionsDefined.find(n => n.nodeType === editData.nodeType)?.nodeCode || selectedNode?.nodeCode :
|
||||
selectedNode?.nodeCode || ''
|
||||
}
|
||||
onChange={(key) => {
|
||||
@ -653,7 +638,6 @@ const NodeDesignForm: React.FC = () => {
|
||||
<FormRenderer
|
||||
schema={getCurrentSchema()}
|
||||
readOnly={tab.readonly}
|
||||
currentTab={tab}
|
||||
/>
|
||||
</div>
|
||||
) : null
|
||||
|
||||
@ -71,11 +71,12 @@ export interface UIVariables extends BaseSchema {
|
||||
}
|
||||
|
||||
// 节点设计数据
|
||||
export interface NodeDesignDataResponse extends BaseResponse{
|
||||
export interface NodeDesignDataResponse extends BaseResponse {
|
||||
nodeCode: string;
|
||||
nodeName: string;
|
||||
nodeType: string;
|
||||
category: string;
|
||||
description: string;
|
||||
panelVariablesSchema: NodeVariablesSchema | null;
|
||||
localVariablesSchema: NodeVariablesSchema | null;
|
||||
formVariablesSchema: NodeVariablesSchema | null;
|
||||
@ -100,6 +101,8 @@ export interface NodeDefinitionResponse extends BaseResponse {
|
||||
nodeCode: string;
|
||||
nodeName: string;
|
||||
nodeType: NodeTypeEnum;
|
||||
category: string;
|
||||
description: string;
|
||||
panelVariablesSchema: NodeVariablesSchema | null;
|
||||
uiVariables: UIVariables | null;
|
||||
localVariablesSchema: NodeVariablesSchema | null;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user