From dd57d2d8c8a5ed14d5912d5dd943a7bdac1a0acf Mon Sep 17 00:00:00 2001 From: dengqichen Date: Thu, 19 Dec 2024 16:37:03 +0800 Subject: [PATCH] 1 --- .../src/pages/Workflow/NodeDesign/Design.tsx | 245 ++++++++++-------- 1 file changed, 141 insertions(+), 104 deletions(-) diff --git a/frontend/src/pages/Workflow/NodeDesign/Design.tsx b/frontend/src/pages/Workflow/NodeDesign/Design.tsx index 9136cedd..747d9150 100644 --- a/frontend/src/pages/Workflow/NodeDesign/Design.tsx +++ b/frontend/src/pages/Workflow/NodeDesign/Design.tsx @@ -1,16 +1,16 @@ import React, { useEffect, useState } from 'react'; import { PageContainer } from '@ant-design/pro-components'; -import { Row, Col, Menu, Tabs } from 'antd'; -import FormRender, { useForm } from 'form-render'; +import { Row, Col, Menu, Tabs, Card } from 'antd'; +import { BetaSchemaForm, ProForm, ProFormGroup } from '@ant-design/pro-form'; import type { NodeDefinitionData } from './types'; import * as service from './service'; // Tab 配置 const TAB_CONFIG = [ - { key: 'panel', label: '属性(预览)', schemaKey: 'panelVariablesSchema' }, - { key: 'local', label: '环境变量(预览)', schemaKey: 'localVariablesSchema' }, - { key: 'form', label: '表单(预览)', schemaKey: 'formVariablesSchema' }, - { key: 'ui', label: 'UI配置', schemaKey: 'uiVariables' } + { key: 'panel', label: '属性(预览)', schemaKey: 'panelVariablesSchema', readonly: true }, + { key: 'local', label: '环境变量(预览)', schemaKey: 'localVariablesSchema', readonly: true }, + { key: 'form', label: '表单(预览)', schemaKey: 'formVariablesSchema', readonly: true }, + { key: 'ui', label: 'UI配置', schemaKey: 'uiVariables', readonly: false } ]; const NodeDesignForm: React.FC = () => { @@ -21,8 +21,6 @@ const NodeDesignForm: React.FC = () => { const [selectedNode, setSelectedNode] = useState(null); // 当前选中的 tab const [activeTab, setActiveTab] = useState('panel'); - // form 实例 - const form = useForm(); // 加载节点定义数据 useEffect(() => { @@ -65,127 +63,166 @@ const NodeDesignForm: React.FC = () => { if (availableTabs.length > 0 && !availableTabs.find(tab => tab.key === activeTab)) { setActiveTab(availableTabs[0].key); } - // 重置表单 - form.resetFields(); } }; // 处理 Tab 切换 const handleTabChange = (newTab: string) => { setActiveTab(newTab); - // 重置表单 - form.resetFields(); }; - // 处理 schema 的 title - const processSchemaTitle = (schema: any) => { - if (!schema || typeof schema !== 'object') return schema; - - const newSchema = { ...schema }; - - // 如果有 properties,处理每个属性 - if (newSchema.properties) { - newSchema.properties = Object.entries(newSchema.properties).reduce((acc, [key, value]: [string, any]) => { - const newValue = { ...value }; - // 如果有 title,添加 key - if (newValue.title) { - newValue.title = `${newValue.title}-${key}`; - } - // 递归处理嵌套的 properties - if (newValue.properties) { - newValue.properties = processSchemaTitle(newValue).properties; - } - return { ...acc, [key]: newValue }; - }, {}); - } - - return newSchema; + // 处理表单提交 + const handleFormSubmit = async (values: any) => { + console.log('表单提交:', values); + // TODO: 调用接口保存数据 }; - // 获取表单 schema - const getFormSchema = (tabKey: string) => { - if (!selectedNode) return null; + // 递归获取默认值 + const getDefaultValues = (schema: any) => { + if (!schema || !schema.properties) return {}; + + return Object.entries(schema.properties).reduce((acc, [key, value]: [string, any]) => { + if (value.type === 'object') { + acc[key] = getDefaultValues(value); + } else if (value.type === 'array' && value.items) { + acc[key] = value.default || []; + } else { + acc[key] = value.default; + } + return acc; + }, {}); + }; - const content = selectedNode[tabKey as keyof NodeDefinitionData]; - if (!content) return null; + // 将 JSON Schema 转换为 ProForm Schema + const convertToProFormSchema = (schema: any, parentKey = '', level = 0) => { + if (!schema || !schema.properties) return []; - // 如果内容本身就是 schema 格式,处理 title 后返回 - if (typeof content === 'object' && 'type' in content && 'properties' in content) { - return processSchemaTitle(content); - } - - // 否则,构建一个 schema - return { - type: 'object', - properties: Object.entries(content).reduce((acc, [key, value]) => { - let fieldSchema: any = { - title: key, - }; - - // 根据值的类型设置不同的 schema - if (typeof value === 'string') { - fieldSchema = { - ...fieldSchema, - type: 'string', - default: value - }; - } else if (typeof value === 'number') { - fieldSchema = { - ...fieldSchema, - type: 'number', - default: value - }; - } else if (typeof value === 'boolean') { - fieldSchema = { - ...fieldSchema, - type: 'boolean', - default: value - }; - } else if (Array.isArray(value)) { - fieldSchema = { - ...fieldSchema, - type: 'array', - items: { - type: typeof value[0] || 'string' - }, - default: value - }; - } else if (typeof value === 'object' && value !== null) { - fieldSchema = { - ...fieldSchema, - type: 'object', - properties: this.getFormSchema(value)?.properties || {}, - default: value - }; + return Object.entries(schema.properties).map(([key, value]: [string, any]) => { + const fullKey = parentKey ? `${parentKey}.${key}` : key; + const baseField = { + title: value.title || key, + dataIndex: fullKey, + tooltip: value.description, + fieldProps: { + style: { width: '100%' } } + }; + // 处理枚举类型 + if (value.enum) { return { - ...acc, - [key]: fieldSchema + ...baseField, + valueType: 'select', + valueEnum: value.enum.reduce((acc: any, item: string, index: number) => { + acc[item] = { text: value.enumNames?.[index] || item }; + return acc; + }, {}) }; - }, {}) - }; + } + + // 处理不同类型的字段 + if (value.type === 'string') { + return { + ...baseField, + valueType: 'text' + }; + } else if (value.type === 'number' || value.type === 'integer') { + return { + ...baseField, + valueType: 'digit' + }; + } else if (value.type === 'boolean') { + return { + ...baseField, + valueType: 'switch' + }; + } else if (value.type === 'array') { + const itemColumns = value.items ? convertToProFormSchema( + { properties: { item: value.items } }, + `${fullKey}.item`, + level + 1 + ) : []; + + return { + ...baseField, + valueType: 'formList', + columns: itemColumns + }; + } else if (value.type === 'object') { + const childColumns = value.properties ? convertToProFormSchema(value, fullKey, level + 1) : []; + + return { + ...baseField, + valueType: 'group', + columns: childColumns, + colProps: { + span: 24 + }, + fieldProps: { + title: value.title, + style: { + padding: level === 0 ? '16px' : '8px', + marginBottom: '16px', + border: '1px solid #f0f0f0', + borderRadius: '4px', + background: level === 0 ? '#fafafa' : 'transparent' + } + } + }; + } + + return baseField; + }); }; // 渲染 Tab 内容 const renderTabContent = (tabKey: string) => { if (!selectedNode) return null; - const schema = getFormSchema(tabKey); - if (!schema) return null; + const content = selectedNode[tabKey as keyof NodeDefinitionData]; + if (!content) return null; + + const currentTab = TAB_CONFIG.find(tab => tab.schemaKey === tabKey); + const isReadOnly = currentTab?.readonly ?? true; + + // 判断是否是 schema 格式 + const isSchema = typeof content === 'object' && 'type' in content && 'properties' in content; + const schema = isSchema ? content : { + type: 'object', + properties: Object.entries(content).reduce((acc, [key, value]) => ({ + ...acc, + [key]: { + title: key, + type: typeof value, + default: value + } + }), {}) + }; + + // 获取默认值 + const defaultValues = getDefaultValues(schema); return ( -
- + -
+ ); };